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