0
|
1 from AccessControl import ClassSecurityInfo
|
|
2 from OFS.Folder import Folder
|
|
3 from OFS.PropertyManager import PropertyManager
|
|
4 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
|
|
5 import Acquisition
|
|
6
|
|
7 import random
|
|
8 import datetime
|
|
9 import logging
|
|
10 import httplib2
|
|
11 import MPIWGFMItem
|
|
12 import xml.etree.ElementTree as ET
|
|
13
|
|
14
|
|
15 # TODO: compatibility
|
|
16 months = [(u"January", u"Januar"),
|
|
17 (u"February", u"Februar"),
|
|
18 (u"March", u"M\u00e4rz"),
|
|
19 (u"April", u"April"),
|
|
20 (u"May", u"Mai"),
|
|
21 (u"June", u"Juni"),
|
|
22 (u"July", u"Juli"),
|
|
23 (u"August", u"August"),
|
|
24 (u"September", u"September"),
|
|
25 (u"October", u"Oktober"),
|
|
26 (u"November", u"November"),
|
|
27 (u"December", u"Dezember"),
|
|
28 ]
|
|
29
|
|
30 map_months = {'EN': [u"",
|
|
31 u"January",
|
|
32 u"February",
|
|
33 u"March",
|
|
34 u"April",
|
|
35 u"May",
|
|
36 u"June",
|
|
37 u"July",
|
|
38 u"August",
|
|
39 u"September",
|
|
40 u"October",
|
|
41 u"November",
|
|
42 u"December"],
|
|
43 'DE': [u"",
|
|
44 u"Januar",
|
|
45 u"Februar",
|
|
46 u"M\u00e4rz",
|
|
47 u"April",
|
|
48 u"Mai",
|
|
49 u"Juni",
|
|
50 u"Juli",
|
|
51 u"August",
|
|
52 u"September",
|
|
53 u"Oktober",
|
|
54 u"November",
|
|
55 u"Dezember"]}
|
|
56
|
|
57
|
|
58 class MPIWGFMManager(Folder, PropertyManager):
|
|
59 """ A Zope-Object for management of the Events
|
|
60
|
|
61 manages MPIWGItem-Objects inside this Folder-like object.
|
|
62 """
|
|
63 _v_items=None
|
|
64 meta_type = 'MPIWGFMManager'
|
|
65 title = ""
|
|
66 project_link = "" # WTF?
|
|
67
|
|
68 _properties = ({'id':'title', 'type':'string'},)
|
|
69
|
|
70 manage_options = Folder.manage_options + (
|
|
71 {'label':'Edit Defaults', 'action':'manage_editMPIWGFMManagerForm'},
|
|
72 {'label':'Edit FM Connection', 'action':'manage_editMPIWGFMConnectionForm'},
|
|
73
|
|
74 )
|
|
75
|
|
76
|
|
77 def __init__(self, id, title,url,username=None,password=None):
|
|
78 self.id = id
|
|
79 self.title = title
|
|
80 self.url=url
|
|
81 self.username=username
|
|
82 self.password=password
|
|
83 self.count = 0
|
|
84 self.Properties = [] # List of 6-tuples (ID_EN,ID_DE,VALUE_EN,VALUE_DE, WEIGHT,ID)
|
|
85 # Note: this defines properties that MPIWGItems will get on creation by default
|
|
86
|
|
87
|
|
88 def getDefaultProperties(self):
|
|
89 """ """
|
|
90 return self.Properties
|
|
91
|
|
92 def deleteObject(self, id):
|
|
93 """ delete an object not implemented management via DB"""
|
|
94 pass
|
|
95
|
|
96 def addProperty(self, tup=("", "", "", "", 0, "")):
|
|
97 self.Properties.append(tup)
|
|
98
|
|
99 def getWeight(self, n):
|
|
100 """ """
|
|
101 return self.Properties[n][4]
|
|
102
|
|
103 def getItems(self):
|
|
104 """returns all items directly"""
|
|
105
|
|
106 if self._v_items is not None:
|
|
107 return self._v_items
|
|
108
|
|
109 ret=[]
|
|
110 #fh = file("/usr/local/testzope13/Products/MPIWGFMManager/kalender.xml")
|
|
111 #root = ET.parse(fh);
|
|
112 url="http://fm8-server.mpiwg-berlin.mpg.de/fmi/xml/fmresultset.xml?-db=Kalender&-lay=Eingabe&-findall"
|
|
113
|
1
|
114 h =httplib2.Http("/var/tmp/.cacheWWW")
|
0
|
115 if self.username is not None:
|
|
116 h.add_credentials(self.username,self.password)
|
|
117
|
|
118 logging.debug(self.url)
|
|
119 resp, content = h.request(self.url)
|
|
120
|
|
121
|
|
122
|
|
123 root=ET.fromstring(content)
|
|
124
|
|
125 ET.register_namespace('', 'http://www.filemaker.com/xml/fmresultset')
|
|
126 records = root.findall(".//{http://www.filemaker.com/xml/fmresultset}record")
|
|
127 #records = root.findall(".//record")
|
|
128
|
|
129 for record in records:
|
|
130
|
|
131 ret.append(MPIWGFMItem.MPIWGFMItem(record,self));
|
|
132
|
|
133 self._v_items=ret
|
|
134 return ret;
|
|
135
|
|
136 def getSortedItems(self, field='Date'):
|
|
137 """return all items sorted by field"""
|
|
138 if field == 'Date':
|
|
139 items = self.getSortedByDate()
|
|
140 else:
|
|
141 items = self.getItems()
|
|
142 items.sort(key=lambda x:x.getValue(field))
|
|
143
|
|
144 return items
|
|
145
|
|
146 def getAllItemsFromTodayOn(self):
|
|
147 """ """
|
|
148 return self.getSortedByDate(startdate=datetime.date.today())
|
|
149
|
|
150 def getAllItemsUntilToday(self, newestFirst=False):
|
|
151 """ """
|
|
152 return self.getSortedByDate(enddate=datetime.date.today(), newestFirst=newestFirst)
|
|
153
|
|
154 def getSortedByDate(self, startdate=None, enddate=None, newestFirst=False):
|
|
155 """ return the Items, sorted by date. The start- and enddate parameters can be set (as strings YYYY.MM.DD) to limit
|
|
156 the list to items that have a date greater or equal to startdate and lower or equal to enddate."""
|
|
157 logging.debug("getsortedbydate startdate=%s enddate=%s" % (startdate, enddate))
|
|
158 #items = [self._getOb(x) for x in self.objectIds(spec="MPIWGItem")]
|
|
159 items = self.getItems()
|
|
160
|
|
161 # filter for startdate
|
|
162 if startdate != None:
|
|
163 try:
|
|
164 if isinstance(startdate, str):
|
|
165 startdatesplitted = [int(x) for x in startdate.split(".")]
|
|
166 logging.debug("getsortedbydate startdate=%s" % repr(startdatesplitted))
|
|
167 startdate = datetime.date(*startdatesplitted)
|
|
168
|
|
169 items = [x for x in items if x.Date >= startdate]
|
|
170 except:
|
|
171 pass
|
|
172
|
|
173 # filter for enddate
|
|
174 if enddate != None:
|
|
175 try:
|
|
176 if isinstance(enddate, str):
|
|
177 enddatesplitted = [int(x) for x in enddate.split(".")]
|
|
178 enddate = datetime.date(*enddatesplitted)
|
|
179
|
|
180 items = [x for x in items if x.Date <= enddate]
|
|
181 except:
|
|
182 pass
|
|
183
|
|
184 if not newestFirst:
|
|
185 items.sort(key=lambda x:x.Date)
|
|
186 else:
|
|
187 items.sort(key=lambda x:x.Date, reverse=True)
|
|
188 return items
|
|
189
|
|
190 def getGroupedByDate(self, lang="EN"):
|
|
191 """ return the entries in a dictionary structure,
|
|
192 grouped by Year, then by Month (and then a sorted list) """
|
|
193
|
|
194 result = {}
|
|
195 for item in self.getItems():
|
|
196 m = item.Date.month
|
|
197 y = item.Date.year
|
|
198
|
|
199 d = 0
|
|
200 if lang.upper() == "DE":
|
|
201 d = 1
|
|
202
|
|
203 if not y in result:
|
|
204 result[y] = {}
|
|
205
|
|
206 if not m in result[y]:
|
|
207 result[y][m] = [months[m - 1][d]]
|
|
208
|
|
209 result[y][m] += [item]
|
|
210
|
|
211 return result
|
|
212
|
|
213 def getGrouped(self, field, type, lang="EN"):
|
|
214 """ return the entries in a dictionary structure,
|
|
215 grouped by the values of field with grouping type.
|
|
216 type='year_month','a_z'"""
|
|
217
|
|
218 if type == 'year_month':
|
|
219 # sort by year, then month
|
|
220 map = map_months[lang.upper()]
|
|
221 key1 = lambda x:x.Date.year
|
|
222 key2 = lambda x:map[x.Date.month]
|
|
223 else:
|
|
224 # sort by first letter of field
|
|
225 key1 = lambda x:x.getValue(field, lang)[0].upper()
|
|
226 key2 = None
|
|
227
|
|
228 result = []
|
|
229 k1 = None
|
|
230 k2 = None
|
|
231 list1 = None
|
|
232 list2 = None
|
|
233 if key2 is None:
|
|
234 # single level
|
|
235 for item in self.getSortedItems(field=field):
|
|
236 if k1 != key1(item):
|
|
237 # new key
|
|
238 k1 = key1(item)
|
|
239 list1 = []
|
|
240 result.append({'key':k1, 'list':list1})
|
|
241
|
|
242 # add item to list
|
|
243 list1.append(item)
|
|
244
|
|
245 else:
|
|
246 # two level
|
|
247 for item in self.getSortedItems(field=field):
|
|
248 if k1 != key1(item):
|
|
249 # new key1
|
|
250 k1 = key1(item)
|
|
251 list1 = []
|
|
252 result.append({'key':k1, 'list':list1})
|
|
253 # invalidate key2
|
|
254 k2 = None
|
|
255
|
|
256 if k2 != key2(item):
|
|
257 # new key2
|
|
258 k2 = key2(item)
|
|
259 list2 = []
|
|
260 list1.append({'key':k2, 'list':list2})
|
|
261
|
|
262 # add item to list
|
|
263 list2.append(item)
|
|
264
|
|
265 return result
|
|
266
|
|
267
|
|
268 def getMostRecent(self, count=2):
|
|
269 """ returns the 'count' most recent event entries as EventObjects """
|
|
270 events = self.getItems()
|
|
271 events.sort(key=lambda x:x.Date)
|
|
272 events.reverse()
|
|
273 return events[:count]
|
|
274
|
|
275 def getFirst(self, count=2, start=0):
|
|
276 """ returns the count first elements """
|
|
277 events = self.getSortedItems()
|
|
278 return events[start:count]
|
|
279
|
|
280
|
|
281 def getNext(self, count=2):
|
|
282 """ returns the next 'count' upcoming events; if there are not enough upcoming events, fill with the latest past events """
|
|
283 today = datetime.date.today()
|
|
284 events = self.getItems()
|
|
285 events.sort(key=lambda x:x.Date)
|
|
286 upcoming = [x for x in events if x.Date >= today]
|
|
287 short = count - len(upcoming)
|
|
288 if short > 0:
|
|
289 pastevents = [x for x in events if x.Date < today]
|
|
290 upcoming += pastevents[-short:]
|
|
291 # upcoming.reverse()
|
|
292 return upcoming[:count]
|
|
293
|
|
294 def getNewID(self):
|
|
295 """ """
|
|
296 items = self.getItems()
|
|
297 if len(items) == 0:
|
|
298 count = 1
|
|
299 else:
|
|
300 itemsnum = [x for x in items if x.id.isdigit()]
|
|
301 itemsnum.sort(lambda a, b :cmp(a.id, b.id))
|
|
302
|
|
303 count = int(itemsnum[-1].id) + 1
|
|
304 return "%04d" % (count)
|
|
305
|
|
306
|
|
307
|
|
308 def manage_editMPIWGFMManager(self, REQUEST):
|
|
309 """ """
|
|
310
|
|
311 formdata = REQUEST.form
|
|
312
|
|
313 # update property names and values and weights
|
|
314 # date,title,category
|
|
315 property_ids = [int(x.split('_')[1]) for x in formdata.keys() if x.endswith('_en_key')]
|
|
316 for pid in property_ids:
|
|
317 if pid < len(self.Properties):
|
|
318 self.Properties[pid] = (
|
|
319 formdata["property_%s_en_key" % pid],
|
|
320 formdata["property_%s_de_key" % pid],
|
|
321 formdata["property_%s_en_value" % pid],
|
|
322 formdata["property_%s_de_value" % pid],
|
|
323 formdata["property_%s_weight" % pid],
|
|
324 formdata["property_%s_id" % pid])
|
|
325
|
|
326 # check if properties need to be removed
|
|
327 deltoken = "del__"
|
|
328 # e.g. "del__property_1"
|
|
329 relevant_keys = [int(x.split('_')[-1]) for x in formdata.keys() if x.find(deltoken) == 0 and formdata[x] == "on"]
|
|
330 relevant_keys.sort()
|
|
331 relevant_keys.reverse()
|
|
332 for n in relevant_keys:
|
|
333 del self.Properties[n]
|
|
334
|
|
335 # sort
|
|
336 self.Properties.sort(lambda a, b: cmp(int(a[4]), int(b[4])))
|
|
337
|
|
338 # add new properties (empty)
|
|
339 try:
|
|
340 add_new = int(formdata['add_new'])
|
|
341
|
|
342 for x in range(add_new):
|
|
343 self.addProperty()
|
|
344 except:
|
|
345 pass
|
|
346
|
|
347 # force update of the Properties list in the ZopeDB
|
|
348 self._p_changed = 1
|
|
349
|
|
350 REQUEST.RESPONSE.redirect('manage_editMPIWGFMManagerForm?rnd=%s' % ''.join(random.sample("abcdefuvwxyz", 8)))
|
|
351
|
|
352 manage_editMPIWGFMManagerForm = PageTemplateFile('zpt/editMPIWGManager.pt', globals())
|
|
353
|
|
354 def manage_editMPIWGFMConnection(self,url,username,password,REQUEST=None):
|
|
355 """change the parameters for connections"""
|
|
356 self.url=url
|
|
357 self.username=username
|
|
358 self.password=password
|
|
359
|
|
360 REQUEST.RESPONSE.redirect(' manage_editMPIWGFMConnectionForm?rnd=%s' % ''.join(random.sample("abcdefuvwxyz", 8)))
|
|
361
|
|
362 manage_editMPIWGFMConnectionForm = PageTemplateFile('zpt/editConnection.pt', globals())
|
|
363
|
|
364
|
|
365 def manage_addMPIWGFMManager(self, id, title, url, username=None,password=None, REQUEST=None):
|
|
366 """ create the new MPIWGManager """
|
|
367 newinst = MPIWGFMManager(id, title,url, username,password)
|
|
368 self._setObject(id, newinst)
|
|
369
|
|
370 REQUEST.RESPONSE.redirect('manage_main')
|
|
371
|
|
372 manage_addMPIWGFMManagerForm = PageTemplateFile('zpt/addMPIWGManager.pt', globals())
|