use Abraham\TwitterOAuth\TwitterOAuth;
use Abraham\TwitterOAuth\TwitterOAuthException;
+use Codebird\Codebird;
use Friendica\App;
use Friendica\Content\OEmbed;
use Friendica\Content\Text\BBCode;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
-use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
+use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
-use Friendica\Model\GContact;
use Friendica\Model\Group;
use Friendica\Model\Item;
use Friendica\Model\ItemContent;
-use Friendica\Model\Queue;
use Friendica\Model\User;
-use Friendica\Object\Image;
+use Friendica\Protocol\Activity;
+use Friendica\Util\ConfigFileLoader;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Strings;
Hook::register('notifier_normal' , __FILE__, 'twitter_post_hook');
Hook::register('jot_networks' , __FILE__, 'twitter_jot_nets');
Hook::register('cron' , __FILE__, 'twitter_cron');
- Hook::register('queue_predeliver' , __FILE__, 'twitter_queue_hook');
Hook::register('follow' , __FILE__, 'twitter_follow');
Hook::register('expire' , __FILE__, 'twitter_expire');
Hook::register('prepare_body' , __FILE__, 'twitter_prepare_body');
Hook::register('check_item_notification', __FILE__, 'twitter_check_item_notification');
- Logger::log("installed twitter");
+ Logger::info("installed twitter");
}
function twitter_uninstall()
Hook::unregister('notifier_normal' , __FILE__, 'twitter_post_hook');
Hook::unregister('jot_networks' , __FILE__, 'twitter_jot_nets');
Hook::unregister('cron' , __FILE__, 'twitter_cron');
- Hook::unregister('queue_predeliver' , __FILE__, 'twitter_queue_hook');
Hook::unregister('follow' , __FILE__, 'twitter_follow');
Hook::unregister('expire' , __FILE__, 'twitter_expire');
Hook::unregister('prepare_body' , __FILE__, 'twitter_prepare_body');
Hook::unregister('addon_settings_post', __FILE__, 'twitter_settings_post');
}
-function twitter_load_config(App $a)
+function twitter_load_config(App $a, ConfigFileLoader $loader)
{
- $a->loadConfigFile(__DIR__ . '/config/twitter.config.php');
+ $a->getConfigCache()->load($loader->loadAddonConfig('twitter'));
}
function twitter_check_item_notification(App $a, array &$notification_data)
{
- $own_id = PConfig::get($notification_data["uid"], 'twitter', 'own_id');
+ $own_id = DI::pConfig()->get($notification_data["uid"], 'twitter', 'own_id');
$own_user = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `alias` = '%s' LIMIT 1",
intval($notification_data["uid"]),
function twitter_follow(App $a, array &$contact)
{
- Logger::log("twitter_follow: Check if contact is twitter contact. " . $contact["url"], Logger::DEBUG);
+ Logger::info('Check if contact is twitter contact', ['url' => $contact["url"]]);
if (!strstr($contact["url"], "://twitter.com") && !strstr($contact["url"], "@twitter.com")) {
return;
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($uid, 'twitter', 'oauthtoken');
- $osecret = PConfig::get($uid, 'twitter', 'oauthsecret');
+ $otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
// If the addon is not configured (general or for this user) quit here
if (empty($ckey) || empty($csecret) || empty($otoken) || empty($osecret)) {
}
}
-function twitter_jot_nets(App $a, &$b)
+function twitter_jot_nets(App $a, array &$jotnets_fields)
{
if (!local_user()) {
return;
}
- $tw_post = PConfig::get(local_user(), 'twitter', 'post');
- if (intval($tw_post) == 1) {
- $tw_defpost = PConfig::get(local_user(), 'twitter', 'post_by_default');
- $selected = ((intval($tw_defpost) == 1) ? ' checked="checked" ' : '');
- $b .= '<div class="profile-jot-net"><input type="checkbox" name="twitter_enable"' . $selected . ' value="1" /> '
- . L10n::t('Post to Twitter') . '</div>';
+ if (DI::pConfig()->get(local_user(), 'twitter', 'post')) {
+ $jotnets_fields[] = [
+ 'type' => 'checkbox',
+ 'field' => [
+ 'twitter_enable',
+ L10n::t('Post to Twitter'),
+ DI::pConfig()->get(local_user(), 'twitter', 'post_by_default')
+ ]
+ ];
}
}
+
function twitter_settings_post(App $a)
{
if (!local_user()) {
} else {
if (isset($_POST['twitter-pin'])) {
// if the user supplied us with a PIN from Twitter, let the magic of OAuth happen
- Logger::log('got a Twitter PIN');
+ Logger::notice('got a Twitter PIN');
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
// the token and secret for which the PIN was generated were hidden in the settings
$connection = new TwitterOAuth($ckey, $csecret, $_POST['twitter-token'], $_POST['twitter-token2']);
$token = $connection->oauth("oauth/access_token", ["oauth_verifier" => $_POST['twitter-pin']]);
// ok, now that we have the Access Token, save them in the user config
- PConfig::set(local_user(), 'twitter', 'oauthtoken', $token['oauth_token']);
- PConfig::set(local_user(), 'twitter', 'oauthsecret', $token['oauth_token_secret']);
- PConfig::set(local_user(), 'twitter', 'post', 1);
+ DI::pConfig()->set(local_user(), 'twitter', 'oauthtoken', $token['oauth_token']);
+ DI::pConfig()->set(local_user(), 'twitter', 'oauthsecret', $token['oauth_token_secret']);
+ DI::pConfig()->set(local_user(), 'twitter', 'post', 1);
} catch(Exception $e) {
info($e->getMessage());
} catch(TwitterOAuthException $e) {
info($e->getMessage());
}
// reload the Addon Settings page, if we don't do it see Bug #42
- System::redirect('settings/connectors');
+ DI::baseUrl()->redirect('settings/connectors');
} else {
// if no PIN is supplied in the POST variables, the user has changed the setting
// to post a tweet for every new __public__ posting to the wall
- PConfig::set(local_user(), 'twitter', 'post', intval($_POST['twitter-enable']));
- PConfig::set(local_user(), 'twitter', 'post_by_default', intval($_POST['twitter-default']));
- PConfig::set(local_user(), 'twitter', 'mirror_posts', intval($_POST['twitter-mirror']));
- PConfig::set(local_user(), 'twitter', 'import', intval($_POST['twitter-import']));
- PConfig::set(local_user(), 'twitter', 'create_user', intval($_POST['twitter-create_user']));
+ DI::pConfig()->set(local_user(), 'twitter', 'post', intval($_POST['twitter-enable']));
+ DI::pConfig()->set(local_user(), 'twitter', 'post_by_default', intval($_POST['twitter-default']));
+ DI::pConfig()->set(local_user(), 'twitter', 'mirror_posts', intval($_POST['twitter-mirror']));
+ DI::pConfig()->set(local_user(), 'twitter', 'import', intval($_POST['twitter-import']));
+ DI::pConfig()->set(local_user(), 'twitter', 'create_user', intval($_POST['twitter-create_user']));
if (!intval($_POST['twitter-mirror'])) {
PConfig::delete(local_user(), 'twitter', 'lastid');
if (!local_user()) {
return;
}
- $a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . $a->getBaseURL() . '/addon/twitter/twitter.css' . '" media="all" />' . "\r\n";
+ DI::page()['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . DI::baseUrl()->get() . '/addon/twitter/twitter.css' . '" media="all" />' . "\r\n";
/* * *
* 1) Check that we have global consumer key & secret
* 2) If no OAuthtoken & stuff is present, generate button to get some
*/
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get(local_user(), 'twitter', 'oauthtoken');
- $osecret = PConfig::get(local_user(), 'twitter', 'oauthsecret');
+ $otoken = DI::pConfig()->get(local_user(), 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get(local_user(), 'twitter', 'oauthsecret');
- $enabled = intval(PConfig::get(local_user(), 'twitter', 'post'));
- $defenabled = intval(PConfig::get(local_user(), 'twitter', 'post_by_default'));
- $mirrorenabled = intval(PConfig::get(local_user(), 'twitter', 'mirror_posts'));
- $importenabled = intval(PConfig::get(local_user(), 'twitter', 'import'));
- $create_userenabled = intval(PConfig::get(local_user(), 'twitter', 'create_user'));
+ $enabled = intval(DI::pConfig()->get(local_user(), 'twitter', 'post'));
+ $defenabled = intval(DI::pConfig()->get(local_user(), 'twitter', 'post_by_default'));
+ $mirrorenabled = intval(DI::pConfig()->get(local_user(), 'twitter', 'mirror_posts'));
+ $importenabled = intval(DI::pConfig()->get(local_user(), 'twitter', 'import'));
+ $create_userenabled = intval(DI::pConfig()->get(local_user(), 'twitter', 'create_user'));
$css = (($enabled) ? '' : '-disabled');
$field_checkbox = Renderer::getMarkupTemplate('field_checkbox.tpl');
- $s .= '<div id="twitter-info" >
+ if (property_exists($details, 'screen_name') &&
+ property_exists($details, 'description') &&
+ property_exists($details, 'profile_image_url')) {
+ $s .= '<div id="twitter-info" >
<p>' . L10n::t('Currently connected to: ') . '<a href="https://twitter.com/' . $details->screen_name . '" target="_twitter">' . $details->screen_name . '</a>
<button type="submit" name="twitter-disconnect" value="1">' . L10n::t('Disconnect') . '</button>
</p>
<em>' . $details->description . '</em>
</p>
</div>';
+ } else {
+ $s .= '<div id="twitter-info" >
+ <p>Invalid Twitter info</p>
+ </div>';
+ Logger::info('Invalid twitter info (verify credentials).', ['auth' => TwitterOAuth::class]);
+ }
$s .= '<div class="clear"></div>';
$s .= Renderer::replaceMacros($field_checkbox, [
return;
}
- if (PConfig::get($post['uid'], 'twitter', 'import')) {
+ if (DI::pConfig()->get($post['uid'], 'twitter', 'import')) {
// Don't fork if it isn't a reply to a twitter post
if (($post['parent'] != $post['id']) && !Item::exists(['id' => $post['parent'], 'network' => Protocol::TWITTER])) {
- Logger::log('No twitter parent found for item ' . $post['id']);
+ Logger::notice('No twitter parent found', ['item' => $post['id']]);
$b['execute'] = false;
return;
}
return;
}
- $twitter_post = intval(PConfig::get(local_user(), 'twitter', 'post'));
+ $twitter_post = intval(DI::pConfig()->get(local_user(), 'twitter', 'post'));
$twitter_enable = (($twitter_post && !empty($_REQUEST['twitter_enable'])) ? intval($_REQUEST['twitter_enable']) : 0);
// if API is used, default to the chosen settings
- if ($b['api_source'] && intval(PConfig::get(local_user(), 'twitter', 'post_by_default'))) {
+ if ($b['api_source'] && intval(DI::pConfig()->get(local_user(), 'twitter', 'post_by_default'))) {
$twitter_enable = 1;
}
{
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($uid, 'twitter', 'oauthtoken');
- $osecret = PConfig::get($uid, 'twitter', 'oauthsecret');
+ $otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
function twitter_post_hook(App $a, array &$b)
{
// Post to Twitter
- if (!PConfig::get($b["uid"], 'twitter', 'import')
+ if (!DI::pConfig()->get($b["uid"], 'twitter', 'import')
&& ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited']))) {
return;
}
}
}
- if (($b['verb'] == ACTIVITY_POST) && $b['deleted']) {
+ if (($b['verb'] == Activity::POST) && $b['deleted']) {
twitter_action($a, $b["uid"], substr($orig_post["uri"], 9), "delete");
}
- if ($b['verb'] == ACTIVITY_LIKE) {
+ if ($b['verb'] == Activity::LIKE) {
Logger::log("twitter_post_hook: parameter 2 " . substr($b["thr-parent"], 9), Logger::DEBUG);
if ($b['deleted']) {
twitter_action($a, $b["uid"], substr($b["thr-parent"], 9), "unlike");
return;
}
- Logger::log('twitter post invoked');
+ Logger::notice('twitter post invoked', ['id' => $b['id'], 'guid' => $b['guid']]);
- PConfig::load($b['uid'], 'twitter');
+ DI::pConfig()->load($b['uid'], 'twitter');
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($b['uid'], 'twitter', 'oauthtoken');
- $osecret = PConfig::get($b['uid'], 'twitter', 'oauthsecret');
+ $otoken = DI::pConfig()->get($b['uid'], 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($b['uid'], 'twitter', 'oauthsecret');
if ($ckey && $csecret && $otoken && $osecret) {
Logger::log('twitter: we have customer key and oauth stuff, going to send.', Logger::DEBUG);
return;
}
+ Codebird::setConsumerKey($ckey, $csecret);
+ $cb = Codebird::getInstance();
+ $cb->setToken($otoken, $osecret);
+
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
// Set the timeout for upload to 30 seconds
$b['body'] = twitter_update_mentions($b['body']);
$msgarr = ItemContent::getPlaintextPost($b, $max_char, true, 8);
+ Logger::info('Got plaintext', ['id' => $b['id'], 'message' => $msgarr]);
$msg = $msgarr["text"];
if (($msg == "") && isset($msgarr["title"])) {
$msg = Plaintext::shorten($msgarr["title"], $max_char - 50);
}
- $image = "";
-
- if (isset($msgarr["url"]) && ($msgarr["type"] != "photo")) {
+ if (!empty($msgarr['url']) && ($msgarr['url'] == $b['plink']) && !empty($msgarr['images']) && (count($msgarr['images']) <= 4)) {
+ $url_added = false;
+ } elseif (isset($msgarr["url"]) && ($msgarr["type"] != "photo")) {
$msg .= "\n" . $msgarr["url"];
$url_added = true;
} else {
$url_added = false;
}
- if (isset($msgarr["image"]) && ($msgarr["type"] != "video")) {
- $image = $msgarr["image"];
- }
-
if (empty($msg)) {
+ Logger::info('Empty message', ['id' => $b['id']]);
return;
}
// and now tweet it :-)
$post = [];
- if (!empty($image)) {
+ if (!empty($msgarr['images'])) {
+ Logger::info('Got images', ['id' => $b['id'], 'images' => $msgarr['images']]);
try {
- $img_str = Network::fetchUrl($image);
+ $media_ids = [];
+ foreach ($msgarr['images'] as $image) {
+ if (count($media_ids) == 4) {
+ continue;
+ }
- $tempfile = tempnam(get_temppath(), 'cache');
- file_put_contents($tempfile, $img_str);
+ $img_str = Network::fetchUrl($image['url']);
- $media = $connection->upload('media/upload', ['media' => $tempfile]);
+ $tempfile = tempnam(get_temppath(), 'cache');
+ file_put_contents($tempfile, $img_str);
- unlink($tempfile);
+ Logger::info('Uploading', ['id' => $b['id'], 'image' => $image['url']]);
+ $media = $connection->upload('media/upload', ['media' => $tempfile]);
- if (isset($media->media_id_string)) {
- $post['media_ids'] = $media->media_id_string;
- } else {
- throw new Exception('Failed upload of ' . $image);
- }
- } catch (Exception $e) {
- Logger::log('Exception when trying to send to Twitter: ' . $e->getMessage());
+ unlink($tempfile);
- // Workaround: Remove the picture link so that the post can be reposted without it
- // When there is another url already added, a second url would be superfluous.
- if (!$url_added) {
- $msg .= "\n" . $image;
- }
+ if (isset($media->media_id_string)) {
+ $media_ids[] = $media->media_id_string;
- $image = "";
+ if (!empty($image['description'])) {
+ $data = ['media_id' => $media->media_id_string,
+ 'alt_text' => ['text' => substr($image['description'], 0, 420)]];
+ $ret = $cb->media_metadata_create($data);
+ Logger::info('Metadata create', ['id' => $b['id'], 'data' => $data, 'return' => json_encode($ret)]);
+ }
+ } else {
+ throw new Exception('Failed upload', ['id' => $b['id'], 'image' => $image['url']]);
+ }
+ }
+ $post['media_ids'] = implode(',', $media_ids);
+ if (empty($post['media_ids'])) {
+ unset($post['media_ids']);
+ }
+ } catch (Exception $e) {
+ Logger::info('Exception when trying to send to Twitter', ['id' => $b['id'], 'message' => $e->getMessage()]);
}
}
$url = 'statuses/update';
$result = $connection->post($url, $post);
- Logger::log('twitter_post send, result: ' . print_r($result, true), Logger::DEBUG);
+ Logger::info('twitter_post send', ['id' => $b['id'], 'result' => $result]);
if (!empty($result->source)) {
Config::set("twitter", "application_name", strip_tags($result->source));
}
if (!empty($result->errors)) {
- Logger::log('Send to Twitter failed: "' . print_r($result->errors, true) . '"');
-
- $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `self`", intval($b['uid']));
- if (DBA::isResult($r)) {
- $a->contact = $r[0]["id"];
- }
-
- $s = serialize(['url' => $url, 'item' => $b['id'], 'post' => $post]);
-
- Queue::add($a->contact, Protocol::TWITTER, $s);
- notice(L10n::t('Twitter post failed. Queued for retry.') . EOL);
+ Logger::info('Send to Twitter failed', ['id' => $b['id'], 'error' => $result->errors]);
+ Worker::defer();
} elseif ($iscomment) {
- Logger::log('twitter_post: Update extid ' . $result->id_str . " for post id " . $b['id']);
+ Logger::info('Update extid', ['id' => $b['id'], 'extid' => $result->id_str]);
Item::update(['extid' => "twitter::" . $result->id_str], ['id' => $b['id']]);
}
}
if ($last) {
$next = $last + ($poll_interval * 60);
if ($next > time()) {
- Logger::log('twitter: poll intervall not reached');
+ Logger::notice('twitter: poll intervall not reached');
return;
}
}
- Logger::log('twitter: cron_start');
+ Logger::notice('twitter: cron_start');
$r = q("SELECT * FROM `pconfig` WHERE `cat` = 'twitter' AND `k` = 'mirror_posts' AND `v` = '1'");
if (DBA::isResult($r)) {
foreach ($r as $rr) {
- Logger::log('twitter: fetching for user ' . $rr['uid']);
- Worker::add(PRIORITY_MEDIUM, "addon/twitter/twitter_sync.php", 1, (int) $rr['uid']);
+ Logger::notice('Fetching', ['user' => $rr['uid']]);
+ Worker::add(['priority' => PRIORITY_MEDIUM, 'force_priority' => true], "addon/twitter/twitter_sync.php", 1, (int) $rr['uid']);
}
}
if ($abandon_days != 0) {
$user = q("SELECT `login_date` FROM `user` WHERE uid=%d AND `login_date` >= '%s'", $rr['uid'], $abandon_limit);
if (!DBA::isResult($user)) {
- Logger::log('abandoned account: timeline from user ' . $rr['uid'] . ' will not be imported');
+ Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $rr['uid']]);
continue;
}
}
- Logger::log('twitter: importing timeline from user ' . $rr['uid']);
- Worker::add(PRIORITY_MEDIUM, "addon/twitter/twitter_sync.php", 2, (int) $rr['uid']);
+ Logger::notice('importing timeline', ['user' => $rr['uid']]);
+ Worker::add(['priority' => PRIORITY_MEDIUM, 'force_priority' => true], "addon/twitter/twitter_sync.php", 2, (int) $rr['uid']);
/*
// To-Do
// check for new contacts once a day
- $last_contact_check = PConfig::get($rr['uid'],'pumpio','contact_check');
+ $last_contact_check = DI::pConfig()->get($rr['uid'],'pumpio','contact_check');
if($last_contact_check)
$next_contact_check = $last_contact_check + 86400;
else
if($next_contact_check <= time()) {
pumpio_getallusers($a, $rr["uid"]);
- PConfig::set($rr['uid'],'pumpio','contact_check',time());
+ DI::pConfig()->set($rr['uid'],'pumpio','contact_check',time());
}
*/
}
}
- Logger::log('twitter: cron_end');
+ Logger::notice('twitter: cron_end');
Config::set('twitter', 'last_poll', time());
}
}
DBA::close($r);
- Logger::log('twitter_expire: expire_start');
+ Logger::notice('twitter_expire: expire_start');
$r = q("SELECT * FROM `pconfig` WHERE `cat` = 'twitter' AND `k` = 'import' AND `v` = '1' ORDER BY RAND()");
if (DBA::isResult($r)) {
foreach ($r as $rr) {
- Logger::log('twitter_expire: user ' . $rr['uid']);
+ Logger::notice('twitter_expire', ['user' => $rr['uid']]);
Item::expire($rr['uid'], $days, Protocol::TWITTER, true);
}
}
- Logger::log('twitter_expire: expire_end');
+ Logger::notice('twitter_expire: expire_end');
}
function twitter_prepare_body(App $a, array &$b)
if ($b["preview"]) {
$max_char = 280;
$item = $b["item"];
- $item["plink"] = $a->getBaseURL() . "/display/" . $a->user["nickname"] . "/" . $item["parent"];
+ $item["plink"] = DI::baseUrl()->get() . "/display/" . $item["guid"];
$condition = ['uri' => $item["thr-parent"], 'uid' => local_user()];
$orig_post = Item::selectFirst(['author-link'], $condition);
{
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($uid, 'twitter', 'oauthtoken');
- $osecret = PConfig::get($uid, 'twitter', 'oauthsecret');
- $lastid = PConfig::get($uid, 'twitter', 'lastid');
+ $otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
+ $lastid = DI::pConfig()->get($uid, 'twitter', 'lastid');
$application_name = Config::get('twitter', 'application_name');
if ($application_name == "") {
- $application_name = $a->getHostName();
+ $application_name = DI::baseUrl()->getHostname();
}
$has_picture = false;
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
- $parameters = ["exclude_replies" => true, "trim_user" => false, "contributor_details" => true, "include_rts" => true, "tweet_mode" => "extended"];
+ $parameters = ["exclude_replies" => true, "trim_user" => false, "contributor_details" => true, "include_rts" => true, "tweet_mode" => "extended", "include_ext_alt_text" => true];
$first_time = ($lastid == "");
try {
$items = $connection->get('statuses/user_timeline', $parameters);
} catch (TwitterOAuthException $e) {
- Logger::log('Error fetching timeline for user ' . $uid . ': ' . $e->getMessage());
+ Logger::notice('Error fetching timeline', ['user' => $uid, 'message' => $e->getMessage()]);
return;
}
if (!is_array($items)) {
- Logger::log('No items for user ' . $uid, Logger::INFO);
+ Logger::notice('No items', ['user' => $uid]);
return;
}
foreach ($posts as $post) {
if ($post->id_str > $lastid) {
$lastid = $post->id_str;
- PConfig::set($uid, 'twitter', 'lastid', $lastid);
+ DI::pConfig()->set($uid, 'twitter', 'lastid', $lastid);
}
if ($first_time) {
}
}
}
- PConfig::set($uid, 'twitter', 'lastid', $lastid);
+ DI::pConfig()->set($uid, 'twitter', 'lastid', $lastid);
Logger::log('Last ID for user ' . $uid . ' is now ' . $lastid, Logger::DEBUG);
}
-function twitter_queue_hook(App $a)
-{
- $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'",
- DBA::escape(Protocol::TWITTER)
- );
- if (!DBA::isResult($qi)) {
- return;
- }
-
- foreach ($qi as $x) {
- if ($x['network'] !== Protocol::TWITTER) {
- continue;
- }
-
- Logger::log('twitter_queue: run');
-
- $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid`
- WHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1",
- intval($x['cid'])
- );
- if (!DBA::isResult($r)) {
- continue;
- }
-
- $user = $r[0];
-
- $ckey = Config::get('twitter', 'consumerkey');
- $csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($user['uid'], 'twitter', 'oauthtoken');
- $osecret = PConfig::get($user['uid'], 'twitter', 'oauthsecret');
-
- $success = false;
-
- if ($ckey && $csecret && $otoken && $osecret) {
- Logger::log('twitter_queue: able to post');
-
- $z = unserialize($x['content']);
-
- $connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
- $result = $connection->post($z['url'], $z['post']);
-
- Logger::log('twitter_queue: post result: ' . print_r($result, true), Logger::DEBUG);
-
- if ($result->errors) {
- Logger::log('twitter_queue: Send to Twitter failed: "' . print_r($result->errors, true) . '"');
- } else {
- $success = true;
- Queue::removeItem($x['id']);
- }
- } else {
- Logger::log("twitter_queue: Error getting tokens for user " . $user['uid']);
- }
-
- if (!$success) {
- Logger::log('twitter_queue: delayed');
- Queue::updateTime($x['id']);
- }
- }
-}
-
function twitter_fix_avatar($avatar)
{
$new_avatar = str_replace("_normal.", ".", $avatar);
- $info = Image::getInfoFromURL($new_avatar);
+ $info = Images::getInfoFromURLCached($new_avatar);
if (!$info) {
$new_avatar = $avatar;
}
$url = "https://twitter.com/" . $data->screen_name;
$addr = $data->screen_name . "@twitter.com";
- GContact::update(["url" => $url, "network" => Protocol::TWITTER,
- "photo" => $avatar, "hide" => true,
- "name" => $data->name, "nick" => $data->screen_name,
- "location" => $data->location, "about" => $data->description,
- "addr" => $addr, "generation" => 2]);
-
$fields = ['url' => $url, 'network' => Protocol::TWITTER,
'name' => $data->name, 'nick' => $data->screen_name, 'addr' => $addr,
'location' => $data->location, 'about' => $data->description];
$contact = DBA::selectFirst('contact', [], ['uid' => $uid, 'alias' => "twitter::" . $data->id_str]);
if (!DBA::isResult($contact) && !$create_user) {
+ Logger::info('User contact not found', ['uid' => $uid, 'twitter-id' => $data->id_str]);
return 0;
}
{
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($uid, 'twitter', 'oauthtoken');
- $osecret = PConfig::get($uid, 'twitter', 'oauthsecret');
+ $otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
$r = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
intval($uid));
$tags_arr = [];
foreach ($item->entities->hashtags AS $hashtag) {
- $url = '#[url=' . $a->getBaseURL() . '/search?tag=' . $hashtag->text . ']' . $hashtag->text . '[/url]';
+ $url = '#[url=' . DI::baseUrl()->get() . '/search?tag=' . $hashtag->text . ']' . $hashtag->text . '[/url]';
$tags_arr['#' . $hashtag->text] = $url;
$body = str_replace('#' . $hashtag->text, $url, $body);
}
if ($url->url && $url->expanded_url && $url->display_url) {
// Quote tweet, we just remove the quoted tweet URL from the body, the share block will be added later.
- if (isset($item->quoted_status_id_str)
+ if (!empty($item->quoted_status) && isset($item->quoted_status_id_str)
&& substr($url->expanded_url, -strlen($item->quoted_status_id_str)) == $item->quoted_status_id_str ) {
$body = str_replace($url->url, '', $body);
continue;
} elseif ($oembed_data->type != 'link') {
$body = str_replace($url->url, '[url=' . $expanded_url . ']' . $url->display_url . '[/url]', $body);
} else {
- $img_str = Network::fetchUrl($final_url, true, $redirects, 4);
+ $img_str = Network::fetchUrl($final_url, true, 4);
$tempfile = tempnam(get_temppath(), 'cache');
file_put_contents($tempfile, $img_str);
}
$basetag = str_replace('_', ' ', substr($tag, 1));
- $url = '#[url=' . $a->getBaseURL() . '/search?tag=' . $basetag . ']' . $basetag . '[/url]';
+ $url = '#[url=' . DI::baseUrl()->get() . '/search?tag=' . $basetag . ']' . $basetag . '[/url]';
$body = str_replace($tag, $url, $body);
$tags_arr['#' . $basetag] = $url;
} elseif (strpos($tag, '@') === 0) {
}
switch ($medium->type) {
case 'photo':
- $media[$medium->url] .= "\n[img]" . $medium->media_url_https . '[/img]';
- $postarray['object-type'] = ACTIVITY_OBJ_IMAGE;
+ if (!empty($medium->ext_alt_text)) {
+ Logger::info('Got text description', ['alt_text' => $medium->ext_alt_text]);
+ $media[$medium->url] .= "\n[img=" . $medium->media_url_https .']' . $medium->ext_alt_text . '[/img]';
+ } else {
+ $media[$medium->url] .= "\n[img]" . $medium->media_url_https . '[/img]';
+ }
+
+ $postarray['object-type'] = Activity\ObjectType::IMAGE;
break;
case 'video':
case 'animated_gif':
- $media[$medium->url] .= "\n[img]" . $medium->media_url_https . '[/img]';
- $postarray['object-type'] = ACTIVITY_OBJ_VIDEO;
+ if (!empty($medium->ext_alt_text)) {
+ Logger::info('Got text description', ['alt_text' => $medium->ext_alt_text]);
+ $media[$medium->url] .= "\n[img=" . $medium->media_url_https .']' . $medium->ext_alt_text . '[/img]';
+ } else {
+ $media[$medium->url] .= "\n[img]" . $medium->media_url_https . '[/img]';
+ }
+
+ $postarray['object-type'] = Activity\ObjectType::VIDEO;
if (is_array($medium->video_info->variants)) {
$bitrate = 0;
// We take the video with the highest bitrate
$postarray['thr-parent'] = $parent_item['uri'];
$postarray['parent-uri'] = $parent_item['parent-uri'];
$postarray['parent'] = $parent_item['parent'];
- $postarray['object-type'] = ACTIVITY_OBJ_COMMENT;
+ $postarray['object-type'] = Activity\ObjectType::COMMENT;
} else {
$postarray['thr-parent'] = $postarray['uri'];
$postarray['parent-uri'] = $postarray['uri'];
- $postarray['object-type'] = ACTIVITY_OBJ_NOTE;
+ $postarray['object-type'] = Activity\ObjectType::NOTE;
}
// Is it me?
- $own_id = PConfig::get($uid, 'twitter', 'own_id');
+ $own_id = DI::pConfig()->get($uid, 'twitter', 'own_id');
if ($post->user->id_str == $own_id) {
$r = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
$create_user = false;
} else {
$postarray['parent-uri'] = $postarray['uri'];
- $postarray['object-type'] = ACTIVITY_OBJ_NOTE;
+ $postarray['object-type'] = Activity\ObjectType::NOTE;
}
if ($contactid == 0) {
$postarray['contact-id'] = $contactid;
- $postarray['verb'] = ACTIVITY_POST;
+ $postarray['verb'] = Activity::POST;
$postarray['author-name'] = $postarray['owner-name'];
$postarray['author-link'] = $postarray['owner-link'];
$postarray['author-avatar'] = $postarray['owner-avatar'];
// When the post contains links then use the correct object type
if (count($post->entities->urls) > 0) {
- $postarray['object-type'] = ACTIVITY_OBJ_BOOKMARK;
+ $postarray['object-type'] = Activity\ObjectType::BOOKMARK;
}
// Search for media links
return [];
}
- $retweet['source'] = $postarray['source'];
- $retweet['private'] = $postarray['private'];
- $retweet['allow_cid'] = $postarray['allow_cid'];
- $retweet['contact-id'] = $postarray['contact-id'];
- $retweet['owner-name'] = $postarray['owner-name'];
- $retweet['owner-link'] = $postarray['owner-link'];
- $retweet['owner-avatar'] = $postarray['owner-avatar'];
+ if (!$noquote) {
+ // Store the original tweet
+ Item::insert($retweet);
+
+ // CHange the other post into a reshare activity
+ $postarray['verb'] = Activity::ANNOUNCE;
+ $postarray['gravity'] = GRAVITY_ACTIVITY;
+ $postarray['object-type'] = Activity\ObjectType::NOTE;
- $postarray = $retweet;
+ $postarray['thr-parent'] = $retweet['uri'];
+ $postarray['parent-uri'] = $retweet['uri'];
+ } else {
+ $retweet['source'] = $postarray['source'];
+ $retweet['private'] = $postarray['private'];
+ $retweet['allow_cid'] = $postarray['allow_cid'];
+ $retweet['contact-id'] = $postarray['contact-id'];
+ $retweet['owner-name'] = $postarray['owner-name'];
+ $retweet['owner-link'] = $postarray['owner-link'];
+ $retweet['owner-avatar'] = $postarray['owner-avatar'];
+
+ $postarray = $retweet;
+ }
}
if (!empty($post->quoted_status) && !$noquote) {
$quoted = twitter_createpost($a, $uid, $post->quoted_status, $self, false, false, true);
- if (empty($quoted['body'])) {
- return [];
+ if (!empty($quoted['body'])) {
+ $postarray['body'] .= "\n" . share_header(
+ $quoted['author-name'],
+ $quoted['author-link'],
+ $quoted['author-avatar'],
+ "",
+ $quoted['created'],
+ $quoted['plink']
+ );
+
+ $postarray['body'] .= $quoted['body'] . '[/share]';
+ } else {
+ // Quoted post author is blocked/ignored, so we just provide the link to avoid removing quote context.
+ $postarray['body'] .= "\n\nhttps://twitter.com/" . $post->quoted_status->user->screen_name . "/status/" . $post->quoted_status->id_str;
}
-
- $postarray['body'] .= "\n" . share_header(
- $quoted['author-name'],
- $quoted['author-link'],
- $quoted['author-avatar'],
- "",
- $quoted['created'],
- $quoted['plink']
- );
-
- $postarray['body'] .= $quoted['body'] . '[/share]';
}
return $postarray;
$posts = [];
while (!empty($post->in_reply_to_status_id_str)) {
- $parameters = ["trim_user" => false, "tweet_mode" => "extended", "id" => $post->in_reply_to_status_id_str];
+ $parameters = ["trim_user" => false, "tweet_mode" => "extended", "id" => $post->in_reply_to_status_id_str, "include_ext_alt_text" => true];
try {
$post = $connection->get('statuses/show', $parameters);
}
if (empty($post)) {
- Logger::log("twitter_fetchparentposts: Can't fetch post " . $parameters->id, Logger::DEBUG);
+ Logger::log("twitter_fetchparentposts: Can't fetch post " . $parameters['id'], Logger::DEBUG);
break;
}
if (!empty($posts)) {
foreach ($posts as $post) {
- $postarray = twitter_createpost($a, $uid, $post, $self, false, false, false);
+ $postarray = twitter_createpost($a, $uid, $post, $self, false, !DI::pConfig()->get($uid, 'twitter', 'create_user'), false);
if (empty($postarray['body'])) {
continue;
{
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($uid, 'twitter', 'oauthtoken');
- $osecret = PConfig::get($uid, 'twitter', 'oauthsecret');
- $create_user = PConfig::get($uid, 'twitter', 'create_user');
- $mirror_posts = PConfig::get($uid, 'twitter', 'mirror_posts');
+ $otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
+ $create_user = DI::pConfig()->get($uid, 'twitter', 'create_user');
+ $mirror_posts = DI::pConfig()->get($uid, 'twitter', 'mirror_posts');
Logger::log("Fetching timeline for user " . $uid, Logger::DEBUG);
$application_name = Config::get('twitter', 'application_name');
if ($application_name == "") {
- $application_name = $a->getHostName();
+ $application_name = DI::baseUrl()->getHostname();
}
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
return;
}
- $parameters = ["exclude_replies" => false, "trim_user" => false, "contributor_details" => true, "include_rts" => true, "tweet_mode" => "extended"];
+ $parameters = ["exclude_replies" => false, "trim_user" => false, "contributor_details" => true, "include_rts" => true, "tweet_mode" => "extended", "include_ext_alt_text" => true];
//$parameters["count"] = 200;
// Fetching timeline
- $lastid = PConfig::get($uid, 'twitter', 'lasthometimelineid');
+ $lastid = DI::pConfig()->get($uid, 'twitter', 'lasthometimelineid');
$first_time = ($lastid == "");
foreach ($posts as $post) {
if ($post->id_str > $lastid) {
$lastid = $post->id_str;
- PConfig::set($uid, 'twitter', 'lasthometimelineid', $lastid);
+ DI::pConfig()->set($uid, 'twitter', 'lasthometimelineid', $lastid);
}
if ($first_time) {
Logger::log('User ' . $uid . ' posted home timeline item ' . $item);
}
}
- PConfig::set($uid, 'twitter', 'lasthometimelineid', $lastid);
+ DI::pConfig()->set($uid, 'twitter', 'lasthometimelineid', $lastid);
Logger::log('Last timeline ID for user ' . $uid . ' is now ' . $lastid, Logger::DEBUG);
// Fetching mentions
- $lastid = PConfig::get($uid, 'twitter', 'lastmentionid');
+ $lastid = DI::pConfig()->get($uid, 'twitter', 'lastmentionid');
$first_time = ($lastid == "");
twitter_fetchparentposts($a, $uid, $post, $connection, $self);
}
- $postarray = twitter_createpost($a, $uid, $post, $self, false, false, false);
+ $postarray = twitter_createpost($a, $uid, $post, $self, false, !$create_user, false);
if (empty($postarray['body'])) {
continue;
}
}
- PConfig::set($uid, 'twitter', 'lastmentionid', $lastid);
+ DI::pConfig()->set($uid, 'twitter', 'lastmentionid', $lastid);
Logger::log('Last mentions ID for user ' . $uid . ' is now ' . $lastid, Logger::DEBUG);
}
{
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($uid, 'twitter', 'oauthtoken');
- $osecret = PConfig::get($uid, 'twitter', 'oauthsecret');
+ $otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
- $own_id = PConfig::get($uid, 'twitter', 'own_id');
+ $own_id = DI::pConfig()->get($uid, 'twitter', 'own_id');
$contact_id = 0;
return false;
}
- PConfig::set($uid, 'twitter', 'own_id', $user->id_str);
+ DI::pConfig()->set($uid, 'twitter', 'own_id', $user->id_str);
$contact_id = twitter_fetch_contact($uid, $user, true);
} else {
$ckey = Config::get('twitter', 'consumerkey');
$csecret = Config::get('twitter', 'consumersecret');
- $otoken = PConfig::get($uid, 'twitter', 'oauthtoken');
- $osecret = PConfig::get($uid, 'twitter', 'oauthsecret');
+ $otoken = DI::pConfig()->get($uid, 'twitter', 'oauthtoken');
+ $osecret = DI::pConfig()->get($uid, 'twitter', 'oauthsecret');
$connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret);
$result = $connection->post('statuses/retweet/' . $id);
function twitter_convert_share(array $attributes, array $author_contact, $content, $is_quote_share)
{
if ($author_contact['network'] == Protocol::TWITTER) {
- $mention = '@' . $author_contact['nickname'];
+ $mention = '@' . $author_contact['nick'];
} else {
$mention = $author_contact['addr'];
}