summaryrefslogtreecommitdiff
path: root/chimere/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'chimere/models.py')
-rw-r--r--chimere/models.py169
1 files changed, 158 insertions, 11 deletions
diff --git a/chimere/models.py b/chimere/models.py
index 827a0e7..c393cba 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,21 @@ class SubCategory(models.Model):
available = models.BooleanField(_(u"Available"), default=True)
submission = models.BooleanField(_(u"Available for submission"),
default=True)
- icon = models.ForeignKey(Icon, verbose_name=_(u"Icon"))
- color_theme = models.ForeignKey(ColorTheme, verbose_name=_(u"Color theme"),
- blank=True, null=True)
- order = models.IntegerField(_(u"Order"), default=1000)
TYPE = (('M', _(u'Marker')),
('R', _(u'Route')),
('B', _(u'Both')),)
item_type = models.CharField(_(u"Item type"), max_length=1, choices=TYPE)
+ dated = models.BooleanField(_(u"Is dated"), default=False)
+ description = models.TextField(blank=True, null=True)
+ 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)
+ as_layer = models.BooleanField(_(u"Displayed in the layer menu"),
+ default=False)
+ routing_warn = models.BooleanField(_(u"Routing warn"), default=False)
+ order = models.IntegerField(_(u"Order"), default=1000)
def __unicode__(self):
return u"%s / %s" % (self.category.name, self.name)
class Meta:
@@ -207,6 +271,32 @@ 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 getJSONDict(self):
+ items = {'id':self.pk, 'name':self.name,
+ 'description':self.description if self.description\
+ else '',
+ 'icon':{'url':self.icon.image.url,
+ 'width':self.icon.image.width,
+ 'height':self.icon.image.height}
+ }
+ if self.hover_icon:
+ items['icon_hover'] = {'url':self.hover_icon.image.url}
+ return items
+
+ def getJSON(self, categories_id=[]):
+ '''Return a JSON string - mainly used to get description
+ '''
+ json_string = json.dumps(self.getJSONDict())
+ return json_string
+
IMPORTERS = {'KML':KMLManager,
'OSM':OSMManager,
'SHP':ShapefileManager,
@@ -338,6 +428,10 @@ class GeographicItem(models.Model):
def properties(cls):
return [pm for pm in PropertyModel.objects.filter(available=True)]
+ @classmethod
+ def all_properties(cls):
+ return [pm for pm in PropertyModel.objects.all()]
+
def property_setter(cls, propertymodel):
def setter(self, value):
marker = self
@@ -360,6 +454,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):
@@ -368,7 +464,7 @@ class Marker(GeographicItem):
def __init__(self, *args, **kwargs):
super(Marker, self).__init__(*args, **kwargs)
# add read attributes for properties
- for pm in self.properties():
+ for pm in self.all_properties():
attr_name = pm.getAttrName()
if not hasattr(self, attr_name):
val = ''
@@ -412,6 +508,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
@@ -467,6 +567,18 @@ class Marker(GeographicItem):
if len(properties) > 1:
for property in properties[1:]:
property.delete()
+ if pm.type == 'C' and value:
+ try:
+ value = str(int(value))
+ except ValueError:
+ choice = PropertyModelChoice.objects.filter(propertymodel=pm,
+ value=value)
+ if choice.count():
+ value = choice.all()[0].pk
+ else:
+ choice = PropertyModelChoice.objects.create(value=value,
+ propertymodel=pm)
+ value = choice.pk
# new property
if not properties:
new_property = Property.objects.create(marker=self,
@@ -498,12 +610,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
@@ -1337,11 +1455,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
@@ -1359,6 +1481,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
'''
@@ -1367,7 +1502,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")
@@ -1378,6 +1520,11 @@ class Property(models.Model):
return datetime.date(*[int(val) for val in self.value.split('-')])
except:
return ""
+ if self.propertymodel.type == 'C' and self.value:
+ try:
+ return PropertyModelChoice.objects.get(pk=self.value)
+ except self.DoesNotExist:
+ return None
else:
return self.value