]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
OStatus: save categories from the Atom entry as hashtags.
authorBrion Vibber <brion@pobox.com>
Thu, 25 Feb 2010 19:26:33 +0000 (11:26 -0800)
committerBrion Vibber <brion@pobox.com>
Thu, 25 Feb 2010 19:26:33 +0000 (11:26 -0800)
classes/Notice.php
lib/activity.php
lib/distribqueuehandler.php
plugins/OStatus/classes/Ostatus_profile.php

index e8d5c45cb2f2dae58887a9c10907300ae4306d20..46c5ebb37cfdde1d2b6caff0b51c03cbd1d8b55b 100644 (file)
@@ -121,6 +121,9 @@ class Notice extends Memcached_DataObject
         $result = parent::delete();
     }
 
+    /**
+     * Extract #hashtags from this notice's content and save them to the database.
+     */
     function saveTags()
     {
         /* extract all #hastags */
@@ -129,14 +132,22 @@ class Notice extends Memcached_DataObject
             return true;
         }
 
+        /* Add them to the database */
+        return $this->saveKnownTags($match[1]);
+    }
+
+    /**
+     * Record the given set of hash tags in the db for this notice.
+     * Given tag strings will be normalized and checked for dupes.
+     */
+    function saveKnownTags($hashtags)
+    {
         //turn each into their canonical tag
         //this is needed to remove dupes before saving e.g. #hash.tag = #hashtag
-        $hashtags = array();
-        for($i=0; $i<count($match[1]); $i++) {
-            $hashtags[] = common_canonical_tag($match[1][$i]);
+        for($i=0; $i<count($hashtags); $i++) {
+            $hashtags[$i] = common_canonical_tag($hashtags[$i]);
         }
 
-        /* Add them to the database */
         foreach(array_unique($hashtags) as $hashtag) {
             /* elide characters we don't want in the tag */
             $this->saveTag($hashtag);
@@ -145,6 +156,10 @@ class Notice extends Memcached_DataObject
         return true;
     }
 
+    /**
+     * Record a single hash tag as associated with this notice.
+     * Tag format and uniqueness must be validated by caller.
+     */
     function saveTag($hashtag)
     {
         $tag = new Notice_tag();
@@ -194,6 +209,8 @@ class Notice extends Memcached_DataObject
      *                              place of extracting @-replies from content.
      *              array 'groups' list of group IDs to deliver to, in place of
      *                              extracting ! tags from content
+     *              array 'tags' list of hashtag strings to save with the notice
+     *                           in place of extracting # tags from content
      * @fixme tag override
      *
      * @return Notice
@@ -343,6 +360,8 @@ class Notice extends Memcached_DataObject
 
         $notice->blowOnInsert();
 
+        // Save per-notice metadata...
+
         if (isset($replies)) {
             $notice->saveKnownReplies($replies);
         } else {
@@ -355,6 +374,16 @@ class Notice extends Memcached_DataObject
             $notice->saveGroups();
         }
 
+        if (isset($tags)) {
+            $notice->saveKnownTags($tags);
+        } else {
+            $notice->saveTags();
+        }
+
+        // @fixme pass in data for URLs too?
+        $notice->saveUrls();
+
+        // Prepare inbox delivery, may be queued to background.
         $notice->distribute();
 
         return $notice;
index 3de5f62c7caf4a4d95c88cbd6a6f47c94cb4efd5..e592aad6ffe3f73ae4137cb6f9d02335d420d090 100644 (file)
@@ -859,6 +859,7 @@ class Activity
     public $content; // HTML content of activity
     public $id;      // ID of the activity
     public $title;   // title of the activity
+    public $categories = array(); // list of AtomCategory objects
 
     /**
      * Turns a regular old Atom <entry> into a magical activity
@@ -947,6 +948,14 @@ class Activity
         $this->summary = ActivityUtils::childContent($entry, 'summary');
         $this->id      = ActivityUtils::childContent($entry, 'id');
         $this->content = ActivityUtils::getContent($entry);
+
+        $catEls = $entry->getElementsByTagNameNS(self::ATOM, 'category');
+        if ($catEls) {
+            for ($i = 0; $i < $catEls->length; $i++) {
+                $catEl = $catEls->item($i);
+                $this->categories[] = new AtomCategory($catEl);
+            }
+        }
     }
 
     /**
@@ -1011,6 +1020,10 @@ class Activity
             $xs->raw($this->target->asString('activity:target'));
         }
 
+        foreach ($this->categories as $cat) {
+            $xs->raw($cat->asString());
+        }
+
         $xs->elementEnd('entry');
 
         return $xs->getString();
@@ -1020,4 +1033,50 @@ class Activity
     {
         return ActivityUtils::child($element, $tag, $namespace);
     }
-}
\ No newline at end of file
+}
+
+class AtomCategory
+{
+    public $term;
+    public $scheme;
+    public $label;
+
+    function __construct($element=null)
+    {
+        if ($element && $element->attributes) {
+            $this->term = $this->extract($element, 'term');
+            $this->scheme = $this->extract($element, 'scheme');
+            $this->label = $this->extract($element, 'label');
+        }
+    }
+
+    protected function extract($element, $attrib)
+    {
+        $node = $element->attributes->getNamedItemNS(Activity::ATOM, $attrib);
+        if ($node) {
+            return trim($node->textContent);
+        }
+        $node = $element->attributes->getNamedItem($attrib);
+        if ($node) {
+            return trim($node->textContent);
+        }
+        return null;
+    }
+
+    function asString()
+    {
+        $attribs = array();
+        if ($this->term !== null) {
+            $attribs['term'] = $this->term;
+        }
+        if ($this->scheme !== null) {
+            $attribs['scheme'] = $this->scheme;
+        }
+        if ($this->label !== null) {
+            $attribs['label'] = $this->label;
+        }
+        $xs = new XMLStringer();
+        $xs->element('category', $attribs);
+        return $xs->asString();
+    }
+}
index dc183fb36a415f901ca22c219b22a8b1d17b09a7..d2be7a92c72488d846374bb27413f103490fd34d 100644 (file)
@@ -62,24 +62,12 @@ class DistribQueueHandler
     {
         // XXX: do we need to change this for remote users?
 
-        try {
-            $notice->saveTags();
-        } catch (Exception $e) {
-            $this->logit($notice, $e);
-        }
-
         try {
             $notice->addToInboxes();
         } catch (Exception $e) {
             $this->logit($notice, $e);
         }
 
-        try {
-            $notice->saveUrls();
-        } catch (Exception $e) {
-            $this->logit($notice, $e);
-        }
-
         try {
             Event::handle('EndNoticeSave', array($notice));
             // Enqueue for other handlers
index 300e38c05d530ed4ee3750e63a54d9ee7ae5e6be..d66939399a3c29115c8150a781f7995cb1572ffe 100644 (file)
@@ -638,7 +638,9 @@ class Ostatus_profile extends Memcached_DataObject
                         'uri' => $sourceUri,
                         'rendered' => $rendered,
                         'replies' => array(),
-                        'groups' => array());
+                        'groups' => array(),
+                        'tags' => array());
+
 
         // Check for optional attributes...
 
@@ -673,6 +675,16 @@ class Ostatus_profile extends Memcached_DataObject
             }
         }
 
+        // Atom categories <-> hashtags
+        foreach ($activity->categories as $cat) {
+            if ($cat->term) {
+                $term = common_canonical_tag($cat->term);
+                if ($term) {
+                    $options['tags'][] = $term;
+                }
+            }
+        }
+
         try {
             $saved = Notice::saveNew($oprofile->profile_id,
                                      $content,