diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/createsim.php | 142 | ||||
-rwxr-xr-x | scripts/getvaliddaemons.php | 12 | ||||
-rwxr-xr-x | scripts/maildaemon.php | 52 | ||||
-rwxr-xr-x | scripts/stopdaemons.sh | 2 | ||||
-rwxr-xr-x | scripts/synctwitterfriends.php | 277 | ||||
-rw-r--r-- | scripts/triminboxes.php | 40 | ||||
-rwxr-xr-x | scripts/twitterstatusfetcher.php | 319 | ||||
-rwxr-xr-x | scripts/xmppdaemon.php | 5 |
8 files changed, 536 insertions, 313 deletions
diff --git a/scripts/createsim.php b/scripts/createsim.php new file mode 100644 index 000000000..71827ba5b --- /dev/null +++ b/scripts/createsim.php @@ -0,0 +1,142 @@ +#!/usr/bin/env php +<?php +/* + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, 2009, Control Yourself, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); + +$shortoptions = 'u:n:b:t:x:'; +$longoptions = array('users=', 'notices=', 'subscriptions=', 'tags=', 'prefix='); + +$helptext = <<<END_OF_CREATESIM_HELP +Creates a lot of test users and notices to (loosely) simulate a real server. + + -u --users Number of users (default 100) + -n --notices Average notices per user (default 100) + -b --subscriptions Average subscriptions per user (default no. users/20) + -t --tags Number of distinct hash tags (default 10000) + -x --prefix User name prefix (default 'testuser') + +END_OF_CREATESIM_HELP; + +require_once INSTALLDIR.'/scripts/commandline.inc'; + +// XXX: make these command-line options + +function newUser($i) +{ + global $userprefix; + User::register(array('nickname' => sprintf('%s%d', $userprefix, $i), + 'password' => sprintf('password%d', $i), + 'fullname' => sprintf('Test User %d', $i))); +} + +function newNotice($i, $tagmax) +{ + global $userprefix; + + $n = rand(0, $i - 1); + $user = User::staticGet('nickname', sprintf('%s%d', $userprefix, $n)); + + $is_reply = rand(0, 4); + + $content = 'Test notice content'; + + if ($is_reply == 0) { + $n = rand(0, $i - 1); + $content = "@$userprefix$n " . $content; + } + + $has_hash = rand(0, 2); + + if ($has_hash == 0) { + $hashcount = rand(0, 2); + for ($j = 0; $j < $hashcount; $j++) { + $h = rand(0, $tagmax); + $content .= " #tag{$h}"; + } + } + + $notice = Notice::saveNew($user->id, $content, 'system'); +} + +function newSub($i) +{ + global $userprefix; + $f = rand(0, $i - 1); + + $fromnick = sprintf('%s%d', $userprefix, $f); + + $from = User::staticGet('nickname', $fromnick); + + if (empty($from)) { + throw new Exception("Can't find user '$fromnick'."); + } + + $t = rand(0, $i - 1); + + if ($t == $f) { + $t++; + if ($t > $i - 1) { + $t = 0; + } + } + + $tunic = sprintf('%s%d', $userprefix, $t); + + $to = User::staticGet('nickname', $tunic); + + if (empty($from)) { + throw new Exception("Can't find user '$tunic'."); + } + + subs_subscribe_to($from, $to); +} + +function main($usercount, $noticeavg, $subsavg, $tagmax) +{ + $n = 1; + + newUser(0); + + // # registrations + # notices + # subs + + $events = $usercount + ($usercount * ($noticeavg + $subsavg)); + + for ($i = 0; $i < $events; $i++) + { + $e = rand(0, 1 + $noticeavg + $subsavg); + + if ($e == 0) { + newUser($n); + $n++; + } else if ($e < $noticeavg + 1) { + newNotice($n, $tagmax); + } else { + newSub($n); + } + } +} + +$usercount = (have_option('u', 'users')) ? get_option_value('u', 'users') : 100; +$noticeavg = (have_option('n', 'notices')) ? get_option_value('n', 'notices') : 100; +$subsavg = (have_option('b', 'subscriptions')) ? get_option_value('b', 'subscriptions') : max($usercount/20, 10); +$tagmax = (have_option('t', 'tags')) ? get_option_value('t', 'tags') : 10000; +$userprefix = (have_option('x', 'prefix')) ? get_option_value('x', 'prefix') : 'testuser'; + +main($usercount, $noticeavg, $subsavg, $tagmax); diff --git a/scripts/getvaliddaemons.php b/scripts/getvaliddaemons.php index 97c230784..f1d8d8116 100755 --- a/scripts/getvaliddaemons.php +++ b/scripts/getvaliddaemons.php @@ -28,7 +28,8 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); $helptext = <<<ENDOFHELP -getvaliddaemons.php - print out the currently configured PID directory +getvaliddaemons.php - print out a list of valid daemons that should be started +by the startdaemons script ENDOFHELP; @@ -42,7 +43,12 @@ if(common_config('twitterbridge','enabled')) { echo "twitterstatusfetcher.php "; } echo "ombqueuehandler.php "; -echo "twitterqueuehandler.php "; +if (common_config('twitter', 'enabled')) { + echo "twitterqueuehandler.php "; + echo "synctwitterfriends.php "; +} echo "facebookqueuehandler.php "; echo "pingqueuehandler.php "; -echo "smsqueuehandler.php "; +if (common_config('sms', 'enabled')) { + echo "smsqueuehandler.php "; +} diff --git a/scripts/maildaemon.php b/scripts/maildaemon.php index 11ddf06b7..91c257adb 100755 --- a/scripts/maildaemon.php +++ b/scripts/maildaemon.php @@ -299,25 +299,43 @@ class MailerDaemon $attachments = array(); + $this->extract_part($parsed,$msg,$attachments); + + return array($from, $to, $msg, $attachments); + } + + function extract_part($parsed,&$msg,&$attachments){ if ($parsed->ctype_primary == 'multipart') { - foreach ($parsed->parts as $part) { - if ($part->ctype_primary == 'text' && - $part->ctype_secondary == 'plain') { - $msg = $part->body; - }else{ - if ($part->body) { - $attachment = tmpfile(); - fwrite($attachment, $part->body); - $attachments[] = $attachment; - } + if($parsed->ctype_secondary == 'alternative'){ + $altmsg = $this->extract_msg_from_multipart_alternative_part($parsed); + if(!empty($altmsg)) $msg = $altmsg; + }else{ + foreach($parsed->parts as $part){ + $this->extract_part($part,$msg,$attachments); } } - } else if ($type == 'text/plain') { + } else if ($parsed->ctype_primary == 'text' + && $parsed->ctype_secondary=='plain') { $msg = $parsed->body; - } else { - $this->unsupported_type($type); + if(strtolower($parsed->ctype_parameters['charset']) != "utf-8"){ + $msg = utf8_encode($msg); + } + }else if(!empty($parsed->body)){ + if(common_config('attachments', 'uploads')){ + //only save attachments if uploads are enabled + $attachment = tmpfile(); + fwrite($attachment, $parsed->body); + $attachments[] = $attachment; + } } - return array($from, $to, $msg, $attachments); + } + + function extract_msg_from_multipart_alternative_part($parsed){ + foreach ($parsed->parts as $part) { + $this->extract_part($part,$msg,$attachments); + } + //we don't want any attachments that are a result of this parsing + return $msg; } function unsupported_type($type) @@ -367,5 +385,7 @@ class MailerDaemon } } -$md = new MailerDaemon(); -$md->handle_message('php://stdin'); +if (common_config('emailpost', 'enabled')) { + $md = new MailerDaemon(); + $md->handle_message('php://stdin'); +} diff --git a/scripts/stopdaemons.sh b/scripts/stopdaemons.sh index 60ffd83ad..894e5aaff 100755 --- a/scripts/stopdaemons.sh +++ b/scripts/stopdaemons.sh @@ -25,7 +25,7 @@ DIR=`php $SDIR/getpiddir.php` for f in jabberhandler ombhandler publichandler smshandler pinghandler \ xmppconfirmhandler xmppdaemon twitterhandler facebookhandler \ - twitterstatusfetcher; do + twitterstatusfetcher synctwitterfriends; do FILES="$DIR/$f.*.pid" for ff in "$FILES" ; do diff --git a/scripts/synctwitterfriends.php b/scripts/synctwitterfriends.php index fe53ff44d..2de464bcc 100755 --- a/scripts/synctwitterfriends.php +++ b/scripts/synctwitterfriends.php @@ -20,85 +20,260 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -// Uncomment this to get useful console output +$shortoptions = 'di::'; +$longoptions = array('id::', 'debug'); + +$helptext = <<<END_OF_TRIM_HELP +Batch script for synching local friends with Twitter friends. + -i --id Identity (default 'generic') + -d --debug Debug (lots of log output) + +END_OF_TRIM_HELP; + +require_once INSTALLDIR . '/scripts/commandline.inc'; +require_once INSTALLDIR . '/lib/parallelizingdaemon.php'; + +/** + * Daemon to sync local friends with Twitter friends + * + * @category Twitter + * @package Laconica + * @author Zach Copley <zach@controlyourself.ca> + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ $helptext = <<<END_OF_TWITTER_HELP Batch script for synching local friends with Twitter friends. END_OF_TWITTER_HELP; -require_once INSTALLDIR.'/scripts/commandline.inc'; +require_once INSTALLDIR . '/scripts/commandline.inc'; +require_once INSTALLDIR . '/lib/parallelizingdaemon.php'; -// Make a lockfile -$lockfilename = lockFilename(); -if (!($lockfile = @fopen($lockfilename, "w"))) { - print "Already running... exiting.\n"; - exit(1); -} +class SyncTwitterFriendsDaemon extends ParallelizingDaemon +{ + /** + * Constructor + * + * @param string $id the name/id of this daemon + * @param int $interval sleep this long before doing everything again + * @param int $max_children maximum number of child processes at a time + * @param boolean $debug debug output flag + * + * @return void + * + **/ -// Obtain an exlcusive lock on file (will fail if script is already going) -if (!@flock( $lockfile, LOCK_EX | LOCK_NB, &$wouldblock) || $wouldblock) { - // Script already running - abort - @fclose($lockfile); - print "Already running... exiting.\n"; - exit(1); -} + function __construct($id = null, $interval = 60, + $max_children = 2, $debug = null) + { + parent::__construct($id, $interval, $max_children, $debug); + } -$flink = new Foreign_link(); -$flink->service = 1; // Twitter -$flink->orderBy('last_friendsync'); -$flink->limit(25); // sync this many users during this run -$cnt = $flink->find(); + /** + * Name of this daemon + * + * @return string Name of the daemon. + */ -print "Updating Twitter friends subscriptions for $cnt users.\n"; + function name() + { + return ('synctwitterfriends.' . $this->_id); + } -while ($flink->fetch()) { + /** + * Find all the Twitter foreign links for users who have requested + * automatically subscribing to their Twitter friends locally. + * + * @return array flinks an array of Foreign_link objects + */ + function getObjects() + { + $flinks = array(); + $flink = new Foreign_link(); - if (($flink->friendsync & FOREIGN_FRIEND_RECV) == FOREIGN_FRIEND_RECV) { + $conn = &$flink->getDatabaseConnection(); - $user = User::staticGet($flink->user_id); + $flink->service = TWITTER_SERVICE; + $flink->orderBy('last_friendsync'); + $flink->limit(25); // sync this many users during this run + $flink->find(); - if (empty($user)) { - common_log(LOG_WARNING, "Unmatched user for ID " . $flink->user_id); - print "Unmatched user for ID $flink->user_id\n"; - continue; + while ($flink->fetch()) { + if (($flink->friendsync & FOREIGN_FRIEND_RECV) == FOREIGN_FRIEND_RECV) { + $flinks[] = clone($flink); + } } - print "Updating Twitter friends for $user->nickname (Laconica ID: $user->id)... "; + $conn->disconnect(); - $fuser = $flink->getForeignUser(); + global $_DB_DATAOBJECT; + unset($_DB_DATAOBJECT['CONNECTIONS']); - if (empty($fuser)) { - common_log(LOG_WARNING, "Unmatched user for ID " . $flink->user_id); - print "Unmatched user for ID $flink->user_id\n"; - continue; - } + return $flinks; + } + + function childTask($flink) { - save_twitter_friends($user, $fuser->id, $fuser->nickname, $flink->credentials); + // Each child ps needs its own DB connection + + // Note: DataObject::getDatabaseConnection() creates + // a new connection if there isn't one already + + $conn = &$flink->getDatabaseConnection(); + + $this->subscribeTwitterFriends($flink); $flink->last_friendsync = common_sql_now(); $flink->update(); - if (defined('SCRIPT_DEBUG')) { - print "\nDONE\n"; - } else { - print "DONE\n"; + $conn->disconnect(); + + // XXX: Couldn't find a less brutal way to blow + // away a cached connection + + global $_DB_DATAOBJECT; + unset($_DB_DATAOBJECT['CONNECTIONS']); + } + + function fetchTwitterFriends($flink) + { + $friends = array(); + + $token = TwitterOAuthClient::unpackToken($flink->credentials); + + $client = new TwitterOAuthClient($token->key, $token->secret); + + try { + $friends_ids = $client->friendsIds(); + } catch (OAuthCurlException $e) { + common_log(LOG_WARNING, $this->name() . + ' - cURL error getting friend ids ' . + $e->getCode() . ' - ' . $e->getMessage()); + return $friends; + } + + if (empty($friends_ids)) { + common_debug($this->name() . + " - Twitter user $flink->foreign_id " . + 'doesn\'t have any friends!'); + return $friends; + } + + common_debug($this->name() . ' - Twitter\'s API says Twitter user id ' . + "$flink->foreign_id has " . + count($friends_ids) . ' friends.'); + + // Calculate how many pages to get... + $pages = ceil(count($friends_ids) / 100); + + if ($pages == 0) { + common_debug($this->name() . " - $user seems to have no friends."); + } + + for ($i = 1; $i <= $pages; $i++) { + + try { + $more_friends = $client->statusesFriends(null, null, null, $i); + } catch (OAuthCurlException $e) { + common_log(LOG_WARNING, $this->name() . + ' - cURL error getting Twitter statuses/friends ' . + "page $i - " . $e->getCode() . ' - ' . + $e->getMessage()); } + + if (empty($more_friends)) { + common_log(LOG_WARNING, $this->name() . + " - Couldn't retrieve page $i " . + "of Twitter user $flink->foreign_id friends."); + continue; + } else { + $friends = array_merge($friends, $more_friends); + } + } + + return $friends; } -} -function lockFilename() -{ - $piddir = common_config('daemon', 'piddir'); - if (!$piddir) { - $piddir = '/var/run'; + function subscribeTwitterFriends($flink) + { + $friends = $this->fetchTwitterFriends($flink); + + if (empty($friends)) { + common_debug($this->name() . + ' - Couldn\'t get friends from Twitter for ' . + "Twitter user $flink->foreign_id."); + return false; + } + + $user = $flink->getUser(); + + foreach ($friends as $friend) { + + $friend_name = $friend->screen_name; + $friend_id = (int) $friend->id; + + // Update or create the Foreign_user record for each + // Twitter friend + + if (!save_twitter_user($friend_id, $friend_name)) { + common_log(LOG_WARNING, $this-name() . + " - Couldn't save $screen_name's friend, $friend_name."); + continue; + } + + // Check to see if there's a related local user + + $friend_flink = Foreign_link::getByForeignID($friend_id, + TWITTER_SERVICE); + + if (!empty($friend_flink)) { + + // Get associated user and subscribe her + + $friend_user = User::staticGet('id', $friend_flink->user_id); + + if (!empty($friend_user)) { + $result = subs_subscribe_to($user, $friend_user); + + if ($result === true) { + common_log(LOG_INFO, + $this->name() . ' - Subscribed ' . + "$friend_user->nickname to $user->nickname."); + } else { + common_debug($this->name() . + ' - Tried subscribing ' . + "$friend_user->nickname to $user->nickname - " . + $result); + } + } + } + } + + return true; } - return $piddir . '/synctwitterfriends.lock'; } -// Cleanup -fclose($lockfile); -unlink($lockfilename); +$id = null; +$debug = null; + +if (have_option('i')) { + $id = get_option_value('i'); +} else if (have_option('--id')) { + $id = get_option_value('--id'); +} else if (count($args) > 0) { + $id = $args[0]; +} else { + $id = null; +} + +if (have_option('d') || have_option('debug')) { + $debug = true; +} + +$syncer = new SyncTwitterFriendsDaemon($id, 60, 2, $debug); +$syncer->runOnce(); -exit(0); diff --git a/scripts/triminboxes.php b/scripts/triminboxes.php index b2135d682..27e200fef 100644 --- a/scripts/triminboxes.php +++ b/scripts/triminboxes.php @@ -52,43 +52,5 @@ if (!empty($id)) { $cnt = $user->find(); while ($user->fetch()) { - - $inbox_entry = new Notice_inbox(); - $inbox_entry->user_id = $user->id; - $inbox_entry->orderBy('created DESC'); - $inbox_entry->limit(1000, 1); - - $id = null; - - if ($inbox_entry->find(true)) { - $id = $inbox_entry->notice_id; - } - - $inbox_entry->free(); - unset($inbox_entry); - - if (is_null($id)) { - continue; - } - - $start = microtime(true); - - $old_inbox = new Notice_inbox(); - $cnt = $old_inbox->query('DELETE from notice_inbox WHERE user_id = ' . $user->id . ' AND notice_id < ' . $id); - $old_inbox->free(); - unset($old_inbox); - - print "Deleted $cnt notices for $user->nickname ($user->id).\n"; - - $finish = microtime(true); - - $delay = 3.0 * ($finish - $start); - - print "Delaying $delay seconds..."; - - // Wait to let slaves catch up - - usleep($delay * 1000000); - - print "DONE.\n"; + Notice_inbox::gc($user->id); } diff --git a/scripts/twitterstatusfetcher.php b/scripts/twitterstatusfetcher.php index 4a1ed8977..f5289c5f4 100755 --- a/scripts/twitterstatusfetcher.php +++ b/scripts/twitterstatusfetcher.php @@ -25,19 +25,18 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); define('MAXCHILDREN', 2); define('POLL_INTERVAL', 60); // in seconds -$shortoptions = 'i::'; -$longoptions = array('id::'); +$shortoptions = 'di::'; +$longoptions = array('id::', 'debug'); $helptext = <<<END_OF_TRIM_HELP Batch script for retrieving Twitter messages from foreign service. - -i --id Identity (default 'generic') + -i --id Identity (default 'generic') + -d --debug Debug (lots of log output) END_OF_TRIM_HELP; -require_once INSTALLDIR.'/scripts/commandline.inc'; - -require_once INSTALLDIR . '/lib/common.php'; +require_once INSTALLDIR .'/scripts/commandline.inc'; require_once INSTALLDIR . '/lib/daemon.php'; /** @@ -57,9 +56,24 @@ require_once INSTALLDIR . '/lib/daemon.php'; // NOTE: an Avatar path MUST be set in config.php for this // script to work: e.g.: $config['avatar']['path'] = '/laconica/avatar'; -class TwitterStatusFetcher extends Daemon +class TwitterStatusFetcher extends ParallelizingDaemon { - private $_children = array(); + /** + * Constructor + * + * @param string $id the name/id of this daemon + * @param int $interval sleep this long before doing everything again + * @param int $max_children maximum number of child processes at a time + * @param boolean $debug debug output flag + * + * @return void + * + **/ + function __construct($id = null, $interval = 60, + $max_children = 2, $debug = null) + { + parent::__construct($id, $interval, $max_children, $debug); + } /** * Name of this daemon @@ -73,121 +87,22 @@ class TwitterStatusFetcher extends Daemon } /** - * Run the daemon + * Find all the Twitter foreign links for users who have requested + * importing of their friends' timelines * - * @return void + * @return array flinks an array of Foreign_link objects */ - function run() + function getObjects() { - do { - - $flinks = $this->refreshFlinks(); - - foreach ($flinks as $f) { - - // We have to disconnect from the DB before forking so - // each sub-process will open its own connection and - // avoid stomping on the others - - $conn = &$f->getDatabaseConnection(); - $conn->disconnect(); - - $pid = pcntl_fork(); - - if ($pid == -1) { - die ("Couldn't fork!"); - } - - if ($pid) { - - // Parent - if (defined('SCRIPT_DEBUG')) { - common_debug("Parent: forked new status ". - " fetcher process " . $pid); - } - - $this->_children[] = $pid; - - } else { - - // Child - $this->getTimeline($f); - exit(); - } - - // Remove child from ps list as it finishes - while (($c = pcntl_wait($status, WNOHANG OR WUNTRACED)) > 0) { - - if (defined('SCRIPT_DEBUG')) { - common_debug("Child $c finished."); - } - - $this->removePs($this->_children, $c); - } + global $_DB_DATAOBJECT; - // Wait! We have too many damn kids. - if (sizeof($this->_children) > MAXCHILDREN) { - - if (defined('SCRIPT_DEBUG')) { - common_debug('Too many children. Waiting...'); - } - - if (($c = pcntl_wait($status, WUNTRACED)) > 0) { - - if (defined('SCRIPT_DEBUG')) { - common_debug("Finished waiting for $c"); - } - - $this->removePs($this->_children, $c); - } - } - } - - // Remove all children from the process list before restarting - while (($c = pcntl_wait($status, WUNTRACED)) > 0) { - - if (defined('SCRIPT_DEBUG')) { - common_debug("Child $c finished."); - } - - $this->removePs($this->_children, $c); - } - - // Rest for a bit before we fetch more statuses - - if (defined('SCRIPT_DEBUG')) { - common_debug('Waiting ' . POLL_INTERVAL . - ' secs before hitting Twitter again.'); - } - - if (POLL_INTERVAL > 0) { - sleep(POLL_INTERVAL); - } - - } while (true); - } - - /** - * Refresh the foreign links for this user - * - * @return void - */ - - function refreshFlinks() - { $flink = new Foreign_link(); + $conn = &$flink->getDatabaseConnection(); - $flink->service = 1; // Twitter - + $flink->service = TWITTER_SERVICE; $flink->orderBy('last_noticesync'); - - $cnt = $flink->find(); - - if (defined('SCRIPT_DEBUG')) { - common_debug('Updating Twitter friends subscriptions' . - " for $cnt users."); - } + $flink->find(); $flinks = array(); @@ -202,78 +117,81 @@ class TwitterStatusFetcher extends Daemon $flink->free(); unset($flink); + $conn->disconnect(); + unset($_DB_DATAOBJECT['CONNECTIONS']); + return $flinks; } - /** - * Unknown - * - * @param array &$plist unknown. - * @param string $ps unknown. - * - * @return unknown - * @todo document - */ + function childTask($flink) { - function removePs(&$plist, $ps) - { - for ($i = 0; $i < sizeof($plist); $i++) { - if ($plist[$i] == $ps) { - unset($plist[$i]); - $plist = array_values($plist); - break; - } - } + // Each child ps needs its own DB connection + + // Note: DataObject::getDatabaseConnection() creates + // a new connection if there isn't one already + + $conn = &$flink->getDatabaseConnection(); + + $this->getTimeline($flink); + + $flink->last_friendsync = common_sql_now(); + $flink->update(); + + $conn->disconnect(); + + // XXX: Couldn't find a less brutal way to blow + // away a cached connection + + global $_DB_DATAOBJECT; + unset($_DB_DATAOBJECT['CONNECTIONS']); } function getTimeline($flink) { - if (empty($flink)) { - common_log(LOG_WARNING, - "Can't retrieve Foreign_link for foreign ID $fid"); + if (empty($flink)) { + common_log(LOG_WARNING, $this->name() . + " - Can't retrieve Foreign_link for foreign ID $fid"); return; } - $fuser = $flink->getForeignUser(); - - if (empty($fuser)) { - common_log(LOG_WARNING, "Unmatched user for ID " . - $flink->user_id); - return; - } - - if (defined('SCRIPT_DEBUG')) { - common_debug('Trying to get timeline for Twitter user ' . - "$fuser->nickname ($flink->foreign_id)."); - } + common_debug($this->name() . ' - Trying to get timeline for Twitter user ' . + $flink->foreign_id); // XXX: Biggest remaining issue - How do we know at which status // to start importing? How many statuses? Right now I'm going // with the default last 20. - $url = 'http://twitter.com/statuses/friends_timeline.json'; + $token = TwitterOAuthClient::unpackToken($flink->credentials); - $timeline_json = get_twitter_data($url, $fuser->nickname, - $flink->credentials); + $client = new TwitterOAuthClient($token->key, $token->secret); - $timeline = json_decode($timeline_json); + $timeline = null; + + try { + $timeline = $client->statusesFriendsTimeline(); + } catch (OAuthClientCurlException $e) { + common_log(LOG_WARNING, $this->name() . + ' - OAuth client unable to get friends timeline for user ' . + $flink->user_id . ' - code: ' . + $e->getCode() . 'msg: ' . $e->getMessage()); + } if (empty($timeline)) { - common_log(LOG_WARNING, "Empty timeline."); + common_log(LOG_WARNING, $this->name() . " - Empty timeline."); return; } // Reverse to preserve order + foreach (array_reverse($timeline) as $status) { // Hacktastic: filter out stuff coming from this Laconica + $source = mb_strtolower(common_config('integration', 'source')); if (preg_match("/$source/", mb_strtolower($status->source))) { - if (defined('SCRIPT_DEBUG')) { - common_debug('Skipping import of status ' . $status->id . - ' with source ' . $source); - } + common_debug($this->name() . ' - Skipping import of status ' . + $status->id . ' with source ' . $source); continue; } @@ -281,6 +199,7 @@ class TwitterStatusFetcher extends Daemon } // Okay, record the time we synced with Twitter for posterity + $flink->last_noticesync = common_sql_now(); $flink->update(); } @@ -288,11 +207,12 @@ class TwitterStatusFetcher extends Daemon function saveStatus($status, $flink) { $id = $this->ensureProfile($status->user); + $profile = Profile::staticGet($id); - if (!$profile) { - common_log(LOG_ERR, - 'Problem saving notice. No associated Profile.'); + if (empty($profile)) { + common_log(LOG_ERR, $this->name() . + ' - Problem saving notice. No associated Profile.'); return null; } @@ -305,7 +225,7 @@ class TwitterStatusFetcher extends Daemon // check to see if we've already imported the status - if (!$notice) { + if (empty($notice)) { $notice = new Notice(); @@ -316,7 +236,7 @@ class TwitterStatusFetcher extends Daemon $notice->content = common_shorten_links($status->text); // XXX $notice->rendered = common_render_content($notice->content, $notice); $notice->source = 'twitter'; - $notice->reply_to = null; // XXX lookup reply + $notice->reply_to = null; // XXX: lookup reply $notice->is_local = Notice::GATEWAY; if (Event::handle('StartNoticeSave', array(&$notice))) { @@ -342,24 +262,22 @@ class TwitterStatusFetcher extends Daemon function ensureProfile($user) { // check to see if there's already a profile for this user + $profileurl = 'http://twitter.com/' . $user->screen_name; $profile = Profile::staticGet('profileurl', $profileurl); - if ($profile) { - if (defined('SCRIPT_DEBUG')) { - common_debug("Profile for $profile->nickname found."); - } + if (!empty($profile)) { + common_debug($this->name() . + " - Profile for $profile->nickname found."); // Check to see if the user's Avatar has changed - $this->checkAvatar($user, $profile); + $this->checkAvatar($user, $profile); return $profile->id; } else { - if (defined('SCRIPT_DEBUG')) { - common_debug('Adding profile and remote profile ' . - "for Twitter user: $profileurl"); - } + common_debug($this->name() . ' - Adding profile and remote profile ' . + "for Twitter user: $profileurl."); $profile = new Profile(); $profile->query("BEGIN"); @@ -381,9 +299,10 @@ class TwitterStatusFetcher extends Daemon } // check for remote profile + $remote_pro = Remote_profile::staticGet('uri', $profileurl); - if (!$remote_pro) { + if (empty($remote_pro)) { $remote_pro = new Remote_profile(); @@ -420,23 +339,18 @@ class TwitterStatusFetcher extends Daemon $oldname = $profile->getAvatar(48)->filename; if ($newname != $oldname) { - - if (defined('SCRIPT_DEBUG')) { - common_debug('Avatar for Twitter user ' . - "$profile->nickname has changed."); - common_debug("old: $oldname new: $newname"); - } + common_debug($this->name() . ' - Avatar for Twitter user ' . + "$profile->nickname has changed."); + common_debug($this->name() . " - old: $oldname new: $newname"); $this->updateAvatars($twitter_user, $profile); } if ($this->missingAvatarFile($profile)) { - - if (defined('SCRIPT_DEBUG')) { - common_debug('Twitter user ' . $profile->nickname . - ' is missing one or more local avatars.'); - common_debug("old: $oldname new: $newname"); - } + common_debug($this->name() . ' - Twitter user ' . + $profile->nickname . + ' is missing one or more local avatars.'); + common_debug($this->name() ." - old: $oldname new: $newname"); $this->updateAvatars($twitter_user, $profile); } @@ -516,23 +430,20 @@ class TwitterStatusFetcher extends Daemon if ($this->fetchAvatar($url, $filename)) { $this->newAvatar($id, $size, $mediatype, $filename); } else { - common_log(LOG_WARNING, "Problem fetching Avatar: $url", __FILE__); + common_log(LOG_WARNING, $this->id() . + " - Problem fetching Avatar: $url"); } } } function updateAvatar($profile_id, $size, $mediatype, $filename) { - if (defined('SCRIPT_DEBUG')) { - common_debug("Updating avatar: $size"); - } + common_debug($this->name() . " - Updating avatar: $size"); $profile = Profile::staticGet($profile_id); if (empty($profile)) { - if (defined('SCRIPT_DEBUG')) { - common_debug("Couldn't get profile: $profile_id!"); - } + common_debug($this->name() . " - Couldn't get profile: $profile_id!"); return; } @@ -540,6 +451,7 @@ class TwitterStatusFetcher extends Daemon $avatar = $profile->getAvatar($sizes[$size]); // Delete the avatar, if present + if ($avatar) { $avatar->delete(); } @@ -577,9 +489,7 @@ class TwitterStatusFetcher extends Daemon $avatar->filename = $filename; $avatar->url = Avatar::url($filename); - if (defined('SCRIPT_DEBUG')) { - common_debug("new filename: $avatar->url"); - } + common_debug($this->name() . " - New filename: $avatar->url"); $avatar->created = common_sql_now(); @@ -590,9 +500,8 @@ class TwitterStatusFetcher extends Daemon return null; } - if (defined('SCRIPT_DEBUG')) { - common_debug("Saved new $size avatar for $profile_id."); - } + common_debug($this->name() . + " - Saved new $size avatar for $profile_id."); return $id; } @@ -605,13 +514,12 @@ class TwitterStatusFetcher extends Daemon $out = fopen($avatarfile, 'wb'); if (!$out) { - common_log(LOG_WARNING, "Couldn't open file $filename", __FILE__); + common_log(LOG_WARNING, $this->name() . + " - Couldn't open file $filename"); return false; } - if (defined('SCRIPT_DEBUG')) { - common_debug("Fetching avatar: $url"); - } + common_debug($this->name() . " - Fetching Twitter avatar: $url"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); @@ -628,7 +536,8 @@ class TwitterStatusFetcher extends Daemon } } -declare(ticks = 1); +$id = null; +$debug = null; if (have_option('i')) { $id = get_option_value('i'); @@ -640,6 +549,10 @@ if (have_option('i')) { $id = null; } -$fetcher = new TwitterStatusFetcher($id); +if (have_option('d') || have_option('debug')) { + $debug = true; +} + +$fetcher = new TwitterStatusFetcher($id, 60, 2, $debug); $fetcher->runOnce(); diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index 488b4b514..69512f243 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -175,6 +175,10 @@ class XMPPDaemon extends Daemon $user = $this->get_user($from); + // For common_current_user to work + global $_cur; + $_cur = $user; + if (!$user) { $this->from_site($from, 'Unknown user; go to ' . common_local_url('imsettings') . @@ -211,6 +215,7 @@ class XMPPDaemon extends Daemon $user->free(); unset($user); + unset($_cur); unset($pl['xml']); $pl['xml'] = null; |