Merge branch 'feature-newstyles' into develop
[snf-cloudcms] / cloudcms / models.py
index 00c514f..d17cb9f 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
+import datetime
 
 from django.db import models
 from django.conf import settings
 from django.contrib.sites import models as sites_models
+from django.utils.translation import ugettext_lazy as _, ugettext, ungettext
+from django.core.cache import cache
+from django.utils import simplejson
 
+from feincms import translations
 from feincms.module.medialibrary.fields import MediaFileForeignKey
 from feincms.module.medialibrary.models import MediaFile
 
 
 class Application(models.Model):
+    """
+    Application object refers to the application each cms is deployed for.
+
+    Each cms deployment should contain at least one application object linked
+    to the site object the cms is deployed for.
+
+    Enabling cloudcms.context_processors.application in CONTEXT_PROCESSROS setting
+    let you can access the application object throughout the html templates.
+    """
+
+    MESSAGE_TYPE_CHOICES = (
+        ('NM','No Message'),
+        ('success','Success'),
+        ('error','Error'),
+        ('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 "\
                     "several places where no free text is allowed"\
@@ -49,9 +73,13 @@ class Application(models.Model):
             help_text="The title of the application")
 
     logo = MediaFileForeignKey(MediaFile, blank=True, null=True)
+    favicon = MediaFileForeignKey(MediaFile, blank=True, null=True,
+            related_name="as_favicon")
     site = models.ForeignKey(sites_models.Site)
     app_url = models.URLField(help_text="The url of the application UI (not "\
-            "the cms", verify_exists=False, blank=True, null=True)
+            "the cms)", verify_exists=False, blank=True, null=True)
+    accounts_url = models.CharField(max_length=255, default="/", blank=True,
+            null=True, help_text="Tha accounts login page")
     index_url = models.CharField(max_length=255, default="/", blank=False,
             null=False)
     linked_in_username = models.CharField(max_length=255, blank=True)
@@ -64,6 +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, 
+                                    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)
@@ -71,6 +104,129 @@ class Application(models.Model):
     def __unicode__(self):
         return self.title
 
+
+# http://stackoverflow.com/a/2680060/114435
+dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.datetime) else None
+
+class Client(models.Model):
+    """
+    Model which refers to a service/application client. Client model contains
+    multiple ClientVersionSource to identify it's version downloads.
+    """
+    uid = models.CharField(max_length=255)
+    name = models.CharField(max_length=255)
+
+    def get_sources(self):
+        sources = {}
+        from cloudcms.clients import ClientVersions
+        for s in self.clientversionsource_set.all():
+            sources[s.os] = {'type': s.source_type,
+                             'args': [s.link]}
+
+        return ClientVersions(sources, cache_backend=cache)
+
+    def to_json(self):
+        return simplejson.dumps(list(self.get_sources().get_latest_versions()),
+                default=dthandler)
+
+    def get_default_os(self):
+        try:
+            return self.clientversionsource_set.filter(default=True)[0].os
+        except IndexError:
+            return self.clientversionsource_set.filter()[0].os
+
+    def __unicode__(self):
+        return self.name
+
+
+class ClientVersionSource(models.Model):
+    """
+    Client version source. source_type choices should map to
+    cloudcms.clients.SOURCE_TYPES.
+    """
+
+    default = models.BooleanField(default=True)
+    source_type = models.CharField(max_length=60,
+            choices=(('link','Link'),
+                     ('direct','Direct'),
+                     ('redmine_files','Redmine files')))
+    os = models.CharField(max_length=255)
+    link = models.CharField(max_length=255)
+    logo = MediaFileForeignKey(MediaFile, blank=True, null=True)
+    architecture = models.CharField(max_length=255, null=True, blank=True,
+            help_text="""Depending the source type this can be left empty and
+            let source type identify the architecture""")
+    client = models.ForeignKey(Client)
+    version_regex = models.CharField(max_length=255, help_text="""Regular expression to
+            match the version of the file based on retrieved source filenames
+            (used in redmine source types)""", null=True, blank=True)
+    file_regex = models.CharField(max_length=255, help_text="""Return only files that
+            match this expression""", null=True, blank=True)
+
+    def __unicode__(self):
+        return "[%s] %s" % (self.get_source_type_display(), self.os)
+
+
 # hook for feincms configuration, is this appropriate place ??? who knows
 from cloudcms.cms import *
 
+class Service(models.Model, translations.TranslatedObjectMixin):
+    """
+    Service.
+    """
+
+    ordering = models.SmallIntegerField(_('ordering'), default=0)
+    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')
+        ordering = ['-ordering',]
+
+    objects = translations.TranslatedObjectManager()
+
+    def get_first_question(self):
+        try:
+            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')
+
+
+class ServiceTranslation(translations.Translation(Service)):
+    """
+    Service translation
+    """
+    title = models.CharField(_('service title'), max_length=100)
+    slug = models.SlugField(_('slug'), unique=True)
+    description = models.CharField(_('description'), max_length=250, blank=True)
+    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')
+        ordering = ['title']
+
+    def __unicode__(self):
+        return self.title
+
+    def save(self, *args, **kwargs):
+        if not self.slug:
+            self.slug = slugify(self.title)
+
+        super(ServiceTranslation, self).save(*args, **kwargs)
+