source: python/newsblur.py @ a852b2b

Last change on this file since a852b2b was 600e09c, checked in by Wilmer van der Gaast <wilmer@…>, at 2015-05-14T16:38:00Z

Rough split of NewsBlur plugin from implugin base. Includes some plumbing
for caching setting values inside the plugin.

  • Property mode set to 100755
File size: 2.6 KB
Line 
1#!/usr/bin/python
2
3import operator
4import re
5
6import requests
7
8import implugin
9
10class NewsBlurPlugin(implugin.BitlBeeIMPlugin):
11        NAME = "newsblur"
12        ACCOUNT_FLAGS = 0
13        SETTINGS = {
14                "backlog": {
15                        "default": 20,
16                        "type": "int",
17                },
18        }
19       
20        BASE_URL = "https://newsblur.com"
21       
22        def url(self, path):
23                return (self.BASE_URL + path)
24
25        def login(self, account):
26                super(NewsBlurPlugin, self).login(account)
27                self.ua = requests.Session()
28                creds = {"username": account["user"], "password": account["pass"]}
29                r = self.ua.post(self.url("/api/login"), creds)
30                self.bee.log("You're running BitlBee %d.%d.%d" % self.bitlbee_version)
31                if r.status_code != 200:
32                        self.bee.error("HTTP error %d" % r.status_code)
33                        self.bee.logout(True)
34                elif r.json()["errors"]:
35                        self.bee.error("Authentication error")
36                        self.bee.logout(False)
37                else:
38                        self.bee.add_buddy("rss", None)
39                        self.bee.connected()
40                        self.seen_hashes = set()
41                        self.keepalive()
42
43        def logout(self):
44                self.bee.log("Ok bye!")
45
46        def buddy_msg(self, handle, msg, flags):
47                feed = self.feeds[handle]
48                cmd = re.split(r"\s+", msg)
49       
50        def set_set_backlog(self, setting, value):
51                print "Setting %s changed to %r" % (setting, value)
52       
53        # BitlBee will call us here every minute which is actually a neat way
54        # to get periodic work (like RSS polling) scheduled. :-D
55        def keepalive(self):
56                r = self.ua.post(
57                        self.url("/reader/unread_story_hashes"),
58                        {"include_timestamps": True})
59                if r.status_code != 200:
60                        self.bee.error("HTTP error %d" % r.status_code)
61                        return
62
63                # Throw all unread-post hashes in a flat list and sort it by posting time.
64                feed_hashes = r.json()["unread_feed_story_hashes"]
65                all_hashes = []
66                for feed, hashes in feed_hashes.iteritems():
67                        all_hashes += [tuple(h) for h in hashes]
68                all_hashes.sort(key=operator.itemgetter(1))
69               
70                # Look at the most recent posts, grab the ones we haven't shown yet.
71                req_hashes = []
72                for hash, _ in all_hashes[-self.setting("backlog"):]:
73                        if hash not in self.seen_hashes:
74                                req_hashes.append(hash)
75               
76                if not req_hashes:
77                        return
78               
79                # Grab post details.
80                r = self.ua.post(self.url("/reader/river_stories"), {"h": req_hashes})
81                if r.status_code != 200:
82                        self.bee.error("HTTP error %d" % r.status_code)
83                        return
84               
85                # Response is not in the order we requested. :-( Make it a hash
86                # and reconstruct order from our request.
87                stories = {s["story_hash"]: s for s in r.json()["stories"]}
88                for s in (stories[hash] for hash in req_hashes):
89                        line = "%(story_title)s <%(story_permalink)s>" % s
90                        ts = int(s.get("story_timestamp", "0"))
91                        self.bee.buddy_msg("rss", line, 0, ts)
92                        self.seen_hashes.add(s["story_hash"])
93
94
95implugin.RunPlugin(NewsBlurPlugin, debug=True)
Note: See TracBrowser for help on using the repository browser.