]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
accept bookmarks over PuSH
authorEvan Prodromou <evan@status.net>
Thu, 23 Dec 2010 17:42:42 +0000 (09:42 -0800)
committerEvan Prodromou <evan@status.net>
Thu, 23 Dec 2010 17:42:42 +0000 (09:42 -0800)
plugins/Bookmark/BookmarkPlugin.php
plugins/Bookmark/Notice_bookmark.php
plugins/OStatus/classes/Ostatus_profile.php

index 080daac59b46ae8fa088e58beacd9c82b69e1f7b..e18ea25eaa100db123ea74d1024ec6799dc5b8ed 100644 (file)
@@ -276,11 +276,17 @@ class BookmarkPlugin extends Plugin
      
     function onStartActivityObjectFromNotice($notice, &$object)
     {
+        common_log(LOG_INFO,
+                   "Checking {$notice->uri} to see if it's a bookmark.");
+
         $nb = Notice_bookmark::staticGet('notice_id',
                                          $notice->id);
                                          
         if (!empty($nb)) {
 
+            common_log(LOG_INFO,
+                       "Formatting notice {$notice->uri} as a bookmark.");
+
             $object->id      = $notice->uri;
             $object->type    = ActivityObject::BOOKMARK;
             $object->title   = $nb->title;
@@ -387,5 +393,104 @@ class BookmarkPlugin extends Plugin
 
         return true;
     }
+
+    /**
+     * Handle a posted bookmark from PuSH
+     *
+     * @param Activity        $activity activity to handle
+     * @param Ostatus_profile $oprofile Profile for the feed
+     *
+     * @return boolean hook value
+     */
+
+    function onStartHandleFeedEntryWithProfile($activity, $oprofile) {
+
+        common_log(LOG_INFO, "BookmarkPlugin called for new feed entry.");
+
+        if ($activity->verb == ActivityVerb::POST &&
+            $activity->objects[0]->type == ActivityObject::BOOKMARK) {
+
+            common_log(LOG_INFO, "Importing activity {$activity->id} as a bookmark.");
+
+            $author = $oprofile->checkAuthorship($activity);
+
+            if (empty($author)) {
+                throw new ClientException(_('Can\'t get author for activity.'));
+            }
+
+            self::_postRemoteBookmark($author,
+                                      $activity);
+
+            return false;
+        }
+
+        return true;
+    }
+
+    static private function _postRemoteBookmark(Ostatus_profile $author, Activity $activity)
+    {
+        $bookmark = $activity->objects[0];
+
+        $relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related');
+
+        if (count($relLinkEls) < 1) {
+            throw new ClientException(_('Expected exactly 1 link rel=related in a Bookmark.'));
+        }
+
+        if (count($relLinkEls) > 1) {
+            common_log(LOG_WARNING, "Got too many link rel=related in a Bookmark.");
+        }
+
+        $linkEl = $relLinkEls[0];
+
+        $url = $linkEl->getAttribute('href');
+
+        $tags = array();
+
+        foreach ($activity->categories as $category) {
+            $tags[] = common_canonical_tag($category->term);
+        }
+
+        $options = array('uri' => $bookmark->id,
+                         'url' => $bookmark->link,
+                         'created' => common_sql_time($activity->time),
+                         'is_local' => Notice::REMOTE_OMB,
+                         'source' => 'ostatus');
+
+        // Fill in location if available
+
+        $location = $activity->context->location;
+
+        if ($location) {
+            $options['lat'] = $location->lat;
+            $options['lon'] = $location->lon;
+            if ($location->location_id) {
+                $options['location_ns'] = $location->location_ns;
+                $options['location_id'] = $location->location_id;
+            }
+        }
+
+        $replies = $activity->context->attention;
+        $options['groups'] = $author->filterReplies($author, $replies);
+        $options['replies'] = $replies;
+
+        // Maintain direct reply associations
+        // @fixme what about conversation ID?
+
+        if (!empty($activity->context->replyToID)) {
+            $orig = Notice::staticGet('uri',
+                                      $activity->context->replyToID);
+            if (!empty($orig)) {
+                $options['reply_to'] = $orig->id;
+            }
+        }
+
+        Notice_bookmark::saveNew($author->localProfile(),
+                                 $bookmark->title,
+                                 $url,
+                                 $tags,
+                                 $bookmark->summary,
+                                 $options);
+    }
 }
 
index 38e2890abe5a1ef7c4bacdd2ca87f007d4cb0e37..3a7d0ed74283c09e5cc45c8db5cc519dacecb526 100644 (file)
@@ -238,7 +238,8 @@ class Notice_bookmark extends Memcached_DataObject
 
         $saved = Notice::saveNew($profile->id,
                                  $content,
-                                 'web',
+                                 array_key_exists('source', $options) ?
+                                 $options['source'] : 'web',
                                  $options);
 
         if (!empty($saved)) {
index 77cf57a6708b4b951a5808bbb7fcf49bdf981abd..9c0f014fc6464cea41cb2c2bbc09c4b1fea73531 100644 (file)
@@ -457,7 +457,8 @@ class Ostatus_profile extends Memcached_DataObject
     {
         $activity = new Activity($entry, $feed);
 
-        if (Event::handle('StartHandleFeedEntry', array($activity))) {
+        if (Event::handle('StartHandleFeedEntryWithProfile', array($activity, $this)) &&
+            Event::handle('StartHandleFeedEntry', array($activity))) {
 
             // @todo process all activity objects
             switch ($activity->objects[0]->type) {
@@ -479,6 +480,7 @@ class Ostatus_profile extends Memcached_DataObject
             }
 
             Event::handle('EndHandleFeedEntry', array($activity));
+            Event::handle('EndHandleFeedEntryWithProfile', array($activity, $this));
         }
     }
 
@@ -491,36 +493,10 @@ class Ostatus_profile extends Memcached_DataObject
      */
     public function processPost($activity, $method)
     {
-        if ($this->isGroup()) {
-            // A group feed will contain posts from multiple authors.
-            // @fixme validate these profiles in some way!
-            $oprofile = self::ensureActorProfile($activity);
-            if ($oprofile->isGroup()) {
-                // Groups can't post notices in StatusNet.
-                common_log(LOG_WARNING, "OStatus: skipping post with group listed as author: $oprofile->uri in feed from $this->uri");
-                return false;
-            }
-        } else {
-            $actor = $activity->actor;
+        $oprofile = $this->checkAuthorship($activity);
 
-            if (empty($actor)) {
-                // OK here! assume the default
-            } else if ($actor->id == $this->uri || $actor->link == $this->uri) {
-                $this->updateFromActivityObject($actor);
-            } else if ($actor->id) {
-                // We have an ActivityStreams actor with an explicit ID that doesn't match the feed owner.
-                // This isn't what we expect from mainline OStatus person feeds!
-                // Group feeds go down another path, with different validation...
-                // Most likely this is a plain ol' blog feed of some kind which
-                // doesn't match our expectations. We'll take the entry, but ignore
-                // the <author> info.
-                common_log(LOG_WARNING, "Got an actor '{$actor->title}' ({$actor->id}) on single-user feed for {$this->uri}");
-            } else {
-                // Plain <author> without ActivityStreams actor info.
-                // We'll just ignore this info for now and save the update under the feed's identity.
-            }
-
-            $oprofile = $this;
+        if (empty($oprofile)) {
+            return false;
         }
 
         // It's not always an ActivityObject::NOTE, but... let's just say it is.
@@ -1810,6 +1786,45 @@ class Ostatus_profile extends Memcached_DataObject
         }
         return $oprofile;
     }
+
+    function checkAuthorship($activity)
+    {
+        if ($this->isGroup()) {
+            // A group feed will contain posts from multiple authors.
+            // @fixme validate these profiles in some way!
+            $oprofile = self::ensureActorProfile($activity);
+            if ($oprofile->isGroup()) {
+                // Groups can't post notices in StatusNet.
+                common_log(LOG_WARNING, 
+                           "OStatus: skipping post with group listed as author: ".
+                           "$oprofile->uri in feed from $this->uri");
+                return false;
+            }
+        } else {
+            $actor = $activity->actor;
+
+            if (empty($actor)) {
+                // OK here! assume the default
+            } else if ($actor->id == $this->uri || $actor->link == $this->uri) {
+                $this->updateFromActivityObject($actor);
+            } else if ($actor->id) {
+                // We have an ActivityStreams actor with an explicit ID that doesn't match the feed owner.
+                // This isn't what we expect from mainline OStatus person feeds!
+                // Group feeds go down another path, with different validation...
+                // Most likely this is a plain ol' blog feed of some kind which
+                // doesn't match our expectations. We'll take the entry, but ignore
+                // the <author> info.
+                common_log(LOG_WARNING, "Got an actor '{$actor->title}' ({$actor->id}) on single-user feed for {$this->uri}");
+            } else {
+                // Plain <author> without ActivityStreams actor info.
+                // We'll just ignore this info for now and save the update under the feed's identity.
+            }
+
+            $oprofile = $this;
+        }
+
+        return $oprofile;
+    }
 }
 
 /**