summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authoretienne <etienne@9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864>2010-02-21 15:42:51 +0000
committeretienne <etienne@9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864>2010-02-21 15:42:51 +0000
commitf7fd3f884d4b1571efa122ddab2c7d4d0b925518 (patch)
tree232b18d00a5ad11eb3b323cb4d81afb574e92e2b /main
parent9e253135138cf65e766959c094ad1182902bd363 (diff)
downloadChimère-f7fd3f884d4b1571efa122ddab2c7d4d0b925518.tar.bz2
Chimère-f7fd3f884d4b1571efa122ddab2c7d4d0b925518.zip
Reorganize the project folder #76
git-svn-id: http://www.peacefrogs.net/svn/chimere/trunk@59 9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864
Diffstat (limited to 'main')
-rw-r--r--main/__init__.py0
-rw-r--r--main/actions.py38
-rw-r--r--main/admin.py91
-rw-r--r--main/forms.py253
-rw-r--r--main/models.py325
-rw-r--r--main/views.py260
-rw-r--r--main/widgets.py292
7 files changed, 0 insertions, 1259 deletions
diff --git a/main/__init__.py b/main/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/main/__init__.py
+++ /dev/null
diff --git a/main/actions.py b/main/actions.py
deleted file mode 100644
index 74b622a..0000000
--- a/main/actions.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# See the file COPYING for details.
-
-"""
-Actions available in the main interface
-"""
-from django.utils.translation import ugettext_lazy as _
-from django.contrib.auth import models
-
-from chimere.settings import EXTRA_URL
-
-class Action:
- def __init__(self, id, path, label):
- self.id, self.path, self.label = id, EXTRA_URL + path, label
-
-actions = ((Action('view', '', _('View')), []),
- (Action('contribute', 'edit', _('Contribute')),
- (Action('edit', 'edit', _('Add a new point of interest')),
- Action('edit_route', 'edit_route', _('Add a new route')))
- ),
- (Action('contact', 'contact', _('Contact us')), []),
- )
diff --git a/main/admin.py b/main/admin.py
deleted file mode 100644
index 195e7c4..0000000
--- a/main/admin.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# See the file COPYING for details.
-
-"""
-Settings for administration pages
-"""
-
-from chimere.main.models import Category, Icon, SubCategory, Marker, \
- PropertyModel, News, Route, Area, ColorTheme, Color
-from chimere.main.forms import MarkerAdminForm, RouteAdminForm, AreaAdminForm,\
- NewsAdminForm, CategoryAdminForm
-from chimere.main.widgets import TextareaWidget
-
-from django.contrib import admin
-
-class MarkerAdmin(admin.ModelAdmin):
- """
- Specialized the Point field.
- """
- search_fields = ("name",)
- list_display = ('name', 'subcategory', 'status')
- list_filter = ('status', 'subcategory')
- form = MarkerAdminForm
-
-class RouteAdmin(admin.ModelAdmin):
- """
- Specialized the Route field.
- """
- search_fields = ("name",)
- list_display = ('name', 'subcategory', 'status')
- list_filter = ('status', 'subcategory')
- form = RouteAdminForm
-
-class AreaAdmin(admin.ModelAdmin):
- """
- Specialized the area field.
- """
- form = AreaAdminForm
- exclude = ['upper_left_corner', 'lower_right_corner']
-
-class SubCategoryAdmin(admin.ModelAdmin):
- """
- Specialized the subcategory admin
- """
- list_display = ('name', 'category', 'available')
- list_filter = ('category',)
-
-class NewsAdmin(admin.ModelAdmin):
- """
- Use the TinyMCE widget for the news content
- """
- form = NewsAdminForm
-
-class CategoryAdmin(admin.ModelAdmin):
- """
- Use the TinyMCE widget for categories
- """
- form = CategoryAdminForm
-
-class ColorInline(admin.TabularInline):
- model = Color
-
-class ColorThemeAdmin(admin.ModelAdmin):
- inlines = [ColorInline,]
-
-# register of differents database fields
-admin.site.register(News, NewsAdmin)
-admin.site.register(Category, CategoryAdmin)
-admin.site.register(Icon)
-admin.site.register(SubCategory, SubCategoryAdmin)
-admin.site.register(Marker, MarkerAdmin)
-admin.site.register(Route, RouteAdmin)
-admin.site.register(PropertyModel)
-admin.site.register(Area, AreaAdmin)
-admin.site.register(ColorTheme, ColorThemeAdmin)
diff --git a/main/forms.py b/main/forms.py
deleted file mode 100644
index be18b2f..0000000
--- a/main/forms.py
+++ /dev/null
@@ -1,253 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# See the file COPYING for details.
-
-"""
-Forms
-"""
-from django import forms
-from django.contrib.gis.db import models
-from django.utils.translation import ugettext as _
-from django.contrib.auth.models import User
-from django.core.mail import EmailMessage, BadHeaderError
-
-from chimere import settings
-
-from chimere.main.models import Marker, Route, PropertyModel, Property, Area,\
- News, Category
-from chimere.main.widgets import AreaField, PointField, TextareaWidget
-
-def notifyStaff(subject, body, sender=None):
- if settings.PROJECT_NAME:
- subject = u'[%s] %s' % (settings.PROJECT_NAME, subject)
- user_list = [u.email for u in
- User.objects.filter(is_staff=True).exclude(email="").order_by('id')]
- headers = {}
- if sender:
- headers['Reply-To'] = sender
- email = EmailMessage(subject, body, user_list[0], user_list,
- headers=headers)
- try:
- email.send()
- except BadHeaderError:
- return False
- return True
-
-def notifySubmission(geo_object):
- category = unicode(geo_object.subcategory)
- subject = u'%s %s' % (_(u"New submission for"), category)
- message = _(u'The new item "%s" has been submited in the category: ') % \
- geo_object.name + category
- message += "\n\n" + _(u"To valid, precise or unvalid this item: ")
- message += settings.BASE_URL + 'admin'
- message += u"\n\n--\nChimère"
- return notifyStaff(subject, message)
-
-class ContactForm(forms.Form):
- """
- Main form for categories
- """
- email = forms.EmailField(label=_("Email (optional)"), required=False)
- content = forms.CharField(label=_("Object"), widget=forms.Textarea)
-
-class NewsAdminForm(forms.ModelForm):
- """
- Main form for news
- """
- content = forms.CharField(widget=TextareaWidget)
- class Meta:
- model = News
-
-class CategoryAdminForm(forms.ModelForm):
- """
- Main form for categories
- """
- description = forms.CharField(widget=TextareaWidget, required=False)
- class Meta:
- model = Category
-
-class MarkerAdminForm(forms.ModelForm):
- """
- Main form for marker
- """
- # declare properties
- for property in PropertyModel.objects.filter(available=True):
- exec('property_%d_%d = forms.CharField(label="%s", widget=%s, \
-required=False)' % (property.order, property.id, property.name,
- PropertyModel.TYPE_WIDGET[property.type]))
- class Meta:
- model = Marker
-
- def __init__(self, *args, **keys):
- """
- Custom initialization method in order to manage properties
- """
- if 'instance' in keys and keys['instance']:
- instance = keys['instance']
- property_dct = {}
- for pm in PropertyModel.objects.filter(available=True):
- property = instance.getProperty(pm)
- if property:
- property_dct[pm.getNamedId()] = property.value
- if 'initial' in keys:
- keys['initial'].update(property_dct)
- else:
- keys['initial'] = property_dct
- super(MarkerAdminForm, self).__init__(*args, **keys)
-
- def save(self, *args, **keys):
- """
- Custom save method in order to manage associeted properties
- """
- new_marker = super(MarkerAdminForm, self).save(*args, **keys)
- if 'status' not in self.cleaned_data:
- new_marker.status = 'S'
- new_marker.save()
- # save each property
- for propertymodel in PropertyModel.objects.filter(available=True):
- properties = Property.objects.filter(marker=new_marker,
- propertymodel=propertymodel)
- # new property
- if not properties:
- new_property = Property.objects.create(marker=new_marker,
- propertymodel=propertymodel,
- value=self.cleaned_data['property_%d_%d' % (
- propertymodel.order, propertymodel.id)])
- new_property.save()
- else:
- # in case of multiple edition as the same time delete arbitrary
- # the others
- if len(properties) > 1:
- for property in properties[1:]:
- property.delete()
- property = properties[0]
- property.value = self.cleaned_data['property_%d_%d' % (
- propertymodel.order, propertymodel.id)]
- property.save()
- return new_marker
-
-class MarkerForm(MarkerAdminForm):
- """
- Form for the edit page
- """
- class Meta:
- model = Marker
- exclude = ('status',)
-
-class RouteAdminForm(forms.ModelForm):
- """
- Main form for route
- """
- """
- # declare properties
- for property in PropertyModel.objects.filter(available=True):
- exec('property_%d_%d = forms.CharField(label="%s", widget=%s, \
-required=False)' % (property.order, property.id, property.name,
- PropertyModel.TYPE_WIDGET[property.type]))"""
- class Meta:
- model = Route
-
- def __init__(self, *args, **keys):
- """
- Custom initialization method in order to manage properties
- """
- if 'instance' in keys and keys['instance']:
- instance = keys['instance']
- property_dct = {}
- for pm in PropertyModel.objects.filter(available=True):
- property = instance.getProperty(pm)
- if property:
- property_dct[pm.getNamedId()] = property.value
- if 'initial' in keys:
- keys['initial'].update(property_dct)
- else:
- keys['initial'] = property_dct
- super(RouteAdminForm, self).__init__(*args, **keys)
-
- def save(self, *args, **keys):
- """
- Custom save method in order to manage associeted properties
- """
- new_marker = super(RouteAdminForm, self).save(*args, **keys)
- if 'status' not in self.cleaned_data:
- new_marker.status = 'S'
- new_marker.save()
- """
- # save each property
- for propertymodel in PropertyModel.objects.filter(available=True):
- properties = Property.objects.filter(marker=new_marker,
- propertymodel=propertymodel)
- # new property
- if not properties:
- new_property = Property.objects.create(marker=new_marker,
- propertymodel=propertymodel,
- value=self.cleaned_data['property_%d_%d' % (
- propertymodel.order, propertymodel.id)])
- new_property.save()
- else:
- # in case of multiple edition as the same time delete arbitrary
- # the others
- if len(properties) > 1:
- for property in properties[1:]:
- property.delete()
- property = properties[0]
- property.value = self.cleaned_data['property_%d_%d' % (
- propertymodel.order, propertymodel.id)]
- property.save()"""
- return new_marker
-
-class RouteForm(RouteAdminForm):
- """
- Form for the edit page
- """
- class Meta:
- model = Route
- exclude = ('status',)
-
-class AreaAdminForm(forms.ModelForm):
- """
- Admin page to create an area
- """
- area = AreaField(label=_("Area"), fields=(PointField(), PointField()))
- class Meta:
- model = Area
-
- def __init__(self, *args, **keys):
- """
- Custom initialization method in order to manage area
- """
- if 'instance' in keys and keys['instance']:
- instance = keys['instance']
- dct = {'area':(instance.upper_left_corner,
- instance.lower_right_corner)}
- if 'initial' in keys:
- keys['initial'].update(dct)
- else:
- keys['initial'] = dct
- super(AreaAdminForm, self).__init__(*args, **keys)
-
- def save(self, *args, **keys):
- """
- Custom save method in order to manage area
- """
- new_area = super(AreaAdminForm, self).save(*args, **keys)
- area = self.cleaned_data['area']
- new_area.upper_left_corner = 'POINT(%s %s)' % (area[0][0], area[0][1])
- new_area.lower_right_corner = 'POINT(%s %s)' % (area[1][0],
- area[1][1])
- return new_area
diff --git a/main/models.py b/main/models.py
deleted file mode 100644
index 14f3481..0000000
--- a/main/models.py
+++ /dev/null
@@ -1,325 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# See the file COPYING for details.
-
-"""
-Models description
-"""
-from django.utils.translation import ugettext_lazy as _
-
-from django.contrib.gis.db import models
-from django.contrib import admin
-
-from chimere import settings
-from chimere.main.widgets import PointField, RouteField
-
-
-class News(models.Model):
- """News of the site
- """
- title = models.CharField(_("Name"), max_length=150)
- available = models.BooleanField(_("Available"))
- date = models.DateField(_("Date"), auto_now_add=True)
- content = models.TextField()
- def __unicode__(self):
- ordering = ["-date"]
- return self.title
- class Meta:
- verbose_name = _("News")
-
-class ColorTheme(models.Model):
- """Color theme
- """
- name = models.CharField(_("Name"), max_length=150)
- def __unicode__(self):
- return self.name
- class Meta:
- verbose_name = _("Color theme")
-
-class Color(models.Model):
- """Color
- """
- code = models.CharField(_("Code"), max_length=6)
- order = models.IntegerField(_("Order"))
- color_theme = models.ForeignKey(ColorTheme, verbose_name=_("Color theme"))
- def __unicode__(self):
- return self.code
- class Meta:
- ordering = ["order"]
- verbose_name = _("Color")
-
-class Category(models.Model):
- """Category of Point Of Interest (POI)
- """
- name = models.CharField(_("Name"), max_length=150)
- available = models.BooleanField(_("Available"))
- order = models.IntegerField(_("Order"))
- description = models.TextField(blank=True, null=True)
- def __unicode__(self):
- return self.name
- class Meta:
- ordering = ["order"]
- verbose_name = _("Category")
-
-class Icon(models.Model):
- '''Icon
- '''
- name = models.CharField(_("Name"), max_length=150)
- image = models.ImageField(_("Image"), upload_to='icons',
- height_field='height', width_field='width')
- def __unicode__(self):
- return self.name
- class Meta:
- verbose_name = _("Icon")
-
-class SubCategory(models.Model):
- '''Sub-category
- '''
- category = models.ForeignKey(Category, verbose_name=_("Category"))
- name = models.CharField(_("Name"), max_length=150)
- available = models.BooleanField(_("Available"))
- icon = models.ForeignKey(Icon, verbose_name=_("Icon"))
- color_theme = models.ForeignKey(ColorTheme, verbose_name=_("Color theme"),
- blank=True, null=True)
- order = models.IntegerField(_("Order"))
- TYPE = (('M', _('Marker')),
- ('R', _('Route')),
- ('B', _('Both')),)
- item_type = models.CharField(_("Item type"), max_length=1, choices=TYPE)
- def __unicode__(self):
- return u"%s / %s" % (self.category.name, self.name)
- class Meta:
- ordering = ["category", "order"]
- verbose_name = _("Subcategory")
-
- def getAvailable(item_types=None):
- '''Get list of tuples with first the category and second the associated
- subcategories
- '''
- sub_categories = {}
- subcategories = None
- if not item_types:
- subcategories = SubCategory.objects.filter(category__available=True,
- available=True)
- else:
- subcategories = SubCategory.objects.filter(category__available=True,
- item_type__in=item_types)
- for sub_category in subcategories:
- if sub_category.category not in sub_categories:
- sub_categories[sub_category.category] = []
- sub_categories[sub_category.category].append(sub_category)
- return [(category, sub_cats) for category, sub_cats \
- in sub_categories.items()]
- getAvailable = staticmethod(getAvailable)
-
-class Marker(models.Model):
- '''Marker for a POI
- '''
- name = models.CharField(_("Name"), max_length=150)
- subcategory = models.ForeignKey(SubCategory, verbose_name=_("Subcategory"))
- point = PointField(_("Localisation"))
- picture = models.ImageField(_("Image"), upload_to='upload', blank=True,
- height_field='height', width_field='width')
- STATUS = (('S', _('Submited')),
- ('A', _('Available')),
- ('D', _('Disabled')),)
- STATUS_DCT = {}
- for key, label in STATUS:
- STATUS_DCT[key] = label
- status = models.CharField(_("Status"), max_length=1, choices=STATUS)
- objects = models.GeoManager()
-
- def __unicode__(self):
- return self.name
-
- class Meta:
- ordering = ('subcategory__category', 'subcategory', 'status', 'name')
- verbose_name = _("Point of interest")
-
- def getLatitude(self):
- '''Return the latitude
- '''
- return self.point.y
-
- def getLongitude(self):
- '''Return the longitude
- '''
- return self.point.x
-
- def getProperty(self, propertymodel, safe=None):
- """Get the property of an associated property model.
- If safe set to True, verify if the property is available
- """
- if safe and not propertymodel.available:
- return
- try:
- property = Property.objects.get(propertymodel=propertymodel,
- marker=self)
- except Property.DoesNotExist:
- return
- return property
-
- def getProperties(self):
- """Get all the property availables
- """
- properties = []
- for pm in PropertyModel.objects.filter(available=True):
- property = self.getProperty(pm)
- if property:
- properties.append(property)
- return properties
-
- def getGeoJSON(self):
- '''Return a GeoJSON string
- '''
- return """{"type":"Feature", "geometry":%(geometry)s, \
-"properties":{"pk": %(id)d, "name": "%(name)s", \
-"icon_path":"%(icon_path)s", "icon_width":%(icon_width)d, \
-"icon_height":%(icon_height)d}}""" % {'id':self.id, 'name':self.name,
-'icon_path':self.subcategory.icon.image, 'geometry':self.point.geojson,
-'icon_width':self.subcategory.icon.image.width,
-'icon_height':self.subcategory.icon.image.height,}
-
-class Route(models.Model):
- '''Route on the map
- '''
- name = models.CharField(_("Name"), max_length=150)
- subcategory = models.ForeignKey(SubCategory, verbose_name=_("Subcategory"))
- route = RouteField(_("Route"))
- picture = models.ImageField(_("Image"), upload_to='upload', blank=True,
- height_field='height', width_field='width')
- STATUS = (('S', _('Submited')),
- ('A', _('Available')),
- ('D', _('Disabled')),)
- STATUS_DCT = {}
- for key, label in STATUS:
- STATUS_DCT[key] = label
- status = models.CharField(_("Status"), max_length=1, choices=STATUS)
- objects = models.GeoManager()
-
- def __unicode__(self):
- return self.name
-
- class Meta:
- ordering = ('subcategory__category', 'subcategory', 'status', 'name')
- verbose_name = _("Route")
-
- def getLatitude(self):
- '''Return the latitude
- '''
- return self.point.y
-
- def getLongitude(self):
- '''Return the longitude
- '''
- return self.point.x
-
- def getProperty(self, propertymodel, safe=None):
- """Get the property of an associated property model.
- If safe set to True, verify if the property is available
- """
- if safe and not propertymodel.available:
- return
- try:
- property = Property.objects.get(propertymodel=propertymodel,
- marker=self)
- except Property.DoesNotExist:
- return
- return property
-
- def getProperties(self):
- """Get all the property availables
- """
- properties = []
- for pm in PropertyModel.objects.filter(available=True):
- property = self.getProperty(pm)
- if property:
- properties.append(property)
- return properties
-
- def getGeoJSON(self, color="#000"):
- '''Return a GeoJSON string
- '''
- if '#' not in color:
- color = '#' + color
- return """{"type":"Feature", "geometry":%(geometry)s, \
-"properties":{"pk": %(id)d, "name": "%(name)s", \
-"color":"%(color)s"}}""" % {'id':self.id, 'name':self.name,
-'color':color, 'geometry':self.route.geojson,}
-
-class Area(models.Model):
- """Rectangular area of the map
- """
- name = models.CharField(_("Name"), max_length=150)
- order = models.IntegerField(_("Order"))
- available = models.BooleanField(_("Available"))
- upper_left_corner = models.PointField(_("Upper left corner"),
- default='POINT(0 0)')
- lower_right_corner = models.PointField(_("Lower right corner"),
- default='POINT(0 0)')
- objects = models.GeoManager()
-
- def __unicode__(self):
- return self.name
-
- class Meta:
- ordering = ('order', 'name')
- verbose_name = _("Area")
-
- def getAvailable():
- '''Get available areas
- '''
- return Area.objects.filter(available=True)
- getAvailable = staticmethod(getAvailable)
-
-class PropertyModel(models.Model):
- '''Model for a property
- '''
- name = models.CharField(_("Name"), max_length=150)
- order = models.IntegerField(_("Order"))
- available = models.BooleanField(_("Available"))
- TYPE = (('T', _('Text')),
- ('L', _('Long text')),
- ('P', _('Password')))
- TYPE_WIDGET = {'T':'forms.TextInput',
- 'L':'TextareaWidget',
- 'P':'forms.PasswordInput'}
- type = models.CharField(_("Type"), max_length=1, choices=TYPE)
- def __unicode__(self):
- return self.name
- class Meta:
- ordering = ('order',)
- verbose_name = _("Property model")
-
- def getNamedId(self):
- '''Get the name used as named id (easily sortable)
- '''
- return 'property_%d_%d' % (self.order, self.id)
-
-class Property(models.Model):
- '''Property for a POI
- '''
- marker = models.ForeignKey(Marker, verbose_name=_("Point of interest"))
- propertymodel = models.ForeignKey(PropertyModel,
- verbose_name=_("Property model"))
- value = models.CharField(_("Value"), max_length=1000)
- def __unicode__(self):
- return "%s : %s" % (str(self.propertymodel), self.value)
- class Meta:
- verbose_name = _("Property")
-
diff --git a/main/views.py b/main/views.py
deleted file mode 100644
index 9de8f4b..0000000
--- a/main/views.py
+++ /dev/null
@@ -1,260 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (C) 2008-2010 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# See the file COPYING for details.
-
-"""
-Views of the project
-"""
-
-import datetime
-
-from django.utils.translation import ugettext as _
-from django.shortcuts import render_to_response
-from django.template import loader
-from django.http import HttpResponseRedirect, HttpResponse
-from django.core import serializers
-
-from chimere import settings
-from chimere.main.actions import actions
-from chimere.main.models import Category, SubCategory, PropertyModel, Marker, \
- Route, News, Area, Color
-
-from chimere.main.widgets import getMapJS, PointChooserWidget, \
- RouteChooserWidget, URL_OSM_JS, URL_OSM_CSS
-from chimere.main.forms import MarkerForm, RouteForm, ContactForm, \
- notifySubmission, notifyStaff
-
-def index(request):
- """
- Main page
- """
- subcategories = SubCategory.getAvailable()
- for cat, sub_cats in subcategories:
- for sub_category in sub_cats:
- if sub_category.id in settings.DEFAULT_CATEGORIES:
- sub_category.selected = True
- cat.selected= True
- extra = ""
- tab = " "*4
- for url in URL_OSM_CSS:
- extra += tab + '<link rel="stylesheet" href="%s" />' % url
- for url in URL_OSM_JS + ["%sbase.js" % settings.MEDIA_URL,
- "%smain_map.js" % settings.MEDIA_URL,]:
- extra += tab + '<script src="%s"></script>\n' % url
- extra += tab + '<script src="/' + settings.EXTRA_URL + 'jsi18n/"></script>\n'
- # show the welcome page
- today = datetime.date.today().strftime('%y-%m-%d')
- display_welcome = None
- if not 'last_visit' in request.session or \
- request.session['last_visit'] != today:
- request.session['last_visit'] = today
- display_welcome = True
- response_dct = {'actions':actions, 'action_selected':('view',),
- 'error_message':'',
- 'sub_categories':subcategories,
- 'extra_head':extra + getMapJS(),
- 'media_path':settings.MEDIA_URL,
- 'extra_url':settings.EXTRA_URL,
- 'welcome':welcome(request, display_welcome),
- 'areas':Area.getAvailable(),
- 'map_layer':settings.MAP_LAYER
- }
- # manage permalink
- if request.GET:
- for key in ('zoom', 'lon', 'lat', 'display_submited'):
- if key in request.GET and request.GET[key]:
- response_dct['p_'+key] = request.GET[key]
- else:
- response_dct['p_'+key] = '""'
- if 'checked_categories' in request.GET \
- and request.GET['checked_categories']:
- cats = request.GET['checked_categories'].split('_')
- response_dct['p_checked_categories'] = ",".join(cats)
- else:
- response_dct['p_checked_categories'] = '';
- return render_to_response('main_map.html', response_dct)
-
-def edit(request):
- """
- Edition page
- """
- # If the form has been submited
- if request.method == 'POST':
- form = MarkerForm(request.POST, request.FILES)
- # All validation rules pass
- if form.is_valid():
- marker = form.save()
- # set the submited status
- marker.status = 'S'
- marker.save()
- notifySubmission(marker)
- return HttpResponseRedirect('/' + settings.EXTRA_URL +'submited/edit')
- else:
- # An unbound form
- form = MarkerForm()
- # get the « manualy » declared_fields. Ie: properties
- declared_fields = form.declared_fields.keys()
- response_dct = {'actions':actions, 'action_selected':('contribute', 'edit'),
- 'error_message':'',
- 'media_path':settings.MEDIA_URL,
- 'extra_url':settings.EXTRA_URL,
- 'map_layer':settings.MAP_LAYER,
- 'form':form,
- 'extra_head':form.media,
- 'sub_categories':SubCategory.getAvailable(['M', 'B']),
- 'point_widget':PointChooserWidget().render('point', None),
- 'properties':declared_fields
- }
- # manualy populate the custom widget
- if 'subcategory' in form.data and form.data['subcategory']:
- response_dct['current_category'] = int(form.data['subcategory'])
- return render_to_response('edit.html', response_dct)
-
-def editRoute(request):
- """
- Route edition page
- """
- # If the form has been submited
- if request.method == 'POST':
- form = RouteForm(request.POST, request.FILES)
- # All validation rules pass
- if form.is_valid():
- route = form.save()
- # set the submited status
- route.status = 'S'
- route.save()
- notifySubmission(route)
- return HttpResponseRedirect('/' + settings.EXTRA_URL + \
- 'submited/edit_route')
- else:
- # An unbound form
- form = RouteForm()
- # get the « manualy » declared_fields. Ie: properties
- declared_fields = form.declared_fields.keys()
- response_dct = {'actions':actions,
- 'action_selected':('contribute', 'edit_route'),
- 'error_message':'',
- 'media_path':settings.MEDIA_URL,
- 'map_layer':settings.MAP_LAYER,
- 'form':form,
- 'extra_head':form.media,
- 'extra_url':settings.EXTRA_URL,
- 'sub_categories':SubCategory.getAvailable(['R', 'B']),
- 'route_widget':RouteChooserWidget().render('route', None),
- 'properties':declared_fields
- }
- # manualy populate the custom widget
- if 'subcategory' in form.data and form.data['subcategory']:
- response_dct['current_category'] = int(form.data['subcategory'])
- return render_to_response('edit_route.html', response_dct)
-
-def welcome(request, display=None):
- """
- Welcome string
- """
- response_dct = {'display':display}
- response_dct['news_lst'] = News.objects.filter(available=True)
- return loader.render_to_string('welcome.html', response_dct)
-
-def submited(request, action):
- """
- Successful submission page
- """
- response_dct = {'actions':actions, 'action_selected':action,
- 'media_path':settings.MEDIA_URL,}
- return render_to_response('submited.html', response_dct)
-
-def contactus(request):
- """
- Contact page
- """
- form = None
- msg = ''
- # If the form has been submited
- if request.method == 'POST':
- form = ContactForm(request.POST)
- # All validation rules pass
- if form.is_valid():
- response = notifyStaff(_(u"Comments/request on the map"),
- form.cleaned_data['content'], form.cleaned_data['email'])
- if response:
- msg = _(u"Thank you for your contribution. It will be taken \
-into account. If you have left your email you may be contacted soon for more \
-details.")
- else:
- msg = _(u"Temporary error. Renew your message later.")
- else:
- form = ContactForm()
- response_dct = {'actions':actions, 'action_selected':('contact',),
- 'media_path':settings.MEDIA_URL,'contact_form':form, 'message':msg}
- return render_to_response('contactus.html', response_dct)
-
-def getDetail(request, marker_id):
- '''
- Get the detail for a marker
- '''
- try:
- marker = Marker.objects.filter(id=int(marker_id), status='A')[0]
- except (ValueError, IndexError):
- return HttpResponse('no results')
- response_dct= {'media_path':settings.MEDIA_URL, 'marker':marker}
- return render_to_response('detail.html', response_dct)
-
-def getDescriptionDetail(request, category_id):
- '''
- Get the description for a category
- '''
- try:
- category = Category.objects.filter(id=int(category_id))[0]
- except (ValueError, IndexError):
- return HttpResponse('no results')
- response_dct= {'media_path':settings.MEDIA_URL, 'category':category}
- return render_to_response('category_detail.html', response_dct)
-
-def getGeoObjects(request, category_ids, status='A'):
- '''
- Get the JSON for a route
- '''
- status = status.split('_')
- try:
- query = Route.objects.filter(status__in=status,
- subcategory__in=category_ids.split('_'))
- except:
- return HttpResponse('no results')
- query.order_by('subcategory')
- routes = list(query)
- jsons = []
- current_cat, colors, idx = None, None, 0
- for route in routes:
- if not current_cat or current_cat != route.subcategory:
- idx = 0
- current_cat = route.subcategory
- colors = list(Color.objects.filter(color_theme=\
- route.subcategory.color_theme))
- jsons.append(route.getGeoJSON(color=colors[idx % len(colors)].code))
- idx += 1
- try:
- query = Marker.objects.filter(status__in=status,
- subcategory__in=category_ids.split('_'))
- except:
- return HttpResponse('no results')
- jsons += [geo_object.getGeoJSON() for geo_object in list(query)]
- if not jsons:
- return HttpResponse('no results')
- data = '{"type": "FeatureCollection", "features":[%s]}' % ",".join(jsons)
- return HttpResponse(data)
diff --git a/main/widgets.py b/main/widgets.py
deleted file mode 100644
index 6b5e544..0000000
--- a/main/widgets.py
+++ /dev/null
@@ -1,292 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# See the file COPYING for details.
-
-"""
-Extra widgets and fields
-"""
-
-from django import forms
-from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext as _
-from django.contrib.gis.geos import fromstr
-
-from chimere import settings
-from django.contrib.gis.db import models
-
-URL_OSM_CSS = ["http://www.openlayers.org/api/theme/default/style.css"]
-URL_OSM_JS = ["http://www.openlayers.org/api/OpenLayers.js",
- "http://www.openstreetmap.org/openlayers/OpenStreetMap.js"]
-
-def getMapJS():
- '''Variable initialization for drawing the map
- '''
- # projection, center and bounds definitions
- js = u"var epsg_display_projection = new OpenLayers.Projection('EPSG:%d')\
-;\n" % settings.EPSG_DISPLAY_PROJECTION
- js += u"var epsg_projection = new OpenLayers.Projection('EPSG:%d');\n" % \
- settings.EPSG_PROJECTION
- js += u"var centerLonLat = new OpenLayers.LonLat(%f,\
-%f).transform(epsg_display_projection, epsg_projection);\n" % \
- settings.DEFAULT_CENTER
- js += u"var media_path = '%s';\n" % settings.MEDIA_URL
- js += u"var map_layer = %s;\n" % settings.MAP_LAYER
- js += u"var restricted_extent;\n"
- if settings.RESTRICTED_EXTENT:
- restricted_extent_str = [str(coord) \
- for coord in settings.RESTRICTED_EXTENT]
- js += u"restricted_extent = new OpenLayers.Bounds(%s);\n" %\
- ", ".join(restricted_extent_str)
- js = u"""<script type="text/javascript"><!--
-%s// !--></script>
-""" % js
- return js
-
-class TextareaWidget(forms.Textarea):
- """
- Manage the edition of a text using TinyMCE
- """
- class Media:
- js = ["%stiny_mce.js" % settings.TINYMCE_URL,
- "%stextareas.js" % settings.MEDIA_URL,]
-
-class PointChooserWidget(forms.TextInput):
- """
- Manage the edition of point on a map
- """
- class Media:
- css = {
- "all": URL_OSM_CSS + ["%sforms.css" % settings.MEDIA_URL,]
- }
- js = URL_OSM_JS + ["%sedit_map.js" % settings.MEDIA_URL,
- "%sbase.js" % settings.MEDIA_URL,]
-
- def render(self, name, value, attrs=None):
- '''
- Render a map and latitude, longitude information field
- '''
- val = '0'
- value_x, value_y = 0, 0
- if value:
- val = str(value)
- if hasattr(value, 'x') and hasattr(value, 'y'):
- value_x, value_y = value.x, value.y
- elif isinstance(value, unicode) and value.startswith('POINT('):
- try:
- value_x, value_y = value.split('(')[1][:-1].split(' ')
- value_x, value_y = float(value_x), float(value_y)
- except:
- value = None
- else:
- value = None
- tpl = getMapJS()
- tpl += u'<script src="%sedit_map.js"></script>\n' % settings.MEDIA_URL
- tpl += u"""<div id='map_edit'></div>
-<div id='live_lonlat'>
-<p><label for='live_latitude'>%s</label>\
-<input type='texte' name='live_latitude' id='live_latitude' size='8' \
-disabled='true' value='%f'/></p>
-<p><label for='live_longitude'>%s</label><input type='texte' \
-name='live_longitude' id='live_longitude' size='8' disabled='true' \
-value='%f'/></p>
-</div>
-<input type='hidden' name='%s' id='id_%s' value="%s"/>
-""" % (_("Latitude"), value_y, _("Longitude"), value_x, name, name, val)
- tpl += """<script type='text/javascript'><!--
-init();"""
- if value:
- tpl += '''var mylonlat = new OpenLayers.LonLat(%f,%f);
-putMarker(mylonlat.transform(epsg_display_projection,
- map.getProjectionObject()).clone(), true);
-''' % (value_x, value_y)
- tpl += """// --></script>
-<hr class='spacer'/>
-"""
- return mark_safe(tpl)
-
-class PointField(models.PointField):
- '''
- Set the widget for the form field
- '''
- def formfield(self, **keys):
- defaults = {'widget': PointChooserWidget}
- keys.update(defaults)
- return super(PointField, self).formfield(**keys)
-
- def clean(self, value):
- if len(value) != 2 and self.required:
- raise ValidationError(_("Invalid point"))
- return value
-
-class RouteChooserWidget(forms.TextInput):
- """
- Manage the edition of route on a map
- """
- class Media:
- css = {
- "all": URL_OSM_CSS + ["%sforms.css" % settings.MEDIA_URL,]
- }
- js = ["%sedit_route_map.js" % settings.MEDIA_URL,
- "%sbase.js" % settings.MEDIA_URL,] + URL_OSM_JS
-
- def render(self, name, value, attrs=None):
- '''
- Render a map and latitude, longitude information field
- '''
- tpl = getMapJS()
- help_create = ''
- if not value:
- help_create = """<h3>%s</h3>
-<p>%s</p>
-<p>%s</p>
-<p>%s</p>
-<p>%s</p>
-<p>%s</p>""" % (_("Creation mode"),
-_("To start drawing the route click on the toggle button : \"Start drawing\"."),
-_("Then click on the map to begin the drawing."),
-_("You can add points by clicking again."),
-_("To finish the drawing double click. When the drawing is finished you can \
-edit it."),
-_("While creating to undo a drawing click again on the toggle button \"Stop \
-drawing\"."))
- help_modify = """<h3>%s</h3>
-<p>%s</p>
-<p>%s</p>
-<p>%s</p>""" % (_("Modification mode"),
-_("To move a point click on it and drag it to the desired position."),
-_("To delete a point move the mouse cursor over it and press the \"d\" key."),
-_("To add a point click in the middle of a segment and drag the new point to \
-the desired position"))
- tpl += u'<script src="%sedit_route_map.js"></script>\n' % \
- settings.MEDIA_URL
- if not value:
- tpl += u"""<div id='draw-toggle-off' class='toggle-button' \
-onclick='toggleDrawOn();'>%s</div>
-<div id='draw-toggle-on' class='toggle-button' \
-onclick='toggleDrawOff();'>%s</div>
-<hr class='spacer'/>""" % (_("Start drawing"), _("Stop drawing"))
- tpl += """
-<div id='map_edit'></div>"""
- if not value:
- tpl += '''
-<div class='help-route' id='help-route-create'>%s</div>''' % help_create
- style = ''
- if value:
- style = " style='display:block'"
- tpl += """
-<div class='help-route' id='help-route-modify'%s>%s</div>
-<hr class='spacer'/>
-<input type='hidden' name='%s' id='id_%s' value="%s"/>
-""" % (style, help_modify, name, name, value)
- tpl += """<script type='text/javascript'><!--
-init();"""
- if value:
- val = value
- if type(value) == unicode:
- try:
- val = fromstr(value)
- except:
- pass
- if hasattr(val, 'json'):
- tpl += """
-var geometry='%s';
-initFeature(geometry);""" % val.json
- tpl += """
-// --></script>
-"""
- return mark_safe(tpl)
-
-class RouteField(models.LineStringField):
- '''
- Set the widget for the form field
- '''
- def formfield(self, **keys):
- defaults = {'widget': RouteChooserWidget}
- keys.update(defaults)
- return super(RouteField, self).formfield(**keys)
-
-class AreaWidget(forms.TextInput):
- """
- Manage the edition of an area on the map
- """
- class Media:
- css = {
- "all": URL_OSM_CSS + ["%sforms.css" % settings.MEDIA_URL,]
- }
- js = URL_OSM_JS + ["%sedit_area.js" % settings.MEDIA_URL,
- "%sbase.js" % settings.MEDIA_URL,]
-
- def render(self, name, value, attrs=None):
- """
- Render a map
- """
- upper_left_lat, upper_left_lon = 0, 0
- lower_right_lat, lower_right_lon = 0, 0
- if value:
- if len(value) == 2:
- upper_left = value[0]
- lower_right = value[1]
- if hasattr(upper_left, 'x') and hasattr(upper_left, 'y'):
- upper_left_lon, upper_left_lat = upper_left.x, upper_left.y
- if hasattr(lower_right, 'x') and hasattr(lower_right, 'y'):
- lower_right_lon, lower_right_lat = lower_right.x, \
- lower_right.y
- tpl = getMapJS()
- tpl += u"""<div id='map_edit'></div>
-<input type='hidden' name='upper_left_lat' id='upper_left_lat' value='%f'/>
-<input type='hidden' name='upper_left_lon' id='upper_left_lon' value='%f'/>
-<input type='hidden' name='lower_right_lat' id='lower_right_lat' value='%f'/>
-<input type='hidden' name='lower_right_lon' id='lower_right_lon' value='%f'/>
-""" % (upper_left_lat, upper_left_lon, lower_right_lat, lower_right_lon)
- tpl += """<script type='text/javascript'><!--
-init();"""
- if value:
- tpl += """var extent = new OpenLayers.Bounds(%f, %f, %f, %f);
-map.zoomToExtent(extent, true);""" % (upper_left_lat, upper_left_lon, lower_right_lat,
- lower_right_lon)
- tpl += """// --></script>
-<hr class='spacer'/>
-"""
- return mark_safe(tpl)
-
- def value_from_datadict(self, data, files, name):
- """
- Return the appropriate values
- """
- values = []
- for keys in (('upper_left_lat', 'upper_left_lon',),
- ('lower_right_lat', 'lower_right_lon')):
- value = []
- for key in keys:
- val = data.get(key, None)
- if not val:
- return []
- value.append(val)
- values.append(value)
- return values
-
-class AreaField(forms.MultiValueField):
- '''
- Set the widget for the form field
- '''
- widget = AreaWidget
-
- def compress(self, data_list):
- if not data_list:
- return None
- return data_list