]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch '0.9.x' into 1.0.x
authorBrion Vibber <brion@pobox.com>
Wed, 3 Nov 2010 23:09:49 +0000 (16:09 -0700)
committerBrion Vibber <brion@pobox.com>
Wed, 3 Nov 2010 23:09:49 +0000 (16:09 -0700)
1  2 
actions/shownotice.php
actions/showstream.php
classes/Profile.php
lib/command.php
lib/util.php
plugins/OStatus/classes/Ostatus_profile.php

diff --combined actions/shownotice.php
index 5b3ec93de10b64082bceb30bc5de46a4c3693c2d,7cc6c54243ac2e1e80493e210c173d2fb140e0c0..6534617319d07c5aaa33db6bc0b1ae10cf9d6e3c
@@@ -167,11 -167,7 +167,7 @@@ class ShownoticeAction extends OwnerDes
  
      function title()
      {
-         if (!empty($this->profile->fullname)) {
-             $base = $this->profile->fullname . ' (' . $this->profile->nickname . ')';
-         } else {
-             $base = $this->profile->nickname;
-         }
+         $base = $this->profile->getFancyName();
  
          return sprintf(_('%1$s\'s status on %2$s'),
                         $base,
                                           'content' => $id->toString()));
          }
  
 -        if ($user->jabbermicroid && $user->jabber && $this->notice->uri) {
 -            $id = new Microid('xmpp:', $user->jabber,
 -                              $this->notice->uri);
 -            $this->element('meta', array('name' => 'microid',
 -                                         'content' => $id->toString()));
 -        }
          $this->element('link',array('rel'=>'alternate',
              'type'=>'application/json+oembed',
              'href'=>common_local_url(
diff --combined actions/showstream.php
index dabdcd103c4b49551f894aed95be5d412c1c6054,5a22bdf288ba02365f999aab7fd5b9f35e1c0091..702edd73272eb01cb3a72465a6eeb11e034104c3
@@@ -66,17 -66,19 +66,19 @@@ class ShowstreamAction extends ProfileA
          $base = $this->profile->getFancyName();
          if (!empty($this->tag)) {
              if ($this->page == 1) {
-                 // TRANS: Page title showing tagged notices in one user's stream. Param 1 is the username, 2 is the hash tag.
+                 // TRANS: Page title showing tagged notices in one user's stream. %1$s is the username, %2$s is the hash tag.
                  return sprintf(_('%1$s tagged %2$s'), $base, $this->tag);
              } else {
-                 // TRANS: Page title showing tagged notices in one user's stream. Param 1 is the username, 2 is the hash tag, 3 is the page number.
+                 // TRANS: Page title showing tagged notices in one user's stream.
+                 // TRANS: %1$s is the username, %2$s is the hash tag, %1$d is the page number.
                  return sprintf(_('%1$s tagged %2$s, page %3$d'), $base, $this->tag, $this->page);
              }
          } else {
              if ($this->page == 1) {
                  return $base;
              } else {
-                 // TRANS: Extended page title showing tagged notices in one user's stream. Param 1 is the username, param 2 is the page number.
+                 // TRANS: Extended page title showing tagged notices in one user's stream.
+                 // TRANS: %1$s is the username, %2$d is the page number.
                  return sprintf(_('%1$s, page %2$d'),
                                 $base,
                                 $this->page);
                                    common_local_url('userrss',
                                                     array('nickname' => $this->user->nickname,
                                                           'tag' => $this->tag)),
+                                   // TRANS: Title for link to notice feed.
+                                   // TRANS: %1$s is a user nickname, %2$s is a hashtag.
                                    sprintf(_('Notice feed for %1$s tagged %2$s (RSS 1.0)'),
                                            $this->user->nickname, $this->tag)));
          }
          return array(new Feed(Feed::RSS1,
                                common_local_url('userrss',
                                                 array('nickname' => $this->user->nickname)),
+                               // TRANS: Title for link to notice feed.
+                               // TRANS: %s is a user nickname.
                                sprintf(_('Notice feed for %s (RSS 1.0)'),
                                        $this->user->nickname)),
                       new Feed(Feed::RSS2,
                                                 array(
                                                      'id' => $this->user->id,
                                                      'format' => 'rss')),
+                               // TRANS: Title for link to notice feed.
+                               // TRANS: %s is a user nickname.
                                sprintf(_('Notice feed for %s (RSS 2.0)'),
                                        $this->user->nickname)),
                       new Feed(Feed::ATOM,
                       new Feed(Feed::FOAF,
                                common_local_url('foaf', array('nickname' =>
                                                               $this->user->nickname)),
+                               // TRANS: Title for link to notice feed. FOAF stands for Friend of a Friend.
+                               // TRANS: More information at http://www.foaf-project.org. %s is a user nickname.
                                sprintf(_('FOAF for %s'), $this->user->nickname)));
      }
  
                                $this->selfUrl());
              $this->element('meta', array('name' => 'microid',
                                           'content' => $id->toString()));
 -        }
 -        if ($this->user->jabbermicroid && $this->user->jabber && $this->profile->profileurl) {
 -            $id = new Microid('xmpp:'.$this->user->jabber,
 -                              $this->selfUrl());
 -            $this->element('meta', array('name' => 'microid',
 -                                         'content' => $id->toString()));
          }
  
          // See https://wiki.mozilla.org/Microsummaries
  
      function showEmptyListMessage()
      {
-         $message = sprintf(_('This is the timeline for %1$s but %2$s hasn\'t posted anything yet.'), $this->user->nickname, $this->user->nickname) . ' ';
+         // TRANS: First sentence of empty list message for a stream. $1%s is a user nickname.
+         $message = sprintf(_('This is the timeline for %1$s, but %1$s hasn\'t posted anything yet.'), $this->user->nickname) . ' ';
  
          if (common_logged_in()) {
              $current_user = common_current_user();
              if ($this->user->id === $current_user->id) {
+                 // TRANS: Second sentence of empty list message for a stream for the user themselves.
                  $message .= _('Seen anything interesting recently? You haven\'t posted any notices yet, now would be a good time to start :)');
              } else {
+                 // TRANS: Second sentence of empty  list message for a non-self stream. %1$s is a user nickname, %2$s is a part of a URL.
+                 // TRANS: This message contains a Markdown link. Keep "](" together.
                  $message .= sprintf(_('You can try to nudge %1$s or [post something to them](%%%%action.newnotice%%%%?status_textarea=%2$s).'), $this->user->nickname, '@' . $this->user->nickname);
              }
          }
          else {
+             // TRANS: Second sentence of empty message for anonymous users. %s is a user nickname.
+             // TRANS: This message contains a Markdown link. Keep "](" together.
              $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->user->nickname);
          }
  
      function showAnonymousMessage()
      {
          if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
+             // TRANS: Announcement for anonymous users showing a stream if site registrations are open.
+             // TRANS: This message contains a Markdown link. Keep "](" together.
              $m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
                             'based on the Free Software [StatusNet](http://status.net/) tool. ' .
                             '[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
                           $this->user->nickname, $this->user->nickname);
          } else {
+             // TRANS: Announcement for anonymous users showing a stream if site registrations are closed or invite only.
+             // TRANS: This message contains a Markdown link. Keep "](" together.
              $m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
                             'based on the Free Software [StatusNet](http://status.net/) tool. '),
                           $this->user->nickname, $this->user->nickname);
@@@ -281,7 -307,6 +301,6 @@@ class ProfileNoticeListItem extends DoF
       *
       * @return void
       */
      function showRepeat()
      {
          if (!empty($this->repeat)) {
                             'class' => 'url');
  
              if (!empty($this->profile->fullname)) {
-                 $attrs['title'] = $this->profile->fullname . ' (' . $this->profile->nickname . ')';
+                 $attrs['title'] = $this->getFancyName();
              }
  
              $this->out->elementStart('span', 'repeat');
  
              $text_link = XMLStringer::estring('a', $attrs, $this->profile->nickname);
  
+             // TRANS: Link to the author of a repeated notice. %s is a linked nickname.
              $this->out->raw(sprintf(_('Repeat of %s'), $text_link));
  
              $this->out->elementEnd('span');
diff --combined classes/Profile.php
index 545950a9ee79c0a2a4c20f040d04d08b20e3dd55,d580e12355a2e09fe3586b2f7a97210c9848ea3f..b56e508c6a8d0da3a66cdf0f8b6a1027307a4688
@@@ -161,7 -161,7 +161,7 @@@ class Profile extends Memcached_DataObj
      {
          if ($this->fullname) {
              // TRANS: Full name of a profile or group followed by nickname in parens
-             return sprintf(_('%1$s (%2$s)'), $this->fullname, $this->nickname);
+             return sprintf(_m('FANCYNAME','%1$s (%2$s)'), $this->fullname, $this->nickname);
          } else {
              return $this->nickname;
          }
  
      function subscriptionCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
  
          if (!empty($c)) {
 -            $cnt = $c->get(common_cache_key('profile:subscription_count:'.$this->id));
 +            $cnt = $c->get(Cache::key('profile:subscription_count:'.$this->id));
              if (is_integer($cnt)) {
                  return (int) $cnt;
              }
          $cnt = ($cnt > 0) ? $cnt - 1 : $cnt;
  
          if (!empty($c)) {
 -            $c->set(common_cache_key('profile:subscription_count:'.$this->id), $cnt);
 +            $c->set(Cache::key('profile:subscription_count:'.$this->id), $cnt);
          }
  
          return $cnt;
  
      function subscriberCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
          if (!empty($c)) {
 -            $cnt = $c->get(common_cache_key('profile:subscriber_count:'.$this->id));
 +            $cnt = $c->get(Cache::key('profile:subscriber_count:'.$this->id));
              if (is_integer($cnt)) {
                  return (int) $cnt;
              }
          $cnt = (int) $sub->count('distinct subscriber');
  
          if (!empty($c)) {
 -            $c->set(common_cache_key('profile:subscriber_count:'.$this->id), $cnt);
 +            $c->set(Cache::key('profile:subscriber_count:'.$this->id), $cnt);
          }
  
          return $cnt;
  
      function hasFave($notice)
      {
 -        $cache = common_memcache();
 +        $cache = Cache::instance();
  
          // XXX: Kind of a hack.
  
  
      function faveCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
          if (!empty($c)) {
 -            $cnt = $c->get(common_cache_key('profile:fave_count:'.$this->id));
 +            $cnt = $c->get(Cache::key('profile:fave_count:'.$this->id));
              if (is_integer($cnt)) {
                  return (int) $cnt;
              }
          $cnt = (int) $faves->count('distinct notice_id');
  
          if (!empty($c)) {
 -            $c->set(common_cache_key('profile:fave_count:'.$this->id), $cnt);
 +            $c->set(Cache::key('profile:fave_count:'.$this->id), $cnt);
          }
  
          return $cnt;
  
      function noticeCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
  
          if (!empty($c)) {
 -            $cnt = $c->get(common_cache_key('profile:notice_count:'.$this->id));
 +            $cnt = $c->get(Cache::key('profile:notice_count:'.$this->id));
              if (is_integer($cnt)) {
                  return (int) $cnt;
              }
          $cnt = (int) $notices->count('distinct id');
  
          if (!empty($c)) {
 -            $c->set(common_cache_key('profile:notice_count:'.$this->id), $cnt);
 +            $c->set(Cache::key('profile:notice_count:'.$this->id), $cnt);
          }
  
          return $cnt;
  
      function blowFavesCache()
      {
 -        $cache = common_memcache();
 +        $cache = Cache::instance();
          if ($cache) {
              // Faves don't happen chronologically, so we need to blow
              // ;last cache, too
 -            $cache->delete(common_cache_key('fave:ids_by_user:'.$this->id));
 -            $cache->delete(common_cache_key('fave:ids_by_user:'.$this->id.';last'));
 -            $cache->delete(common_cache_key('fave:ids_by_user_own:'.$this->id));
 -            $cache->delete(common_cache_key('fave:ids_by_user_own:'.$this->id.';last'));
 +            $cache->delete(Cache::key('fave:ids_by_user:'.$this->id));
 +            $cache->delete(Cache::key('fave:ids_by_user:'.$this->id.';last'));
 +            $cache->delete(Cache::key('fave:ids_by_user_own:'.$this->id));
 +            $cache->delete(Cache::key('fave:ids_by_user_own:'.$this->id.';last'));
          }
          $this->blowFaveCount();
      }
  
      function blowSubscriberCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
          if (!empty($c)) {
 -            $c->delete(common_cache_key('profile:subscriber_count:'.$this->id));
 +            $c->delete(Cache::key('profile:subscriber_count:'.$this->id));
          }
      }
  
      function blowSubscriptionCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
          if (!empty($c)) {
 -            $c->delete(common_cache_key('profile:subscription_count:'.$this->id));
 +            $c->delete(Cache::key('profile:subscription_count:'.$this->id));
          }
      }
  
      function blowFaveCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
          if (!empty($c)) {
 -            $c->delete(common_cache_key('profile:fave_count:'.$this->id));
 +            $c->delete(Cache::key('profile:fave_count:'.$this->id));
          }
      }
  
      function blowNoticeCount()
      {
 -        $c = common_memcache();
 +        $c = Cache::instance();
          if (!empty($c)) {
 -            $c->delete(common_cache_key('profile:notice_count:'.$this->id));
 +            $c->delete(Cache::key('profile:notice_count:'.$this->id));
          }
      }
  
diff --combined lib/command.php
index bd8a4ebfe9688bea9a28faced4a0d38d8b45cd08,ae69f04a1366b80d990110344374db868c40ef09..a25ea4a9d66a3548d08f8085935514a181854f98
@@@ -423,7 -423,7 +423,7 @@@ class WhoisCommand extends Comman
  
          // TRANS: Whois output.
          // TRANS: %1$s nickname of the queried user, %2$s is their profile URL.
-         $whois = sprintf(_("%1\$s (%2\$s)"), $recipient->nickname,
+         $whois = sprintf(_m('WHOIS',"%1\$s (%2\$s)"), $recipient->nickname,
                           $recipient->profileurl);
          if ($recipient->fullname) {
              // TRANS: Whois output. %s is the full name of the queried user.
@@@ -718,7 -718,7 +718,7 @@@ class OffCommand extends Comman
      }
      function handle($channel)
      {
 -        if ($other) {
 +        if ($this->other) {
              // TRANS: Error text shown when issuing the command "off" with a setting which has not yet been implemented.
              $channel->error($this->user, _("Command not yet implemented."));
          } else {
@@@ -744,7 -744,7 +744,7 @@@ class OnCommand extends Comman
  
      function handle($channel)
      {
 -        if ($other) {
 +        if ($this->other) {
              // TRANS: Error text shown when issuing the command "on" with a setting which has not yet been implemented.
              $channel->error($this->user, _("Command not yet implemented."));
          } else {
diff --combined lib/util.php
index 5094b2712644d066a2730f0f91c3e3d886f87f95,8f2a9f17389d4460a188ca892deb5752e041df5e..1d4f5a5499228947cd459fdf425e6e3675024500
@@@ -157,38 -157,22 +157,38 @@@ function common_timezone(
      return common_config('site', 'timezone');
  }
  
 +function common_valid_language($lang)
 +{
 +    if ($lang) {
 +        // Validate -- we don't want to end up with a bogus code
 +        // left over from some old junk.
 +        foreach (common_config('site', 'languages') as $code => $info) {
 +            if ($info['lang'] == $lang) {
 +                return true;
 +            }
 +        }
 +    }
 +    return false;
 +}
 +
  function common_language()
  {
 +    // Allow ?uselang=xx override, very useful for debugging
 +    // and helping translators check usage and context.
 +    if (isset($_GET['uselang'])) {
 +        $uselang = strval($_GET['uselang']);
 +        if (common_valid_language($uselang)) {
 +            return $uselang;
 +        }
 +    }
 +
      // If there is a user logged in and they've set a language preference
      // then return that one...
      if (_have_config() && common_logged_in()) {
          $user = common_current_user();
 -        $user_language = $user->language;
 -
 -        if ($user->language) {
 -            // Validate -- we don't want to end up with a bogus code
 -            // left over from some old junk.
 -            foreach (common_config('site', 'languages') as $code => $info) {
 -                if ($info['lang'] == $user_language) {
 -                    return $user_language;
 -                }
 -            }
 +
 +        if (common_valid_language($user->language)) {
 +            return $user->language;
          }
      }
  
@@@ -928,21 -912,9 +928,21 @@@ function common_linkify($url) 
  
  function common_shorten_links($text, $always = false)
  {
 -    $maxLength = Notice::maxContent();
 -    if (!$always && ($maxLength == 0 || mb_strlen($text) <= $maxLength)) return $text;
 -    return common_replace_urls_callback($text, array('File_redirection', 'makeShort'));
 +    common_debug("common_shorten_links() called");
 +
 +    $user = common_current_user();
 +
 +    $maxLength = User_urlshortener_prefs::maxNoticeLength($user);
 +
 +    common_debug("maxLength = $maxLength");
 +
 +    if ($always || mb_strlen($text) > $maxLength) {
 +        common_debug("Forcing shortening");
 +        return common_replace_urls_callback($text, array('File_redirection', 'forceShort'));
 +    } else {
 +        common_debug("Not forcing shortening");
 +        return common_replace_urls_callback($text, array('File_redirection', 'makeShort'));
 +    }
  }
  
  /**
@@@ -1038,7 -1010,7 +1038,7 @@@ function common_group_link($sender_id, 
          $attrs = array('href' => $group->permalink(),
                         'class' => 'url');
          if (!empty($group->fullname)) {
-             $attrs['title'] = $group->fullname . ' (' . $group->nickname . ')';
+             $attrs['title'] = $group->getFancyName();
          }
          $xs = new XMLStringer();
          $xs->elementStart('span', 'vcard');
@@@ -1326,8 -1298,14 +1326,8 @@@ function common_redirect($url, $code=30
      exit;
  }
  
 -function common_broadcast_notice($notice, $remote=false)
 -{
 -    // DO NOTHING!
 -}
 +// Stick the notice on the queue
  
 -/**
 - * Stick the notice on the queue.
 - */
  function common_enqueue_notice($notice)
  {
      static $localTransports = array('omb',
          $transports[] = 'plugin';
      }
  
 -    $xmpp = common_config('xmpp', 'enabled');
 -
 -    if ($xmpp) {
 -        $transports[] = 'jabber';
 -    }
 -
      // We can skip these for gatewayed notices.
      if ($notice->isLocal()) {
          $transports = array_merge($transports, $localTransports);
 -        if ($xmpp) {
 -            $transports[] = 'public';
 -        }
      }
  
      if (Event::handle('StartEnqueueNotice', array($notice, &$transports))) {
@@@ -1881,6 -1868,21 +1881,6 @@@ function common_session_token(
      return $_SESSION['token'];
  }
  
 -function common_cache_key($extra)
 -{
 -    return Cache::key($extra);
 -}
 -
 -function common_keyize($str)
 -{
 -    return Cache::keyize($str);
 -}
 -
 -function common_memcache()
 -{
 -    return Cache::instance();
 -}
 -
  function common_license_terms($uri)
  {
      if(preg_match('/creativecommons.org\/licenses\/([^\/]+)/', $uri, $matches)) {
@@@ -1921,42 -1923,30 +1921,42 @@@ function common_database_tablename($tab
  /**
   * Shorten a URL with the current user's configured shortening service,
   * or ur1.ca if configured, or not at all if no shortening is set up.
 - * Length is not considered.
   *
 - * @param string $long_url
 + * @param string  $long_url original URL
 + * @param boolean $force    Force shortening (used when notice is too long)
 + *
   * @return string may return the original URL if shortening failed
   *
   * @fixme provide a way to specify a particular shortener
   * @fixme provide a way to specify to use a given user's shortening preferences
   */
 -function common_shorten_url($long_url)
 +
 +function common_shorten_url($long_url, $force = false)
  {
 +    common_debug("Shortening URL '$long_url' (force = $force)");
 +
      $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
 -        // therefore we'll set one here fix, so that XMPP given URLs may be shortened
 -        $shortenerName = 'ur1.ca';
 -    } else {
 -        $shortenerName = $user->urlshorteningservice;
 +
 +    $maxUrlLength = User_urlshortener_prefs::maxUrlLength($user);
 +    common_debug("maxUrlLength = $maxUrlLength");
 +
 +    // $force forces shortening even if it's not strictly needed
 +
 +    if (mb_strlen($long_url) < $maxUrlLength && !$force) {
 +        common_debug("Skipped shortening URL.");
 +        return $long_url;
      }
  
 -    if(Event::handle('StartShortenUrl', array($long_url,$shortenerName,&$shortenedUrl))){
 +    $shortenerName = User_urlshortener_prefs::urlShorteningService($user);
 +
 +    common_debug("Shortener name = '$shortenerName'");
 +
 +    if (Event::handle('StartShortenUrl', array($long_url, $shortenerName, &$shortenedUrl))) {
          //URL wasn't shortened, so return the long url
          return $long_url;
 -    }else{
 +    } else {
          //URL was shortened, so return the result
          return trim($shortenedUrl);
      }
index 1ae9717c71b4300b49cbbaa878279b23893f0eca,b43a2b5f11fde33c05d8524808dd0e4def553117..3dd00de29039583633c2897377bc72493cb4c588
@@@ -25,8 -25,7 +25,8 @@@ if (!defined('STATUSNET')) 
   * @package OStatusPlugin
   * @maintainer Brion Vibber <brion@status.net>
   */
 -class Ostatus_profile extends Memcached_DataObject
 +
 +class Ostatus_profile extends Managed_DataObject
  {
      public $__table = 'ostatus_profile';
  
      }
  
      /**
 -     * return table definition for DB_DataObject
 -     *
 -     * DB_DataObject needs to know something about the table to manipulate
 -     * instances. This method provides all the DB_DataObject needs to know.
 +     * Return table definition for Schema setup and DB_DataObject usage.
       *
       * @return array array of column definitions
       */
 -    function table()
 -    {
 -        return array('uri' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
 -                     'profile_id' => DB_DATAOBJECT_INT,
 -                     'group_id' => DB_DATAOBJECT_INT,
 -                     'feeduri' => DB_DATAOBJECT_STR,
 -                     'salmonuri' =>  DB_DATAOBJECT_STR,
 -                     'avatar' =>  DB_DATAOBJECT_STR,
 -                     'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
 -                     'modified' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL);
 -    }
  
      static function schemaDef()
      {
 -        return array(new ColumnDef('uri', 'varchar',
 -                                   255, false, 'PRI'),
 -                     new ColumnDef('profile_id', 'integer',
 -                                   null, true, 'UNI'),
 -                     new ColumnDef('group_id', 'integer',
 -                                   null, true, 'UNI'),
 -                     new ColumnDef('feeduri', 'varchar',
 -                                   255, true, 'UNI'),
 -                     new ColumnDef('salmonuri', 'text',
 -                                   null, true),
 -                     new ColumnDef('avatar', 'text',
 -                                   null, true),
 -                     new ColumnDef('created', 'datetime',
 -                                   null, false),
 -                     new ColumnDef('modified', 'datetime',
 -                                   null, false));
 -    }
 -
 -    /**
 -     * return key definitions for DB_DataObject
 -     *
 -     * DB_DataObject needs to know about keys that the table has; this function
 -     * defines them.
 -     *
 -     * @return array key definitions
 -     */
 -    function keys()
 -    {
 -        return array_keys($this->keyTypes());
 -    }
 -
 -    /**
 -     * return key definitions for Memcached_DataObject
 -     *
 -     * Our caching system uses the same key definitions, but uses a different
 -     * method to get them.
 -     *
 -     * @return array key definitions
 -     */
 -    function keyTypes()
 -    {
 -        return array('uri' => 'K', 'profile_id' => 'U', 'group_id' => 'U', 'feeduri' => 'U');
 -    }
 -
 -    function sequenceKey()
 -    {
 -        return array(false, false, false);
 +        return array(
 +            'fields' => array(
 +                'uri' => array('type' => 'varchar', 'length' => 255, 'not null' => true),
 +                'profile_id' => array('type' => 'integer'),
 +                'group_id' => array('type' => 'integer'),
 +                'feeduri' => array('type' => 'varchar', 'length' => 255),
 +                'salmonuri' => array('type' => 'varchar', 'length' => 255),
 +                'avatar' => array('type' => 'text'),
 +                'created' => array('type' => 'datetime', 'not null' => true),
 +                'modified' => array('type' => 'datetime', 'not null' => true),
 +            ),
 +            'primary key' => array('uri'),
 +            'unique keys' => array(
 +                'ostatus_profile_profile_id_idx' => array('profile_id'),
 +                'ostatus_profile_group_id_idx' => array('group_id'),
 +                'ostatus_profile_feeduri_idx' => array('feeduri'),
 +            ),
 +            'foreign keys' => array(
 +                'ostatus_profile_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
 +                'ostatus_profile_group_id_fkey' => array('user_group', array('group_id' => 'id')),
 +            ),
 +        );
      }
  
      /**
          } else if ($this->group_id && !$this->profile_id) {
              return true;
          } else if ($this->group_id && $this->profile_id) {
-             // TRANS: Server exception.
+             // TRANS: Server exception. %s is a URI.
              throw new ServerException(sprintf(_m('Invalid ostatus_profile state: both group and profile IDs set for %s.'),$this->uri));
          } else {
-             // TRANS: Server exception.
+             // TRANS: Server exception. %s is a URI.
              throw new ServerException(sprintf(_m('Invalid ostatus_profile state: both group and profile IDs empty for %s.'),$this->uri));
          }
      }
          } else if ($feed->localName == 'rss') { // @fixme check namespace
              $this->processRssFeed($feed, $source);
          } else {
+             // TRANS: Exception.
              throw new Exception(_m('Unknown feed format.'));
          }
      }
          $channels = $rss->getElementsByTagName('channel');
  
          if ($channels->length == 0) {
+             // TRANS: Exception.
              throw new Exception(_m('RSS feed without a channel.'));
          } else if ($channels->length > 1) {
              common_log(LOG_WARNING, __METHOD__ . ": more than one channel in an RSS feed");
              $sourceContent = $note->title;
          } else {
              // @fixme fetch from $sourceUrl?
-             // TRANS: Client exception. %s is a source URL.
+             // TRANS: Client exception. %s is a source URI.
              throw new ClientException(sprintf(_m('No content for notice %s.'),$sourceUri));
          }
  
                  // so we can fold-out the full version inline.
  
                  // @fixme I18N this tooltip will be saved with the site's default language
-                 // TRANS: Shown when a notice is longer than supported and/or when attachments are present. At runtime this will usually be replaced with localized text from StatusNet core messages.
+                 // TRANS: Shown when a notice is longer than supported and/or when attachments are present. At runtime
+                 // TRANS: this will usually be replaced with localised text from StatusNet core messages.
                  $showMoreText = _m('Show more');
                  $attachUrl = common_local_url('attachment',
                                                array('attachment' => $attachment->id));
              return self::ensureFeedURL($feedurl, $hints);
          }
  
-         // TRANS: Exception.
+         // TRANS: Exception. %s is a URL.
          throw new Exception(sprintf(_m('Could not find a feed URL for profile page %s.'),$finalUrl));
      }
  
          }
  
          // XXX: make some educated guesses here
+         // TRANS: Feed sub exception.
          throw new FeedSubException(_m('Can\'t find enough profile information to make a feed.'));
      }
  
              return;
          }
          if (!common_valid_http_url($url)) {
+             // TRANS: Server exception. %s is a URL.
              throw new ServerException(sprintf(_m("Invalid avatar URL %s."), $url));
          }
  
          }
          if (!$self) {
              throw new ServerException(sprintf(
+                 // TRANS: Server exception. %s is a URI.
                  _m("Tried to update avatar for unsaved remote profile %s."),
                  $this->uri));
          }
          $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
          try {
              if (!copy($url, $temp_filename)) {
+                 // TRANS: Server exception. %s is a URL.
                  throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
              }
  
  
              $oprofile->profile_id = $profile->insert();
              if (!$oprofile->profile_id) {
-             // TRANS: Exception.
+             // TRANS: Server exception.
                  throw new ServerException(_m('Can\'t save local profile.'));
              }
          } else {
  
              $oprofile->group_id = $group->insert();
              if (!$oprofile->group_id) {
-                 // TRANS: Exception.
+                 // TRANS: Server exception.
                  throw new ServerException(_m('Can\'t save local profile.'));
              }
          }
          $ok = $oprofile->insert();
  
          if (!$ok) {
-             // TRANS: Exception.
+             // TRANS: Server exception.
              throw new ServerException(_m('Can\'t save OStatus profile.'));
          }
  
  
          if ($file_id === false) {
              common_log_db_error($file, "INSERT", __FILE__);
+             // TRANS: Server exception.
              throw new ServerException(_m('Could not store HTML content of long post as file.'));
          }