diff MPIWGFMManager.py @ 0:957bcf42f206

initial
author dwinter
date Thu, 02 May 2013 08:33:53 +0200
parents
children 03cd09e9133e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MPIWGFMManager.py	Thu May 02 08:33:53 2013 +0200
@@ -0,0 +1,372 @@
+from AccessControl import ClassSecurityInfo
+from OFS.Folder import Folder
+from OFS.PropertyManager import PropertyManager
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+import Acquisition
+
+import random
+import datetime
+import logging
+import httplib2
+import MPIWGFMItem
+import xml.etree.ElementTree as ET
+
+
+# TODO: compatibility
+months = [(u"January", u"Januar"),
+          (u"February", u"Februar"),
+          (u"March", u"M\u00e4rz"),
+          (u"April", u"April"),
+          (u"May", u"Mai"),
+          (u"June", u"Juni"),
+          (u"July", u"Juli"),
+          (u"August", u"August"),
+          (u"September", u"September"),
+          (u"October", u"Oktober"),
+          (u"November", u"November"),
+          (u"December", u"Dezember"),
+          ]
+
+map_months = {'EN': [u"",
+               u"January",
+               u"February",
+               u"March",
+               u"April",
+               u"May",
+               u"June",
+               u"July",
+               u"August",
+               u"September",
+               u"October",
+               u"November",
+               u"December"],
+              'DE': [u"",
+               u"Januar",
+               u"Februar",
+               u"M\u00e4rz",
+               u"April",
+               u"Mai",
+               u"Juni",
+               u"Juli",
+               u"August",
+               u"September",
+               u"Oktober",
+               u"November",
+               u"Dezember"]}
+
+
+class MPIWGFMManager(Folder, PropertyManager):
+    """ A Zope-Object for management of the Events  
+    
+    manages MPIWGItem-Objects inside this Folder-like object. 
+    """
+    _v_items=None   
+    meta_type = 'MPIWGFMManager'
+    title = ""
+    project_link = ""  # WTF?
+
+    _properties = ({'id':'title', 'type':'string'},)
+                   
+    manage_options = Folder.manage_options + (
+        {'label':'Edit Defaults', 'action':'manage_editMPIWGFMManagerForm'},
+         {'label':'Edit FM Connection', 'action':'manage_editMPIWGFMConnectionForm'},
+
+        )
+
+
+    def __init__(self, id, title,url,username=None,password=None):
+        self.id = id
+        self.title = title
+        self.url=url
+        self.username=username
+        self.password=password
+        self.count = 0
+        self.Properties = []  # List of 6-tuples (ID_EN,ID_DE,VALUE_EN,VALUE_DE, WEIGHT,ID)
+                             # Note: this defines properties that MPIWGItems will get on creation by default
+
+
+    def getDefaultProperties(self):
+        """ """
+        return self.Properties
+
+    def deleteObject(self, id):
+        """ delete an object not implemented management via DB"""
+        pass
+
+    def addProperty(self, tup=("", "", "", "", 0, "")):
+        self.Properties.append(tup)
+
+    def getWeight(self, n):
+        """ """
+        return self.Properties[n][4]
+
+    def getItems(self):
+        """returns all items directly"""
+        
+        if self._v_items is not None:
+            return self._v_items
+        
+        ret=[]
+        #fh = file("/usr/local/testzope13/Products/MPIWGFMManager/kalender.xml")
+        #root = ET.parse(fh);
+        url="http://fm8-server.mpiwg-berlin.mpg.de/fmi/xml/fmresultset.xml?-db=Kalender&-lay=Eingabe&-findall"
+        
+        h =httplib2.Http(".cache")
+        if self.username is not None:
+            h.add_credentials(self.username,self.password)
+        
+        logging.debug(self.url)
+        resp, content = h.request(self.url)
+        
+        
+        
+        root=ET.fromstring(content)
+       
+        ET.register_namespace('', 'http://www.filemaker.com/xml/fmresultset')
+        records = root.findall(".//{http://www.filemaker.com/xml/fmresultset}record")
+        #records = root.findall(".//record")
+        
+        for record in records:
+            
+            ret.append(MPIWGFMItem.MPIWGFMItem(record,self));
+        
+        self._v_items=ret
+        return ret;
+
+    def getSortedItems(self, field='Date'):
+        """return all items sorted by field"""
+        if field == 'Date':
+            items = self.getSortedByDate()
+        else:
+            items = self.getItems()
+            items.sort(key=lambda x:x.getValue(field))
+            
+        return items
+
+    def getAllItemsFromTodayOn(self):
+        """ """
+        return self.getSortedByDate(startdate=datetime.date.today())
+    
+    def getAllItemsUntilToday(self, newestFirst=False):
+        """ """
+        return self.getSortedByDate(enddate=datetime.date.today(), newestFirst=newestFirst)
+
+    def getSortedByDate(self, startdate=None, enddate=None, newestFirst=False):
+        """ return the Items, sorted by date. The start- and enddate parameters can be set (as strings YYYY.MM.DD) to limit 
+        the list to items that have a date greater or equal to startdate and lower or equal to enddate."""
+        logging.debug("getsortedbydate startdate=%s enddate=%s" % (startdate, enddate))
+        #items = [self._getOb(x) for x in self.objectIds(spec="MPIWGItem")]
+        items = self.getItems()
+        
+        # filter for startdate
+        if startdate != None:
+            try:
+                if isinstance(startdate, str):
+                    startdatesplitted = [int(x) for x in startdate.split(".")]
+                    logging.debug("getsortedbydate startdate=%s" % repr(startdatesplitted))
+                    startdate = datetime.date(*startdatesplitted)
+                    
+                items = [x for x in items if x.Date >= startdate]
+            except:
+                pass
+            
+        # filter for enddate
+        if enddate != None:
+            try:
+                if isinstance(enddate, str):
+                    enddatesplitted = [int(x) for x in enddate.split(".")]
+                    enddate = datetime.date(*enddatesplitted)
+                    
+                items = [x for x in items if x.Date <= enddate]
+            except:
+                pass
+
+        if not newestFirst:
+            items.sort(key=lambda x:x.Date)
+        else:
+            items.sort(key=lambda x:x.Date, reverse=True)
+        return items
+
+    def getGroupedByDate(self, lang="EN"):
+        """ return the entries in a dictionary structure, 
+        grouped by Year, then by Month (and then a sorted list) """
+
+        result = {}
+        for item in self.getItems():
+            m = item.Date.month
+            y = item.Date.year
+
+            d = 0
+            if lang.upper() == "DE":
+                d = 1
+
+            if not y in result:
+                result[y] = {}
+            
+            if not m in result[y]:
+                result[y][m] = [months[m - 1][d]]
+
+            result[y][m] += [item]
+
+        return result
+
+    def getGrouped(self, field, type, lang="EN"):
+        """ return the entries in a dictionary structure, 
+        grouped by the values of field with grouping type.
+        type='year_month','a_z'"""
+
+        if type == 'year_month':
+            # sort by year, then month
+            map = map_months[lang.upper()]
+            key1 = lambda x:x.Date.year
+            key2 = lambda x:map[x.Date.month]
+        else:
+            # sort by first letter of field
+            key1 = lambda x:x.getValue(field, lang)[0].upper()
+            key2 = None
+            
+        result = []
+        k1 = None
+        k2 = None
+        list1 = None
+        list2 = None
+        if key2 is None:
+            # single level
+            for item in self.getSortedItems(field=field):
+                if k1 != key1(item):
+                    # new key
+                    k1 = key1(item)
+                    list1 = []
+                    result.append({'key':k1, 'list':list1})
+                             
+                # add item to list      
+                list1.append(item)
+        
+        else:
+            # two level
+            for item in self.getSortedItems(field=field):
+                if k1 != key1(item):
+                    # new key1
+                    k1 = key1(item)
+                    list1 = []
+                    result.append({'key':k1, 'list':list1})
+                    # invalidate key2
+                    k2 = None
+                             
+                if k2 != key2(item):
+                    # new key2
+                    k2 = key2(item)
+                    list2 = []
+                    list1.append({'key':k2, 'list':list2})
+                             
+                # add item to list      
+                list2.append(item)
+                
+        return result
+
+
+    def getMostRecent(self, count=2):
+        """ returns the 'count' most recent event entries as EventObjects """
+        events = self.getItems()
+        events.sort(key=lambda x:x.Date)
+        events.reverse()
+        return events[:count]
+
+    def getFirst(self, count=2, start=0):
+        """ returns the count first elements """
+        events = self.getSortedItems()
+        return events[start:count]
+        
+
+    def getNext(self, count=2):
+        """ returns the next 'count' upcoming events; if there are not enough upcoming events, fill with the latest past events """
+        today = datetime.date.today()
+        events = self.getItems()
+        events.sort(key=lambda x:x.Date)
+        upcoming = [x for x in events if x.Date >= today]
+        short = count - len(upcoming)
+        if short > 0:
+            pastevents = [x for x in events if x.Date < today]
+            upcoming += pastevents[-short:]
+        # upcoming.reverse()
+        return upcoming[:count]
+
+    def getNewID(self):
+        """ """
+        items = self.getItems()
+        if len(items) == 0:
+            count = 1
+        else:
+            itemsnum = [x for x in items if x.id.isdigit()]
+            itemsnum.sort(lambda a, b :cmp(a.id, b.id))
+        
+            count = int(itemsnum[-1].id) + 1
+        return "%04d" % (count)
+
+
+    
+    def manage_editMPIWGFMManager(self, REQUEST):
+        """ """
+
+        formdata = REQUEST.form
+
+        # update property names and values and weights
+        # date,title,category
+        property_ids = [int(x.split('_')[1]) for x in formdata.keys() if x.endswith('_en_key')]
+        for pid in property_ids:
+            if pid < len(self.Properties):
+                self.Properties[pid] = (
+                    formdata["property_%s_en_key" % pid],
+                    formdata["property_%s_de_key" % pid],
+                    formdata["property_%s_en_value" % pid],
+                    formdata["property_%s_de_value" % pid],
+                    formdata["property_%s_weight" % pid],
+                    formdata["property_%s_id" % pid])
+
+        # check if properties need to be removed
+        deltoken = "del__"
+        # e.g. "del__property_1"
+        relevant_keys = [int(x.split('_')[-1]) for x in formdata.keys() if x.find(deltoken) == 0 and formdata[x] == "on"]
+        relevant_keys.sort()
+        relevant_keys.reverse()
+        for n in relevant_keys:
+            del self.Properties[n]
+
+        # sort
+        self.Properties.sort(lambda a, b: cmp(int(a[4]), int(b[4])))
+        
+        # add new properties (empty)
+        try:
+            add_new = int(formdata['add_new'])
+            
+            for x in range(add_new):
+                self.addProperty()
+        except:
+            pass
+
+        # force update of the Properties list in the ZopeDB
+        self._p_changed = 1
+
+        REQUEST.RESPONSE.redirect('manage_editMPIWGFMManagerForm?rnd=%s' % ''.join(random.sample("abcdefuvwxyz", 8)))
+
+    manage_editMPIWGFMManagerForm = PageTemplateFile('zpt/editMPIWGManager.pt', globals())
+    
+    def manage_editMPIWGFMConnection(self,url,username,password,REQUEST=None):
+        """change the parameters for connections"""
+        self.url=url
+        self.username=username
+        self.password=password
+        
+        REQUEST.RESPONSE.redirect(' manage_editMPIWGFMConnectionForm?rnd=%s' % ''.join(random.sample("abcdefuvwxyz", 8)))
+            
+    manage_editMPIWGFMConnectionForm = PageTemplateFile('zpt/editConnection.pt', globals())
+   
+
+def manage_addMPIWGFMManager(self, id, title, url, username=None,password=None, REQUEST=None):
+    """ create the new MPIWGManager """
+    newinst = MPIWGFMManager(id, title,url, username,password)
+    self._setObject(id, newinst)
+
+    REQUEST.RESPONSE.redirect('manage_main')
+
+manage_addMPIWGFMManagerForm = PageTemplateFile('zpt/addMPIWGManager.pt', globals())