27
|
1 from twisted.application import service |
|
2 from twisted.internet import defer |
|
3 from twisted.protocols.jabber import jid |
|
4 import backend |
|
5 |
|
6 class Subscription: |
|
7 def __init__(self, state): |
|
8 self.state = state |
|
9 |
|
10 class NodeConfiguration: |
|
11 def __init__(self): |
|
12 self.persist_items = False |
|
13 self.deliver_payloads = False |
|
14 |
|
15 class Node: |
|
16 def __init__(self, id): |
|
17 self.id = id |
|
18 self.configuration = NodeConfiguration() |
|
19 self.subscriptions = {} |
|
20 self.affiliations = {} |
|
21 self.items = {} |
|
22 |
|
23 class MemoryBackendService(service.Service): |
|
24 |
|
25 __implements__ = backend.IService, |
|
26 |
|
27 def __init__(self): |
|
28 self.nodes = {} |
|
29 |
|
30 node = Node("ralphm/mood/ralphm@ik.nu") |
|
31 node.subscriptions["ralphm@doe.ik.nu"] = Subscription("subscribed") |
|
32 node.subscriptions["notify@ik.nu/mood_monitor"] = Subscription("subscribed") |
|
33 node.affiliations["ralphm@ik.nu"] = "owner" |
|
34 node.affiliations["ralphm@doe.ik.nu"] = "publisher" |
|
35 node.configuration.persist_items = True |
|
36 node.configuration.deliver_payloads = True |
|
37 self.nodes[node.id] = node |
|
38 |
|
39 def do_publish(self, node_id, publisher, items): |
|
40 try: |
|
41 node = self.nodes[node_id] |
|
42 persist_items = node.configuration.persist_items |
|
43 deliver_payloads = node.configuration.deliver_payloads |
|
44 except KeyError: |
|
45 raise backend.NodeNotFound |
|
46 |
|
47 try: |
|
48 if node.affiliations[publisher] not in ['owner', 'publisher']: |
|
49 raise backend.NotAuthorized |
|
50 except KeyError: |
|
51 raise backend.NotAuthorized |
|
52 |
|
53 if items and not persist_items and not deliver_payloads: |
|
54 raise backend.NoPayloadAllowed |
|
55 elif not items and (persist_items or deliver_payloads): |
|
56 raise backend.PayloadExpected |
|
57 |
|
58 print "publish by %s to %s" % (publisher, node_id) |
|
59 |
|
60 if persist_items or deliver_payloads: |
|
61 for item in items: |
|
62 if item["id"] is None: |
|
63 item["id"] = 'random' # FIXME |
|
64 |
|
65 if persist_items: |
|
66 self.storeItems(node_id, publisher, items) |
|
67 |
|
68 if items and not deliver_payloads: |
|
69 for item in items: |
|
70 item.children = [] |
|
71 |
|
72 recipients = self.get_subscribers(node_id) |
|
73 recipients.addCallback(self.magic_filter, node_id, items) |
|
74 recipients.addCallback(self.pubsub_service.do_notification, node_id) |
|
75 |
|
76 return defer.succeed(None) |
|
77 |
|
78 def do_subscribe(self, node_id, subscriber, requestor): |
|
79 # expect subscriber and requestor to be a jid.JID |
|
80 try: |
|
81 node = self.nodes[node_id] |
|
82 except KeyError: |
|
83 raise backend.NodeNotFound |
|
84 |
|
85 affiliation = node.affiliations.get(requestor.full(), 'none') |
|
86 |
|
87 if affiliation == 'banned': |
|
88 raise backend.NotAuthorized |
|
89 |
|
90 print subscriber.full() |
|
91 print subscriber.userhostJID().full() |
|
92 print requestor.full() |
|
93 |
|
94 if subscriber.userhostJID() != requestor: |
|
95 raise backend.NotAuthorized |
|
96 |
|
97 try: |
|
98 subscription = node.subscriptions[subscriber.full()] |
|
99 except KeyError: |
|
100 subscription = Subscription('subscribed') |
|
101 node.subscriptions[subscriber.full()] = subscription |
|
102 |
|
103 print node.subscriptions |
|
104 |
|
105 return defer.succeed({ |
|
106 'affiliation': affiliation, |
|
107 'node': node_id, |
|
108 'jid': subscriber, |
|
109 'subscription': subscription.state}) |
|
110 |
|
111 def magic_filter(self, subscribers, node_id, items): |
|
112 list = {} |
|
113 for subscriber in subscribers: |
|
114 list[subscriber] = items |
|
115 |
|
116 return list |
|
117 |
|
118 def get_subscribers(self, node_id): |
|
119 d = defer.Deferred() |
|
120 try: |
|
121 return defer.succeed(self.nodes[node_id].subscriptions.keys()) |
|
122 except: |
|
123 return defer.fail() |
|
124 |
|
125 def storeItems(self, node_id, publisher, items): |
|
126 for item in items: |
|
127 self.nodes[node_id].items[item["id"]] = item |
|
128 |
|
129 print self.nodes[node_id].items |
|
130 |
|
131 def create_node(self, node_id, owner): |
|
132 result = {} |
|
133 |
|
134 if not node_id: |
|
135 raise backend.NoInstantNodes |
|
136 |
|
137 if node_id in self.nodes: |
|
138 raise backend.NodeExists |
|
139 |
|
140 node = Node(node_id) |
|
141 node.affiliations[owner.full()] = 'owner' |
|
142 self.nodes[node_id] = node |
|
143 |
|
144 return defer.succeed({'node_id': node.id}) |