]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'invite-enabled' of git://gitorious.org/~jeff-themovie/laconica/jeff...
authorJeffery To <jeffery.to@gmail.com>
Fri, 26 Jun 2009 07:39:08 +0000 (15:39 +0800)
committerJeffery To <jeffery.to@gmail.com>
Fri, 26 Jun 2009 07:39:08 +0000 (15:39 +0800)
49 files changed:
actions/conversation.php
actions/file.php
actions/groupdesignsettings.php
actions/newnotice.php
actions/public.php
actions/showfavorites.php
actions/twitapifavorites.php
actions/twitapistatuses.php
actions/userdesignsettings.php
classes/Fave.php
classes/File.php
classes/File_redirection.php
classes/File_to_post.php
classes/Foreign_user.php
classes/Group_inbox.php
classes/Notice.php
classes/Notice_inbox.php
classes/Profile.php
classes/User.php
classes/User_group.php
db/074to080.sql [new file with mode: 0644]
db/laconica.sql
index.php
js/userdesign.go.js
js/util.js
lib/attachmentlist.php
lib/common.php
lib/designsettings.php
lib/imagefile.php
lib/noticelist.php
lib/queuehandler.php
lib/util.php
lib/xmppqueuehandler.php
scripts/allsites.php [new file with mode: 0755]
scripts/delete_status_network.sh [new file with mode: 0755]
scripts/getvaliddaemons.php
scripts/jabberqueuehandler.php
scripts/publicqueuehandler.php
scripts/setup.cfg.sample
scripts/setup_status_network.sh
scripts/startdaemons.sh
scripts/xmppconfirmhandler.php
scripts/xmppdaemon.php
theme/base/css/display.css
theme/base/css/ie.css
theme/default/css/display.css
theme/default/css/ie.css
theme/identica/css/display.css
theme/identica/css/ie.css

index d3fc5b6a9c31d124056619d6a2a0d5c771f8ae10..654a670f54ca6113ddcc31ad34503c29cfdf1791 100644 (file)
@@ -63,6 +63,7 @@ class ConversationAction extends Action
         if (empty($this->id)) {
             return false;
         }
+        $this->id = $this->id+0;
         $this->page = $this->trimmed('page');
         if (empty($this->page)) {
             $this->page = 1;
@@ -106,18 +107,10 @@ class ConversationAction extends Action
 
     function showContent()
     {
-        // FIXME this needs to be a tree, not a list
-
-        $qry = 'SELECT * FROM notice WHERE conversation = %s ';
-
         $offset = ($this->page-1) * NOTICES_PER_PAGE;
         $limit  = NOTICES_PER_PAGE + 1;
 
-        $txt = sprintf($qry, $this->id);
-
-        $notices = Notice::getStream($txt,
-                                     'notice:conversation:'.$this->id,
-                                     $offset, $limit);
+        $notices = Notice::conversationStream($this->id, $offset, $limit);
 
         $ct = new ConversationTree($notices, $this);
 
@@ -126,7 +119,6 @@ class ConversationAction extends Action
         $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
                           $this->page, 'conversation', array('id' => $this->id));
     }
-
 }
 
 /**
index bb245c4a778abd73145db2b3006e061008a1fee9..271f57ab9634aeaa4a6d675d30ac46a2849f30c8 100644 (file)
@@ -21,20 +21,40 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/actions/shownotice.php');
 
-class FileAction extends ShowNoticeAction
+class FileAction extends Action
 {
-    function showPage() {
-        $source_url = common_local_url('file', array('notice' => $this->notice->id));
-        $query = "select file_redirection.url as url from file join file_redirection on file.id = file_redirection.file_id where file.url = '$source_url'";
-        $file = new File_redirection;
-        $file->query($query);
-        $file->fetch();
-        if (empty($file->url)) {
-            die('nothing attached here');
-        } else {
-            header("Location: {$file->url}");
-            die();
+    var $id = null;
+    var $filerec = null;
+
+    function prepare($args)
+    {
+        parent::prepare($args);
+        $this->id = $this->trimmed('notice');
+        if (empty($this->id)) {
+            $this->clientError(_('No notice id'));
+        }
+        $notice = Notice::staticGet('id', $this->id);
+        if (empty($notice)) {
+            $this->clientError(_('No notice'));
+        }
+        $atts = $notice->attachments();
+        if (empty($atts)) {
+            $this->clientError(_('No attachments'));
+        }
+        foreach ($atts as $att) {
+            if (!empty($att->filename)) {
+                $this->filerec = $att;
+                break;
+            }
         }
+        if (empty($this->filerec)) {
+            $this->clientError(_('No uploaded attachments'));
+        }
+        return true;
+    }
+
+    function handle() {
+        common_redirect($this->filerec->url);
     }
 }
 
index 7270bc8f7ecf7023c3accff952548953f3b3a61d..79c192ac466bceeb9b0988a67ade4a9ae2ab7aad 100644 (file)
@@ -238,7 +238,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction
             $design->sidebarcolor    = $sbcolor->intValue();
             $design->textcolor       = $tcolor->intValue();
             $design->linkcolor       = $lcolor->intValue();
-            $design->backgroundimage = $filepath;
 
             $design->setDisposition($on, $off, $tile);
 
@@ -263,7 +262,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction
             $design->sidebarcolor    = $sbcolor->intValue();
             $design->textcolor       = $tcolor->intValue();
             $design->linkcolor       = $lcolor->intValue();
-            $design->backgroundimage = $filepath;
 
             $design->setDisposition($on, $off, $tile);
 
index 4a2c369f0f873de20b425ef30c3b3be2589a07fc..15caff6eaab0042783314c8cc1e6d80e7f9977cc 100644 (file)
@@ -236,6 +236,7 @@ class NewnoticeAction extends Action
                 $this->deleteFile($filename);
                 $this->clientError(_('Max notice size is 140 chars, including attachment URL.'));
             }
+            $fileRecord = $this->rememberFile($filename, $mimetype, $short_fileurl);
         }
 
         $notice = Notice::saveNew($user->id, $content_shortened, 'web', 1,
@@ -249,7 +250,7 @@ class NewnoticeAction extends Action
         }
 
         if (isset($mimetype)) {
-            $this->attachFile($notice, $filename, $mimetype, $short_fileurl);
+            $this->attachFile($notice, $fileRecord);
         }
 
         common_broadcast_notice($notice);
@@ -304,12 +305,12 @@ class NewnoticeAction extends Action
         @unlink($filepath);
     }
 
-    function attachFile($notice, $filename, $mimetype, $short)
+    function rememberFile($filename, $mimetype, $short)
     {
         $file = new File;
         $file->filename = $filename;
 
-        $file->url = common_local_url('file', array('notice' => $notice->id));
+        $file->url = File::url($filename);
 
         $filepath = File::path($filename);
 
@@ -324,28 +325,37 @@ class NewnoticeAction extends Action
             $this->clientError(_('There was a database error while saving your file. Please try again.'));
         }
 
-        $file_redir = new File_redirection;
-        $file_redir->url = File::url($filename);
-        $file_redir->file_id = $file_id;
+        $this->maybeAddRedir($file_id, $short);
 
-        $result = $file_redir->insert();
+        return $file;
+    }
 
-        if (!$result) {
-            common_log_db_error($file_redir, "INSERT", __FILE__);
-            $this->clientError(_('There was a database error while saving your file. Please try again.'));
-        }
+    function maybeAddRedir($file_id, $url)
+    {
+        $file_redir = File_redirection::staticGet('url', $url);
 
-        $f2p = new File_to_post;
-        $f2p->file_id = $file_id;
-        $f2p->post_id = $notice->id;
-        $f2p->insert();
+        if (empty($file_redir)) {
+            $file_redir = new File_redirection;
+            $file_redir->url = $url;
+            $file_redir->file_id = $file_id;
 
-        if (!$result) {
-            common_log_db_error($f2p, "INSERT", __FILE__);
-            $this->clientError(_('There was a database error while saving your file. Please try again.'));
+            $result = $file_redir->insert();
+
+            if (!$result) {
+                common_log_db_error($file_redir, "INSERT", __FILE__);
+                $this->clientError(_('There was a database error while saving your file. Please try again.'));
+            }
         }
     }
 
+    function attachFile($notice, $filerec)
+    {
+        File_to_post::processNew($filerec->id, $notice->id);
+
+        $this->maybeAddRedir($filerec->id,
+            common_local_url('file', array('notice' => $notice->id)));
+    }
+
     /**
      * Show an Ajax-y error message
      *
index 27153f13159daf2c990ba7937cc697e0724ad27f..9851285c4821367288b1bd8c5797d3a4912ca840 100644 (file)
@@ -35,6 +35,10 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php';
 require_once INSTALLDIR.'/lib/noticelist.php';
 require_once INSTALLDIR.'/lib/feedlist.php';
 
+// Farther than any human will go
+
+define('MAX_PUBLIC_PAGE', 100);
+
 /**
  * Action for displaying the public stream
  *
@@ -74,6 +78,10 @@ class PublicAction extends Action
         parent::prepare($args);
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
 
+        if ($this->page > MAX_PUBLIC_PAGE) {
+            $this->clientError(sprintf(_("Beyond the page limit (%s)"), MAX_PUBLIC_PAGE));
+        }
+
         common_set_returnto($this->selfUrl());
 
         return true;
index 01f38a8927ced49a4a2f88864f905e9b4104bbaf..b723924a5e0a323209f0daf09888933841b0b9b6 100644 (file)
@@ -191,10 +191,21 @@ class ShowfavoritesAction extends CurrentUserDesignAction
 
     function showContent()
     {
-        $notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
-                                               NOTICES_PER_PAGE + 1);
+        $cur = common_current_user();
 
-        if (!$notice) {
+        if (!empty($cur) && $cur->id == $this->user->id) {
+
+            // Show imported/gateway notices as well as local if
+            // the user is looking at his own favorites
+
+            $notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
+                                                   NOTICES_PER_PAGE + 1, true);
+        } else {
+            $notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
+                                                   NOTICES_PER_PAGE + 1, false);
+        }
+
+        if (empty($notice)) {
             $this->serverError(_('Could not retrieve favorite notices.'));
             return;
         }
index e40fea91afa7997e1d952e1d28e77b1c32c44c50..8256668f3d22a0622de9e3708c64173d4eab4ad1 100644 (file)
@@ -61,7 +61,11 @@ class TwitapifavoritesAction extends TwitterapiAction
         $since_id = (int)$this->arg('since_id', 0);
         $since    = $this->arg('since');
 
-        $notice = $user->favoriteNotices(($page-1)*$count, $count);
+        if (!empty($this->auth_user) && $this->auth_user->id == $user->id) {
+            $notice = $user->favoriteNotices(($page-1)*$count, $count, true);
+        } else {
+            $notice = $user->favoriteNotices(($page-1)*$count, $count, false);
+        }
 
         switch($apidata['content-type']) {
         case 'xml':
index 2bc404063846d58f15fdc63b845837aba97b5a1e..555c746cbcae6b041369627a89cc61dc1ef721d6 100644 (file)
@@ -75,8 +75,8 @@ class TwitapistatusesAction extends TwitterapiAction
     {
         parent::handle($args);
 
+        $this->auth_user = $apidata['user'];
         $user = $this->get_user($apidata['api_arg'], $apidata);
-        $this->auth_user = $user;
 
         if (empty($user)) {
              $this->clientError(_('No such user!'), 404,
@@ -100,8 +100,13 @@ class TwitapistatusesAction extends TwitterapiAction
         $since_id = (int)$this->arg('since_id', 0);
         $since    = $this->arg('since');
 
-        $notice = $user->noticesWithFriends(($page-1)*$count,
-            $count, $since_id, $max_id,$since);
+        if (!empty($this->auth_user) && $this->auth_user->id == $user->id) {
+            $notice = $user->noticeInbox(($page-1)*$count,
+                $count, $since_id, $max_id, $since);
+        } else {
+            $notice = $user->noticesWithFriends(($page-1)*$count,
+                $count, $since_id, $max_id, $since);
+        }
 
         switch($apidata['content-type']) {
         case 'xml':
index d6088aa9d004d39f152de0f786b3881b7478a7da..6e745e96f8dd9614da4743822a95bf1937062500 100644 (file)
@@ -149,7 +149,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
             $design->sidebarcolor    = $sbcolor->intValue();
             $design->textcolor       = $tcolor->intValue();
             $design->linkcolor       = $lcolor->intValue();
-            $design->backgroundimage = $filepath;
 
             $design->setDisposition($on, $off, $tile);
 
@@ -174,7 +173,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
             $design->sidebarcolor    = $sbcolor->intValue();
             $design->textcolor       = $tcolor->intValue();
             $design->linkcolor       = $lcolor->intValue();
-            $design->backgroundimage = $filepath;
 
             $design->setDisposition($on, $off, $tile);
 
index 572334ce4f8cf17e8811cf0eab51cd77ed922549..f4cf6256ff314af7aca2b5b7867c5dca011b8177 100644 (file)
@@ -37,52 +37,62 @@ class Fave extends Memcached_DataObject
         return Memcached_DataObject::pkeyGet('Fave', $kv);
     }
 
-    function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE)
+    function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $own=false)
     {
         $ids = Notice::stream(array('Fave', '_streamDirect'),
-                              array($user_id),
-                              'fave:ids_by_user:'.$user_id,
+                              array($user_id, $own),
+                              ($own) ? 'fave:ids_by_user_own:'.$user_id :
+                              'fave:by_user:'.$user_id,
                               $offset, $limit);
         return $ids;
     }
 
-    function _streamDirect($user_id, $offset, $limit, $since_id, $max_id, $since)
+    function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id, $since)
     {
         $fav = new Fave();
-
-        $fav->user_id = $user_id;
-
-        $fav->selectAdd();
-        $fav->selectAdd('notice_id');
+        $qry = null;
+
+        if ($own) {
+            $qry  = 'SELECT fave.* FROM fave ';
+            $qry .= 'WHERE fave.user_id = ' . $user_id . ' ';
+        } else {
+             $qry =  'SELECT fave.* FROM fave ';
+             $qry .= 'INNER JOIN notice ON fave.notice_id = notice.id ';
+             $qry .= 'WHERE fave.user_id = ' . $user_id . ' ';
+             $qry .= 'AND notice.is_local != ' . NOTICE_GATEWAY . ' ';
+        }
 
         if ($since_id != 0) {
-            $fav->whereAdd('notice_id > ' . $since_id);
+            $qry .= 'AND notice_id > ' . $since_id . ' ';
         }
 
         if ($max_id != 0) {
-            $fav->whereAdd('notice_id <= ' . $max_id);
+            $qry .= 'AND notice_id <= ' . $max_id . ' ';
         }
 
         if (!is_null($since)) {
-            $fav->whereAdd('modified > \'' . date('Y-m-d H:i:s', $since) . '\'');
+            $qry .= 'AND modified > \'' . date('Y-m-d H:i:s', $since) . '\' ';
         }
 
         // NOTE: we sort by fave time, not by notice time!
 
-        $fav->orderBy('modified DESC');
+        $qry .= 'ORDER BY modified DESC ';
 
         if (!is_null($offset)) {
-            $fav->limit($offset, $limit);
+            $qry .= "LIMIT $offset, $limit";
         }
 
+        $fav->query($qry);
+
         $ids = array();
 
-        if ($fav->find()) {
-            while ($fav->fetch()) {
-                $ids[] = $fav->notice_id;
-            }
+        while ($fav->fetch()) {
+            $ids[] = $fav->notice_id;
         }
 
+        $fav->free();
+        unset($fav);
+
         return $ids;
     }
 }
index b98c9e665faede2082577995b96c4468da11596b..5dd7cd8651d832faa6197000627190be09c3946f 100644 (file)
@@ -91,9 +91,10 @@ class File extends Memcached_DataObject
         $given_url = File_redirection::_canonUrl($given_url);
         if (empty($given_url)) return -1;   // error, no url to process
         $file = File::staticGet('url', $given_url);
-        if (empty($file->id)) {
+        if (empty($file)) {
             $file_redir = File_redirection::staticGet('url', $given_url);
-            if (empty($file_redir->id)) {
+            if (empty($file_redir)) {
+                common_debug("processNew() '$given_url' not a known redirect.\n");
                 $redir_data = File_redirection::where($given_url);
                 $redir_url = $redir_data['url'];
                 if ($redir_url === $given_url) {
index c173017e2df1efffbcd8c32dd76618404006b89d..d6fa0bcb6286bc6d13b6527e40b99b92878606db 100644 (file)
@@ -66,21 +66,17 @@ class File_redirection extends Memcached_DataObject
 
         // let's see if we know this...
         $a = File::staticGet('url', $short_url);
-        if (empty($a->id)) {
+
+        if (!empty($a)) {
+            // this is a direct link to $a->url
+            return $a->url;
+        } else {
             $b = File_redirection::staticGet('url', $short_url);
-            if (empty($b->id)) {
-                // we'll have to figure it out
-            } else {
+            if (!empty($b)) {
                 // this is a redirect to $b->file_id
-                $a = File::staticGet($b->file_id);
-                $url = $a->url;
+                $a = File::staticGet('id', $b->file_id);
+                return $a->url;
             }
-        } else {
-            // this is a direct link to $a->url
-            $url = $a->url;
-        }
-        if (isset($url)) {
-            return $url;
         }
 
         $curlh = File_redirection::_commonCurl($short_url, $redirs);
@@ -118,28 +114,22 @@ class File_redirection extends Memcached_DataObject
     }
 
     function makeShort($long_url) {
-        $long_url = File_redirection::_canonUrl($long_url);
-        // do we already know this long_url and have a short redirection for it?
-        $file       = new File;
-        $file_redir = new File_redirection;
-        $file->url  = $long_url;
-        $file->joinAdd($file_redir);
-        $file->selectAdd('length(file_redirection.url) as len');
-        $file->limit(1);
-        $file->orderBy('len');
-        $file->find(true);
-        if (!empty($file->url) && (strlen($file->url) < strlen($long_url))) {
-            return $file->url;
-        }
 
-        // if yet unknown, we must find a short url according to user settings
-        $short_url = File_redirection::_userMakeShort($long_url, common_current_user());
-        return $short_url;
+        $canon = File_redirection::_canonUrl($long_url);
+
+        $short_url = File_redirection::_userMakeShort($canon);
+
+        // Did we get one? Is it shorter?
+        if (!empty($short_url) && mb_strlen($short_url) < mb_strlen($long_url)) {
+            return $short_url;
+        } else {
+            return $long_url;
+        }
     }
 
-    function _userMakeShort($long_url, $user) {
+    function _userMakeShort($long_url) {
         $short_url = common_shorten_url($long_url);
-        if ($short_url) {
+        if (!empty($short_url) && $short_url != $long_url) {
             $short_url = (string)$short_url;
             // store it
             $file = File::staticGet('url', $long_url);
@@ -162,7 +152,7 @@ class File_redirection extends Memcached_DataObject
             }
             return $short_url;
         }
-        return $long_url;
+        return null;
     }
 
     function _canonUrl($in_url, $default_scheme = 'http://') {
index db0a8d2169c4f67bb45502c10f71b29a9e75bafb..d35febb77873af9503cdbe74460882d543e2a15f 100644 (file)
@@ -25,7 +25,7 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
  * Table Definition for file_to_post
  */
 
-class File_to_post extends Memcached_DataObject 
+class File_to_post extends Memcached_DataObject
 {
     ###START_AUTOCODE
     /* the code below is auto generated do not remove the above tag */
@@ -44,17 +44,27 @@ class File_to_post extends Memcached_DataObject
     function processNew($file_id, $notice_id) {
         static $seen = array();
         if (empty($seen[$notice_id]) || !in_array($file_id, $seen[$notice_id])) {
-            $f2p = new File_to_post;
-            $f2p->file_id = $file_id;
-            $f2p->post_id = $notice_id;
-            $f2p->insert();
+
+            $f2p = File_to_post::pkeyGet(array('post_id' => $notice_id,
+                                               'file_id' => $file_id));
+            if (empty($f2p)) {
+                $f2p = new File_to_post;
+                $f2p->file_id = $file_id;
+                $f2p->post_id = $notice_id;
+                $f2p->insert();
+            }
+
             if (empty($seen[$notice_id])) {
                 $seen[$notice_id] = array($file_id);
             } else {
                 $seen[$notice_id][] = $file_id;
             }
         }
+    }
 
+    function &pkeyGet($kv)
+    {
+        return Memcached_DataObject::pkeyGet('File_to_post', $kv);
     }
 }
 
index 61727abe5ed5924d6a8a7bb41eb721a2d672cefc..8b3e03dfb33f3d7f5c1e39cdf2d04160c72d07de 100644 (file)
@@ -4,42 +4,41 @@
  */
 require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
 
-class Foreign_user extends Memcached_DataObject 
+class Foreign_user extends Memcached_DataObject
 {
     ###START_AUTOCODE
     /* the code below is auto generated do not remove the above tag */
 
     public $__table = 'foreign_user';                    // table name
-    public $id;                              // int(4)  primary_key not_null
+    public $id;                              // bigint(8)  primary_key not_null
     public $service;                         // int(4)  primary_key not_null
     public $uri;                             // varchar(255)  unique_key not_null
-    public $nickname;                        // varchar(255)  
+    public $nickname;                        // varchar(255)
     public $created;                         // datetime()   not_null
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=null)
-    { return Memcached_DataObject::staticGet('Foreign_user',$k,$v); }
+    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Foreign_user',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
-    
+
     // XXX:  This only returns a 1->1 single obj mapping.  Change?  Or make
     // a getForeignUsers() that returns more than one? --Zach
-    static function getForeignUser($id, $service) {        
+    static function getForeignUser($id, $service) {
         $fuser = new Foreign_user();
         $fuser->whereAdd("service = $service");
         $fuser->whereAdd("id = $id");
         $fuser->limit(1);
-        
+
         if ($fuser->find()) {
             $fuser->fetch();
             return $fuser;
         }
-        
-        return null;        
+
+        return null;
     }
-    
+
     function updateKeys(&$orig)
     {
         $parts = array();
@@ -68,5 +67,4 @@ class Foreign_user extends Memcached_DataObject
         return $result;
     }
 
-    
 }
index b80ba42729d8b84cfb0a9186584721406d6355d7..1af7439f7f749e668824773aa6363012e77e33f2 100644 (file)
@@ -14,8 +14,14 @@ class Group_inbox extends Memcached_DataObject
     public $created;                         // datetime()   not_null
 
     /* Static get */
+
     function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Group_inbox',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
+
+    function &pkeyGet($kv)
+    {
+        return Memcached_DataObject::pkeyGet('Group_inbox', $kv);
+    }
 }
index b6bbf66cacd376f3e8f136df4b16280c570aee26..fdcef1bc2ed6de3e17a82e505abe90b2aeb5eebf 100644 (file)
@@ -331,6 +331,20 @@ class Notice extends Memcached_DataObject
         return $n_attachments;
     }
 
+    function attachments() {
+        // XXX: cache this
+        $att = array();
+        $f2p = new File_to_post;
+        $f2p->post_id = $this->id;
+        if ($f2p->find()) {
+            while ($f2p->fetch()) {
+                $f = File::staticGet($f2p->file_id);
+                $att[] = clone($f);
+            }
+        }
+        return $att;
+    }
+
     function blowCaches($blowLast=false)
     {
         $this->blowSubsCache($blowLast);
@@ -339,6 +353,19 @@ class Notice extends Memcached_DataObject
         $this->blowPublicCache($blowLast);
         $this->blowTagCache($blowLast);
         $this->blowGroupCache($blowLast);
+        $this->blowConversationCache($blowLast);
+    }
+
+    function blowConversationCache($blowLast=false)
+    {
+        $cache = common_memcache();
+        if ($cache) {
+            $ck = common_cache_key('notice:conversation_ids:'.$this->conversation);
+            $cache->delete($ck);
+            if ($blowLast) {
+                $cache->delete($ck.';last');
+            }
+        }
     }
 
     function blowGroupCache($blowLast=false)
@@ -471,8 +498,10 @@ class Notice extends Memcached_DataObject
             if ($fave->find()) {
                 while ($fave->fetch()) {
                     $cache->delete(common_cache_key('fave:ids_by_user:'.$fave->user_id));
+                    $cache->delete(common_cache_key('fave:by_user_own:'.$fave->user_id));
                     if ($blowLast) {
                         $cache->delete(common_cache_key('fave:ids_by_user:'.$fave->user_id.';last'));
+                        $cache->delete(common_cache_key('fave:by_user_own:'.$fave->user_id.';last'));
                     }
                 }
             }
@@ -675,7 +704,10 @@ class Notice extends Memcached_DataObject
         if (!empty($cache)) {
             $notices = array();
             foreach ($ids as $id) {
-                $notices[] = Notice::staticGet('id', $id);
+                $n = Notice::staticGet('id', $id);
+                if (!empty($n)) {
+                    $notices[] = $n;
+                }
             }
             return new ArrayWrapper($notices);
         } else {
@@ -744,29 +776,116 @@ class Notice extends Memcached_DataObject
         return $ids;
     }
 
+    function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null)
+    {
+        $ids = Notice::stream(array('Notice', '_conversationStreamDirect'),
+                              array($id),
+                              'notice:conversation_ids:'.$id,
+                              $offset, $limit, $since_id, $max_id, $since);
+
+        return Notice::getStreamByIds($ids);
+    }
+
+    function _conversationStreamDirect($id, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null)
+    {
+        $notice = new Notice();
+
+        $notice->selectAdd(); // clears it
+        $notice->selectAdd('id');
+
+        $notice->whereAdd('conversation = '.$id);
+
+        $notice->orderBy('id DESC');
+
+        if (!is_null($offset)) {
+            $notice->limit($offset, $limit);
+        }
+
+        if ($since_id != 0) {
+            $notice->whereAdd('id > ' . $since_id);
+        }
+
+        if ($max_id != 0) {
+            $notice->whereAdd('id <= ' . $max_id);
+        }
+
+        if (!is_null($since)) {
+            $notice->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\'');
+        }
+
+        $ids = array();
+
+        if ($notice->find()) {
+            while ($notice->fetch()) {
+                $ids[] = $notice->id;
+            }
+        }
+
+        $notice->free();
+        $notice = NULL;
+
+        return $ids;
+    }
+
     function addToInboxes()
     {
         $enabled = common_config('inboxes', 'enabled');
 
         if ($enabled === true || $enabled === 'transitional') {
-            $inbox = new Notice_inbox();
-            $UT = common_config('db','type')=='pgsql'?'"user"':'user';
-            $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created) ' .
-              "SELECT $UT.id, " . $this->id . ", '" . $this->created . "' " .
-              "FROM $UT JOIN subscription ON $UT.id = subscription.subscriber " .
-              'WHERE subscription.subscribed = ' . $this->profile_id . ' ' .
-              'AND NOT EXISTS (SELECT user_id, notice_id ' .
-              'FROM notice_inbox ' .
-              "WHERE user_id = $UT.id " .
-              'AND notice_id = ' . $this->id . ' )';
-            if ($enabled === 'transitional') {
-                $qry .= " AND $UT.inboxed = 1";
+
+            $users = $this->getSubscribedUsers();
+
+            // FIXME: kind of ignoring 'transitional'...
+            // we'll probably stop supporting inboxless mode
+            // in 0.9.x
+
+            foreach ($users as $id) {
+                $this->addToUserInbox($id, NOTICE_INBOX_SOURCE_SUB);
             }
-            $inbox->query($qry);
         }
+
         return;
     }
 
+    function getSubscribedUsers()
+    {
+        $user = new User();
+
+        $qry =
+          'SELECT id ' .
+          'FROM user JOIN subscription '.
+          'ON user.id = subscription.subscriber ' .
+          'WHERE subscription.subscribed = %d ';
+
+        $user->query(sprintf($qry, $this->profile_id));
+
+        $ids = array();
+
+        while ($user->fetch()) {
+            $ids[] = $user->id;
+        }
+
+        $user->free();
+
+        return $ids;
+    }
+
+    function addToUserInbox($user_id, $source)
+    {
+        $inbox = Notice_inbox::pkeyGet(array('user_id' => $user_id,
+                                             'notice_id' => $this->id));
+        if (empty($inbox)) {
+            $inbox = new Notice_inbox();
+            $inbox->user_id   = $user_id;
+            $inbox->notice_id = $this->id;
+            $inbox->source    = $source;
+            $inbox->created   = $this->created;
+            return $inbox->insert();
+        }
+
+        return true;
+    }
+
     function saveGroups()
     {
         $enabled = common_config('inboxes', 'enabled');
@@ -805,13 +924,7 @@ class Notice extends Memcached_DataObject
 
             if ($profile->isMember($group)) {
 
-                $gi = new Group_inbox();
-
-                $gi->group_id  = $group->id;
-                $gi->notice_id = $this->id;
-                $gi->created   = common_sql_now();
-
-                $result = $gi->insert();
+                $result = $this->addToGroupInbox($group);
 
                 if (!$result) {
                     common_log_db_error($gi, 'INSERT', __FILE__);
@@ -819,27 +932,37 @@ class Notice extends Memcached_DataObject
 
                 // FIXME: do this in an offline daemon
 
-                $this->addToGroupInboxes($group);
+                $this->addToGroupMemberInboxes($group);
             }
         }
     }
 
-    function addToGroupInboxes($group)
+    function addToGroupInbox($group)
     {
-        $inbox = new Notice_inbox();
-        $UT = common_config('db','type')=='pgsql'?'"user"':'user';
-        $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created, source) ' .
-          "SELECT $UT.id, " . $this->id . ", '" . $this->created . "', " . NOTICE_INBOX_SOURCE_GROUP . " " .
-          "FROM $UT JOIN group_member ON $UT.id = group_member.profile_id " .
-          'WHERE group_member.group_id = ' . $group->id . ' ' .
-          'AND NOT EXISTS (SELECT user_id, notice_id ' .
-          'FROM notice_inbox ' .
-          "WHERE user_id = $UT.id " .
-          'AND notice_id = ' . $this->id . ' )';
-        if ($enabled === 'transitional') {
-            $qry .= " AND $UT.inboxed = 1";
-        }
-        $result = $inbox->query($qry);
+        $gi = Group_inbox::pkeyGet(array('group_id' => $group->id,
+                                         'notice_id' => $this->id));
+
+        if (empty($gi)) {
+
+            $gi = new Group_inbox();
+
+            $gi->group_id  = $group->id;
+            $gi->notice_id = $this->id;
+            $gi->created   = $this->created;
+
+            return $gi->insert();
+        }
+
+        return true;
+    }
+
+    function addToGroupMemberInboxes($group)
+    {
+        $users = $group->getUserMembers();
+
+        foreach ($users as $id) {
+            $this->addToUserInbox($id, NOTICE_INBOX_SOURCE_GROUP);
+        }
     }
 
     function saveReplies()
index 4ca2e9ae3c6705bc53c58ca8bd8826f19131d7e7..940381f84cd1e258ba0a8563ea79bae62c6b4b8a 100644 (file)
@@ -27,6 +27,7 @@ define('INBOX_CACHE_WINDOW', 101);
 
 define('NOTICE_INBOX_SOURCE_SUB', 1);
 define('NOTICE_INBOX_SOURCE_GROUP', 2);
+define('NOTICE_INBOX_SOURCE_REPLY', 3);
 define('NOTICE_INBOX_SOURCE_GATEWAY', -1);
 
 class Notice_inbox extends Memcached_DataObject
index 6b27c80cb5528e549126e4b84294f142f0c54cfb..a0ed6b3ca349e0da83dc161a409893f821cdb8af 100644 (file)
@@ -289,4 +289,52 @@ class Profile extends Memcached_DataObject
             return Avatar::defaultImage($size);
         }
     }
+
+    function getSubscriptions($offset=0, $limit=null)
+    {
+        $qry =
+          'SELECT profile.* ' .
+          'FROM profile JOIN subscription ' .
+          'ON profile.id = subscription.subscribed ' .
+          'WHERE subscription.subscriber = %d ' .
+          'AND subscription.subscribed != subscription.subscriber ' .
+          'ORDER BY subscription.created DESC ';
+
+        if (common_config('db','type') == 'pgsql') {
+            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+        } else {
+            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+        }
+
+        $profile = new Profile();
+
+        $profile->query(sprintf($qry, $this->id));
+
+        return $profile;
+    }
+
+    function getSubscribers($offset=0, $limit=null)
+    {
+        $qry =
+          'SELECT profile.* ' .
+          'FROM profile JOIN subscription ' .
+          'ON profile.id = subscription.subscriber ' .
+          'WHERE subscription.subscribed = %d ' .
+          'AND subscription.subscribed != subscription.subscriber ' .
+          'ORDER BY subscription.created DESC ';
+
+        if ($offset) {
+            if (common_config('db','type') == 'pgsql') {
+                $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+            } else {
+                $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+            }
+        }
+
+        $profile = new Profile();
+
+        $cnt = $profile->query(sprintf($qry, $this->id));
+
+        return $profile;
+    }
 }
index e8c8c5a75b48d1691cbb17cbf4eb8a3db3c7ae54..62a3f8a66e214835548ceec645e021587e54a1bd 100644 (file)
@@ -424,9 +424,9 @@ class User extends Memcached_DataObject
         }
     }
 
-    function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE)
+    function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE, $own=false)
     {
-        $ids = Fave::stream($this->id, $offset, $limit);
+        $ids = Fave::stream($this->id, $offset, $limit, $own);
         return Notice::getStreamByIds($ids);
     }
 
@@ -600,50 +600,16 @@ class User extends Memcached_DataObject
 
     function getSubscriptions($offset=0, $limit=null)
     {
-        $qry =
-          'SELECT profile.* ' .
-          'FROM profile JOIN subscription ' .
-          'ON profile.id = subscription.subscribed ' .
-          'WHERE subscription.subscriber = %d ' .
-          'AND subscription.subscribed != subscription.subscriber ' .
-          'ORDER BY subscription.created DESC ';
-
-        if (common_config('db','type') == 'pgsql') {
-            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-        } else {
-            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
-        }
-
-        $profile = new Profile();
-
-        $profile->query(sprintf($qry, $this->id));
-
-        return $profile;
+        $profile = $this->getProfile();
+        assert(!empty($profile));
+        return $profile->getSubscriptions($offset, $limit);
     }
 
     function getSubscribers($offset=0, $limit=null)
     {
-        $qry =
-          'SELECT profile.* ' .
-          'FROM profile JOIN subscription ' .
-          'ON profile.id = subscription.subscriber ' .
-          'WHERE subscription.subscribed = %d ' .
-          'AND subscription.subscribed != subscription.subscriber ' .
-          'ORDER BY subscription.created DESC ';
-
-        if ($offset) {
-            if (common_config('db','type') == 'pgsql') {
-                $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-            } else {
-                $qry .= ' LIMIT ' . $offset . ', ' . $limit;
-            }
-        }
-
-        $profile = new Profile();
-
-        $cnt = $profile->query(sprintf($qry, $this->id));
-
-        return $profile;
+        $profile = $this->getProfile();
+        assert(!empty($profile));
+        return $profile->getSubscribers($offset, $limit);
     }
 
     function getTaggedSubscribers($tag, $offset=0, $limit=null)
index 8a56b9e52b32e893cab4fd5f0c582abd2380330b..9b4b01ead7424f60ba7bae7db2df4152ee2ab335 100644 (file)
@@ -246,4 +246,28 @@ class User_group extends Memcached_DataObject
         return Design::staticGet('id', $this->design_id);
     }
 
+    function getUserMembers()
+    {
+        // XXX: cache this
+
+        $user = new User();
+
+        $qry =
+          'SELECT id ' .
+          'FROM user JOIN group_member '.
+          'ON user.id = group_member.profile_id ' .
+          'WHERE group_member.group_id = %d ';
+
+        $user->query(sprintf($qry, $this->id));
+
+        $ids = array();
+
+        while ($user->fetch()) {
+            $ids[] = $user->id;
+        }
+
+        $user->free();
+
+        return $ids;
+    }
 }
diff --git a/db/074to080.sql b/db/074to080.sql
new file mode 100644 (file)
index 0000000..ff08191
--- /dev/null
@@ -0,0 +1,109 @@
+alter table user
+     add column design_id integer comment 'id of a design' references design(id),
+     add column viewdesigns tinyint default 1 comment 'whether to view user-provided designs';
+
+alter table notice add column
+     conversation integer comment 'id of root notice in this conversation' references notice (id),
+     add index notice_conversation_idx (conversation);
+
+alter table foreign_user
+     modify column id bigint not null comment 'unique numeric key on foreign service';
+
+alter table foreign_link
+     modify column foreign_id bigint unsigned comment 'link to user on foreign service, if exists';
+
+alter table user_group
+      add column design_id integer comment 'id of a design' references design(id);
+
+create table file (
+    id integer primary key auto_increment,
+    url varchar(255) comment 'destination URL after following redirections',
+    mimetype varchar(50) comment 'mime type of resource',
+    size integer comment 'size of resource when available',
+    title varchar(255) comment 'title of resource when available',
+    date integer(11) comment 'date of resource according to http query',
+    protected integer(1) comment 'true when URL is private (needs login)',
+    filename varchar(255) comment 'if a local file, name of the file',
+    modified timestamp comment 'date this record was modified',
+
+    unique(url)
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
+
+create table file_oembed (
+    file_id integer primary key comment 'oEmbed for that URL/file' references file (id),
+    version varchar(20) comment 'oEmbed spec. version',
+    type varchar(20) comment 'oEmbed type: photo, video, link, rich',
+    provider varchar(50) comment 'name of this oEmbed provider',
+    provider_url varchar(255) comment 'URL of this oEmbed provider',
+    width integer comment 'width of oEmbed resource when available',
+    height integer comment 'height of oEmbed resource when available',
+    html text comment 'html representation of this oEmbed resource when applicable',
+    title varchar(255) comment 'title of oEmbed resource when available',
+    author_name varchar(50) comment 'author name for this oEmbed resource',
+    author_url varchar(255) comment 'author URL for this oEmbed resource',
+    url varchar(255) comment 'URL for this oEmbed resource when applicable (photo, link)',
+    modified timestamp comment 'date this record was modified'
+
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
+
+create table file_redirection (
+
+    url varchar(255) primary key comment 'short URL (or any other kind of redirect) for file (id)',
+    file_id integer comment 'short URL for what URL/file' references file (id),
+    redirections integer comment 'redirect count',
+    httpcode integer comment 'HTTP status code (20x, 30x, etc.)',
+    modified timestamp comment 'date this record was modified'
+
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+create table file_thumbnail (
+
+    file_id integer primary key comment 'thumbnail for what URL/file' references file (id),
+    url varchar(255) comment 'URL of thumbnail',
+    width integer comment 'width of thumbnail',
+    height integer comment 'height of thumbnail',
+    modified timestamp comment 'date this record was modified',
+
+    unique(url)
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+create table file_to_post (
+
+    file_id integer comment 'id of URL/file' references file (id),
+    post_id integer comment 'id of the notice it belongs to' references notice (id),
+    modified timestamp comment 'date this record was modified',
+
+    constraint primary key (file_id, post_id)
+
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+create table design (
+    id integer primary key auto_increment comment 'design ID',
+    backgroundcolor integer comment 'main background color',
+    contentcolor integer comment 'content area background color',
+    sidebarcolor integer comment 'sidebar background color',
+    textcolor integer comment 'text color',
+    linkcolor integer comment 'link color',
+    backgroundimage varchar(255) comment 'background image, if any',
+    disposition tinyint default 1 comment 'bit 1 = hide background image, bit 2 = display background image, bit 4 = tile background image'
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+create table group_block (
+   group_id integer not null comment 'group profile is blocked from' references user_group (id),
+   blocked integer not null comment 'profile that is blocked' references profile (id),
+   blocker integer not null comment 'user making the block' references user (id),
+   modified timestamp comment 'date of blocking',
+
+   constraint primary key (group_id, blocked)
+
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+create table group_alias (
+
+   alias varchar(64) primary key comment 'additional nickname for the group',
+   group_id integer not null comment 'group profile is blocked from' references user_group (id),
+   modified timestamp comment 'date alias was created',
+
+   index group_alias_group_id_idx (group_id)
+
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
index 95796d5cc60692ee55f4e22ff7b52bf15870cb17..3f8918de62d3b8bb9d5ebbadb79834162f8f6638 100644 (file)
@@ -277,7 +277,7 @@ create table foreign_service (
 ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
 
 create table foreign_user (
-     id int not null comment 'unique numeric key on foreign service',
+     id bigint not null comment 'unique numeric key on foreign service',
      service int not null comment 'foreign key to service' references foreign_service(id),
      uri varchar(255) not null unique key comment 'identifying URI',
      nickname varchar(255) comment 'nickname on foreign service',
index cb26e21961412e2cc59b41965762e3acb74965ed..cb6a0fe6032677522b9cb42f1d360932f17f1fd5 100644 (file)
--- a/index.php
+++ b/index.php
@@ -48,7 +48,14 @@ function handleError($error)
         $logmsg .= " : ". $error->getDebugInfo();
     }
     common_log(LOG_ERR, $logmsg);
-    if ($error instanceof DB_DataObject_Error) {
+    if(common_config('site', 'logdebug')) {
+        $bt = $error->getBacktrace();
+        foreach ($bt as $line) {
+            common_log(LOG_ERR, $line);
+        }
+    }
+    if ($error instanceof DB_DataObject_Error ||
+        $error instanceof DB_Error) {
         $msg = sprintf(_('The database for %s isn\'t responding correctly, '.
                          'so the site won\'t work properly. '.
                          'The site admins probably know about the problem, '.
index b54b492cce34ed52e6c7efed3dc29d027bd899ed..833b19adcb50ebd3c4715f0a69f5bb584124afed 100644 (file)
@@ -89,11 +89,10 @@ $(document).ready(function() {
         $('body').css({'background-image':'none'});
     });
     $('#design_background-image_on').focus(function() {
-        var bis = $('#design_background-image_onoff img')[0].src;
-        $('body').css({'background-image':'url('+bis+')'});
+        $('body').css({'background-image':'url('+$('#design_background-image_onoff img')[0].src+')'});
     });
 
     $('#design_background-image_repeat').click(function() {
         ($(this)[0].checked) ? $('body').css({'background-repeat':'repeat'}) : $('body').css({'background-repeat':'no-repeat'});
     });
-});
\ No newline at end of file
+});
index 65a77960a06d570a84f2d556a9f63828ab07ea40..e7c54b74accb245d8397105efe30cd3af19ecb67 100644 (file)
@@ -222,6 +222,7 @@ $(document).ready(function(){
                                                                                                        }
                                                                                                        $("#notice_data-text").val("");
                                                                                                $("#notice_data-attach").val("");
+                                                    $('#notice_data-attach_selected').remove();
                                                     counter();
                                                                                                }
                                                                                                $("#form_notice").removeClass("processing");
@@ -233,6 +234,7 @@ $(document).ready(function(){
        $("#form_notice").each(addAjaxHidden);
     NoticeReply();
     NoticeAttachments();
+    NoticeDataAttach();
 });
 
 function NoticeReply() {
@@ -280,13 +282,13 @@ function NoticeAttachments() {
         timeout : 0
     };
 
-    $('a.attachment').click(function() {
+    $('#content .notice a.attachment').click(function() {
         $().jOverlay({url: $('address .url')[0].href+'/attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
         return false;
     });
     
     var t;
-    $("body:not(#shownotice) a.thumbnail").hover(
+    $("body:not(#shownotice) #content .notice a.thumbnail").hover(
         function() {
             var anchor = $(this);
             $("a.thumbnail").children('img').hide();
@@ -310,3 +312,16 @@ function NoticeAttachments() {
         }
     );
 }
+
+function NoticeDataAttach() {
+    NDA = $('#notice_data-attach');
+    NDA.change(function() {
+        S = '<div id="notice_data-attach_selected" class="success"><code>'+$(this).val()+'</code> <button>&#215;</button></div>';
+        NDAS = $('#notice_data-attach_selected');
+        (NDAS.length > 0) ? NDAS.replaceWith(S) : $('#form_notice').append(S);
+        $('#notice_data-attach_selected button').click(function(){
+            $('#notice_data-attach_selected').remove();
+            NDA.val('');
+        });
+    });
+}
index a2446a886a73715193f9ea68f36fcc149733b312..f6a1b59d03d8521752aa58f9ade72c1ac82d428e 100644 (file)
@@ -82,7 +82,8 @@ class AttachmentList extends Widget
         $atts = new File;
         $att = $atts->getAttachments($this->notice->id);
         if (empty($att)) return 0;
-        $this->out->elementStart('dl', array('id' =>'attachments'));
+        $this->out->elementStart('dl', array('id' =>'attachments',
+                                             'class' => 'entry-content'));
         $this->out->element('dt', null, _('Attachments'));
         $this->out->elementStart('dd');
         $this->out->elementStart('ol', array('class' => 'attachments'));
@@ -249,10 +250,13 @@ class Attachment extends AttachmentListItem
         $this->out->elementStart('div', 'entry-title');
         $this->out->elementStart('a', $this->linkAttr());
         $this->out->element('span', null, $this->linkTitle());
-        $this->showRepresentation();
         $this->out->elementEnd('a');
         $this->out->elementEnd('div');
 
+        $this->out->elementStart('div', 'entry-content');
+        $this->showRepresentation();
+        $this->out->elementEnd('div');
+
         if (!empty($this->oembed->author_name) || !empty($this->oembed->provider)) {
             $this->out->elementStart('div', array('id' => 'oembed_info', 
                                                   'class' => 'entry-content'));
index 99d460e6c69849b879db8170b316cd1a170825c4..c9e5fb0c9c7c7ec3b0f1d652b8a5be797f874f98 100644 (file)
@@ -95,9 +95,9 @@ $config =
               'server' => $_server,
               'theme' => 'default',
               'design' =>
-              array('backgroundcolor' => '#F0F2F5',
+              array('backgroundcolor' => '#CEE1E9',
                     'contentcolor' => '#FFFFFF',
-                    'sidebarcolor' => '#CEE1E9',
+                    'sidebarcolor' => '#C8D1D5',
                     'textcolor' => '#000000',
                     'linkcolor' => '#002E6E',
                     'backgroundimage' => null,
@@ -125,7 +125,13 @@ $config =
         array('appname' => 'laconica', # for syslog
               'priority' => 'debug'), # XXX: currently ignored
         'queue' =>
-        array('enabled' => false),
+        array('enabled' => false,
+              'subsystem' => 'db', # default to database, or 'stomp'
+              'stomp_server' => null,
+              'queue_basename' => 'laconica',
+              'stomp_username' => null,
+              'stomp_password' => null,
+              ),
         'license' =>
         array('url' => 'http://creativecommons.org/licenses/by/3.0/',
               'title' => 'Creative Commons Attribution 3.0',
index 6aa6bb2f193cef4fe345e363f0b94e2e790ea24b..9650679ac5b620c51f356c1d57d07e3235abfbac 100644 (file)
@@ -132,13 +132,13 @@ class DesignSettingsAction extends AccountSettingsAction
                                           _('Off'));
             $this->element('p', 'form_guide', _('Turn background image on or off.'));
             $this->elementEnd('li');
-        }
 
-        $this->elementStart('li');
-        $this->checkbox('design_background-image_repeat',
-                        _('Tile background image'),
-                        ($design->disposition & BACKGROUND_TILE) ? true : false );
-        $this->elementEnd('li');
+            $this->elementStart('li');
+            $this->checkbox('design_background-image_repeat',
+                            _('Tile background image'),
+                            ($design->disposition & BACKGROUND_TILE) ? true : false );
+            $this->elementEnd('li');
+        }
 
         $this->elementEnd('ul');
         $this->elementEnd('fieldset');
@@ -388,7 +388,11 @@ class DesignSettingsAction extends AccountSettingsAction
 
             $original = clone($design);
             $design->backgroundimage = $filename;
+
+            // default to on, no tile
+
             $design->setDisposition(true, false, false);
+
             $result = $design->update($original);
 
             if ($result === false) {
index 0c93b257ed394d5433e6a2c8f147e18aad480587..52e4c4b2272d66e8a2b9e0de1612e0a73e7d308e 100644 (file)
@@ -72,7 +72,8 @@ class ImageFile
             break;
          case UPLOAD_ERR_INI_SIZE:
          case UPLOAD_ERR_FORM_SIZE:
-            throw new Exception(sprintf(_('That file is too big. The maximum file size is %d.'), $this->maxFileSize()));
+            throw new Exception(sprintf(_('That file is too big. The maximum file size is %d.'),
+                ImageFile::maxFileSize()));
             return;
          case UPLOAD_ERR_PARTIAL:
             @unlink($_FILES[$param]['tmp_name']);
index 6f05c63d66dd3454211ab9ac9a6df0060ac20688..44726a17b7b7a3da4116724bc0ed1d4c69b8d35b 100644 (file)
@@ -432,7 +432,7 @@ class NoticeListItem extends Widget
             $this->out->elementStart('dl', 'response');
             $this->out->element('dt', null, _('To'));
             $this->out->elementStart('dd');
-            $this->out->element('a', array('href' => $convurl),
+            $this->out->element('a', array('href' => $convurl.'#notice-'.$this->notice->id),
                                 _('in context'));
             $this->out->elementEnd('dd');
             $this->out->elementEnd('dl');
index d5e0150d9c9997ba334b8df6c00a15d141ea8daa..ae403c65e24f815f4f38b56b9ec081e760092074 100644 (file)
@@ -112,12 +112,21 @@ class QueueHandler extends Daemon
     }
 
     function stomp_dispatch() {
-        require("Stomp.php");
-        $con = new Stomp(common_config('queue','stomp_server'));
-        if (!$con->connect()) {
+
+        // use an external message queue system via STOMP
+        require_once("Stomp.php");
+
+        $server = common_config('queue','stomp_server');
+        $username = common_config('queue', 'stomp_username');
+        $password = common_config('queue', 'stomp_password');
+
+        $con = new Stomp($server);
+
+        if (!$con->connect($username, $password)) {
             $this->log(LOG_ERR, 'Failed to connect to queue server');
             return false;
         }
+
         $queue_basename = common_config('queue','queue_basename');
         // subscribe to the relevant queue (format: basename-transport)
         $con->subscribe('/queue/'.$queue_basename.'-'.$this->transport());
index 1af4625167eda081ad32a5b0c092dbd3e832a322..f6d50b18074be35f8729ae3410ed2f6fbe30c44b 100644 (file)
@@ -497,6 +497,22 @@ function common_linkify($url) {
 
     $attrs = array('href' => $longurl, 'rel' => 'external');
 
+    $is_attachment = false;
+    $attachment_id = null;
+    $has_thumb = false;
+
+    // Check to see whether there's a filename associated with this URL.
+    // If there is, it's an upload and qualifies as an attachment
+
+    $localfile = File::staticGet('url', $longurl);
+
+    if (!empty($localfile)) {
+        if (isset($localfile->filename)) {
+            $is_attachment = true;
+            $attachment_id = $localfile->id;
+        }
+    }
+
 // if this URL is an attachment, then we set class='attachment' and id='attahcment-ID'
 // where ID is the id of the attachment for the given URL.
 //
@@ -504,24 +520,35 @@ function common_linkify($url) {
 // we're currently picking up oembeds only.
 // I think the best option is another file_view table in the db
 // and associated dbobject.
+
     $query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'";
     $file = new File;
     $file->query($query);
     $file->fetch();
 
     if (!empty($file->file_id)) {
+        $is_attachment = true;
+        $attachment_id = $file->file_id;
+
         $query = "select file_thumbnail.file_id as file_id from file join file_thumbnail on file.id = file_thumbnail.file_id where file.url='$longurl'";
         $file2 = new File;
         $file2->query($query);
         $file2->fetch();
 
-        if (empty($file2->file_id)) {
-            $attrs['class'] = 'attachment';
-        } else {
+        if (!empty($file2)) {
+            $has_thumb = true;
+        }
+    }
+
+    // Add clippy
+    if ($is_attachment) {
+        $attrs['class'] = 'attachment';
+        if ($has_thumb) {
             $attrs['class'] = 'attachment thumbnail';
         }
-        $attrs['id'] = "attachment-{$file->file_id}";
+        $attrs['id'] = "attachment-{$attachment_id}";
     }
+
     return XMLStringer::estring('a', $attrs, $display);
 }
 
@@ -826,89 +853,91 @@ function common_broadcast_notice($notice, $remote=false)
 
 function common_enqueue_notice($notice)
 {
+    $transports = array('omb', 'sms', 'public', 'twitter', 'facebook', 'ping');
+
+    if (common_config('xmpp', 'enabled'))
+    {
+        $transports[] = 'jabber';
+    }
+
     if (common_config('queue','subsystem') == 'stomp') {
-       // use an external message queue system via STOMP
-       require_once("Stomp.php");
-       $con = new Stomp(common_config('queue','stomp_server'));
-       if (!$con->connect()) {
-               common_log(LOG_ERR, 'Failed to connect to queue server');
-               return false;
-       }
-       $queue_basename = common_config('queue','queue_basename');
-       foreach (array('jabber', 'omb', 'sms', 'public', 'twitter', 'facebook', 'ping') as $transport) {
-               if (!$con->send(
-                       '/queue/'.$queue_basename.'-'.$transport, // QUEUE
-                       $notice->id,            // BODY of the message
-                       array (                 // HEADERS of the msg
-                       'created' => $notice->created
-                       ))) {
-                       common_log(LOG_ERR, 'Error sending to '.$transport.' queue');
-                       return false;
-               }
-        common_log(LOG_DEBUG, 'complete remote queueing notice ID = ' . $notice->id . ' for ' . $transport);
-       }
-
-       //send tags as headers, so they can be used as JMS selectors
-        common_log(LOG_DEBUG, 'searching for tags ' . $notice->id);
-        $tags = array();
-       $tag = new Notice_tag();
-        $tag->notice_id = $notice->id;
-        if ($tag->find()) {
-            while ($tag->fetch()) {
-               common_log(LOG_DEBUG, 'tag found = ' . $tag->tag);
-               array_push($tags,$tag->tag);
-            }
-        }
-        $tag->free();
-
-       $con->send('/topic/laconica.'.$notice->profile_id,
-                       $notice->content,
-                       array(
-                               'profile_id' => $notice->profile_id,
-                               'created' => $notice->created,
-                               'tags' => implode($tags,' - ')
-                               )
-                       );
-        common_log(LOG_DEBUG, 'sent to personal topic ' . $notice->id);
-       $con->send('/topic/laconica.allusers',
-                       $notice->content,
-                       array(
-                               'profile_id' => $notice->profile_id,
-                               'created' => $notice->created,
-                               'tags' => implode($tags,' - ')
-                               )
-                       );
-        common_log(LOG_DEBUG, 'sent to catch-all topic ' . $notice->id);
-       $result = true;
+        common_enqueue_notice_stomp($notice, $transports);
     }
     else {
-       // in any other case, 'internal'
-       foreach (array('jabber', 'omb', 'sms', 'public', 'twitter', 'facebook', 'ping') as $transport) {
-               $qi = new Queue_item();
-               $qi->notice_id = $notice->id;
-               $qi->transport = $transport;
-               $qi->created = $notice->created;
-               $result = $qi->insert();
-               if (!$result) {
-                   $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
-                   common_log(LOG_ERR, 'DB error inserting queue item: ' . $last_error->message);
-                   return false;
-               }
-               common_log(LOG_DEBUG, 'complete queueing notice ID = ' . $notice->id . ' for ' . $transport);
-        }
+        common_enqueue_notice_db($notice, $transports);
     }
     return $result;
 }
 
-function common_post_inbox_transports()
+function common_enqueue_notice_stomp($notice, $transports)
 {
-    $transports = array('omb', 'sms');
+    // use an external message queue system via STOMP
+    require_once("Stomp.php");
+
+    $server = common_config('queue','stomp_server');
+    $username = common_config('queue', 'stomp_username');
+    $password = common_config('queue', 'stomp_password');
+
+    $con = new Stomp($server);
+
+    if (!$con->connect($username, $password)) {
+        common_log(LOG_ERR, 'Failed to connect to queue server');
+        return false;
+    }
+
+    $queue_basename = common_config('queue','queue_basename');
 
-    if (common_config('xmpp', 'enabled')) {
-        $transports = array_merge($transports, array('jabber', 'public'));
+    foreach ($transports as $transport) {
+        $result = $con->send('/queue/'.$queue_basename.'-'.$transport, // QUEUE
+                             $notice->id,              // BODY of the message
+                             array ('created' => $notice->created));
+        if (!$result) {
+            common_log(LOG_ERR, 'Error sending to '.$transport.' queue');
+            return false;
+        }
+        common_log(LOG_DEBUG, 'complete remote queueing notice ID = ' . $notice->id . ' for ' . $transport);
     }
 
-    return $transports;
+    //send tags as headers, so they can be used as JMS selectors
+    common_log(LOG_DEBUG, 'searching for tags ' . $notice->id);
+    $tags = array();
+    $tag = new Notice_tag();
+    $tag->notice_id = $notice->id;
+    if ($tag->find()) {
+        while ($tag->fetch()) {
+            common_log(LOG_DEBUG, 'tag found = ' . $tag->tag);
+            array_push($tags,$tag->tag);
+        }
+    }
+    $tag->free();
+
+    $con->send('/topic/laconica.'.$notice->profile_id,
+               $notice->content,
+               array(
+                     'profile_id' => $notice->profile_id,
+                     'created' => $notice->created,
+                     'tags' => implode($tags,' - ')
+                     )
+               );
+    common_log(LOG_DEBUG, 'sent to personal topic ' . $notice->id);
+    $con->send('/topic/laconica.allusers',
+               $notice->content,
+               array(
+                     'profile_id' => $notice->profile_id,
+                     'created' => $notice->created,
+                     'tags' => implode($tags,' - ')
+                     )
+               );
+    common_log(LOG_DEBUG, 'sent to catch-all topic ' . $notice->id);
+    $result = true;
+}
+
+function common_enqueue_notice_db($notice, $transports)
+{
+    // in any other case, 'internal'
+    foreach ($transports as $transport) {
+        common_enqueue_notice_transport($notice, $transport);
+    }
 }
 
 function common_enqueue_notice_transport($notice, $transport)
index a078cd9f7e13c90fd10e520caa7cb004c36588a8..986e09c25e4c353cb0d849b5a4736edfd6638cac 100644 (file)
@@ -22,7 +22,7 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/queuehandler.php');
 
 /**
- * Common superclass for all XMPP-using queue handlers. They all need to 
+ * Common superclass for all XMPP-using queue handlers. They all need to
  * service their message queues on idle, and forward any incoming messages
  * to the XMPP listener connection. So, we abstract out common code to a
  * superclass.
@@ -30,12 +30,11 @@ require_once(INSTALLDIR.'/lib/queuehandler.php');
 
 class XmppQueueHandler extends QueueHandler
 {
-    
     function start()
     {
         # Low priority; we don't want to receive messages
         $this->log(LOG_INFO, "INITIALIZE");
-        $this->conn = jabber_connect($this->_id);
+        $this->conn = jabber_connect($this->_id.$this->transport());
         if ($this->conn) {
             $this->conn->addEventHandler('message', 'forward_message', $this);
             $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
@@ -44,7 +43,7 @@ class XmppQueueHandler extends QueueHandler
         }
         return !is_null($this->conn);
     }
-    
+
     function handle_reconnect(&$pl)
     {
         $this->conn->processUntil('session_start');
@@ -63,7 +62,7 @@ class XmppQueueHandler extends QueueHandler
             die($e->getMessage());
         }
     }
-    
+
     function forward_message(&$pl)
     {
         if ($pl['type'] != 'chat') {
diff --git a/scripts/allsites.php b/scripts/allsites.php
new file mode 100755 (executable)
index 0000000..d6768c2
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+<?php
+/*
+ * Laconica - a distributed open-source microblogging tool
+ * Copyright (C) 2009, Control Yourself, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+# Abort if called from a web server
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+
+$helptext = <<<ENDOFHELP
+allsites.php - list all sites configured for multi-site use
+
+returns the nickname of each site configured for multi-site use
+
+ENDOFHELP;
+
+require_once INSTALLDIR.'/scripts/commandline.inc';
+
+$sn = new Status_network();
+
+if ($sn->find()) {
+    while ($sn->fetch()) {
+        print "$sn->nickname\n";
+    }
+}
\ No newline at end of file
diff --git a/scripts/delete_status_network.sh b/scripts/delete_status_network.sh
new file mode 100755 (executable)
index 0000000..3218738
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+source /etc/laconica/setup.cfg
+
+export nickname=$1
+
+export database=$nickname$DBBASE
+
+# Create the db
+
+mysqladmin -h $DBHOST -u $ADMIN --password=$ADMINPASS -f drop $database
+
+mysql -h $DBHOST -u $ADMIN --password=$ADMINPASS $SITEDB << ENDOFCOMMANDS
+
+delete from status_network where nickname = '$nickname';
+
+ENDOFCOMMANDS
+
+for top in $AVATARBASE $FILEBASE $BACKGROUNDBASE; do
+    rm -Rf $top/$nickname
+done
index 198ea8fb9ab36eaad343557dee0bb899272bd7f6..97c230784f73e5be9897bfc536583a6cdd97c900 100755 (executable)
@@ -38,9 +38,6 @@ if(common_config('xmpp','enabled')) {
     echo "xmppdaemon.php jabberqueuehandler.php publicqueuehandler.php ";
     echo "xmppconfirmhandler.php ";
 }
-if(common_config('memcached','enabled')) {
-    echo "memcachedqueuehandler.php ";
-}
 if(common_config('twitterbridge','enabled')) {
     echo "twitterstatusfetcher.php ";
 }
index a449932364d70bcf4585cf4a613911cfbc0d749e..5b581629d33fc79a58844ab236f46a73944e3263 100755 (executable)
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 
-$shortoptions = 'r::';
-$longoptions = array('resource::');
+$shortoptions = 'i::';
+$longoptions = array('id::');
 
 $helptext = <<<END_OF_JABBER_HELP
 Daemon script for pushing new notices to Jabber users.
 
-    -r --resource       Jabber Resource ID (default to config)
+    -i --id           Identity (default none)
 
 END_OF_JABBER_HELP;
 
@@ -63,16 +63,16 @@ if (common_config('xmpp','enabled')==false) {
     exit();
 }
 
-if (have_option('r')) {
-    $resource = get_option_value('r');
-} else if (have_option('--resource')) {
-    $resource = get_option_value('--resource');
+if (have_option('i')) {
+    $id = get_option_value('i');
+} else if (have_option('--id')) {
+    $id = get_option_value('--id');
 } else if (count($args) > 0) {
-    $resource = $args[0];
+    $id = $args[0];
 } else {
-    $resource = null;
+    $id = null;
 }
 
-$handler = new JabberQueueHandler($resource);
+$handler = new JabberQueueHandler($id);
 
 $handler->runOnce();
index 58ecc1745eb8d7b7a181f4fe5cc7b6a0440e6c56..701d50e0189f737ed36b41d4f90bcbcf2c23e5dc 100755 (executable)
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 
-$shortoptions = 'r::';
-$longoptions = array('resource::');
+$shortoptions = 'i::';
+$longoptions = array('id::');
 
 $helptext = <<<END_OF_PUBLIC_HELP
 Daemon script for pushing new notices to public XMPP subscribers.
 
-    -r --resource       Jabber Resource ID
+    -i --id           Identity (default none)
 
 END_OF_PUBLIC_HELP;
 
@@ -61,16 +61,16 @@ if (common_config('xmpp','enabled')==false) {
     exit();
 }
 
-if (have_option('r')) {
-    $resource = get_option_value('r');
-} else if (have_option('--resource')) {
-    $resource = get_option_value('--resource');
+if (have_option('i')) {
+    $id = get_option_value('i');
+} else if (have_option('--id')) {
+    $id = get_option_value('--id');
 } else if (count($args) > 0) {
-    $resource = $args[0];
+    $id = $args[0];
 } else {
-    $resource = null;
+    $id = null;
 }
 
-$handler = new PublicQueueHandler($resource);
+$handler = new PublicQueueHandler($id);
 
 $handler->runOnce();
index dd3c2705fc420ef84be940da0beacce694617b74..8d03b06f5e8db8c13e00f8ee888195cc32fe3fe6 100644 (file)
@@ -1,13 +1,14 @@
 # CONFIGURATION FILE for setup_status_network.sh
 
-# Base database name; full name will include nickname
-
-export DBHOST=masterdb.example.net
+export DBHOST=localhost
+export DBHOSTNAME=masterdb.example.net
 export DBBASE=_example_net
 export USERBASE=_example_net
 export ADMIN=root
 export ADMINPASS=yourpassword
 export SITEDB=example_net_site
 export AVATARBASE=/var/www/avatar.example.net
+export BACKGROUNDBASE=/var/www/background.example.net
+export FILEBASE=/var/www/file.example.net
 export PWDGEN="pwgen 20"
 
index 29ee010ed9784d050745907effee4de234e5c7ab..17440640e429d23e9af469ce6f8bd89b5b9bd6cc 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-source ./setup.cfg
+source /etc/laconica/setup.cfg
 
 export nickname=$1
 export sitename=$2
@@ -22,9 +22,11 @@ mysql -h $DBHOST -u $ADMIN --password=$ADMINPASS $SITEDB << ENDOFCOMMANDS
 GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'localhost' IDENTIFIED BY '$password';
 GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'%' IDENTIFIED BY '$password';
 INSERT INTO status_network (nickname, dbhost, dbuser, dbpass, dbname, sitename, created)
-VALUES ('$nickname', '$DBHOST', '$username', '$password', '$database', '$sitename', now());
+VALUES ('$nickname', '$DBHOSTNAME', '$username', '$password', '$database', '$sitename', now());
 
 ENDOFCOMMANDS
 
-mkdir $AVATARBASE/$nickname
-chmod a+w $AVATARBASE/$nickname
+for top in $AVATARBASE $FILEBASE $BACKGROUNDBASE; do
+    mkdir $top/$nickname
+    chmod a+w $top/$nickname
+done
index 053c4f8ee028575dd23cae44c045d676dc1c3794..9ead20acd6c0230f0b42af6a24f6cd670404c297 100755 (executable)
 # This program tries to start the daemons for Laconica.
 # Note that the 'maildaemon' needs to run as a mail filter.
 
+ARGSG=
+ARGSD=
+
+if [ $# -gt 0 ]; then
+    ARGSG="$ARGSG -s$1"
+    ID=`echo $1 | sed s/\\\\./_/g`
+    ARGSD="$ARGSD -s$1 -i$ID"
+fi
+
+if [ $# -gt 1 ]; then
+    ARGSD="$ARGSD -p$2"
+    ARGSG="$ARGSG -p$2"
+fi
+
 DIR=`dirname $0`
-DAEMONS=`php $DIR/getvaliddaemons.php`
+DAEMONS=`php $DIR/getvaliddaemons.php $ARGSG`
 
 for f in $DAEMONS; do
 
-         echo -n "Starting $f...";
-        php $DIR/$f
-        echo "DONE."
+         printf "Starting $f...";
+        php $DIR/$f $ARGSD
+        printf "DONE.\n"
+
 done
index 883934fd6c9dde66a7a93206b2066eefceabd5a8..d6821ddefae03affd7595396f14489f6a74f8571 100755 (executable)
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 
-$shortoptions = 'r::';
-$longoptions = array('resource::');
+$shortoptions = 'i::';
+$longoptions = array('id::');
 
 $helptext = <<<END_OF_JABBER_HELP
 Daemon script for pushing new confirmations to Jabber users.
 
-    -r --resource       Jabber Resource ID (default to config)
+    -i --id           Identity (default none)
 
 END_OF_JABBER_HELP;
 
@@ -147,17 +147,17 @@ if (common_config('xmpp','enabled')==false) {
     exit();
 }
 
-if (have_option('r')) {
-    $resource = get_option_value('r');
-} else if (have_option('--resource')) {
-    $resource = get_option_value('--resource');
+if (have_option('i')) {
+    $id = get_option_value('i');
+} else if (have_option('--id')) {
+    $id = get_option_value('--id');
 } else if (count($args) > 0) {
-    $resource = $args[0];
+    $id = $args[0];
 } else {
-    $resource = null;
+    $id = null;
 }
 
-$handler = new XmppConfirmHandler($resource);
+$handler = new XmppConfirmHandler($id);
 
 $handler->runOnce();
 
index 661631937f3839c2b9b9658aaebaf6e2be8c0729..3eecfec29a13725aa46684428b30dc1d301b3052 100755 (executable)
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 
-$shortoptions = 'r::';
-$longoptions = array('resource::');
+$shortoptions = 'i::';
+$longoptions = array('id::');
 
 $helptext = <<<END_OF_XMPP_HELP
 Daemon script for receiving new notices from Jabber users.
 
-    -r --resource       Jabber Resource ID (default to config)
+    -i --id           Identity (default none)
 
 END_OF_XMPP_HELP;
 
@@ -52,7 +52,7 @@ class XMPPDaemon extends Daemon
         }
 
         if ($resource) {
-            $this->resource = $resource;
+            $this->resource = $resource . 'daemon';
         } else {
             $this->resource = common_config('xmpp', 'resource') . 'daemon';
         }
@@ -323,16 +323,16 @@ if (common_config('xmpp','enabled')==false) {
     exit();
 }
 
-if (have_option('r')) {
-    $resource = get_option_value('r');
-} else if (have_option('--resource')) {
-    $resource = get_option_value('--resource');
+if (have_option('i')) {
+    $id = get_option_value('i');
+} else if (have_option('--id')) {
+    $id = get_option_value('--id');
 } else if (count($args) > 0) {
-    $resource = $args[0];
+    $id = $args[0];
 } else {
-    $resource = null;
+    $id = null;
 }
 
-$daemon = new XMPPDaemon($resource);
+$daemon = new XMPPDaemon($id);
 
 $daemon->runOnce();
index 8957a5b40142e071a0aa3a41dc6cb590fc8c6341..78fcd7ecefcca0187e3a620f6dcd6eb8c4cf4d91 100644 (file)
@@ -510,13 +510,26 @@ margin-bottom:7px;
 margin-left:18px;
 float:left;
 }
-#form_notice .error {
+#form_notice .error,
+#form_notice .success {
 float:left;
 clear:both;
-width:96.9%;
+width:81.5%;
 margin-bottom:0;
 line-height:1.618;
 }
+#form_notice #notice_data-attach_selected code {
+float:left;
+width:90%;
+display:block;
+font-size:1.1em;
+line-height:1.8;
+overflow:auto;
+}
+#form_notice #notice_data-attach_selected button {
+float:right;
+font-size:0.8em;
+}
 
 /* entity_profile */
 .entity_profile {
@@ -548,7 +561,8 @@ margin-bottom:18px;
 .entity_profile .entity_location,
 .entity_profile .entity_url,
 .entity_profile .entity_note,
-.entity_profile .entity_tags {
+.entity_profile .entity_tags,
+.entity_profile .entity_aliases {
 margin-left:113px;
 margin-bottom:4px;
 }
index da200388eb57d8c704005f86123c0e7aab5f8458..43fb01492abadf734c9576824031ce48be0ac97c 100644 (file)
@@ -19,6 +19,12 @@ display:block;
 width:17%;
 max-width:17%;
 }
+#form_notice #notice_data-attach_selected {
+width:78.5%;
+}
+#form_notice #notice_data-attach_selected button {
+padding:0 4px;
+}
 #anon_notice {
 max-width:39%;
 }
index 7e8b84b4cc231c6b62b5585b1695bdc3373573b5..89197bddb941dd39056e7bd352071f1233a56a33 100644 (file)
@@ -11,7 +11,7 @@
 
 body,
 a:active {
-background-color:#C3D6DF;
+background-color:#CEE1E9;
 }
 body {
 font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
@@ -29,7 +29,7 @@ input, textarea, select,
 border-color:#AAAAAA;
 }
 #filter_tags ul li {
-border-color:#C3D6DF;
+border-color:#DDDDDD;
 }
 
 .form_settings input.form_action-primary {
@@ -40,12 +40,12 @@ input.submit,
 #form_notice.warning #notice_text-count,
 .form_settings .form_note,
 .entity_remote_subscribe {
-background-color:#A9BF4F;
+background-color:#9BB43E;
 }
 
 input:focus, textarea:focus, select:focus,
 #form_notice.warning #notice_data-text {
-border-color:#A9BF4F;
+border-color:#9BB43E;
 box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
 -moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
 -webkit-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
@@ -71,14 +71,14 @@ color:#002E6E;
 
 .notice,
 .profile {
-border-top-color:#D1D9E4;
+border-top-color:#C8D1D5;
 }
 .section .profile {
-border-top-color:#C3D6DF;
+border-top-color:#87B4C8;
 }
 
 #aside_primary {
-background-color:#CEE1E9;
+background-color:#C8D1D5;
 }
 
 #notice_text-count {
@@ -136,13 +136,13 @@ background-color:#EFF3DC;
 }
 
 #anon_notice {
-background-color:#C3D6DF;
+background-color:#87B4C8;
 color:#FFFFFF;
 border-color:#FFFFFF;
 }
 
 #showstream #anon_notice {
-background-color:#A9BF4F;
+background-color:#9BB43E;
 }
 
 #export_data li a {
@@ -176,13 +176,13 @@ background-color:transparent;
 .form_group_leave input.submit
 .form_user_subscribe input.submit,
 .form_user_unsubscribe input.submit {
-background-color:#A9BF4F;
+background-color:#9BB43E;
 color:#FFFFFF;
 }
 .form_user_unsubscribe input.submit,
 .form_group_leave input.submit,
 .form_user_authorization input.reject {
-background-color:#C3D6DF;
+background-color:#87B4C8;
 }
 
 .entity_edit a {
@@ -245,7 +245,7 @@ div.notice-options input {
 font-family:sans-serif;
 }
 #content .notices li:hover {
-background-color:#FCFCFC;
+background-color:rgba(240, 240, 240, 0.2);
 }
 #conversation .notices li:hover {
 background-color:transparent;
@@ -272,7 +272,7 @@ background:transparent url(../../base/images/icons/twotone/green/news.gif) no-re
 .pagination .nav_prev a,
 .pagination .nav_next a {
 background-repeat:no-repeat;
-border-color:#D1D9E4;
+border-color:#C8D1D5;
 }
 .pagination .nav_prev a {
 background-image:url(../../base/images/icons/twotone/green/arrow-left.gif);
index 6501f4e48e9451d6ca5cac962a2a0fc6b4af6372..cbbd49ce6ca6a87a7d928834d158d764ad1a55af 100644 (file)
@@ -1,14 +1,14 @@
 /* IE specific styles */
 
 .notice-options input.submit {
-color:#fff;
+color:#FFFFFF;
 }
 #site_nav_local_views a {
-background-color:#ACCCDA;
+background-color:#C8D1D5;
 }
 #form_notice .form_note + label {
 background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
 }
 #form_notice #notice_data-attach {
 filter: alpha(opacity=0);
-}
\ No newline at end of file
+}
index 09ad4c9724a2f072dc540ce18cc6f686f6062f04..025debf34caf91049c7f2e6c597d2a5017af3c3c 100644 (file)
@@ -245,7 +245,7 @@ div.notice-options input {
 font-family:sans-serif;
 }
 #content .notices li:hover {
-background-color:#FCFCFC;
+background-color:rgba(240, 240, 240, 0.2);
 }
 #conversation .notices li:hover {
 background-color:transparent;
index 69db16aad080bb1a0dc37386e1f184a6ec68c32b..97cabc30a534a505d2b1ea92c6407aedd087493a 100644 (file)
@@ -1,14 +1,14 @@
 /* IE specific styles */
 
 .notice-options input.submit {
-color:#fff;
+color:#FFFFFF;
 }
 #site_nav_local_views a {
-background-color:#D0DFE7;
+background-color:#D9DADB;
 }
 #form_notice .form_note + label {
 background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
 }
 #form_notice #notice_data-attach {
 filter: alpha(opacity=0);
-}
\ No newline at end of file
+}