]> jfr.im git - irc/rizon/acid.git/blob - pyva/src/main/python/pseudoclient/collection.py
Import acidictive 4 and pyva plugin
[irc/rizon/acid.git] / pyva / src / main / python / pseudoclient / collection.py
1 from datetime import datetime
2 from utils import *
3 from istring import *
4 import traceback
5 import inspect
6
7 class InvariantCollection(object):
8 def __init__(self):
9 self.__entries = {}
10
11 def __len__(self):
12 return len(self.__entries)
13
14 def __getitem__(self, key):
15 invariant_key = istring(key)
16
17 if not self.__contains__(invariant_key):
18 raise KeyError('Entry with key %s not present.' % key)
19
20 return self.__entries[invariant_key]
21
22 def __setitem__(self, key, value):
23 self.__entries[istring(key)] = value
24
25 def __delitem__(self, key):
26 invariant_key = istring(key)
27
28 if not self.__contains__(invariant_key):
29 raise KeyError('Entry with key %s not present.' % key)
30
31 del(self.__entries[invariant_key])
32
33 def __iter__(self):
34 for entry in self.__entries:
35 yield entry
36
37 def __contains__(self, item):
38 if not isinstance(item, basestring):
39 raise TypeError('%s is not an allowed indexing type.' % type(item))
40
41 return istring(item) in self.__entries
42
43 def list_all(self):
44 return [self[item] for item in self]
45
46 class CollectionEntity(object):
47 def __init__(self, id, ban_source = None, ban_reason = None, ban_date = None, ban_expiry = None):
48 self.id = id
49 self.ban_source = ban_source
50 self.ban_reason = ban_reason
51 self.ban_date = ban_date
52 self.ban_expiry = ban_expiry
53 self.dirty = False
54 self.registered = self.banned = False
55
56 class CollectionManager(InvariantCollection):
57 def __init__(self, type):
58 InvariantCollection.__init__(self)
59 self.__type = type
60 self.__deleted_items = []
61
62 self.db_open()
63
64 self.load()
65
66 def load(self):
67 self.cursor.execute("CREATE TABLE IF NOT EXISTS " + self.module.name + "_" + self.name + " (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(51) NOT NULL, PRIMARY KEY (id), UNIQUE KEY (name)) ENGINE=InnoDB")
68
69 self.cursor.execute("CREATE TABLE IF NOT EXISTS " + self.module.name + "_" + self.name + "_options (id INT, name VARCHAR(32) NOT NULL, value TINYTEXT, UNIQUE KEY (id, name)) ENGINE=InnoDB")
70 #self.cursor.execute("ALTER TABLE " + self.module.name + "_" + self.name + "_options ADD CONSTRAINT FOREIGN KEY IF NOT EXISTS (id) REFERENCES " + self.module.name + "_" + self.name + " (id)")
71
72 self.cursor.execute("SELECT id, name FROM " + self.module.name + "_" + self.name)
73 r = self.cursor.fetchall()
74
75 for row in r:
76 id = row[0]
77 name = istring(row[1])
78
79 self.module.elog.debug('Loading ' + name + ' for ' + self.module.name + '_' + self.name)
80
81 self[name] = e = self.__type(id, name)
82
83 self.cursor.execute("SELECT name,value FROM " + self.module.name + "_" + self.name + "_options WHERE `id` = %s", (id,))
84 r2 = self.cursor.fetchall()
85 for row2 in r2:
86 setattr(e, row2[0], row2[1])
87
88 def __get_attributes(self, obj):
89 boring = dir(type('dummy', (object,), {}))
90 return [item for item in inspect.getmembers(obj) if item[0] not in boring]
91
92 def commit(self):
93 try:
94 deleted = [(e.id, ) for e in self.list_deleted()]
95 changed = [e for e in self.list_dirty()]
96
97 if len(deleted) > 0:
98 self.cursor.executemany("DELETE FROM " + self.module.name + "_" + self.name + "_options WHERE id = %s", deleted)
99 self.cursor.executemany("DELETE FROM " + self.module.name + "_" + self.name + " WHERE id = %s", deleted)
100 self.module.elog.commit('Deleted %d %s from database.' % (len(deleted), self.name))
101
102 for e in changed:
103 if e.id == -1:
104 self.cursor.execute("INSERT INTO " + self.module.name + "_" + self.name + " (name) VALUES(%s)", (e.name,))
105 e.id = self.cursor.lastrowid
106 else: # delete options as we are aboue to re-flush them
107 self.cursor.execute("DELETE FROM " + self.module.name + "_" + self.name + "_options WHERE `id` = %s", (e.id,))
108
109 for a in self.__get_attributes(e):
110 attr_name = a[0]
111 attr = getattr(e, attr_name)
112 if attr:
113 self.cursor.execute("INSERT INTO " + self.module.name + "_" + self.name + "_options (id, name, value) VALUES (%s, %s, %s)", (e.id, attr_name, attr))
114 if len(changed) > 0:
115 self.module.elog.commit('Committed %d %s to database.' % (len(changed), self.name))
116
117 self.clear_deleted()
118
119 for e in self.list_all():
120 e.dirty = False
121 except Exception, err:
122 traceback.print_exc()
123 self.module.elog.error(self.name + ' commit failed: @b%s@b' % err)
124
125 def check(self, item):
126 if not item in self:
127 return
128
129 entity = self[item]
130
131 if entity.ban_expiry != None and entity.ban_expiry <= unix_time(datetime.now()):
132 self.unban(item)
133
134 def is_dirty(self, item):
135 self.check(item)
136
137 return item in self and self[item].dirty
138
139 def is_valid(self, item):
140 self.check(item)
141
142 return item in self and self[item].registered and not self[item].banned
143
144 def is_banned(self, item):
145 self.check(item)
146
147 return item in self and self[item].banned
148
149 def get(self, item, attribute):
150 if not item in self:
151 return None
152
153 return getattr(self[item], attribute)
154
155 def set(self, item, attribute, value):
156 entity = self.add(item)
157 old_value = getattr(entity, attribute)
158
159 if old_value != value:
160 setattr(entity, attribute, value)
161 entity.dirty = True
162
163 def add(self, item):
164 if not item in self:
165 entity = self.__type(-1, item)
166 entity.dirty = True
167 entity.registered = True
168 self[item] = entity
169
170 self.on_added(item)
171
172 return self[item]
173
174 def remove(self, item):
175 if not item in self:
176 return
177
178 entity = self[item]
179
180 if entity.banned and entity.registered:
181 entity.registered = False
182 entity.clear()
183 entity.dirty = True
184 elif not entity.banned:
185 if not item.lower() in self.__deleted_items:
186 self.__deleted_items.append(entity)
187
188 del(self[item])
189
190 self.on_removed(item)
191
192 def ban(self, item, source, reason, date, expiry):
193 entity = self.add(item)
194 entity.banned = True
195 entity.ban_source = source
196 entity.ban_reason = reason
197 entity.ban_date = date
198 entity.ban_expiry = expiry
199 entity.dirty = True
200
201 self.on_banned(item)
202
203 def unban(self, item):
204 if not item in self or not self[item].banned:
205 return
206
207 entity = self[item]
208 entity.banned = False
209 entity.ban_source = None
210 entity.ban_reason = None
211 entity.ban_date = None
212 entity.ban_expiry = None
213
214 if not entity.registered:
215 self.remove(item)
216 else:
217 entity.dirty = True
218
219 self.on_unbanned(item)
220
221 def on_added(self, item):
222 pass
223
224 def on_removed(self, item):
225 pass
226
227 def on_banned(self, item):
228 pass
229
230 def on_unbanned(self, item):
231 pass
232
233 def clear_deleted(self):
234 self.__deleted_items = []
235
236 def list_deleted(self):
237 return self.__deleted_items
238
239 def list_dirty(self):
240 items = [item for item in self]
241 return [self[item] for item in items if self.is_dirty(item)]
242
243 def list_valid(self):
244 items = [item for item in self]
245 return [self[item] for item in items if self.is_valid(item)]
246
247 def list_banned(self):
248 items = [item for item in self]
249 return [self[item] for item in items if self.is_banned(item)]