]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'api-media-upload' into 0.9.x
authorZach Copley <zach@status.net>
Thu, 29 Oct 2009 00:18:33 +0000 (17:18 -0700)
committerZach Copley <zach@status.net>
Thu, 29 Oct 2009 00:18:33 +0000 (17:18 -0700)
* api-media-upload:
  Rearanged a couple things & removed debugging statements
  Rework MailDaemon to use the MediaFile class for uploads
  Implement media upload in the API
  Extract media upload stuff into its own library class.

14 files changed:
EVENTS.txt
actions/newnotice.php
classes/Notice.php
classes/User.php
lib/command.php
lib/commandinterpreter.php
lib/jabber.php
lib/router.php
plugins/Facebook/facebookaction.php
plugins/Facebook/facebookapp.css [new file with mode: 0644]
plugins/Facebook/facebookinvite.php
plugins/OpenID/OpenIDPlugin.php
theme/base/css/facebookapp.css [deleted file]
theme/default/css/display.css

index 5d34a9e13b75ef7ab3730037af4277cfdbd67216..d989557e64713360adeb986da99d467f0dfb3c64 100644 (file)
@@ -129,6 +129,9 @@ StartSubGroupNav: Showing the subscriptions group nav menu
 EndSubGroupNav: At the end of the subscriptions group nav menu
 - $action: the current action
 
+StartInitializeRouter: Before the router instance has been initialized; good place to add routes
+- $m: the Net_URL_Mapper that has just been set up
+
 RouterInitialized: After the router instance has been initialized
 - $m: the Net_URL_Mapper that has just been set up
 
index 59fb9f46199d0411fd2e275cf5eb52fb19599a86..f677c49a96fc4de2fa160ecf5ad613dabbcd9dba 100644 (file)
@@ -134,18 +134,12 @@ class NewnoticeAction extends Action
 
         if (!$content) {
             $this->clientError(_('No content!'));
-        } else {
-            $content_shortened = common_shorten_links($content);
-            if (Notice::contentTooLong($content_shortened)) {
-                $this->clientError(sprintf(_('That\'s too long. '.
-                                             'Max notice size is %d chars.'),
-                                           Notice::maxContent()));
-            }
+            return;
         }
 
         $inter = new CommandInterpreter();
 
-        $cmd = $inter->handle_command($user, $content_shortened);
+        $cmd = $inter->handle_command($user, $content);
 
         if ($cmd) {
             if ($this->boolean('ajax')) {
@@ -156,6 +150,13 @@ class NewnoticeAction extends Action
             return;
         }
 
+        $content_shortened = common_shorten_links($content);
+        if (Notice::contentTooLong($content_shortened)) {
+            $this->clientError(sprintf(_('That\'s too long. '.
+                                         'Max notice size is %d chars.'),
+                                       Notice::maxContent()));
+        }
+
         $replyto = $this->trimmed('inreplyto');
         #If an ID of 0 is wrongly passed here, it will cause a database error,
         #so override it...
index cd3906ca17fb2a7f201056495ac9647392eb3beb..7d4e6182387e8b2a412478fc9f7616f968568ad4 100644 (file)
@@ -172,7 +172,7 @@ class Notice extends Memcached_DataObject
             throw new ClientException(_('Problem saving notice. Too long.'));
         }
 
-        if (!$profile) {
+        if (empty($profile)) {
             throw new ClientException(_('Problem saving notice. Unknown user.'));
         }
 
@@ -269,7 +269,6 @@ class Notice extends Memcached_DataObject
 
             // XXX: do we need to change this for remote users?
 
-            $notice->saveReplies();
             $notice->saveTags();
 
             $notice->addToInboxes();
@@ -307,11 +306,11 @@ class Notice extends Memcached_DataObject
 
     static function checkDupes($profile_id, $content) {
         $profile = Profile::staticGet($profile_id);
-        if (!$profile) {
+        if (empty($profile)) {
             return false;
         }
         $notice = $profile->getNotices(0, NOTICE_CACHE_WINDOW);
-        if ($notice) {
+        if (!empty($notice)) {
             $last = 0;
             while ($notice->fetch()) {
                 if (time() - strtotime($notice->created) >= common_config('site', 'dupelimit')) {
@@ -337,7 +336,7 @@ class Notice extends Memcached_DataObject
 
     static function checkEditThrottle($profile_id) {
         $profile = Profile::staticGet($profile_id);
-        if (!$profile) {
+        if (empty($profile)) {
             return false;
         }
         # Get the Nth notice
@@ -658,7 +657,7 @@ class Notice extends Memcached_DataObject
 
         $cache = common_memcache();
 
-        if (!$cache) {
+        if (empty($cache)) {
             return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null);
         }
 
@@ -719,7 +718,7 @@ class Notice extends Memcached_DataObject
 
         # If there are no hits, just return the value
 
-        if (!$notice) {
+        if (empty($notice)) {
             return $notice;
         }
 
@@ -909,6 +908,18 @@ class Notice extends Memcached_DataObject
             }
         }
 
+        $recipients = $this->saveReplies();
+
+        foreach ($recipients as $recipient) {
+
+            if (!array_key_exists($recipient, $ni)) {
+                $recipientUser = User::staticGet('id', $recipient);
+                if (!empty($recipientUser)) {
+                    $ni[$recipient] = NOTICE_INBOX_SOURCE_REPLY;
+                }
+            }
+        }
+
         $cnt = 0;
 
         $qryhdr = 'INSERT INTO notice_inbox (user_id, notice_id, source, created) VALUES ';
@@ -1061,12 +1072,12 @@ class Notice extends Memcached_DataObject
         for ($i=0; $i<count($names); $i++) {
             $nickname = $names[$i];
             $recipient = common_relative_profile($sender, $nickname, $this->created);
-            if (!$recipient) {
+            if (empty($recipient)) {
                 continue;
             }
             // Don't save replies from blocked profile to local user
             $recipient_user = User::staticGet('id', $recipient->id);
-            if ($recipient_user && $recipient_user->hasBlocked($sender)) {
+            if (!empty($recipient_user) && $recipient_user->hasBlocked($sender)) {
                 continue;
             }
             $reply = new Reply();
@@ -1077,7 +1088,7 @@ class Notice extends Memcached_DataObject
                 $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
                 common_log(LOG_ERR, 'DB error inserting reply: ' . $last_error->message);
                 common_server_error(sprintf(_('DB error inserting reply: %s'), $last_error->message));
-                return;
+                return array();
             } else {
                 $replied[$recipient->id] = 1;
             }
@@ -1101,7 +1112,7 @@ class Notice extends Memcached_DataObject
                         $id = $reply->insert();
                         if (!$id) {
                             common_log_db_error($reply, 'INSERT', __FILE__);
-                            return;
+                            return array();
                         } else {
                             $replied[$recipient->id] = 1;
                         }
@@ -1110,12 +1121,16 @@ class Notice extends Memcached_DataObject
             }
         }
 
-        foreach (array_keys($replied) as $recipient) {
+        $recipientIds = array_keys($replied);
+
+        foreach ($recipientIds as $recipient) {
             $user = User::staticGet('id', $recipient);
             if ($user) {
                 mail_notify_attn($user, $this);
             }
         }
+
+        return $recipientIds;
     }
 
     function asAtomEntry($namespace=false, $source=false)
index 0a70c9801402f8038d1dc59bb72bf0204ce1f3c7..9481399f8a5d042288888ad40a6efbaa18e5d996 100644 (file)
@@ -319,6 +319,7 @@ class User extends Memcached_DataObject
                                                   common_config('site', 'name'),
                                                   $user->nickname),
                                           'system');
+                common_broadcast_notice($notice);
             }
         }
 
index 11d40b8e156da190df5b33aa0a45f8aa36a34041..9efa406964651f8abf3ee1f85e08e93c10420f5b 100644 (file)
@@ -73,7 +73,7 @@ class UntrackCommand extends UnimplementedCommand
     }
 }
 
-class NudgeCommand extends UnimplementedCommand
+class NudgeCommand extends Command
 {
     var $other = null;
     function __construct($user, $other)
@@ -81,6 +81,26 @@ class NudgeCommand extends UnimplementedCommand
         parent::__construct($user);
         $this->other = $other;
     }
+    function execute($channel)
+    {
+        $recipient = User::staticGet('nickname', $this->other);
+        if(! $recipient){
+            $channel->error($this->user, sprintf(_('Could not find a user with nickname %s'),
+                               $this->other));
+        }else{
+            if ($recipient->id == $this->user->id) {
+                $channel->error($this->user, _('It does not make a lot of sense to nudge yourself!'));
+            }else{
+                if ($recipient->email && $recipient->emailnotifynudge) {
+                    mail_notify_nudge($this->user, $recipient);
+                }
+                // XXX: notify by IM
+                // XXX: notify by SMS
+                $channel->output($this->user, sprintf(_('Nudge sent to %s'),
+                               $recipient->nickname));
+            }
+        }
+    }
 }
 
 class InviteCommand extends UnimplementedCommand
@@ -124,18 +144,30 @@ class FavCommand extends Command
 
     function execute($channel)
     {
+        if(substr($this->other,0,1)=='#'){
+            //favoriting a specific notice_id
 
-        $recipient =
-          common_relative_profile($this->user, common_canonical_nickname($this->other));
+            $notice = Notice::staticGet(substr($this->other,1));
+            if (!$notice) {
+                $channel->error($this->user, _('Notice with that id does not exist'));
+                return;
+            }
+            $recipient = $notice->getProfile();
+        }else{
+            //favoriting a given user's last notice
 
-        if (!$recipient) {
-            $channel->error($this->user, _('No such user.'));
-            return;
-        }
-        $notice = $recipient->getCurrentNotice();
-        if (!$notice) {
-            $channel->error($this->user, _('User has no last notice'));
-            return;
+            $recipient =
+              common_relative_profile($this->user, common_canonical_nickname($this->other));
+
+            if (!$recipient) {
+                $channel->error($this->user, _('No such user.'));
+                return;
+            }
+            $notice = $recipient->getCurrentNotice();
+            if (!$notice) {
+                $channel->error($this->user, _('User has no last notice'));
+                return;
+            }
         }
 
         $fave = Fave::addNew($this->user, $notice);
@@ -347,6 +379,71 @@ class MessageCommand extends Command
     }
 }
 
+class ReplyCommand extends Command
+{
+    var $other = null;
+    var $text = null;
+    function __construct($user, $other, $text)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+        $this->text = $text;
+    }
+
+    function execute($channel)
+    {
+        if(substr($this->other,0,1)=='#'){
+            //replying to a specific notice_id
+
+            $notice = Notice::staticGet(substr($this->other,1));
+            if (!$notice) {
+                $channel->error($this->user, _('Notice with that id does not exist'));
+                return;
+            }
+            $recipient = $notice->getProfile();
+        }else{
+            //replying to a given user's last notice
+
+            $recipient =
+              common_relative_profile($this->user, common_canonical_nickname($this->other));
+
+            if (!$recipient) {
+                $channel->error($this->user, _('No such user.'));
+                return;
+            }
+            $notice = $recipient->getCurrentNotice();
+            if (!$notice) {
+                $channel->error($this->user, _('User has no last notice'));
+                return;
+            }
+        }
+
+        $len = mb_strlen($this->text);
+
+        if ($len == 0) {
+            $channel->error($this->user, _('No content!'));
+            return;
+        }
+
+        $this->text = common_shorten_links($this->text);
+
+        if (Notice::contentTooLong($this->text)) {
+            $channel->error($this->user, sprintf(_('Notice too long - maximum is %d characters, you sent %d'),
+                                                 Notice::maxContent(), mb_strlen($this->text)));
+            return;
+        }
+
+        $notice = Notice::saveNew($this->user->id, $this->text, $channel->source(), 1,
+                                  $notice->id);
+        if ($notice) {
+            $channel->output($this->user, sprintf(_('Reply to %s sent'), $recipient->nickname));
+        } else {
+            $channel->error($this->user, _('Error saving notice.'));
+        }
+        common_broadcast_notice($notice);
+    }
+}
+
 class GetCommand extends Command
 {
 
@@ -497,6 +594,9 @@ class HelpCommand extends Command
                            "get <nickname> - get last notice from user\n".
                            "whois <nickname> - get profile info on user\n".
                            "fav <nickname> - add user's last notice as a 'fave'\n".
+                           "fav #<notice_id> - add notice with the given id as a 'fave'\n".
+                           "reply #<notice_id> - reply to notice with a given id\n".
+                           "reply <nickname> - reply to the last notice from user\n".
                            "join <group> - join group\n".
                            "drop <group> - leave group\n".
                            "stats - get your stats\n".
@@ -507,7 +607,7 @@ class HelpCommand extends Command
                            "last <nickname> - same as 'get'\n".
                            "on <nickname> - not yet implemented.\n".
                            "off <nickname> - not yet implemented.\n".
-                           "nudge <nickname> - not yet implemented.\n".
+                           "nudge <nickname> - remind a user to update.\n".
                            "invite <phone number> - not yet implemented.\n".
                            "track <word> - not yet implemented.\n".
                            "untrack <word> - not yet implemented.\n".
index 60fc4c3c44802755af6e8bc1c6a5e4ea54bd92f1..b921a17cc25cedec84860fbd19cdd83f50defe1b 100644 (file)
@@ -134,6 +134,17 @@ class CommandInterpreter
             } else {
                 return new MessageCommand($user, $other, $extra);
             }
+         case 'r':
+         case 'reply':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = $this->split_arg($arg);
+            if (!$extra) {
+                return null;
+            } else {
+                return new ReplyCommand($user, $other, $extra);
+            }
          case 'whois':
             if (!$arg) {
                 return null;
index 3dcdce5dbf349b87b629e9186bcb98ef519d22a9..73f2ec66059a6010fa956a80cdfe528500d27817 100644 (file)
@@ -176,6 +176,7 @@ function jabber_format_entry($profile, $notice)
     $xs = new XMLStringer();
     $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
     $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
+    $xs->element("img", array('src'=> $profile->avatarUrl(AVATAR_MINI_SIZE) , 'alt' => $profile->nickname));
     $xs->element('a', array('href' => $profile->profileurl),
                  $profile->nickname);
     $xs->text(": ");
@@ -184,6 +185,11 @@ function jabber_format_entry($profile, $notice)
     } else {
         $xs->raw(common_render_content($notice->content, $notice));
     }
+    $xs->raw(" ");
+    $xs->element('a', array(
+        'href'=>common_local_url('conversation',
+            array('id' => $notice->conversation)).'#notice-'.$notice->id
+         ),sprintf(_('notice id: %s'),$notice->id));
     $xs->elementEnd('body');
     $xs->elementEnd('html');
 
index 4fb0834fd0fdb38e173968a944b9a3a7cf875e92..dedf73c865732822789a7692d5da243763c28a9a 100644 (file)
@@ -71,562 +71,564 @@ class Router
     {
         $m = Net_URL_Mapper::getInstance();
 
-        // In the "root"
+        if (Event::handle('StartInitializeRouter', array(&$m))) {
 
-        $m->connect('', array('action' => 'public'));
-        $m->connect('rss', array('action' => 'publicrss'));
-        $m->connect('featuredrss', array('action' => 'featuredrss'));
-        $m->connect('favoritedrss', array('action' => 'favoritedrss'));
-        $m->connect('opensearch/people', array('action' => 'opensearch',
-                                               'type' => 'people'));
-        $m->connect('opensearch/notice', array('action' => 'opensearch',
-                                               'type' => 'notice'));
+            // In the "root"
 
-        // docs
+            $m->connect('', array('action' => 'public'));
+            $m->connect('rss', array('action' => 'publicrss'));
+            $m->connect('featuredrss', array('action' => 'featuredrss'));
+            $m->connect('favoritedrss', array('action' => 'favoritedrss'));
+            $m->connect('opensearch/people', array('action' => 'opensearch',
+                                                   'type' => 'people'));
+            $m->connect('opensearch/notice', array('action' => 'opensearch',
+                                                   'type' => 'notice'));
 
-        $m->connect('doc/:title', array('action' => 'doc'));
+            // docs
 
-        // main stuff is repetitive
+            $m->connect('doc/:title', array('action' => 'doc'));
 
-        $main = array('login', 'logout', 'register', 'subscribe',
-                      'unsubscribe', 'confirmaddress', 'recoverpassword',
-                      'invite', 'favor', 'disfavor', 'sup',
-                      'block', 'unblock', 'subedit',
-                      'groupblock', 'groupunblock');
+            // main stuff is repetitive
 
-        foreach ($main as $a) {
-            $m->connect('main/'.$a, array('action' => $a));
-        }
+            $main = array('login', 'logout', 'register', 'subscribe',
+                          'unsubscribe', 'confirmaddress', 'recoverpassword',
+                          'invite', 'favor', 'disfavor', 'sup',
+                          'block', 'unblock', 'subedit',
+                          'groupblock', 'groupunblock');
 
-        $m->connect('main/sup/:seconds', array('action' => 'sup'),
-                    array('seconds' => '[0-9]+'));
+            foreach ($main as $a) {
+                $m->connect('main/'.$a, array('action' => $a));
+            }
 
-        $m->connect('main/tagother/:id', array('action' => 'tagother'));
+            $m->connect('main/sup/:seconds', array('action' => 'sup'),
+                        array('seconds' => '[0-9]+'));
 
-        $m->connect('main/oembed',
-                    array('action' => 'oembed'));
+            $m->connect('main/tagother/:id', array('action' => 'tagother'));
 
-        // these take a code
+            $m->connect('main/oembed',
+                        array('action' => 'oembed'));
 
-        foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) {
-            $m->connect('main/'.$c.'/:code', array('action' => $c));
-        }
+            // these take a code
 
-        // exceptional
+            foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) {
+                $m->connect('main/'.$c.'/:code', array('action' => $c));
+            }
 
-        $m->connect('main/remote', array('action' => 'remotesubscribe'));
-        $m->connect('main/remote?nickname=:nickname', array('action' => 'remotesubscribe'), array('nickname' => '[A-Za-z0-9_-]+'));
+            // exceptional
 
-        foreach (Router::$bare as $action) {
-            $m->connect('index.php?action=' . $action, array('action' => $action));
-        }
+            $m->connect('main/remote', array('action' => 'remotesubscribe'));
+            $m->connect('main/remote?nickname=:nickname', array('action' => 'remotesubscribe'), array('nickname' => '[A-Za-z0-9_-]+'));
 
-        // settings
+            foreach (Router::$bare as $action) {
+                $m->connect('index.php?action=' . $action, array('action' => $action));
+            }
 
-        foreach (array('profile', 'avatar', 'password', 'im',
-                       'email', 'sms', 'userdesign', 'other') as $s) {
-            $m->connect('settings/'.$s, array('action' => $s.'settings'));
-        }
+            // settings
+
+            foreach (array('profile', 'avatar', 'password', 'im',
+                           'email', 'sms', 'userdesign', 'other') as $s) {
+                $m->connect('settings/'.$s, array('action' => $s.'settings'));
+            }
 
-        // search
+            // search
 
-        foreach (array('group', 'people', 'notice') as $s) {
-            $m->connect('search/'.$s, array('action' => $s.'search'));
-            $m->connect('search/'.$s.'?q=:q',
-                        array('action' => $s.'search'),
+            foreach (array('group', 'people', 'notice') as $s) {
+                $m->connect('search/'.$s, array('action' => $s.'search'));
+                $m->connect('search/'.$s.'?q=:q',
+                            array('action' => $s.'search'),
+                            array('q' => '.+'));
+            }
+
+            // The second of these is needed to make the link work correctly
+            // when inserted into the page. The first is needed to match the
+            // route on the way in. Seems to be another Net_URL_Mapper bug to me.
+            $m->connect('search/notice/rss', array('action' => 'noticesearchrss'));
+            $m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),
                         array('q' => '.+'));
-        }
 
-        // The second of these is needed to make the link work correctly
-        // when inserted into the page. The first is needed to match the
-        // route on the way in. Seems to be another Net_URL_Mapper bug to me.
-        $m->connect('search/notice/rss', array('action' => 'noticesearchrss'));
-        $m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),
-                    array('q' => '.+'));
-
-        $m->connect('attachment/:attachment',
-                    array('action' => 'attachment'),
-                    array('attachment' => '[0-9]+'));
-
-        $m->connect('attachment/:attachment/ajax',
-                    array('action' => 'attachment_ajax'),
-                    array('attachment' => '[0-9]+'));
-
-        $m->connect('attachment/:attachment/thumbnail',
-                    array('action' => 'attachment_thumbnail'),
-                    array('attachment' => '[0-9]+'));
-
-        $m->connect('notice/new', array('action' => 'newnotice'));
-        $m->connect('notice/new?replyto=:replyto',
-                    array('action' => 'newnotice'),
-                    array('replyto' => '[A-Za-z0-9_-]+'));
-        $m->connect('notice/new?replyto=:replyto&inreplyto=:inreplyto',
-                    array('action' => 'newnotice'),
-                    array('replyto' => '[A-Za-z0-9_-]+'),
-                    array('inreplyto' => '[0-9]+'));
-
-        $m->connect('notice/:notice/file',
-            array('action' => 'file'),
-            array('notice' => '[0-9]+'));
-
-        $m->connect('notice/:notice',
-                    array('action' => 'shownotice'),
-                    array('notice' => '[0-9]+'));
-        $m->connect('notice/delete', array('action' => 'deletenotice'));
-        $m->connect('notice/delete/:notice',
-                    array('action' => 'deletenotice'),
-                    array('notice' => '[0-9]+'));
-
-        // conversation
-
-        $m->connect('conversation/:id',
-                    array('action' => 'conversation'),
-                    array('id' => '[0-9]+'));
-
-        $m->connect('message/new', array('action' => 'newmessage'));
-        $m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => '[A-Za-z0-9_-]+'));
-        $m->connect('message/:message',
-                    array('action' => 'showmessage'),
-                    array('message' => '[0-9]+'));
-
-        $m->connect('user/:id',
-                    array('action' => 'userbyid'),
-                    array('id' => '[0-9]+'));
-
-        $m->connect('tags/', array('action' => 'publictagcloud'));
-        $m->connect('tag/', array('action' => 'publictagcloud'));
-        $m->connect('tags', array('action' => 'publictagcloud'));
-        $m->connect('tag', array('action' => 'publictagcloud'));
-        $m->connect('tag/:tag/rss',
-                    array('action' => 'tagrss'),
-                    array('tag' => '[a-zA-Z0-9]+'));
-        $m->connect('tag/:tag',
-                    array('action' => 'tag'),
-                    array('tag' => '[\pL\pN_\-\.]{1,64}'));
-
-        $m->connect('peopletag/:tag',
-                    array('action' => 'peopletag'),
-                    array('tag' => '[a-zA-Z0-9]+'));
-
-        $m->connect('featured/', array('action' => 'featured'));
-        $m->connect('featured', array('action' => 'featured'));
-        $m->connect('favorited/', array('action' => 'favorited'));
-        $m->connect('favorited', array('action' => 'favorited'));
-
-        // groups
-
-        $m->connect('group/new', array('action' => 'newgroup'));
-
-        foreach (array('edit', 'join', 'leave') as $v) {
-            $m->connect('group/:nickname/'.$v,
-                        array('action' => $v.'group'),
+            $m->connect('attachment/:attachment',
+                        array('action' => 'attachment'),
+                        array('attachment' => '[0-9]+'));
+
+            $m->connect('attachment/:attachment/ajax',
+                        array('action' => 'attachment_ajax'),
+                        array('attachment' => '[0-9]+'));
+
+            $m->connect('attachment/:attachment/thumbnail',
+                        array('action' => 'attachment_thumbnail'),
+                        array('attachment' => '[0-9]+'));
+
+            $m->connect('notice/new', array('action' => 'newnotice'));
+            $m->connect('notice/new?replyto=:replyto',
+                        array('action' => 'newnotice'),
+                        array('replyto' => '[A-Za-z0-9_-]+'));
+            $m->connect('notice/new?replyto=:replyto&inreplyto=:inreplyto',
+                        array('action' => 'newnotice'),
+                        array('replyto' => '[A-Za-z0-9_-]+'),
+                        array('inreplyto' => '[0-9]+'));
+
+            $m->connect('notice/:notice/file',
+                        array('action' => 'file'),
+                        array('notice' => '[0-9]+'));
+
+            $m->connect('notice/:notice',
+                        array('action' => 'shownotice'),
+                        array('notice' => '[0-9]+'));
+            $m->connect('notice/delete', array('action' => 'deletenotice'));
+            $m->connect('notice/delete/:notice',
+                        array('action' => 'deletenotice'),
+                        array('notice' => '[0-9]+'));
+
+            // conversation
+
+            $m->connect('conversation/:id',
+                        array('action' => 'conversation'),
+                        array('id' => '[0-9]+'));
+
+            $m->connect('message/new', array('action' => 'newmessage'));
+            $m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => '[A-Za-z0-9_-]+'));
+            $m->connect('message/:message',
+                        array('action' => 'showmessage'),
+                        array('message' => '[0-9]+'));
+
+            $m->connect('user/:id',
+                        array('action' => 'userbyid'),
+                        array('id' => '[0-9]+'));
+
+            $m->connect('tags/', array('action' => 'publictagcloud'));
+            $m->connect('tag/', array('action' => 'publictagcloud'));
+            $m->connect('tags', array('action' => 'publictagcloud'));
+            $m->connect('tag', array('action' => 'publictagcloud'));
+            $m->connect('tag/:tag/rss',
+                        array('action' => 'tagrss'),
+                        array('tag' => '[a-zA-Z0-9]+'));
+            $m->connect('tag/:tag',
+                        array('action' => 'tag'),
+                        array('tag' => '[\pL\pN_\-\.]{1,64}'));
+
+            $m->connect('peopletag/:tag',
+                        array('action' => 'peopletag'),
+                        array('tag' => '[a-zA-Z0-9]+'));
+
+            $m->connect('featured/', array('action' => 'featured'));
+            $m->connect('featured', array('action' => 'featured'));
+            $m->connect('favorited/', array('action' => 'favorited'));
+            $m->connect('favorited', array('action' => 'favorited'));
+
+            // groups
+
+            $m->connect('group/new', array('action' => 'newgroup'));
+
+            foreach (array('edit', 'join', 'leave') as $v) {
+                $m->connect('group/:nickname/'.$v,
+                            array('action' => $v.'group'),
+                            array('nickname' => '[a-zA-Z0-9]+'));
+            }
+
+            foreach (array('members', 'logo', 'rss', 'designsettings') as $n) {
+                $m->connect('group/:nickname/'.$n,
+                            array('action' => 'group'.$n),
+                            array('nickname' => '[a-zA-Z0-9]+'));
+            }
+
+            $m->connect('group/:nickname/foaf',
+                        array('action' => 'foafgroup'),
                         array('nickname' => '[a-zA-Z0-9]+'));
-        }
 
-        foreach (array('members', 'logo', 'rss', 'designsettings') as $n) {
-            $m->connect('group/:nickname/'.$n,
-                        array('action' => 'group'.$n),
+            $m->connect('group/:nickname/blocked',
+                        array('action' => 'blockedfromgroup'),
                         array('nickname' => '[a-zA-Z0-9]+'));
-        }
-
-        $m->connect('group/:nickname/foaf',
-                    array('action' => 'foafgroup'),
-                    array('nickname' => '[a-zA-Z0-9]+'));
-
-        $m->connect('group/:nickname/blocked',
-                    array('action' => 'blockedfromgroup'),
-                    array('nickname' => '[a-zA-Z0-9]+'));
-
-        $m->connect('group/:nickname/makeadmin',
-                    array('action' => 'makeadmin'),
-                    array('nickname' => '[a-zA-Z0-9]+'));
-
-        $m->connect('group/:id/id',
-                    array('action' => 'groupbyid'),
-                    array('id' => '[0-9]+'));
-
-        $m->connect('group/:nickname',
-                    array('action' => 'showgroup'),
-                    array('nickname' => '[a-zA-Z0-9]+'));
-
-        $m->connect('group/', array('action' => 'groups'));
-        $m->connect('group', array('action' => 'groups'));
-        $m->connect('groups/', array('action' => 'groups'));
-        $m->connect('groups', array('action' => 'groups'));
-
-        // Twitter-compatible API
-
-        // statuses API
-
-        $m->connect('api/statuses/public_timeline.:format',
-                    array('action' => 'ApiTimelinePublic',
-                    'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/friends_timeline.:format',
-                    array('action' => 'ApiTimelineFriends',
-                          'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/friends_timeline/:id.:format',
-                    array('action' => 'ApiTimelineFriends',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json|rss|atom)'));
-        $m->connect('api/statuses/home_timeline.:format',
-                    array('action' => 'ApiTimelineFriends',
-                          'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/home_timeline/:id.:format',
-                    array('action' => 'ApiTimelineFriends',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/user_timeline.:format',
-                    array('action' => 'ApiTimelineUser',
-                    'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/user_timeline/:id.:format',
-                    array('action' => 'ApiTimelineUser',
-                    'id' => '[a-zA-Z0-9]+',
-                    'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/mentions.:format',
-                    array('action' => 'ApiTimelineMentions',
-                    'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/mentions/:id.:format',
-                    array('action' => 'ApiTimelineMentions',
-                    'id' => '[a-zA-Z0-9]+',
-                    'format' => '(xml|json|rss|atom)'));
 
-        $m->connect('api/statuses/replies.:format',
-                    array('action' => 'ApiTimelineMentions',
-                    'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/replies/:id.:format',
-                    array('action' => 'ApiTimelineMentions',
-                    'id' => '[a-zA-Z0-9]+',
-                    'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statuses/friends.:format',
-                     array('action' => 'ApiUserFriends',
-                           'format' => '(xml|json)'));
-
-        $m->connect('api/statuses/friends/:id.:format',
-                    array('action' => 'ApiUserFriends',
-                    'id' => '[a-zA-Z0-9]+',
-                    'format' => '(xml|json)'));
+            $m->connect('group/:nickname/makeadmin',
+                        array('action' => 'makeadmin'),
+                        array('nickname' => '[a-zA-Z0-9]+'));
 
-        $m->connect('api/statuses/followers.:format',
-                     array('action' => 'ApiUserFollowers',
-                           'format' => '(xml|json)'));
+            $m->connect('group/:id/id',
+                        array('action' => 'groupbyid'),
+                        array('id' => '[0-9]+'));
 
-        $m->connect('api/statuses/followers/:id.:format',
-                    array('action' => 'ApiUserFollowers',
-                    'id' => '[a-zA-Z0-9]+',
-                    'format' => '(xml|json)'));
+            $m->connect('group/:nickname',
+                        array('action' => 'showgroup'),
+                        array('nickname' => '[a-zA-Z0-9]+'));
 
-        $m->connect('api/statuses/show.:format',
-                    array('action' => 'ApiStatusesShow',
-                          'format' => '(xml|json)'));
+            $m->connect('group/', array('action' => 'groups'));
+            $m->connect('group', array('action' => 'groups'));
+            $m->connect('groups/', array('action' => 'groups'));
+            $m->connect('groups', array('action' => 'groups'));
+
+            // Twitter-compatible API
+
+            // statuses API
+
+            $m->connect('api/statuses/public_timeline.:format',
+                        array('action' => 'ApiTimelinePublic',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/friends_timeline.:format',
+                        array('action' => 'ApiTimelineFriends',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/friends_timeline/:id.:format',
+                        array('action' => 'ApiTimelineFriends',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json|rss|atom)'));
+            $m->connect('api/statuses/home_timeline.:format',
+                        array('action' => 'ApiTimelineFriends',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/home_timeline/:id.:format',
+                        array('action' => 'ApiTimelineFriends',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json|rss|atom)'));
 
-        $m->connect('api/statuses/show/:id.:format',
-                    array('action' => 'ApiStatusesShow',
-                          'id' => '[0-9]+',
-                          'format' => '(xml|json)'));
+            $m->connect('api/statuses/user_timeline.:format',
+                        array('action' => 'ApiTimelineUser',
+                              'format' => '(xml|json|rss|atom)'));
 
-        $m->connect('api/statuses/update.:format',
-                    array('action' => 'ApiStatusesUpdate',
-                          'format' => '(xml|json)'));
+            $m->connect('api/statuses/user_timeline/:id.:format',
+                        array('action' => 'ApiTimelineUser',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/mentions.:format',
+                        array('action' => 'ApiTimelineMentions',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/mentions/:id.:format',
+                        array('action' => 'ApiTimelineMentions',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/replies.:format',
+                        array('action' => 'ApiTimelineMentions',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/replies/:id.:format',
+                        array('action' => 'ApiTimelineMentions',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statuses/friends.:format',
+                        array('action' => 'ApiUserFriends',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statuses/friends/:id.:format',
+                        array('action' => 'ApiUserFriends',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/statuses/destroy.:format',
-                  array('action' => 'ApiStatusesDestroy',
-                        'format' => '(xml|json)'));
+            $m->connect('api/statuses/followers.:format',
+                        array('action' => 'ApiUserFollowers',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/statuses/destroy/:id.:format',
-                  array('action' => 'ApiStatusesDestroy',
-                        'id' => '[0-9]+',
-                        'format' => '(xml|json)'));
+            $m->connect('api/statuses/followers/:id.:format',
+                        array('action' => 'ApiUserFollowers',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        // users
+            $m->connect('api/statuses/show.:format',
+                        array('action' => 'ApiStatusesShow',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/users/show/:id.:format',
-                    array('action' => 'ApiUserShow',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
+            $m->connect('api/statuses/show/:id.:format',
+                        array('action' => 'ApiStatusesShow',
+                              'id' => '[0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/users/:method',
-                    array('action' => 'api',
-                          'apiaction' => 'users'),
-                    array('method' => 'show(\.(xml|json))?'));
+            $m->connect('api/statuses/update.:format',
+                        array('action' => 'ApiStatusesUpdate',
+                              'format' => '(xml|json)'));
 
-        // direct messages
+            $m->connect('api/statuses/destroy.:format',
+                        array('action' => 'ApiStatusesDestroy',
+                              'format' => '(xml|json)'));
 
+            $m->connect('api/statuses/destroy/:id.:format',
+                        array('action' => 'ApiStatusesDestroy',
+                              'id' => '[0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/direct_messages.:format',
-                    array('action' => 'ApiDirectMessage',
-                          'format' => '(xml|json|rss|atom)'));
+            // users
 
-        $m->connect('api/direct_messages/sent.:format',
-                    array('action' => 'ApiDirectMessage',
-                          'format' => '(xml|json|rss|atom)',
-                          'sent' => true));
+            $m->connect('api/users/show/:id.:format',
+                        array('action' => 'ApiUserShow',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/direct_messages/new.:format',
-                     array('action' => 'ApiDirectMessageNew',
-                           'format' => '(xml|json)'));
+            $m->connect('api/users/:method',
+                        array('action' => 'api',
+                              'apiaction' => 'users'),
+                        array('method' => 'show(\.(xml|json))?'));
 
-        // friendships
+            // direct messages
 
-        $m->connect('api/friendships/show.:format',
-                    array('action' => 'ApiFriendshipsShow',
-                          'format' => '(xml|json)'));
+            $m->connect('api/direct_messages.:format',
+                        array('action' => 'ApiDirectMessage',
+                              'format' => '(xml|json|rss|atom)'));
 
-        $m->connect('api/friendships/exists.:format',
-                    array('action' => 'ApiFriendshipsExists',
-                          'format' => '(xml|json)'));
+            $m->connect('api/direct_messages/sent.:format',
+                        array('action' => 'ApiDirectMessage',
+                              'format' => '(xml|json|rss|atom)',
+                              'sent' => true));
 
-        $m->connect('api/friendships/create.:format',
-                    array('action' => 'ApiFriendshipsCreate',
-                          'format' => '(xml|json)'));
+            $m->connect('api/direct_messages/new.:format',
+                        array('action' => 'ApiDirectMessageNew',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/friendships/destroy.:format',
-                     array('action' => 'ApiFriendshipsDestroy',
-                          'format' => '(xml|json)'));
+            // friendships
 
-        $m->connect('api/friendships/create/:id.:format',
-                    array('action' => 'ApiFriendshipsCreate',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
+            $m->connect('api/friendships/show.:format',
+                        array('action' => 'ApiFriendshipsShow',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/friendships/destroy/:id.:format',
-                    array('action' => 'ApiFriendshipsDestroy',
-                    'id' => '[a-zA-Z0-9]+',
-                    'format' => '(xml|json)'));
+            $m->connect('api/friendships/exists.:format',
+                        array('action' => 'ApiFriendshipsExists',
+                              'format' => '(xml|json)'));
 
-        // Social graph
+            $m->connect('api/friendships/create.:format',
+                        array('action' => 'ApiFriendshipsCreate',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/friends/ids/:id.:format',
-                    array('action' => 'apiFriends',
-                          'ids_only' => true));
+            $m->connect('api/friendships/destroy.:format',
+                        array('action' => 'ApiFriendshipsDestroy',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/followers/ids/:id.:format',
-                    array('action' => 'apiFollowers',
-                          'ids_only' => true));
+            $m->connect('api/friendships/create/:id.:format',
+                        array('action' => 'ApiFriendshipsCreate',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/friends/ids.:format',
-                    array('action' => 'apiFriends',
-                          'ids_only' => true));
+            $m->connect('api/friendships/destroy/:id.:format',
+                        array('action' => 'ApiFriendshipsDestroy',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/followers/ids.:format',
-                     array('action' => 'apiFollowers',
-                          'ids_only' => true));
+            // Social graph
 
-        // account
+            $m->connect('api/friends/ids/:id.:format',
+                        array('action' => 'apiFriends',
+                              'ids_only' => true));
 
-        $m->connect('api/account/verify_credentials.:format',
-                    array('action' => 'ApiAccountVerifyCredentials'));
+            $m->connect('api/followers/ids/:id.:format',
+                        array('action' => 'apiFollowers',
+                              'ids_only' => true));
 
-        // special case where verify_credentials is called w/out a format
+            $m->connect('api/friends/ids.:format',
+                        array('action' => 'apiFriends',
+                              'ids_only' => true));
 
-        $m->connect('api/account/verify_credentials',
-                    array('action' => 'ApiAccountVerifyCredentials'));
+            $m->connect('api/followers/ids.:format',
+                        array('action' => 'apiFollowers',
+                              'ids_only' => true));
 
-        $m->connect('api/account/rate_limit_status.:format',
-                    array('action' => 'ApiAccountRateLimitStatus'));
+            // account
 
-        // favorites
+            $m->connect('api/account/verify_credentials.:format',
+                        array('action' => 'ApiAccountVerifyCredentials'));
 
-        $m->connect('api/favorites.:format',
-                    array('action' => 'ApiTimelineFavorites',
-                    'format' => '(xml|json|rss|atom)'));
+            // special case where verify_credentials is called w/out a format
 
-        $m->connect('api/favorites/:id.:format',
-                    array('action' => 'ApiTimelineFavorites',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xmljson|rss|atom)'));
+            $m->connect('api/account/verify_credentials',
+                        array('action' => 'ApiAccountVerifyCredentials'));
 
-        $m->connect('api/favorites/create/:id.:format',
-                    array('action' => 'ApiFavoriteCreate',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
+            $m->connect('api/account/rate_limit_status.:format',
+                        array('action' => 'ApiAccountRateLimitStatus'));
 
-        $m->connect('api/favorites/destroy/:id.:format',
-                    array('action' => 'ApiFavoriteDestroy',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
+            // favorites
 
-        // notifications
+            $m->connect('api/favorites.:format',
+                        array('action' => 'ApiTimelineFavorites',
+                              'format' => '(xml|json|rss|atom)'));
 
-        $m->connect('api/notifications/:method/:argument',
-                    array('action' => 'api',
-                          'apiaction' => 'favorites'));
+            $m->connect('api/favorites/:id.:format',
+                        array('action' => 'ApiTimelineFavorites',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xmljson|rss|atom)'));
 
-        // blocks
+            $m->connect('api/favorites/create/:id.:format',
+                        array('action' => 'ApiFavoriteCreate',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/blocks/create/:id.:format',
-                    array('action' => 'ApiBlockCreate',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
+            $m->connect('api/favorites/destroy/:id.:format',
+                        array('action' => 'ApiFavoriteDestroy',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/blocks/destroy/:id.:format',
-                    array('action' => 'ApiBlockDestroy',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
-        // help
+            // notifications
 
-        $m->connect('api/help/test.:format',
-                    array('action' => 'ApiHelpTest',
-                          'format' => '(xml|json)'));
+            $m->connect('api/notifications/:method/:argument',
+                        array('action' => 'api',
+                              'apiaction' => 'favorites'));
 
-        // statusnet
+            // blocks
 
-        $m->connect('api/statusnet/version.:format',
-                    array('action' => 'ApiStatusnetVersion',
-                          'format' => '(xml|json)'));
+            $m->connect('api/blocks/create/:id.:format',
+                        array('action' => 'ApiBlockCreate',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/statusnet/config.:format',
-                    array('action' => 'ApiStatusnetConfig',
-                   'format' => '(xml|json)'));
+            $m->connect('api/blocks/destroy/:id.:format',
+                        array('action' => 'ApiBlockDestroy',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
+            // help
 
-        // For older methods, we provide "laconica" base action
-
-        $m->connect('api/laconica/version.:format',
-                    array('action' => 'ApiStatusnetVersion',
-                          'format' => '(xml|json)'));
-
-        $m->connect('api/laconica/config.:format',
-                    array('action' => 'ApiStatusnetConfig',
-                    'format' => '(xml|json)'));
+            $m->connect('api/help/test.:format',
+                        array('action' => 'ApiHelpTest',
+                              'format' => '(xml|json)'));
 
-        // Groups and tags are newer than 0.8.1 so no backward-compatibility
-        // necessary
+            // statusnet
 
-        // Groups
-        //'list' has to be handled differently, as php will not allow a method to be named 'list'
+            $m->connect('api/statusnet/version.:format',
+                        array('action' => 'ApiStatusnetVersion',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/statusnet/groups/timeline/:id.:format',
-                    array('action' => 'ApiTimelineGroup',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xmljson|rss|atom)'));
+            $m->connect('api/statusnet/config.:format',
+                        array('action' => 'ApiStatusnetConfig',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/statusnet/groups/show.:format',
-                    array('action' => 'ApiGroupShow',
-                    'format' => '(xml|json)'));
+            // For older methods, we provide "laconica" base action
+
+            $m->connect('api/laconica/version.:format',
+                        array('action' => 'ApiStatusnetVersion',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/laconica/config.:format',
+                        array('action' => 'ApiStatusnetConfig',
+                              'format' => '(xml|json)'));
 
-        $m->connect('api/statusnet/groups/show/:id.:format',
-                    array('action' => 'ApiGroupShow',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
-
-        $m->connect('api/statusnet/groups/join.:format',
-                    array('action' => 'ApiGroupJoin',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
-
-        $m->connect('api/statusnet/groups/join/:id.:format',
-                    array('action' => 'ApiGroupJoin',
-                    'format' => '(xml|json)'));
-
-        $m->connect('api/statusnet/groups/leave.:format',
-                    array('action' => 'ApiGroupLeave',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json)'));
-
-        $m->connect('api/statusnet/groups/leave/:id.:format',
-                    array('action' => 'ApiGroupLeave',
-                          'format' => '(xml|json)'));
-
-        $m->connect('api/statusnet/groups/is_member.:format',
-                    array('action' => 'ApiGroupIsMember',
-                          'format' => '(xml|json)'));
-
-        $m->connect('api/statusnet/groups/list.:format',
-                    array('action' => 'ApiGroupList',
-                          'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statusnet/groups/list/:id.:format',
-                    array('action' => 'ApiGroupList',
-                          'id' => '[a-zA-Z0-9]+',
-                          'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statusnet/groups/list_all.:format',
-                    array('action' => 'ApiGroupListAll',
-                          'format' => '(xml|json|rss|atom)'));
-
-        $m->connect('api/statusnet/groups/membership.:format',
-                    array('action' => 'ApiGroupMembership',
-                         'format' => '(xml|json)'));
-
-        $m->connect('api/statusnet/groups/membership/:id.:format',
-                    array('action' => 'ApiGroupMembership',
-                           'id' => '[a-zA-Z0-9]+',
-                           'format' => '(xml|json)'));
-                           
-        $m->connect('api/statusnet/groups/create.:format',
-                    array('action' => 'ApiGroupCreate',
-                          'format' => '(xml|json)'));
-        // Tags
-        $m->connect('api/statusnet/tags/timeline/:tag.:format',
-                    array('action' => 'ApiTimelineTag',
-                          'format' => '(xmljson|rss|atom)'));
-
-        // search
-        $m->connect('api/search.atom', array('action' => 'twitapisearchatom'));
-        $m->connect('api/search.json', array('action' => 'twitapisearchjson'));
-        $m->connect('api/trends.json', array('action' => 'twitapitrends'));
-
-        // user stuff
-
-        foreach (array('subscriptions', 'subscribers',
-                       'nudge', 'all', 'foaf', 'xrds',
-                       'replies', 'inbox', 'outbox', 'microsummary') as $a) {
-            $m->connect(':nickname/'.$a,
-                        array('action' => $a),
+            // Groups and tags are newer than 0.8.1 so no backward-compatibility
+            // necessary
+
+            // Groups
+            //'list' has to be handled differently, as php will not allow a method to be named 'list'
+
+            $m->connect('api/statusnet/groups/timeline/:id.:format',
+                        array('action' => 'ApiTimelineGroup',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xmljson|rss|atom)'));
+
+            $m->connect('api/statusnet/groups/show.:format',
+                        array('action' => 'ApiGroupShow',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/show/:id.:format',
+                        array('action' => 'ApiGroupShow',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/join.:format',
+                        array('action' => 'ApiGroupJoin',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/join/:id.:format',
+                        array('action' => 'ApiGroupJoin',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/leave.:format',
+                        array('action' => 'ApiGroupLeave',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/leave/:id.:format',
+                        array('action' => 'ApiGroupLeave',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/is_member.:format',
+                        array('action' => 'ApiGroupIsMember',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/list.:format',
+                        array('action' => 'ApiGroupList',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statusnet/groups/list/:id.:format',
+                        array('action' => 'ApiGroupList',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statusnet/groups/list_all.:format',
+                        array('action' => 'ApiGroupListAll',
+                              'format' => '(xml|json|rss|atom)'));
+
+            $m->connect('api/statusnet/groups/membership.:format',
+                        array('action' => 'ApiGroupMembership',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/membership/:id.:format',
+                        array('action' => 'ApiGroupMembership',
+                              'id' => '[a-zA-Z0-9]+',
+                              'format' => '(xml|json)'));
+
+            $m->connect('api/statusnet/groups/create.:format',
+                        array('action' => 'ApiGroupCreate',
+                              'format' => '(xml|json)'));
+            // Tags
+            $m->connect('api/statusnet/tags/timeline/:tag.:format',
+                        array('action' => 'ApiTimelineTag',
+                              'format' => '(xmljson|rss|atom)'));
+
+            // search
+            $m->connect('api/search.atom', array('action' => 'twitapisearchatom'));
+            $m->connect('api/search.json', array('action' => 'twitapisearchjson'));
+            $m->connect('api/trends.json', array('action' => 'twitapitrends'));
+
+            // user stuff
+
+            foreach (array('subscriptions', 'subscribers',
+                           'nudge', 'all', 'foaf', 'xrds',
+                           'replies', 'inbox', 'outbox', 'microsummary') as $a) {
+                $m->connect(':nickname/'.$a,
+                            array('action' => $a),
+                            array('nickname' => '[a-zA-Z0-9]{1,64}'));
+            }
+
+            foreach (array('subscriptions', 'subscribers') as $a) {
+                $m->connect(':nickname/'.$a.'/:tag',
+                            array('action' => $a),
+                            array('tag' => '[a-zA-Z0-9]+',
+                                  'nickname' => '[a-zA-Z0-9]{1,64}'));
+            }
+
+            foreach (array('rss', 'groups') as $a) {
+                $m->connect(':nickname/'.$a,
+                            array('action' => 'user'.$a),
+                            array('nickname' => '[a-zA-Z0-9]{1,64}'));
+            }
+
+            foreach (array('all', 'replies', 'favorites') as $a) {
+                $m->connect(':nickname/'.$a.'/rss',
+                            array('action' => $a.'rss'),
+                            array('nickname' => '[a-zA-Z0-9]{1,64}'));
+            }
+
+            $m->connect(':nickname/favorites',
+                        array('action' => 'showfavorites'),
                         array('nickname' => '[a-zA-Z0-9]{1,64}'));
-        }
 
-        foreach (array('subscriptions', 'subscribers') as $a) {
-            $m->connect(':nickname/'.$a.'/:tag',
-                        array('action' => $a),
-                        array('tag' => '[a-zA-Z0-9]+',
+            $m->connect(':nickname/avatar/:size',
+                        array('action' => 'avatarbynickname'),
+                        array('size' => '(original|96|48|24)',
                               'nickname' => '[a-zA-Z0-9]{1,64}'));
-        }
-
-        foreach (array('rss', 'groups') as $a) {
-            $m->connect(':nickname/'.$a,
-                        array('action' => 'user'.$a),
-                        array('nickname' => '[a-zA-Z0-9]{1,64}'));
-        }
-
-        foreach (array('all', 'replies', 'favorites') as $a) {
-            $m->connect(':nickname/'.$a.'/rss',
-                        array('action' => $a.'rss'),
-                        array('nickname' => '[a-zA-Z0-9]{1,64}'));
-        }
 
-        $m->connect(':nickname/favorites',
-                    array('action' => 'showfavorites'),
-                    array('nickname' => '[a-zA-Z0-9]{1,64}'));
+            $m->connect(':nickname/tag/:tag/rss',
+                        array('action' => 'userrss'),
+                        array('nickname' => '[a-zA-Z0-9]{1,64}'),
+                        array('tag' => '[a-zA-Z0-9]+'));
 
-        $m->connect(':nickname/avatar/:size',
-                    array('action' => 'avatarbynickname'),
-                    array('size' => '(original|96|48|24)',
-                          'nickname' => '[a-zA-Z0-9]{1,64}'));
+            $m->connect(':nickname/tag/:tag',
+                        array('action' => 'showstream'),
+                        array('nickname' => '[a-zA-Z0-9]{1,64}'),
+                        array('tag' => '[a-zA-Z0-9]+'));
 
-        $m->connect(':nickname/tag/:tag/rss',
-            array('action' => 'userrss'),
-            array('nickname' => '[a-zA-Z0-9]{1,64}'),
-            array('tag' => '[a-zA-Z0-9]+'));
-
-        $m->connect(':nickname/tag/:tag',
-                    array('action' => 'showstream'),
-                    array('nickname' => '[a-zA-Z0-9]{1,64}'),
-                    array('tag' => '[a-zA-Z0-9]+'));
-
-        $m->connect(':nickname',
-                    array('action' => 'showstream'),
-                    array('nickname' => '[a-zA-Z0-9]{1,64}'));
+            $m->connect(':nickname',
+                        array('action' => 'showstream'),
+                        array('nickname' => '[a-zA-Z0-9]{1,64}'));
 
-        Event::handle('RouterInitialized', array($m));
+            Event::handle('RouterInitialized', array($m));
+        }
 
         return $m;
     }
index f5ad3d06b4be00efc25c41571ca8138fb5384237..a10fdf90d4e55b5214be9a982d9eef80aa0dbdca 100644 (file)
@@ -83,8 +83,8 @@ class FacebookAction extends Action
     function showStylesheets()
     {
         $this->cssLink('css/display.css', 'base');
-        $this->cssLink('css/display.css',null,'screen, projection, tv');
-        $this->cssLink('css/facebookapp.css', 'base');
+        $this->cssLink('css/display.css', null, 'screen, projection, tv');
+        $this->cssLink('plugins/Facebook/facebookapp.css');
     }
 
     function showScripts()
diff --git a/plugins/Facebook/facebookapp.css b/plugins/Facebook/facebookapp.css
new file mode 100644 (file)
index 0000000..8cd06f7
--- /dev/null
@@ -0,0 +1,115 @@
+* {
+font-size:14px;
+font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
+}
+
+#wrap {
+background-color:#F0F2F5;
+padding-left:1.795%;
+padding-right:1.795%;
+width:auto;
+}
+
+p,label,
+h1,h2,h3,h4,h5,h6 {
+color:#000;
+}
+
+#header {
+width:131%;
+}
+
+#content {
+width:92.7%;
+}
+
+#aside_primary {
+display:none;
+}
+
+#site_nav_local_views a {
+background-color:#D0DFE7;
+}
+#site_nav_local_views a:hover {
+background-color:#FAFBFC;
+}
+
+#form_notice .form_note + label,
+#form_notice #notice_data-attach {
+display:none;
+}
+
+#form_notice #notice_action-submit {
+height:47px !important;
+}
+
+
+span.facebook-button {
+border: 2px solid #aaa;
+padding: 3px;
+display: block;
+float: left;
+margin-right: 20px;
+-moz-border-radius: 4px; 
+border-radius:4px; 
+-webkit-border-radius:4px;
+font-weight: bold;
+background-color:#A9BF4F;
+color:#fff;
+font-size:1.2em
+}
+
+span.facebook-button a { color:#fff }
+
+.facebook_guide {
+margin-bottom:18px;
+}
+.facebook_guide p {
+font-weight:bold;
+}
+
+
+input {
+height:auto !important;
+}
+
+#facebook-friends {
+float:left;
+width:100%;
+}
+
+#facebook-friends li {
+float:left;
+margin-right:2%;
+margin-bottom:11px;
+width:18%;
+height:115px;
+}
+#facebook-friends li a {
+float:left;
+}
+
+#add_to_profile {
+position:absolute;
+right:18px;
+top:10px;
+z-index:2;
+}
+
+.notice div.entry-content dl,
+.notice div.entry-content dt, 
+.notice div.entry-content dd {
+margin-right:5px;
+}
+
+#content_inner p {
+margin-bottom:18px;
+}
+
+#content_inner ul {
+list-style-type:none;
+}
+
+.form_settings label {
+margin-right:18px;
+}
index ecda1717c3e37b2b184a12ce8460e6ab2005fd1c..3380b4c857d4de1f365d5534cf80fbc76ae5c71e 100644 (file)
@@ -105,6 +105,7 @@ class FacebookinviteAction extends FacebookAction
         $multi_params = array('showborder' => 'false');
         $multi_params['actiontext'] = $actiontext;
         $multi_params['bypass'] = 'cancel';
+        $multi_params['cols'] = 4;
 
         // Get a list of users who are already using the app for exclusion
         $exclude_ids = $this->facebook->api_client->friends_getAppUsers();
index a933a1155510296983c2cd1bf2cdcbc7d2776bb9..560da71e7b7a1b788863286adbe0f00667163956 100644 (file)
@@ -150,11 +150,15 @@ class OpenIDPlugin extends Plugin
      * @return void
      */
 
-    function onEndHeadChildren($action)
+    function onEndShowHeadElements($action)
     {
-        // for client side of OpenID authentication
-        $action->element('meta', array('http-equiv' => 'X-XRDS-Location',
-                                       'content' => common_local_url('publicxrds')));
+        if ($action->trimmed('action') == 'public') {
+            // for client side of OpenID authentication
+            $action->element('meta', array('http-equiv' => 'X-XRDS-Location',
+                                           'content' => common_local_url('publicxrds')));
+        }
+
+        return true;
     }
 
     /**
diff --git a/theme/base/css/facebookapp.css b/theme/base/css/facebookapp.css
deleted file mode 100644 (file)
index e6b1c9e..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-* {
-font-size:14px;
-font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
-}
-
-#wrap {
-background-color:#F0F2F5;
-padding-left:18px;
-padding-right:18px;
-width:auto;
-}
-
-p,label,
-h1,h2,h3,h4,h5,h6 {
-color:#000;
-}
-
-#content {
-width:95%;
-}
-
-#site_nav_local_views a {
-background-color:#D0DFE7;
-}
-#site_nav_local_views a:hover {
-background-color:#FAFBFC;
-}
-
-span.facebook-button {
-border: 2px solid #aaa;
-padding: 3px;
-display: block;
-float: left;
-margin-right: 20px;
--moz-border-radius: 4px; 
-border-radius:4px; 
--webkit-border-radius:4px;
-font-weight: bold;
-background-color:#A9BF4F;
-color:#fff;
-font-size:1.2em
-}
-
-span.facebook-button a { color:#fff }
-
-.facebook_guide {
-margin-bottom:18px;
-}
-.facebook_guide p {
-font-weight:bold;
-}
-
-
-input {
-height:auto !important;
-}
-
-#facebook-friends {
-float:left;
-width:100%;
-}
-
-#facebook-friends li {
-float:left;
-margin-right:2%;
-margin-bottom:11px;
-width:18%;
-height:115px;
-}
-#facebook-friends li a {
-float:left;
-}
-
-#add_to_profile {
-position:absolute;
-right:18px;
-top:10px;
-z-index:2;
-}
-
-.notice div.entry-content dl,
-.notice div.entry-content dt, 
-.notice div.entry-content dd {
-margin-right:5px;
-}
-
-#content_inner p {
-margin-bottom:18px;
-}
-
-#content_inner ul {
-list-style-type:none;
-}
-
-.form_settings label {
-margin-right:18px;
-}
index 6833373b456a2920542406078562b95d88ee61a0..a5f1fd6e47e47179dbc7636097536b9e0a34131f 100644 (file)
@@ -18,7 +18,7 @@ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
 font-size:1em;
 }
 address {
-margin-right:5.8%;
+margin-right:5.7%;
 }
 
 input, textarea, select, option {