Mercurial > libervia-pubsub
annotate idavoll/backend.py @ 20:eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Renamed 'name' attribute of Node to 'id'.
Added create_node() method.
author | Ralph Meijer <ralphm@ik.nu> |
---|---|
date | Wed, 06 Oct 2004 21:05:42 +0000 |
parents | 7937d6fbbe2a |
children | 884268687229 |
rev | line source |
---|---|
1 | 1 from twisted.application import service |
2 from twisted.python import components, failure | |
3 from twisted.internet import defer, reactor | |
15 | 4 from twisted.protocols.jabber import jid |
1 | 5 |
6 class IBackendService(components.Interface): | |
7 """ Interface to a backend service of a pubsub service """ | |
8 | |
2 | 9 def do_publish(self, node, publisher, item): |
10 """ Returns a deferred that returns """ | |
11 | |
1 | 12 class BackendException(Exception): |
13 def __init__(self, msg = ''): | |
14 self.msg = msg | |
15 | |
16 def __str__(self): | |
17 return self.msg | |
18 | |
19 class NodeNotFound(BackendException): | |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
20 def __init__(self, msg = 'Node not found'): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
21 BackendException.__init__(self, msg) |
1 | 22 |
23 class NotAuthorized(BackendException): | |
24 pass | |
25 | |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
26 class PayloadExpected(BackendException): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
27 def __init__(self, msg = 'Payload expected'): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
28 BackendException.__init__(self, msg) |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
29 |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
30 class NoPayloadAllowed(BackendException): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
31 def __init__(self, msg = 'No payload allowed'): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
32 BackendException.__init__(self, msg) |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
33 |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
34 class NoInstantNodes(BackendException): |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
35 pass |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
36 |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
37 class NodeExists(BackendException): |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
38 pass |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
39 |
15 | 40 class Subscription: |
41 def __init__(self, state): | |
42 self.state = state | |
43 | |
44 class NodeConfiguration: | |
45 def __init__(self): | |
46 self.persist_items = False | |
47 self.deliver_payloads = False | |
48 | |
49 class Node: | |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
50 def __init__(self, id): |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
51 self.id = id |
15 | 52 self.configuration = NodeConfiguration() |
53 self.subscriptions = {} | |
54 self.affiliations = {} | |
55 self.items = {} | |
56 | |
1 | 57 class MemoryBackendService(service.Service): |
58 | |
59 __implements__ = IBackendService, | |
60 | |
61 def __init__(self): | |
15 | 62 self.nodes = {} |
1 | 63 |
15 | 64 node = Node("ralphm/mood/ralphm@ik.nu") |
65 node.subscriptions["ralphm@doe.ik.nu"] = Subscription("subscribed") | |
18 | 66 node.subscriptions["notify@ik.nu/mood_monitor"] = Subscription("subscribed") |
15 | 67 node.affiliations["ralphm@ik.nu"] = "owner" |
68 node.affiliations["ralphm@doe.ik.nu"] = "publisher" | |
69 node.configuration.persist_items = True | |
70 node.configuration.deliver_payloads = True | |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
71 self.nodes[node.id] = node |
15 | 72 |
73 def do_publish(self, node_id, publisher, items): | |
1 | 74 try: |
75 try: | |
15 | 76 node = self.nodes[node_id] |
77 persist_items = node.configuration.persist_items | |
78 deliver_payloads = node.configuration.deliver_payloads | |
1 | 79 except KeyError: |
80 raise NodeNotFound | |
81 | |
82 try: | |
15 | 83 if node.affiliations[publisher] not in ['owner', 'publisher']: |
1 | 84 raise NotAuthorized |
85 except KeyError: | |
86 raise NotAuthorized() | |
2 | 87 |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
88 if items and not persist_items and not deliver_payloads: |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
89 raise NoPayloadAllowed |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
90 elif not items and (persist_items or deliver_payloads): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
91 raise PayloadExpected |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
92 |
15 | 93 print "publish by %s to %s" % (publisher, node_id) |
2 | 94 |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
95 if persist_items or deliver_payloads: |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
96 for item in items: |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
97 if item["id"] is None: |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
98 item["id"] = 'random' # FIXME |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
99 |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
100 if persist_items: |
15 | 101 self.storeItems(node_id, publisher, items) |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
102 |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
103 if items and not deliver_payloads: |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
104 for item in items: |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
105 item.children = [] |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
106 |
15 | 107 recipients = self.get_subscribers(node_id) |
108 recipients.addCallback(self.magic_filter, node_id, items) | |
109 recipients.addCallback(self.pubsub_service.do_notification, node_id) | |
2 | 110 |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
111 return defer.succeed(None) |
1 | 112 except: |
18 | 113 return defer.fail(failure.Failure()) |
1 | 114 |
15 | 115 def do_subscribe(self, node_id, subscriber, requestor): |
116 # expect subscriber and requestor to be a jid.JID | |
117 try: | |
118 try: | |
119 node = self.nodes[node_id] | |
120 except KeyError: | |
121 raise NodeNotFound | |
122 | |
123 affiliation = node.affiliations.get(requestor.full(), 'none') | |
124 | |
125 if affiliation == 'banned': | |
126 raise NotAuthorized | |
127 | |
128 print subscriber.full() | |
129 print subscriber.userhostJID().full() | |
130 print requestor.full() | |
131 | |
132 if subscriber.userhostJID() != requestor: | |
133 raise NotAuthorized | |
134 | |
135 try: | |
136 subscription = node.subscriptions[subscriber.full()] | |
137 except KeyError: | |
138 subscription = Subscription('subscribed') | |
139 node.subscriptions[subscriber.full()] = subscription | |
140 | |
141 print node.subscriptions | |
142 | |
143 return defer.succeed({ | |
144 'affiliation': affiliation, | |
145 'node': node_id, | |
146 'jid': subscriber, | |
147 'subscription': subscription.state}) | |
148 except: | |
18 | 149 return defer.fail(failure.Failure) |
15 | 150 |
151 | |
152 def magic_filter(self, subscribers, node_id, items): | |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
153 list = {} |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
154 for subscriber in subscribers: |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
155 list[subscriber] = items |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
156 |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
157 return list |
2 | 158 |
15 | 159 def get_subscribers(self, node_id): |
1 | 160 d = defer.Deferred() |
161 try: | |
15 | 162 result = self.nodes[node_id].subscriptions.keys() |
1 | 163 except: |
164 f = failure.Failure() | |
165 reactor.callLater(0, d.errback, f) | |
166 else: | |
167 reactor.callLater(0, d.callback, result) | |
168 | |
169 return d | |
170 | |
15 | 171 def storeItems(self, node_id, publisher, items): |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
172 for item in items: |
15 | 173 self.nodes[node_id].items[item["id"]] = item |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
174 |
15 | 175 print self.nodes[node_id].items |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
176 |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
177 def create_node(node_id, owner): |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
178 result = {} |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
179 |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
180 try: |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
181 if not node_id: |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
182 raise NoInstantNodes |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
183 |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
184 if node_id in self.nodes: |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
185 raise NodeExists |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
186 |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
187 self.nodes[node_id] = Node(node_id) |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
188 node.affiliations[owner.full()] = 'owner' |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
189 return defer.succeed({'node_id': node.id}) |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
190 except: |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
191 return defer.fail(failure.Failure) |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
192 |