From 9d42137024027eeded76016d4708439395983870 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 30 Apr 2013 09:56:14 -0400 Subject: [PATCH 1/6] Make optional arguments for getNoticeIds explicit --- lib/profilenoticestream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/profilenoticestream.php b/lib/profilenoticestream.php index f7154a52be..0cf088a702 100644 --- a/lib/profilenoticestream.php +++ b/lib/profilenoticestream.php @@ -62,7 +62,7 @@ class ProfileNoticeStream extends ScopingNoticeStream $userProfile); } - function getNoticeIds($offset, $limit, $since_id, $max_id) + function getNoticeIds($offset, $limit, $sinceId = null, $maxId = null) { if ($this->impossibleStream()) { return array(); From bf1868450900736ebf3b717634ea5269c1fad7dd Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 24 May 2013 09:19:17 -0400 Subject: [PATCH 2/6] More aggressively avoid OOM errors in useractivitystream --- lib/useractivitystream.php | 67 ++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/lib/useractivitystream.php b/lib/useractivitystream.php index d1e3e28fb8..bd26d38ee0 100644 --- a/lib/useractivitystream.php +++ b/lib/useractivitystream.php @@ -67,6 +67,7 @@ class UserActivityStream extends AtomUserNoticeFeed // Assume that everything but notices is feasible // to pull at once and work with in memory... + $subscriptions = $this->getSubscriptions(); $subscribers = $this->getSubscribers(); $groups = $this->getGroups(); @@ -74,15 +75,24 @@ class UserActivityStream extends AtomUserNoticeFeed $objs = array_merge($subscriptions, $subscribers, $groups, $faves, $notices); + $subscriptions = null; + $subscribers = null; + $groups = null; + $faves = null; + + unset($subscriptions); + unset($subscribers); + unset($groups); + unset($faves); + // Sort by create date usort($objs, 'UserActivityStream::compareObject'); // We'll keep these around for later, and interleave them into // the output stream with the user's notices. - foreach ($objs as $obj) { - $this->activities[] = $obj->asActivity(); - } + + $this->objs = $objs; } /** @@ -92,29 +102,66 @@ class UserActivityStream extends AtomUserNoticeFeed function renderEntries() { $end = time() + 1; - foreach ($this->activities as $act) { + $i = 0; + foreach ($this->objs as $obj) { + $i++; + try { + $act = $obj->asActivity(); + } catch (Exception $e) { + common_log(LOG_ERR, $e->getMessage()); + continue; + } + $start = $act->time; if ($this->outputMode == self::OUTPUT_RAW && $start != $end) { // In raw mode, we haven't pre-fetched notices. // Grab the chunks of notices between other activities. - $notices = $this->getNoticesBetween($start, $end); - foreach ($notices as $noticeAct) { - $noticeAct->asActivity()->outputTo($this, false, false); + try { + $notices = $this->getNoticesBetween($start, $end); + foreach ($notices as $noticeAct) { + try { + $nact = $noticeAct->asActivity(); + $nact->outputTo($this, false, false); + } catch (Exception $e) { + common_log(LOG_ERR, $e->getMessage()); + continue; + } + $nact = null; + unset($nact); + } + } catch (Exception $e) { + common_log(LOG_ERR, $e->getMessage()); } } + $notices = null; + unset($notices); + // Only show the author sub-element if it's different from default user $act->outputTo($this, false, ($act->actor->id != $this->user->uri)); + $act = null; + unset($act); + $end = $start; } if ($this->outputMode == self::OUTPUT_RAW) { // Grab anything after the last pre-sorted activity. - $notices = $this->getNoticesBetween(0, $end); - foreach ($notices as $noticeAct) { - $noticeAct->asActivity()->outputTo($this, false, false); + try { + $notices = $this->getNoticesBetween(0, $end); + foreach ($notices as $noticeAct) { + try { + $nact = $noticeAct->asActivity(); + $nact->outputTo($this, false, false); + } catch (Exception $e) { + common_log(LOG_ERR, $e->getMessage()); + continue; + } + } + } catch (Exception $e) { + common_log(LOG_ERR, $e->getMessage()); } } } From b359854150c58937e57c81c91ec927bb5253fe54 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 24 May 2013 09:26:58 -0400 Subject: [PATCH 3/6] Throw an exception converting fave to activity for non-existent notice or profile --- classes/Fave.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/classes/Fave.php b/classes/Fave.php index 59a1e00318..455e7b089c 100644 --- a/classes/Fave.php +++ b/classes/Fave.php @@ -124,9 +124,18 @@ class Fave extends Managed_DataObject function asActivity() { - $notice = Notice::staticGet('id', $this->notice_id); + $notice = Notice::staticGet('id', $this->notice_id); + + if (!$notice) { + throw new Exception("Fave for non-existent notice: " . $this->notice_id); + } + $profile = Profile::staticGet('id', $this->user_id); + if (!$profile) { + throw new Exception("Fave by non-existent profile: " . $this->user_id); + } + $act = new Activity(); $act->verb = ActivityVerb::FAVORITE; From 4f818c5c81148ccb5552fa2618ee9a93a44ee4ec Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 24 May 2013 13:50:24 -0400 Subject: [PATCH 4/6] Add JSON output for backups --- lib/useractivitystream.php | 36 +++++++++++++++++++++++++++++------- scripts/backupuser.php | 12 ++++++++---- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/useractivitystream.php b/lib/useractivitystream.php index bd26d38ee0..82f0be0504 100644 --- a/lib/useractivitystream.php +++ b/lib/useractivitystream.php @@ -99,12 +99,10 @@ class UserActivityStream extends AtomUserNoticeFeed * Interleave the pre-sorted subs/groups/faves with the user's * notices, all in reverse chron order. */ - function renderEntries() + function renderEntries($format=Feed::ATOM, $handle=null) { $end = time() + 1; - $i = 0; foreach ($this->objs as $obj) { - $i++; try { $act = $obj->asActivity(); } catch (Exception $e) { @@ -122,7 +120,11 @@ class UserActivityStream extends AtomUserNoticeFeed foreach ($notices as $noticeAct) { try { $nact = $noticeAct->asActivity(); - $nact->outputTo($this, false, false); + if ($format == Feed::ATOM) { + $nact->outputTo($this, false, false); + } else { + fwrite($handle, json_encode($nact->asArray())); + } } catch (Exception $e) { common_log(LOG_ERR, $e->getMessage()); continue; @@ -138,8 +140,16 @@ class UserActivityStream extends AtomUserNoticeFeed $notices = null; unset($notices); - // Only show the author sub-element if it's different from default user - $act->outputTo($this, false, ($act->actor->id != $this->user->uri)); + try { + if ($format == Feed::ATOM) { + // Only show the author sub-element if it's different from default user + $act->outputTo($this, false, ($act->actor->id != $this->user->uri)); + } else { + fwrite($handle, json_encode($act->asArray())); + } + } catch (Exception $e) { + common_log(LOG_ERR, $e->getMessage()); + } $act = null; unset($act); @@ -154,7 +164,11 @@ class UserActivityStream extends AtomUserNoticeFeed foreach ($notices as $noticeAct) { try { $nact = $noticeAct->asActivity(); - $nact->outputTo($this, false, false); + if ($format == Feed::ATOM) { + $nact->outputTo($this, false, false); + } else { + fwrite($handle, json_encode($nact->asArray())); + } } catch (Exception $e) { common_log(LOG_ERR, $e->getMessage()); continue; @@ -284,4 +298,12 @@ class UserActivityStream extends AtomUserNoticeFeed return $groups; } + + function writeJSON($handle) + { + require_once INSTALLDIR.'/lib/activitystreamjsondocument.php'; + fwrite($handle, '{"items": ['); + $this->renderEntries(Feed::JSON, $handle); + fwrite($handle, ']'); + } } diff --git a/scripts/backupuser.php b/scripts/backupuser.php index ee2951fc8f..d183dba2b9 100644 --- a/scripts/backupuser.php +++ b/scripts/backupuser.php @@ -19,8 +19,8 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -$shortoptions = 'i:n:f:'; -$longoptions = array('id=', 'nickname=', 'file='); +$shortoptions = 'i:n:f:j'; +$longoptions = array('id=', 'nickname=', 'file=', 'json'); $helptext = <<getString(); + if (have_option('j', 'json')) { + $actstr->writeJSON(STDOUT); + } else { + print $actstr->getString(); + } } catch (Exception $e) { print $e->getMessage()."\n"; exit(1); From 2f5cdbb9c18f5605c979892836d152b1e48e04d6 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 29 May 2013 16:45:52 -0400 Subject: [PATCH 5/6] Correctly output commas for JSON backups --- lib/useractivitystream.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/useractivitystream.php b/lib/useractivitystream.php index 82f0be0504..962ef77bd5 100644 --- a/lib/useractivitystream.php +++ b/lib/useractivitystream.php @@ -101,6 +101,8 @@ class UserActivityStream extends AtomUserNoticeFeed */ function renderEntries($format=Feed::ATOM, $handle=null) { + $haveOne = false; + $end = time() + 1; foreach ($this->objs as $obj) { try { @@ -123,7 +125,11 @@ class UserActivityStream extends AtomUserNoticeFeed if ($format == Feed::ATOM) { $nact->outputTo($this, false, false); } else { + if ($haveOne) { + fwrite($handle, ","); + } fwrite($handle, json_encode($nact->asArray())); + $haveOne = true; } } catch (Exception $e) { common_log(LOG_ERR, $e->getMessage()); @@ -145,7 +151,11 @@ class UserActivityStream extends AtomUserNoticeFeed // Only show the author sub-element if it's different from default user $act->outputTo($this, false, ($act->actor->id != $this->user->uri)); } else { + if ($haveOne) { + fwrite($handle, ","); + } fwrite($handle, json_encode($act->asArray())); + $haveOne = true; } } catch (Exception $e) { common_log(LOG_ERR, $e->getMessage()); @@ -167,7 +177,11 @@ class UserActivityStream extends AtomUserNoticeFeed if ($format == Feed::ATOM) { $nact->outputTo($this, false, false); } else { + if ($haveOne) { + fwrite($handle, ","); + } fwrite($handle, json_encode($nact->asArray())); + $haveOne = true; } } catch (Exception $e) { common_log(LOG_ERR, $e->getMessage()); From 2a3abf8850981db4718dd0edca62767e7601737c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 29 May 2013 17:03:08 -0400 Subject: [PATCH 6/6] Close the collection object --- lib/useractivitystream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/useractivitystream.php b/lib/useractivitystream.php index 962ef77bd5..5422afc2c0 100644 --- a/lib/useractivitystream.php +++ b/lib/useractivitystream.php @@ -318,6 +318,6 @@ class UserActivityStream extends AtomUserNoticeFeed require_once INSTALLDIR.'/lib/activitystreamjsondocument.php'; fwrite($handle, '{"items": ['); $this->renderEntries(Feed::JSON, $handle); - fwrite($handle, ']'); + fwrite($handle, ']}'); } }