From 2c677e0f2d881f0c9f5713fcbc37ad24ef0dab26 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 1 Mar 2010 18:49:39 -0500 Subject: [PATCH 01/22] Revert "show service debug info" This reverts commit 19ec0e3a62d4c60d7e5581b4e38ec705650b1d18. --- lib/omb.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/omb.php b/lib/omb.php index 8bbe5e8aac..db60fa0ef2 100644 --- a/lib/omb.php +++ b/lib/omb.php @@ -144,9 +144,6 @@ function omb_broadcast_profile($profile) $service = new StatusNet_OMB_Service_Consumer( array(OMB_ENDPOINT_UPDATEPROFILE => $rp->updateprofileurl), $rp->uri); - - common_debug('service = ' . print_r($service, true)); - try { $service->setToken($rp->token, $rp->secret); $service->updateProfile($omb_profile); From c38ed1bb194ebba9ec73d0b4cde28ea4fb0bd001 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 1 Mar 2010 18:46:34 -0800 Subject: [PATCH 02/22] High-priority OStatus fixes: * PuSHing out to multiple client services could fail; only first callback got reached * Correction for re-sub request to a known sub --- plugins/OStatus/actions/pushhub.php | 2 +- plugins/OStatus/classes/HubSub.php | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/OStatus/actions/pushhub.php b/plugins/OStatus/actions/pushhub.php index f33690bc49..842d65e7d2 100644 --- a/plugins/OStatus/actions/pushhub.php +++ b/plugins/OStatus/actions/pushhub.php @@ -104,7 +104,7 @@ class PushHubAction extends Action throw new ClientException("Invalid hub.secret $secret; must be under 200 bytes."); } - $sub = HubSub::staticGet($sub->topic, $sub->callback); + $sub = HubSub::staticGet($topic, $callback); if (!$sub) { // Creating a new one! $sub = new HubSub(); diff --git a/plugins/OStatus/classes/HubSub.php b/plugins/OStatus/classes/HubSub.php index e599d83a96..3120a70f9f 100644 --- a/plugins/OStatus/classes/HubSub.php +++ b/plugins/OStatus/classes/HubSub.php @@ -260,9 +260,15 @@ class HubSub extends Memcached_DataObject $retries = intval(common_config('ostatus', 'hub_retries')); } - $data = array('sub' => clone($this), + // We dare not clone() as when the clone is discarded it'll + // destroy the result data for the parent query. + // @fixme use clone() again when it's safe to copy an + // individual item from a multi-item query again. + $sub = HubSub::staticGet($this->topic, $this->callback); + $data = array('sub' => $sub, 'atom' => $atom, 'retries' => $retries); + common_log(LOG_INFO, "Queuing PuSH: $this->topic to $this->callback"); $qm = QueueManager::get(); $qm->enqueue($data, 'hubout'); } From c25fc8a4b51466f13c41efc0565bf15f78f6cb4d Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 2 Mar 2010 02:54:52 -0500 Subject: [PATCH 03/22] Show and no activity actors for user feed We only need one author for user feeds: the user themselves. So, show the user as the activity:subject, and don't repeat the same activity:actor for every notice unnecessarily. --- classes/Notice.php | 8 +++++--- lib/atomnoticefeed.php | 16 +++++++++++++--- lib/atomusernoticefeed.php | 11 +++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/classes/Notice.php b/classes/Notice.php index 3702dbcfa8..4b5dbb416f 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1090,7 +1090,7 @@ class Notice extends Memcached_DataObject return $groups; } - function asAtomEntry($namespace=false, $source=false) + function asAtomEntry($namespace=false, $source=false, $author=true) { $profile = $this->getProfile(); @@ -1136,8 +1136,10 @@ class Notice extends Memcached_DataObject $xs->element('title', null, $this->content); $xs->element('summary', null, $this->content); - $xs->raw($profile->asAtomAuthor()); - $xs->raw($profile->asActivityActor()); + if ($author) { + $xs->raw($profile->asAtomAuthor()); + $xs->raw($profile->asActivityActor()); + } $xs->element('link', array('rel' => 'alternate', 'type' => 'text/html', diff --git a/lib/atomnoticefeed.php b/lib/atomnoticefeed.php index 3c3556cb95..e4df731fe0 100644 --- a/lib/atomnoticefeed.php +++ b/lib/atomnoticefeed.php @@ -107,9 +107,19 @@ class AtomNoticeFeed extends Atom10Feed */ function addEntryFromNotice($notice) { - $this->addEntryRaw($notice->asAtomEntry()); + $source = $this->showSource(); + $author = $this->showAuthor(); + + $this->addEntryRaw($notice->asAtomEntry(false, $source, $author)); } + function showSource() + { + return true; + } + + function showAuthor() + { + return true; + } } - - diff --git a/lib/atomusernoticefeed.php b/lib/atomusernoticefeed.php index 2ad8de4550..6485aaa43d 100644 --- a/lib/atomusernoticefeed.php +++ b/lib/atomusernoticefeed.php @@ -61,6 +61,7 @@ class AtomUserNoticeFeed extends AtomNoticeFeed if (!empty($user)) { $profile = $user->getProfile(); $this->addAuthor($profile->nickname, $user->uri); + $this->setActivitySubject($profile->asActivityNoun('subject')); } } @@ -68,4 +69,14 @@ class AtomUserNoticeFeed extends AtomNoticeFeed { return $this->user; } + + function showSource() + { + return false; + } + + function showAuthor() + { + return false; + } } From 40ac7247979dc6f33f56b20c907d55deb6b9c815 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 2 Mar 2010 03:13:05 -0500 Subject: [PATCH 04/22] don't duplicate title in summary in Atom output per RFC4287 4.2.13 --- classes/Notice.php | 1 - 1 file changed, 1 deletion(-) diff --git a/classes/Notice.php b/classes/Notice.php index 4b5dbb416f..c31d8bd69e 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1134,7 +1134,6 @@ class Notice extends Memcached_DataObject } $xs->element('title', null, $this->content); - $xs->element('summary', null, $this->content); if ($author) { $xs->raw($profile->asAtomAuthor()); From 9816b35063b75f1aa051d8b1ecefe716d99f5dc4 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 2 Mar 2010 00:38:00 -0800 Subject: [PATCH 05/22] Update Facebook plugin README with info about new admin panel --- plugins/Facebook/README | 84 +++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/plugins/Facebook/README b/plugins/Facebook/README index bf2f4a1800..14c1d32419 100644 --- a/plugins/Facebook/README +++ b/plugins/Facebook/README @@ -1,6 +1,9 @@ -This plugin allows you to use Facebook Connect with StatusNet, provides a -Facebook application for your users, and allows them to update their -Facebook statuses from StatusNet. +Facebook Plugin +=============== + +This plugin allows you to use Facebook Connect with StatusNet, provides +a Facebook canvas application for your users, and allows them to update +their Facebook statuses from StatusNet. Facebook Connect ---------------- @@ -15,12 +18,12 @@ Facebook credentials. With Facebook Connect, your users can: Built-in Facebook Application ----------------------------- -The plugin also installs a StatusNet Facebook application that allows your -users to automatically update their Facebook statuses with their latest -notices, invite their friends to use the app (and thus your site), view -their notice timelines, and post notices -- all from within Facebook. The -application is built into the StatusNet Facebook plugin and runs on your -host. +The plugin also installs a StatusNet Facebook canvas application that +allows your users to automatically update their Facebook status with +their latest notices, invite their friends to use the app (and thus your +site), view their notice timelines and post notices -- all from within +Facebook. The application is built into the StatusNet Facebook plugin +and runs on your host. Quick setup instructions* ------------------------- @@ -29,13 +32,9 @@ Install the Facebook Developer application on Facebook: http://www.facebook.com/developers/ -Use it to create a new application and generate an API key and secret. Add a -Facebook app section of your config.php and copy in the key and secret, -e.g.: - - // Config section for the built-in Facebook application - $config['facebook']['apikey'] = 'APIKEY'; - $config['facebook']['secret'] = 'SECRET'; +Use it to create a new application and generate an API key and secret. +You will need the key and secret so cut-n-paste them into your text +editor or write them down. In Facebook's application editor, specify the following URLs for your app: @@ -67,11 +66,36 @@ can be left with default values. http://wiki.developers.facebook.com/index.php/Connect/Setting_Up_Your_Site http://wiki.developers.facebook.com/index.php/Creating_your_first_application -Finally you must activate the plugin by adding the following line to your -config.php: +Finally you must activate the plugin by adding it in your config.php +(this is where you'll need the API key and secret generated earlier): + + addPlugin( + 'Facebook', + array( + 'apikey' => 'YOUR_APIKEY', + 'secret' => 'YOUR_SECRET' + ) + ); + +Administration Panel +-------------------- + +As of StatusNet 0.9.0 you can alternatively specify the key and secret +via a Facebook administration panel from within StatusNet, in which case +you can just add: addPlugin('Facebook'); +to activate the plugin. + +NOTE: To enable the administration panel you'll need to add it to the +list of active administration panels, e.g.: + + $config['admin']['panels'][] = 'facebook'; + +and of course you'll need a user with the administrative role to access +it and input the API key and secret (see: scripts/userrole.php). + Testing It Out -------------- @@ -81,11 +105,11 @@ disconnect* to their Facebook accounts from it. To try out the plugin, fire up your browser and connect to: - http://SITE/PATH_TO_STATUSNET/main/facebooklogin + http://example.net/mublog/main/facebooklogin or, if you do not have fancy URLs turned on: - http://SITE/PATH_TO_STATUSNET/index.php/main/facebooklogin + http://example.net/mublog/index.php/main/facebooklogin You should see a page with a blue button that says: "Connect with Facebook" and you should be able to login or register. @@ -101,7 +125,7 @@ the app, you are given the option to update their Facebook status via StatusNet. * Note: Before a user can disconnect from Facebook, she must set a normal - StatusNet password. Otherwise, she might not be able to login in to her + StatusNet password. Otherwise, she might not be able to login in to her account in the future. This is usually only required for users who have used Facebook Connect to register their StatusNet account, and therefore haven't already set a local password. @@ -109,16 +133,20 @@ StatusNet. Offline Queue Handling ---------------------- -For larger sites needing better performance it's possible to enable queuing -and have users' notices posted to Facebook via a separate "offline" -FacebookQueueHandler (facebookqueuhandler.php in the Facebook plugin -directory), which will be started by the plugin along with their other -daemons when you run scripts/startdaemons.sh. See the StatusNet README for -more about queuing and daemons. +For larger sites needing better performance it's possible to enable +queuing and have users' notices posted to Facebook via a separate +"offline" process -- FacebookQueueHandler (facebookqueuhandler.php in +the Facebook plugin directory). It will run automatically if you have +enabled StatusNet's offline queueing subsystem. See the "Queues and +daemons" section in the StatusNet README for more about queuing. + TODO ---- +- Make Facebook Connect work for authentication for multi-site setups + (e.g.: *.status.net) +- Posting to Facebook user streams using only Facebook Connect - Invite Facebook friends to use your StatusNet installation via Facebook Connect - Auto-subscribe Facebook friends already using StatusNet @@ -126,4 +154,4 @@ TODO - Allow users to update their Facebook statuses once they have authenticated with Facebook Connect (no need for them to use the Facebook app if they don't want to). -- Re-design the whole thing to support multiple instances of StatusNet +- Import a user's Facebook updates into StatusNet From e2578cfad68c45ca177c51997c4cc7c0abafbd9a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 2 Mar 2010 03:40:43 -0500 Subject: [PATCH 06/22] Revert "Show and no activity actors for user feed" This reverts commit c25fc8a4b51466f13c41efc0565bf15f78f6cb4d. --- classes/Notice.php | 8 +++----- lib/atomnoticefeed.php | 16 +++------------- lib/atomusernoticefeed.php | 11 ----------- 3 files changed, 6 insertions(+), 29 deletions(-) diff --git a/classes/Notice.php b/classes/Notice.php index c31d8bd69e..7c424ee8a6 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1090,7 +1090,7 @@ class Notice extends Memcached_DataObject return $groups; } - function asAtomEntry($namespace=false, $source=false, $author=true) + function asAtomEntry($namespace=false, $source=false) { $profile = $this->getProfile(); @@ -1135,10 +1135,8 @@ class Notice extends Memcached_DataObject $xs->element('title', null, $this->content); - if ($author) { - $xs->raw($profile->asAtomAuthor()); - $xs->raw($profile->asActivityActor()); - } + $xs->raw($profile->asAtomAuthor()); + $xs->raw($profile->asActivityActor()); $xs->element('link', array('rel' => 'alternate', 'type' => 'text/html', diff --git a/lib/atomnoticefeed.php b/lib/atomnoticefeed.php index e4df731fe0..3c3556cb95 100644 --- a/lib/atomnoticefeed.php +++ b/lib/atomnoticefeed.php @@ -107,19 +107,9 @@ class AtomNoticeFeed extends Atom10Feed */ function addEntryFromNotice($notice) { - $source = $this->showSource(); - $author = $this->showAuthor(); - - $this->addEntryRaw($notice->asAtomEntry(false, $source, $author)); + $this->addEntryRaw($notice->asAtomEntry()); } - function showSource() - { - return true; - } - - function showAuthor() - { - return true; - } } + + diff --git a/lib/atomusernoticefeed.php b/lib/atomusernoticefeed.php index 6485aaa43d..2ad8de4550 100644 --- a/lib/atomusernoticefeed.php +++ b/lib/atomusernoticefeed.php @@ -61,7 +61,6 @@ class AtomUserNoticeFeed extends AtomNoticeFeed if (!empty($user)) { $profile = $user->getProfile(); $this->addAuthor($profile->nickname, $user->uri); - $this->setActivitySubject($profile->asActivityNoun('subject')); } } @@ -69,14 +68,4 @@ class AtomUserNoticeFeed extends AtomNoticeFeed { return $this->user; } - - function showSource() - { - return false; - } - - function showAuthor() - { - return false; - } } From 623faf9f2d83b8fd6134e77ad6f5dd1cedc7a5c1 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 09:57:28 -0500 Subject: [PATCH 07/22] Just a label change. Since the user already went ahead with subscribing, in this step we are just confirming the profile. --- plugins/OStatus/actions/ostatussub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index f45e6a8d1a..e318701a24 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -112,7 +112,7 @@ class OStatusSubAction extends Action $this->submit('submit', _m('Join'), 'submit', null, _m('Join this group')); } else { - $this->submit('submit', _m('Subscribe'), 'submit', null, + $this->submit('submit', _m('Confirm'), 'submit', null, _m('Subscribe to this user')); } $this->elementEnd('fieldset'); From 350e1289af67cb2830c8ca7fc8202566ab32f2e0 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 12:33:25 -0500 Subject: [PATCH 08/22] Added event hook for before and after personal timeline content --- EVENTS.txt | 6 ++++++ actions/all.php | 22 +++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/EVENTS.txt b/EVENTS.txt index a2b405acc8..bb4936b354 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -770,6 +770,12 @@ StartShowSubscriptionsContent: before showing the subscriptions content EndShowSubscriptionsContent: after showing the subscriptions content - $action: the current action +StartShowAllContent: before showing the all (you and friends) content +- $action: the current action + +EndShowAllContent: after showing the all (you and friends) content +- $action: the current action + StartDeleteUserForm: starting the data in the form for deleting a user - $action: action being shown - $user: user being deleted diff --git a/actions/all.php b/actions/all.php index 3eb1852147..6be0c00e3a 100644 --- a/actions/all.php +++ b/actions/all.php @@ -144,18 +144,22 @@ class AllAction extends ProfileAction function showContent() { - $nl = new NoticeList($this->notice, $this); + if (Event::handle('StartShowAllContent', array($this))) { + $nl = new NoticeList($this->notice, $this); - $cnt = $nl->show(); + $cnt = $nl->show(); - if (0 == $cnt) { - $this->showEmptyListMessage(); + if (0 == $cnt) { + $this->showEmptyListMessage(); + } + + $this->pagination( + $this->page > 1, $cnt > NOTICES_PER_PAGE, + $this->page, 'all', array('nickname' => $this->user->nickname) + ); + + Event::handle('EndShowAllContent', array($this)); } - - $this->pagination( - $this->page > 1, $cnt > NOTICES_PER_PAGE, - $this->page, 'all', array('nickname' => $this->user->nickname) - ); } function showPageTitle() From 5abff9104130ca6b49de6ab19f0359e888e1a085 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 12:34:35 -0500 Subject: [PATCH 09/22] Generalized style for entity remote subscription action --- plugins/OStatus/theme/base/css/ostatus.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/OStatus/theme/base/css/ostatus.css b/plugins/OStatus/theme/base/css/ostatus.css index feeeb47d38..e370810af7 100644 --- a/plugins/OStatus/theme/base/css/ostatus.css +++ b/plugins/OStatus/theme/base/css/ostatus.css @@ -38,11 +38,11 @@ display:none; min-width:96px; } -#subscriptions #entity_remote_subscribe { +#entity_remote_subscribe { padding:0; float:right; } -#subscriptions .entity_remote_subscribe { +.entity_remote_subscribe { float:right; } From 88c33bbb57433b3f10407f590b49d11ec4d5d530 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 12:35:27 -0500 Subject: [PATCH 10/22] Showing remote subscription button on the personal timeline --- plugins/OStatus/OStatusPlugin.php | 18 ++++++++++++++++++ plugins/OStatus/theme/base/css/ostatus.css | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 4ffbba45b9..64504547f4 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -721,6 +721,24 @@ class OStatusPlugin extends Plugin return true; } + function onStartShowAllContent($action) + { + $user = common_current_user(); + if ($user && ($user->id == $action->profile->id)) { + $action->elementStart('div', 'entity_actions'); + $action->elementStart('p', array('id' => 'entity_remote_subscribe', + 'class' => 'entity_subscribe')); + $action->element('a', array('href' => common_local_url('ostatussub'), + 'class' => 'entity_remote_subscribe') + , _m('Subscribe to remote user')); + $action->elementEnd('p'); + $action->elementEnd('div'); + } + + return true; + } + + /** * Ping remote profiles with updates to this profile. * Salmon pings are queued for background processing. diff --git a/plugins/OStatus/theme/base/css/ostatus.css b/plugins/OStatus/theme/base/css/ostatus.css index e370810af7..68470f4e41 100644 --- a/plugins/OStatus/theme/base/css/ostatus.css +++ b/plugins/OStatus/theme/base/css/ostatus.css @@ -46,3 +46,7 @@ float:right; .entity_remote_subscribe { float:right; } + +#all #entity_remote_subscribe { +margin-top:-52px; +} From e3c2b8e0b50d750ad35cb313726fd2706684c09b Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 12:41:18 -0500 Subject: [PATCH 11/22] Refactored remote subscribe action in OStatus --- plugins/OStatus/OStatusPlugin.php | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 64504547f4..7b6d22acf3 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -706,22 +706,19 @@ class OStatusPlugin extends Plugin function onStartShowSubscriptionsContent($action) { - $user = common_current_user(); - if ($user && ($user->id == $action->profile->id)) { - $action->elementStart('div', 'entity_actions'); - $action->elementStart('p', array('id' => 'entity_remote_subscribe', - 'class' => 'entity_subscribe')); - $action->element('a', array('href' => common_local_url('ostatussub'), - 'class' => 'entity_remote_subscribe') - , _m('Subscribe to remote user')); - $action->elementEnd('p'); - $action->elementEnd('div'); - } + $this->showEntityRemoteSubscribe($action); return true; } function onStartShowAllContent($action) + { + $this->showEntityRemoteSubscribe($action); + + return true; + } + + function showEntityRemoteSubscribe($action) { $user = common_current_user(); if ($user && ($user->id == $action->profile->id)) { @@ -734,11 +731,8 @@ class OStatusPlugin extends Plugin $action->elementEnd('p'); $action->elementEnd('div'); } - - return true; } - /** * Ping remote profiles with updates to this profile. * Salmon pings are queued for background processing. From f596e072e79ec87541b27008ea2327275e5fc669 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Mar 2010 09:53:00 -0800 Subject: [PATCH 12/22] Fix for regression in updated mention checks, sometimes lost links to folks mentioned in the replied message. --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util.php b/lib/util.php index d12a7920d2..485f6f0d9d 100644 --- a/lib/util.php +++ b/lib/util.php @@ -550,7 +550,7 @@ function common_find_mentions($text, $notice) } else if (!empty($originalMentions) && array_key_exists($nickname, $originalMentions)) { - $mention = $originalMentions[$nickname]; + $mentioned = $originalMentions[$nickname]; } else { $mentioned = common_relative_profile($sender, $nickname); } From 6b134ae4c7e15ce9853bc82545c3beb67a2dfdad Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Mar 2010 11:54:02 -0800 Subject: [PATCH 13/22] Dropped deprecated timestamp-based 'since' parameter for all API methods. When it sneaks in it can cause some very slow queries due to mismatches with the indexing. Twitter removed 'since' support some time ago, and we've already removed it from the public timeline, so it shouldn't be missed. --- actions/apidirectmessage.php | 5 ---- actions/apigrouplist.php | 3 +-- actions/apigroupmembership.php | 3 +-- actions/apitimelinefriends.php | 4 ++-- actions/apitimelinegroup.php | 3 +-- actions/apitimelinehome.php | 4 ++-- actions/apitimelinementions.php | 2 +- actions/apitimelinepublic.php | 4 ---- actions/apitimelineuser.php | 2 +- classes/Fave.php | 6 +---- classes/Inbox.php | 8 +++---- classes/Notice.php | 26 +++++++------------- classes/Notice_inbox.php | 4 ++-- classes/Notice_tag.php | 6 +---- classes/Profile.php | 20 +++++----------- classes/Reply.php | 10 +++----- classes/User.php | 42 +++++++++++++-------------------- classes/User_group.php | 6 +---- lib/apiaction.php | 8 +++---- 19 files changed, 57 insertions(+), 109 deletions(-) diff --git a/actions/apidirectmessage.php b/actions/apidirectmessage.php index 5355acf825..53da9e0c68 100644 --- a/actions/apidirectmessage.php +++ b/actions/apidirectmessage.php @@ -182,11 +182,6 @@ class ApiDirectMessageAction extends ApiAuthAction $message->whereAdd('id > ' . $this->since_id); } - if (!empty($since)) { - $d = date('Y-m-d H:i:s', $this->since); - $message->whereAdd("created > '$d'"); - } - $message->orderBy('created DESC, id DESC'); $message->limit((($this->page - 1) * $this->count), $this->count); $message->find(); diff --git a/actions/apigrouplist.php b/actions/apigrouplist.php index 605b382326..98fdb0497a 100644 --- a/actions/apigrouplist.php +++ b/actions/apigrouplist.php @@ -152,8 +152,7 @@ class ApiGroupListAction extends ApiBareAuthAction ($this->page - 1) * $this->count, $this->count, $this->since_id, - $this->max_id, - $this->since + $this->max_id ); while ($group->fetch()) { diff --git a/actions/apigroupmembership.php b/actions/apigroupmembership.php index 3c7c8e8835..9f72b527cf 100644 --- a/actions/apigroupmembership.php +++ b/actions/apigroupmembership.php @@ -125,8 +125,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction ($this->page - 1) * $this->count, $this->count, $this->since_id, - $this->max_id, - $this->since + $this->max_id ); while ($profile->fetch()) { diff --git a/actions/apitimelinefriends.php b/actions/apitimelinefriends.php index 2db76857e3..9ef3ace607 100644 --- a/actions/apitimelinefriends.php +++ b/actions/apitimelinefriends.php @@ -202,11 +202,11 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) { $notice = $this->user->ownFriendsTimeline(($this->page-1) * $this->count, $this->count, $this->since_id, - $this->max_id, $this->since); + $this->max_id); } else { $notice = $this->user->friendsTimeline(($this->page-1) * $this->count, $this->count, $this->since_id, - $this->max_id, $this->since); + $this->max_id); } while ($notice->fetch()) { diff --git a/actions/apitimelinegroup.php b/actions/apitimelinegroup.php index 04456ffea4..d0af49844c 100644 --- a/actions/apitimelinegroup.php +++ b/actions/apitimelinegroup.php @@ -204,8 +204,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction ($this->page-1) * $this->count, $this->count, $this->since_id, - $this->max_id, - $this->since + $this->max_id ); while ($notice->fetch()) { diff --git a/actions/apitimelinehome.php b/actions/apitimelinehome.php index 0c72f4020c..abd3877860 100644 --- a/actions/apitimelinehome.php +++ b/actions/apitimelinehome.php @@ -200,13 +200,13 @@ class ApiTimelineHomeAction extends ApiBareAuthAction $notice = $this->user->noticeInbox( ($this->page-1) * $this->count, $this->count, $this->since_id, - $this->max_id, $this->since + $this->max_id ); } else { $notice = $this->user->noticesWithFriends( ($this->page-1) * $this->count, $this->count, $this->since_id, - $this->max_id, $this->since + $this->max_id ); } diff --git a/actions/apitimelinementions.php b/actions/apitimelinementions.php index a39c63346a..31627ab7bf 100644 --- a/actions/apitimelinementions.php +++ b/actions/apitimelinementions.php @@ -189,7 +189,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction $notice = $this->user->getReplies( ($this->page - 1) * $this->count, $this->count, - $this->since_id, $this->max_id, $this->since + $this->since_id, $this->max_id ); while ($notice->fetch()) { diff --git a/actions/apitimelinepublic.php b/actions/apitimelinepublic.php index 1ff0fd2617..3e4dad690e 100644 --- a/actions/apitimelinepublic.php +++ b/actions/apitimelinepublic.php @@ -75,10 +75,6 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction $this->notices = $this->getNotices(); - if ($this->since) { - throw new ServerException("since parameter is disabled for performance; use since_id", 403); - } - return true; } diff --git a/actions/apitimelineuser.php b/actions/apitimelineuser.php index b3ded97c0f..94491946c2 100644 --- a/actions/apitimelineuser.php +++ b/actions/apitimelineuser.php @@ -211,7 +211,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction $notice = $this->user->getNotices( ($this->page-1) * $this->count, $this->count, - $this->since_id, $this->max_id, $this->since + $this->since_id, $this->max_id ); while ($notice->fetch()) { diff --git a/classes/Fave.php b/classes/Fave.php index 0b6eec2bc4..a04f15e9c4 100644 --- a/classes/Fave.php +++ b/classes/Fave.php @@ -77,7 +77,7 @@ class Fave extends Memcached_DataObject return $ids; } - function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id, $since) + function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id) { $fav = new Fave(); $qry = null; @@ -100,10 +100,6 @@ class Fave extends Memcached_DataObject $qry .= 'AND notice_id <= ' . $max_id . ' '; } - if (!is_null($since)) { - $qry .= 'AND modified > \'' . date('Y-m-d H:i:s', $since) . '\' '; - } - // NOTE: we sort by fave time, not by notice time! $qry .= 'ORDER BY modified DESC '; diff --git a/classes/Inbox.php b/classes/Inbox.php index be62611a16..014ba3d829 100644 --- a/classes/Inbox.php +++ b/classes/Inbox.php @@ -137,7 +137,7 @@ class Inbox extends Memcached_DataObject } } - function stream($user_id, $offset, $limit, $since_id, $max_id, $since, $own=false) + function stream($user_id, $offset, $limit, $since_id, $max_id, $own=false) { $inbox = Inbox::staticGet('user_id', $user_id); @@ -195,15 +195,15 @@ class Inbox extends Memcached_DataObject * @param int $limit * @param mixed $since_id return only notices after but not including this id * @param mixed $max_id return only notices up to and including this id - * @param mixed $since obsolete/ignored * @param mixed $own ignored? * @return array of Notice objects * * @todo consider repacking the inbox when this happens? + * @fixme reimplement $own if we need it? */ - function streamNotices($user_id, $offset, $limit, $since_id, $max_id, $since, $own=false) + function streamNotices($user_id, $offset, $limit, $since_id, $max_id, $own=false) { - $ids = self::stream($user_id, $offset, self::MAX_NOTICES, $since_id, $max_id, $since, $own); + $ids = self::stream($user_id, $offset, self::MAX_NOTICES, $since_id, $max_id, $own); // Do a bulk lookup for the first $limit items // Fast path when nothing's deleted. diff --git a/classes/Notice.php b/classes/Notice.php index 3702dbcfa8..22dcbcd741 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -559,17 +559,17 @@ class Notice extends Memcached_DataObject } } - function publicStream($offset=0, $limit=20, $since_id=0, $max_id=0, $since=null) + function publicStream($offset=0, $limit=20, $since_id=0, $max_id=0) { $ids = Notice::stream(array('Notice', '_publicStreamDirect'), array(), 'public', - $offset, $limit, $since_id, $max_id, $since); + $offset, $limit, $since_id, $max_id); return Notice::getStreamByIds($ids); } - function _publicStreamDirect($offset=0, $limit=20, $since_id=0, $max_id=0, $since=null) + function _publicStreamDirect($offset=0, $limit=20, $since_id=0, $max_id=0) { $notice = new Notice(); @@ -598,10 +598,6 @@ class Notice extends Memcached_DataObject $notice->whereAdd('id <= ' . $max_id); } - if (!is_null($since)) { - $notice->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\''); - } - $ids = array(); if ($notice->find()) { @@ -616,17 +612,17 @@ class Notice extends Memcached_DataObject return $ids; } - function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null) + function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0) { $ids = Notice::stream(array('Notice', '_conversationStreamDirect'), array($id), 'notice:conversation_ids:'.$id, - $offset, $limit, $since_id, $max_id, $since); + $offset, $limit, $since_id, $max_id); return Notice::getStreamByIds($ids); } - function _conversationStreamDirect($id, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null) + function _conversationStreamDirect($id, $offset=0, $limit=20, $since_id=0, $max_id=0) { $notice = new Notice(); @@ -649,10 +645,6 @@ class Notice extends Memcached_DataObject $notice->whereAdd('id <= ' . $max_id); } - if (!is_null($since)) { - $notice->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\''); - } - $ids = array(); if ($notice->find()) { @@ -1270,16 +1262,16 @@ class Notice extends Memcached_DataObject } } - function stream($fn, $args, $cachekey, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null) + function stream($fn, $args, $cachekey, $offset=0, $limit=20, $since_id=0, $max_id=0) { $cache = common_memcache(); if (empty($cache) || - $since_id != 0 || $max_id != 0 || (!is_null($since) && $since > 0) || + $since_id != 0 || $max_id != 0 || is_null($limit) || ($offset + $limit) > NOTICE_CACHE_WINDOW) { return call_user_func_array($fn, array_merge($args, array($offset, $limit, $since_id, - $max_id, $since))); + $max_id))); } $idkey = common_cache_key($cachekey); diff --git a/classes/Notice_inbox.php b/classes/Notice_inbox.php index c27dcdfd61..47ed6b22db 100644 --- a/classes/Notice_inbox.php +++ b/classes/Notice_inbox.php @@ -49,12 +49,12 @@ class Notice_inbox extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - function stream($user_id, $offset, $limit, $since_id, $max_id, $since, $own=false) + function stream($user_id, $offset, $limit, $since_id, $max_id, $own=false) { throw new Exception('Notice_inbox no longer used; use Inbox'); } - function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id, $since) + function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id) { throw new Exception('Notice_inbox no longer used; use Inbox'); } diff --git a/classes/Notice_tag.php b/classes/Notice_tag.php index 4fd76e8ea8..a5d0716a71 100644 --- a/classes/Notice_tag.php +++ b/classes/Notice_tag.php @@ -46,7 +46,7 @@ class Notice_tag extends Memcached_DataObject return Notice::getStreamByIds($ids); } - function _streamDirect($tag, $offset, $limit, $since_id, $max_id, $since) + function _streamDirect($tag, $offset, $limit, $since_id, $max_id) { $nt = new Notice_tag(); @@ -63,10 +63,6 @@ class Notice_tag extends Memcached_DataObject $nt->whereAdd('notice_id < ' . $max_id); } - if (!is_null($since)) { - $nt->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\''); - } - $nt->orderBy('notice_id DESC'); if (!is_null($offset)) { diff --git a/classes/Profile.php b/classes/Profile.php index 78223b34a1..470ef33207 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -163,27 +163,27 @@ class Profile extends Memcached_DataObject return null; } - function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null) + function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0) { $ids = Notice::stream(array($this, '_streamTaggedDirect'), array($tag), 'profile:notice_ids_tagged:' . $this->id . ':' . $tag, - $offset, $limit, $since_id, $max_id, $since); + $offset, $limit, $since_id, $max_id); return Notice::getStreamByIds($ids); } - function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null) + function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0) { // XXX: I'm not sure this is going to be any faster. It probably isn't. $ids = Notice::stream(array($this, '_streamDirect'), array(), 'profile:notice_ids:' . $this->id, - $offset, $limit, $since_id, $max_id, $since); + $offset, $limit, $since_id, $max_id); return Notice::getStreamByIds($ids); } - function _streamTaggedDirect($tag, $offset, $limit, $since_id, $max_id, $since) + function _streamTaggedDirect($tag, $offset, $limit, $since_id, $max_id) { // XXX It would be nice to do this without a join @@ -202,10 +202,6 @@ class Profile extends Memcached_DataObject $query .= " and id < $max_id"; } - if (!is_null($since)) { - $query .= " and created > '" . date('Y-m-d H:i:s', $since) . "'"; - } - $query .= ' order by id DESC'; if (!is_null($offset)) { @@ -223,7 +219,7 @@ class Profile extends Memcached_DataObject return $ids; } - function _streamDirect($offset, $limit, $since_id, $max_id, $since = null) + function _streamDirect($offset, $limit, $since_id, $max_id) { $notice = new Notice(); @@ -240,10 +236,6 @@ class Profile extends Memcached_DataObject $notice->whereAdd('id <= ' . $max_id); } - if (!is_null($since)) { - $notice->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\''); - } - $notice->orderBy('id DESC'); if (!is_null($offset)) { diff --git a/classes/Reply.php b/classes/Reply.php index 49b1e05e51..659e04c925 100644 --- a/classes/Reply.php +++ b/classes/Reply.php @@ -22,16 +22,16 @@ class Reply extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null) + function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0) { $ids = Notice::stream(array('Reply', '_streamDirect'), array($user_id), 'reply:stream:' . $user_id, - $offset, $limit, $since_id, $max_id, $since); + $offset, $limit, $since_id, $max_id); return $ids; } - function _streamDirect($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null) + function _streamDirect($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0) { $reply = new Reply(); $reply->profile_id = $user_id; @@ -44,10 +44,6 @@ class Reply extends Memcached_DataObject $reply->whereAdd('notice_id < ' . $max_id); } - if (!is_null($since)) { - $reply->whereAdd('modified > \'' . date('Y-m-d H:i:s', $since) . '\''); - } - $reply->orderBy('notice_id DESC'); if (!is_null($offset)) { diff --git a/classes/User.php b/classes/User.php index 10b1f48651..57d76731b8 100644 --- a/classes/User.php +++ b/classes/User.php @@ -456,28 +456,28 @@ class User extends Memcached_DataObject return $user; } - function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { - $ids = Reply::stream($this->id, $offset, $limit, $since_id, $before_id, $since); + $ids = Reply::stream($this->id, $offset, $limit, $since_id, $before_id); return Notice::getStreamByIds($ids); } - function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { + function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { $profile = $this->getProfile(); if (!$profile) { return null; } else { - return $profile->getTaggedNotices($tag, $offset, $limit, $since_id, $before_id, $since); + return $profile->getTaggedNotices($tag, $offset, $limit, $since_id, $before_id); } } - function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { $profile = $this->getProfile(); if (!$profile) { return null; } else { - return $profile->getNotices($offset, $limit, $since_id, $before_id, $since); + return $profile->getNotices($offset, $limit, $since_id, $before_id); } } @@ -487,24 +487,24 @@ class User extends Memcached_DataObject return Notice::getStreamByIds($ids); } - function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { - return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, false); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, false); } - function noticeInbox($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + function noticeInbox($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { - return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, true); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, true); } - function friendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + function friendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { - return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, false); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, false); } - function ownFriendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + function ownFriendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { - return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, true); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, true); } function blowFavesCache() @@ -789,7 +789,7 @@ class User extends Memcached_DataObject return Notice::getStreamByIds($ids); } - function _repeatedByMeDirect($offset, $limit, $since_id, $max_id, $since) + function _repeatedByMeDirect($offset, $limit, $since_id, $max_id) { $notice = new Notice(); @@ -813,10 +813,6 @@ class User extends Memcached_DataObject $notice->whereAdd('id <= ' . $max_id); } - if (!is_null($since)) { - $notice->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\''); - } - $ids = array(); if ($notice->find()) { @@ -836,12 +832,12 @@ class User extends Memcached_DataObject $ids = Notice::stream(array($this, '_repeatsOfMeDirect'), array(), 'user:repeats_of_me:'.$this->id, - $offset, $limit, $since_id, $max_id, null); + $offset, $limit, $since_id, $max_id); return Notice::getStreamByIds($ids); } - function _repeatsOfMeDirect($offset, $limit, $since_id, $max_id, $since) + function _repeatsOfMeDirect($offset, $limit, $since_id, $max_id) { $qry = 'SELECT DISTINCT original.id AS id ' . @@ -856,10 +852,6 @@ class User extends Memcached_DataObject $qry .= 'AND original.id <= ' . $max_id . ' '; } - if (!is_null($since)) { - $qry .= 'AND original.modified > \'' . date('Y-m-d H:i:s', $since) . '\' '; - } - // NOTE: we sort by fave time, not by notice time! $qry .= 'ORDER BY original.id DESC '; diff --git a/classes/User_group.php b/classes/User_group.php index 7240e27037..64fe024b34 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -91,7 +91,7 @@ class User_group extends Memcached_DataObject return Notice::getStreamByIds($ids); } - function _streamDirect($offset, $limit, $since_id, $max_id, $since) + function _streamDirect($offset, $limit, $since_id, $max_id) { $inbox = new Group_inbox(); @@ -108,10 +108,6 @@ class User_group extends Memcached_DataObject $inbox->whereAdd('notice_id <= ' . $max_id); } - if (!is_null($since)) { - $inbox->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\''); - } - $inbox->orderBy('notice_id DESC'); if (!is_null($offset)) { diff --git a/lib/apiaction.php b/lib/apiaction.php index 2af150ab99..8049c09016 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -63,7 +63,6 @@ class ApiAction extends Action var $count = null; var $max_id = null; var $since_id = null; - var $since = null; var $access = self::READ_ONLY; // read (default) or read-write @@ -85,7 +84,10 @@ class ApiAction extends Action $this->count = (int)$this->arg('count', 20); $this->max_id = (int)$this->arg('max_id', 0); $this->since_id = (int)$this->arg('since_id', 0); - $this->since = $this->arg('since'); + + if ($this->arg('since')) { + $this->clientError(_("since parameter is disabled for performance; use since_id"), 403); + } return true; } @@ -1325,8 +1327,6 @@ class ApiAction extends Action case 'max_id': $max_id = (int)$this->args['max_id']; return ($max_id < 1) ? 0 : $max_id; - case 'since': - return strtotime($this->args['since']); default: return parent::arg($key, $def); } From b1ffbf17d3da90f4c509a47c9fd876304ed9e3fc Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Mar 2010 12:06:40 -0800 Subject: [PATCH 14/22] Performance fix on Sphinx search results: use id instead of created timestamp for reverse date sorting; should give same result but doesn't trigger a filesort. --- plugins/SphinxSearch/sphinxsearch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SphinxSearch/sphinxsearch.php b/plugins/SphinxSearch/sphinxsearch.php index 71f3308281..654b9c9d5b 100644 --- a/plugins/SphinxSearch/sphinxsearch.php +++ b/plugins/SphinxSearch/sphinxsearch.php @@ -75,7 +75,7 @@ class SphinxSearch extends SearchEngine { if ('chron' === $mode) { $this->sphinx->SetSortMode(SPH_SORT_ATTR_DESC, 'created_ts'); - return $this->target->orderBy('created desc'); + return $this->target->orderBy('id desc'); } } From 1550d1004d44c8223b2280a35ca2f64ed61178ef Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 15:24:07 -0500 Subject: [PATCH 15/22] Don't need to float the anchor --- plugins/OStatus/theme/base/css/ostatus.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/OStatus/theme/base/css/ostatus.css b/plugins/OStatus/theme/base/css/ostatus.css index 68470f4e41..13e30ef5df 100644 --- a/plugins/OStatus/theme/base/css/ostatus.css +++ b/plugins/OStatus/theme/base/css/ostatus.css @@ -43,10 +43,6 @@ padding:0; float:right; } -.entity_remote_subscribe { -float:right; -} - #all #entity_remote_subscribe { margin-top:-52px; } From 4113f28851020509163a31ab20658429d86c3134 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 15:25:32 -0500 Subject: [PATCH 16/22] Added Subscribe button to remote user entity actions in profie lists --- lib/profilelist.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/profilelist.php b/lib/profilelist.php index 693cd64492..4f1e84a6af 100644 --- a/lib/profilelist.php +++ b/lib/profilelist.php @@ -273,13 +273,18 @@ class ProfileListItem extends Widget $usf = new UnsubscribeForm($this->out, $this->profile); $usf->show(); } else { - // Is it a local user? can't remote sub from a list - // XXX: make that possible! $other = User::staticGet('id', $this->profile->id); if (!empty($other)) { $sf = new SubscribeForm($this->out, $this->profile); $sf->show(); } + else { + $url = common_local_url('remotesubscribe', + array('nickname' => $this->profile->nickname)); + $this->out->element('a', array('href' => $url, + 'class' => 'entity_remote_subscribe'), + _('Subscribe')); + } } $this->out->elementEnd('li'); } From c30f95c55cb4fcdde53c0549335d29ed6849cf95 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 22 Jan 2010 10:12:26 -0500 Subject: [PATCH 17/22] Updated some references to the long gnone "isEnclosure" function to the new "getEnclosure" --- classes/File.php | 2 ++ lib/apiaction.php | 9 +++++---- lib/util.php | 15 ++++----------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/classes/File.php b/classes/File.php index 91b12d2e28..189e04ce02 100644 --- a/classes/File.php +++ b/classes/File.php @@ -279,6 +279,8 @@ class File extends Memcached_DataObject if($oembed->modified) $enclosure->modified=$oembed->modified; unset($oembed->size); } + } else { + return false; } } } diff --git a/lib/apiaction.php b/lib/apiaction.php index 8049c09016..f71432e032 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -291,11 +291,12 @@ class ApiAction extends Action $twitter_status['attachments'] = array(); foreach ($attachments as $attachment) { - if ($attachment->isEnclosure()) { + $enclosure_o=$attachment->getEnclosure(); + if ($attachment_enclosure) { $enclosure = array(); - $enclosure['url'] = $attachment->url; - $enclosure['mimetype'] = $attachment->mimetype; - $enclosure['size'] = $attachment->size; + $enclosure['url'] = $enclosure_o->url; + $enclosure['mimetype'] = $enclosure_o->mimetype; + $enclosure['size'] = $enclosure_o->size; $twitter_status['attachments'][] = $enclosure; } } diff --git a/lib/util.php b/lib/util.php index 439db581a5..add1b0ae67 100644 --- a/lib/util.php +++ b/lib/util.php @@ -770,20 +770,13 @@ function common_linkify($url) { } if (!empty($f)) { - if ($f->isEnclosure()) { + if ($f->getEnclosure()) { $is_attachment = true; $attachment_id = $f->id; - } else { - $foe = File_oembed::staticGet('file_id', $f->id); - if (!empty($foe)) { - // if it has OEmbed info, it's an attachment, too - $is_attachment = true; - $attachment_id = $f->id; - $thumb = File_thumbnail::staticGet('file_id', $f->id); - if (!empty($thumb)) { - $has_thumb = true; - } + $thumb = File_thumbnail::staticGet('file_id', $f->id); + if (!empty($thumb)) { + $has_thumb = true; } } } From 09705a1e989d202859d637f8a84383f365b7906a Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 22 Jan 2010 10:40:21 -0500 Subject: [PATCH 18/22] stupid mistake... let's not talk about this. --- lib/apiaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/apiaction.php b/lib/apiaction.php index f71432e032..eef0ba637d 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -292,7 +292,7 @@ class ApiAction extends Action foreach ($attachments as $attachment) { $enclosure_o=$attachment->getEnclosure(); - if ($attachment_enclosure) { + if ($enclosure_o) { $enclosure = array(); $enclosure['url'] = $enclosure_o->url; $enclosure['mimetype'] = $enclosure_o->mimetype; From 9f94d6defa0d2536cb1f20a4c1c44ff78fd3f039 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 19:15:24 -0500 Subject: [PATCH 19/22] Changed the geo location cookie Expire to Session. --- js/util.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/util.js b/js/util.js index 949aec957d..d08c46fe64 100644 --- a/js/util.js +++ b/js/util.js @@ -53,7 +53,7 @@ var SN = { // StatusNet NoticeLocationNs: 'notice_data-location_ns', NoticeGeoName: 'notice_data-geo_name', NoticeDataGeo: 'notice_data-geo', - NoticeDataGeoCookie: 'notice_data-geo_cookie', + NoticeDataGeoCookie: 'NoticeDataGeo', NoticeDataGeoSelected: 'notice_data-geo_selected', StatusNetInstance:'StatusNetInstance' } @@ -494,7 +494,7 @@ var SN = { // StatusNet $('#'+SN.C.S.NoticeLocationId).val(''); $('#'+SN.C.S.NoticeDataGeo).attr('checked', false); - $.cookie(SN.C.S.NoticeDataGeoCookie, 'disabled', { path: '/', expires: SN.U.GetFullYear(2029, 0, 1) }); + $.cookie(SN.C.S.NoticeDataGeoCookie, 'disabled', { path: '/' }); } function getJSONgeocodeURL(geocodeURL, data) { @@ -537,7 +537,7 @@ var SN = { // StatusNet NDG: true }; - $.cookie(SN.C.S.NoticeDataGeoCookie, JSON.stringify(cookieValue), { path: '/', expires: SN.U.GetFullYear(2029, 0, 1) }); + $.cookie(SN.C.S.NoticeDataGeoCookie, JSON.stringify(cookieValue), { path: '/' }); }); } From 79ffebb51b1141791d5ee7478e3a7beaa9fe8faa Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Mar 2010 16:30:09 -0800 Subject: [PATCH 20/22] OStatus: save file records for enclosures Also stripping id from foreign HTML messages (could interfere with UI) and disabled failing attachment popup for a.attachment links that don't have a proper id, so you can click through instead of getting an error. Issues: * any other links aren't marked and saved * inconsistent behavior between local and remote attachments (local displays in lightbox, remote doesn't) * if the enclosure'd object isn't referenced in the content, you won't be offered a link to it in our UI --- classes/File.php | 7 ++++++ classes/Notice.php | 28 +++++++++++++++++++-- js/util.js | 7 ++++-- lib/activity.php | 5 ++++ plugins/OStatus/classes/Ostatus_profile.php | 12 +++++++-- 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/classes/File.php b/classes/File.php index 189e04ce02..1b8ef1b3ee 100644 --- a/classes/File.php +++ b/classes/File.php @@ -286,5 +286,12 @@ class File extends Memcached_DataObject } return $enclosure; } + + // quick back-compat hack, since there's still code using this + function isEnclosure() + { + $enclosure = $this->getEnclosure(); + return !empty($enclosure); + } } diff --git a/classes/Notice.php b/classes/Notice.php index 63dc968972..c1263c7821 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -211,6 +211,8 @@ class Notice extends Memcached_DataObject * extracting ! tags from content * array 'tags' list of hashtag strings to save with the notice * in place of extracting # tags from content + * array 'urls' list of attached/referred URLs to save with the + * notice in place of extracting links from content * @fixme tag override * * @return Notice @@ -380,8 +382,11 @@ class Notice extends Memcached_DataObject $notice->saveTags(); } - // @fixme pass in data for URLs too? - $notice->saveUrls(); + if (isset($urls)) { + $notice->saveKnownUrls($urls); + } else { + $notice->saveUrls(); + } // Prepare inbox delivery, may be queued to background. $notice->distribute(); @@ -427,6 +432,25 @@ class Notice extends Memcached_DataObject common_replace_urls_callback($this->content, array($this, 'saveUrl'), $this->id); } + /** + * Save the given URLs as related links/attachments to the db + * + * follow redirects and save all available file information + * (mimetype, date, size, oembed, etc.) + * + * @return void + */ + function saveKnownUrls($urls) + { + // @fixme validation? + foreach ($urls as $url) { + File::processNew($url, $this->id); + } + } + + /** + * @private callback + */ function saveUrl($data) { list($url, $notice_id) = $data; File::processNew($url, $notice_id); diff --git a/js/util.js b/js/util.js index d08c46fe64..3efda0d7b9 100644 --- a/js/util.js +++ b/js/util.js @@ -423,8 +423,11 @@ var SN = { // StatusNet }; notice.find('a.attachment').click(function() { - $().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'}); - return false; + var attachId = ($(this).attr('id').substring('attachment'.length + 1)); + if (attachId) { + $().jOverlay({url: $('address .url')[0].href+'attachment/' + attachId + '/ajax'}); + return false; + } }); if ($('#shownotice').length == 0) { diff --git a/lib/activity.php b/lib/activity.php index b201532138..ce14fa2546 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -1044,6 +1044,7 @@ class Activity public $id; // ID of the activity public $title; // title of the activity public $categories = array(); // list of AtomCategory objects + public $enclosures = array(); // list of enclosure URL references /** * Turns a regular old Atom into a magical activity @@ -1140,6 +1141,10 @@ class Activity $this->categories[] = new AtomCategory($catEl); } } + + foreach (ActivityUtils::getLinks($entry, 'enclosure') as $link) { + $this->enclosures[] = $link->getAttribute('href'); + } } /** diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index a33e95d932..059c19e7c2 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -550,7 +550,8 @@ class Ostatus_profile extends Memcached_DataObject 'rendered' => $rendered, 'replies' => array(), 'groups' => array(), - 'tags' => array()); + 'tags' => array(), + 'urls' => array()); // Check for optional attributes... @@ -595,6 +596,12 @@ class Ostatus_profile extends Memcached_DataObject } } + // Atom enclosures -> attachment URLs + foreach ($activity->enclosures as $href) { + // @fixme save these locally or....? + $options['urls'][] = $href; + } + try { $saved = Notice::saveNew($oprofile->profile_id, $content, @@ -620,7 +627,8 @@ class Ostatus_profile extends Memcached_DataObject protected function purify($html) { require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php'; - $config = array('safe' => 1); + $config = array('safe' => 1, + 'deny_attribute' => 'id,style,on*'); return htmLawed($html, $config); } From ca21f1da8603be348c1a34a8bcc3e7610b9a395d Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 2 Mar 2010 16:49:29 -0800 Subject: [PATCH 21/22] - Have Twitter bridge check for a global key and secret if it can't find one in the local config - Refuse to work at all if the consumer key and secret aren't set --- plugins/TwitterBridge/README | 17 +++- plugins/TwitterBridge/TwitterBridgePlugin.php | 98 +++++++++++++------ plugins/TwitterBridge/twitteroauthclient.php | 21 +++- 3 files changed, 101 insertions(+), 35 deletions(-) diff --git a/plugins/TwitterBridge/README b/plugins/TwitterBridge/README index 72278b32e6..5117cf69ac 100644 --- a/plugins/TwitterBridge/README +++ b/plugins/TwitterBridge/README @@ -20,7 +20,7 @@ on Twitter (http://twitter.com/apps). During the application registration process your application will be assigned a "consumer" key and secret, which the plugin will use to make OAuth requests to Twitter. You can either pass the consumer key and secret in when you enable the -plugin, or set it using the Twitter administration panel. +plugin, or set it using the Twitter administration panel**. When registering your application with Twitter set the type to "Browser" and your Callback URL to: @@ -42,11 +42,26 @@ To enable the plugin, add the following to your config.php: ) ); +or just: + + addPlugin('TwitterBridge'); + +if you want to set the consumer key and secret from the Twitter bridge +administration panel. (The Twitter bridge wont work at all +unless you configure it with a consumer key and secret.) + * Note: The plugin will still push notices to Twitter for users who have previously set up the Twitter bridge using their Twitter name and password under an older version of StatusNet, but all new Twitter bridge connections will use OAuth. +** For multi-site setups you can also set a global consumer key and and + secret. The Twitter bridge will fall back on the global key pair if + it can't find a local pair, e.g.: + + $config['twitter']['global_consumer_key'] = 'YOUR_CONSUMER_KEY' + $config['twitter']['global_consumer_secret'] = 'YOUR_CONSUMER_SECRET' + Administration panel -------------------- diff --git a/plugins/TwitterBridge/TwitterBridgePlugin.php b/plugins/TwitterBridge/TwitterBridgePlugin.php index 6ce69d5e2b..bc702e745b 100644 --- a/plugins/TwitterBridge/TwitterBridgePlugin.php +++ b/plugins/TwitterBridge/TwitterBridgePlugin.php @@ -79,6 +79,30 @@ class TwitterBridgePlugin extends Plugin } } + /** + * Check to see if there is a consumer key and secret defined + * for Twitter integration. + * + * @return boolean result + */ + + static function hasKeys() + { + $key = common_config('twitter', 'consumer_key'); + $secret = common_config('twitter', 'consumer_secret'); + + if (empty($key) && empty($secret)) { + $key = common_config('twitter', 'global_consumer_key'); + $secret = common_config('twitter', 'global_consumer_secret'); + } + + if (!empty($key) && !empty($secret)) { + return true; + } + + return false; + } + /** * Add Twitter-related paths to the router table * @@ -91,14 +115,22 @@ class TwitterBridgePlugin extends Plugin function onRouterInitialized($m) { - $m->connect( - 'twitter/authorization', - array('action' => 'twitterauthorization') - ); - $m->connect('settings/twitter', array('action' => 'twittersettings')); - - if (common_config('twitter', 'signin')) { - $m->connect('main/twitterlogin', array('action' => 'twitterlogin')); + if (self::hasKeys()) { + $m->connect( + 'twitter/authorization', + array('action' => 'twitterauthorization') + ); + $m->connect( + 'settings/twitter', array( + 'action' => 'twittersettings' + ) + ); + if (common_config('twitter', 'signin')) { + $m->connect( + 'main/twitterlogin', + array('action' => 'twitterlogin') + ); + } } $m->connect('admin/twitter', array('action' => 'twitteradminpanel')); @@ -117,7 +149,7 @@ class TwitterBridgePlugin extends Plugin { $action_name = $action->trimmed('action'); - if (common_config('twitter', 'signin')) { + if (self::hasKeys() && common_config('twitter', 'signin')) { $action->menuItem( common_local_url('twitterlogin'), _m('Twitter'), @@ -138,15 +170,16 @@ class TwitterBridgePlugin extends Plugin */ function onEndConnectSettingsNav(&$action) { - $action_name = $action->trimmed('action'); - - $action->menuItem( - common_local_url('twittersettings'), - _m('Twitter'), - _m('Twitter integration options'), - $action_name === 'twittersettings' - ); + if (self::hasKeys()) { + $action_name = $action->trimmed('action'); + $action->menuItem( + common_local_url('twittersettings'), + _m('Twitter'), + _m('Twitter integration options'), + $action_name === 'twittersettings' + ); + } return true; } @@ -188,12 +221,12 @@ class TwitterBridgePlugin extends Plugin */ function onStartEnqueueNotice($notice, &$transports) { - // Avoid a possible loop - - if ($notice->source != 'twitter') { - array_push($transports, 'twitter'); + if (self::hasKeys()) { + // Avoid a possible loop + if ($notice->source != 'twitter') { + array_push($transports, 'twitter'); + } } - return true; } @@ -206,18 +239,19 @@ class TwitterBridgePlugin extends Plugin */ function onGetValidDaemons($daemons) { - array_push( - $daemons, - INSTALLDIR - . '/plugins/TwitterBridge/daemons/synctwitterfriends.php' - ); - - if (common_config('twitterimport', 'enabled')) { + if (self::hasKeys()) { array_push( $daemons, INSTALLDIR - . '/plugins/TwitterBridge/daemons/twitterstatusfetcher.php' + . '/plugins/TwitterBridge/daemons/synctwitterfriends.php' ); + if (common_config('twitterimport', 'enabled')) { + array_push( + $daemons, + INSTALLDIR + . '/plugins/TwitterBridge/daemons/twitterstatusfetcher.php' + ); + } } return true; @@ -232,7 +266,9 @@ class TwitterBridgePlugin extends Plugin */ function onEndInitializeQueueManager($manager) { - $manager->connect('twitter', 'TwitterQueueHandler'); + if (self::hasKeys()) { + $manager->connect('twitter', 'TwitterQueueHandler'); + } return true; } diff --git a/plugins/TwitterBridge/twitteroauthclient.php b/plugins/TwitterBridge/twitteroauthclient.php index ba45b533dc..93f6aadd1e 100644 --- a/plugins/TwitterBridge/twitteroauthclient.php +++ b/plugins/TwitterBridge/twitteroauthclient.php @@ -22,7 +22,7 @@ * @category Integration * @package StatusNet * @author Zach Copley - * @copyright 2009 StatusNet, Inc. + * @copyright 2009-2010 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ @@ -61,8 +61,23 @@ class TwitterOAuthClient extends OAuthClient $consumer_key = common_config('twitter', 'consumer_key'); $consumer_secret = common_config('twitter', 'consumer_secret'); - parent::__construct($consumer_key, $consumer_secret, - $oauth_token, $oauth_token_secret); + if (empty($consumer_key) && empty($consumer_secret)) { + $consumer_key = common_config( + 'twitter', + 'global_consumer_key' + ); + $consumer_secret = common_config( + 'twitter', + 'global_consumer_secret' + ); + } + + parent::__construct( + $consumer_key, + $consumer_secret, + $oauth_token, + $oauth_token_secret + ); } // XXX: the following two functions are to support the horrible hack From 08422dfa17a5c52d51f21087be0f1d8d602ed0af Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 2 Mar 2010 16:53:37 -0800 Subject: [PATCH 22/22] Remove double word from Twitter bridge README --- plugins/TwitterBridge/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/TwitterBridge/README b/plugins/TwitterBridge/README index 5117cf69ac..d0d34b7ef2 100644 --- a/plugins/TwitterBridge/README +++ b/plugins/TwitterBridge/README @@ -55,7 +55,7 @@ unless you configure it with a consumer key and secret.) password under an older version of StatusNet, but all new Twitter bridge connections will use OAuth. -** For multi-site setups you can also set a global consumer key and and +** For multi-site setups you can also set a global consumer key and secret. The Twitter bridge will fall back on the global key pair if it can't find a local pair, e.g.: