/[glsr]/trunk/site/script.py
Gentoo

Contents of /trunk/site/script.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 186 - (show annotations) (download) (as text)
Tue Nov 15 06:01:54 2005 UTC (8 years, 8 months ago) by hadfield
File MIME type: text/x-python
File size: 15760 byte(s)
implemented standard search.
1 # Copyright 2005 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 #
4
5 """The DB access module for the script and subscript table.
6
7 Implements all functions necessary for creating, modifying, and managing
8 scripts and subscripts.
9 """
10
11 __revision__ = "$Id$"
12 __authors__ = ["Scott Hadfield <hadfield@gentoo.org>",
13 "Ian Leitch <port001@gentoo.org>"]
14 __modulename__ = "script"
15
16 from time import strftime, gmtime
17 import types
18
19 from glsr.setup import config
20 from glsr.core.db.mysql import SQLdb
21 from glsr.site import user
22
23 def create_script(submitter_id, name = "",
24 descr = "", version = "1.0", language = 0,
25 category = 0, body = "", changelog = ""):
26 """Add a new script to the database."""
27
28 sql_handle = SQLdb(config.db)
29
30 # Add the script to the database
31 sql_handle.query(
32 "INSERT INTO %(prefix)sscript " % {'prefix': config.db['prefix']} +
33 "(script_submitter_id, script_category_id, script_language_id," +
34 " script_rank, script_name, script_descr)" +
35 " VALUES (%s, %s, %s, 0, %s, %s)",
36 (submitter_id, category, language, name, descr), fetch = "none")
37
38 # Get the scripts id
39 results = sql_handle.query("SELECT LAST_INSERT_ID() as id", fetch = "one")
40
41 assert(results.has_key("id"))
42 subscript_id = create_subscript(results["id"], version, body, changelog)
43
44 return (results["id"], subscript_id)
45
46 def create_subscript(parent_id, version, body, changelog):
47 """Add a new subscript to the database."""
48
49 # FIXME: Default status should be based on the config.
50 status = "published"
51
52
53 sql_handle = SQLdb(config.db)
54
55 results = sql_handle.query(
56 "INSERT INTO %(prefix)ssubscript " % {'prefix': config.db['prefix']} +
57 "(subscript_parent_id, subscript_version, subscript_body," +
58 " subscript_changelog, subscript_date, subscript_status)" +
59 " VALUES (%s, %s, %s, %s, NOW(), %s)",
60 (parent_id, version, body, changelog, status), fetch = "one")
61
62 # Get the subscripts id
63 results = sql_handle.query("SELECT LAST_INSERT_ID() as id",
64 fetch = "one")
65 assert(results.has_key("id"))
66
67 return results["id"]
68
69 def list_subscripts(script_restrict = None, subscript_restrict = None):
70 """Returns a list of each script combined with its current subscript."""
71 pass
72
73 def _list_scripts(columns = None, constraints = None):
74 """Return selected columns from all rows in the script table.
75
76 This is copied from the user.list_all method.
77 """
78 # FIXME: Sanity checks on column names and contrainst keys.
79 # Without this we could have mysql injection attacks.
80
81 if columns is None:
82 return []
83 else:
84 columns = ", ".join(columns)
85
86 where_clause = ""
87 if constraints is not None:
88 where_clause = " AND ".join(["script_%s = %%s" % key
89 for key in constraints])
90 if where_clause != "":
91 where_clause = "WHERE " + where_clause
92 else:
93 constraints = {}
94
95 results = SQLdb(config.db).query(
96 "SELECT %(columns)s FROM %(prefix)sscript %(where)s" %
97 {'columns': columns, 'prefix': config.db['prefix'],
98 'where': where_clause}, constraints.values(), fetch="all")
99
100 return results
101
102 def list_scripts(script_columns = None, subscript_columns = None,
103 script_constraints = None, subscript_constraints = None,
104 get_subscript = True):
105 """Returns a list of each script combined with its current subscript."""
106
107 if script_columns != None:
108 if len(script_columns) == 0:
109 script_columns = ['*']
110 elif "script_id" not in script_columns:
111 script_columns.append("script_id")
112 else:
113 script_columns = ['*']
114
115 script_arr = _list_scripts(script_columns, script_constraints)
116
117 if not get_subscript:
118 return script_arr
119
120 retval = []
121 for record in script_arr:
122 script = Script(record["script_id"])
123 subscript = script.current()
124 subscript_record = subscript.get_columns(["*"])
125
126 for column, value in subscript_record.iteritems():
127 record.update({column: value})
128
129 retval.append(record)
130
131 return retval
132
133 def search(columns = None, terms = None):
134 """Search for scripts in the DB.
135
136 Terms should be a dictionary of (field, value) pairs. If 'value' is a
137 ListType then they will be OR'd
138 (i.e. field = value[0] OR field = value[1]...)
139
140 Searchable values include: language, category, status, name, descr,
141 submitter
142 """
143
144 # FIXME: Needs some more sanity checking on incoming columns and terms.
145 # Potential for mysql injection.
146
147 if columns is None:
148 return []
149 else:
150 columns = ", ".join(columns)
151
152 if terms is None:
153 return []
154
155 where_clause = __mk_query(["language", "category"], terms)
156 if where_clause != "":
157 where_clause = "WHERE " + where_clause
158
159 # FIXME: Use the columns variable instead of 'select *'
160 scripts = SQLdb(config.db).query(
161 "SELECT * FROM %(prefix)sscript %(where)s" %
162 {'columns': columns, 'prefix': config.db["prefix"],
163 'where': where_clause})
164
165 found = []
166 for script in scripts:
167 for key in ["name", "descr"]:
168 if (terms.has_key(key)
169 and script["script_" + key].find(terms[key]) != -1):
170 if script not in found:
171 found.append(script)
172
173 for script in scripts:
174 if terms.has_key("submitter_id"):
175 search_user = user.User(terms["submitter_id"])
176 script_user = user.User(script["script_submitter_id"])
177 if search_user.get_alias().find(script_user.get_alias()) != -1:
178 if script not in found:
179 found.append(script)
180
181 for script in scripts:
182 if (terms.has_key("category_id") and
183 script["script_category_id"] == int(terms["category_id"])):
184 if script not in found:
185 found.append(script)
186
187 for script in scripts:
188 if (terms.has_key("language_id") and
189 script["script_language_id"] == int(terms["language_id"])):
190 if script not in found:
191 found.append(script)
192
193 # Get the subscripts
194 where_clause = __mk_query(["status"], terms)
195 if where_clause != "":
196 where_clause = "AND " + where_clause
197
198 for i in range(len(found)):
199
200 qstr = ("SELECT subscript_version, subscript_date, subscript_status," +
201 " subscript_approvedby " +
202 "FROM %(prefix)ssubscript " % {'prefix': config.db["prefix"]} +
203 "WHERE subscript_status != 'draft'" +
204 " AND subscript_parent_id = %s " % found[i]["script_id"] +
205 where_clause)
206
207 if "current" in terms.keys():
208 subscript = SQLdb(config.db).query(
209 qstr + " ORDER BY subscript_version", fetch = "one")
210 found[i].update(subscript)
211
212 else:
213 subscripts = SQLdb(config.db).query(qstr, fetch = "all")
214
215 for subscript in subscripts[1:]:
216 # Since we're selecting all subscripts we need to copy the
217 # script again for each additional subscript.
218 found.append(found[i])
219 found[len(found)].update(subscript)
220
221 found[i].update(subscripts[0])
222
223 return found
224
225 def listing(count):
226
227 import user
228
229 # TODO: The script selection needs to be ordered by date!
230 results = list_scripts(
231 ["script_submitter_id", "script_id", "script_name", "script_descr"],
232 ["subscript_version", "subscript_date"])
233
234 results = results[:count]
235 for result in results:
236 user_obj = user.User(result["script_submitter_id"])
237 result.update({"user_alias": user_obj.get_alias()})
238
239 return results
240
241 def __mk_query(fields, terms):
242
243 qstr = ""
244 for (key,value) in terms.items():
245 if key in fields:
246 if qstr != "":
247 qstr = qstr + " AND "
248 qstr = qstr + __mk_query_str(key, terms)
249
250 return qstr
251
252 def __mk_query_str(field, terms):
253
254 import string
255
256 qstr = field + " IN "
257 if type(terms[field]) == types.ListType:
258
259 if not len(terms[field]):
260 return ""
261
262 newlist = map(lambda x: "'%s'" % x, terms[field])
263 value = string.join(newlist, "," % field)
264
265 else:
266 value = terms[field]
267
268 return "%s (%s)" % (qstr, value)
269
270
271 class Script:
272 """Defines the get and set attributes for a Script."""
273
274 def __init__(self, script_id):
275
276 self._db = SQLdb(config.db)
277 self._script_id = script_id
278
279 def _get_attr(self, attr):
280 """Return the value of the specified attribute, or DB field."""
281
282 result = self._db.query(
283 "SELECT %(attr)s FROM %(prefix)sscript " %
284 {"attr": attr, "prefix": config.db["prefix"]} +
285 "WHERE script_id = %s", str(self._script_id), fetch = "one")
286
287 if result != None:
288 return result[attr]
289
290 return None
291
292 def approve(self):
293 """Mark script as approved"""
294 self.current().approve()
295
296 def get_author(self):
297 """Return the script submitters username."""
298
299 from glsr.site import user
300 submitter_id = self._get_attr("script_submitter_id")
301 user_obj = user.User(submitter_id)
302 return user_obj.get_alias()
303
304 def get_category(self):
305 """Return the name of the category this script is in."""
306
307 from glsr.site import category
308 category_id = self._get_attr("script_category_id")
309 cat_obj = category.Category(category_id)
310 return category_id, cat_obj.name()
311
312 def get_language(self):
313 """Return the name of the language this script is written in."""
314 from glsr.site import language
315 language_id = self._get_attr("script_language_id")
316 lang_obj = language.Language(language_id)
317 return language_id, lang_obj.name()
318
319 def get_name(self):
320 """Return the name of this script."""
321 return self._get_attr("script_name")
322
323 def get_descr(self):
324 """Return the name of this script."""
325 return self._get_attr("script_descr")
326
327 def get_rank(self):
328 """Return the name of this script."""
329 return self._get_attr("script_rank")
330
331 def get_version(self):
332 """Return the name of this script."""
333 cur_subscript = self.current()
334 return cur_subscript.get_version()
335
336 def get_body(self):
337 """Return the name of this script."""
338 cur_subscript = self.current()
339 return cur_subscript.get_body()
340
341 def get_changelog(self, from_revision = None, to_revision = None):
342 changelogs = []
343 for subscript_id in self.list_subscripts(order = "subscript_version"):
344 subscript_obj = Subscript(subscript_id)
345 changelogs.append({"version": subscript_obj.get_version(),
346 "status": subscript_obj.get_status(),
347 "approved": subscript_obj.get_approved(),
348 "approvedby": subscript_obj.get_approvedby(),
349 "date": subscript_obj.get_date(),
350 "changelog": subscript_obj.get_changelog()})
351 return changelogs
352
353 def current(self):
354 """Returns the id of the current subscript."""
355
356 # FIXME: This returns most recent script, but should be stable as well.
357 # In other words, the newest script might be a draft or
358 # non-approved
359 result = self._db.query(
360 "SELECT subscript_id FROM %(prefix)ssubscript " %
361 {'prefix': config.db['prefix']} +
362 "WHERE subscript_parent_id = %s ORDER BY subscript_date DESC",
363 self._script_id, fetch='one')
364
365 assert(result is not None)
366
367 return Subscript(result["subscript_id"])
368
369 def get_columns(self, columns):
370
371 columns = ", ".join(columns)
372
373 result = self._db.query(
374 "SELECT %(columns)s FROM %(prefix)sscript " %
375 {'columns': columns, 'prefix': config.db['prefix']} +
376 "WHERE script_id = %s", self._script_id, fetch = "one")
377
378 assert(result is not None)
379
380 return result
381
382 def incr_rank(self):
383 rank = self.get_rank()
384
385 self._db.query(
386 "UPDATE %sscript " % config.db["prefix"] +
387 "SET script_rank = %s " +
388 "WHERE script_id = %s", (rank + 1, self._script_id),
389 fetch = "none")
390
391 def list_subscripts(self, constraint = None, order = None):
392 """Returns a list of all subscripts."""
393
394 order_str = ""
395 if order is not None:
396 order_str = "ORDER BY %s DESC" % order
397
398 results = self._db.query(
399 "SELECT subscript_id FROM %ssubscript " % config.db["prefix"] +
400 "WHERE subscript_parent_id = %%s %s" % order_str,
401 self._script_id, fetch = "all")
402 return [result["subscript_id"] for result in results]
403
404 def update(self, name = "", descr = "", version = "1.0", language = 0,
405 category = 0, body = "", changelog = ""):
406
407 self._db.query(
408 "UPDATE %(prefix)sscript " % {'prefix': config.db['prefix']} +
409 "SET script_category_id = %s," +
410 " script_language_id = %s, script_name = %s," +
411 " script_descr = %s",
412 (category, language, name, descr), fetch = "none")
413
414 subscript_id = create_subscript(self._script_id, version, body,
415 changelog)
416
417 return subscript_id
418
419 class Subscript:
420
421 def __init__(self, subscript_id):
422
423 self._db = SQLdb(config.db)
424 self._subscript_id = subscript_id
425
426 def _get_attr(self, attr):
427 """Return the value of the specified attribute, or DB field."""
428
429 result = self._db.query(
430 "SELECT %(attr)s FROM %(prefix)ssubscript " %
431 {"attr": attr, "prefix": config.db["prefix"]} +
432 "WHERE subscript_id = %s", str(self._subscript_id), fetch = "one")
433
434 if result != None:
435 return result[attr]
436
437 return None
438
439 def get_columns(self, columns):
440
441 columns = ", ".join(columns)
442
443 result = self._db.query(
444 "SELECT %(columns)s FROM %(prefix)ssubscript " %
445 {'columns': columns, 'prefix': config.db['prefix']} +
446 "WHERE subscript_id = %s", self._subscript_id, fetch = "one")
447
448 assert(result is not None)
449
450 return result
451
452 def get_id(self):
453 return self._subscript_id
454
455 def get_body(self):
456 return self._get_attr("subscript_body")
457
458 def get_version(self):
459 return self._get_attr("subscript_version")
460
461 def get_status(self):
462 return self._get_attr("subscript_status")
463
464 def get_approved(self):
465 return self._get_attr("subscript_approved")
466
467 def get_approvedby(self):
468 return self._get_attr("subscript_approvedby")
469
470 def get_date(self):
471 return self._get_attr("subscript_date")
472
473 def get_changelog(self):
474 return self._get_attr("subscript_changelog")
475
476 def modify(self, script_id, parent_id, details):
477 """Add a new subscript."""
478 pass
479
480 def approve(self):
481 """Mark script as approved."""
482 pass
483
484 def parent_id(self):
485 """Return the parent id for this subscript."""
486 pass

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.20