Merge branch 'testing' of git@gitorious.org:statusnet/mainline into testing

This commit is contained in:
Zach Copley 2010-03-03 00:54:35 +00:00
commit 097e3f89b6
36 changed files with 327 additions and 219 deletions

View File

@ -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

View File

@ -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()

View File

@ -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();

View File

@ -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()) {

View File

@ -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()) {

View File

@ -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()) {

View File

@ -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()) {

View File

@ -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
);
}

View File

@ -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()) {

View File

@ -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;
}

View File

@ -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()) {

View File

@ -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 ';

View File

@ -279,10 +279,19 @@ class File extends Memcached_DataObject
if($oembed->modified) $enclosure->modified=$oembed->modified;
unset($oembed->size);
}
} else {
return false;
}
}
}
return $enclosure;
}
// quick back-compat hack, since there's still code using this
function isEnclosure()
{
$enclosure = $this->getEnclosure();
return !empty($enclosure);
}
}

View File

@ -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.

View File

@ -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);
@ -559,17 +583,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 +622,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 +636,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 +669,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()) {
@ -1134,7 +1150,6 @@ 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());
@ -1270,16 +1285,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);

View File

@ -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');
}

View File

@ -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)) {

View File

@ -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)) {

View File

@ -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)) {

View File

@ -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 ';

View File

@ -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)) {

View File

@ -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'
}
@ -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) {
@ -494,7 +497,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 +540,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: '/' });
});
}

View File

@ -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 <entry> 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');
}
}
/**

View File

@ -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;
}
@ -289,11 +291,12 @@ class ApiAction extends Action
$twitter_status['attachments'] = array();
foreach ($attachments as $attachment) {
if ($attachment->isEnclosure()) {
$enclosure_o=$attachment->getEnclosure();
if ($enclosure_o) {
$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;
}
}
@ -1325,8 +1328,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);
}

View File

@ -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);

View File

@ -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');
}

View File

@ -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);
}
@ -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;
}
}
}

View File

@ -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

View File

@ -705,6 +705,20 @@ class OStatusPlugin extends Plugin
}
function onStartShowSubscriptionsContent($action)
{
$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)) {
@ -717,8 +731,6 @@ class OStatusPlugin extends Plugin
$action->elementEnd('p');
$action->elementEnd('div');
}
return true;
}
/**

View File

@ -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');

View File

@ -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);
}

View File

@ -38,11 +38,11 @@ display:none;
min-width:96px;
}
#subscriptions #entity_remote_subscribe {
#entity_remote_subscribe {
padding:0;
float:right;
}
#subscriptions .entity_remote_subscribe {
float:right;
#all #entity_remote_subscribe {
margin-top:-52px;
}

View File

@ -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');
}
}

View File

@ -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
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
--------------------

View File

@ -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;
}

View File

@ -22,7 +22,7 @@
* @category Integration
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @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