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