diff options
author | Zach Copley <zach@status.net> | 2010-02-26 21:34:39 +0000 |
---|---|---|
committer | Zach Copley <zach@status.net> | 2010-02-26 21:34:39 +0000 |
commit | 1883da64185022866572f9eb27938b4cc7724328 (patch) | |
tree | a21f97c220b8b4da4435756979a2c5ec74c58773 /lib | |
parent | d4b47eb6995942f1a906eb3cd5c6bd8c98c3b2cf (diff) | |
parent | c82cee18769763d105304f09de9b6b4079e48aae (diff) |
Merge branch 'testing' of git@gitorious.org:statusnet/mainline into testing
Diffstat (limited to 'lib')
-rw-r--r-- | lib/action.php | 2 | ||||
-rw-r--r-- | lib/activity.php | 380 | ||||
-rw-r--r-- | lib/adminpanelaction.php | 29 | ||||
-rw-r--r-- | lib/apiaction.php (renamed from lib/api.php) | 21 | ||||
-rw-r--r-- | lib/apiauth.php | 1 | ||||
-rw-r--r-- | lib/atomnoticefeed.php | 5 | ||||
-rw-r--r-- | lib/common.php | 2 | ||||
-rw-r--r-- | lib/default.php | 1 | ||||
-rw-r--r-- | lib/distribqueuehandler.php | 12 | ||||
-rw-r--r-- | lib/joinform.php | 2 | ||||
-rw-r--r-- | lib/leaveform.php | 2 | ||||
-rw-r--r-- | lib/noticelist.php | 23 | ||||
-rw-r--r-- | lib/profilequeuehandler.php | 52 | ||||
-rw-r--r-- | lib/queuemanager.php | 3 | ||||
-rw-r--r-- | lib/router.php | 7 | ||||
-rw-r--r-- | lib/util.php | 22 |
16 files changed, 465 insertions, 99 deletions
diff --git a/lib/action.php b/lib/action.php index fa9ddb911..a7e0eb33b 100644 --- a/lib/action.php +++ b/lib/action.php @@ -976,7 +976,7 @@ class Action extends HTMLOutputter // lawsuit if (is_null($arg)) { return $def; - } else if (in_array($arg, array('true', 'yes', '1'))) { + } else if (in_array($arg, array('true', 'yes', '1', 'on'))) { return true; } else if (in_array($arg, array('false', 'no', '0'))) { return false; diff --git a/lib/activity.php b/lib/activity.php index 5cbab8d5f..b20153213 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -154,7 +154,15 @@ class PoCo PoCo::NS ); - array_push($urls, new PoCoURL($type, $value, $primary)); + $isPrimary = false; + + if (isset($primary) && $primary == 'true') { + $isPrimary = true; + } + + // @todo check to make sure a primary hasn't already been added + + array_push($urls, new PoCoURL($type, $value, $isPrimary)); } return $urls; } @@ -167,16 +175,18 @@ class PoCo PoCo::NS ); - $formatted = ActivityUtils::childContent( - $addressEl, - PoCoAddress::FORMATTED, - self::NS - ); + if (!empty($addressEl)) { + $formatted = ActivityUtils::childContent( + $addressEl, + PoCoAddress::FORMATTED, + self::NS + ); - if (!empty($formatted)) { - $address = new PoCoAddress(); - $address->formatted = $formatted; - return $address; + if (!empty($formatted)) { + $address = new PoCoAddress(); + $address->formatted = $formatted; + return $address; + } } return null; @@ -213,6 +223,46 @@ class PoCo return $poco; } + function fromGroup($group) + { + if (empty($group)) { + return null; + } + + $poco = new PoCo(); + + $poco->preferredUsername = $group->nickname; + $poco->displayName = $group->getBestName(); + + $poco->note = $group->description; + + $paddy = new PoCoAddress(); + $paddy->formatted = $group->location; + $poco->address = $paddy; + + if (!empty($group->homepage)) { + array_push( + $poco->urls, + new PoCoURL( + 'homepage', + $group->homepage, + true + ) + ); + } + + return $poco; + } + + function getPrimaryURL() + { + foreach ($this->urls as $url) { + if ($url->primary) { + return $url; + } + } + } + function asString() { $xs = new XMLStringer(true); @@ -292,7 +342,7 @@ class ActivityUtils * @return string related link, if any */ - static function getLink($element, $rel, $type=null) + static function getLink(DOMNode $element, $rel, $type=null) { $links = $element->getElementsByTagnameNS(self::ATOM, self::LINK); @@ -310,6 +360,25 @@ class ActivityUtils return null; } + static function getLinks(DOMNode $element, $rel, $type=null) + { + $links = $element->getElementsByTagnameNS(self::ATOM, self::LINK); + $out = array(); + + foreach ($links as $link) { + + $linkRel = $link->getAttribute(self::REL); + $linkType = $link->getAttribute(self::TYPE); + + if ($linkRel == $rel && + (is_null($type) || $linkType == $type)) { + $out[] = $link; + } + } + + return $out; + } + /** * Gets the first child element with the given tag * @@ -320,7 +389,7 @@ class ActivityUtils * @return DOMElement found element or null */ - static function child($element, $tag, $namespace=self::ATOM) + static function child(DOMNode $element, $tag, $namespace=self::ATOM) { $els = $element->childNodes; if (empty($els) || $els->length == 0) { @@ -345,7 +414,7 @@ class ActivityUtils * @return string content of the child */ - static function childContent($element, $tag, $namespace=self::ATOM) + static function childContent(DOMNode $element, $tag, $namespace=self::ATOM) { $el = self::child($element, $tag, $namespace); @@ -415,6 +484,75 @@ class ActivityUtils } } +// XXX: Arg! This wouldn't be necessary if we used Avatars conistently +class AvatarLink +{ + public $url; + public $type; + public $size; + public $width; + public $height; + + function __construct($element=null) + { + if ($element) { + // @fixme use correct namespaces + $this->url = $element->getAttribute('href'); + $this->type = $element->getAttribute('type'); + $width = $element->getAttribute('media:width'); + if ($width != null) { + $this->width = intval($width); + } + $height = $element->getAttribute('media:height'); + if ($height != null) { + $this->height = intval($height); + } + } + } + + static function fromAvatar($avatar) + { + if (empty($avatar)) { + return null; + } + $alink = new AvatarLink(); + $alink->type = $avatar->mediatype; + $alink->height = $avatar->height; + $alink->width = $avatar->width; + $alink->url = $avatar->displayUrl(); + return $alink; + } + + static function fromFilename($filename, $size) + { + $alink = new AvatarLink(); + $alink->url = $filename; + $alink->height = $size; + if (!empty($filename)) { + $alink->width = $size; + $alink->type = self::mediatype($filename); + } else { + $alink->url = User_group::defaultLogo($size); + $alink->type = 'image/png'; + } + return $alink; + } + + // yuck! + static function mediatype($filename) { + $ext = strtolower(end(explode('.', $filename))); + if ($ext == 'jpeg') { + $ext = 'jpg'; + } + // hope we don't support any others + $types = array('png', 'gif', 'jpg', 'jpeg'); + if (in_array($ext, $types)) { + return 'image/' . $ext; + } + return null; + } +} + /** * A noun-ish thing in the activity universe * @@ -471,7 +609,7 @@ class ActivityObject public $content; public $link; public $source; - public $avatar; + public $avatarLinks = array(); public $geopoint; public $poco; public $displayName; @@ -494,6 +632,12 @@ class ActivityObject $this->element = $element; + $this->geopoint = $this->_childContent( + $element, + ActivityContext::POINT, + ActivityContext::GEORSS + ); + if ($element->tagName == 'author') { $this->type = self::PERSON; // XXX: is this fair? @@ -533,8 +677,10 @@ class ActivityObject if ($this->type == self::PERSON || $this->type == self::GROUP) { $this->displayName = $this->title; - // @fixme we may have multiple avatars with different resolutions specified - $this->avatar = ActivityUtils::getLink($element, 'avatar'); + $avatars = ActivityUtils::getLinks($element, 'avatar'); + foreach ($avatars as $link) { + $this->avatarLinks[] = new AvatarLink($link); + } $this->poco = new PoCo($element); } @@ -585,10 +731,40 @@ class ActivityObject $object->id = $profile->getUri(); $object->title = $profile->getBestName(); $object->link = $profile->profileurl; - $object->avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); + + $orig = $profile->getOriginalAvatar(); + + if (!empty($orig)) { + $object->avatarLinks[] = AvatarLink::fromAvatar($orig); + } + + $sizes = array( + AVATAR_PROFILE_SIZE, + AVATAR_STREAM_SIZE, + AVATAR_MINI_SIZE + ); + + foreach ($sizes as $size) { + + $alink = null; + $avatar = $profile->getAvatar($size); + + if (!empty($avatar)) { + $alink = AvatarLink::fromAvatar($avatar); + } else { + $alink = new AvatarLink(); + $alink->type = 'image/png'; + $alink->height = $size; + $alink->width = $size; + $alink->url = Avatar::defaultImage($size); + } + + $object->avatarLinks[] = $alink; + } if (isset($profile->lat) && isset($profile->lon)) { - $object->geopoint = (float)$profile->lat . ' ' . (float)$profile->lon; + $object->geopoint = (float)$profile->lat + . ' ' . (float)$profile->lon; } $object->poco = PoCo::fromProfile($profile); @@ -596,6 +772,36 @@ class ActivityObject return $object; } + static function fromGroup($group) + { + $object = new ActivityObject(); + + $object->type = ActivityObject::GROUP; + $object->id = $group->getUri(); + $object->title = $group->getBestName(); + $object->link = $group->getUri(); + + $object->avatarLinks[] = AvatarLink::fromFilename( + $group->homepage_logo, + AVATAR_PROFILE_SIZE + ); + + $object->avatarLinks[] = AvatarLink::fromFilename( + $group->stream_logo, + AVATAR_STREAM_SIZE + ); + + $object->avatarLinks[] = AvatarLink::fromFilename( + $group->mini_logo, + AVATAR_MINI_SIZE + ); + + $object->poco = PoCo::fromGroup($group); + + return $object; + } + + function asString($tag='activity:object') { $xs = new XMLStringer(true); @@ -633,16 +839,19 @@ class ActivityObject if ($this->type == ActivityObject::PERSON || $this->type == ActivityObject::GROUP) { - $xs->element( - 'link', array( - 'type' => empty($this->avatar) ? 'image/png' : $this->avatar->mediatype, - 'rel' => 'avatar', - 'href' => empty($this->avatar) - ? Avatar::defaultImage(AVATAR_PROFILE_SIZE) - : $this->avatar->displayUrl() - ), - null - ); + + foreach ($this->avatarLinks as $avatar) { + $xs->element( + 'link', array( + 'rel' => 'avatar', + 'type' => $avatar->type, + 'media:width' => $avatar->width, + 'media:height' => $avatar->height, + 'href' => $avatar->url + ), + null + ); + } } if (!empty($this->geopoint)) { @@ -691,6 +900,9 @@ class ActivityVerb const UNFAVORITE = 'http://ostatus.org/schema/1.0/unfavorite'; const UNFOLLOW = 'http://ostatus.org/schema/1.0/unfollow'; const LEAVE = 'http://ostatus.org/schema/1.0/leave'; + + // For simple profile-update pings; no content to share. + const UPDATE_PROFILE = 'http://ostatus.org/schema/1.0/update-profile'; } class ActivityContext @@ -756,22 +968,29 @@ class ActivityContext for ($i = 0; $i < $points->length; $i++) { $point = $points->item($i)->textContent; - $point = str_replace(',', ' ', $point); // per spec "treat commas as whitespace" - $point = preg_replace('/\s+/', ' ', $point); - $point = trim($point); - $coords = explode(' ', $point); - if (count($coords) == 2) { - list($lat, $lon) = $coords; - if (is_numeric($lat) && is_numeric($lon)) { - common_log(LOG_INFO, "Looking up location for $lat $lon from georss"); - return Location::fromLatLon($lat, $lon); - } - } - common_log(LOG_ERR, "Ignoring bogus georss:point value $point"); + return self::locationFromPoint($point); } return null; } + + // XXX: Move to ActivityUtils or Location? + static function locationFromPoint($point) + { + $point = str_replace(',', ' ', $point); // per spec "treat commas as whitespace" + $point = preg_replace('/\s+/', ' ', $point); + $point = trim($point); + $coords = explode(' ', $point); + if (count($coords) == 2) { + list($lat, $lon) = $coords; + if (is_numeric($lat) && is_numeric($lon)) { + common_log(LOG_INFO, "Looking up location for $lat $lon from georss point"); + return Location::fromLatLon($lat, $lon); + } + } + common_log(LOG_ERR, "Ignoring bogus georss:point value $point"); + return null; + } } /** @@ -824,6 +1043,7 @@ class Activity public $content; // HTML content of activity public $id; // ID of the activity public $title; // title of the activity + public $categories = array(); // list of AtomCategory objects /** * Turns a regular old Atom <entry> into a magical activity @@ -912,6 +1132,14 @@ class Activity $this->summary = ActivityUtils::childContent($entry, 'summary'); $this->id = ActivityUtils::childContent($entry, 'id'); $this->content = ActivityUtils::getContent($entry); + + $catEls = $entry->getElementsByTagNameNS(self::ATOM, 'category'); + if ($catEls) { + for ($i = 0; $i < $catEls->length; $i++) { + $catEl = $catEls->item($i); + $this->categories[] = new AtomCategory($catEl); + } + } } /** @@ -934,7 +1162,8 @@ class Activity 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', - 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0'); + 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', + 'xmlns:media' => 'http://purl.org/syndication/atommedia'); } else { $attrs = array(); } @@ -957,11 +1186,28 @@ class Activity } // XXX: add context - // XXX: add target + $xs->elementStart('author'); + $xs->element('uri', array(), $this->actor->id); + if ($this->actor->title) { + $xs->element('name', array(), $this->actor->title); + } + $xs->elementEnd('author'); $xs->raw($this->actor->asString('activity:actor')); + $xs->element('activity:verb', null, $this->verb); - $xs->raw($this->object->asString()); + + if ($this->object) { + $xs->raw($this->object->asString()); + } + + if ($this->target) { + $xs->raw($this->target->asString('activity:target')); + } + + foreach ($this->categories as $cat) { + $xs->raw($cat->asString()); + } $xs->elementEnd('entry'); @@ -972,4 +1218,50 @@ class Activity { return ActivityUtils::child($element, $tag, $namespace); } -}
\ No newline at end of file +} + +class AtomCategory +{ + public $term; + public $scheme; + public $label; + + function __construct($element=null) + { + if ($element && $element->attributes) { + $this->term = $this->extract($element, 'term'); + $this->scheme = $this->extract($element, 'scheme'); + $this->label = $this->extract($element, 'label'); + } + } + + protected function extract($element, $attrib) + { + $node = $element->attributes->getNamedItemNS(Activity::ATOM, $attrib); + if ($node) { + return trim($node->textContent); + } + $node = $element->attributes->getNamedItem($attrib); + if ($node) { + return trim($node->textContent); + } + return null; + } + + function asString() + { + $attribs = array(); + if ($this->term !== null) { + $attribs['term'] = $this->term; + } + if ($this->scheme !== null) { + $attribs['scheme'] = $this->scheme; + } + if ($this->label !== null) { + $attribs['label'] = $this->label; + } + $xs = new XMLStringer(); + $xs->element('category', $attribs); + return $xs->asString(); + } +} diff --git a/lib/adminpanelaction.php b/lib/adminpanelaction.php index f05627b31..536d97cdf 100644 --- a/lib/adminpanelaction.php +++ b/lib/adminpanelaction.php @@ -103,7 +103,7 @@ class AdminPanelAction extends Action $name = mb_substr($name, 0, -10); - if (!in_array($name, common_config('admin', 'panels'))) { + if (!self::canAdmin($name)) { $this->clientError(_('Changes to that panel are not allowed.'), 403); return false; } @@ -262,6 +262,17 @@ class AdminPanelAction extends Action return $result; } + + function canAdmin($name) + { + $isOK = false; + + if (Event::handle('AdminPanelCheck', array($name, &$isOK))) { + $isOK = in_array($name, common_config('admin', 'panels')); + } + + return $isOK; + } } /** @@ -307,32 +318,32 @@ class AdminPanelNav extends Widget if (Event::handle('StartAdminPanelNav', array($this))) { - if ($this->canAdmin('site')) { + if (AdminPanelAction::canAdmin('site')) { $this->out->menuItem(common_local_url('siteadminpanel'), _('Site'), _('Basic site configuration'), $action_name == 'siteadminpanel', 'nav_site_admin_panel'); } - if ($this->canAdmin('design')) { + if (AdminPanelAction::canAdmin('design')) { $this->out->menuItem(common_local_url('designadminpanel'), _('Design'), _('Design configuration'), $action_name == 'designadminpanel', 'nav_design_admin_panel'); } - if ($this->canAdmin('user')) { + if (AdminPanelAction::canAdmin('user')) { $this->out->menuItem(common_local_url('useradminpanel'), _('User'), _('User configuration'), $action_name == 'useradminpanel', 'nav_design_admin_panel'); } - if ($this->canAdmin('access')) { + if (AdminPanelAction::canAdmin('access')) { $this->out->menuItem(common_local_url('accessadminpanel'), _('Access'), _('Access configuration'), $action_name == 'accessadminpanel', 'nav_design_admin_panel'); } - if ($this->canAdmin('paths')) { + if (AdminPanelAction::canAdmin('paths')) { $this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'), _('Paths configuration'), $action_name == 'pathsadminpanel', 'nav_design_admin_panel'); } - if ($this->canAdmin('sessions')) { + if (AdminPanelAction::canAdmin('sessions')) { $this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'), _('Sessions configuration'), $action_name == 'sessionsadminpanel', 'nav_design_admin_panel'); } @@ -342,8 +353,4 @@ class AdminPanelNav extends Widget $this->action->elementEnd('ul'); } - function canAdmin($name) - { - return in_array($name, common_config('admin', 'panels')); - } } diff --git a/lib/api.php b/lib/apiaction.php index 0bcf4cc21..2af150ab9 100644 --- a/lib/api.php +++ b/lib/apiaction.php @@ -1218,7 +1218,12 @@ class ApiAction extends Action return User_group::staticGet($this->arg('id')); } else if ($this->arg('id')) { $nickname = common_canonical_nickname($this->arg('id')); - return User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if (empty($local)) { + return null; + } else { + return User_group::staticGet('id', $local->id); + } } else if ($this->arg('group_id')) { // This is to ensure that a non-numeric user_id still // overrides screen_name even if it doesn't get used @@ -1227,14 +1232,24 @@ class ApiAction extends Action } } else if ($this->arg('group_name')) { $nickname = common_canonical_nickname($this->arg('group_name')); - return User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if (empty($local)) { + return null; + } else { + return User_group::staticGet('id', $local->id); + } } } else if (is_numeric($id)) { return User_group::staticGet($id); } else { $nickname = common_canonical_nickname($id); - return User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if (empty($local)) { + return null; + } else { + return User_group::staticGet('id', $local->group_id); + } } } diff --git a/lib/apiauth.php b/lib/apiauth.php index 25e2196cf..5090871cf 100644 --- a/lib/apiauth.php +++ b/lib/apiauth.php @@ -38,7 +38,6 @@ if (!defined('STATUSNET')) { exit(1); } -require_once INSTALLDIR . '/lib/api.php'; require_once INSTALLDIR . '/lib/apioauth.php'; /** diff --git a/lib/atomnoticefeed.php b/lib/atomnoticefeed.php index d2bf2a416..3c3556cb9 100644 --- a/lib/atomnoticefeed.php +++ b/lib/atomnoticefeed.php @@ -65,6 +65,11 @@ class AtomNoticeFeed extends Atom10Feed ); $this->addNamespace( + 'media', + 'http://purl.org/syndication/atommedia' + ); + + $this->addNamespace( 'poco', 'http://portablecontacts.net/spec/1.0' ); diff --git a/lib/common.php b/lib/common.php index 68723955e..2dbe3b3c5 100644 --- a/lib/common.php +++ b/lib/common.php @@ -22,7 +22,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } //exit with 200 response, if this is checking fancy from the installer if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; } -define('STATUSNET_VERSION', '0.9.0beta5'); +define('STATUSNET_VERSION', '0.9.0beta6'); define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility define('STATUSNET_CODENAME', 'Stand'); diff --git a/lib/default.php b/lib/default.php index bb7708bfc..d849055c2 100644 --- a/lib/default.php +++ b/lib/default.php @@ -278,7 +278,6 @@ $default = 'TightUrl' => array('shortenerName' => '2tu.us', 'freeService' => true,'serviceUrl'=>'http://2tu.us/?save=y&url=%1$s'), 'Geonames' => null, 'Mapstraction' => null, - 'Linkback' => null, 'WikiHashtags' => null, 'OpenID' => null), ), diff --git a/lib/distribqueuehandler.php b/lib/distribqueuehandler.php index dc183fb36..d2be7a92c 100644 --- a/lib/distribqueuehandler.php +++ b/lib/distribqueuehandler.php @@ -63,24 +63,12 @@ class DistribQueueHandler // XXX: do we need to change this for remote users? try { - $notice->saveTags(); - } catch (Exception $e) { - $this->logit($notice, $e); - } - - try { $notice->addToInboxes(); } catch (Exception $e) { $this->logit($notice, $e); } try { - $notice->saveUrls(); - } catch (Exception $e) { - $this->logit($notice, $e); - } - - try { Event::handle('EndNoticeSave', array($notice)); // Enqueue for other handlers } catch (Exception $e) { diff --git a/lib/joinform.php b/lib/joinform.php index aefb553aa..aa8bc20e2 100644 --- a/lib/joinform.php +++ b/lib/joinform.php @@ -100,7 +100,7 @@ class JoinForm extends Form function action() { return common_local_url('joingroup', - array('nickname' => $this->group->nickname)); + array('id' => $this->group->id)); } /** diff --git a/lib/leaveform.php b/lib/leaveform.php index e63d96ee8..5469b5704 100644 --- a/lib/leaveform.php +++ b/lib/leaveform.php @@ -100,7 +100,7 @@ class LeaveForm extends Form function action() { return common_local_url('leavegroup', - array('nickname' => $this->group->nickname)); + array('id' => $this->group->id)); } /** diff --git a/lib/noticelist.php b/lib/noticelist.php index dcf17be08..7d1d2828f 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -380,12 +380,12 @@ class NoticeListItem extends Widget function showNoticeLink() { - if($this->notice->is_local == Notice::LOCAL_PUBLIC || $this->notice->is_local == Notice::LOCAL_NONPUBLIC){ - $noticeurl = common_local_url('shownotice', - array('notice' => $this->notice->id)); - }else{ - $noticeurl = $this->notice->uri; - } + $noticeurl = $this->notice->bestUrl(); + + // above should always return an URL + + assert(!empty($noticeurl)); + $this->out->elementStart('a', array('rel' => 'bookmark', 'class' => 'timestamp', 'href' => $noticeurl)); @@ -540,16 +540,13 @@ class NoticeListItem extends Widget function showContext() { $hasConversation = false; - if( !empty($this->notice->conversation) - && $this->notice->conversation != $this->notice->id){ - $hasConversation = true; - }else{ - $conversation = Notice::conversationStream($this->notice->id, 1, 1); - if($conversation->N > 0){ + if (!empty($this->notice->conversation)) { + $conversation = Notice::conversationStream($this->notice->conversation, 1, 1); + if ($conversation->N > 0) { $hasConversation = true; } } - if ($hasConversation){ + if ($hasConversation) { $this->out->text(' '); $convurl = common_local_url('conversation', array('id' => $this->notice->conversation)); diff --git a/lib/profilequeuehandler.php b/lib/profilequeuehandler.php new file mode 100644 index 000000000..6ce93229b --- /dev/null +++ b/lib/profilequeuehandler.php @@ -0,0 +1,52 @@ +<?php +/* + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2010, StatusNet, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * @package QueueHandler + * @maintainer Brion Vibber <brion@status.net> + */ + +class ProfileQueueHandler extends QueueHandler +{ + + function transport() + { + return 'profile'; + } + + function handle($profile) + { + if (!($profile instanceof Profile)) { + common_log(LOG_ERR, "Got a bogus profile, not broadcasting"); + return true; + } + + if (Event::handle('StartBroadcastProfile', array($profile))) { + require_once(INSTALLDIR.'/lib/omb.php'); + try { + omb_broadcast_profile($profile); + } catch (Exception $e) { + common_log(LOG_ERR, "Failed sending OMB profiles: " . $e->getMessage()); + } + } + Event::handle('EndBroadcastProfile', array($profile)); + return true; + } + +} diff --git a/lib/queuemanager.php b/lib/queuemanager.php index 8f8c8f133..9fdc80110 100644 --- a/lib/queuemanager.php +++ b/lib/queuemanager.php @@ -262,6 +262,9 @@ abstract class QueueManager extends IoManager $this->connect('sms', 'SmsQueueHandler'); } + // Broadcasting profile updates to OMB remote subscribers + $this->connect('profile', 'ProfileQueueHandler'); + // XMPP output handlers... if (common_config('xmpp', 'enabled')) { // Delivery prep, read by queuedaemon.php: diff --git a/lib/router.php b/lib/router.php index 987d0152e..abbce041d 100644 --- a/lib/router.php +++ b/lib/router.php @@ -247,6 +247,9 @@ class Router $m->connect('group/:nickname/'.$v, array('action' => $v.'group'), array('nickname' => '[a-zA-Z0-9]+')); + $m->connect('group/:id/id/'.$v, + array('action' => $v.'group'), + array('id' => '[0-9]+')); } foreach (array('members', 'logo', 'rss', 'designsettings') as $n) { @@ -668,7 +671,7 @@ class Router foreach (array('subscriptions', 'subscribers', 'all', 'foaf', 'xrds', - 'replies', 'microsummary') as $a) { + 'replies', 'microsummary', 'hcard') as $a) { $m->connect($a, array('action' => $a, 'nickname' => $nickname)); @@ -734,7 +737,7 @@ class Router foreach (array('subscriptions', 'subscribers', 'nudge', 'all', 'foaf', 'xrds', - 'replies', 'inbox', 'outbox', 'microsummary') as $a) { + 'replies', 'inbox', 'outbox', 'microsummary', 'hcard') as $a) { $m->connect(':nickname/'.$a, array('action' => $a), array('nickname' => '[a-zA-Z0-9]{1,64}')); diff --git a/lib/util.php b/lib/util.php index 7fb2c6c4b..8381bc63c 100644 --- a/lib/util.php +++ b/lib/util.php @@ -134,7 +134,7 @@ function common_check_user($nickname, $password) $authenticatedUser = false; if (Event::handle('StartCheckPassword', array($nickname, $password, &$authenticatedUser))) { - $user = User::staticGet('nickname', $nickname); + $user = User::staticGet('nickname', common_canonical_nickname($nickname)); if (!empty($user)) { if (!empty($password)) { // never allow login with blank password if (0 == strcmp(common_munge_password($password, $user->id), @@ -1119,12 +1119,16 @@ function common_enqueue_notice($notice) return true; } -function common_broadcast_profile($profile) +/** + * Broadcast profile updates to OMB and other remote subscribers. + * + * Since this may be slow with a lot of subscribers or bad remote sites, + * this is run through the background queues if possible. + */ +function common_broadcast_profile(Profile $profile) { - // XXX: optionally use a queue system like http://code.google.com/p/microapps/wiki/NQDQ - require_once(INSTALLDIR.'/lib/omb.php'); - omb_broadcast_profile($profile); - // XXX: Other broadcasts...? + $qm = QueueManager::get(); + $qm->enqueue($profile, "profile"); return true; } @@ -1602,6 +1606,7 @@ function common_database_tablename($tablename) */ function common_shorten_url($long_url) { + $long_url = trim($long_url); $user = common_current_user(); if (empty($user)) { // common current user does not find a user when called from the XMPP daemon @@ -1616,7 +1621,7 @@ function common_shorten_url($long_url) return $long_url; }else{ //URL was shortened, so return the result - return $shortenedUrl; + return trim($shortenedUrl); } } @@ -1693,7 +1698,8 @@ function common_url_to_nickname($url) # Strip starting, ending slashes $path = preg_replace('@/$@', '', $parts['path']); $path = preg_replace('@^/@', '', $path); - if (strpos($path, '/') === false) { + $path = basename($path); + if ($path) { return common_nicknamize($path); } } |