/src/baruwa/utils/queryfilters.py

https://github.com/rehle/baruwa · Python · 408 lines · 338 code · 50 blank · 20 comment · 101 complexity · 7ba2d3c487472c2d0f9ed629cf1926a2 MD5 · raw file

  1. #
  2. # Baruwa - Web 2.0 MailScanner front-end.
  3. # Copyright (C) 2010-2011 Andrew Colin Kissa <andrew@topdog.za.net>
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License along
  16. # with this program; if not, write to the Free Software Foundation, Inc.,
  17. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. #
  19. # vim: ai ts=4 sts=4 et sw=4
  20. #
  21. from django.db.models import Q
  22. from baruwa.reports.forms import FILTER_ITEMS, FILTER_BY
  23. def place_positive_vars(key, largs, kwargs, lkwargs, value):
  24. "utility function"
  25. if key in kwargs:
  26. kwords = {str(key): value}
  27. largs.append(Q(**kwords))
  28. kwords = {str(key): str(kwargs[key])}
  29. largs.append(Q(**kwords))
  30. lkwargs.update(kwords)
  31. del kwargs[key]
  32. else:
  33. kwords = {str(key): value}
  34. if key in lkwargs:
  35. largs.append(Q(**kwords))
  36. else:
  37. kwargs.update(kwords)
  38. def place_negative_vars(key, nargs, nkwargs, lnkwargs, value):
  39. "utility function"
  40. if key in nkwargs:
  41. kwords = {str(key): value}
  42. nargs.append(Q(**kwords))
  43. kwords = {str(key): str(nkwargs[key])}
  44. nargs.append(Q(**kwords))
  45. lnkwargs.update(kwords)
  46. del nkwargs[key]
  47. else:
  48. kwords = {str(key): value}
  49. if key in lnkwargs:
  50. nargs.append(Q(**kwords))
  51. else:
  52. nkwargs.update(kwords)
  53. def raw_user_filter(user, addresses, account_type):
  54. "builds user filter"
  55. dsql = []
  56. esql = []
  57. sql = '1 != 1'
  58. if not user.is_superuser:
  59. if account_type == 2:
  60. if addresses:
  61. for domain in addresses:
  62. dsql.append('to_domain="' + domain + '"')
  63. dsql.append('from_domain="' + domain + '"')
  64. sql = ' OR '.join(dsql)
  65. if account_type == 3:
  66. if addresses:
  67. for email in addresses:
  68. esql.append('to_address="' + email + '"')
  69. esql.append('from_address="' + email + '"')
  70. esql.append('to_address="' + user.username + '"')
  71. sql = ' OR '.join(esql)
  72. else:
  73. sql = 'to_address="%s"' % user.username
  74. return '(' + sql + ')'
  75. def get_active_filters(filter_list, active_filters):
  76. "generates a dictionary of active filters"
  77. if not active_filters is None:
  78. filter_items = dict(FILTER_ITEMS)
  79. filter_by = dict(FILTER_BY)
  80. for filter_item in filter_list:
  81. active_filters.append(dict(
  82. filter_field=filter_items[filter_item['field']],
  83. filter_by=filter_by[int(filter_item['filter'])],
  84. filter_value=filter_item['value']))
  85. def gen_dynamic_query(model, filter_list, active_filters=None):
  86. "build a dynamic query"
  87. kwargs = {}
  88. lkwargs = {}
  89. nkwargs = {}
  90. lnkwargs = {}
  91. nargs = []
  92. largs = []
  93. filter_items = dict(FILTER_ITEMS)
  94. filter_by = dict(FILTER_BY)
  95. for filter_item in filter_list:
  96. value = str(filter_item['value'])
  97. if filter_item['filter'] == 1:
  98. tmp = "%s__exact" % filter_item['field']
  99. place_positive_vars(tmp, largs, kwargs, lkwargs, value)
  100. if filter_item['filter'] == 2:
  101. tmp = "%s__exact" % filter_item['field']
  102. place_negative_vars(tmp, nargs, nkwargs, lnkwargs, value)
  103. if filter_item['filter'] == 3:
  104. tmp = "%s__gt" % filter_item['field']
  105. place_positive_vars(tmp, largs, kwargs, lkwargs, value)
  106. if filter_item['filter'] == 4:
  107. tmp = "%s__lt" % filter_item['field']
  108. place_positive_vars(tmp, largs, kwargs, lkwargs, value)
  109. if filter_item['filter'] == 5:
  110. tmp = "%s__icontains" % filter_item['field']
  111. place_positive_vars(tmp, largs, kwargs, lkwargs, value)
  112. if filter_item['filter'] == 6:
  113. tmp = "%s__icontains" % filter_item['field']
  114. place_negative_vars(tmp, nargs, nkwargs, lnkwargs, value)
  115. if filter_item['filter'] == 7:
  116. tmp = "%s__regex" % filter_item['field']
  117. place_positive_vars(tmp, largs, kwargs, lkwargs, value)
  118. if filter_item['filter'] == 8:
  119. tmp = "%s__regex" % filter_item['field']
  120. place_negative_vars(tmp, nargs, nkwargs, lnkwargs, value)
  121. if filter_item['filter'] == 9:
  122. tmp = "%s__isnull" % filter_item['field']
  123. place_positive_vars(tmp, largs, kwargs, lkwargs, value)
  124. if filter_item['filter'] == 10:
  125. tmp = "%s__isnull" % filter_item['field']
  126. place_negative_vars(tmp, nargs, nkwargs, lnkwargs, value)
  127. if filter_item['filter'] == 11:
  128. tmp = "%s__gt" % filter_item['field']
  129. place_positive_vars(tmp, largs, kwargs, lkwargs, 0)
  130. if filter_item['filter'] == 12:
  131. tmp = "%s__exact" % filter_item['field']
  132. place_positive_vars(tmp, largs, kwargs, lkwargs, 0)
  133. if not active_filters is None:
  134. active_filters.append(
  135. {
  136. 'filter_field': filter_items[filter_item['field']],
  137. 'filter_by': filter_by[int(filter_item['filter'])],
  138. 'filter_value': value}
  139. )
  140. if kwargs:
  141. model = model.filter(**kwargs)
  142. if nkwargs:
  143. model = model.exclude(**nkwargs)
  144. if nargs:
  145. query = Q()
  146. for sub_query in nargs:
  147. query = query | sub_query
  148. model = model.exclude(query)
  149. if largs:
  150. query = Q()
  151. for sub_query in largs:
  152. query = query | sub_query
  153. model = model.filter(query)
  154. return model
  155. def apply_filter(model, request, active_filters):
  156. "apply filters to a model"
  157. if request.session.get('filter_by', False):
  158. filter_list = request.session.get('filter_by')
  159. model = gen_dynamic_query(model, filter_list, active_filters)
  160. return model
  161. def gen_dynamic_raw_query(filter_list):
  162. "generates a dynamic query"
  163. sql = []
  164. asql = []
  165. avals = []
  166. osql = []
  167. ovals = []
  168. nosql = []
  169. novals = []
  170. for filter_item in filter_list:
  171. if filter_item['filter'] == 1:
  172. tmp = "%s = %%s" % filter_item['field']
  173. if tmp in asql:
  174. inx = asql.index(tmp)
  175. tvl = avals[inx]
  176. osql.append(asql[inx])
  177. ovals.append(tvl)
  178. asql.remove(tmp)
  179. avals.remove(tvl)
  180. osql.append(tmp)
  181. ovals.append(filter_item['value'])
  182. else:
  183. if tmp in osql:
  184. osql.append(tmp)
  185. ovals.append(filter_item['value'])
  186. else:
  187. asql.append(tmp)
  188. avals.append(filter_item['value'])
  189. if filter_item['filter'] == 2:
  190. tmp = "%s != %%s" % filter_item['field']
  191. if tmp in asql:
  192. inx = asql.index(tmp)
  193. tvl = avals[inx]
  194. nosql.append(asql[inx])
  195. novals.append(tvl)
  196. asql.remove(tmp)
  197. avals.remove(tvl)
  198. nosql.append(tmp)
  199. novals.append(filter_item['value'])
  200. else:
  201. if tmp in nosql:
  202. nosql.append(tmp)
  203. novals.append(filter_item['value'])
  204. else:
  205. asql.append(tmp)
  206. avals.append(filter_item['value'])
  207. if filter_item['filter'] == 3:
  208. tmp = "%s > %%s" % filter_item['field']
  209. if tmp in asql:
  210. inx = asql.index(tmp)
  211. tvl = avals[inx]
  212. osql.append(asql[inx])
  213. ovals.append(tvl)
  214. asql.remove(tmp)
  215. avals.remove(tvl)
  216. osql.append(tmp)
  217. ovals.append(filter_item['value'])
  218. else:
  219. if tmp in osql:
  220. osql.append(tmp)
  221. ovals.append(filter_item['value'])
  222. else:
  223. asql.append(tmp)
  224. avals.append(filter_item['value'])
  225. if filter_item['filter'] == 4:
  226. tmp = "%s < %%s" % filter_item['field']
  227. if tmp in asql:
  228. inx = asql.index(tmp)
  229. tvl = avals[inx]
  230. osql.append(asql[inx])
  231. ovals.append(tvl)
  232. asql.remove(tmp)
  233. avals.remove(tvl)
  234. osql.append(tmp)
  235. ovals.append(filter_item['value'])
  236. else:
  237. if tmp in osql:
  238. osql.append(tmp)
  239. ovals.append(filter_item['value'])
  240. else:
  241. asql.append(tmp)
  242. avals.append(filter_item['value'])
  243. if filter_item['filter'] == 5:
  244. tmp = "%s LIKE %%s" % filter_item['field']
  245. if tmp in asql:
  246. inx = asql.index(tmp)
  247. tvl = avals[inx]
  248. osql.append(asql[inx])
  249. ovals.append(tvl)
  250. asql.remove(tmp)
  251. avals.remove(tvl)
  252. osql.append(tmp)
  253. ovals.append(filter_item['value'])
  254. else:
  255. if tmp in osql:
  256. osql.append(tmp)
  257. ovals.append(filter_item['value'])
  258. else:
  259. asql.append(tmp)
  260. avals.append('%' + filter_item['value'] + '%')
  261. if filter_item['filter'] == 6:
  262. tmp = "%s NOT LIKE %%s" % filter_item['field']
  263. if tmp in asql:
  264. inx = asql.index(tmp)
  265. tvl = avals[inx]
  266. nosql.append(asql[inx])
  267. novals.append(tvl)
  268. asql.remove(tmp)
  269. avals.remove(tvl)
  270. nosql.append(tmp)
  271. novals.append(filter_item['value'])
  272. else:
  273. if tmp in nosql:
  274. nosql.append(tmp)
  275. novals.append(filter_item['value'])
  276. else:
  277. asql.append(tmp)
  278. avals.append('%' + filter_item['value'] + '%')
  279. if filter_item['filter'] == 7:
  280. tmp = "%s REGEXP %%s" % filter_item['field']
  281. if tmp in asql:
  282. inx = asql.index(tmp)
  283. tvl = avals[inx]
  284. osql.append(asql[inx])
  285. ovals.append(tvl)
  286. asql.remove(tmp)
  287. avals.remove(tvl)
  288. osql.append(tmp)
  289. ovals.append(filter_item['value'])
  290. else:
  291. if tmp in osql:
  292. osql.append(tmp)
  293. ovals.append(filter_item['value'])
  294. else:
  295. asql.append(tmp)
  296. avals.append(filter_item['value'])
  297. if filter_item['filter'] == 8:
  298. tmp = "%s NOT REGEXP %%s" % filter_item['field']
  299. if tmp in asql:
  300. inx = asql.index(tmp)
  301. tvl = avals[inx]
  302. nosql.append(asql[inx])
  303. novals.append(tvl)
  304. asql.remove(tmp)
  305. avals.remove(tvl)
  306. nosql.append(tmp)
  307. novals.append(filter_item['value'])
  308. else:
  309. if tmp in nosql:
  310. nosql.append(tmp)
  311. novals.append(filter_item['value'])
  312. else:
  313. asql.append(tmp)
  314. avals.append(filter_item['value'])
  315. if filter_item['filter'] == 9:
  316. tmp = "%s IS NULL" % filter_item['field']
  317. sql.append(tmp)
  318. if filter_item['filter'] == 10:
  319. tmp = "%s IS NOT NULL" % filter_item['field']
  320. sql.append(tmp)
  321. if filter_item['filter'] == 11:
  322. tmp = "%s > 0" % filter_item['field']
  323. sql.append(tmp)
  324. if filter_item['filter'] == 12:
  325. tmp = "%s = 0" % filter_item['field']
  326. sql.append(tmp)
  327. for item in sql:
  328. asql.append(item)
  329. andsql = ' AND '.join(asql)
  330. orsql = ' OR '.join(osql)
  331. nsql = ' AND '.join(nosql)
  332. for item in ovals:
  333. avals.append(item)
  334. for item in novals:
  335. avals.append(item)
  336. if andsql != '':
  337. if orsql != '':
  338. if nsql != '':
  339. sql = andsql + ' AND ( ' + orsql + ' ) AND ( ' + nsql + ' )'
  340. else:
  341. sql = andsql + ' AND ( ' + orsql + ' )'
  342. else:
  343. if nsql != '':
  344. sql = andsql + ' AND ( ' + nsql + ' )'
  345. else:
  346. sql = andsql
  347. else:
  348. if orsql != '':
  349. if nsql != '':
  350. sql = '( ' + orsql + ' ) AND ( ' + nsql + ' )'
  351. else:
  352. sql = '( ' + orsql + ' )'
  353. else:
  354. if nsql != '':
  355. sql = '( ' + nsql + ' )'
  356. else:
  357. sql = ' 1=1 '
  358. return (sql, avals)