mise a jour du modele Record et création d'une interface d'admin. (Le modele record...
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / lib / backend.py
1 # -*- encoding: utf-8 -*-
2 import simplejson, re, datetime, operator
3 from savoirs.globals import *
4 from savoirs.models import Record, HarvestLog
5
6
7 class Backend:
8 def close (self):
9 pass
10
11 def add (self, metadata):
12 r = Record ()
13 for k in metadata.keys ():
14 setattr (r, k, simplejson.dumps(metadata[k]))
15 r.save()
16
17 def delete (self, id):
18 r = Record.objects.get(id = id)
19 r.delete()
20
21 def update (self, id, metadata):
22 r = Record.objects.get(id = id)
23 for k in metadata.keys ():
24 setattr (r, k, simplejson.dumps(metadata[k]))
25 r.save()
26
27 def get (self, id):
28 r = Record.objects.get(id = id)
29 meta = {}
30 for k in META.keys ():
31 if hasattr (r, k):
32 v = getattr (r, k)
33 if v is not None:
34 meta[k] = simplejson.loads(v)
35 return meta
36
37 def ids (self):
38 return [x.id for x in Record.objects.all()]
39
40 def _text_search (self, q, fields = None):
41 if fields is None:
42 fields = [x for x in META.keys() if META[x].get("text_search", False)]
43
44 w = re.compile (r'\W+', re.U)
45 words = w.split (q)
46
47 matches = []
48 suffix = ""
49 if len(fields)==1 and fields[0] == "subject":
50 suffix = " IN BOOLEAN MODE"
51
52 for k in fields:
53 matches.append ("MATCH(`%s`) AGAINST ('%s'%s)" % (k, " ".join(words), suffix))
54 m = "+".join (matches)
55
56 q = "SELECT id, (" + m + ") AS score FROM savoirs_record WHERE (" \
57 + m + ") HAVING score > 0 ORDER BY score DESC"
58
59 from django.db import connection, transaction
60 cursor = connection.cursor()
61 cursor.execute(q)
62 rc = cursor.fetchall()
63 return rc
64
65 def filter_string_contains (self, set, q, key):
66 rc = []
67 words = q.get (key)
68 if words:
69 r = re.compile (r'%s' % words, re.IGNORECASE)
70 for k in set:
71 str = self.get(k).get(key, "").encode("utf-8")
72 if r.search (str) is not None:
73 rc.append (k)
74 else:
75 rc = set
76 return rc
77
78 def filter_string_equals (self, q, key):
79 rc = []
80 keys = self.ids ()
81 for k in keys:
82 str = self.get(k).get(key, "")
83 if str.lower() == q[key].lower():
84 rc.append ((k, 1))
85 return rc
86
87 def _score (self, matches):
88 rc = 0
89 for i in matches:
90 for j in i:
91 if len (j.strip()) > 0:
92 rc += 1
93 return rc
94
95 def _combine (self, result_lists, op):
96 scores = {}
97 simple_sets = []
98
99 for list in result_lists:
100 simple_sets.append (set([x[0] for x in list]))
101 for (id, score) in list:
102 if scores.get (id) is None:
103 scores[id] = 0
104 scores[id] += score
105
106 matches = []
107 for s in simple_sets:
108 if op == "|":
109 matches = set(matches) | s
110 elif op == "&":
111 if len (matches) == 0:
112 matches = s
113 else:
114 matches = set(matches) & s
115 #print "EE", matches
116
117 return [(x, scores[x]) for x in matches]
118
119 def search (self, q):
120 rc = []
121 sets = []
122
123 if len (q) > 0:
124 # Recherche "simple"
125 ww = simplejson.dumps(q.get ("q", "").strip())[1:-1]
126 if len (ww) > 0:
127 s = self._text_search (ww)
128 if len(s) > 0:
129 rc.append (s)
130 # Recherche URL
131 elif q.get (URI) is not None:
132 s = []
133 try:
134 s.append((Record.objects.get(uri__iexact = \
135 "\"" + q.get(URI) + "\"").id, 1))
136 rc.append(s)
137 except: pass
138 # Recherche avancée
139 else:
140 creator = simplejson.dumps(q.get ("creator", ""))[1:-1]
141 title = simplejson.dumps(q.get ("title", ""))[1:-1]
142 description = simplejson.dumps(q.get ("description", ""))[1:-1]
143 subject = simplejson.dumps(q.get ("subject", ""))[1:-1]
144
145 if len (creator) > 0:
146 sets.append (self._text_search (creator, [CREATOR, CONTRIBUTOR]))
147 if len (title) > 0:
148 sets.append (self._text_search (title, [TITLE, ALT_TITLE]))
149 if len (description) > 0:
150 sets.append (self._text_search (description, [DESCRIPTION, ABSTRACT]))
151 if len (subject) > 0:
152 sets.append (self._text_search (subject, [SUBJECT,]))
153 rc = self._combine (sets, q.get ("operator", "|"))
154 rc.sort (key = operator.itemgetter(1), reverse = True)
155
156 if len(rc) > 0:
157 rc = [x[0] for x in rc]
158
159 else:
160 rc = self.ids()
161
162 return rc
163
164 def add_log (self, name, count):
165 try:
166 t = HarvestLog.objects.get(name = name)
167 except:
168 t = HarvestLog(name = name)
169
170 t.count = count
171 t.date = datetime.datetime.today()
172 t.save()
173
174 def logs (self):
175 rc = {}
176 tmp = HarvestLog.objects.all()
177 for r in tmp:
178 rc[r.name] = (r.date, r.count)
179 return rc
180
181
182