summaryrefslogtreecommitdiff
path: root/chimere/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'chimere/models.py')
-rw-r--r--chimere/models.py153
1 files changed, 144 insertions, 9 deletions
diff --git a/chimere/models.py b/chimere/models.py
index c3a5f6e..357a32a 100644
--- a/chimere/models.py
+++ b/chimere/models.py
@@ -25,6 +25,8 @@ import simplejson as json
from lxml import etree
from PIL import Image
from subprocess import Popen, PIPE
+from BeautifulSoup import BeautifulSoup
+
from django import forms
from django.conf import settings
from django.contrib import admin
@@ -45,13 +47,64 @@ from chimere.managers import BaseGeoManager
from chimere.utils import KMLManager, OSMManager, ShapefileManager, \
GeoRSSManager, CSVManager
+class Page(models.Model):
+ """Simple extra pages
+ """
+ title = models.CharField(_(u"Name"), max_length=150)
+ mnemonic = models.CharField(_(u"Mnemonic"), max_length=10, blank=True,
+ null=True)
+ available = models.BooleanField(_(u"Available"), default=True)
+ order = models.IntegerField(_(u"Order"), default=10, blank=True, null=True)
+ template_path = models.CharField(_(u"Template path"), max_length=150,
+ blank=True, null=True)
+ content = models.TextField(blank=True, null=True)
+ def __unicode__(self):
+ ordering = ["order"]
+ return self.title
+ class Meta:
+ verbose_name = _(u"Page")
+ verbose_name_plural = _(u"Page")
+
+def page_post_save(sender, **kwargs):
+ if not kwargs['instance']:
+ return
+ page = kwargs['instance']
+ if not page.mnemonic:
+ page.mnemonic = defaultfilters.slugify(page.title)
+ page.save()
+post_save.connect(page_post_save, sender=Page)
+
+def shortify(text):
+ if not text:
+ return ''
+ if len(text) <= settings.CHIMERE_SHORT_DESC_LENGTH:
+ return text
+ desc = text[:settings.CHIMERE_SHORT_DESC_LENGTH]
+ short_desc = ""
+ # find a correct opportunity to cut
+ for idx, c in enumerate(reversed(desc)):
+ if c == '>':
+ break
+ if c == '<':
+ short_desc = desc[:-(idx+1)]
+ break
+ if not short_desc:
+ for idx, c in enumerate(reversed(desc)):
+ if c == ' ' or c == '\n':
+ short_desc = desc[:-(idx+1)]
+ break
+ return BeautifulSoup(short_desc).prettify()
+
class News(models.Model):
"""News of the site
"""
title = models.CharField(_(u"Name"), max_length=150)
available = models.BooleanField(_(u"Available"))
+ is_front_page = models.NullBooleanField(_(u"Is front page"), blank=True,
+ null=True)
date = models.DateField(_(u"Date"), auto_now_add=True)
content = models.TextField()
+ url = models.URLField(_(u"Url"), max_length=200, blank=True, null=True)
areas = SelectMultipleField('Area', verbose_name=_(u"Associated areas"),
blank=True, null=True)
def __unicode__(self):
@@ -61,6 +114,10 @@ class News(models.Model):
verbose_name = _(u"News")
verbose_name_plural = _(u"News")
+ @property
+ def short_desc(self):
+ return shortify(self.content)
+
class TinyUrl(models.Model):
"""Tinyfied version of permalink parameters
"""
@@ -156,14 +213,20 @@ class SubCategory(models.Model):
available = models.BooleanField(_(u"Available"), default=True)
submission = models.BooleanField(_(u"Available for submission"),
default=True)
+ as_layer = models.BooleanField(_(u"Displayed in the layer menu"),
+ default=False)
icon = models.ForeignKey(Icon, verbose_name=_(u"Icon"))
+ hover_icon = models.ForeignKey(Icon, verbose_name=_(u"Hover icon"),
+ blank=True, null=True, related_name='subcat_hovered')
color_theme = models.ForeignKey(ColorTheme, verbose_name=_(u"Color theme"),
blank=True, null=True)
order = models.IntegerField(_(u"Order"), default=1000)
+ dated = models.BooleanField(_(u"Is dated"), default=False)
TYPE = (('M', _(u'Marker')),
('R', _(u'Route')),
('B', _(u'Both')),)
item_type = models.CharField(_(u"Item type"), max_length=1, choices=TYPE)
+ description = models.TextField(blank=True, null=True)
def __unicode__(self):
return u"%s / %s" % (self.category.name, self.name)
class Meta:
@@ -207,6 +270,24 @@ class SubCategory(models.Model):
subcategories = sorted(subcategories, key=get_cat_order)
return subcategories
+ @classmethod
+ def getAvailableTuples(cls, area_name=None):
+ cats = []
+ for cat, subcats in cls.getAvailable(area_name=area_name):
+ cats.append((unicode(cat),
+ [(subcat.pk, subcat.name) for subcat in subcats]))
+ return cats
+
+ def getJSON(self, categories_id=[]):
+ '''Return a JSON string - mainly used to get description
+ '''
+ items = {'id':self.pk, 'name':json.dumps(self.name),
+ 'description':json.dumps(self.description) if self.description\
+ else ''}
+ json_string = u'{"pk": %(id)d, "name": %(name)s, '\
+ u'"description":%(description)s}' % items
+ return json_string
+
IMPORTERS = {'KML':KMLManager,
'OSM':OSMManager,
'SHP':ShapefileManager,
@@ -359,6 +440,8 @@ class Marker(GeographicItem):
route = models.ForeignKey(u"Route", blank=True, null=True,
related_name='associated_marker')
description = models.TextField(_(u"Description"), blank=True, null=True)
+ is_front_page = models.NullBooleanField(_(u"Is front page"), blank=True,
+ null=True)
objects = models.GeoManager()
def __unicode__(self):
@@ -411,6 +494,10 @@ class Marker(GeographicItem):
return self.start_date
@property
+ def short_desc(self):
+ return shortify(self.description)
+
+ @property
def geometry(self):
return self.point.wkt
@@ -493,12 +580,18 @@ class Marker(GeographicItem):
items = {'id':self.id, 'name':json.dumps(self.name),
'geometry':self.point.geojson,
'icon_path':cat.icon.image,
+ 'icon_hover_path':cat.hover_icon.image \
+ if cat.hover_icon else '',
'icon_width':cat.icon.image.width,
- 'icon_height':cat.icon.image.height,}
+ 'icon_height':cat.icon.image.height,
+ 'category_name':json.dumps(cat.name)}
jsons.append(u'{"type":"Feature", "geometry":%(geometry)s, '\
u'"properties":{"pk": %(id)d, "name": %(name)s, '\
- u'"icon_path":"%(icon_path)s", "icon_width":%(icon_width)d, '\
- u'"icon_height":%(icon_height)d}}' % items)
+ u'"icon_path":"%(icon_path)s", '\
+ u'"icon_hover_path":"%(icon_hover_path)s", '\
+ u'"icon_width":%(icon_width)d, '\
+ u'"icon_height":%(icon_height)d, '\
+ u'"category_name":%(category_name)s}}' % items)
return ",".join(jsons)
@property
@@ -603,17 +696,30 @@ IFRAME_LINKS = {
'youtube':((re.compile(r'youtube.com\/watch\?v=([A-Za-z0-9_-]*)'),
re.compile(r'youtu.be\/([A-Za-z0-9_-]*)'),
re.compile(r'youtube.com\/embed\/([A-Za-z0-9_-]*)')),
- "http://www.youtube.com/embed/%s"),
+ "http://www.youtube.com/embed/%s"),
'dailymotion':(
(re.compile(r'dailymotion.com/video/([A-Za-z0-9]*)_[A-Za-z0-9_-]*'),
re.compile(r'dailymotion.com/embed/video/([A-Za-z0-9]*)'),
re.compile("http://www.dailymotion.com/embed/video/%s")),
- 'http://www.dailymotion.com/embed/video/%s'),
+ 'http://www.dailymotion.com/embed/video/%s'),
'vimeo':((re.compile(r'vimeo.com/([A-Za-z0-9]*)'),
re.compile(r'vimeo.com/video/([A-Za-z0-9]*)')),
- "http://player.vimeo.com/video/%s")
+ "http://player.vimeo.com/video/%s")
}
+class MultimediaExtension(models.Model):
+ name = models.CharField(_(u"Extension name"), max_length=6)
+ multimedia_type = models.ForeignKey(MultimediaType,
+ verbose_name=_(u"Associated multimedia type"),
+ related_name='extensions')
+
+ class Meta:
+ verbose_name = _(u"Multimedia extension")
+ verbose_name_plural = _(u"Multimedia extensions")
+
+ def __unicode__(self):
+ return self.name
+
class MultimediaFile(models.Model):
name = models.CharField(_(u"Name"), max_length=150)
url = models.URLField(_(u"Url"), max_length=200)
@@ -1286,11 +1392,15 @@ class PropertyModel(models.Model):
TYPE = (('T', _('Text')),
('L', _('Long text')),
('P', _('Password')),
- ('D', _("Date")))
+ ('D', _("Date")),
+ ('C', _("Choices")),
+ )
TYPE_WIDGET = {'T':forms.TextInput,
'L':TextareaWidget,
'P':forms.PasswordInput,
- 'D':DatePickerWidget}
+ 'D':DatePickerWidget,
+ 'C':forms.Select
+ }
type = models.CharField(_(u"Type"), max_length=1, choices=TYPE)
def __unicode__(self):
return self.name
@@ -1308,6 +1418,19 @@ class PropertyModel(models.Model):
'''
return 'property_%d_%d' % (self.order, self.id)
+class PropertyModelChoice(models.Model):
+ '''Choices for property model
+ '''
+ propertymodel = models.ForeignKey(PropertyModel, related_name='choices',
+ verbose_name=_(u"Property model"))
+ value = models.CharField(_(u"Value"), max_length=150)
+ available = models.BooleanField(_(u"Available"), default=True)
+ def __unicode__(self):
+ return unicode(self.value)
+
+ class Meta:
+ verbose_name = _(u"Model property choice")
+
class Property(models.Model):
'''Property for a POI
'''
@@ -1316,7 +1439,14 @@ class Property(models.Model):
verbose_name=_(u"Property model"))
value = models.TextField(_(u"Value"))
def __unicode__(self):
- return "%s : %s" % (str(self.propertymodel), self.value)
+ if self.propertymodel.type == 'C':
+ try:
+ return unicode(PropertyModelChoice.objects.get(
+ pk=self.value).value)
+ except self.DoesNotExist:
+ return ""
+ return unicode(self.value)
+
class Meta:
verbose_name = _(u"Property")
@@ -1327,6 +1457,11 @@ class Property(models.Model):
return datetime.date(*[int(val) for val in self.value.split('-')])
except:
return ""
+ if self.propertymodel.type == 'C':
+ try:
+ return PropertyModelChoice.objects.get(pk=self.value)
+ except self.DoesNotExist:
+ return None
else:
return self.value