]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'candrews-review' into 0.8.x
authorZach Copley <zach@controlyourself.ca>
Fri, 10 Jul 2009 21:03:44 +0000 (21:03 +0000)
committerZach Copley <zach@controlyourself.ca>
Fri, 10 Jul 2009 21:03:44 +0000 (21:03 +0000)
README
actions/twitapiusers.php
classes/Notice.php
classes/Profile.php
classes/User.php
lib/command.php
lib/common.php
lib/profileaction.php
lib/profilesection.php
lib/subs.php
lib/twitterapi.php

diff --git a/README b/README
index 97432e5660dcb537a5c970870783fb6566180ea8..40e5263550ef3c563c35566ae934e3c975b477b6 100644 (file)
--- a/README
+++ b/README
@@ -535,6 +535,11 @@ All the daemons write their process IDs (pids) to /var/run/ by
 default. This can be useful for starting, stopping, and monitoring the
 daemons.
 
+With version 0.8.0, it's now possible to use a STOMP server instead of
+our kind of hacky home-grown DB-based queue solution. See the "queues"
+config section below for how to configure to use STOMP. As of this
+writing, the software has been tested with ActiveMQ (
+
 Twitter Friends Syncing
 -----------------------
 
@@ -892,6 +897,8 @@ fancy: whether or not your site uses fancy URLs (see Fancy URLs
 logfile: full path to a file for Laconica to save logging
         information to. You may want to use this if you don't have
         access to syslog.
+logdebug: whether to log additional debug info like backtraces on
+          hard errors. Default false.
 locale_path: full path to the directory for locale data. Unless you
             store all your locale data in one place, you probably
             don't need to use this.
@@ -946,6 +953,15 @@ sslserver: use an alternate server name for SSL URLs, like
 shorturllength: Length of URL at which URLs in a message exceeding 140
                 characters will be sent to the user's chosen
                 shortening service.
+<<<<<<< HEAD:README
+design: a default design (colors and background) for the site.
+        Sub-items are: backgroundcolor, contentcolor, sidebarcolor,
+        textcolor, linkcolor, backgroundimage, disposition.
+dupelimit: minimum time allowed for one person to say the same thing
+           twice. Default 60s. Anything lower is considered a user
+           or UI error.
+=======
+>>>>>>> 0.7.x:README
 
 db
 --
@@ -996,6 +1012,10 @@ appname: The name that Laconica uses to log messages. By default it's
         "laconica", but if you have more than one installation on the
         server, you may want to change the name for each instance so
         you can track log messages more easily.
+priority: level to log at. Currently ignored.
+facility: what syslog facility to used. Defaults to LOG_USER, only
+          reset if you know what syslog is and have a good reason
+          to change it.
 
 queue
 -----
@@ -1005,7 +1025,19 @@ sending out SMS email or XMPP messages, for off-line processing. See
 'Queues and daemons' above for how to set this up.
 
 enabled: Whether to uses queues. Defaults to false.
-
+subsystem: Which kind of queueserver to use. Values include "db" for
+           our hacked-together database queuing (no other server
+           required) and "stomp" for a stomp server.
+stomp_server: "broker URI" for stomp server. Something like
+              "tcp://hostname:61613". More complicated ones are
+              possible; see your stomp server's documentation for
+              details.
+queue_basename: a root name to use for queues (stomp only). Typically
+                something like '/queue/sitename/' makes sense.
+stomp_username: username for connecting to the stomp server; defaults
+                to null.
+stomp_password: password for connecting to the stomp server; defaults
+                to null.
 license
 -------
 
@@ -1075,6 +1107,8 @@ localonly: If set to true, only messages posted by users of this
 blacklist: An array of IDs of users to hide from the public stream.
           Useful if you have someone making excessive Twitterfeed posts
           to the site, other kinds of automated posts, testing bots, etc.
+autosource: Sources of notices that are from automatic posters, and thus
+            should be kept off the public timeline. Default empty.
 
 theme
 -----
@@ -1137,6 +1171,15 @@ dropoff: Decay factor for tag listing, in seconds.
         Defaults to exponential decay over ten days; you can twiddle
         with it to try and get better results for your site.
 
+popular
+-------
+
+Settings for the "popular" section of the site.
+
+dropoff: Decay factor for popularity listing, in seconds.
+        Defaults to exponential decay over ten days; you can twiddle
+        with it to try and get better results for your site.
+
 daemon
 ------
 
@@ -1190,6 +1233,7 @@ source: The name to use for the source of posts to Twitter. Defaults
        Twitter <http://twitter.com/help/request_source>, you can use
        that here instead. Status updates on Twitter will then have
        links to your site.
+taguri: base for tag:// URIs. Defaults to site-server + ',2009'.
 
 inboxes
 -------
@@ -1276,7 +1320,7 @@ detection.
 
 supported: an array of mime types you accept to store and distribute,
            like 'image/gif', 'video/mpeg', 'audio/mpeg', etc. Make sure you
-           setup your server to properly reckognize the types you want to
+           setup your server to properly recognize the types you want to
            support.
 uploads:   false to disable uploading files with notices (true by default).
 filecommand: The required MIME_Type library may need to use the 'file'
@@ -1297,6 +1341,17 @@ user_quota: total size in bytes a user can store on this server. Each user
             not exceed the user_quota.
 monthly_quota: total size permitted in the current month. This is the total
             size in bytes that a user can upload each month.
+dir: directory accessible to the Web process where uploads should go.
+     Defaults to the 'file' subdirectory of the install directory, which
+     should be writeable by the Web user.
+server: server name to use when creating URLs for uploaded files.
+        Defaults to null, meaning to use the default Web server. Using
+        a virtual server here can speed up Web performance.
+path: URL path, relative to the server, to find files. Defaults to
+      main path + '/file/'.
+filecommand: command to use for determining the type of a file. May be
+             skipped if fileinfo extension is installed. Defaults to
+             '/usr/bin/file'.
 
 group
 -----
@@ -1337,6 +1392,38 @@ handle: boolean. Whether we should register our own PHP session-handling
 debug: whether to output debugging info for session storage. Can help
        with weird session bugs, sometimes. Default false.
 
+background
+----------
+
+Users can upload backgrounds for their pages; this section defines
+their use.
+
+server: the server to use for background. Using a separate (even
+        virtual) server for this can speed up load times. Default is
+        null; same as site server.
+dir: directory to write backgrounds too. Default is '/background/'
+     subdir of install dir.
+path: path to backgrounds. Default is sub-path of install path; note
+      that you may need to change this if you change site-path too.
+
+twitterbridge
+-------------
+
+A bi-direction bridge to Twitter (http://twitter.com/).
+
+enabled: default false. If true, will show user's Twitter friends'
+         notices in their inbox and faves pages, only to the user. You
+         must also run the twitterstatusfetcher.php script.
+
+ping
+----
+
+Using the "XML-RPC Ping" method initiated by weblogs.com, the site can
+notify third-party servers of updates.
+
+notify: an array of URLs for ping endpoints. Default is the empty
+        array (no notification).
+
 Troubleshooting
 ===============
 
index de8326e3adcc481bb77272d4ba14965ea7c4c397..fea41b3971d3f9a77b342e6304f6e83e96fa6784 100644 (file)
@@ -51,6 +51,13 @@ class TwitapiusersAction extends TwitterapiAction
             return;
         }
 
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
+
         $twitter_user = $this->twitter_user_array($user->getProfile(), true);
 
         if ($apidata['content-type'] == 'xml') {
index e975cab93ce6b44e8bef11375c866ec1d3304382..75044cf638ae1b5218a08863ceed01f2a59a4191 100644 (file)
@@ -356,6 +356,8 @@ class Notice extends Memcached_DataObject
         $this->blowTagCache($blowLast);
         $this->blowGroupCache($blowLast);
         $this->blowConversationCache($blowLast);
+        $profile = Profile::staticGet($this->profile_id);
+        $profile->blowNoticeCount();
     }
 
     function blowConversationCache($blowLast=false)
index a0ed6b3ca349e0da83dc161a409893f821cdb8af..224b61bd2ee3508f19789923879b07f5ae3582e5 100644 (file)
@@ -337,4 +337,132 @@ class Profile extends Memcached_DataObject
 
         return $profile;
     }
+
+    function subscriptionCount()
+    {
+        $c = common_memcache();
+
+        if (!empty($c)) {
+            $cnt = $c->get(common_cache_key('profile:subscription_count:'.$this->id));
+            if (is_integer($cnt)) {
+                return (int) $cnt;
+            }
+        }
+
+        $sub = new Subscription();
+        $sub->subscriber = $this->id;
+
+        $cnt = (int) $sub->count('distinct subscribed');
+
+        $cnt = ($cnt > 0) ? $cnt - 1 : $cnt;
+
+        if (!empty($c)) {
+            $c->set(common_cache_key('profile:subscription_count:'.$this->id), $cnt);
+        }
+
+        common_debug("subscriptionCount == $cnt");
+        return $cnt;
+    }
+
+    function subscriberCount()
+    {
+        $c = common_memcache();
+        if (!empty($c)) {
+            $cnt = $c->get(common_cache_key('profile:subscriber_count:'.$this->id));
+            if (is_integer($cnt)) {
+                return (int) $cnt;
+            }
+        }
+
+        $sub = new Subscription();
+        $sub->subscribed = $this->id;
+
+        $cnt = (int) $sub->count('distinct subscriber');
+
+        $cnt = ($cnt > 0) ? $cnt - 1 : $cnt;
+
+        if (!empty($c)) {
+            $c->set(common_cache_key('profile:subscriber_count:'.$this->id), $cnt);
+        }
+
+        common_debug("subscriberCount == $cnt");
+        return $cnt;
+    }
+
+    function faveCount()
+    {
+        $c = common_memcache();
+        if (!empty($c)) {
+            $cnt = $c->get(common_cache_key('profile:fave_count:'.$this->id));
+            if (is_integer($cnt)) {
+                return (int) $cnt;
+            }
+        }
+
+        $faves = new Fave();
+        $faves->user_id = $this->id;
+        $cnt = (int) $faves->count('distinct notice_id');
+
+        if (!empty($c)) {
+            $c->set(common_cache_key('profile:fave_count:'.$this->id), $cnt);
+        }
+
+        common_debug("faveCount == $cnt");
+        return $cnt;
+    }
+
+    function noticeCount()
+    {
+        $c = common_memcache();
+
+        if (!empty($c)) {
+            $cnt = $c->get(common_cache_key('profile:notice_count:'.$this->id));
+            if (is_integer($cnt)) {
+                return (int) $cnt;
+            }
+        }
+
+        $notices = new Notice();
+        $notices->profile_id = $this->id;
+        $cnt = (int) $notices->count('distinct id');
+
+        if (!empty($c)) {
+            $c->set(common_cache_key('profile:notice_count:'.$this->id), $cnt);
+        }
+
+        common_debug("noticeCount == $cnt");
+        return $cnt;
+    }
+
+    function blowSubscriberCount()
+    {
+        $c = common_memcache();
+        if (!empty($c)) {
+            $c->delete(common_cache_key('profile:subscriber_count:'.$this->id));
+        }
+    }
+
+    function blowSubscriptionCount()
+    {
+        $c = common_memcache();
+        if (!empty($c)) {
+            $c->delete(common_cache_key('profile:subscription_count:'.$this->id));
+        }
+    }
+
+    function blowFaveCount()
+    {
+        $c = common_memcache();
+        if (!empty($c)) {
+            $c->delete(common_cache_key('profile:fave_count:'.$this->id));
+        }
+    }
+
+    function blowNoticeCount()
+    {
+        $c = common_memcache();
+        if (!empty($c)) {
+            $c->delete(common_cache_key('profile:notice_count:'.$this->id));
+        }
+    }
 }
index 04b38a0d2223ef7d240768ec0de6282d03bc51a8..6c1f149e4ded31fca07627ab0c16210e63ece717 100644 (file)
@@ -494,6 +494,8 @@ class User extends Memcached_DataObject
             $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'));
         }
+        $profile = $this->getProfile();
+        $profile->blowFaveCount();
     }
 
     function getSelfTags()
index 56466138293caa18cab3023d5bfca0dd2a24ffff..4e2280bc8070d58bc5edefc5edd09230f5a7c95b 100644 (file)
@@ -97,18 +97,11 @@ class StatsCommand extends Command
 {
     function execute($channel)
     {
+        $profile = $this->user->getProfile();
 
-        $subs = new Subscription();
-        $subs->subscriber = $this->user->id;
-        $subs_count = (int) $subs->count() - 1;
-
-        $subbed = new Subscription();
-        $subbed->subscribed = $this->user->id;
-        $subbed_count = (int) $subbed->count() - 1;
-
-        $notices = new Notice();
-        $notices->profile_id = $this->user->id;
-        $notice_count = (int) $notices->count();
+        $subs_count   = $profile->subscriptionCount();
+        $subbed_count = $profile->subscriberCount();
+        $notice_count = $profile->noticeCount();
 
         $channel->output($this->user, sprintf(_("Subscriptions: %1\$s\n".
                                    "Subscribers: %2\$s\n".
index 14be747bc7a65db1ac31f44bbfc2c9899c71ad51..c47702779d9fa4f8827213ccfd053345c064def2 100644 (file)
@@ -19,7 +19,7 @@
 
 if (!defined('LACONICA')) { exit(1); }
 
-define('LACONICA_VERSION', '0.8.0dev');
+define('LACONICA_VERSION', '0.8.0');
 
 define('AVATAR_PROFILE_SIZE', 96);
 define('AVATAR_STREAM_SIZE', 48);
@@ -206,7 +206,7 @@ $config =
         'inboxes' =>
         array('enabled' => true), # on by default for new sites
         'newuser' =>
-        array('subscribe' => null,
+        array('default' => null,
               'welcome' => null),
         'snapshot' =>
         array('run' => 'web',
@@ -282,6 +282,39 @@ if (function_exists('date_default_timezone_set')) {
     date_default_timezone_set('UTC');
 }
 
+function addPlugin($name, $attrs = null)
+{
+    $name = ucfirst($name);
+    $pluginclass = "{$name}Plugin";
+
+    if (!class_exists($pluginclass)) {
+
+        $files = array("local/plugins/{$pluginclass}.php",
+                       "local/plugins/{$name}/{$pluginclass}.php",
+                       "local/{$pluginclass}.php",
+                       "local/{$name}/{$pluginclass}.php",
+                       "plugins/{$pluginclass}.php",
+                       "plugins/{$name}/{$pluginclass}.php");
+
+        foreach ($files as $file) {
+            $fullpath = INSTALLDIR.'/'.$file;
+            if (@file_exists($fullpath)) {
+                include_once($fullpath);
+                break;
+            }
+        }
+    }
+
+    $inst = new $pluginclass();
+
+    if (!empty($attrs)) {
+        foreach ($attrs as $aname => $avalue) {
+            $inst->$aname = $avalue;
+        }
+    }
+    return $inst;
+}
+
 // From most general to most specific:
 // server-wide, then vhost-wide, then for a path,
 // finally for a dir (usually only need one of the last two).
index eeb5dbe48d80db5510b98861626f62ad6badd343..9e9c79c78a90436c76397427826ecf40f4d41bc2 100644 (file)
@@ -163,18 +163,9 @@ class ProfileAction extends OwnerDesignAction
 
     function showStatistics()
     {
-        // XXX: WORM cache this
-        $subs = new Subscription();
-        $subs->subscriber = $this->profile->id;
-        $subs_count = (int) $subs->count() - 1;
-
-        $subbed = new Subscription();
-        $subbed->subscribed = $this->profile->id;
-        $subbed_count = (int) $subbed->count() - 1;
-
-        $notices = new Notice();
-        $notices->profile_id = $this->profile->id;
-        $notice_count = (int) $notices->count();
+        $subs_count   = $this->profile->subscriptionCount();
+        $subbed_count = $this->profile->subscriberCount();
+        $notice_count = $this->profile->noticeCount();
 
         $this->elementStart('div', array('id' => 'entity_statistics',
                                          'class' => 'section'));
@@ -199,7 +190,7 @@ class ProfileAction extends OwnerDesignAction
                                                              array('nickname' => $this->profile->nickname))),
                        _('Subscriptions'));
         $this->elementEnd('dt');
-        $this->element('dd', null, (is_int($subs_count)) ? $subs_count : '0');
+        $this->element('dd', null, $subs_count);
         $this->elementEnd('dl');
 
         $this->elementStart('dl', 'entity_subscribers');
@@ -208,12 +199,12 @@ class ProfileAction extends OwnerDesignAction
                                                              array('nickname' => $this->profile->nickname))),
                        _('Subscribers'));
         $this->elementEnd('dt');
-        $this->element('dd', 'subscribers', (is_int($subbed_count)) ? $subbed_count : '0');
+        $this->element('dd', 'subscribers', $subbed_count);
         $this->elementEnd('dl');
 
         $this->elementStart('dl', 'entity_notices');
         $this->element('dt', null, _('Notices'));
-        $this->element('dd', null, (is_int($notice_count)) ? $notice_count : '0');
+        $this->element('dd', null, $notice_count);
         $this->elementEnd('dl');
 
         $this->elementEnd('div');
index 8ed290e03aa3c6195567da6c50401f8b12924cdf..9ff243fb53fab479a7ebd9142032409cbab4366f 100644 (file)
@@ -94,8 +94,8 @@ class ProfileSection extends Section
                                     $profile->fullname :
                                     $profile->nickname));
         $this->out->element('span', 'fn nickname', $profile->nickname);
-        $this->out->elementEnd('span');
         $this->out->elementEnd('a');
+        $this->out->elementEnd('span');
         $this->out->elementEnd('td');
         if ($profile->value) {
             $this->out->element('td', 'value', $profile->value);
index 3bd67b39c7142ffb64deb1926afa378b4315cfa0..e76023752725344128009f3dc2af602c9d3d5b93 100644 (file)
@@ -44,7 +44,6 @@ function subs_subscribe_user($user, $other_nickname)
 
 function subs_subscribe_to($user, $other)
 {
-
     if ($user->isSubscribed($other)) {
         return _('Already subscribed!.');
     }
@@ -60,12 +59,16 @@ function subs_subscribe_to($user, $other)
 
     subs_notify($other, $user);
 
-        $cache = common_memcache();
+    $cache = common_memcache();
 
     if ($cache) {
         $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
        }
 
+    $profile = $user->getProfile();
+
+    $profile->blowSubscriptionsCount();
+    $other->blowSubscribersCount();
 
     if ($other->autosubscribe && !$other->isSubscribed($user) && !$user->hasBlocked($other)) {
         if (!$other->subscribeTo($user)) {
@@ -117,7 +120,6 @@ function subs_unsubscribe_user($user, $other_nickname)
 
 function subs_unsubscribe_to($user, $other)
 {
-
     if (!$user->isSubscribed($other))
         return _('Not subscribed!.');
 
@@ -139,6 +141,11 @@ function subs_unsubscribe_to($user, $other)
         $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
        }
 
+    $profile = $user->getProfile();
+
+    $profile->blowSubscriptionsCount();
+    $other->blowSubscribersCount();
+
     return true;
 }
 
index 8f902cbcaf87066ab58cc5d1cd2e693d19145db0..f48513e67f7d243140cdba2c19883dadc10cb2a0 100644 (file)
@@ -89,7 +89,7 @@ class TwitterapiAction extends Action
 
         $twitter_user['url'] = ($profile->homepage) ? $profile->homepage : null;
         $twitter_user['protected'] = false; # not supported by Laconica yet
-        $twitter_user['followers_count'] = $this->count_subscriptions($profile);
+        $twitter_user['followers_count'] = $profile->subscriberCount();
 
         // To be supported soon...
         $twitter_user['profile_background_color'] = '';
@@ -98,17 +98,11 @@ class TwitterapiAction extends Action
         $twitter_user['profile_sidebar_fill_color'] = '';
         $twitter_user['profile_sidebar_border_color'] = '';
 
-        $subbed = DB_DataObject::factory('subscription');
-        $subbed->subscriber = $profile->id;
-        $subbed_count = (int) $subbed->count() - 1;
-        $twitter_user['friends_count'] = (is_int($subbed_count)) ? $subbed_count : 0;
+        $twitter_user['friends_count'] = $profile->subscriptionCount();
 
         $twitter_user['created_at'] = $this->date_twitter($profile->created);
 
-        $faves = DB_DataObject::factory('fave');
-        $faves->user_id = $user->id;
-        $faves_count = (int) $faves->count();
-        $twitter_user['favourites_count'] = $faves_count; // British spelling!
+        $twitter_user['favourites_count'] = $profile->faveCount(); // British spelling!
 
         // Need to pull up the user for some of this
         $user = User::staticGet($profile->id);
@@ -129,11 +123,7 @@ class TwitterapiAction extends Action
         $twitter_user['profile_background_image_url'] = '';
         $twitter_user['profile_background_tile'] = false;
 
-        $notices = DB_DataObject::factory('notice');
-        $notices->profile_id = $profile->id;
-        $notice_count = (int) $notices->count();
-
-        $twitter_user['statuses_count'] = (is_int($notice_count)) ? $notice_count : 0;
+        $twitter_user['statuses_count'] = $profile->noticeCount();
 
         // Is the requesting user following this user?
         $twitter_user['following'] = false;
@@ -396,7 +386,7 @@ class TwitterapiAction extends Action
             $enclosure = $entry['enclosures'][0];
             $this->element('enclosure', array('url'=>$enclosure['url'],'type'=>$enclosure['mimetype'],'length'=>$enclosure['size']), null);
         }
-        
+
         $this->elementEnd('item');
     }