Mercurial > libervia-pubsub
comparison idavoll/memory_backend.py @ 30:ff7c73b253bf
Recode backend to match interaces: one big Service that handles everything
and several skeleton Services that declare the interface that they implement
along with passing on calls to the 'implemented' methods.
author | Ralph Meijer <ralphm@ik.nu> |
---|---|
date | Tue, 26 Oct 2004 16:28:07 +0000 |
parents | e6d62c93cd0a |
children | 9aa20efac203 |
comparison
equal
deleted
inserted
replaced
29:d4fc29bb5381 | 30:ff7c73b253bf |
---|---|
2 from twisted.internet import defer | 2 from twisted.internet import defer |
3 from twisted.protocols.jabber import jid | 3 from twisted.protocols.jabber import jid |
4 import backend | 4 import backend |
5 | 5 |
6 class Subscription: | 6 class Subscription: |
7 def __init__(self, state): | 7 def __init__(self, state): |
8 self.state = state | 8 self.state = state |
9 | 9 |
10 class NodeConfiguration: | 10 class NodeConfiguration: |
11 def __init__(self): | 11 def __init__(self): |
12 self.persist_items = False | 12 self.persist_items = False |
13 self.deliver_payloads = False | 13 self.deliver_payloads = False |
14 | 14 |
15 class Node: | 15 class Node: |
16 def __init__(self, id): | 16 def __init__(self, id): |
17 self.id = id | 17 self.id = id |
18 self.configuration = NodeConfiguration() | 18 self.configuration = NodeConfiguration() |
19 self.subscriptions = {} | 19 self.subscriptions = {} |
20 self.affiliations = {} | 20 self.affiliations = {} |
21 self.items = {} | 21 self.items = {} |
22 | 22 |
23 class MemoryBackendService(service.Service): | 23 class BackendService(backend.BackendService): |
24 | 24 |
25 __implements__ = backend.IService, | 25 def __init__(self): |
26 backend.BackendService.__init__(self) | |
26 | 27 |
27 def __init__(self): | 28 self.nodes = {} |
28 self.nodes = {} | |
29 | 29 |
30 node = Node("ralphm/mood/ralphm@ik.nu") | 30 node = Node("ralphm/mood/ralphm@ik.nu") |
31 node.subscriptions["ralphm@doe.ik.nu"] = Subscription("subscribed") | 31 node.subscriptions["ralphm@doe.ik.nu"] = Subscription("subscribed") |
32 node.subscriptions["notify@ik.nu/mood_monitor"] = Subscription("subscribed") | 32 node.subscriptions["notify@ik.nu/mood_monitor"] = Subscription("subscribed") |
33 node.affiliations["ralphm@ik.nu"] = "owner" | 33 node.affiliations["ralphm@ik.nu"] = "owner" |
34 node.affiliations["ralphm@doe.ik.nu"] = "publisher" | 34 node.affiliations["ralphm@doe.ik.nu"] = "publisher" |
35 node.configuration.persist_items = True | 35 node.configuration.persist_items = True |
36 node.configuration.deliver_payloads = True | 36 node.configuration.deliver_payloads = True |
37 self.nodes[node.id] = node | 37 self.nodes[node.id] = node |
38 | |
39 def get_supported_affiliations(self): | |
40 return ['none', 'owner', 'outcast', 'publisher'] | |
38 | 41 |
39 def do_publish(self, node_id, publisher, items): | 42 def create_node(self, node_id, requestor): |
40 try: | 43 if not node_id: |
41 node = self.nodes[node_id] | 44 raise backend.NoInstantNodes |
42 persist_items = node.configuration.persist_items | |
43 deliver_payloads = node.configuration.deliver_payloads | |
44 except KeyError: | |
45 raise backend.NodeNotFound | |
46 | 45 |
47 try: | 46 if node_id in self.nodes: |
48 if node.affiliations[publisher] not in ['owner', 'publisher']: | 47 raise backend.NodeExists |
49 raise backend.NotAuthorized | 48 |
50 except KeyError: | 49 node = Node(node_id) |
51 raise backend.NotAuthorized | 50 node.affiliations[requestor.full()] = 'owner' |
51 self.nodes[node_id] = node | |
52 | 52 |
53 if items and not persist_items and not deliver_payloads: | 53 return defer.succeed({'node_id': node.id}) |
54 raise backend.NoPayloadAllowed | |
55 elif not items and (persist_items or deliver_payloads): | |
56 raise backend.PayloadExpected | |
57 | 54 |
58 print "publish by %s to %s" % (publisher, node_id) | 55 def publish(self, node_id, items, requestor): |
56 try: | |
57 node = self.nodes[node_id] | |
58 persist_items = node.configuration.persist_items | |
59 deliver_payloads = node.configuration.deliver_payloads | |
60 except KeyError: | |
61 raise backend.NodeNotFound | |
59 | 62 |
60 if persist_items or deliver_payloads: | 63 try: |
61 for item in items: | 64 if node.affiliations[requestor.full()] not in \ |
62 if item["id"] is None: | 65 ['owner', 'publisher']: |
63 item["id"] = 'random' # FIXME | 66 raise backend.NotAuthorized |
67 except KeyError: | |
68 raise backend.NotAuthorized | |
64 | 69 |
65 if persist_items: | 70 if items and not persist_items and not deliver_payloads: |
66 self.storeItems(node_id, publisher, items) | 71 raise backend.NoPayloadAllowed |
72 elif not items and (persist_items or deliver_payloads): | |
73 raise backend.PayloadExpected | |
67 | 74 |
68 if items and not deliver_payloads: | 75 print "publish by %s to %s" % (requestor.full(), node_id) |
69 for item in items: | |
70 item.children = [] | |
71 | 76 |
72 recipients = self.get_subscribers(node_id) | 77 if persist_items or deliver_payloads: |
73 recipients.addCallback(self.magic_filter, node_id, items) | 78 for item in items: |
74 recipients.addCallback(self.pubsub_service.do_notification, node_id) | 79 if item["id"] is None: |
80 item["id"] = 'random' # FIXME | |
75 | 81 |
76 return defer.succeed(None) | 82 if persist_items: |
83 self.store_items(node_id, items, requestor) | |
77 | 84 |
78 def do_subscribe(self, node_id, subscriber, requestor): | 85 if items and not deliver_payloads: |
79 # expect subscriber and requestor to be a jid.JID | 86 for item in items: |
80 try: | 87 item.children = [] |
81 node = self.nodes[node_id] | |
82 except KeyError: | |
83 raise backend.NodeNotFound | |
84 | 88 |
85 affiliation = node.affiliations.get(requestor.full(), 'none') | 89 self.dispatch({ 'items': items, 'node_id': node_id }, |
90 '//event/pubsub/notify') | |
91 return defer.succeed(None) | |
86 | 92 |
87 if affiliation == 'banned': | 93 def get_notification_list(self, node_id, items): |
88 raise backend.NotAuthorized | 94 |
95 try: | |
96 d = defer.succeed(self.nodes[node_id].subscriptions.keys()) | |
97 except: | |
98 d = defer.fail() | |
89 | 99 |
90 print subscriber.full() | 100 d.addCallback(self._magic_filter, node_id, items) |
91 print subscriber.userhostJID().full() | |
92 print requestor.full() | |
93 | 101 |
94 if subscriber.userhostJID() != requestor: | 102 return d |
95 raise backend.NotAuthorized | |
96 | 103 |
97 try: | 104 def _magic_filter(self, subscribers, node_id, items): |
98 subscription = node.subscriptions[subscriber.full()] | 105 list = {} |
99 except KeyError: | 106 for subscriber in subscribers: |
100 subscription = Subscription('subscribed') | 107 list[subscriber] = items |
101 node.subscriptions[subscriber.full()] = subscription | |
102 | 108 |
103 print node.subscriptions | 109 return list |
104 | 110 |
105 return defer.succeed({ | 111 def subscribe(self, node_id, subscriber, requestor): |
106 'affiliation': affiliation, | 112 # expect subscriber and requestor to be a jid.JID |
107 'node': node_id, | 113 try: |
108 'jid': subscriber, | 114 node = self.nodes[node_id] |
109 'subscription': subscription.state}) | 115 except KeyError: |
110 | 116 raise backend.NodeNotFound |
111 def magic_filter(self, subscribers, node_id, items): | |
112 list = {} | |
113 for subscriber in subscribers: | |
114 list[subscriber] = items | |
115 | 117 |
116 return list | 118 if subscriber.userhostJID() != requestor: |
119 raise backend.NotAuthorized | |
117 | 120 |
118 def get_subscribers(self, node_id): | 121 affiliation = node.affiliations.get(subscriber.full(), 'none') |
119 d = defer.Deferred() | |
120 try: | |
121 return defer.succeed(self.nodes[node_id].subscriptions.keys()) | |
122 except: | |
123 return defer.fail() | |
124 | 122 |
125 def storeItems(self, node_id, publisher, items): | 123 if affiliation == 'outcast': |
126 for item in items: | 124 raise backend.NotAuthorized |
127 self.nodes[node_id].items[item["id"]] = item | |
128 | 125 |
129 print self.nodes[node_id].items | 126 try: |
127 subscription = node.subscriptions[subscriber.full()] | |
128 except KeyError: | |
129 subscription = Subscription('subscribed') | |
130 node.subscriptions[subscriber.full()] = subscription | |
130 | 131 |
131 def create_node(self, node_id, owner): | 132 print node.subscriptions |
132 result = {} | |
133 | 133 |
134 if not node_id: | 134 return defer.succeed({ |
135 raise backend.NoInstantNodes | 135 'affiliation': affiliation, |
136 'node': node_id, | |
137 'jid': subscriber, | |
138 'subscription': subscription.state}) | |
139 | |
140 def store_items(self, node_id, items, publisher): | |
141 for item in items: | |
142 self.nodes[node_id].items[item["id"]] = item | |
143 print self.nodes[node_id].items | |
136 | 144 |
137 if node_id in self.nodes: | 145 class NodeCreationService(service.Service): |
138 raise backend.NodeExists | |
139 | |
140 node = Node(node_id) | |
141 node.affiliations[owner.full()] = 'owner' | |
142 self.nodes[node_id] = node | |
143 | 146 |
144 return defer.succeed({'node_id': node.id}) | 147 __implements__ = backend.INodeCreationService, |
148 | |
149 def create_node(self, node_id, requestor): | |
150 return self.parent.create_node(node_id, requestor) | |
151 | |
152 class PublishService(service.Service): | |
153 | |
154 __implements__ = backend.IPublishService, | |
155 | |
156 def publish(self, node_id, items, requestor): | |
157 return self.parent.publish(node_id, items, requestor) | |
158 | |
159 class NotificationService(backend.NotificationService): | |
160 | |
161 __implements__ = backend.INotificationService, | |
162 | |
163 def get_notification_list(self, node_id, items): | |
164 return self.parent.get_notification_list(node_id, items) | |
165 | |
166 class SubscriptionService(service.Service): | |
167 | |
168 __implements__ = backend.ISubscriptionService, | |
169 | |
170 def subscribe(self, node_id, subscriber, requestor): | |
171 return self.parent.subscribe(node_id, subscriber, requestor) | |
172 | |
173 def unsubscribe(self, node_id, subscriber, requestor): | |
174 raise backend.NotImplemented | |
175 | |
176 class PersistenceService(service.Service): | |
177 | |
178 __implements__ = backend.IPersistenceService, | |
179 | |
180 def store_items(self, node_id, items, publisher): | |
181 return self.parent.store_items(node_id, items, publisher) | |
182 |