source: python/implugin.py @ 2533d10

Last change on this file since 2533d10 was 2533d10, checked in by Wilmer van der Gaast <wilmer@…>, at 2015-05-06T20:58:51Z

Very limited test RSS plugin. I'll try NewsBlur instead.

  • Property mode set to 100755
File size: 3.9 KB
RevLine 
[f3af614]1#!/usr/bin/python
2
3import sys
4import bjsonrpc
5from bjsonrpc.handlers import BaseHandler
6
7import random
8import re
9import socket
10import time
11
[2533d10]12import feedparser
13
[f3af614]14# List of functions an IM plugin can export. This library will indicate to
15# BitlBee which functions are actually implemented so omitted features
16# will be disabled, but note that some/many functions are simply mandatory.
[2533d10]17# (Currently login/-out, buddy_msg, add/remove_buddy.)
[f3af614]18SUPPORTED_FUNCTIONS = [
19        'login', 'keepalive', 'logout', 'buddy_msg', 'set_away',
20        'send_typing', 'add_buddy', 'remove_buddy', 'add_permit',
21        'add_deny', 'rem_permit', 'rem_deny', 'get_info', 'chat_invite',
22        'chat_kick', 'chat_leave', 'chat_msg', 'chat_with', 'chat_join',
23        'chat_topic'
24]
25
26class RpcForwarder(object):
27        """Tiny object that forwards RPCs from local Python code to BitlBee
28        with a marginally nicer syntax. This layer could eventually be
29        used to add basic parameter checking though I don't think that should
30        be done here."""
31       
32        def __init__(self, methods, target):
33                for m in methods:
34                        # imc(b)_ prefix is not useful here, chop it.
35                        # (Maybe do this in BitlBee already as well.)
36                        newname = re.sub("^imcb?_", "", m)
37                        self.__setattr__(newname, target.__getattr__(m))
38
39class BitlBeeIMPlugin(BaseHandler):
[c5a7b8d]40        # Protocol name to be used in the BitlBee CLI, etc.
[f3af614]41        NAME = "rpc-test"
[c5a7b8d]42
43        # See account.h (TODO: Add constants.)
44        ACCOUNT_FLAGS = 3
45       
46        # Supported away states. If your protocol supports a specific set of
47        # away states, put them in a list in this variable.
[2533d10]48        AWAY_STATES = None
[f3af614]49       
50        # Filled in during initialisation:
51        # Version code in hex. So if you need to do comparisions, for example
52        # check "self.bitlbee_version >= 0x030202" for versions 3.2.2+
53        bitlbee_version = None
54        # Full version string
55        bitlbee_version_str = None
[c5a7b8d]56        # Will become an RpcForwarder object to call into BitlBee
57        bee = None
[f3af614]58       
59        @classmethod
60        def _factory(cls, *args, **kwargs):
61                def handler_factory(connection):
62                        handler = cls(connection, *args, **kwargs)
63                        return handler
64                return handler_factory
65       
66        #def __init__(self, connection, *args, **kwargs):
67        #       BaseHandler.__init__(self,connection)
68
69        def init(self, bee):
70                self.bee = RpcForwarder(bee["method_list"], self._conn.call)
71                self.bitlbee_version = bee["version"]
72                self.bitlbee_version_str = bee["version_str"]
[2533d10]73
74                self.feeds = {}
75
[f3af614]76                # TODO: See how to call into the module here.
77                return {
78                        "name": self.NAME,
79                        "method_list": list(set(dir(self)) & set(SUPPORTED_FUNCTIONS)),
[c5a7b8d]80                        "account_flags": self.ACCOUNT_FLAGS,
81                        "away_state_list": self.AWAY_STATES,
[f3af614]82                        "settings": {
83                                "oauth": {
84                                        "default": "off",
[f15553d]85                                        "type": "bool",
[f3af614]86                                },
87                                "test": {
88                                        "default": "123",
[f15553d]89                                        "type": "int",
[f3af614]90                                },
[f15553d]91                                "stringetje": {
92                                        "default": "testje",
93                                        "flags": 0x04,
94                                }
[f3af614]95                        },
96                }
97       
98        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]
104
105        def logout(self):
106                self.bee.error("Ok bye!")
107
108        def add_buddy(self, handle, group):
[2533d10]109                self.bee.add_buddy(handle, None)
110                self.feeds[handle] = {
111                        "url": handle,
112                        "seen": set(),
113                }
[c5a7b8d]114       
[2533d10]115        def buddy_msg(self, handle, msg, flags):
116                feed = self.feeds[handle]
117                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)
[f15553d]127       
128        def set_set(self, setting, value):
129                print "Setting %s changed to %r" % (setting, value)
[f3af614]130
131def RunPlugin(plugin, debug=True):
132        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
133        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
134        sock.bind("/tmp/rpcplugins/test2")
135        sock.listen(3)
136       
137        srv = bjsonrpc.server.Server(sock, plugin._factory())
138       
139        srv.debug_socket(debug)
140        srv.serve()
141
142RunPlugin(BitlBeeIMPlugin)
Note: See TracBrowser for help on using the repository browser.