commit 66b454b7f5a15db8e82e777cfd34f350a55a8c8d
Author: Kostas Papadimitriou <kpap@grnet.gr>
Date:   Mon Dec 9 14:36:16 2013 +0200

    ui: Additional Pithos versioninfo.xml client type

diff --git a/cloudcms/clients.py b/cloudcms/clients.py
index 004cf28..53f960e 100644
--- a/cloudcms/clients.py
+++ b/cloudcms/clients.py
@@ -10,7 +10,7 @@ import urllib, urllib2, cookielib, urlparse
 from datetime import datetime
 from lxml import html
 
-from synnefo import settings
+from django.conf import settings
 
 CLIENTS_CACHE_TIMEOUT = getattr(settings, 'CLOUDCMS_CLIENTS_CACHE_TIMEOUT', 120)
 
@@ -170,10 +170,50 @@ class ClientVersions(object):
             yield source.get_latest()
 
 
+
+class PithosXMLSource(VersionSource):
+    """
+    Extract version from versioninfo.xml
+    """
+    source_type = 'pithos_xml'
+
+    def load(self):
+        """
+        Extract first item from versioninfo.xml
+        """
+        spliturl = urlparse.urlsplit(self.link)
+        baseurl = spliturl.geturl().replace(spliturl.path, '')
+        html = self.get_url(self.link)
+        items = html.xpath("//item")
+
+        # helper lambdas
+        def _parse_row(row):
+            try:
+                name = row.find("title").text
+                link = row.find("enclosure").attrib["url"]
+                strdate = row.find("pubdate").text
+                date = datetime.strptime(strdate.split(" +")[0],
+                                         "%a, %d %B %Y %H:%M:%S")
+                print "DATE", date
+                version = row.find("title").text
+                return {
+                    'name': name,
+                    'link': link,
+                    'date': date,
+                    'version': version
+                }
+            except Exception, e:
+                return None
+
+        versions = filter(bool, map(_parse_row, items))
+        self.versions = versions
+        return self
+
+
 # SOURCE TYPES CLASS MAP
 SOURCE_TYPES = {
     'redmine_files': RedmineSource,
     'direct': DirectSource,
+    'pithos_xml': PithosXMLSource,
     'link': LinkSource
 }
-
diff --git a/cloudcms/models.py b/cloudcms/models.py
index d17cb9f..0ea46a6 100644
--- a/cloudcms/models.py
+++ b/cloudcms/models.py
@@ -63,7 +63,7 @@ class Application(models.Model):
         ('warning','Warning'),
         ('info','Info'),
     )
- 
+
 
     code = models.CharField('Identifier', max_length=100, null=False, blank=False,
             help_text="Just a codename of the application, to be used in "\
@@ -92,11 +92,11 @@ class Application(models.Model):
     footer_top = models.TextField(default="", blank=True)
     footer_bottom = models.TextField(default="", blank=True)
 
-    message_type = models.CharField(max_length=20, 
+    message_type = models.CharField(max_length=20,
                                     choices= MESSAGE_TYPE_CHOICES,
                                     default = 'NM' )
     custom_message = models.TextField(default="", blank=True)
-    
+
     @classmethod
     def current(cls):
         return cls.objects.get(site__pk=settings.SITE_ID)
@@ -149,6 +149,7 @@ class ClientVersionSource(models.Model):
     source_type = models.CharField(max_length=60,
             choices=(('link','Link'),
                      ('direct','Direct'),
+                     ('pithos_xml','Pithos XML'),
                      ('redmine_files','Redmine files')))
     os = models.CharField(max_length=255)
     link = models.CharField(max_length=255)
@@ -179,8 +180,8 @@ class Service(models.Model, translations.TranslatedObjectMixin):
     image_faq = MediaFileForeignKey(MediaFile, blank=True, null=True, related_name='image_faq')
     image_userguide = MediaFileForeignKey(MediaFile, blank=True, null=True,related_name='image_userguide')
     class_name = models.CharField(_('class name'), max_length=100, blank=True)
-    
-    
+
+
     class Meta:
         verbose_name = _('service')
         verbose_name_plural = _('services')
@@ -193,13 +194,13 @@ class Service(models.Model, translations.TranslatedObjectMixin):
             return self.faqs.filter(is_active=True)[0]
         except:
             return None
-        
+
     def get_first_entry(self):
         try:
             return self.userguideentries.filter(is_active=True)[0]
         except:
             return None
-        
+
     def __unicode__(self):
         trans = translations.TranslatedObjectMixin.__unicode__(self)
         return trans or _('Unnamed category')
@@ -215,7 +216,7 @@ class ServiceTranslation(translations.Translation(Service)):
     cms_page = models.ForeignKey(Page, null=True, blank=True)
     title_faq = models.CharField(_('service title (faq section)'), max_length=100, blank=True)
     title_userguide = models.CharField(_('service title (userguide section)'), max_length=100, blank=True)
-    
+
     class Meta:
         verbose_name = _('service translation')
         verbose_name_plural = _('service translations')
