Changeset e9face7


Ignore:
Timestamp:
2015-05-07T09:56:01Z (9 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Children:
f8feb8a
Parents:
2533d10
Message:

Example plugin is now a very simple NewsBlur client.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • protocols/rpc/rpc.c

    r2533d10 re9face7  
    133133        JSON_Object *o = json_object(v);
    134134        json_object_set_string(o, "user", acc->user);
    135         json_object_set_string(o, "pass", acc->user);
     135        json_object_set_string(o, "pass", acc->pass);
    136136        if (acc->server)
    137137                json_object_set_string(o, "server", acc->server);
  • python/implugin.py

    r2533d10 re9face7  
    55from bjsonrpc.handlers import BaseHandler
    66
     7import operator
    78import random
    89import re
     
    1011import time
    1112
    12 import feedparser
     13import requests
    1314
    1415# List of functions an IM plugin can export. This library will indicate to
     
    4243
    4344        # See account.h (TODO: Add constants.)
    44         ACCOUNT_FLAGS = 3
     45        ACCOUNT_FLAGS = 0
    4546       
    4647        # Supported away states. If your protocol supports a specific set of
     
    5758        bee = None
    5859       
     60        BASE_URL = "https://newsblur.com"
     61       
    5962        @classmethod
    6063        def _factory(cls, *args, **kwargs):
     
    6770        #       BaseHandler.__init__(self,connection)
    6871
     72        def url(self, path):
     73                return (self.BASE_URL + path)
     74
    6975        def init(self, bee):
    7076                self.bee = RpcForwarder(bee["method_list"], self._conn.call)
    7177                self.bitlbee_version = bee["version"]
    7278                self.bitlbee_version_str = bee["version_str"]
    73 
    74                 self.feeds = {}
    7579
    7680                # TODO: See how to call into the module here.
     
    97101       
    98102        def login(self, account):
    99                 print "Logging in with username %s and password %s" % (account['user'], account['pass'])
    100                 self.bee.log("Blaataap %r" % account)
    101                 self.bee.error("HALP!")
    102                 self.bee.connected()
    103                 return [{1:2,3:4}, {"a":"A", "b":"B"}, 1, 2, True]
     103                self.ua = requests.Session()
     104                creds = {"username": account["user"], "password": account["pass"]}
     105                r = self.ua.post(self.url("/api/login"), creds)
     106                if r.status_code != 200:
     107                        self.bee.error("HTTP error %d" % r.status_code)
     108                        self.bee.logout(True)
     109                elif r.json()["errors"]:
     110                        self.bee.error("Authentication error")
     111                        self.bee.logout(False)
     112                else:
     113                        self.bee.add_buddy("rss", None)
     114                        self.bee.connected()
     115                        self.seen_hashes = set()
     116                        self.keepalive()
    104117
    105118        def logout(self):
     
    107120
    108121        def add_buddy(self, handle, group):
    109                 self.bee.add_buddy(handle, None)
    110                 self.feeds[handle] = {
    111                         "url": handle,
    112                         "seen": set(),
    113                 }
     122                return False
     123       
     124        def remove_buddy(self, handle, group):
     125                return False
    114126       
    115127        def buddy_msg(self, handle, msg, flags):
    116128                feed = self.feeds[handle]
    117129                cmd = re.split(r"\s+", msg)
    118                 if cmd[0] == "list":
    119                         fp = feedparser.parse(handle)
    120                         for art in fp.entries:
    121                                 line = "%(title)s <%(link)s>" % art
    122                                 ts = 0
    123                                 if "updated_parsed" in art:
    124                                         ts = int(time.mktime(art.updated_parsed))
    125                                 self.bee.buddy_msg(handle, line, 0, ts)
    126                                 feed["seen"].add(art.id)
    127130       
    128131        def set_set(self, setting, value):
    129132                print "Setting %s changed to %r" % (setting, value)
     133       
     134        # BitlBee will call us here every minute which is actually a neat way
     135        # to get periodic work (like RSS polling) scheduled. :-D
     136        def keepalive(self):
     137                r = self.ua.post(
     138                        self.url("/reader/unread_story_hashes"),
     139                        {"include_timestamps": True})
     140                if r.status_code != 200:
     141                        self.bee.error("HTTP error %d" % r.status_code)
     142                        return
     143
     144                # Throw all unread-post hashes in a long list and sort it by posting time.
     145                #feed_hashes = r.json()["unread_feed_story_hashes"]
     146                wtf = r.json()
     147                feed_hashes = wtf["unread_feed_story_hashes"]
     148                all_hashes = []
     149                for feed, hashes in feed_hashes.iteritems():
     150                        all_hashes += [tuple(h) for h in hashes]
     151                all_hashes.sort(key=operator.itemgetter(1))
     152               
     153                # Look at the most recent 20, grab the ones we haven't shown yet.
     154                req_hashes = []
     155                for hash, _ in all_hashes[-20:]:
     156                        if hash not in self.seen_hashes:
     157                                req_hashes.append(hash)
     158               
     159                if not req_hashes:
     160                        return
     161                print req_hashes
     162               
     163                # Grab post details.
     164                r = self.ua.post(self.url("/reader/river_stories"), {"h": req_hashes})
     165                if r.status_code != 200:
     166                        self.bee.error("HTTP error %d" % r.status_code)
     167                        return
     168               
     169                # Response is not in the order we requested. :-(
     170                wtf = r.json()
     171                stories = {}
     172                for s in wtf["stories"]:
     173                        stories[s["story_hash"]] = s
     174               
     175                for s in (stories[hash] for hash in req_hashes):
     176                        line = "%(story_title)s <%(story_permalink)s>" % s
     177                        ts = int(s.get("story_timestamp", "0"))
     178                        self.bee.buddy_msg("rss", line, 0, ts)
     179                        self.seen_hashes.add(s["story_hash"])
     180                        print s["story_hash"]
     181
    130182
    131183def RunPlugin(plugin, debug=True):
Note: See TracChangeset for help on using the changeset viewer.