Inoreader sync better item matching
authorJack Miller <millerjo@us.ibm.com>
Wed, 3 Jun 2015 17:31:53 +0000 (12:31 -0500)
committerJack Miller <millerjo@us.ibm.com>
Wed, 3 Jun 2015 17:40:55 +0000 (12:40 -0500)
- Cover the case where canto fetches an item first, it leaves the source
  feed (expires, whatever), and then later we get Inoreader data on it.
Canto should now properly synchronize all items it has, instead of just
the items that are present in the feed and Inoreader at the same time.

plugins/sync-inoreader.py

index 254b8ef..d3bb82c 100644 (file)
@@ -180,22 +180,27 @@ def sync_state_to(changes, attrs, add_only = False):
             if "user:" + tag not in changes[item_id]["canto-tags"]:
                 inoreader_remove_tag(attrs["inoreader_id"], tag)
 
-# Inoreader communicates with canto through this fetch thread plugin
+class CantoFeedInoReader(DaemonFeedPlugin):
+    def __init__(self, feed):
+        self.plugin_attrs = { "edit_inoreader_sync" : self.edit_inoreader_sync }
+        self.feed = feed
 
-# After we've grabbed the feed, and used feedparser on it, we run
-# fetch_inoreader_sync which will add inoreader information.
+    def _list_add(self, item, attr, new):
+        if attr not in item:
+            item[attr] = [ new ]
+        elif new not in item[attr]:
+            item[attr].append(new)
+
+    def add_utag(self, item, tags_to_add, tag):
+        self._list_add(item, "canto-tags", "user:" + tag)
+        tags_to_add.append((self.feed._cacheitem(item)["id"], "user:" + tag))
 
-class CantoFetchInoReader(DaemonFetchThreadPlugin):
-    def __init__(self, fetch_thread):
-        self.plugin_attrs = { "fetch_inoreader_sync" : self.fetch_inoreader_sync }
-        self.fetch_thread = fetch_thread
+    def add_state(self, item, state):
+        self._list_add(item, "canto-state", state)
 
-    def fetch_inoreader_sync(self, **kwargs):
+    def fetch_inoreader_data(self, feed, newcontent):
         # Grab these from the parent object
 
-        feed = kwargs["feed"]
-        newcontent = kwargs["newcontent"]
-
         stream_id = quote("feed/" + feed.URL, [])
 
         query = { "n" : 1000 }
@@ -217,45 +222,22 @@ class CantoFetchInoReader(DaemonFetchThreadPlugin):
             log.debug("EXCEPT: %s" % traceback.format_exc(e))
 
         for ino_entry in ino_entries:
-
             for canto_entry in newcontent["entries"]:
                 if ino_entry["canonical"][0]["href"] != canto_entry["link"]:
                     continue
 
                 canto_entry["inoreader_id"] = ino_entry["id"]
                 canto_entry["inoreader_categories"] = ino_entry["categories"]
-
-
-# Since we've included the Inoreader information, wait until we've done most of
-# feed.index to edit the internal state.
-
-# We do this separately because it's not until after feed.index() that we have
-# existing information (canto-state / canto-tags) included in the feedparser
-# data.
-
-class CantoFeedInoReader(DaemonFeedPlugin):
-    def __init__(self, feed):
-        self.plugin_attrs = { "edit_inoreader_sync" : self.edit_inoreader_sync }
-        self.feed = feed
-
-    def _list_add(self, item, attr, new):
-        if attr not in item:
-            item[attr] = [ new ]
-        elif new not in item[attr]:
-            item[attr].append(new)
-
-    def add_utag(self, item, tags_to_add, tag):
-        self._list_add(item, "canto-tags", "user:" + tag)
-        tags_to_add.append((self.feed._cacheitem(item)["id"], "user:" + tag))
-
-    def add_state(self, item, state):
-        self._list_add(item, "canto-state", state)
+                break
 
     def edit_inoreader_sync(self, **kwargs):
+        feed = kwargs["feed"]
         newcontent = kwargs["newcontent"]
         tags_to_add = kwargs["tags_to_add"]
         tags_to_remove = kwargs["tags_to_remove"]
 
+        self.fetch_inoreader_data(feed, newcontent)
+
         for entry in newcontent["entries"]:
             # If we didn't get an id for this item, skip it