summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chimere/actions.py39
-rw-r--r--chimere/admin.py26
-rw-r--r--chimere/forms.py96
-rw-r--r--chimere/locale/fr/LC_MESSAGES/django.po684
-rw-r--r--chimere/migrations/0001_initial.py520
-rw-r--r--chimere/migrations/0002_auto__add_propertymodelchoice__add_page__add_field_subcategory_dated__.py361
-rw-r--r--chimere/migrations/0003_create_aggregate_route_view.py290
-rw-r--r--chimere/models.py204
-rw-r--r--chimere/old_migrations/v2.0/0001_initial.py342
-rw-r--r--chimere/old_migrations/v2.0/0002_rename_models.py (renamed from chimere/migrations/0002_rename_models.py)0
-rw-r--r--chimere/old_migrations/v2.0/0003_auto__add_field_route_submiter_session_key__add_field_route_submiter_e.py (renamed from chimere/migrations/0003_auto__add_field_route_submiter_session_key__add_field_route_submiter_e.py)0
-rw-r--r--chimere/old_migrations/v2.0/0004_auto__add_picturefile__add_multimediafile.py (renamed from chimere/migrations/0004_auto__add_picturefile__add_multimediafile.py)0
-rw-r--r--chimere/old_migrations/v2.0/0005_auto__add_multimediatype__add_field_picturefile_order__del_field_multi.py (renamed from chimere/migrations/0005_auto__add_multimediatype__add_field_picturefile_order__del_field_multi.py)0
-rw-r--r--chimere/old_migrations/v2.0/0006_auto__add_importer__add_field_route_import_key__add_field_marker_impor.py (renamed from chimere/migrations/0006_auto__add_importer__add_field_route_import_key__add_field_marker_impor.py)0
-rw-r--r--chimere/old_migrations/v2.0/0007_auto__add_field_marker_description.py (renamed from chimere/migrations/0007_auto__add_field_marker_description.py)0
-rw-r--r--chimere/old_migrations/v2.0/0008_auto__del_field_importer_subcategory__add_field_route_import_source__a.py (renamed from chimere/migrations/0008_auto__del_field_importer_subcategory__add_field_route_import_source__a.py)0
-rw-r--r--chimere/old_migrations/v2.0/0009_auto__add_field_importer_state.py (renamed from chimere/migrations/0009_auto__add_field_importer_state.py)0
-rw-r--r--chimere/old_migrations/v2.0/0010_auto__add_field_route_import_version__add_field_marker_import_version.py (renamed from chimere/migrations/0010_auto__add_field_route_import_version__add_field_marker_import_version.py)0
-rw-r--r--chimere/old_migrations/v2.0/0011_auto__del_field_importer_source_url__add_field_importer_source.py (renamed from chimere/migrations/0011_auto__del_field_importer_source_url__add_field_importer_source.py)0
-rw-r--r--chimere/old_migrations/v2.0/0012_auto__chg_field_picturefile_name__chg_field_multimediafile_url__chg_fi.py (renamed from chimere/migrations/0012_auto__chg_field_picturefile_name__chg_field_multimediafile_url__chg_fi.py)0
-rw-r--r--chimere/old_migrations/v2.0/0013_auto__add_field_multimediafile_miniature.py (renamed from chimere/migrations/0013_auto__add_field_multimediafile_miniature.py)0
-rw-r--r--chimere/old_migrations/v2.0/0014_auto__add_field_picturefile_marker__add_field_multimediafile_marker__a.py (renamed from chimere/migrations/0014_auto__add_field_picturefile_marker__add_field_multimediafile_marker__a.py)0
-rw-r--r--chimere/old_migrations/v2.0/0015_auto__chg_field_picturefile_marker__chg_field_multimediafile_marker.py (renamed from chimere/migrations/0015_auto__chg_field_picturefile_marker__chg_field_multimediafile_marker.py)0
-rw-r--r--chimere/old_migrations/v2.0/0016_auto__add_field_importer_zipped.py (renamed from chimere/migrations/0016_auto__add_field_importer_zipped.py)0
-rw-r--r--chimere/old_migrations/v2.0/0017_auto__add_field_importer_srid.py (renamed from chimere/migrations/0017_auto__add_field_importer_srid.py)0
-rw-r--r--chimere/old_migrations/v2.0/0018_auto__add_layer__add_arealayers.py (renamed from chimere/migrations/0018_auto__add_layer__add_arealayers.py)0
-rw-r--r--chimere/old_migrations/v2.0/0019_auto__chg_field_layer_layer_code__add_field_area_welcome_message.py (renamed from chimere/migrations/0019_auto__chg_field_layer_layer_code__add_field_area_welcome_message.py)0
-rw-r--r--chimere/old_migrations/v2.0/0020_auto.py (renamed from chimere/migrations/0020_auto.py)0
-rw-r--r--chimere/old_migrations/v2.0/0021_auto.py (renamed from chimere/migrations/0021_auto.py)0
-rw-r--r--chimere/old_migrations/v2.0/0022_auto__add_field_area_external_css.py (renamed from chimere/migrations/0022_auto__add_field_area_external_css.py)0
-rw-r--r--chimere/old_migrations/v2.0/0023_auto__add_field_area_restrict_to_extent.py (renamed from chimere/migrations/0023_auto__add_field_area_restrict_to_extent.py)0
-rw-r--r--chimere/old_migrations/v2.0/0024_auto__add_field_marker_available_date.py (renamed from chimere/migrations/0024_auto__add_field_marker_available_date.py)0
-rw-r--r--chimere/old_migrations/v2.0/0025_auto__add_field_area_dynamic_categories.py (renamed from chimere/migrations/0025_auto__add_field_area_dynamic_categories.py)0
-rw-r--r--chimere/old_migrations/v2.0/0026_auto__add_field_marker_submiter_name__add_field_route_submiter_name.py (renamed from chimere/migrations/0026_auto__add_field_marker_submiter_name__add_field_route_submiter_name.py)0
-rw-r--r--chimere/old_migrations/v2.0/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py (renamed from chimere/migrations/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py)0
-rw-r--r--chimere/old_migrations/v2.0/0028_auto__add_field_picturefile_thumbnailfile__add_field_picturefile_thumb.py (renamed from chimere/migrations/0028_auto__add_field_picturefile_thumbnailfile__add_field_picturefile_thumb.py)0
-rw-r--r--chimere/old_migrations/v2.0/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py (renamed from chimere/migrations/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py)0
-rw-r--r--chimere/old_migrations/v2.0/0030_auto__add_field_importer_default_name.py (renamed from chimere/migrations/0030_auto__add_field_importer_default_name.py)0
-rw-r--r--chimere/old_migrations/v2.0/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py (renamed from chimere/migrations/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py)0
-rw-r--r--chimere/old_migrations/v2.0/0032_auto__add_field_subcategory_submission.py (renamed from chimere/migrations/0032_auto__add_field_subcategory_submission.py)0
-rw-r--r--chimere/old_migrations/v2.0/0033_auto__add_field_importer_source_file.py (renamed from chimere/migrations/0033_auto__add_field_importer_source_file.py)0
-rw-r--r--chimere/old_migrations/v2.0/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py (renamed from chimere/migrations/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py)0
-rw-r--r--chimere/old_migrations/v2.0/0035_area_permissions.py (renamed from chimere/migrations/0035_area_permissions.py)0
-rw-r--r--chimere/old_migrations/v2.0/0036_auto.py (renamed from chimere/migrations/0036_auto.py)0
-rw-r--r--chimere/old_migrations/v2.0/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py (renamed from chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py)0
-rw-r--r--chimere/old_migrations/v2.0/0038_osm_import_filtr.py (renamed from chimere/migrations/0038_osm_import_filtr.py)0
-rw-r--r--chimere/old_migrations/v2.0/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py (renamed from chimere/migrations/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py)0
-rw-r--r--chimere/old_migrations/v2.0/0040_remove_excluded_status.py (renamed from chimere/migrations/0040_remove_excluded_status.py)0
-rw-r--r--chimere/old_migrations/v2.0/0041_auto__add_field_importer_overwrite.py (renamed from chimere/migrations/0041_auto__add_field_importer_overwrite.py)0
-rw-r--r--chimere/old_migrations/v2.0/0042_fix_rights.py (renamed from chimere/migrations/0042_fix_rights.py)0
-rw-r--r--chimere/old_migrations/v2.0/0043_auto__add_field_importer_get_description.py (renamed from chimere/migrations/0043_auto__add_field_importer_get_description.py)0
-rw-r--r--chimere/old_migrations/v2.0/0044_auto__add_field_importer_default_description.py (renamed from chimere/migrations/0044_auto__add_field_importer_default_description.py)0
-rw-r--r--chimere/old_migrations/v2.0/__init__.py0
-rw-r--r--chimere/route.py121
-rw-r--r--chimere/settings.sample.py289
-rw-r--r--chimere/static/chimere/css/admin.css6
-rw-r--r--chimere/static/chimere/css/print.css40
-rw-r--r--chimere/static/chimere/css/styles.css255
-rw-r--r--chimere/static/chimere/img/bottom-arrow.pngbin0 -> 199 bytes
-rw-r--r--chimere/static/chimere/img/close.pngbin0 -> 856 bytes
-rw-r--r--chimere/static/chimere/img/empty.pngbin0 -> 165 bytes
-rw-r--r--chimere/static/chimere/img/feed.pngbin0 -> 1453 bytes
-rw-r--r--chimere/static/chimere/img/film_logo.pngbin0 -> 748 bytes
-rw-r--r--chimere/static/chimere/img/flag-finish.pngbin0 -> 1652 bytes
-rw-r--r--chimere/static/chimere/img/flag-start.pngbin0 -> 1165 bytes
-rw-r--r--chimere/static/chimere/img/flag-step.pngbin0 -> 1256 bytes
-rw-r--r--chimere/static/chimere/img/images_licences17
-rw-r--r--chimere/static/chimere/img/img_logo.pngbin0 -> 864 bytes
-rw-r--r--chimere/static/chimere/img/marker-cluster.pngbin0 -> 1211 bytes
-rw-r--r--chimere/static/chimere/img/printer.pngbin0 -> 914 bytes
-rw-r--r--chimere/static/chimere/img/share-icon.pngbin0 -> 1208 bytes
-rw-r--r--chimere/static/chimere/img/share-icon.xcfbin0 -> 5431 bytes
-rw-r--r--chimere/static/chimere/js/base.js36
-rw-r--r--chimere/static/chimere/js/clustering.js278
-rw-r--r--chimere/static/chimere/js/jquery.chimere.js995
-rw-r--r--chimere/static/chimere/js/nominatim-widget.js46
-rw-r--r--chimere/static/chimere/js/routing-widget.js47
-rw-r--r--chimere/static/chimere/js/utils.js6
-rw-r--r--chimere/tasks.py2
-rw-r--r--chimere/templates/base.html38
-rw-r--r--chimere/templates/chimere/base.html1
-rw-r--r--chimere/templates/chimere/blocks/actions.html4
-rw-r--r--chimere/templates/chimere/blocks/alternate_multimedia.html37
-rw-r--r--chimere/templates/chimere/blocks/categories.html4
-rw-r--r--chimere/templates/chimere/blocks/footer.html2
-rw-r--r--chimere/templates/chimere/blocks/head_chimere.html13
-rw-r--r--chimere/templates/chimere/blocks/head_form.html2
-rw-r--r--chimere/templates/chimere/blocks/head_jme.html12
-rw-r--r--chimere/templates/chimere/blocks/live_coordinates.html2
-rw-r--r--chimere/templates/chimere/blocks/map.html43
-rw-r--r--chimere/templates/chimere/blocks/map_menu.html14
-rw-r--r--chimere/templates/chimere/blocks/multimedia_file.html2
-rw-r--r--chimere/templates/chimere/blocks/news.html53
-rw-r--r--chimere/templates/chimere/blocks/routing.html48
-rw-r--r--chimere/templates/chimere/blocks/share_bar.html39
-rw-r--r--chimere/templates/chimere/default_extra_page.html15
-rw-r--r--chimere/templates/chimere/detail.html14
-rw-r--r--chimere/templates/chimere/edit.html5
-rw-r--r--chimere/templates/chimere/main_map.html20
-rw-r--r--chimere/templatetags/chimere_tags.py143
-rw-r--r--chimere/tests.py26
-rw-r--r--chimere/urls.py28
-rw-r--r--chimere/utils.py11
-rw-r--r--chimere/views.py222
-rw-r--r--chimere/widgets.py106
105 files changed, 4937 insertions, 667 deletions
diff --git a/chimere/actions.py b/chimere/actions.py
index 0363d54..8ef5338 100644
--- a/chimere/actions.py
+++ b/chimere/actions.py
@@ -22,21 +22,44 @@ Actions available in the main interface
"""
from django.conf import settings
from django.contrib.auth import models
+from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
+from models import Page
+
class Action:
- def __init__(self, id, path, label):
+ def __init__(self, id, path, label, extra_url_args=[]):
self.id, self.path, self.label = id, path, label
+ self.extra_url_args, self.url = extra_url_args, None
+
+ def update_url(self, area_name):
+ self.url = reverse(self.path,
+ args=[area_name + '/' if area_name else ''] + self.extra_url_args)
-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'))),
- ),]
+default_actions = [(Action('view', 'chimere:index', _('View')), []),
+ (Action('contribute', 'chimere:edit', _('Contribute')),
+ (Action('edit', 'chimere:edit', _('Add a new point of interest')),
+ Action('edit-route', 'chimere:editroute', _('Add a new route'))),
+ ),]
if settings.CHIMERE_FEEDS:
- actions.append((Action('rss', 'feeds', _('RSS feeds')), []))
+ default_actions.append((Action('rss', 'chimere:feeds-form',
+ _('RSS feeds')), []))
if settings.EMAIL_HOST:
- actions.append((Action('contact', 'contact', _('Contact us')), []),)
+ default_actions.append((Action('contact', 'chimere:contact',
+ _('Contact us')), []),)
+
+def actions(area_name=''):
+ acts = default_actions[:]
+ for act, childs in default_actions:
+ act.update_url(area_name)
+ for child_act in childs:
+ child_act.update_url(area_name)
+ for page in Page.objects.filter(available=True).order_by('order'):
+ act = Action(page.mnemonic, 'chimere:extra_page', page.title,
+ [page.mnemonic])
+ act.update_url(area_name)
+ acts.append((act, []))
+ return acts
diff --git a/chimere/admin.py b/chimere/admin.py
index 6c7b2cc..c9107a5 100644
--- a/chimere/admin.py
+++ b/chimere/admin.py
@@ -37,15 +37,15 @@ except ImportError:
pass
from chimere.forms import MarkerAdminForm, RouteAdminForm, AreaAdminForm,\
- NewsAdminForm, CategoryAdminForm, ImporterAdminForm, \
- PictureFileAdminForm, MultimediaFileAdminForm, OSMForm
+ NewsAdminForm, CategoryAdminForm, ImporterAdminForm, OSMForm, \
+ PageAdminForm, PictureFileAdminForm, MultimediaFileAdminForm
from chimere.models import Category, Icon, SubCategory, Marker, \
PropertyModel, News, Route, Area, ColorTheme, Color, \
MultimediaFile, PictureFile, Importer, Layer, AreaLayers,\
+ PropertyModelChoice, MultimediaExtension, Page,\
get_areas_for_user, get_users_by_area
from chimere.utils import unicode_normalize, ShapefileManager, KMLManager,\
CSVManager
-from chimere.widgets import TextareaWidget
def disable(modeladmin, request, queryset):
for item in queryset:
@@ -186,9 +186,9 @@ class MarkerAdmin(admin.ModelAdmin):
actions = [validate, disable, managed_modified, export_to_kml,
export_to_shapefile, export_to_csv]
exclude = ['submiter_session_key', 'import_key', 'import_version',
- 'available_date']
+ 'available_date', 'ref_item']
readonly_fields = ['submiter_email', 'submiter_comment', 'import_source',
- 'ref_item', 'modified_since_import', 'route']
+ 'submiter_name', 'ref_item', 'modified_since_import', 'route']
form = MarkerAdminForm
fieldsets = ((None, {
'fields': ['point', 'name', 'status', 'categories',
@@ -387,11 +387,17 @@ class ImporterAdmin(admin.ModelAdmin):
form = ImporterAdminForm
list_display = ('display_categories', 'default_name', 'importer_type',
'source', 'state', 'filtr')
- list_filter = ('importer_type',)
+ list_filter = ('importer_type', 'categories')
readonly_fields = ('state',)
actions = [importing, cancel_import, export_to_osm, cancel_export]
admin.site.register(Importer, ImporterAdmin)
+class PageAdmin(admin.ModelAdmin):
+ """
+ Use the TinyMCE widget for the page content
+ """
+ form = PageAdminForm
+
class PropertyModelAdmin(admin.ModelAdmin):
list_display = ('name', 'order', 'available')
@@ -421,8 +427,16 @@ class ColorThemeAdmin(admin.ModelAdmin):
class IconAdmin(admin.ModelAdmin):
exclude = ['height', 'width']
+ list_display = ['name']
+
+class PropertyModelChoiceInline(admin.TabularInline):
+ model = PropertyModelChoice
+ extra = 1
+class PropertyModelAdmin(admin.ModelAdmin):
+ inlines = [PropertyModelChoiceInline]
# register of differents database fields
+admin.site.register(Page, PageAdmin)
admin.site.register(News, NewsAdmin)
admin.site.register(Category, CategoryAdmin)
admin.site.register(Icon, IconAdmin)
diff --git a/chimere/forms.py b/chimere/forms.py
index 774f510..655bbd3 100644
--- a/chimere/forms.py
+++ b/chimere/forms.py
@@ -33,10 +33,11 @@ from django.core.mail import EmailMessage, BadHeaderError
from chimere.models import Marker, Route, PropertyModel, Property, Area,\
News, Category, SubCategory, RouteFile, MultimediaFile, MultimediaType, \
- PictureFile, Importer, IMPORTER_CHOICES, IFRAME_LINKS, MultimediaExtension
+ PictureFile, Importer, PropertyModelChoice, IFRAME_LINKS, \
+ MultimediaExtension, Page, IMPORTER_CHOICES
from chimere.widgets import AreaField, PointField, TextareaWidget, \
- ImportFiltrWidget, TextareaAdminWidget, DatePickerWidget, \
- ImporterChoicesWidget, RE_XAPI
+ FullTextareaWidget, DatePickerWidget, ButtonSelectWidget, NominatimWidget, \
+ TextareaAdminWidget, ImportFiltrWidget, ImporterChoicesWidget, RE_XAPI
from datetime import timedelta, datetime, tzinfo
@@ -54,13 +55,18 @@ class UTC(tzinfo):
def dst(self, dt):
return ZERO
+def getStaffEmails():
+ return [u.email for u in
+ User.objects.filter(is_staff=True).exclude(email="").order_by('id')]
+
def notifyStaff(subject, body, sender=None):
if not settings.EMAIL_HOST:
return
+ user_list = getStaffEmails()
+ if not user_list:
+ return
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
@@ -90,6 +96,20 @@ class ContactForm(forms.Form):
email = forms.EmailField(label=_("Email (optional)"), required=False)
content = forms.CharField(label=_("Object"), widget=forms.Textarea)
+class SubCategoryAdminForm(forms.ModelForm):
+ '''
+ Add a tinyMCE widget to fill description
+ '''
+ description = forms.CharField(widget=FullTextareaWidget, required=False)
+
+class PageAdminForm(forms.ModelForm):
+ """
+ Main form for extra pages
+ """
+ content = forms.CharField(widget=FullTextareaWidget)
+ class Meta:
+ model = Page
+
class OSMForm(forms.Form):
"""
OSM export form
@@ -165,6 +185,9 @@ class CategoryAdminForm(forms.ModelForm):
js = list(settings.JQUERY_JS_URLS) + [
'%schimere/js/menu-sort.js' % settings.STATIC_URL,
]
+ css = {
+ 'all': ('chimere/css/admin.css',)
+ }
class Meta:
model = Category
@@ -248,16 +271,32 @@ class MarkerAdminFormBase(forms.ModelForm):
return new_marker
# As we have dynamic fields, it's cleaner to make the class dynamic too
-fields = {}
-# declare properties
-for prop in PropertyModel.objects.filter(available=True):
- key = "property_%d_%d" % (prop.order, prop.id)
- fields[key] = forms.CharField(label=prop.name,
- widget=PropertyModel.TYPE_WIDGET[prop.type],
- required=False)
-MarkerAdminForm = type("MarkerAdminForm", (MarkerAdminFormBase,), fields)
-
-class MarkerForm(MarkerAdminForm):
+def get_properties(queryset):
+ fields = {}
+ for prop in queryset:
+ key = "property_%d_%d" % (prop.order, prop.id)
+ if prop.type == 'C':
+ choices = PropertyModelChoice.objects.filter(propertymodel=prop,
+ available=True
+ ).order_by('value')
+ fields[key] = forms.ChoiceField(label=prop.name,
+ choices=[('', '--')] + \
+ [(choice.pk, unicode(choice))
+ for choice in choices],
+ required=False)
+ else:
+ fields[key] = forms.CharField(label=prop.name,
+ widget=PropertyModel.TYPE_WIDGET[prop.type],
+ required=False)
+ return fields
+
+# in admin all fields are displayed
+MarkerAdminForm = type("MarkerAdminForm", (MarkerAdminFormBase,),
+ get_properties(PropertyModel.objects.all()))
+MarkerBaseForm = type("MarkerBaseForm", (MarkerAdminFormBase,),
+ get_properties(PropertyModel.objects.filter(available=True)))
+
+class MarkerForm(MarkerBaseForm):
"""
Form for the edit page
"""
@@ -564,3 +603,30 @@ class AreaForm(AreaAdminForm):
class Meta:
model = Area
+CHIMERE_ROUTING_TRANSPORT = []
+ROUTING_INIT = None
+if hasattr(settings, 'CHIMERE_ROUTING_TRANSPORT'):
+ CHIMERE_ROUTING_TRANSPORT = [(idx, _(lbl))
+ for idx, lbl in settings.CHIMERE_ROUTING_TRANSPORT]
+ if CHIMERE_ROUTING_TRANSPORT:
+ ROUTING_INIT = CHIMERE_ROUTING_TRANSPORT[0][0]
+
+
+class RoutingForm(forms.Form):
+ transport = forms.ChoiceField(label='', widget=ButtonSelectWidget,
+ choices=CHIMERE_ROUTING_TRANSPORT,
+ initial=ROUTING_INIT)
+ start = forms.CharField(label=_(u"Start"), widget=NominatimWidget)
+ end = forms.CharField(label=_(u"Finish"), widget=NominatimWidget)
+ speed = forms.ChoiceField(label=_(u"Speed"), choices=[],
+ required=False, widget=forms.RadioSelect)
+
+ def __init__(self, *args, **kwargs):
+ super(RoutingForm, self).__init__(*args, **kwargs)
+ if not settings.CHIMERE_ROUTING_SPEEDS:
+ self.fields.pop('speed')
+ self.fields['speed'].widget.choices = []
+ for transport in settings.CHIMERE_ROUTING_SPEEDS:
+ for speed, lbl in settings.CHIMERE_ROUTING_SPEEDS[transport]:
+ self.fields['speed'].widget.choices.append(
+ ("%s_%d" % (transport, speed), _(lbl)))
diff --git a/chimere/locale/fr/LC_MESSAGES/django.po b/chimere/locale/fr/LC_MESSAGES/django.po
index b2fc81c..f0b15b1 100644
--- a/chimere/locale/fr/LC_MESSAGES/django.po
+++ b/chimere/locale/fr/LC_MESSAGES/django.po
@@ -7,34 +7,34 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-02-01 13:13+0100\n"
+"POT-Creation-Date: 2013-03-14 18:43+0100\n"
"PO-Revision-Date: 2010-03-20 20:00+0100\n"
"Last-Translator: Étienne Loks <etienne.loks@peacefrogs.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: actions.py:31
+#: actions.py:39
msgid "View"
msgstr "Voir"
-#: actions.py:32
+#: actions.py:40
msgid "Contribute"
msgstr "Participer"
-#: actions.py:33
+#: actions.py:41
msgid "Add a new point of interest"
msgstr "Ajout d'un point remarquable"
-#: actions.py:34
+#: actions.py:42
msgid "Add a new route"
msgstr "Ajout d'un nouveau trajet"
-#: actions.py:38
+#: actions.py:47
msgid "RSS feeds"
msgstr "Flux RSS"
-#: actions.py:41
+#: actions.py:51
msgid "Contact us"
msgstr "Nous contacter"
@@ -75,57 +75,57 @@ msgstr "Élément modifié traité."
msgid "Managed modified items"
msgstr "Gérer les éléments modifiés"
-#: admin.py:197 admin.py:272
+#: admin.py:197 admin.py:274
msgid "Submitter"
msgstr "Demandeur"
-#: admin.py:202 admin.py:277 admin.py:328
+#: admin.py:202 admin.py:279 admin.py:331
msgid "Import"
msgstr "Import"
-#: admin.py:207 admin.py:282
+#: admin.py:207 admin.py:284
msgid "Associated items"
msgstr "Éléments associés"
-#: admin.py:334
+#: admin.py:337
msgid "Cancel import"
msgstr "Annuler l'import"
-#: admin.py:340
+#: admin.py:343
msgid "Cancel export"
msgstr "Annuler l'export"
-#: admin.py:344
+#: admin.py:347
msgid "Can manage only one OSM export at a time."
msgstr "Ne peux gérer qu'un seul export OSM à la fois."
-#: admin.py:349
+#: admin.py:352
msgid ""
"You must treat all item with the status \"imported\" before exporting to OSM."
msgstr ""
"Vous devez traiter tous les éléments avec le status « importé » avant "
"d'exporter vers OSM."
-#: admin.py:353
+#: admin.py:356
msgid "Only OSM importer are managed for export."
msgstr "Seul les imports de type OSM peuvent être gérés pour les exports."
-#: admin.py:360
+#: admin.py:363
msgid "No point of interest are concerned by this export."
msgstr "Aucun point d'intérêt n'est concerné par cet export."
-#: admin.py:372
+#: admin.py:375
msgid "Export launched."
msgstr "Export lancé."
-#: admin.py:376
+#: admin.py:379
#, python-format
msgid ""
"%s point(s) of interest concerned by this export before bounding box filter."
msgstr ""
"%s point(s) d'intérêt concerné par cet export (avant le filtre sur la zone)"
-#: admin.py:381
+#: admin.py:384
msgid "Export to osm"
msgstr "Exporter vers osm"
@@ -141,50 +141,50 @@ msgstr "Nouveaux points d'intérêt de "
msgid "Last points of interest by area"
msgstr "Nouveaux points d'intérêt par zone"
-#: forms.py:77
+#: forms.py:83
msgid "New submission for"
msgstr "Nouvelle proposition pour"
-#: forms.py:78
+#: forms.py:84
#, python-format
msgid "The new item \"%s\" has been submited in the category: "
msgstr "Le nouvel élément « %s » a été proposé dans la catégorie : "
-#: forms.py:80
+#: forms.py:86
msgid "To valid, precise or unvalid this item: "
msgstr "Pour valider, préciser ou rejeter cet élément : "
-#: forms.py:90
+#: forms.py:96
msgid "Email (optional)"
msgstr "Courriel (optionnel) "
-#: forms.py:91
+#: forms.py:97
msgid "Object"
msgstr "Objet"
-#: forms.py:97
+#: forms.py:117
msgid "OSM user"
msgstr "Utilisateur OSM"
-#: forms.py:98 models.py:1351
+#: forms.py:118 models.py:1500
msgid "Password"
msgstr "Mot de passe"
-#: forms.py:102
+#: forms.py:122
msgid "API"
msgstr "API"
-#: forms.py:105
+#: forms.py:125
#, python-format
msgid "Test API - %s"
msgstr "API de test - %s"
-#: forms.py:107
+#: forms.py:127
#, python-format
msgid "Main API - %s"
msgstr "API principale - %s"
-#: forms.py:138 forms.py:142
+#: forms.py:158 forms.py:162
msgid ""
"For OSM import you must be provide a filter. Select an area and node/way "
"filter."
@@ -192,485 +192,530 @@ msgstr ""
"Pour les imports OSM vous devez fournir un filtre. Sélectionnez une zone et "
"un filtre sur les nœuds/routes."
-#: forms.py:146
+#: forms.py:166
msgid "Shapefiles must be provided in a zipped archive."
msgstr ""
"Les fichiers Shapefiles doivent être fournis regroupés dans une archive zip."
-#: forms.py:150
+#: forms.py:170
msgid "You have to set \"source\" or \"source file\" but not both."
msgstr ""
"Vous devez spécifier le champ « Source » ou « Fichier source » mais pas les "
"deux."
-#: forms.py:155
+#: forms.py:175
msgid "You have to set \"source\" or \"source file\"."
msgstr "Vous devez spécifier le champ « Source » ou « Fichier source »."
-#: forms.py:213
+#: forms.py:236
msgid "End date has been set with no start date"
msgstr "Une date de fin a été donnée sans date de début"
-#: forms.py:217
+#: forms.py:240
msgid "End date can't be before start date"
msgstr "La date de fin ne peut pas être antérieure à la date de début"
-#: forms.py:227
+#: forms.py:250
msgid "This field is mandatory for the selected categories"
msgstr "Ce champ est obligatoire pour les catégories sélectionnées"
-#: forms.py:462
+#: forms.py:501
msgid "File"
msgstr "Fichier"
-#: forms.py:468
+#: forms.py:507
msgid "Bad file format: this must be a GPX or KML file"
msgstr "Mauvais format de fichier : KML et GPX sont supportés"
-#: forms.py:473 models.py:51 models.py:106 models.py:127 models.py:140
-#: models.py:155 models.py:278 models.py:595 models.py:651 models.py:710
-#: models.py:826 models.py:1155 models.py:1167 models.py:1341 utils.py:482
-#: templates/admin/chimere/managed_modified.html:23
+#: forms.py:512 models.py:53 models.py:101 models.py:163 models.py:184
+#: models.py:197 models.py:212 models.py:375 models.py:720 models.py:776
+#: models.py:835 models.py:953 models.py:1304 models.py:1316 models.py:1490
+#: utils.py:485 templates/admin/chimere/managed_modified.html:23
#: templates/chimere/edit.html:40 templates/chimere/edit_route.html:37
-#: templates/chimere/blocks/alternate_multimedia.html:38
+#: templates/chimere/blocks/alternate_multimedia.html:39
msgid "Name"
msgstr "Nom"
-#: forms.py:482 models.py:1204
+#: forms.py:521 models.py:1353
msgid "Area"
msgstr "Zone"
-#: forms.py:522
+#: forms.py:561
msgid "No area selected."
msgstr "Pas de zone sélectionnée."
-#: forms.py:529
+#: forms.py:568
#, python-format
msgid "The area \"%s\" has the same order, you need to choose another one."
msgstr ""
"La zone « %s » a le même numéro d'ordre, vous devez un choisir un autre."
-#: models.py:52 models.py:128 models.py:156 models.py:289 models.py:599
-#: models.py:1173 models.py:1343
+#: forms.py:613
+msgid "Start"
+msgstr "Départ"
+
+#: forms.py:614
+msgid "Finish"
+msgstr "Arrivée"
+
+#: forms.py:615
+msgid "Speed"
+msgstr "Vitesse"
+
+#: models.py:54
+msgid "Mnemonic"
+msgstr "Mnémonique"
+
+#: models.py:56 models.py:102 models.py:185 models.py:213 models.py:368
+#: models.py:724 models.py:1322 models.py:1492 models.py:1533
msgid "Available"
msgstr "Disponible"
-#: models.py:53 models.py:1352
+#: models.py:57 models.py:173 models.py:186 models.py:230 models.py:778
+#: models.py:850 models.py:1321 models.py:1479 models.py:1491
+msgid "Order"
+msgstr "Ordre"
+
+#: models.py:58
+msgid "Template path"
+msgstr "Chemin du patron"
+
+#: models.py:65 models.py:66
+msgid "Page"
+msgstr "Page"
+
+#: models.py:103 models.py:469
+msgid "Is front page"
+msgstr "Est en page principale"
+
+#: models.py:105 models.py:1501
msgid "Date"
msgstr "Date"
-#: models.py:55
+#: models.py:107 models.py:777
+msgid "Url"
+msgstr "Url"
+
+#: models.py:108
msgid "Associated areas"
msgstr "Zones associées"
-#: models.py:61 models.py:62
+#: models.py:114 models.py:115 templates/chimere/blocks/news.html:3
+#: templates/chimere/blocks/news.html:5
msgid "News"
msgstr "Nouvelle"
-#: models.py:67
+#: models.py:124
msgid "Parameters"
msgstr "Paramètres"
-#: models.py:71
+#: models.py:128
msgid "TinyUrl"
msgstr "Mini-url"
-#: models.py:110 models.py:117 models.py:160
+#: models.py:167 models.py:174 models.py:225
msgid "Color theme"
msgstr "Thème de couleur"
-#: models.py:115
+#: models.py:172
msgid "Code"
msgstr "Code"
-#: models.py:116 models.py:129 models.py:162 models.py:653 models.py:725
-#: models.py:1172 models.py:1330 models.py:1342
-msgid "Order"
-msgstr "Ordre"
-
-#: models.py:122
+#: models.py:179
msgid "Color"
msgstr "Couleur"
-#: models.py:135 models.py:153
+#: models.py:192 models.py:210
msgid "Category"
msgstr "Catégorie"
-#: models.py:141 models.py:591 models.py:711 models.py:892
-#: templates/chimere/blocks/alternate_multimedia.html:42
+#: models.py:198 models.py:716 models.py:836 models.py:1019
+#: templates/chimere/blocks/alternate_multimedia.html:43
msgid "Image"
msgstr "Image"
-#: models.py:143 models.py:713 models.py:894
+#: models.py:200 models.py:838 models.py:1021
msgid "Height"
msgstr "Hauteur"
-#: models.py:144 models.py:714 models.py:895
+#: models.py:201 models.py:839 models.py:1022
msgid "Width"
msgstr "Largeur"
-#: models.py:148 models.py:159
+#: models.py:205 models.py:222
msgid "Icon"
msgstr "Icône"
-#: models.py:157
+#: models.py:214
msgid "Available for submission"
msgstr "Disponible pour soumission"
-#: models.py:163
+#: models.py:216
msgid "Marker"
msgstr "Point d'intérêt"
-#: models.py:164 models.py:888 models.py:905
+#: models.py:217 models.py:1015 models.py:1032
#: templates/chimere/edit_route.html:28
msgid "Route"
msgstr "Trajet"
-#: models.py:165
+#: models.py:218
msgid "Both"
msgstr "Mixte"
-#: models.py:166
+#: models.py:219
msgid "Item type"
msgstr "Type d'élément"
-#: models.py:171
+#: models.py:220
+msgid "Is dated"
+msgstr "Est daté"
+
+#: models.py:223
+msgid "Hover icon"
+msgstr "Icône en survol"
+
+#: models.py:227
+msgid "Displayed in the layer menu"
+msgstr "Apparaît dans le menu des couches ?"
+
+#: models.py:229
+msgid "Routing warn"
+msgstr "Avertissement sur les itinéraires"
+
+#: models.py:235
msgid "Sub-category"
msgstr "Sous-catégorie"
-#: models.py:172
+#: models.py:236
msgid "Sub-categories"
msgstr "Sous-catégories"
-#: models.py:230
+#: models.py:320
msgid "Importer type"
msgstr "Type d'import"
-#: models.py:232
+#: models.py:322
msgid "Filter"
msgstr "Filtre"
-#: models.py:234 templates/chimere/blocks/alternate_multimedia.html:48
+#: models.py:324 templates/chimere/blocks/alternate_multimedia.html:49
msgid "Web address"
msgstr "Adresse web"
-#: models.py:236
+#: models.py:326
msgid "Source file"
msgstr "Fichier source"
-#: models.py:238
+#: models.py:328
msgid "Name by default"
msgstr "Nom par défaut"
-#: models.py:240
+#: models.py:330
msgid "SRID"
msgstr "SRID"
-#: models.py:241
+#: models.py:331
msgid "Zipped file"
msgstr "Fichier zippé"
-#: models.py:242
+#: models.py:332
msgid "Overwrite existing data"
msgstr "Écraser les données existantes"
-#: models.py:244
+#: models.py:334
msgid "Get description from source"
-msgstr "Obtenir une description depuis la source de données"
+msgstr "Obtenir une description depuis la source"
-#: models.py:246
+#: models.py:336
msgid "Default description"
msgstr "Description par défaut"
-#: models.py:248 models.py:305
+#: models.py:338 models.py:396
msgid "Origin"
msgstr "Origine"
-#: models.py:250 models.py:307
+#: models.py:340 models.py:398
msgid "License"
msgstr "Licence"
-#: models.py:253
+#: models.py:343
msgid "Associated subcategories"
msgstr "Sous-catégories associées"
-#: models.py:254 utils.py:486
+#: models.py:344 utils.py:489
msgid "State"
msgstr "État"
-#: models.py:256
+#: models.py:346
msgid "Automatically associate a marker to a way"
msgstr "Associer automatiquement un marqueur à une route"
-#: models.py:260
+#: models.py:350
msgid "Importer"
msgstr "Import"
-#: models.py:280
-msgid "Submitter session key"
-msgstr "Clé de session du demandeur"
-
-#: models.py:282
-msgid "Submitter name or nickname"
-msgstr "Nom ou pseudo du demandeur"
-
-#: models.py:284
-msgid "Submitter email"
-msgstr "Courriel du demandeur"
-
-#: models.py:286
-msgid "Submitter comment"
-msgstr "Commentaire du demandeur"
-
-#: models.py:288
+#: models.py:367
msgid "Submited"
msgstr "Soumis"
-#: models.py:290
+#: models.py:369
msgid "Modified"
msgstr "Modifié"
-#: models.py:291
+#: models.py:370
msgid "Disabled"
msgstr "Désactivé"
-#: models.py:292
+#: models.py:371
msgid "Imported"
msgstr "Importé"
-#: models.py:294
+#: models.py:377
+msgid "Submitter session key"
+msgstr "Clé de session du demandeur"
+
+#: models.py:379
+msgid "Submitter name or nickname"
+msgstr "Nom ou pseudo du demandeur"
+
+#: models.py:381
+msgid "Submitter email"
+msgstr "Courriel du demandeur"
+
+#: models.py:383
+msgid "Submitter comment"
+msgstr "Commentaire du demandeur"
+
+#: models.py:385 models.py:1195
msgid "Status"
msgstr "État"
-#: models.py:295
+#: models.py:386
msgid "Import key"
msgstr "Clé d'import"
-#: models.py:297
+#: models.py:388
msgid "Import version"
msgstr "Version de l'import"
-#: models.py:299
+#: models.py:390
msgid "Source"
msgstr "Source"
-#: models.py:301
+#: models.py:392
msgid "Modified since last import"
msgstr "Modifié depuis le dernier import"
-#: models.py:303
+#: models.py:394
msgid "Not to be exported to OSM"
msgstr "À ne pas exporter vers OSM"
-#: models.py:309 templates/chimere/edit.html:57
+#: models.py:400 templates/chimere/edit.html:57
#: templates/chimere/edit_route.html:53
msgid "Start date"
msgstr "Date de début"
-#: models.py:310
+#: models.py:401
msgid "Not mandatory. Set it for dated item such as event. Format YYYY-MM-DD"
msgstr ""
"Optionnel. Précisez ce champ pour les éléments datés comme un événement. "
"Format du champ : AAAA-MM-JJ"
-#: models.py:312 templates/chimere/edit.html:63
+#: models.py:403 templates/chimere/edit.html:63
#: templates/chimere/edit_route.html:59
msgid "End date"
msgstr "Date de fin"
-#: models.py:313
+#: models.py:404
msgid ""
"Not mandatory. Set it only if you have a multi-day event. Format YYYY-MM-DD"
msgstr ""
"Optionnel. Précisez ce champ seulement pour des événements durant plusieurs "
"jours. Format du champ : AAAA-MM-JJ"
-#: models.py:366
+#: models.py:461
msgid "Reference marker"
msgstr "Point d'intérêt de référence"
-#: models.py:367 utils.py:488
+#: models.py:462 utils.py:491
msgid "Localisation"
msgstr "Localisation"
-#: models.py:369
+#: models.py:464
msgid "Available Date"
msgstr "Date de mise en disponibilité"
-#: models.py:373 utils.py:487 templates/admin/chimere/managed_modified.html:31
+#: models.py:468 utils.py:490 templates/admin/chimere/managed_modified.html:31
#: templates/chimere/edit.html:50 templates/chimere/edit_route.html:47
msgid "Description"
msgstr "Description"
-#: models.py:435 models.py:1377
+#: models.py:539 models.py:1543
msgid "Point of interest"
msgstr "Point d'intérêt"
-#: models.py:589
+#: models.py:714
msgid "Audio"
msgstr "Audio"
-#: models.py:590
+#: models.py:715
msgid "Video"
msgstr "Vidéo"
-#: models.py:592
+#: models.py:717
msgid "Other"
msgstr "Autre"
-#: models.py:593
+#: models.py:718
msgid "Media type"
msgstr "Type de media"
-#: models.py:596
+#: models.py:721
msgid "Mime type"
msgstr "Type mime"
-#: models.py:598
+#: models.py:723
msgid "Inside an iframe"
msgstr "À l'intérieur d'un iframe"
-#: models.py:602
+#: models.py:727
msgid "Multimedia type"
msgstr "Type de multimedia"
-#: models.py:603
+#: models.py:728
msgid "Multimedia types"
msgstr "Types de multimedia"
-#: models.py:612
+#: models.py:737
msgid "Automatic recognition"
msgstr "Reconnaissance automatique"
-#: models.py:638
+#: models.py:763
msgid "Extension name"
msgstr "Nom de l'extension"
-#: models.py:640
+#: models.py:765
msgid "Associated multimedia type"
msgstr "Type de multimedia associé"
-#: models.py:644
+#: models.py:769
msgid "Multimedia extension"
msgstr "Extension multimedia"
-#: models.py:645
+#: models.py:770
msgid "Multimedia extensions"
msgstr "Extensions multimedia"
-#: models.py:652
-msgid "Url"
-msgstr "Url"
-
-#: models.py:655 models.py:715
+#: models.py:780 models.py:840
msgid "Display inside the description?"
msgstr "Apparaît dans la description ?"
-#: models.py:660
+#: models.py:785
msgid "Multimedia file"
msgstr "Fichier multimedia"
-#: models.py:661
+#: models.py:786
msgid "Multimedia files"
msgstr "Fichiers multimedias"
-#: models.py:717
+#: models.py:842
msgid "Thumbnail"
msgstr "Miniature"
-#: models.py:721
+#: models.py:846
msgid "Thumbnail height"
msgstr "Hauteur de la miniature"
-#: models.py:723
+#: models.py:848
msgid "Thumbnail width"
msgstr "Largeur de la miniature"
-#: models.py:732
+#: models.py:857
msgid "Picture file"
msgstr "Fichier d'image"
-#: models.py:733
+#: models.py:858
msgid "Picture files"
msgstr "Fichiers d'image"
-#: models.py:827
+#: models.py:954
msgid "Raw file (gpx or kml)"
msgstr "Fichier brut (gpx ou kml)"
-#: models.py:829
+#: models.py:956
msgid "Simplified file"
msgstr "Fichier simplifié"
-#: models.py:831
+#: models.py:958
msgid "KML"
msgstr "KML"
-#: models.py:831
+#: models.py:958
msgid "GPX"
msgstr "GPX"
-#: models.py:836
+#: models.py:963
msgid "Route file"
msgstr "Fichier de trajet"
-#: models.py:837
+#: models.py:964
msgid "Route files"
msgstr "Fichiers de trajet"
-#: models.py:887
+#: models.py:1014
msgid "Reference route"
msgstr "Trajet de référence"
-#: models.py:891
+#: models.py:1018
msgid "Associated file"
msgstr "Fichier associé"
-#: models.py:896
+#: models.py:1023
msgid "Has an associated marker"
msgstr "Dispose d'un marqueur associé"
-#: models.py:1156
+#: models.py:1305
msgid "Layer code"
msgstr "Code pour la couche"
-#: models.py:1162
+#: models.py:1311
msgid "Layer"
msgstr "Couche"
-#: models.py:1168
+#: models.py:1317
msgid "Area urn"
msgstr "Urn de la zone"
-#: models.py:1170 templates/chimere/blocks/welcome.html:3
+#: models.py:1319 templates/chimere/blocks/welcome.html:3
msgid "Welcome message"
msgstr "Message d'accueil"
-#: models.py:1174
+#: models.py:1323
msgid "Upper left corner"
msgstr "Coin en haut à gauche"
-#: models.py:1176
+#: models.py:1325
msgid "Lower right corner"
msgstr "Coin en bas à droite"
-#: models.py:1178
+#: models.py:1327
msgid "Default area"
msgstr "Zone par défaut"
-#: models.py:1179
+#: models.py:1328
msgid "Only one area is set by default"
msgstr "Seule une zone est définie par défaut"
-#: models.py:1183
+#: models.py:1332
msgid "Sub-categories checked by default"
msgstr "Sous-catégories cochées par défaut"
-#: models.py:1185
+#: models.py:1334
msgid "Sub-categories dynamicaly displayed"
msgstr "Sous-categories affichées dynamiquement"
-#: models.py:1186
+#: models.py:1335
msgid ""
"If checked, categories are only displayed in the menu if they are available "
"on the current extent."
@@ -678,64 +723,72 @@ msgstr ""
"Si coché, les catégories sont disponibles sur le menu seulement si elles "
"apparaissent sur la zone affichée."
-#: models.py:1190 models.py:1346
+#: models.py:1339 models.py:1495
msgid "Restricted to theses sub-categories"
msgstr "Restreindre à ces sous-categories"
-#: models.py:1191
+#: models.py:1340
msgid "If no sub-category is set all sub-categories are available"
msgstr ""
"Si aucune sous-catégorie n'est définie toutes les sous-catégories sont "
"disponibles"
-#: models.py:1193
+#: models.py:1342
msgid "Link to an external CSS"
msgstr "Lien vers une feuille de style externe"
-#: models.py:1195
+#: models.py:1344
msgid "Restrict to the area extent"
msgstr "Restreindre à l'étendue de la zone"
-#: models.py:1331
+#: models.py:1480 widgets.py:88
msgid "Default layer"
msgstr "Couche par défaut"
-#: models.py:1335 models.py:1336
+#: models.py:1484 models.py:1485
msgid "Layers"
msgstr "Couches"
-#: models.py:1344
+#: models.py:1493
msgid "Mandatory"
msgstr "Obligatoire"
-#: models.py:1347
+#: models.py:1496
msgid ""
"If no sub-category is set all the property applies to all sub-categories"
msgstr ""
"Si aucune sous-catégorie n'est précisée, cette propriété est disponible pour "
"toutes les sous-catégories"
-#: models.py:1349
+#: models.py:1498
msgid "Text"
msgstr "Texte"
-#: models.py:1350
+#: models.py:1499
msgid "Long text"
msgstr "Texte long"
-#: models.py:1357
+#: models.py:1502
+msgid "Choices"
+msgstr "Choix"
+
+#: models.py:1510
msgid "Type"
msgstr "Type"
-#: models.py:1362 models.py:1379
+#: models.py:1515 models.py:1531 models.py:1545
msgid "Property model"
msgstr "Modèle de propriété"
-#: models.py:1380
+#: models.py:1532 models.py:1546
msgid "Value"
msgstr "Valeur"
-#: models.py:1384
+#: models.py:1538
+msgid "Model property choice"
+msgstr "Choix pour les modèles de propriété"
+
+#: models.py:1557
msgid "Property"
msgstr "Propriété"
@@ -789,69 +842,70 @@ msgstr "Export échoué"
msgid "Export canceled"
msgstr "Export annulé"
-#: utils.py:145 utils.py:194
+#: utils.py:148 utils.py:197
msgid "Bad zip file"
msgstr "Mauvais fichier zip"
-#: utils.py:197
+#: utils.py:200
msgid "Missing file(s) inside the zip file"
msgstr "Fichier(s) manquant(s) dans l'archive zip"
-#: utils.py:238
+#: utils.py:241
msgid "Bad XML file"
msgstr "Mauvais fichier XML"
-#: utils.py:325
+#: utils.py:328
msgid "Error while reading the data source."
msgstr "Erreur lors de la lecture de la source."
-#: utils.py:343
+#: utils.py:346
#, python-format
msgid "SRID cannot be guessed. The default SRID (%s) has been used."
msgstr "Le SRID n'a pu être trouvé. Le SRID par défaut (%s) a été utilisé."
-#: utils.py:364
+#: utils.py:367
+#, python-format
msgid "Type of geographic item (%s) of this shapefile is not managed by Chimère."
msgstr ""
"Les types des éléments géographiques (%s) de ce fichier Shapefile ne sont pas "
-"gérés par Chimère."
+ "gérés par Chimère."
-#: utils.py:384
+#: utils.py:387
msgid "Bad Shapefile"
msgstr "Mauvais fichier Shapefile"
-#: utils.py:426
+#: utils.py:429
msgid "Could not create file!"
msgstr "Ne peut pas créer le fichier !"
-#: utils.py:437
+#: utils.py:440
msgid "Failed to create field"
msgstr "Ne peut pas créer un champ"
-#: utils.py:483 templates/admin/chimere/managed_modified.html:25
+#: utils.py:486 templates/admin/chimere/managed_modified.html:25
#: templates/chimere/edit.html:45 templates/chimere/edit_route.html:42
#: templates/chimere/main_map.html:13
#: templates/chimere/main_map_simple.html:10
msgid "Categories"
msgstr "Catégories"
-#: utils.py:516
+#: utils.py:519
msgid "Invalid CSV format"
msgstr "Fichier CSV non valide"
-#: utils.py:594
+#: utils.py:597
msgid "RSS feed is not well formed"
msgstr "Flux RSS non valide"
-#: utils.py:670
+#: utils.py:673
msgid "Nothing to import"
msgstr "Rien à importer"
-#: utils.py:754
+#: utils.py:757
msgid "New items imported - validate them before exporting"
msgstr "Nouveaux éléments importés - valider ceux-ci avant d'exporter"
-#: utils.py:756
+#: utils.py:759
msgid ""
"There are items from a former import not yet validated - validate them "
"before exporting"
@@ -859,19 +913,19 @@ msgstr ""
"Il y a des éléments d'un import précédent pas encore validé - Validez les "
"avant d'exporter"
-#: utils.py:768
+#: utils.py:771
msgid "Bad params - programming error"
msgstr "Mauvais paramètres - erreur de programmation"
-#: utils.py:778
+#: utils.py:781
msgid "Bad param"
msgstr "Mauvais paramètre"
-#: utils.py:793
+#: utils.py:796
msgid "No non ambigious tag is defined in the XAPI request"
msgstr "Pas de tag non ambigü définis dans la requête XAPI"
-#: utils.py:795
+#: utils.py:798
msgid ""
"No bounding box is defined in the XAPI request.If you are sure to manage the "
"entire planet set the bounding box to -180,-90,180,90"
@@ -880,19 +934,19 @@ msgstr ""
"vouloir lancer la requête sur la planète entière fixez la « bounding box » "
"à -180,-90,180,90"
-#: views.py:240
+#: views.py:290
msgid "There are missing field(s) and/or errors in the submited form."
msgstr "Il y a des champs manquants ou des erreurs dans ce formulaire."
-#: views.py:325
+#: views.py:375
msgid "Bad file. Please check it with an external software."
msgstr "Fichier incohérent. Merci de le vérifier avec un logiciel externe."
-#: views.py:435
+#: views.py:487
msgid "Comments/request on the map"
msgstr "Commentaires/requètes sur la carte"
-#: views.py:438
+#: views.py:490
msgid ""
"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."
@@ -901,48 +955,56 @@ msgstr ""
"laissé votre courriel vous serez peut-être contacté bientôt pour plus de "
"détails."
-#: views.py:442
+#: views.py:494
msgid "Temporary error. Renew your message later."
msgstr "Erreur temporaire. Réenvoyez votre message plus tard."
-#: views.py:578
+#: views.py:663
msgid "No category available in this area."
msgstr "Pas de catégorie disponible sur cette zone."
-#: views.py:686
+#: views.py:763
+msgid "Bad geometry"
+msgstr "Géométrie incorrecte"
+
+#: views.py:848
msgid "Incorrect choice in the list"
msgstr "Choix incorrect dans la liste"
-#: widgets.py:216
+#: widgets.py:242
+msgid "Street, City, Country"
+msgstr "Rue, Commune, Pays"
+
+#: widgets.py:311
msgid "Latitude"
msgstr "Latitude"
-#: widgets.py:216
+#: widgets.py:311
msgid "Longitude"
msgstr "Longitude"
-#: widgets.py:240
+#: widgets.py:335
msgid "Invalid point"
msgstr "Point invalide"
-#: widgets.py:292
+#: widgets.py:391
msgid "Creation mode"
msgstr "Mode création"
-#: widgets.py:293
+#: widgets.py:392
msgid "To start drawing the route click on the toggle button: \"Draw\"."
msgstr ""
"Pour commencer le dessin cliquez sur le bouton&nbsp;: «&nbsp;Tracer&nbsp;»."
-#: widgets.py:295
+#: widgets.py:394
msgid "Then click on the map to begin the drawing."
msgstr "Puis cliquez sur la carte pour commencer le dessin."
-#: widgets.py:296
+#: widgets.py:395
msgid "You can add points by clicking again."
msgstr "Vous pouvez ajouter des points en cliquant de nouveau."
-#: widgets.py:297
+#: widgets.py:396
msgid ""
"To finish the drawing double click. When the drawing is finished you can "
"edit it."
@@ -950,7 +1012,7 @@ msgstr ""
"Pour finir le tracé double-cliquez. Quand le tracé est fini vous pouvez "
"toujours l'éditer."
-#: widgets.py:299
+#: widgets.py:398
msgid ""
"While creating to undo a drawing click again on the toggle button \"Stop "
"drawing\"."
@@ -958,17 +1020,17 @@ msgstr ""
"En mode création vous pouvez annuler un tracé en appuyant sur le bouton "
"«&nbsp;Arrêter le tracé&nbsp;»."
-#: widgets.py:304
+#: widgets.py:403
msgid "Modification mode"
msgstr "Mode modification"
-#: widgets.py:305
+#: widgets.py:404
msgid "To move a point click on it and drag it to the desired position."
msgstr ""
"Pour bouger un point, cliquez dessus, maintenez le click pour le déposer à "
"la position désirée."
-#: widgets.py:306
+#: widgets.py:405
msgid ""
"To delete a point move the mouse cursor over it and press the \"d\" or \"Del"
"\" key."
@@ -976,7 +1038,7 @@ msgstr ""
"Pour supprimer un point, mettez le curseur de la souris sur celui-ci et "
"appuyez sur le touche «&nbsp;d&nbsp;» ou «&nbsp;Suppr&nbsp;»."
-#: widgets.py:308
+#: widgets.py:407
msgid ""
"To add a point click in the middle of a segment and drag the new point to "
"the desired position"
@@ -985,51 +1047,51 @@ msgstr ""
"maintenez le bouton appuyé et déplacez le nouveau point à la position "
"désirée."
-#: widgets.py:315
+#: widgets.py:414
msgid "Give a name and set category before uploading a file."
msgstr ""
"Renseignez le nom et choisissez au moins une catégorie avant de déposer un "
"fichier."
-#: widgets.py:318
+#: widgets.py:417
msgid "Upload a route file (GPX or KML)"
msgstr "Déposer un trajet (fichier GPX ou KML)"
-#: widgets.py:319
+#: widgets.py:418
msgid "or"
msgstr "ou"
-#: widgets.py:324
+#: widgets.py:423
msgid "Start \"hand\" drawing"
msgstr "Commencer le tracé manuellement"
-#: widgets.py:347
+#: widgets.py:446
msgid "Move on the map"
msgstr "Se déplacer"
-#: widgets.py:347
+#: widgets.py:446
msgid "Draw"
msgstr "Tracer"
-#: widgets.py:437
+#: widgets.py:536
msgid "Hold CTRL, click and drag to select area on the map"
msgstr ""
"Maintenir la touche Control, cliquez puis glissez pour sélectionner une zone "
"sur la carte"
-#: widgets.py:494
+#: widgets.py:593
msgid "Type:"
msgstr "Type :"
-#: widgets.py:494
+#: widgets.py:593
msgid "Node"
msgstr "Nœud"
-#: widgets.py:495
+#: widgets.py:594
msgid "Way"
msgstr "Route"
-#: widgets.py:506
+#: widgets.py:605
msgid ""
"Enter an OSM \"tag=value\" string such as \"amenity=pub\". A list of common "
"tag is available <a href='https://wiki.openstreetmap.org/wiki/Map_Features' "
@@ -1039,39 +1101,39 @@ msgstr ""
"liste des clés est disponible <a href='https://wiki.openstreetmap.org/wiki/"
"FR:Map_Features' target='_blank'>ici</a>."
-#: widgets.py:513
+#: widgets.py:612
msgid "Tag:"
msgstr "Clé/valeur :"
-#: widgets.py:517
+#: widgets.py:616
msgid "You have to select an area."
msgstr "Vous devez sélectionner une zone."
-#: widgets.py:519
+#: widgets.py:618
msgid "You have to select a type."
msgstr "Vous devez sélectionner un type."
-#: widgets.py:521
+#: widgets.py:620
msgid "You have to insert a filter tag."
msgstr "Vous devez saisir une clé=valeur."
-#: widgets.py:523
+#: widgets.py:622
msgid "If you change the above form don't forget to refresh before submit!"
msgstr ""
"Si vous modifiez le formulaire ci-dessus n'oubliez pas de rafraîchir avant "
"de valider !"
-#: widgets.py:526
+#: widgets.py:625
msgid "You can put a Folder name of the KML file to filter on it."
msgstr ""
"Vous pouvez saisir le nom d'un « Folder » du fichier KML pour filter sur "
"celui-ci."
-#: widgets.py:534
+#: widgets.py:633
msgid "Refresh"
msgstr "Rafraîchir"
-#: widgets.py:600
+#: widgets.py:699
msgid "Select..."
msgstr "Sélectionner..."
@@ -1166,7 +1228,7 @@ msgstr ""
"Après ajout/modification de modèle de propriété vous aurez à recharger le "
"serveur web."
-#: templates/chimere/base.html:11
+#: templates/chimere/base.html:12
msgid "You must enable JavaScript in your browser to display Chimère."
msgstr ""
"Vous devez activer le JavaScript dans votre navigateur pour afficher Chimère."
@@ -1210,14 +1272,6 @@ msgstr "Proposer une modification"
msgid "I would like to propose an amendment for this item:"
msgstr "Je souhaiterais proposer une modification pour cet élément :"
-#: templates/chimere/detail.html:40
-msgid "Share on"
-msgstr "Partager sur"
-
-#: templates/chimere/detail.html:44
-msgid "Share"
-msgstr "Partager"
-
#: templates/chimere/edit.html:20
msgid "Error"
msgstr "Erreur"
@@ -1279,7 +1333,7 @@ msgstr "Commentaires au sujet de votre proposition"
msgid "Upload in progress. Please wait..."
msgstr "Dépôt en cours. Veuillez patienter..."
-#: templates/chimere/edit.html:152 templates/chimere/edit_route.html:78
+#: templates/chimere/edit.html:153 templates/chimere/edit_route.html:78
msgid "Propose"
msgstr "Proposez"
@@ -1291,7 +1345,7 @@ msgstr "Modifier un trajet"
msgid "Add a route"
msgstr "Ajout d'un nouveau trajet"
-#: templates/chimere/main_map.html:27
+#: templates/chimere/main_map.html:35
msgid "Simple map"
msgstr "Carte simple"
@@ -1307,17 +1361,17 @@ msgstr "Déposer un fichier"
msgid "Upload"
msgstr "Déposer"
-#: templates/chimere/blocks/alternate_multimedia.html:32
-#: templates/chimere/blocks/alternate_multimedia.html:50
+#: templates/chimere/blocks/alternate_multimedia.html:33
+#: templates/chimere/blocks/alternate_multimedia.html:51
#: templates/chimere/blocks/inline_formset.html:22
msgid "Add"
msgstr "Ajouter"
-#: templates/chimere/blocks/alternate_multimedia.html:34
-msgid "Add multimedia from your computer or a site"
+#: templates/chimere/blocks/alternate_multimedia.html:35
+msgid "Add multimedia from your computer or a website"
msgstr "Ajoutez du multimedia depuis votre ordinateur ou un site web"
-#: templates/chimere/blocks/alternate_multimedia.html:35
+#: templates/chimere/blocks/alternate_multimedia.html:36
msgid ""
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu luctus "
"ipsum. Donec vel urna a turpis consectetur consectetur. Vestibulum ut enim "
@@ -1327,31 +1381,31 @@ msgstr ""
"ipsum. Donec vel urna a turpis consectetur consectetur. Vestibulum ut enim "
"vel odio porta vulputate."
-#: templates/chimere/blocks/alternate_multimedia.html:43
+#: templates/chimere/blocks/alternate_multimedia.html:44
msgid "Audio, video, other..."
msgstr "Audio, vidéo, autre..."
-#: templates/chimere/blocks/alternate_multimedia.html:46
+#: templates/chimere/blocks/alternate_multimedia.html:47
msgid "Download"
msgstr "Télécharger"
-#: templates/chimere/blocks/alternate_multimedia.html:47
+#: templates/chimere/blocks/alternate_multimedia.html:48
msgid "Or"
msgstr "Ou"
-#: templates/chimere/blocks/alternate_multimedia.html:76
+#: templates/chimere/blocks/alternate_multimedia.html:80
msgid "You must provide a name."
msgstr "Vous devez renseigner le nom."
-#: templates/chimere/blocks/alternate_multimedia.html:81
+#: templates/chimere/blocks/alternate_multimedia.html:85
msgid "You must choose a media type."
msgstr "Vous devez renseigner un type de fichier média."
-#: templates/chimere/blocks/alternate_multimedia.html:87
+#: templates/chimere/blocks/alternate_multimedia.html:91
msgid "You must provide a file or a web address."
msgstr "Vous devez renseigner un fichier ou une adresse web."
-#: templates/chimere/blocks/alternate_multimedia.html:92
+#: templates/chimere/blocks/alternate_multimedia.html:96
msgid "You must provide a web address."
msgstr "Vous devez fournir une adresse web."
@@ -1390,16 +1444,101 @@ msgstr "Carte"
msgid "Loading of the map in progress"
msgstr "Chargement de la carte en cours"
-#: templates/chimere/blocks/map.html:18
+#: templates/chimere/blocks/map.html:13
+msgid "Display options"
+msgstr "Options d'affichage"
+
+#: templates/chimere/blocks/map.html:15
+msgid "Map type"
+msgstr "Type de carte"
+
+#: templates/chimere/blocks/map.html:24
msgid "Permalink"
msgstr "Lien permanent"
+#: templates/chimere/blocks/map_menu.html:5
+msgctxt "routing"
+msgid "From"
+msgstr "En partir"
+
+#: templates/chimere/blocks/map_menu.html:6
+msgctxt "routing"
+msgid "Add a step"
+msgstr "Ajout d'une étape"
+
+#: templates/chimere/blocks/map_menu.html:7
+msgctxt "routing"
+msgid "To"
+msgstr "Y aller"
+
+#: templates/chimere/blocks/map_menu.html:8
+msgctxt "routing"
+msgid "Clear the itinerary"
+msgstr "Effacer l'itinéraire"
+
+#: templates/chimere/blocks/map_menu.html:10
+msgid "Zoom in"
+msgstr "Zoomer en avant"
+
+#: templates/chimere/blocks/map_menu.html:11
+msgid "Zoom out"
+msgstr "Zoomer en arrière"
+
+#: templates/chimere/blocks/map_menu.html:12
+msgid "Center the map here"
+msgstr "Centrer la carte ici"
+
#: templates/chimere/blocks/multimedia_file.html:19
msgid "Please use a modern browser or install the non free Flash-Plugin."
msgstr ""
"Utilisez un navigateur internet plus récent ou installez le greffon non "
"libre Flash."
+#: templates/chimere/blocks/news.html:42
+#: templates/chimere/blocks/welcome.html:52
+msgid "See it on the map"
+msgstr "Voir sur la carte"
+
+#: templates/chimere/blocks/routing.html:5
+msgid "Itinerary"
+msgstr "Itinéraire"
+
+#: templates/chimere/blocks/routing.html:16
+msgid "Add a step"
+msgstr "Ajouter une étape"
+
+#: templates/chimere/blocks/routing.html:17
+msgid "Search"
+msgstr "Rechercher"
+
+#: templates/chimere/blocks/routing.html:23
+msgid "Modify"
+msgstr "Modifier"
+
+#: templates/chimere/blocks/routing.html:26
+msgid "New search"
+msgstr "Nouvelle recherche"
+
+#: templates/chimere/blocks/routing.html:34
+msgid "Start:"
+msgstr "Départ :"
+
+#: templates/chimere/blocks/routing.html:38
+msgid "Finish:"
+msgstr "Arrivée :"
+
+#: templates/chimere/blocks/routing.html:44
+msgid "Step"
+msgstr "Étape"
+
+#: templates/chimere/blocks/share_bar.html:3
+msgid "Share on"
+msgstr "Partager sur"
+
+#: templates/chimere/blocks/share_bar.html:7
+msgid "Share"
+msgstr "Partager"
+
#: templates/chimere/blocks/submited.html:3
msgid ""
"Your new proposition/modification has been submited. A moderator will treat "
@@ -1428,10 +1567,6 @@ msgstr "Retourner à la carte"
msgid "Welcome"
msgstr "Accueil"
-#: templates/chimere/blocks/welcome.html:52
-msgid "See it on the map"
-msgstr "Voir sur la carte"
-
#: templates/chimere/feeds/rss.html:13
msgid "Subscribe to RSS feed"
msgstr "Souscrire à un flux RSS"
@@ -1472,6 +1607,11 @@ msgstr "Description :"
msgid ":"
msgstr " :"
+#: templatetags/chimere_tags.py:80
+#, python-format
+msgid "Welcome to the %s"
+msgstr "Bienvenue sur %s"
+
#~ msgid "Advanced options"
#~ msgstr "Options avancées"
diff --git a/chimere/migrations/0001_initial.py b/chimere/migrations/0001_initial.py
index 74f67a6..c98ec01 100644
--- a/chimere/migrations/0001_initial.py
+++ b/chimere/migrations/0001_initial.py
@@ -1,319 +1,605 @@
-# encoding: utf-8
+# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+
class Migration(SchemaMigration):
-
+
def forwards(self, orm):
-
# Adding model 'News'
- db.create_table('main_news', (
- ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
- ('date', self.gf('django.db.models.fields.DateField')(auto_now_add=True, blank=True)),
- ('content', self.gf('django.db.models.fields.TextField')()),
+ db.create_table('chimere_news', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('date', self.gf('django.db.models.fields.DateField')(auto_now_add=True, blank=True)),
+ ('content', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal('chimere', ['News'])
+ # Adding M2M table for field areas on 'News'
+ db.create_table('chimere_news_areas', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('news', models.ForeignKey(orm['chimere.news'], null=False)),
+ ('area', models.ForeignKey(orm['chimere.area'], null=False))
+ ))
+ db.create_unique('chimere_news_areas', ['news_id', 'area_id'])
+
# Adding model 'TinyUrl'
- db.create_table('main_tinyurl', (
+ db.create_table('chimere_tinyurl', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('parameters', self.gf('django.db.models.fields.CharField')(max_length=500)),
))
db.send_create_signal('chimere', ['TinyUrl'])
# Adding model 'ColorTheme'
- db.create_table('main_colortheme', (
+ db.create_table('chimere_colortheme', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
))
db.send_create_signal('chimere', ['ColorTheme'])
# Adding model 'Color'
- db.create_table('main_color', (
- ('code', self.gf('django.db.models.fields.CharField')(max_length=6)),
- ('color_theme', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.ColorTheme'])),
+ db.create_table('chimere_color', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('code', self.gf('django.db.models.fields.CharField')(max_length=6)),
('order', self.gf('django.db.models.fields.IntegerField')()),
+ ('color_theme', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.ColorTheme'])),
))
db.send_create_signal('chimere', ['Color'])
# Adding model 'Category'
- db.create_table('main_category', (
- ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
- ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
- ('order', self.gf('django.db.models.fields.IntegerField')()),
+ db.create_table('chimere_category', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('order', self.gf('django.db.models.fields.IntegerField')()),
+ ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
))
db.send_create_signal('chimere', ['Category'])
# Adding model 'Icon'
- db.create_table('main_icon', (
- ('width', self.gf('django.db.models.fields.IntegerField')()),
- ('image', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
- ('height', self.gf('django.db.models.fields.IntegerField')()),
+ db.create_table('chimere_icon', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('image', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
+ ('height', self.gf('django.db.models.fields.IntegerField')()),
+ ('width', self.gf('django.db.models.fields.IntegerField')()),
))
db.send_create_signal('chimere', ['Icon'])
# Adding model 'SubCategory'
- db.create_table('main_subcategory', (
- ('category', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Category'])),
- ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
- ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
- ('order', self.gf('django.db.models.fields.IntegerField')()),
- ('item_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
- ('color_theme', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.ColorTheme'], null=True, blank=True)),
+ db.create_table('chimere_subcategory', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('category', self.gf('django.db.models.fields.related.ForeignKey')(related_name='subcategories', to=orm['chimere.Category'])),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('submission', self.gf('django.db.models.fields.BooleanField')(default=True)),
('icon', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Icon'])),
+ ('color_theme', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.ColorTheme'], null=True, blank=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')(default=1000)),
+ ('item_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
))
db.send_create_signal('chimere', ['SubCategory'])
- # Adding M2M table for field areas on 'SubCategory'
- db.create_table('main_subcategory_areas', (
+ # Adding model 'Importer'
+ db.create_table('chimere_importer', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('importer_type', self.gf('django.db.models.fields.CharField')(max_length=4)),
+ ('filtr', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('source', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('source_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
+ ('default_name', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('srid', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('zipped', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('overwrite', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('get_description', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('default_description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ('origin', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
+ ('license', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
+ ('state', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('associate_marker_to_way', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ))
+ db.send_create_signal('chimere', ['Importer'])
+
+ # Adding M2M table for field categories on 'Importer'
+ db.create_table('chimere_importer_categories', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
- ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False)),
- ('area', models.ForeignKey(orm['chimere.area'], null=False))
+ ('importer', models.ForeignKey(orm['chimere.importer'], null=False)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
))
- db.create_unique('main_subcategory_areas', ['subcategory_id', 'area_id'])
+ db.create_unique('chimere_importer_categories', ['importer_id', 'subcategory_id'])
# Adding model 'Marker'
- db.create_table('main_marker', (
- ('status', self.gf('django.db.models.fields.CharField')(max_length=1)),
- ('picture', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True)),
+ db.create_table('chimere_marker', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('submiter_session_key', self.gf('django.db.models.fields.CharField')(max_length=40, null=True, blank=True)),
+ ('submiter_name', self.gf('django.db.models.fields.CharField')(max_length=40, null=True, blank=True)),
+ ('submiter_email', self.gf('django.db.models.fields.EmailField')(max_length=75, null=True, blank=True)),
+ ('submiter_comment', self.gf('django.db.models.fields.TextField')(max_length=200, null=True, blank=True)),
+ ('status', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('import_key', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('import_version', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('import_source', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('modified_since_import', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('not_for_osm', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('origin', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
+ ('license', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
+ ('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
('end_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+ ('ref_item', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='submited_marker', null=True, to=orm['chimere.Marker'])),
('point', self.gf('chimere.widgets.PointField')()),
- ('route', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Route'], null=True, blank=True)),
- ('height', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
- ('width', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
- ('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
('available_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
- ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('route', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='associated_marker', null=True, to=orm['chimere.Route'])),
+ ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
))
db.send_create_signal('chimere', ['Marker'])
# Adding M2M table for field categories on 'Marker'
- db.create_table('main_marker_categories', (
+ db.create_table('chimere_marker_categories', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('marker', models.ForeignKey(orm['chimere.marker'], null=False)),
('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
))
- db.create_unique('main_marker_categories', ['marker_id', 'subcategory_id'])
+ db.create_unique('chimere_marker_categories', ['marker_id', 'subcategory_id'])
+
+ # Adding model 'MultimediaType'
+ db.create_table('chimere_multimediatype', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('media_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('mime_type', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)),
+ ('iframe', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ))
+ db.send_create_signal('chimere', ['MultimediaType'])
+
+ # Adding model 'MultimediaExtension'
+ db.create_table('chimere_multimediaextension', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=6)),
+ ('multimedia_type', self.gf('django.db.models.fields.related.ForeignKey')(related_name='extensions', to=orm['chimere.MultimediaType'])),
+ ))
+ db.send_create_signal('chimere', ['MultimediaExtension'])
+
+ # Adding model 'MultimediaFile'
+ db.create_table('chimere_multimediafile', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('url', self.gf('django.db.models.fields.URLField')(max_length=200)),
+ ('order', self.gf('django.db.models.fields.IntegerField')(default=1)),
+ ('multimedia_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.MultimediaType'], null=True, blank=True)),
+ ('miniature', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('marker', self.gf('django.db.models.fields.related.ForeignKey')(related_name='multimedia_files', to=orm['chimere.Marker'])),
+ ))
+ db.send_create_signal('chimere', ['MultimediaFile'])
+
+ # Adding model 'PictureFile'
+ db.create_table('chimere_picturefile', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('picture', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
+ ('height', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('width', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('miniature', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('thumbnailfile', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True)),
+ ('thumbnailfile_height', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('thumbnailfile_width', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')(default=1)),
+ ('marker', self.gf('django.db.models.fields.related.ForeignKey')(related_name='pictures', to=orm['chimere.Marker'])),
+ ))
+ db.send_create_signal('chimere', ['PictureFile'])
# Adding model 'RouteFile'
- db.create_table('main_routefile', (
- ('file_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
- ('raw_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
- ('simplified_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
+ db.create_table('chimere_routefile', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('raw_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+ ('simplified_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
+ ('file_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
))
db.send_create_signal('chimere', ['RouteFile'])
# Adding model 'Route'
- db.create_table('main_route', (
- ('status', self.gf('django.db.models.fields.CharField')(max_length=1)),
- ('picture', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True)),
+ db.create_table('chimere_route', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('submiter_session_key', self.gf('django.db.models.fields.CharField')(max_length=40, null=True, blank=True)),
+ ('submiter_name', self.gf('django.db.models.fields.CharField')(max_length=40, null=True, blank=True)),
+ ('submiter_email', self.gf('django.db.models.fields.EmailField')(max_length=75, null=True, blank=True)),
+ ('submiter_comment', self.gf('django.db.models.fields.TextField')(max_length=200, null=True, blank=True)),
+ ('status', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('import_key', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('import_version', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('import_source', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+ ('modified_since_import', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('not_for_osm', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('origin', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
+ ('license', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
+ ('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
('end_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+ ('ref_item', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='submited_route', null=True, to=orm['chimere.Route'])),
('route', self.gf('chimere.widgets.RouteField')()),
+ ('associated_file', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.RouteFile'], null=True, blank=True)),
+ ('picture', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True)),
('height', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
('width', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
- ('associated_file', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.RouteFile'], null=True, blank=True)),
- ('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
- ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('has_associated_marker', self.gf('django.db.models.fields.BooleanField')(default=True)),
))
db.send_create_signal('chimere', ['Route'])
# Adding M2M table for field categories on 'Route'
- db.create_table('main_route_categories', (
+ db.create_table('chimere_route_categories', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('route', models.ForeignKey(orm['chimere.route'], null=False)),
('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
))
- db.create_unique('main_route_categories', ['route_id', 'subcategory_id'])
+ db.create_unique('chimere_route_categories', ['route_id', 'subcategory_id'])
- # Adding model 'Area'
- db.create_table('main_area', (
- ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ # Adding model 'Layer'
+ db.create_table('chimere_layer', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
- ('urn', self.gf('django.db.models.fields.SlugField')(db_index=True, unique=True, max_length=50, blank=True)),
+ ('layer_code', self.gf('django.db.models.fields.TextField')(max_length=300)),
+ ))
+ db.send_create_signal('chimere', ['Layer'])
+
+ # Adding model 'Area'
+ db.create_table('chimere_area', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('urn', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, blank=True)),
+ ('welcome_message', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')(unique=True)),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False)),
('upper_left_corner', self.gf('django.contrib.gis.db.models.fields.PointField')(default='POINT(0 0)')),
- ('order', self.gf('django.db.models.fields.IntegerField')()),
('lower_right_corner', self.gf('django.contrib.gis.db.models.fields.PointField')(default='POINT(0 0)')),
+ ('default', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)),
+ ('dynamic_categories', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)),
+ ('external_css', self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True)),
+ ('restrict_to_extent', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal('chimere', ['Area'])
- # Adding model 'PropertyModel'
- db.create_table('main_propertymodel', (
- ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ # Adding M2M table for field default_subcategories on 'Area'
+ db.create_table('chimere_area_default_subcategories', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('area', models.ForeignKey(orm['chimere.area'], null=False)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
+ ))
+ db.create_unique('chimere_area_default_subcategories', ['area_id', 'subcategory_id'])
+
+ # Adding M2M table for field subcategories on 'Area'
+ db.create_table('chimere_subcategory_areas', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('area', models.ForeignKey(orm['chimere.area'], null=False)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
+ ))
+ db.create_unique('chimere_subcategory_areas', ['area_id', 'subcategory_id'])
+
+ # Adding model 'AreaLayers'
+ db.create_table('chimere_arealayers', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('area', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Area'])),
+ ('layer', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Layer'])),
('order', self.gf('django.db.models.fields.IntegerField')()),
- ('type', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('default', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)),
+ ))
+ db.send_create_signal('chimere', ['AreaLayers'])
+
+ # Adding model 'PropertyModel'
+ db.create_table('chimere_propertymodel', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('order', self.gf('django.db.models.fields.IntegerField')()),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('mandatory', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('type', self.gf('django.db.models.fields.CharField')(max_length=1)),
))
db.send_create_signal('chimere', ['PropertyModel'])
+ # Adding M2M table for field subcategories on 'PropertyModel'
+ db.create_table('chimere_propertymodel_subcategories', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('propertymodel', models.ForeignKey(orm['chimere.propertymodel'], null=False)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
+ ))
+ db.create_unique('chimere_propertymodel_subcategories', ['propertymodel_id', 'subcategory_id'])
+
# Adding model 'Property'
- db.create_table('main_property', (
- ('marker', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Marker'])),
+ db.create_table('chimere_property', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('value', self.gf('django.db.models.fields.TextField')()),
+ ('marker', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Marker'])),
('propertymodel', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.PropertyModel'])),
+ ('value', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal('chimere', ['Property'])
-
-
+
+
def backwards(self, orm):
-
# Deleting model 'News'
- db.delete_table('main_news')
+ db.delete_table('chimere_news')
+
+ # Removing M2M table for field areas on 'News'
+ db.delete_table('chimere_news_areas')
# Deleting model 'TinyUrl'
- db.delete_table('main_tinyurl')
+ db.delete_table('chimere_tinyurl')
# Deleting model 'ColorTheme'
- db.delete_table('main_colortheme')
+ db.delete_table('chimere_colortheme')
# Deleting model 'Color'
- db.delete_table('main_color')
+ db.delete_table('chimere_color')
# Deleting model 'Category'
- db.delete_table('main_category')
+ db.delete_table('chimere_category')
# Deleting model 'Icon'
- db.delete_table('main_icon')
+ db.delete_table('chimere_icon')
# Deleting model 'SubCategory'
- db.delete_table('main_subcategory')
+ db.delete_table('chimere_subcategory')
+
+ # Deleting model 'Importer'
+ db.delete_table('chimere_importer')
- # Removing M2M table for field areas on 'SubCategory'
- db.delete_table('main_subcategory_areas')
+ # Removing M2M table for field categories on 'Importer'
+ db.delete_table('chimere_importer_categories')
# Deleting model 'Marker'
- db.delete_table('main_marker')
+ db.delete_table('chimere_marker')
# Removing M2M table for field categories on 'Marker'
- db.delete_table('main_marker_categories')
+ db.delete_table('chimere_marker_categories')
+
+ # Deleting model 'MultimediaType'
+ db.delete_table('chimere_multimediatype')
+
+ # Deleting model 'MultimediaExtension'
+ db.delete_table('chimere_multimediaextension')
+
+ # Deleting model 'MultimediaFile'
+ db.delete_table('chimere_multimediafile')
+
+ # Deleting model 'PictureFile'
+ db.delete_table('chimere_picturefile')
# Deleting model 'RouteFile'
- db.delete_table('main_routefile')
+ db.delete_table('chimere_routefile')
# Deleting model 'Route'
- db.delete_table('main_route')
+ db.delete_table('chimere_route')
# Removing M2M table for field categories on 'Route'
- db.delete_table('main_route_categories')
+ db.delete_table('chimere_route_categories')
+
+ # Deleting model 'Layer'
+ db.delete_table('chimere_layer')
# Deleting model 'Area'
- db.delete_table('main_area')
+ db.delete_table('chimere_area')
+
+ # Removing M2M table for field default_subcategories on 'Area'
+ db.delete_table('chimere_area_default_subcategories')
+
+ # Removing M2M table for field subcategories on 'Area'
+ db.delete_table('chimere_subcategory_areas')
+
+ # Deleting model 'AreaLayers'
+ db.delete_table('chimere_arealayers')
# Deleting model 'PropertyModel'
- db.delete_table('main_propertymodel')
+ db.delete_table('chimere_propertymodel')
+
+ # Removing M2M table for field subcategories on 'PropertyModel'
+ db.delete_table('chimere_propertymodel_subcategories')
# Deleting model 'Property'
- db.delete_table('main_property')
-
-
+ db.delete_table('chimere_property')
+
+
models = {
'chimere.area': {
- 'Meta': {'object_name': 'Area', 'db_table': "'main_area'"},
- 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'dynamic_categories': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}),
'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
- 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
+ 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}),
'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
- 'urn': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'unique': 'True', 'max_length': '50', 'blank': 'True'})
+ 'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.arealayers': {
+ 'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'},
+ 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
},
'chimere.category': {
- 'Meta': {'object_name': 'Category', 'db_table': "'main_category'"},
- 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'Meta': {'ordering': "['order']", 'object_name': 'Category'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
'order': ('django.db.models.fields.IntegerField', [], {})
},
'chimere.color': {
- 'Meta': {'object_name': 'Color', 'db_table': "'main_color'"},
+ 'Meta': {'ordering': "['order']", 'object_name': 'Color'},
'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}),
'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {})
},
'chimere.colortheme': {
- 'Meta': {'object_name': 'ColorTheme', 'db_table': "'main_colortheme'"},
+ 'Meta': {'object_name': 'ColorTheme'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
},
'chimere.icon': {
- 'Meta': {'object_name': 'Icon', 'db_table': "'main_icon'"},
+ 'Meta': {'object_name': 'Icon'},
'height': ('django.db.models.fields.IntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
'width': ('django.db.models.fields.IntegerField', [], {})
},
+ 'chimere.importer': {
+ 'Meta': {'object_name': 'Importer'},
+ 'associate_marker_to_way': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'default_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'default_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'filtr': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'get_description': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'overwrite': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'source_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'chimere.layer': {
+ 'Meta': {'object_name': 'Layer'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
'chimere.marker': {
- 'Meta': {'object_name': 'Marker', 'db_table': "'main_marker'"},
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'},
+ 'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
- 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'point': ('chimere.widgets.PointField', [], {}),
- 'route': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Route']", 'null': 'True', 'blank': 'True'}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}),
+ 'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
- 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.multimediaextension': {
+ 'Meta': {'object_name': 'MultimediaExtension'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'extensions'", 'to': "orm['chimere.MultimediaType']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '6'})
+ },
+ 'chimere.multimediafile': {
+ 'Meta': {'object_name': 'MultimediaFile'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']", 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'chimere.multimediatype': {
+ 'Meta': {'object_name': 'MultimediaType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
},
'chimere.news': {
- 'Meta': {'object_name': 'News', 'db_table': "'main_news'"},
- 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'Meta': {'object_name': 'News'},
+ 'areas': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'to': "orm['chimere.Area']", 'null': 'True', 'blank': 'True'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'content': ('django.db.models.fields.TextField', [], {}),
'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '150'})
},
+ 'chimere.picturefile': {
+ 'Meta': {'object_name': 'PictureFile'},
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'thumbnailfile': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'thumbnailfile_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'thumbnailfile_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
'chimere.property': {
- 'Meta': {'object_name': 'Property', 'db_table': "'main_property'"},
+ 'Meta': {'object_name': 'Property'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}),
'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}),
'value': ('django.db.models.fields.TextField', [], {})
},
'chimere.propertymodel': {
- 'Meta': {'object_name': 'PropertyModel', 'db_table': "'main_propertymodel'"},
- 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mandatory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'properties'", 'blank': 'True', 'to': "orm['chimere.SubCategory']"}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '1'})
},
'chimere.route': {
- 'Meta': {'object_name': 'Route', 'db_table': "'main_route'"},
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'},
'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}),
'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'has_associated_marker': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}),
'route': ('chimere.widgets.RouteField', [], {}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
},
'chimere.routefile': {
- 'Meta': {'object_name': 'RouteFile', 'db_table': "'main_routefile'"},
+ 'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'},
'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
@@ -321,22 +607,22 @@ class Migration(SchemaMigration):
'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
},
'chimere.subcategory': {
- 'Meta': {'object_name': 'SubCategory', 'db_table': "'main_subcategory'"},
- 'areas': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'to': "orm['chimere.Area']"}),
- 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
- 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Category']"}),
+ 'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subcategories'", 'to': "orm['chimere.Category']"}),
'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}),
'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
- 'order': ('django.db.models.fields.IntegerField', [], {})
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1000'}),
+ 'submission': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'chimere.tinyurl': {
- 'Meta': {'object_name': 'TinyUrl', 'db_table': "'main_tinyurl'"},
+ 'Meta': {'object_name': 'TinyUrl'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'})
}
}
-
- complete_apps = ['chimere']
+
+ complete_apps = ['chimere'] \ No newline at end of file
diff --git a/chimere/migrations/0002_auto__add_propertymodelchoice__add_page__add_field_subcategory_dated__.py b/chimere/migrations/0002_auto__add_propertymodelchoice__add_page__add_field_subcategory_dated__.py
new file mode 100644
index 0000000..e9dd34c
--- /dev/null
+++ b/chimere/migrations/0002_auto__add_propertymodelchoice__add_page__add_field_subcategory_dated__.py
@@ -0,0 +1,361 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'PropertyModelChoice'
+ db.create_table('chimere_propertymodelchoice', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('propertymodel', self.gf('django.db.models.fields.related.ForeignKey')(related_name='choices', to=orm['chimere.PropertyModel'])),
+ ('value', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ))
+ db.send_create_signal('chimere', ['PropertyModelChoice'])
+
+ # Adding model 'Page'
+ db.create_table('chimere_page', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('mnemonic', self.gf('django.db.models.fields.CharField')(max_length=10, null=True, blank=True)),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')(default=10, null=True, blank=True)),
+ ('template_path', self.gf('django.db.models.fields.CharField')(max_length=150, null=True, blank=True)),
+ ('content', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ))
+ db.send_create_signal('chimere', ['Page'])
+
+ # Adding field 'SubCategory.dated'
+ db.add_column('chimere_subcategory', 'dated',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
+
+ # Adding field 'SubCategory.description'
+ db.add_column('chimere_subcategory', 'description',
+ self.gf('django.db.models.fields.TextField')(null=True, blank=True),
+ keep_default=False)
+
+ # Adding field 'SubCategory.hover_icon'
+ db.add_column('chimere_subcategory', 'hover_icon',
+ self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='subcat_hovered', null=True, to=orm['chimere.Icon']),
+ keep_default=False)
+
+ # Adding field 'SubCategory.as_layer'
+ db.add_column('chimere_subcategory', 'as_layer',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
+
+ # Adding field 'SubCategory.routing_warn'
+ db.add_column('chimere_subcategory', 'routing_warn',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
+
+ # Adding field 'News.is_front_page'
+ db.add_column('chimere_news', 'is_front_page',
+ self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True),
+ keep_default=False)
+
+ # Adding field 'News.url'
+ db.add_column('chimere_news', 'url',
+ self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True),
+ keep_default=False)
+
+ # Adding field 'Marker.is_front_page'
+ db.add_column('chimere_marker', 'is_front_page',
+ self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting model 'PropertyModelChoice'
+ db.delete_table('chimere_propertymodelchoice')
+
+ # Deleting model 'Page'
+ db.delete_table('chimere_page')
+
+ # Deleting field 'SubCategory.dated'
+ db.delete_column('chimere_subcategory', 'dated')
+
+ # Deleting field 'SubCategory.description'
+ db.delete_column('chimere_subcategory', 'description')
+
+ # Deleting field 'SubCategory.hover_icon'
+ db.delete_column('chimere_subcategory', 'hover_icon_id')
+
+ # Deleting field 'SubCategory.as_layer'
+ db.delete_column('chimere_subcategory', 'as_layer')
+
+ # Deleting field 'SubCategory.routing_warn'
+ db.delete_column('chimere_subcategory', 'routing_warn')
+
+ # Deleting field 'News.is_front_page'
+ db.delete_column('chimere_news', 'is_front_page')
+
+ # Deleting field 'News.url'
+ db.delete_column('chimere_news', 'url')
+
+ # Deleting field 'Marker.is_front_page'
+ db.delete_column('chimere_marker', 'is_front_page')
+
+
+ models = {
+ 'chimere.aggregatedroute': {
+ 'Meta': {'object_name': 'AggregatedRoute', 'db_table': "'chimere_aggregated_routes'", 'managed': 'False'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'route': ('django.contrib.gis.db.models.fields.MultiLineStringField', [], {}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'subcategory': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.SubCategory']"})
+ },
+ 'chimere.area': {
+ 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'dynamic_categories': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}),
+ 'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
+ 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}),
+ 'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.arealayers': {
+ 'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'},
+ 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.category': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Category'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.color': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Color'},
+ 'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.colortheme': {
+ 'Meta': {'object_name': 'ColorTheme'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.icon': {
+ 'Meta': {'object_name': 'Icon'},
+ 'height': ('django.db.models.fields.IntegerField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.importer': {
+ 'Meta': {'object_name': 'Importer'},
+ 'associate_marker_to_way': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'default_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'default_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'filtr': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'get_description': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'overwrite': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'source_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'chimere.layer': {
+ 'Meta': {'object_name': 'Layer'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.marker': {
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'},
+ 'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'point': ('chimere.widgets.PointField', [], {}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}),
+ 'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.multimediaextension': {
+ 'Meta': {'object_name': 'MultimediaExtension'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'extensions'", 'to': "orm['chimere.MultimediaType']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '6'})
+ },
+ 'chimere.multimediafile': {
+ 'Meta': {'object_name': 'MultimediaFile'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']", 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'chimere.multimediatype': {
+ 'Meta': {'object_name': 'MultimediaType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.news': {
+ 'Meta': {'object_name': 'News'},
+ 'areas': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'to': "orm['chimere.Area']", 'null': 'True', 'blank': 'True'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'content': ('django.db.models.fields.TextField', [], {}),
+ 'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.page': {
+ 'Meta': {'object_name': 'Page'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mnemonic': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '10', 'null': 'True', 'blank': 'True'}),
+ 'template_path': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.picturefile': {
+ 'Meta': {'object_name': 'PictureFile'},
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'thumbnailfile': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'thumbnailfile_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'thumbnailfile_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.property': {
+ 'Meta': {'object_name': 'Property'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}),
+ 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}),
+ 'value': ('django.db.models.fields.TextField', [], {})
+ },
+ 'chimere.propertymodel': {
+ 'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mandatory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'properties'", 'blank': 'True', 'to': "orm['chimere.SubCategory']"}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '1'})
+ },
+ 'chimere.propertymodelchoice': {
+ 'Meta': {'object_name': 'PropertyModelChoice'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'choices'", 'to': "orm['chimere.PropertyModel']"}),
+ 'value': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.route': {
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'},
+ 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'has_associated_marker': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}),
+ 'route': ('chimere.widgets.RouteField', [], {}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.routefile': {
+ 'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'},
+ 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+ 'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.subcategory': {
+ 'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'},
+ 'as_layer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subcategories'", 'to': "orm['chimere.Category']"}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}),
+ 'dated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'hover_icon': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subcat_hovered'", 'null': 'True', 'to': "orm['chimere.Icon']"}),
+ 'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1000'}),
+ 'routing_warn': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'submission': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'chimere.tinyurl': {
+ 'Meta': {'object_name': 'TinyUrl'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ }
+ }
+
+ complete_apps = ['chimere'] \ No newline at end of file
diff --git a/chimere/migrations/0003_create_aggregate_route_view.py b/chimere/migrations/0003_create_aggregate_route_view.py
new file mode 100644
index 0000000..ca32eb6
--- /dev/null
+++ b/chimere/migrations/0003_create_aggregate_route_view.py
@@ -0,0 +1,290 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ sql = """
+ create view chimere_aggregated_routes (id, subcategory_id, status, route) as
+ SELECT row_number()
+ OVER (ORDER BY "chimere_route_categories"."subcategory_id",
+ "chimere_route"."status"),
+ "chimere_route_categories"."subcategory_id", "chimere_route"."status",
+ ST_Multi(ST_Collect("chimere_route"."route")) FROM "chimere_route"
+ LEFT OUTER JOIN "chimere_route_categories" ON (
+ "chimere_route"."id" = "chimere_route_categories"."route_id")
+ WHERE ("chimere_route"."start_date" IS NULL
+ OR ("chimere_route"."start_date" <= CURRENT_DATE
+ AND "chimere_route"."start_date" >= CURRENT_DATE)
+ OR ("chimere_route"."start_date" <= CURRENT_DATE
+ AND "chimere_route"."end_date" >= CURRENT_DATE))
+ GROUP BY "chimere_route_categories"."subcategory_id",
+ "chimere_route"."status";
+ """
+ db.execute(sql)
+
+ def backwards(self, orm):
+ sql = "drop view chimere_aggregated_routes;"
+ db.execute(sql)
+
+ models = {
+ 'chimere.aggregatedroute': {
+ 'Meta': {'object_name': 'AggregatedRoute', 'db_table': "'chimere_aggregated_routes'", 'managed': 'False'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'route': ('django.contrib.gis.db.models.fields.MultiLineStringField', [], {}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'subcategory': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.SubCategory']"})
+ },
+ 'chimere.area': {
+ 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'dynamic_categories': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}),
+ 'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
+ 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}),
+ 'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.arealayers': {
+ 'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'},
+ 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.category': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Category'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.color': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Color'},
+ 'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.colortheme': {
+ 'Meta': {'object_name': 'ColorTheme'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.icon': {
+ 'Meta': {'object_name': 'Icon'},
+ 'height': ('django.db.models.fields.IntegerField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.importer': {
+ 'Meta': {'object_name': 'Importer'},
+ 'associate_marker_to_way': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'default_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'default_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'filtr': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'get_description': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'overwrite': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'source_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'chimere.layer': {
+ 'Meta': {'object_name': 'Layer'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.marker': {
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'},
+ 'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'point': ('chimere.widgets.PointField', [], {}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}),
+ 'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.multimediaextension': {
+ 'Meta': {'object_name': 'MultimediaExtension'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'extensions'", 'to': "orm['chimere.MultimediaType']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '6'})
+ },
+ 'chimere.multimediafile': {
+ 'Meta': {'object_name': 'MultimediaFile'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']", 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'chimere.multimediatype': {
+ 'Meta': {'object_name': 'MultimediaType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.news': {
+ 'Meta': {'object_name': 'News'},
+ 'areas': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'to': "orm['chimere.Area']", 'null': 'True', 'blank': 'True'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'content': ('django.db.models.fields.TextField', [], {}),
+ 'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.page': {
+ 'Meta': {'object_name': 'Page'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mnemonic': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '10', 'null': 'True', 'blank': 'True'}),
+ 'template_path': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.picturefile': {
+ 'Meta': {'object_name': 'PictureFile'},
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'thumbnailfile': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'thumbnailfile_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'thumbnailfile_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.property': {
+ 'Meta': {'object_name': 'Property'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}),
+ 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}),
+ 'value': ('django.db.models.fields.TextField', [], {})
+ },
+ 'chimere.propertymodel': {
+ 'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mandatory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'properties'", 'blank': 'True', 'to': "orm['chimere.SubCategory']"}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '1'})
+ },
+ 'chimere.propertymodelchoice': {
+ 'Meta': {'object_name': 'PropertyModelChoice'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'choices'", 'to': "orm['chimere.PropertyModel']"}),
+ 'value': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.route': {
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'},
+ 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'has_associated_marker': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}),
+ 'route': ('chimere.widgets.RouteField', [], {}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.routefile': {
+ 'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'},
+ 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+ 'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.subcategory': {
+ 'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'},
+ 'as_layer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subcategories'", 'to': "orm['chimere.Category']"}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}),
+ 'dated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'hover_icon': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subcat_hovered'", 'null': 'True', 'to': "orm['chimere.Icon']"}),
+ 'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1000'}),
+ 'routing_warn': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'submission': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'chimere.tinyurl': {
+ 'Meta': {'object_name': 'TinyUrl'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ }
+ }
+
+ complete_apps = ['chimere']
diff --git a/chimere/models.py b/chimere/models.py
index 25bc708..545d7e0 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,
@@ -274,6 +364,13 @@ class Importer(models.Model):
def display_categories(self):
return u"\n".join([cat.name for cat in self.categories.all()])
+STATUS = (('S', _(u'Submited')),
+ ('A', _(u'Available')),
+ ('M', _(u'Modified')),
+ ('D', _(u'Disabled')),
+ ('I', _(u'Imported')))
+STATUS_DCT = dict(STATUS)
+
class GeographicItem(models.Model):
name = models.CharField(_(u"Name"), max_length=150)
categories = SelectMultipleField(SubCategory)
@@ -285,12 +382,6 @@ class GeographicItem(models.Model):
null=True)
submiter_comment = models.TextField(_(u"Submitter comment"), max_length=200,
blank=True, null=True)
- STATUS = (('S', _(u'Submited')),
- ('A', _(u'Available')),
- ('M', _(u'Modified')),
- ('D', _(u'Disabled')),
- ('I', _(u'Imported')))
- STATUS_DCT = dict(STATUS)
status = models.CharField(_(u"Status"), max_length=1, choices=STATUS)
import_key = models.CharField(_(u"Import key"), max_length=200,
blank=True, null=True)
@@ -349,6 +440,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
@@ -371,6 +466,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):
@@ -379,7 +476,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 = ''
@@ -426,6 +523,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
@@ -481,6 +582,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,
@@ -512,12 +625,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
@@ -1067,6 +1186,28 @@ def getDateCondition():
date_condition += "%(alias)s.end_date >='" + now + "')) "
return date_condition
+class AggregatedRoute(models.Model):
+ '''
+ Database view for aggregated routes
+ '''
+ route = models.MultiLineStringField()
+ subcategory = models.ForeignKey(SubCategory)
+ status = models.CharField(_(u"Status"), max_length=1, choices=STATUS)
+ class Meta:
+ managed = False
+ db_table = 'chimere_aggregated_routes'
+
+ def getGeoJSON(self, color="#000"):
+ '''Return a GeoJSON string
+ '''
+ if '#' not in color:
+ color = '#' + color
+ attributes = {'id':self.id, 'name':json.dumps(u'Aggregated route'),
+ 'color':color, 'geometry':self.route.geojson,}
+ return u'{"type":"Feature", "geometry":%(geometry)s, '\
+ u'"properties":{"pk": %(id)d, "name": %(name)s, '\
+ u'"color":"%(color)s"}}' % attributes
+
class SimplePoint:
"""
Point in the map (not in the database)
@@ -1357,11 +1498,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
@@ -1379,6 +1524,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
'''
@@ -1387,7 +1545,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")
@@ -1398,6 +1563,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
diff --git a/chimere/old_migrations/v2.0/0001_initial.py b/chimere/old_migrations/v2.0/0001_initial.py
new file mode 100644
index 0000000..74f67a6
--- /dev/null
+++ b/chimere/old_migrations/v2.0/0001_initial.py
@@ -0,0 +1,342 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'News'
+ db.create_table('main_news', (
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('date', self.gf('django.db.models.fields.DateField')(auto_now_add=True, blank=True)),
+ ('content', self.gf('django.db.models.fields.TextField')()),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ))
+ db.send_create_signal('chimere', ['News'])
+
+ # Adding model 'TinyUrl'
+ db.create_table('main_tinyurl', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('parameters', self.gf('django.db.models.fields.CharField')(max_length=500)),
+ ))
+ db.send_create_signal('chimere', ['TinyUrl'])
+
+ # Adding model 'ColorTheme'
+ db.create_table('main_colortheme', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ))
+ db.send_create_signal('chimere', ['ColorTheme'])
+
+ # Adding model 'Color'
+ db.create_table('main_color', (
+ ('code', self.gf('django.db.models.fields.CharField')(max_length=6)),
+ ('color_theme', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.ColorTheme'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')()),
+ ))
+ db.send_create_signal('chimere', ['Color'])
+
+ # Adding model 'Category'
+ db.create_table('main_category', (
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')()),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ))
+ db.send_create_signal('chimere', ['Category'])
+
+ # Adding model 'Icon'
+ db.create_table('main_icon', (
+ ('width', self.gf('django.db.models.fields.IntegerField')()),
+ ('image', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
+ ('height', self.gf('django.db.models.fields.IntegerField')()),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ))
+ db.send_create_signal('chimere', ['Icon'])
+
+ # Adding model 'SubCategory'
+ db.create_table('main_subcategory', (
+ ('category', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Category'])),
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('order', self.gf('django.db.models.fields.IntegerField')()),
+ ('item_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('color_theme', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.ColorTheme'], null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('icon', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Icon'])),
+ ))
+ db.send_create_signal('chimere', ['SubCategory'])
+
+ # Adding M2M table for field areas on 'SubCategory'
+ db.create_table('main_subcategory_areas', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False)),
+ ('area', models.ForeignKey(orm['chimere.area'], null=False))
+ ))
+ db.create_unique('main_subcategory_areas', ['subcategory_id', 'area_id'])
+
+ # Adding model 'Marker'
+ db.create_table('main_marker', (
+ ('status', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('picture', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('end_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+ ('point', self.gf('chimere.widgets.PointField')()),
+ ('route', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Route'], null=True, blank=True)),
+ ('height', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('width', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+ ('available_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('chimere', ['Marker'])
+
+ # Adding M2M table for field categories on 'Marker'
+ db.create_table('main_marker_categories', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('marker', models.ForeignKey(orm['chimere.marker'], null=False)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
+ ))
+ db.create_unique('main_marker_categories', ['marker_id', 'subcategory_id'])
+
+ # Adding model 'RouteFile'
+ db.create_table('main_routefile', (
+ ('file_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('raw_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+ ('simplified_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ))
+ db.send_create_signal('chimere', ['RouteFile'])
+
+ # Adding model 'Route'
+ db.create_table('main_route', (
+ ('status', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('picture', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('end_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+ ('route', self.gf('chimere.widgets.RouteField')()),
+ ('height', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('width', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('associated_file', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.RouteFile'], null=True, blank=True)),
+ ('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('chimere', ['Route'])
+
+ # Adding M2M table for field categories on 'Route'
+ db.create_table('main_route_categories', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('route', models.ForeignKey(orm['chimere.route'], null=False)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
+ ))
+ db.create_unique('main_route_categories', ['route_id', 'subcategory_id'])
+
+ # Adding model 'Area'
+ db.create_table('main_area', (
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ('urn', self.gf('django.db.models.fields.SlugField')(db_index=True, unique=True, max_length=50, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('upper_left_corner', self.gf('django.contrib.gis.db.models.fields.PointField')(default='POINT(0 0)')),
+ ('order', self.gf('django.db.models.fields.IntegerField')()),
+ ('lower_right_corner', self.gf('django.contrib.gis.db.models.fields.PointField')(default='POINT(0 0)')),
+ ))
+ db.send_create_signal('chimere', ['Area'])
+
+ # Adding model 'PropertyModel'
+ db.create_table('main_propertymodel', (
+ ('available', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')()),
+ ('type', self.gf('django.db.models.fields.CharField')(max_length=1)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=150)),
+ ))
+ db.send_create_signal('chimere', ['PropertyModel'])
+
+ # Adding model 'Property'
+ db.create_table('main_property', (
+ ('marker', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Marker'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('value', self.gf('django.db.models.fields.TextField')()),
+ ('propertymodel', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.PropertyModel'])),
+ ))
+ db.send_create_signal('chimere', ['Property'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'News'
+ db.delete_table('main_news')
+
+ # Deleting model 'TinyUrl'
+ db.delete_table('main_tinyurl')
+
+ # Deleting model 'ColorTheme'
+ db.delete_table('main_colortheme')
+
+ # Deleting model 'Color'
+ db.delete_table('main_color')
+
+ # Deleting model 'Category'
+ db.delete_table('main_category')
+
+ # Deleting model 'Icon'
+ db.delete_table('main_icon')
+
+ # Deleting model 'SubCategory'
+ db.delete_table('main_subcategory')
+
+ # Removing M2M table for field areas on 'SubCategory'
+ db.delete_table('main_subcategory_areas')
+
+ # Deleting model 'Marker'
+ db.delete_table('main_marker')
+
+ # Removing M2M table for field categories on 'Marker'
+ db.delete_table('main_marker_categories')
+
+ # Deleting model 'RouteFile'
+ db.delete_table('main_routefile')
+
+ # Deleting model 'Route'
+ db.delete_table('main_route')
+
+ # Removing M2M table for field categories on 'Route'
+ db.delete_table('main_route_categories')
+
+ # Deleting model 'Area'
+ db.delete_table('main_area')
+
+ # Deleting model 'PropertyModel'
+ db.delete_table('main_propertymodel')
+
+ # Deleting model 'Property'
+ db.delete_table('main_property')
+
+
+ models = {
+ 'chimere.area': {
+ 'Meta': {'object_name': 'Area', 'db_table': "'main_area'"},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'urn': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'unique': 'True', 'max_length': '50', 'blank': 'True'})
+ },
+ 'chimere.category': {
+ 'Meta': {'object_name': 'Category', 'db_table': "'main_category'"},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.color': {
+ 'Meta': {'object_name': 'Color', 'db_table': "'main_color'"},
+ 'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.colortheme': {
+ 'Meta': {'object_name': 'ColorTheme', 'db_table': "'main_colortheme'"},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.icon': {
+ 'Meta': {'object_name': 'Icon', 'db_table': "'main_icon'"},
+ 'height': ('django.db.models.fields.IntegerField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.marker': {
+ 'Meta': {'object_name': 'Marker', 'db_table': "'main_marker'"},
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'point': ('chimere.widgets.PointField', [], {}),
+ 'route': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Route']", 'null': 'True', 'blank': 'True'}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.news': {
+ 'Meta': {'object_name': 'News', 'db_table': "'main_news'"},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'content': ('django.db.models.fields.TextField', [], {}),
+ 'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.property': {
+ 'Meta': {'object_name': 'Property', 'db_table': "'main_property'"},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}),
+ 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}),
+ 'value': ('django.db.models.fields.TextField', [], {})
+ },
+ 'chimere.propertymodel': {
+ 'Meta': {'object_name': 'PropertyModel', 'db_table': "'main_propertymodel'"},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '1'})
+ },
+ 'chimere.route': {
+ 'Meta': {'object_name': 'Route', 'db_table': "'main_route'"},
+ 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'route': ('chimere.widgets.RouteField', [], {}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.routefile': {
+ 'Meta': {'object_name': 'RouteFile', 'db_table': "'main_routefile'"},
+ 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+ 'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.subcategory': {
+ 'Meta': {'object_name': 'SubCategory', 'db_table': "'main_subcategory'"},
+ 'areas': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'to': "orm['chimere.Area']"}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Category']"}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}),
+ 'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.tinyurl': {
+ 'Meta': {'object_name': 'TinyUrl', 'db_table': "'main_tinyurl'"},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ }
+ }
+
+ complete_apps = ['chimere']
diff --git a/chimere/migrations/0002_rename_models.py b/chimere/old_migrations/v2.0/0002_rename_models.py
index 32aabc7..32aabc7 100644
--- a/chimere/migrations/0002_rename_models.py
+++ b/chimere/old_migrations/v2.0/0002_rename_models.py
diff --git a/chimere/migrations/0003_auto__add_field_route_submiter_session_key__add_field_route_submiter_e.py b/chimere/old_migrations/v2.0/0003_auto__add_field_route_submiter_session_key__add_field_route_submiter_e.py
index 11ce001..11ce001 100644
--- a/chimere/migrations/0003_auto__add_field_route_submiter_session_key__add_field_route_submiter_e.py
+++ b/chimere/old_migrations/v2.0/0003_auto__add_field_route_submiter_session_key__add_field_route_submiter_e.py
diff --git a/chimere/migrations/0004_auto__add_picturefile__add_multimediafile.py b/chimere/old_migrations/v2.0/0004_auto__add_picturefile__add_multimediafile.py
index cfa1db0..cfa1db0 100644
--- a/chimere/migrations/0004_auto__add_picturefile__add_multimediafile.py
+++ b/chimere/old_migrations/v2.0/0004_auto__add_picturefile__add_multimediafile.py
diff --git a/chimere/migrations/0005_auto__add_multimediatype__add_field_picturefile_order__del_field_multi.py b/chimere/old_migrations/v2.0/0005_auto__add_multimediatype__add_field_picturefile_order__del_field_multi.py
index fd7a86b..fd7a86b 100644
--- a/chimere/migrations/0005_auto__add_multimediatype__add_field_picturefile_order__del_field_multi.py
+++ b/chimere/old_migrations/v2.0/0005_auto__add_multimediatype__add_field_picturefile_order__del_field_multi.py
diff --git a/chimere/migrations/0006_auto__add_importer__add_field_route_import_key__add_field_marker_impor.py b/chimere/old_migrations/v2.0/0006_auto__add_importer__add_field_route_import_key__add_field_marker_impor.py
index 3157039..3157039 100644
--- a/chimere/migrations/0006_auto__add_importer__add_field_route_import_key__add_field_marker_impor.py
+++ b/chimere/old_migrations/v2.0/0006_auto__add_importer__add_field_route_import_key__add_field_marker_impor.py
diff --git a/chimere/migrations/0007_auto__add_field_marker_description.py b/chimere/old_migrations/v2.0/0007_auto__add_field_marker_description.py
index 99382d5..99382d5 100644
--- a/chimere/migrations/0007_auto__add_field_marker_description.py
+++ b/chimere/old_migrations/v2.0/0007_auto__add_field_marker_description.py
diff --git a/chimere/migrations/0008_auto__del_field_importer_subcategory__add_field_route_import_source__a.py b/chimere/old_migrations/v2.0/0008_auto__del_field_importer_subcategory__add_field_route_import_source__a.py
index c40b027..c40b027 100644
--- a/chimere/migrations/0008_auto__del_field_importer_subcategory__add_field_route_import_source__a.py
+++ b/chimere/old_migrations/v2.0/0008_auto__del_field_importer_subcategory__add_field_route_import_source__a.py
diff --git a/chimere/migrations/0009_auto__add_field_importer_state.py b/chimere/old_migrations/v2.0/0009_auto__add_field_importer_state.py
index 42d1048..42d1048 100644
--- a/chimere/migrations/0009_auto__add_field_importer_state.py
+++ b/chimere/old_migrations/v2.0/0009_auto__add_field_importer_state.py
diff --git a/chimere/migrations/0010_auto__add_field_route_import_version__add_field_marker_import_version.py b/chimere/old_migrations/v2.0/0010_auto__add_field_route_import_version__add_field_marker_import_version.py
index c94710f..c94710f 100644
--- a/chimere/migrations/0010_auto__add_field_route_import_version__add_field_marker_import_version.py
+++ b/chimere/old_migrations/v2.0/0010_auto__add_field_route_import_version__add_field_marker_import_version.py
diff --git a/chimere/migrations/0011_auto__del_field_importer_source_url__add_field_importer_source.py b/chimere/old_migrations/v2.0/0011_auto__del_field_importer_source_url__add_field_importer_source.py
index 31ce4d8..31ce4d8 100644
--- a/chimere/migrations/0011_auto__del_field_importer_source_url__add_field_importer_source.py
+++ b/chimere/old_migrations/v2.0/0011_auto__del_field_importer_source_url__add_field_importer_source.py
diff --git a/chimere/migrations/0012_auto__chg_field_picturefile_name__chg_field_multimediafile_url__chg_fi.py b/chimere/old_migrations/v2.0/0012_auto__chg_field_picturefile_name__chg_field_multimediafile_url__chg_fi.py
index fc6007c..fc6007c 100644
--- a/chimere/migrations/0012_auto__chg_field_picturefile_name__chg_field_multimediafile_url__chg_fi.py
+++ b/chimere/old_migrations/v2.0/0012_auto__chg_field_picturefile_name__chg_field_multimediafile_url__chg_fi.py
diff --git a/chimere/migrations/0013_auto__add_field_multimediafile_miniature.py b/chimere/old_migrations/v2.0/0013_auto__add_field_multimediafile_miniature.py
index bc9e003..bc9e003 100644
--- a/chimere/migrations/0013_auto__add_field_multimediafile_miniature.py
+++ b/chimere/old_migrations/v2.0/0013_auto__add_field_multimediafile_miniature.py
diff --git a/chimere/migrations/0014_auto__add_field_picturefile_marker__add_field_multimediafile_marker__a.py b/chimere/old_migrations/v2.0/0014_auto__add_field_picturefile_marker__add_field_multimediafile_marker__a.py
index 5c059fd..5c059fd 100644
--- a/chimere/migrations/0014_auto__add_field_picturefile_marker__add_field_multimediafile_marker__a.py
+++ b/chimere/old_migrations/v2.0/0014_auto__add_field_picturefile_marker__add_field_multimediafile_marker__a.py
diff --git a/chimere/migrations/0015_auto__chg_field_picturefile_marker__chg_field_multimediafile_marker.py b/chimere/old_migrations/v2.0/0015_auto__chg_field_picturefile_marker__chg_field_multimediafile_marker.py
index 83c7535..83c7535 100644
--- a/chimere/migrations/0015_auto__chg_field_picturefile_marker__chg_field_multimediafile_marker.py
+++ b/chimere/old_migrations/v2.0/0015_auto__chg_field_picturefile_marker__chg_field_multimediafile_marker.py
diff --git a/chimere/migrations/0016_auto__add_field_importer_zipped.py b/chimere/old_migrations/v2.0/0016_auto__add_field_importer_zipped.py
index 9df4d91..9df4d91 100644
--- a/chimere/migrations/0016_auto__add_field_importer_zipped.py
+++ b/chimere/old_migrations/v2.0/0016_auto__add_field_importer_zipped.py
diff --git a/chimere/migrations/0017_auto__add_field_importer_srid.py b/chimere/old_migrations/v2.0/0017_auto__add_field_importer_srid.py
index 378da72..378da72 100644
--- a/chimere/migrations/0017_auto__add_field_importer_srid.py
+++ b/chimere/old_migrations/v2.0/0017_auto__add_field_importer_srid.py
diff --git a/chimere/migrations/0018_auto__add_layer__add_arealayers.py b/chimere/old_migrations/v2.0/0018_auto__add_layer__add_arealayers.py
index 0ea2062..0ea2062 100644
--- a/chimere/migrations/0018_auto__add_layer__add_arealayers.py
+++ b/chimere/old_migrations/v2.0/0018_auto__add_layer__add_arealayers.py
diff --git a/chimere/migrations/0019_auto__chg_field_layer_layer_code__add_field_area_welcome_message.py b/chimere/old_migrations/v2.0/0019_auto__chg_field_layer_layer_code__add_field_area_welcome_message.py
index d6475c1..d6475c1 100644
--- a/chimere/migrations/0019_auto__chg_field_layer_layer_code__add_field_area_welcome_message.py
+++ b/chimere/old_migrations/v2.0/0019_auto__chg_field_layer_layer_code__add_field_area_welcome_message.py
diff --git a/chimere/migrations/0020_auto.py b/chimere/old_migrations/v2.0/0020_auto.py
index e7f4d70..e7f4d70 100644
--- a/chimere/migrations/0020_auto.py
+++ b/chimere/old_migrations/v2.0/0020_auto.py
diff --git a/chimere/migrations/0021_auto.py b/chimere/old_migrations/v2.0/0021_auto.py
index 9193147..9193147 100644
--- a/chimere/migrations/0021_auto.py
+++ b/chimere/old_migrations/v2.0/0021_auto.py
diff --git a/chimere/migrations/0022_auto__add_field_area_external_css.py b/chimere/old_migrations/v2.0/0022_auto__add_field_area_external_css.py
index 206b6d8..206b6d8 100644
--- a/chimere/migrations/0022_auto__add_field_area_external_css.py
+++ b/chimere/old_migrations/v2.0/0022_auto__add_field_area_external_css.py
diff --git a/chimere/migrations/0023_auto__add_field_area_restrict_to_extent.py b/chimere/old_migrations/v2.0/0023_auto__add_field_area_restrict_to_extent.py
index 742793c..742793c 100644
--- a/chimere/migrations/0023_auto__add_field_area_restrict_to_extent.py
+++ b/chimere/old_migrations/v2.0/0023_auto__add_field_area_restrict_to_extent.py
diff --git a/chimere/migrations/0024_auto__add_field_marker_available_date.py b/chimere/old_migrations/v2.0/0024_auto__add_field_marker_available_date.py
index 78b5a68..78b5a68 100644
--- a/chimere/migrations/0024_auto__add_field_marker_available_date.py
+++ b/chimere/old_migrations/v2.0/0024_auto__add_field_marker_available_date.py
diff --git a/chimere/migrations/0025_auto__add_field_area_dynamic_categories.py b/chimere/old_migrations/v2.0/0025_auto__add_field_area_dynamic_categories.py
index ac8b62e..ac8b62e 100644
--- a/chimere/migrations/0025_auto__add_field_area_dynamic_categories.py
+++ b/chimere/old_migrations/v2.0/0025_auto__add_field_area_dynamic_categories.py
diff --git a/chimere/migrations/0026_auto__add_field_marker_submiter_name__add_field_route_submiter_name.py b/chimere/old_migrations/v2.0/0026_auto__add_field_marker_submiter_name__add_field_route_submiter_name.py
index 9965ec1..9965ec1 100644
--- a/chimere/migrations/0026_auto__add_field_marker_submiter_name__add_field_route_submiter_name.py
+++ b/chimere/old_migrations/v2.0/0026_auto__add_field_marker_submiter_name__add_field_route_submiter_name.py
diff --git a/chimere/migrations/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py b/chimere/old_migrations/v2.0/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py
index 53ee3d4..53ee3d4 100644
--- a/chimere/migrations/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py
+++ b/chimere/old_migrations/v2.0/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py
diff --git a/chimere/migrations/0028_auto__add_field_picturefile_thumbnailfile__add_field_picturefile_thumb.py b/chimere/old_migrations/v2.0/0028_auto__add_field_picturefile_thumbnailfile__add_field_picturefile_thumb.py
index 2f81645..2f81645 100644
--- a/chimere/migrations/0028_auto__add_field_picturefile_thumbnailfile__add_field_picturefile_thumb.py
+++ b/chimere/old_migrations/v2.0/0028_auto__add_field_picturefile_thumbnailfile__add_field_picturefile_thumb.py
diff --git a/chimere/migrations/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py b/chimere/old_migrations/v2.0/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py
index 72d718c..72d718c 100644
--- a/chimere/migrations/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py
+++ b/chimere/old_migrations/v2.0/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py
diff --git a/chimere/migrations/0030_auto__add_field_importer_default_name.py b/chimere/old_migrations/v2.0/0030_auto__add_field_importer_default_name.py
index b43d44c..b43d44c 100644
--- a/chimere/migrations/0030_auto__add_field_importer_default_name.py
+++ b/chimere/old_migrations/v2.0/0030_auto__add_field_importer_default_name.py
diff --git a/chimere/migrations/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py b/chimere/old_migrations/v2.0/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py
index dac7145..dac7145 100644
--- a/chimere/migrations/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py
+++ b/chimere/old_migrations/v2.0/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py
diff --git a/chimere/migrations/0032_auto__add_field_subcategory_submission.py b/chimere/old_migrations/v2.0/0032_auto__add_field_subcategory_submission.py
index d96e5bb..d96e5bb 100644
--- a/chimere/migrations/0032_auto__add_field_subcategory_submission.py
+++ b/chimere/old_migrations/v2.0/0032_auto__add_field_subcategory_submission.py
diff --git a/chimere/migrations/0033_auto__add_field_importer_source_file.py b/chimere/old_migrations/v2.0/0033_auto__add_field_importer_source_file.py
index 788d12c..788d12c 100644
--- a/chimere/migrations/0033_auto__add_field_importer_source_file.py
+++ b/chimere/old_migrations/v2.0/0033_auto__add_field_importer_source_file.py
diff --git a/chimere/migrations/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py b/chimere/old_migrations/v2.0/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py
index 757deab..757deab 100644
--- a/chimere/migrations/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py
+++ b/chimere/old_migrations/v2.0/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py
diff --git a/chimere/migrations/0035_area_permissions.py b/chimere/old_migrations/v2.0/0035_area_permissions.py
index d396050..d396050 100644
--- a/chimere/migrations/0035_area_permissions.py
+++ b/chimere/old_migrations/v2.0/0035_area_permissions.py
diff --git a/chimere/migrations/0036_auto.py b/chimere/old_migrations/v2.0/0036_auto.py
index bb93496..bb93496 100644
--- a/chimere/migrations/0036_auto.py
+++ b/chimere/old_migrations/v2.0/0036_auto.py
diff --git a/chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py b/chimere/old_migrations/v2.0/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py
index 5269e8b..5269e8b 100644
--- a/chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py
+++ b/chimere/old_migrations/v2.0/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py
diff --git a/chimere/migrations/0038_osm_import_filtr.py b/chimere/old_migrations/v2.0/0038_osm_import_filtr.py
index 2b8666b..2b8666b 100644
--- a/chimere/migrations/0038_osm_import_filtr.py
+++ b/chimere/old_migrations/v2.0/0038_osm_import_filtr.py
diff --git a/chimere/migrations/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py b/chimere/old_migrations/v2.0/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py
index 0b26a27..0b26a27 100644
--- a/chimere/migrations/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py
+++ b/chimere/old_migrations/v2.0/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py
diff --git a/chimere/migrations/0040_remove_excluded_status.py b/chimere/old_migrations/v2.0/0040_remove_excluded_status.py
index 3fda56b..3fda56b 100644
--- a/chimere/migrations/0040_remove_excluded_status.py
+++ b/chimere/old_migrations/v2.0/0040_remove_excluded_status.py
diff --git a/chimere/migrations/0041_auto__add_field_importer_overwrite.py b/chimere/old_migrations/v2.0/0041_auto__add_field_importer_overwrite.py
index 9ae6b84..9ae6b84 100644
--- a/chimere/migrations/0041_auto__add_field_importer_overwrite.py
+++ b/chimere/old_migrations/v2.0/0041_auto__add_field_importer_overwrite.py
diff --git a/chimere/migrations/0042_fix_rights.py b/chimere/old_migrations/v2.0/0042_fix_rights.py
index 6b64313..6b64313 100644
--- a/chimere/migrations/0042_fix_rights.py
+++ b/chimere/old_migrations/v2.0/0042_fix_rights.py
diff --git a/chimere/migrations/0043_auto__add_field_importer_get_description.py b/chimere/old_migrations/v2.0/0043_auto__add_field_importer_get_description.py
index 295d3b2..295d3b2 100644
--- a/chimere/migrations/0043_auto__add_field_importer_get_description.py
+++ b/chimere/old_migrations/v2.0/0043_auto__add_field_importer_get_description.py
diff --git a/chimere/migrations/0044_auto__add_field_importer_default_description.py b/chimere/old_migrations/v2.0/0044_auto__add_field_importer_default_description.py
index ccabcd4..ccabcd4 100644
--- a/chimere/migrations/0044_auto__add_field_importer_default_description.py
+++ b/chimere/old_migrations/v2.0/0044_auto__add_field_importer_default_description.py
diff --git a/chimere/old_migrations/v2.0/__init__.py b/chimere/old_migrations/v2.0/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chimere/old_migrations/v2.0/__init__.py
diff --git a/chimere/route.py b/chimere/route.py
new file mode 100644
index 0000000..8c4638a
--- /dev/null
+++ b/chimere/route.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2012 É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.
+
+"""
+Routing management
+"""
+
+import os, re, shutil, tempfile
+from BeautifulSoup import BeautifulSoup
+from subprocess import Popen, PIPE
+from django.contrib.gis.gdal import DataSource
+from django.contrib.gis.gdal.error import OGRException
+
+from django.conf import settings
+
+class Router:
+ def route(self, lon1, lat1, lon2, lat2, transport='foot'):
+ '''
+ Get a list of geojson polylines
+ '''
+ return []
+
+class RoutinoRouter(Router):
+ re_desc = [re.compile("<tr class='n'>"), re.compile("<tr class='s'>"),
+ re.compile("<tr class='t'>")]
+ def route(self, lon1, lat1, lon2, lat2, steps=[], transport='foot',
+ speed=None):
+ '''
+ Get a list of geojson polylines and route description
+ '''
+ language = settings.LANGUAGE_CODE.split('-')[0]
+ args = [settings.CHIMERE_ROUTING_ENGINE['PATH'],
+ "--dir=%s" % settings.CHIMERE_ROUTING_ENGINE['DB_PATH'],
+ "--transport=%s" % transport,
+ "--language=%s" % language,
+ "--shortest",
+ "--output-html",
+ "--output-gpx-track",
+ "--lat1=%0.15f" % lat1,
+ "--lon1=%0.15f" % lon1,
+ ]
+ if speed:
+ args += ["--speed-%s=%s" % (highway, unicode(speed))
+ for highway in ('motorway', 'trunk', 'primary', 'secondary',
+ 'tertiary', 'unclassified', 'residential', 'service',
+ 'track','cycleway','path','steps')]
+ lonlat_index = 1
+ for lon, lat in steps:
+ lonlat_index += 1
+ args += ["--lat%d=%0.15f" % (lonlat_index, lat),
+ "--lon%d=%0.15f" % (lonlat_index, lon)]
+ lonlat_index += 1
+ args += ["--lat%d=%0.15f" % (lonlat_index, lat2),
+ "--lon%d=%0.15f" % (lonlat_index, lon2)]
+ tmp_dir = tempfile.mkdtemp(prefix='chimere_') + os.sep
+ p = Popen(args, stdout=PIPE, cwd=tmp_dir)
+ p.communicate()
+ try:
+ ds = DataSource(tmp_dir + 'shortest-track.gpx')
+ except OGRException:
+ return [], None, None
+ if not ds:
+ return [], None, None
+ layer = ds[0]
+ trk_layer = None
+ for layer in ds:
+ if layer.name == 'tracks':
+ trk_layer = layer
+ break
+ multilines = trk_layer.get_geoms()
+ res = []
+ for multiline in multilines:
+ res += [geom.geojson for geom in multiline]
+ desc = []
+ # only keeping interessant lines of the desc
+ for line in open(tmp_dir + 'shortest.html').readlines():
+ if [True for r in self.re_desc if r.match(line)]:
+ desc.append(BeautifulSoup(line).prettify())
+ total = self.webify(desc[-1])
+ desc = desc[1:-2]
+ # very fragile piece of code but only break the numerotation
+ number_tpl = '<tr class="n"><span class="number">%d.</span>'
+ desc = [re.sub('<tr class="n">', number_tpl % (idx/2+1), d)
+ if idx % 2 else d
+ for idx, d in enumerate(desc)]
+ desc = self.webify(BeautifulSoup('\n'.join(desc)).prettify())
+ desc = re.sub(" \[", "", desc)
+ desc = re.sub(" \]", "", desc)
+ shutil.rmtree(tmp_dir)
+ return res, desc, total
+
+ @staticmethod
+ def webify(lbl):
+ lbl = re.sub("<td", "<span", lbl)
+ lbl = re.sub("</td>", "</span>", lbl)
+ lbl = re.sub("</tr>", "</div>", lbl)
+ lbl = re.sub("<tr", "<div", lbl)
+ return lbl
+
+router = None
+if hasattr(settings, 'CHIMERE_ROUTING_ENGINE') and \
+ settings.CHIMERE_ROUTING_ENGINE['ENGINE'] == 'routino':
+ router = RoutinoRouter()
+
diff --git a/chimere/settings.sample.py b/chimere/settings.sample.py
new file mode 100644
index 0000000..bf7c484
--- /dev/null
+++ b/chimere/settings.sample.py
@@ -0,0 +1,289 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is an example of settings.py for a Chimère project
+
+import os
+_ = lambda s: s
+
+DEBUG = False
+TEMPLATE_DEBUG = DEBUG
+
+# Django settings for chimere project.
+PROJECT_NAME = 'Chimere'
+ROOT_PATH = os.path.realpath(os.path.dirname(__file__)) + "/"
+
+EMAIL_HOST = 'localhost'
+CONTACT_EMAIL = ''
+STATIC_URL = '/static/'
+STATIC_ROOT = ROOT_PATH + 'static/'
+
+TINYMCE_URL = '/tinymce/'
+JQUERY_JS_URLS = ('/javascript/jquery/jquery.js',
+ '/javascript/jquery-ui/jquery-ui.js',)
+JQUERY_CSS_URLS = ('/javascript/jquery-ui/css/smoothness/jquery-ui.css',
+ '/javascript/jquery-ui-themes/base/jquery.ui.all.css')
+
+OSM_CSS_URLS = ["http://www.openlayers.org/api/theme/default/style.css"]
+
+GPSBABEL = '/usr/bin/gpsbabel'
+GPSBABEL_OPTIONS = 'simplify,crosstrack,error=0.005k' # simplify with an
+ # error of 5 meters
+#GPSBABEL_OPTIONS = 'simplify,count=100'
+
+## chimere specific ##
+CHIMERE_DEFAULT_ZOOM = 10
+# center of the map
+CHIMERE_DEFAULT_CENTER = (-1.679444, 48.114722)
+# projection used by the main map
+# most public map providers use spherical mercator : 900913
+CHIMERE_EPSG_PROJECTION = 900913
+# projection displayed to the end user by openlayers
+# chimere use the same projection to save its data in the database
+CHIMERE_EPSG_DISPLAY_PROJECTION = 4326
+# display of shortcuts for areas
+CHIMERE_DISPLAY_AREAS = True
+# number of day before an event to display
+# if equal to 0: disable event management
+# if you change this value from 0 to a value in a production environnement
+# don't forget to run the upgrade.py script to create appropriate fields in
+# the database
+CHIMERE_DAYS_BEFORE_EVENT = 30
+# allow feeds
+CHIMERE_FEEDS = True
+
+CHIMERE_ICON_WIDTH = 21
+CHIMERE_ICON_HEIGHT = 25
+CHIMERE_ICON_OFFSET_X = -10
+CHIMERE_ICON_OFFSET_Y = -25
+
+# display picture inside the description by default or inside a galery?
+CHIMERE_MINIATURE_BY_DEFAULT = False
+
+# JS definition of the default map (for admin and when no map are defined in
+# the application)
+# cf. OpenLayers documentation for more details
+CHIMERE_DEFAULT_MAP_LAYER = "new OpenLayers.Layer.OSM.Mapnik('Mapnik')" # OSM mapnik map
+
+CHIMERE_XAPI_URL = 'http://open.mapquestapi.com/xapi/api/0.6/'
+CHIMERE_OSM_API_URL = 'api06.dev.openstreetmap.org' # test URL
+CHIMERE_OSM_USER = 'test'
+CHIMERE_OSM_PASSWORD = 'test'
+
+# encoding for shapefile import
+CHIMERE_SHAPEFILE_ENCODING = 'ISO-8859-1'
+
+# as the web server need to be reloaded when property models are changed
+# it could be a good idea to hide it to an admin who could'nt do that
+CHIMERE_HIDE_PROPERTYMODEL = False
+
+# enable routing in Chimère
+CHIMERE_ENABLE_ROUTING = False
+
+CHIMERE_ROUTING_TRANSPORT = (('foot', _(u"Foot")),
+ ('bicycle', _(u"Bicycle")),
+ ('motorcar', _(u"Motorcar")),
+ )
+
+CHIMERE_ROUTING_SPEEDS = {'foot':((3, _(u"You are walking slowly")),
+ (6, _(u"You are walking pretty quickly")),),
+ 'bicycle':((16, _(u"You are riding pretty slowly")),
+ (22, _(u"You are riding pretty quickly")),)
+ }
+
+# available routing engine: 'routino'
+CHIMERE_ROUTING_ENGINE = {
+ 'ENGINE': 'routino',
+ 'PATH': '/usr/local/src/web/bin/router',
+ 'DB_PATH': '/var/local/routino/',
+}
+
+CHIMERE_ROUTING_FAIL_MESSAGE = u"""<h3 class='warn'>Attention</h3>
+<p>Le moteur de routage a échoué dans sa recherche de trajet. Les points de
+départ ou d'arrivée sont peut-être trop loin d'une voie existante ou le trajet
+est trop dangereux.</p>"""
+
+NOMINATIM_URL = 'http://nominatim.openstreetmap.org/search'
+
+# thumbnail
+CHIMERE_THUMBS_SCALE_HEIGHT=250
+CHIMERE_THUMBS_SCALE_WIDTH=None
+
+CHIMERE_CSV_ENCODING = 'ISO-8859-1'
+
+ADMINS = (
+ # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASES = {
+ 'default': {
+ 'NAME': 'ratatouille',
+ 'ENGINE': 'django.contrib.gis.db.backends.postgis',
+ 'HOST': 'localhost',
+ 'PORT': '5432',
+ 'USER': 'ratatouille',
+ 'PASSWORD': 'wiki',
+ },
+}
+
+# Local time zone for this installation. Choices can be found here:
+# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
+# although not all variations may be possible on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'Europe/Paris'
+
+# Language code for this installation. All choices can be found here:
+# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
+# http://blogs.law.harvard.edu/tech/stories/storyReader$15
+LANGUAGE_CODE = 'fr-fr'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+USE_L10N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ROOT_PATH + 'media/'
+
+# URL that handles the media served from MEDIA_ROOT.
+# Example: "http://media.lawrence.com"
+MEDIA_URL = '/media/'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
+# 'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.middleware.doc.XViewMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware'
+)
+
+ROOT_URLCONF = 'chimere_example_project.urls'
+
+TEMPLATE_DIRS = [
+ # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+ # Always use forward slashes, even on Windows.
+ # Don't forget to use absolute paths, not relative paths.
+ ROOT_PATH + 'templates',
+]
+
+TEMPLATE_CONTEXT_PROCESSORS = (
+ "django.contrib.auth.context_processors.auth",
+ "django.core.context_processors.debug",
+ "django.core.context_processors.i18n",
+ "django.core.context_processors.media",
+ "django.core.context_processors.static",
+ "django.contrib.messages.context_processors.messages",
+ "django.core.context_processors.request",
+)
+
+INSTALLED_APPS = [
+ 'django.contrib.auth',
+ 'django.contrib.admin',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.sites',
+ 'django.contrib.gis',
+ 'django.contrib.staticfiles',
+]
+
+# celery
+try:
+ import djcelery
+ import kombu
+ djcelery.setup_loader()
+ BROKER_URL = 'django://'
+ INSTALLED_APPS += ['kombu.transport.django',
+ 'djcelery']
+except ImportError:
+ # some import and export will not be available
+ pass
+
+INSTALLED_APPS += [
+ 'south',
+ 'chimere',
+]
+
+LOG_PATH = '/var/log/django/'
+
+try:
+ from local_settings import *
+except ImportError, e:
+ print 'Unable to load local_settings.py:', e
+
+if 'LOGGING' not in globals():
+ global LOGGING
+ LOGGING = {'version': 1,
+ 'disable_existing_loggers': False,
+ 'handlers': {
+ # Include the default Django email handler for errors
+ # This is what you'd get without configuring logging at all.
+ 'mail_admins': {
+ 'class': 'django.utils.log.AdminEmailHandler',
+ 'level': 'ERROR',
+ # But the emails are plain text by default - HTML is nicer
+ 'include_html': True,
+ },
+ # Log to a text file that can be rotated by logrotate
+ 'logfile': {
+ 'class': 'logging.handlers.WatchedFileHandler',
+ 'filename': LOG_PATH + 'chimere.log'
+ },
+ },
+ 'loggers': {
+ # Again, default Django configuration to email unhandled exceptions
+ 'django.request': {
+ 'handlers': ['mail_admins'],
+ 'level': 'ERROR',
+ 'propagate': True,
+ },
+ # Might as well log any errors anywhere else in Django
+ 'django': {
+ 'handlers': ['logfile'],
+ 'level': 'ERROR',
+ 'propagate': False,
+ },
+ # Your own app - this assumes all your logger names start with "myapp."
+ 'chimere': {
+ 'handlers': ['logfile'],
+ 'level': 'WARNING', # Or maybe INFO or DEBUG
+ 'propogate': False
+ },
+ },
+ }
+
+
+if 'CHIMERE_SHARE_NETWORKS' not in globals():
+ # after the locals to get the right STATIC_URL
+
+ # share with
+ global CHIMERE_SHARE_NETWORKS
+ CHIMERE_SHARE_NETWORKS = (
+ ("Email", 'mailto:?subject=%(text)s&body=%(url)s',
+ STATIC_URL + 'chimere/img/email.png'),
+ ("Facebook", 'http://www.facebook.com/sharer.php?t=%(text)s&u=%(url)s',
+ STATIC_URL + 'chimere/img/facebook.png'),
+ ("Twitter", 'http://twitter.com/home?status=%(text)s %(url)s',
+ STATIC_URL + 'chimere/img/twitter.png'),
+ ("Identi.ca", 'http://identi.ca/index.php?action=newnotice&status_textarea=%(text)s %(url)s',
+ STATIC_URL + 'chimere/img/identica.png'),
+ )
+
+if 'OSM_JS_URLS' not in globals():
+ global OSM_JS_URLS
+ OSM_JS_URLS = [STATIC_URL + "openlayers/OpenLayers.js",
+ STATIC_URL + "openlayers/SimplePanZoom.js",
+ "http://www.openstreetmap.org/openlayers/OpenStreetMap.js"]
+
diff --git a/chimere/static/chimere/css/admin.css b/chimere/static/chimere/css/admin.css
new file mode 100644
index 0000000..931d139
--- /dev/null
+++ b/chimere/static/chimere/css/admin.css
@@ -0,0 +1,6 @@
+.vTextField{
+ width:150px;
+}
+.vLargeTextField{
+ width:200px;
+}
diff --git a/chimere/static/chimere/css/print.css b/chimere/static/chimere/css/print.css
new file mode 100644
index 0000000..8dda0b8
--- /dev/null
+++ b/chimere/static/chimere/css/print.css
@@ -0,0 +1,40 @@
+#topbar, .no-titlebar-simple.ui-dialog,
+#zoombar, #zoomin, #zoomout, #slidebar,
+#pandown, #panup, #panright, #panleft,
+div#footer p.map-footer{
+ display:none;
+}
+
+#main-map{
+ z-index:10;
+ top:0;
+ bottom:0;
+ height:605pt;
+ max-height:605pt;
+ width:1200pt;
+ right:50%;
+ border:none;
+}
+
+#panel #chimere_itinerary_panel{
+ width:870pt;
+ bottom:auto;
+ left:auto;
+ right:auto;
+ top:605pt;
+ position:absolute;
+ z-index:1000;
+}
+
+#sidebar div#panel{
+ width:900pt;
+ border:none;
+ overflow:visible;
+}
+
+#chimere_start_label,
+#chimere_end_label{
+ width:auto;
+ overflow:auto;
+}
+
diff --git a/chimere/static/chimere/css/styles.css b/chimere/static/chimere/css/styles.css
index 9d26b67..ea7d4c0 100644
--- a/chimere/static/chimere/css/styles.css
+++ b/chimere/static/chimere/css/styles.css
@@ -15,7 +15,9 @@ a, a:link, a:visited, legend,
h2, h3, th, .action li, .action li a,
.action li li a, #no-js-message,
-#footer a, #footer a:link, #footer a:visited, .ui-widget-header{
+#footer a, #footer a:link, #footer a:visited, .ui-widget-header,
+#layer_selection h4,
+#chimere_itinerary td.l{
color:#fff;
}
@@ -25,11 +27,23 @@ h2, h3, th, .action li, .action li a,
color:#333;
}
+.nominatim-widget, .disabled{
+ color:#aaa;
+}
+
+#chimere_total_label td.l{
+ color:#000;
+}
+
/* background-color definition */
body, h2, h3, th,
.ui-widget-header,
-.action li.selected, #no-js-message{
+#layer_selection h4,
+.action li.selected, #no-js-message,
+#content .olControlLayerSwitcher .layersDiv,
+#content .olControlLayerSwitcher span,
+#chimere_itinerary td.l{
background-color:#449506;
}
@@ -38,10 +52,12 @@ body, h2, h3, th,
}
fieldset, .action li, #content,
-#map-footer, #panel, #areas,
+#layer_selection #layer_list,
+#map-footer, #panel, #chimere_itinerary_panel, #areas,
#welcome, #detail, .detail_footer a,
#content .olControlLayerSwitcher .layersDiv,
#content .olControlLayerSwitcher span,
+#chimere_total_label td.l,
#main-map, .window{
background-color:#FFF;
}
@@ -58,12 +74,14 @@ div.warning, .errorlist{
border:1px solid #54c200;
}
+#layer_selection h4,
+#layer_selection #layer_list,
#areas, #detail, #main-map,
div.warning,
#content,
.action li.selected,
#content .olControlLayerSwitcher .layersDiv,
-#panel, #map-footer,
+#panel, #map-footer, #chimere_itinerary_panel,
#utils-div{
border:1px solid #327e04;
}
@@ -92,7 +110,7 @@ h2, #action li, .detail_footer{
fieldset, #content, #panel,
#areas, #welcome, #detail,
-#category_detail, div.warning{
+#category_description, div.warning{
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
@@ -143,7 +161,6 @@ h3{
h4, caption{
font-weight:normal;
- font-style:italic;
margin:0;
text-align:left;
}
@@ -164,6 +181,10 @@ fieldset{
margin-top:8px;
}
+.hidden{
+ display:none;
+}
+
.ui-dialog-buttonset{
text-align:center;
}
@@ -182,7 +203,7 @@ fieldset{
}
#topbar{
- z-index:0;
+ z-index:10;
}
ul.action{
@@ -243,8 +264,14 @@ ul#action-2 {
width:auto;
}
+#utils-div a{
+ display:block;
+ width:100%;
+}
+
#areas-div,
-#areas-div label{
+#areas-div label,
+#utils-div a{
padding:0.3em;
}
@@ -314,6 +341,7 @@ ul.share{
list-style-type:none;
margin:0;
padding:0;
+ display:inline;
}
ul.share li{
@@ -332,6 +360,10 @@ ul.share li{
height:22px;
}
+.share .share-icon img{
+ width:74px;
+}
+
.detail_footer{
text-align:center;
position:absolute;
@@ -356,8 +388,6 @@ ul.share li{
#main-map{
position:absolute;
- margin:0px;
- padding:0px;
height:93%;
margin:0;
padding:0;
@@ -388,6 +418,45 @@ ul.share li{
z-index:0;
}
+#layer_selection{
+ position:absolute;
+ z-index:100;
+ top:280px;
+ left:24px;
+}
+
+#layer_selection h4,
+#layer_selection #layer_list li{
+ padding:2px 5px;
+}
+
+#layer_selection h4{
+ font-weight:normal;
+ border-width:1px;
+ border-style:solid;
+ width:140px;
+ text-align:center;
+}
+
+#layer_selection h4:hover{
+ cursor:pointer;
+}
+
+#layer_selection ul{
+ display:block;
+}
+
+#layer_selection ul#layer_list{
+ width:150px;
+ display:none;
+ list-style:none;
+ margin:0;
+ padding:0;
+ border-width:1px;
+ border-style:solid;
+ border-top:none;
+}
+
.news h3{
padding:0px;
margin:0;
@@ -410,12 +479,110 @@ ul.share li{
top:50px;
right:18px;
width:300px;
- bottom:44px;
+ max-height:300px;
overflow:auto;
padding:0.5em;
padding-top:0;
}
+#chimere_itinerary_panel,
+#chimere_itinerary{
+ display:none;
+}
+
+#chimere_itinerary_panel label{
+ color:#000;
+}
+
+#chimere_itinerary_panel p
+{
+ margin:0.5em;
+}
+
+#total_label_div{
+ margin:5px 0;
+}
+
+.itinerary_label{
+ font-size:0.9em;
+ padding-top:0.5em;
+ font-style:italic;
+}
+
+.itinerary_label .label{
+ font-style:normal;
+ font-weight:bold;
+ padding:3px 8px;
+}
+
+
+#chimere_itinerary_content{
+ overflow:auto;
+ height:190px;
+ margin-top:10px;
+}
+
+#chimere_itinerary_content span.l{
+ padding:5px;
+ width:60px;
+}
+
+#chimere_itinerary_content span.j{
+ font-style:italic;
+}
+
+#chimere_itinerary_content .number{
+ font-weight:bold;
+}
+
+#chimere_itinerary_content span.t,
+#chimere_itinerary_content span.b
+{
+ text-transform: lowercase;
+}
+
+#chimere_map_menu{
+ z-index:4;
+ display:none;
+ position:absolute;
+ padding:0.5em;
+ background-color:#fff;
+ border:1px solid #bbb;
+ -webkit-border-radius: 0 8px 8px 8px;
+ -moz-border-radius: 0 8px 8px 8px;
+ border-radius: 0 8px 8px 8px;
+}
+
+#map_menu_clear{
+ display:none;
+}
+
+#map_menu_zoomin{
+ border-top:1px solid #999;
+}
+
+#chimere_map_menu ul, #chimere_map_menu li{
+ padding:0.2em;
+ margin:0;
+ list-style:none;
+}
+
+#chimere_map_menu li:hover{
+ cursor:pointer;
+ background-color:#ccc;
+}
+
+.nominatim-label{
+ display:block;
+ font-size:0.9em;
+ font-weight:bold;
+ height:2.8em;
+}
+
+.nominatim-widget{
+ font-style:italic;
+}
+
.simple #panel{
top:5px;
bottom:auto;
@@ -494,6 +661,11 @@ ul.subcategories label img{
height:20px;
}
+li.main_category > span:hover,
+li.main_category label:hover{
+ cursor:pointer;
+}
+
#categories li#display_submited{
font-variant:normal;
}
@@ -546,11 +718,10 @@ p.warning{
}
-#welcome_button,
-#simple_button,
+a#welcome_button,
+a#routing_button,
#permalink{
display: block;
- text-align:center;
margin:0.3em;
padding:0.2em;
width:100%;
@@ -601,6 +772,40 @@ table.inline-table td input[type=file]{
margin-right: auto;
}
+.alert-box .ui-dialog-titlebar {
+ display:none;
+}
+
+ul#multimedia_list_content{
+ padding:0;
+ margin:0;
+ list-style-type:none;
+}
+
+ul#multimedia_list_content li{
+ padding:0.5em 5px 0.5em 35px;
+ margin:0;
+ display:block;
+ list-style-type:none;
+ border-bottom:1px solid;
+}
+
+ul#multimedia_list_content li img{
+ display:block;
+ float:right;
+}
+
+ul#multimedia_list_content li.picture{
+ background-image:url("../img/img_logo.png");
+ background-position:4px center;
+ background-repeat:no-repeat;
+}
+
+ul#multimedia_list_content li.multimedia{
+ background-image:url("../img/film_logo.png");
+ background-position:6px center;
+ background-repeat:no-repeat;
+}
#waiting{ /* Fixed position to provide the vertical offset */
position:fixed;
@@ -746,7 +951,7 @@ p.legend{
}
.media-img{
- max-height:400px;
+ max-height:200px;
}
.media-video,
@@ -799,6 +1004,26 @@ div.pp_default .pp_expand{
SimplePanZoom
*/
+#main_map.olMap{
+ z-index:0;
+}
+
+#marker_hover{
+ display:none;
+ position:absolute;
+ z-index:5;
+ background-image: url('../img/bottom-arrow.png');
+ background-repeat: no-repeat;
+ background-position: center bottom;
+}
+
+#marker_hover_content{
+ margin-bottom:6px;
+ background-color:#fff;
+ border:1px solid #000;
+ padding:0.1em 0.5em;
+}
+
.olControlSimplePanZoom {
top: 10px;
right: 10px;
diff --git a/chimere/static/chimere/img/bottom-arrow.png b/chimere/static/chimere/img/bottom-arrow.png
new file mode 100644
index 0000000..7393ffe
--- /dev/null
+++ b/chimere/static/chimere/img/bottom-arrow.png
Binary files differ
diff --git a/chimere/static/chimere/img/close.png b/chimere/static/chimere/img/close.png
new file mode 100644
index 0000000..f9e8d04
--- /dev/null
+++ b/chimere/static/chimere/img/close.png
Binary files differ
diff --git a/chimere/static/chimere/img/empty.png b/chimere/static/chimere/img/empty.png
new file mode 100644
index 0000000..1ad1e19
--- /dev/null
+++ b/chimere/static/chimere/img/empty.png
Binary files differ
diff --git a/chimere/static/chimere/img/feed.png b/chimere/static/chimere/img/feed.png
new file mode 100644
index 0000000..19d2246
--- /dev/null
+++ b/chimere/static/chimere/img/feed.png
Binary files differ
diff --git a/chimere/static/chimere/img/film_logo.png b/chimere/static/chimere/img/film_logo.png
new file mode 100644
index 0000000..1ccdc2e
--- /dev/null
+++ b/chimere/static/chimere/img/film_logo.png
Binary files differ
diff --git a/chimere/static/chimere/img/flag-finish.png b/chimere/static/chimere/img/flag-finish.png
new file mode 100644
index 0000000..04bfa1d
--- /dev/null
+++ b/chimere/static/chimere/img/flag-finish.png
Binary files differ
diff --git a/chimere/static/chimere/img/flag-start.png b/chimere/static/chimere/img/flag-start.png
new file mode 100644
index 0000000..c93f2a3
--- /dev/null
+++ b/chimere/static/chimere/img/flag-start.png
Binary files differ
diff --git a/chimere/static/chimere/img/flag-step.png b/chimere/static/chimere/img/flag-step.png
new file mode 100644
index 0000000..5556c94
--- /dev/null
+++ b/chimere/static/chimere/img/flag-step.png
Binary files differ
diff --git a/chimere/static/chimere/img/images_licences b/chimere/static/chimere/img/images_licences
index 0e732fc..d6d2773 100644
--- a/chimere/static/chimere/img/images_licences
+++ b/chimere/static/chimere/img/images_licences
@@ -1,5 +1,5 @@
-* Upload image credit
+* Upload image credit (upload.png)
* Farm-Fresh layer gps.png in Farm-Fresh Web Icons
Author: FatCow Web Hosting
@@ -16,17 +16,26 @@ Author: The Tango! Desktop Project
Licence: Public domain
Url: http://commons.wikimedia.org/wiki/File:Internet-web-browser.svg
-* Drawing image credit
+* Drawing image credit (drawing.png)
* Icons from the Tango! project set.
Author: The Tango! Desktop Project
Licence: Public domain
Url: http://commons.wikimedia.org/wiki/File:Edit-find-replace.svg
-Url 2: http://commons.wikimedia.org/wiki/File:Internet-web-browser.svg
+ http://commons.wikimedia.org/wiki/File:Internet-web-browser.svg
+ https://commons.wikimedia.org/wiki/File:Document-print.svg
-* Quaver image credit
+* Quaver image credit (8thNote.png)
* An 8th-note.
Author: Sbrools
Licence: Public domain
Url: https://commons.wikimedia.org/wiki/File:8thNote.svg
+
+* Flags image credit (flag-start.png, flag-step.png, flag-finish.png)
+
+Author: FatCow Web Hosting
+Licence: Creative Commons Attribution 3.0 United States license
+Url: https://upload.wikimedia.org/wikipedia/commons/c/cb/Farm-Fresh_flag_1.png
+ https://upload.wikimedia.org/wikipedia/commons/8/81/Farm-Fresh_flag_blue.png
+ https://upload.wikimedia.org/wikipedia/commons/6/64/Farm-Fresh_flag_finish.png
diff --git a/chimere/static/chimere/img/img_logo.png b/chimere/static/chimere/img/img_logo.png
new file mode 100644
index 0000000..b487506
--- /dev/null
+++ b/chimere/static/chimere/img/img_logo.png
Binary files differ
diff --git a/chimere/static/chimere/img/marker-cluster.png b/chimere/static/chimere/img/marker-cluster.png
new file mode 100644
index 0000000..73b4146
--- /dev/null
+++ b/chimere/static/chimere/img/marker-cluster.png
Binary files differ
diff --git a/chimere/static/chimere/img/printer.png b/chimere/static/chimere/img/printer.png
new file mode 100644
index 0000000..5a5dbaf
--- /dev/null
+++ b/chimere/static/chimere/img/printer.png
Binary files differ
diff --git a/chimere/static/chimere/img/share-icon.png b/chimere/static/chimere/img/share-icon.png
new file mode 100644
index 0000000..f21b76e
--- /dev/null
+++ b/chimere/static/chimere/img/share-icon.png
Binary files differ
diff --git a/chimere/static/chimere/img/share-icon.xcf b/chimere/static/chimere/img/share-icon.xcf
new file mode 100644
index 0000000..d149768
--- /dev/null
+++ b/chimere/static/chimere/img/share-icon.xcf
Binary files differ
diff --git a/chimere/static/chimere/js/base.js b/chimere/static/chimere/js/base.js
index e76fe76..fe8d954 100644
--- a/chimere/static/chimere/js/base.js
+++ b/chimere/static/chimere/js/base.js
@@ -1,5 +1,5 @@
/* base function shared by some pages */
-/* Copyright (C) 2009-2011 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+/* Copyright (C) 2009-2013 É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
@@ -107,3 +107,37 @@ function zoomToCurrentExtent(map){
map.zoomToExtent(extent, true);
return true;
}
+
+/* interface */
+function share_link_update(){
+ $('.share_link').click(function(){
+ if (this.share_initialized){
+ return false;
+ }
+ this.share_initialized = true;
+ var href = $(this).attr('href');
+ var url = get_share_url;
+ var classes = $(this).attr('class').split(' ');
+ prefix = 'share_id_';
+ var share_id;
+ for (idx=0;idx<classes.length;idx++){
+ if(classes[idx].substring(0, prefix.length) == prefix){
+ var share_id = classes[idx].substring(prefix.length);
+ share_id = share_id.split('_')[0];
+ }
+ }
+ var params = $('#permalink a').attr('href').split('/');
+ url += share_id + params[params.length-1];
+ $.ajax({url: url,
+ dataType: "html",
+ success: function (url) {
+ window.location.href = url;
+ return true;
+ },
+ error: function(){
+ return false;
+ }
+ });
+ return false;
+ });
+}
diff --git a/chimere/static/chimere/js/clustering.js b/chimere/static/chimere/js/clustering.js
new file mode 100644
index 0000000..b3a142c
--- /dev/null
+++ b/chimere/static/chimere/js/clustering.js
@@ -0,0 +1,278 @@
+/*
+ Add a recluster to Cluster class.
+ probably part of OpenLayers 2.13
+*/
+
+
+OpenLayers.Strategy.Cluster = OpenLayers.Class(OpenLayers.Strategy, {
+
+ /**
+ * APIProperty: distance
+ * {Integer} Pixel distance between features that should be considered a
+ * single cluster. Default is 20 pixels.
+ */
+ distance: 20,
+
+ /**
+ * APIProperty: threshold
+ * {Integer} Optional threshold below which original features will be
+ * added to the layer instead of clusters. For example, a threshold
+ * of 3 would mean that any time there are 2 or fewer features in
+ * a cluster, those features will be added directly to the layer instead
+ * of a cluster representing those features. Default is null (which is
+ * equivalent to 1 - meaning that clusters may contain just one feature).
+ */
+ threshold: null,
+
+ /**
+ * Property: features
+ * {Array(<OpenLayers.Feature.Vector>)} Cached features.
+ */
+ features: null,
+
+ /**
+ * Property: clusters
+ * {Array(<OpenLayers.Feature.Vector>)} Calculated clusters.
+ */
+ clusters: null,
+
+ /**
+ * Property: clustering
+ * {Boolean} The strategy is currently clustering features.
+ */
+ clustering: false,
+
+ /**
+ * Property: resolution
+ * {Float} The resolution (map units per pixel) of the current cluster set.
+ */
+ resolution: null,
+
+ /**
+ * Constructor: OpenLayers.Strategy.Cluster
+ * Create a new clustering strategy.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * instance.
+ */
+
+ /**
+ * APIMethod: activate
+ * Activate the strategy. Register any listeners, do appropriate setup.
+ *
+ * Returns:
+ * {Boolean} The strategy was successfully activated.
+ */
+ activate: function() {
+ var activated = OpenLayers.Strategy.prototype.activate.call(this);
+ if(activated) {
+ this.layer.events.on({
+ "beforefeaturesadded": this.cacheFeatures,
+ "moveend": this.cluster,
+ scope: this
+ });
+ }
+ return activated;
+ },
+
+ /**
+ * APIMethod: deactivate
+ * Deactivate the strategy. Unregister any listeners, do appropriate
+ * tear-down.
+ *
+ * Returns:
+ * {Boolean} The strategy was successfully deactivated.
+ */
+ deactivate: function() {
+ var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);
+ if(deactivated) {
+ this.clearCache();
+ this.layer.events.un({
+ "beforefeaturesadded": this.cacheFeatures,
+ "moveend": this.cluster,
+ scope: this
+ });
+ }
+ return deactivated;
+ },
+
+ /**
+ * Method: cacheFeatures
+ * Cache features before they are added to the layer.
+ *
+ * Parameters:
+ * event - {Object} The event that this was listening for. This will come
+ * with a batch of features to be clustered.
+ *
+ * Returns:
+ * {Boolean} False to stop features from being added to the layer.
+ */
+ cacheFeatures: function(event) {
+ var propagate = true;
+ if(!this.clustering) {
+ this.clearCache();
+ this.features = event.features;
+ this.cluster();
+ propagate = false;
+ }
+ return propagate;
+ },
+
+ /**
+ * Method: clearCache
+ * Clear out the cached features.
+ */
+ clearCache: function() {
+ this.features = null;
+ },
+
+ /**
+ * Method: cluster
+ * Cluster features based on some threshold distance.
+ *
+ * Parameters:
+ * event - {Object} The event received when cluster is called as a
+ * result of a moveend event.
+ */
+ cluster: function(event) {
+ if((!event || event.zoomChanged || (event && event.recluster)) && this.features) {
+ var resolution = this.layer.map.getResolution();
+ if(resolution != this.resolution || !this.clustersExist() || (event && event.recluster)) {
+ this.resolution = resolution;
+ var clusters = [];
+ var feature, clustered, cluster;
+ for(var i=0; i<this.features.length; ++i) {
+ feature = this.features[i];
+ if(feature.geometry) {
+ clustered = false;
+ for(var j=clusters.length-1; j>=0; --j) {
+ cluster = clusters[j];
+ if(this.shouldCluster(cluster, feature)) {
+ this.addToCluster(cluster, feature);
+ clustered = true;
+ break;
+ }
+ }
+ if(!clustered) {
+ clusters.push(this.createCluster(this.features[i]));
+ }
+ }
+ }
+ this.layer.removeAllFeatures();
+ if(clusters.length > 0) {
+ if(this.threshold > 1) {
+ var clone = clusters.slice();
+ clusters = [];
+ var candidate;
+ for(var i=0, len=clone.length; i<len; ++i) {
+ candidate = clone[i];
+ if(candidate.attributes.count < this.threshold) {
+ Array.prototype.push.apply(clusters, candidate.cluster);
+ } else {
+ clusters.push(candidate);
+ }
+ }
+ }
+ this.clustering = true;
+ // A legitimate feature addition could occur during this
+ // addFeatures call. For clustering to behave well, features
+ // should be removed from a layer before requesting a new batch.
+ this.layer.addFeatures(clusters);
+ this.clustering = false;
+ }
+ this.clusters = clusters;
+ }
+ }
+ },
+
+ /**
+ * Method: recluster
+ * User-callable function to recluster features
+ * Useful for instances where a clustering attribute (distance, threshold, ...)
+ * has changed
+ */
+ recluster: function(){
+ var event={"recluster":true};
+ this.cluster(event);
+ },
+
+ /**
+ * Method: clustersExist
+ * Determine whether calculated clusters are already on the layer.
+ *
+ * Returns:
+ * {Boolean} The calculated clusters are already on the layer.
+ */
+ clustersExist: function() {
+ var exist = false;
+ if(this.clusters && this.clusters.length > 0 &&
+ this.clusters.length == this.layer.features.length) {
+ exist = true;
+ for(var i=0; i<this.clusters.length; ++i) {
+ if(this.clusters[i] != this.layer.features[i]) {
+ exist = false;
+ break;
+ }
+ }
+ }
+ return exist;
+ },
+
+ /**
+ * Method: shouldCluster
+ * Determine whether to include a feature in a given cluster.
+ *
+ * Parameters:
+ * cluster - {<OpenLayers.Feature.Vector>} A cluster.
+ * feature - {<OpenLayers.Feature.Vector>} A feature.
+ *
+ * Returns:
+ * {Boolean} The feature should be included in the cluster.
+ */
+ shouldCluster: function(cluster, feature) {
+ var cc = cluster.geometry.getBounds().getCenterLonLat();
+ var fc = feature.geometry.getBounds().getCenterLonLat();
+ var distance = (
+ Math.sqrt(
+ Math.pow((cc.lon - fc.lon), 2) + Math.pow((cc.lat - fc.lat), 2)
+ ) / this.resolution
+ );
+ return (distance <= this.distance);
+ },
+
+ /**
+ * Method: addToCluster
+ * Add a feature to a cluster.
+ *
+ * Parameters:
+ * cluster - {<OpenLayers.Feature.Vector>} A cluster.
+ * feature - {<OpenLayers.Feature.Vector>} A feature.
+ */
+ addToCluster: function(cluster, feature) {
+ cluster.cluster.push(feature);
+ cluster.attributes.count += 1;
+ },
+
+ /**
+ * Method: createCluster
+ * Given a feature, create a cluster.
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>}
+ *
+ * Returns:
+ * {<OpenLayers.Feature.Vector>} A cluster.
+ */
+ createCluster: function(feature) {
+ var center = feature.geometry.getBounds().getCenterLonLat();
+ var cluster = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(center.lon, center.lat),
+ {count: 1}
+ );
+ cluster.cluster = [feature];
+ return cluster;
+ },
+
+ CLASS_NAME: "OpenLayers.Strategy.Cluster"
+});
diff --git a/chimere/static/chimere/js/jquery.chimere.js b/chimere/static/chimere/js/jquery.chimere.js
index 6675dcd..2e2d238 100644
--- a/chimere/static/chimere/js/jquery.chimere.js
+++ b/chimere/static/chimere/js/jquery.chimere.js
@@ -68,6 +68,11 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
lat: null,
lon: null,
simple: false,
+ routing_start_lat: null,
+ routing_start_lon: null,
+ routing_end_lat: null,
+ routing_end_lon: null,
+ routing_steps_lonlat: null,
// Provide this function to make a custom click event on the marker
on_marker_click: null,
// Provide this function to override the feature detail display
@@ -75,24 +80,44 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
// Provide this function for overriding the getSubcategories default
get_subcategories_fx: null,
hide_popup_fx: null,
+ // if leave to false every click on the map hide the pop-up
+ explicit_popup_hide: false,
controls:[new OpenLayers.Control.Navigation(),
- new OpenLayers.Control.SimplePanZoom(),
+ new OpenLayers.Control.PanPanel(),
+ new OpenLayers.Control.ZoomPanel(),
new OpenLayers.Control.ScaleLine()],
+ popupClass: OpenLayers.Popup.FramedCloud,
+ popupContentFull: false, // if true the detail is inside the popup
+ category_accordion: true, // category opening behave like an accordion
maxResolution: 156543.0399,
units: 'm',
projection: new OpenLayers.Projection('EPSG:4326'),
- theme:null,
+ theme: null,
+ enable_clustering: false,
+ routing: false, // enable routing management
+ routing_panel_open: function(){
+ $('#chimere_itinerary_panel').dialog('open');
+ },
current_feature: null, // To store the active POI
current_control: null, // To store the current control
current_popup: null, // To store the current POI popup displayed
current_category: null, // To store the current category clicked in list
+ current_route_feature: null, // To store the current route find by routing
+ itinerary_step_number:0, // current step number
icon_offset: new OpenLayers.Pixel(0, 0),
edition: false, // edition mode
edition_type_is_route: false, // route or POI edition
default_icon: new OpenLayers.Icon(
'http://www.openlayers.org/dev/img/marker-green.png',
new OpenLayers.Size(21, 25),
- new OpenLayers.Pixel(-(21/2), -25))
+ new OpenLayers.Pixel(-(21/2), -25)),
+ cluster_icon: null,
+ marker_hover_id:'marker_hover',
+ marker_hover_content_id:'marker_hover_content',
+ marker_hover_offset: null,
+ icon_start: null,
+ icon_step: null,
+ icon_end: null
};
var settings = {};
/*
@@ -104,6 +129,31 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
*/
init: function ( options ) {
/* Manage parameters */
+ // not staticaly in default because of STATIC_URL init
+ if (defaults.cluster_icon == null && typeof STATIC_URL != 'undefined'){
+ defaults.cluster_icon = new OpenLayers.Icon(
+ STATIC_URL+'chimere/img/marker-cluster.png',
+ new OpenLayers.Size(36, 39),
+ new OpenLayers.Pixel(-(36/2), -(39/2)));
+ }
+ if (defaults.icon_start == null && typeof STATIC_URL != 'undefined'){
+ defaults.icon_start = new OpenLayers.Icon(
+ STATIC_URL + "chimere/img/flag-start.png",
+ new OpenLayers.Size(32, 32),
+ new OpenLayers.Pixel(0, -32));
+ }
+ if (defaults.icon_step == null && typeof STATIC_URL != 'undefined'){
+ defaults.icon_step = new OpenLayers.Icon(
+ STATIC_URL + "chimere/img/flag-step.png",
+ new OpenLayers.Size(32, 32),
+ new OpenLayers.Pixel(0, -32));
+ }
+ if (defaults.icon_end == null && typeof STATIC_URL != 'undefined'){
+ defaults.icon_end = new OpenLayers.Icon(
+ STATIC_URL + "chimere/img/flag-finish.png",
+ new OpenLayers.Size(32, 32),
+ new OpenLayers.Pixel(0, -32));
+ }
settings = $.extend({}, defaults);
if ( options ) $.extend(settings, options);
var map_element = $(this).get(0);
@@ -120,6 +170,8 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
map_options['restrictedExtent'] = settings.restricted_extent;
}
+ settings.current_position = null;
+
/* Create map object */
settings.map = map = new OpenLayers.Map(map_element, map_options);
@@ -145,8 +197,29 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
// Make specific params
params.checked_categories = settings.checked_categories;
params.display_submited = settings.display_submited;
- if(settings.current_feature){
+ if(settings.current_feature)
params.current_feature = settings.current_feature.pk;
+ if (settings.routing_start){
+ lonlat = settings.routing_start.lonlat.clone().transform(
+ EPSG_PROJECTION, EPSG_DISPLAY_PROJECTION);
+ params.routing_start_lon = lonlat.lon;
+ params.routing_start_lat = lonlat.lat;
+ }
+ if (settings.routing_end){
+ lonlat = settings.routing_end.lonlat.clone().transform(
+ EPSG_PROJECTION, EPSG_DISPLAY_PROJECTION);
+ params.routing_end_lon = lonlat.lon;
+ params.routing_end_lat = lonlat.lat;
+ }
+ if (settings.routing_steps){
+ var steps = [];
+ for (var i = 0; i < settings.routing_steps.length; i++){
+ lonlat = settings.routing_steps[i].lonlat.clone(
+ ).transform(EPSG_PROJECTION,
+ EPSG_DISPLAY_PROJECTION);
+ steps.push([lonlat.lon, lonlat.lat]);
+ }
+ params.routing_steps = steps;
}
return params;
}
@@ -171,6 +244,26 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
}
settings.map.setBaseLayer(
settings.map_layers[settings.selected_map_layer]);
+
+ /* manage the context menu */
+ $('#map_menu_zoomin').bind("click", methods.zoomIn);
+ $('#map_menu_zoomout').bind("click", methods.zoomOut);
+ $('#map_menu_center').bind("click", methods.mapCenter);
+ /* manage the routing */
+ if (settings.routing){
+ settings.routing_start = null;
+ settings.routing_steps = new Array();
+ settings.routing_end = null;
+ $('#map_menu_from').bind("click", methods.routingFrom);
+ $('#map_menu_step').bind("click", methods.routingAddStep);
+ $('#map_menu_to').bind("click", methods.routingTo);
+ $('#map_menu_clear').bind("click", methods.routingClear);
+ settings.layerRoute = new OpenLayers.Layer.Vector("Route Layer");
+ settings.map.addLayer(settings.layerRoute);
+ settings.layerRouteMarker = new OpenLayers.Layer.Markers(
+ 'Route markers');
+ settings.map.addLayer(settings.layerRouteMarker);
+ }
/* Vectors layer */
settings.layerVectors = new OpenLayers.Layer.Vector("Vector Layer");
settings.map.addLayer(settings.layerVectors);
@@ -181,10 +274,94 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
settings.map.addControl(new OpenLayers.Control.ModifyFeature(
settings.layerVectors, {clickout:false, toggle:false}));
}
+
+ if (settings.enable_clustering){
+ var style = new OpenLayers.Style({
+ graphicTitle: "${name}",
+ externalGraphic: "${icon}",
+ graphicWidth: "${width}",
+ graphicHeight: "${height}",
+ graphicXOffset: "${offsetx}",
+ graphicYOffset: "${offsety}",
+ graphicOpacity: 1,
+ label: "${label}",
+ labelYOffset: "2",
+ fontSize:'1.3em'
+ }, {
+ context: {
+ name: function(feature) {
+ if(feature.cluster) {
+ feature.attributes.width = settings.cluster_icon.size.w;
+ feature.attributes.height = settings.cluster_icon.size.h;
+ feature.attributes.offsetx = settings.cluster_icon.offset.x;
+ feature.attributes.offsety = settings.cluster_icon.offset.y;
+ } else{
+ var marker = feature.attributes.marker
+ feature.attributes.width = marker.icon.size.w;
+ feature.attributes.height = marker.icon.size.h;
+ feature.attributes.offsetx = settings.icon_offset.x;
+ feature.attributes.offsety = settings.icon_offset.y;
+ }
+ return feature.attributes.name;
+ },
+ label: function(feature) {
+ // clustered features count or blank if feature is not a cluster
+ return feature.cluster ? feature.cluster.length : "";
+ },
+ icon: function(feature) {
+ if (feature.cluster){
+ return settings.cluster_icon.url;
+ } else {
+ return STATIC_URL + 'chimere/img/empty.png';
+ }
+ },
+ width: function(feature) { return feature.attributes.width; },
+ height: function(feature) { return feature.attributes.height; },
+ offsetx: function(feature) { return feature.attributes.offsetx; },
+ offsety: function(feature) { return feature.attributes.offsety; }
+ }});
+
+
+ /* Cluster layer */
+ settings.clustering = new OpenLayers.Strategy.Cluster({
+ distance: 10,
+ threshold: 2});
+ settings.layerCluster = new OpenLayers.Layer.Vector("Cluster layer",
+ {styleMap: new OpenLayers.StyleMap({'default': style}),
+ strategies: [settings.clustering]});
+ settings.map.addLayer(settings.layerCluster);
+
+ var highlightCtrl = new OpenLayers.Control.SelectFeature(
+ settings.layerCluster, {
+ hover: true,
+ highlightOnly: true,
+ eventListeners: {
+ featurehighlighted: function(e) {
+ if(e.feature.attributes.marker)
+ e.feature.attributes.marker.events.triggerEvent('mouseover');
+ },
+ featureunhighlighted: function(e) {
+ if(e.feature.attributes.marker)
+ e.feature.attributes.marker.events.triggerEvent('mouseout');
+ }
+ }
+ });
+
+ var selectCtrl = new OpenLayers.Control.SelectFeature(
+ settings.layerCluster,{
+ onSelect: methods.zoomOnCluster
+ });
+
+ settings.map.addControl(highlightCtrl);
+ settings.map.addControl(selectCtrl);
+
+ highlightCtrl.activate();
+ selectCtrl.activate();
+ }
+
/* Markers layer */
settings.layerMarkers = new OpenLayers.Layer.Markers('POIs');
settings.map.addLayer(settings.layerMarkers);
- settings.layerMarkers.setOpacity(0.8);
if (settings.dynamic_categories){
settings.map.events.register('moveend', settings.map,
@@ -209,15 +386,16 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
}
if (!settings.edition){
+ if (settings.enable_clustering){
+ settings.map.events.register('zoomend', null,
+ methods.cleanCluster);
+ }
methods.loadCategories();
methods.loadGeoObjects();
- // Hide popUp when clicking on map
- settings.map.events.register('click', settings.map,
- methods.hidePopup);
+ methods.activateContextMenu()
} else {
if (!settings.edition_type_is_route){
- map.events.register('click', settings.map,
- methods.setMarker);
+ methods.activateMarkerEdit();
} else {
settings.layerVectors.events.register('featuremodified',
settings.layerVectors, helpers.updateRouteForm);
@@ -225,9 +403,139 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
settings.layerVectors, helpers.featureRouteCreated);
}
}
+ if (settings.routing_start_lon && settings.routing_start_lat){
+ settings.current_position = new OpenLayers.LonLat(
+ settings.routing_start_lon, settings.routing_start_lat
+ ).transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION);
+ methods.routingFrom();
+ }
+ if (settings.routing_end_lon && settings.routing_end_lat){
+ settings.current_position = new OpenLayers.LonLat(
+ settings.routing_end_lon, settings.routing_end_lat
+ ).transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION);
+ methods.routingTo();
+ }
+ if (settings.routing_steps_lonlat){
+ for (var i = 0; i < settings.routing_steps_lonlat.length/2; i++) {
+ lon = settings.routing_steps_lonlat[i*2];
+ lat = settings.routing_steps_lonlat[i*2+1];
+ settings.current_position = new OpenLayers.LonLat(lon, lat
+ ).transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION);
+ methods.routingAddStep();
+ }
+ }
+ methods.preload_images();
}, // end of init
+ /* Preload icons */
+ preload_images: function(){
+ if (typeof extra_url == 'undefined') return;
+ var uri = extra_url + "getAllCategories/";
+ $.ajax({url: uri,
+ dataType: "json",
+ success: function (data) {
+ if (!data.categories){return}
+ for(var idx=0; idx<data.categories.length; idx++){
+ new Image().src = data.categories[idx].icon.url;
+ if(data.categories[idx].icon_hover){
+ new Image().src =
+ data.categories[idx].icon_hover.url;
+ }
+ }
+ },
+ error: function (data) {
+ // fail silently
+ }
+ });
+ },
+
+ activateContextMenu: function(){
+ settings.edition_type_is_route = false;
+ settings.map.events.unregister('click', settings.map,
+ methods.setMarker);
+ settings.map.events.register('click', settings.map,
+ methods.displayMapMenu);
+ },
+
+ activateRouteEdit: function(){
+ settings.edition_type_is_route = true;
+ settings.map.events.unregister('click', settings.map,
+ methods.setMarker);
+ settings.map.events.register('click', settings.map,
+ methods.displayMapMenu);
+ },
+
+ activateMarkerEdit: function(){
+ settings.edition_type_is_route = false;
+ if ($('#chimere_map_menu').length){
+ $('#chimere_map_menu').hide();
+ }
+ if (settings.current_popup != null) {
+ settings.current_popup.hide();
+ }
+ settings.map.events.unregister('click', settings.map,
+ methods.displayMapMenu);
+ settings.map.events.register('click', settings.map,
+ methods.setMarker);
+ },
+ // change map_layer
+ changeMapLayer: function(map_idx){
+ settings.map.setBaseLayer(settings.map_layers[map_idx]);
+ },
+
+ // init the context menu
+ zoomIn: function(){
+ methods.mapCenter();
+ settings.map.zoomIn();
+ },
+
+ // zoom out from the map menu
+ zoomOut: function(){
+ methods.mapCenter();
+ settings.map.zoomOut();
+ },
+
+ // center from the map menu
+ mapCenter: function(){
+ $('#chimere_map_menu').hide();
+ settings.map.setCenter(settings.current_position);
+ },
+
+ // set current position
+ setCurrentPosition: function(lonlat){
+ settings.current_position = lonlat;
+ },
+ zoomOnCluster: function(feature){
+ if(!feature.cluster) // if not cluster
+ {
+ feature.attributes.marker.events.triggerEvent('click');
+ feature.attributes.marker.events.triggerEvent('mouseover');
+ feature.attributes.marker.events.triggerEvent('mouseout');
+ } else {
+ methods.zoomIn();
+ settings.map.setCenter(
+ feature.geometry.getBounds().getCenterLonLat());
+ }
+ },
/*
+ * Display menu on the map
+ */
+ displayMapMenu: function(e) {
+ if (methods.hidePopup(e)) return;
+ if ($('#chimere_map_menu').is(":visible")){
+ $('#chimere_map_menu').hide();
+ } else{
+ methods.setCurrentPosition(
+ settings.map.getLonLatFromViewPortPx(e.xy));
+ var offsetX = e.pageX;
+ var offsetY = e.pageY;
+ $('#chimere_map_menu').show('fast');
+ $('#chimere_map_menu').css('display', 'block');
+ $('#chimere_map_menu').css('top', offsetY);
+ $('#chimere_map_menu').css('left', offsetX);
+ }
+ },
+ /*
* Load markers and route from DB
*/
loadGeoObjects: function () {
@@ -237,30 +545,44 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
if (!ids) ids = '0';
var uri = extra_url + "getGeoObjects/" + ids;
if (settings.display_submited) uri += "/A_S";
- $.ajax({url: uri,
+ $.ajax({url: uri,
dataType: "json",
success: function (data) {
settings.layerMarkers.clearMarkers();
settings.layerVectors.removeAllFeatures();
+ if (settings.enable_clustering){
+ settings.cluster_array = [];
+ settings.layerCluster.removeAllFeatures();
+ }
for (var i = 0; i < data.features.length; i++) {
var feature = data.features[i];
if (feature.geometry.type == 'Point'){
methods.addMarker(feature);
} else if (feature.geometry.type == 'LineString') {
methods.addRoute(feature);
+ } else if (feature.geometry.type == 'MultiLineString') {
+ methods.addMultiLine(feature);
}
}
+ if (settings.enable_clustering){
+ settings.layerCluster.addFeatures(
+ settings.cluster_array);
+ methods.cleanCluster();
+ }
+ settings.map.resetLayersZIndex();
},
- error: function (data) {
+ error: function (data, textStatus, errorThrown) {
settings.layerMarkers.clearMarkers();
settings.layerVectors.removeAllFeatures();
+ if (settings.enable_clustering){
+ settings.layerCluster.removeAllFeatures();
+ }
},
complete: function () {
if($('#waiting').length){$('#waiting').hide();}
}
});
},
-
/*
* Update the categories div in ajax
*/
@@ -276,9 +598,11 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
uri += "getAvailableCategories/";
var params = {"current_extent": current_extent}
if (settings.display_submited) params["status"] = "A_S";
- $.ajax({url: uri,
- data: params,
+ $.ajax({url: uri,
+ data: params,
+ cache: false,
success: function (data) {
+ $('#categories').empty();
$('#categories').html(data);
_init_categories();
_reCheckCategories();
@@ -295,7 +619,13 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
category_element.parent().find("li input").attr("checked", val);
}
var _toggle_categories = function (subcategory_element) {
- var parent = subcategory_element.parent().parent().parent();
+ var parent = subcategory_element.closest('ul');
+ var parent_label = parent.parent().find("> span");
+ if (parent.find('input[type=checkbox]:checked').length){
+ parent_label.addClass('category-selected');
+ } else {
+ parent_label.removeClass('category-selected');
+ }
var master_check = parent.find("> input");
if (parent.find('.subcategories input[type=checkbox]').length ==
parent.find('.subcategories input[type=checkbox]:checked').length){
@@ -303,32 +633,66 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
} else {
master_check.removeAttr('checked');
}
+
+ if($('#action-categories').length){
+ if ($('#categories input[type=checkbox]:checked').length){
+ $('#action-categories').addClass('category-selected');
+ } else {
+ $('#action-categories').removeClass('category-selected');
+ }
+ }
return master_check;
};
var _init_categories = function () {
/*
* Add event listener in categories DOM elements
*/
- $('#categories #ul_categories > li > input').bind("click", function () {
- methods.hidePopup();
+ $('#categories #ul_categories > li > input').bind("click",
+ function (e) {
+ methods.hidePopup(e);
_toggle_subcategories($(this));
methods.loadGeoObjects();
settings.permalink.updateLink();
});
- $('.subcategories li input').bind("click", function () {
- methods.hidePopup();
+ $('.subcategories li input').bind("click", function (e) {
+ var c_name = $(this).attr('name');
+ c_name = c_name.substr(c_name.lastIndexOf("_")+1);
+ if($(this).is(':checked')){
+ methods.subcategory_detail(c_name);
+ }
+ var par = $(this).parent();
+ if ($(this).attr('checked')){
+ par.addClass('selected');
+ } else {
+ par.removeClass('selected');
+ }
+ methods.hidePopup(e);
methods.loadGeoObjects();
_toggle_categories($(this));
settings.permalink.updateLink();
+ if ($('#layer_cat_'+c_name).length){
+ $('#layer_cat_'+c_name).prop("checked",
+ this.checked);
+ }
});
$('#display_submited_check').bind("click", function () {
methods.loadGeoObjects();
settings.permalink.updateLink();
});
// Zoom to category
- $(".zoom_to_category").bind("click", function (e) {var id = this.id.substr(this.id.lastIndexOf("_")+1); helpers.zoom_to_category(id);});
- $(".zoom_to_subcategory").bind("click", function (e) {var id = this.id.substr(this.id.lastIndexOf("_")+1); helpers.zoom_to_subcategories([id]);});
- $(".toggle_category").bind("click", function (e) {var id = this.id.substr(this.id.lastIndexOf("_")+1); methods.toggle_category(id); });
+ $(".zoom_to_category").bind("click", function (e) {
+ var id = this.id.substr(this.id.lastIndexOf("_")+1);
+ helpers.zoom_to_category(id);
+ });
+ $(".zoom_to_subcategory").bind("click", function (e) {
+ var id = this.id.substr(this.id.lastIndexOf("_")+1);
+ helpers.zoom_to_subcategories([id]);
+ });
+ $(".toggle_category").parent().bind("click", function (e) {
+ var item = $(this).children('.toggle_category');
+ var id = item.attr('id').substr(item.attr('id').lastIndexOf("_")+1);
+ methods.toggle_category(id);
+ });
}
var _reCheckCategories = function (){
/* recheck categories on init or when a redraw occurs */
@@ -351,6 +715,37 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
}
},
/*
+ * Hide clusterized markers
+ */
+ cleanCluster: function (){
+ if (settings.map.getZoom() === 18) {
+ // Don't cluster at this level. No matter what.
+ settings.clustering.threshold = 1000;
+ } else {
+ settings.clustering.threshold = 2;
+ }
+ //settings.layerCluster.refresh({force:true});
+ settings.clustering.recluster();
+ var hidden_feature_idx = [];
+ if (settings.map.getZoom() != 18) {
+ for(var idx=0; idx<settings.layerCluster.features.length; idx++){
+ if(settings.layerCluster.features[idx].cluster){
+ for(var c=0;c < settings.layerCluster.features[idx].cluster.length; c++) {
+ hidden_feature_idx.push(
+ settings.layerCluster.features[idx].cluster[c].attributes.pk);
+ }
+ }
+ }
+ }
+ for(j=0; j<settings.layerMarkers.markers.length;j++){
+ if(hidden_feature_idx.indexOf(settings.layerMarkers.markers[j].pk) > -1){
+ settings.layerMarkers.markers[j].display(false);
+ } else {
+ settings.layerMarkers.markers[j].display(true);
+ }
+ }
+ },
+ /*
* Put a marker on the map
*/
addMarker: function (mark) {
@@ -362,24 +757,37 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
var lon = mark.geometry.coordinates[0];
var size = new OpenLayers.Size(mark.properties.icon_width,
mark.properties.icon_height);
- var iconclone = new OpenLayers.Icon(MEDIA_URL + mark.properties.icon_path,
- size, settings.icon_offset);
+ var icon_url = MEDIA_URL + mark.properties.icon_path;
+ var icon_hover_url = '';
+ if (mark.properties.icon_hover_path){
+ var icon_hover_url = MEDIA_URL + mark.properties.icon_hover_path;
+ }
+ var iconclone = new OpenLayers.Icon(icon_url, size,
+ settings.icon_offset);
+
var feature = new OpenLayers.Feature(settings.layerMarkers,
- new OpenLayers.LonLat(lon, lat).transform(EPSG_DISPLAY_PROJECTION,
- EPSG_PROJECTION),
+ new OpenLayers.LonLat(lon, lat).transform(
+ EPSG_DISPLAY_PROJECTION,
+ EPSG_PROJECTION),
{icon:iconclone});
feature.pk = mark.properties.pk;
- feature.popupClass = OpenLayers.Popup.FramedCloud;
+ feature.popupClass = settings.popupClass;
feature.data.popupContentHTML = "<div class='cloud'>";
- feature.data.popupContentHTML += mark.properties.name;
+ if (!settings.popupContentFull) {
+ feature.data.popupContentHTML += mark.properties.name;
+ }
feature.data.popupContentHTML += "</div>";
feature.data.overflow = 'hidden';
var marker = feature.createMarker();
+ marker.pk = feature.pk;
+ marker.icon_url = icon_url;
+ marker.icon_hover_url = icon_hover_url;
+ marker.category_name = mark.properties.category_name;
/* manage markers events */
var _popup = function() {
/* show the popup */
if (settings.current_popup != null) {
- settings.current_popup.hide();
+ settings.current_popup.hide();
}
if (feature.popup == null) {
feature.popup = feature.createPopup();
@@ -389,42 +797,101 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
}
settings.current_popup = feature.popup;
/* hide on click on the cloud */
- settings.current_popup.groupDiv.onclick = methods.hidePopup;
+ if (!settings.explicit_popup_hide){
+ settings.current_popup.groupDiv.onclick = methods.hidePopup;
+ }
settings.permalink.updateLink();
}
+ var _repan_popup = function(){
+ /* re-pan manually */
+
+ // no clean way to detect if all the element are ready
+ // lack of better...
+ setTimeout(
+ function(){
+ settings.current_popup.panIntoView();
+ }, 1000);
+ }
+
var markerClick = function (evt) {
settings.current_feature = feature;
+ methods.setCurrentPosition(feature.lonlat);
if ( settings.on_marker_click ) {
settings.on_marker_click(evt, mark, settings);
}
else
{
+ methods.center_on_feature();
+ $('#chimere_map_menu').hide();
// Default popup
if (feature.popup && feature.popup.visible()) {
if (settings.current_popup == feature.popup) {
feature.popup.hide();
if (!settings.simple){
- $('#panel').removeClass('panel-minified');
$('#detail').hide();
}
} else {
settings.current_popup.hide();
_popup();
methods.display_feature_detail(feature.pk);
+ _repan_popup();
}
} else {
_popup();
methods.display_feature_detail(feature.pk);
+ _repan_popup();
}
}
OpenLayers.Event.stop(evt);
};
var markerOver = function (evt) {
document.body.style.cursor='pointer';
+ if (settings.current_feature && settings.current_feature.popup
+ && settings.current_feature.popup.visible()) return;
+ var marker = evt.object;
+ if (marker.icon_hover_url){
+ marker.setUrl(marker.icon_hover_url);
+ }
+ px = settings.map.getPixelFromLonLat(marker.lonlat);
+ marker_hover = $('#'+settings.marker_hover_id);
+ marker_hover_content = $('#'+settings.marker_hover_content_id);
+ marker_hover_content.html(marker.category_name);
+ var map_position = $(settings.map.div).offset();
+
+ var width = marker_hover.width();
+ width += parseInt(marker_hover.css("padding-left"), 10)
+ + parseInt(marker_hover.css("padding-right"), 10)
+ + parseInt(marker_hover.css("margin-left"), 10)
+ + parseInt(marker_hover.css("margin-right"), 10)
+ + parseInt(marker_hover.css("borderLeftWidth"), 10)
+ + parseInt(marker_hover.css("borderRightWidth"), 10);
+ var pos_x = px.x + map_position.left
+ - width/2 + 1;
+ if (settings.marker_hover_offset)
+ pos_x += settings.marker_hover_offset.x;
+ $('#'+settings.marker_hover_id).css('left', pos_x);
+ var height = marker_hover.height();
+ height += parseInt(marker_hover.css("padding-top"), 10)
+ + parseInt(marker_hover.css("padding-bottom"), 10)
+ + parseInt(marker_hover.css("margin-top"), 10)
+ + parseInt(marker_hover.css("margin-bottom"), 10)
+ + parseInt(marker_hover.css("borderBottomWidth"), 10)
+ + parseInt(marker_hover.css("borderTopWidth"), 10);
+ var pos_y = px.y + map_position.top
+ - height - marker.icon.size.h;
+ if (settings.marker_hover_offset)
+ pos_y += settings.marker_hover_offset.y;
+ $('#'+settings.marker_hover_id).css('top', pos_y);
+ $('#'+settings.marker_hover_id).show();
OpenLayers.Event.stop(evt);
};
var markerOut = function (evt) {
document.body.style.cursor='auto';
+ var marker = evt.object;
+ if (marker.icon_hover_url){
+ marker.setUrl(marker.icon_url);
+ }
+ $('#'+settings.marker_hover_id).hide();
OpenLayers.Event.stop(evt);
};
marker.events.register('click', feature, markerClick);
@@ -433,13 +900,29 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
settings.layerMarkers.addMarker(marker);
/* show the item when designed in the permalink */
if (settings.display_feature == feature.pk){
+ settings.current_feature = feature;
_popup(feature);
methods.display_feature_detail(feature.pk);
if (!settings.display_route){
settings.map.setCenter(feature.lonlat, 16);
- methods.loadCategories();
+ _repan_popup();
}
+ settings.display_feature = null;
+ //methods.loadCategories();
+ }
+
+ if (settings.enable_clustering){
+ // manage cluster layer
+ var point = new OpenLayers.Geometry.Point(lon, lat).transform(
+ EPSG_DISPLAY_PROJECTION,
+ EPSG_PROJECTION);
+ var feat = new OpenLayers.Feature.Vector(point);
+ feat.attributes = { icon: MEDIA_URL + mark.properties.icon_path,
+ name: "", label:"", pk:mark.properties.pk,
+ marker:marker};
+ settings.cluster_array.push(feat);
}
+
return feature;
},
@@ -459,7 +942,7 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
settings.current_feature = new OpenLayers.Feature.Vector();
var style = OpenLayers.Util.extend({},
- OpenLayers.Feature.Vector.style['default']);
+ OpenLayers.Feature.Vector.style['default']);
style.strokeColor = route.properties.color;
style.strokeWidth = 3;
settings.current_feature.style = style;
@@ -471,6 +954,307 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
methods.loadCategories();
}
},
+ /*
+ * Put a multiline on the map
+ */
+ addMultiLine: function(feature) {
+ var gformat = new OpenLayers.Format.GeoJSON();
+ var feats = gformat.read(feature);
+ var style = OpenLayers.Util.extend({},
+ OpenLayers.Feature.Vector.style['default']);
+ style.strokeColor = feature.properties.color;
+ style.strokeWidth = 2;
+ feats[0].style = style;
+ feats[0].geometry = feats[0].geometry.transform(
+ EPSG_DISPLAY_PROJECTION,
+ settings.map.getProjectionObject());
+ settings.layerVectors.addFeatures(feats);
+ },
+ routingInputChange: function(nominatim_id){
+ $('#map_menu_clear').show();
+ switch(nominatim_id){
+ case 'nominatim_start':
+ settings.routing_start = new OpenLayers.Marker(
+ new OpenLayers.LonLat(
+ $('#'+nominatim_id+'_lon').val(),
+ $('#'+nominatim_id+'_lat').val()
+ ).transform(EPSG_DISPLAY_PROJECTION,
+ settings.map.getProjectionObject()),
+ settings.icon_start);
+ settings.layerRouteMarker.addMarker(settings.routing_start);
+ break;
+ case 'nominatim_end':
+ settings.routing_end = new OpenLayers.Marker(
+ new OpenLayers.LonLat(
+ $('#'+nominatim_id+'_lon').val(),
+ $('#'+nominatim_id+'_lat').val()
+ ).transform(EPSG_DISPLAY_PROJECTION,
+ settings.map.getProjectionObject()),
+ settings.icon_end);
+ settings.layerRouteMarker.addMarker(settings.routing_end);
+ break;
+ default:
+ settings.routing_steps.push(new OpenLayers.Marker(
+ new OpenLayers.LonLat(
+ $('#'+nominatim_id+'_lon').val(),
+ $('#'+nominatim_id+'_lat').val()
+ ).transform(EPSG_DISPLAY_PROJECTION,
+ settings.map.getProjectionObject()),
+ settings.icon_step.clone()));
+ settings.layerRouteMarker.addMarker(
+ settings.routing_steps[settings.routing_steps.length-1]);
+ break;
+ }
+ if (settings.routing_end && settings.routing_start
+ && $('#search_routing').length) {
+ $('#search_routing').button('enable');
+ }
+ },
+
+ redrawRoutingIcons: function(){
+ settings.layerRouteMarker.clearMarkers();
+ settings.layerRouteMarker.addMarker(settings.routing_start);
+ settings.layerRouteMarker.addMarker(settings.routing_end);
+ for (var k=0;k<settings.routing_steps.length;k++){
+ settings.layerRouteMarker.addMarker(settings.routing_steps[k]);
+ }
+ },
+
+ // set the start point for routing
+ routingFrom: function(){
+ $('#chimere_map_menu').hide();
+ settings.routing_panel_open();
+ $('#map_menu_clear').show();
+ settings.routing_start = new OpenLayers.Marker(
+ settings.current_position.clone(),
+ settings.icon_start);
+ settings.layerRouteMarker.addMarker(settings.routing_start);
+ if (nominatim_url){
+ helpers.updateNominatimName(settings.current_position.clone()
+ .transform(settings.map.getProjectionObject(),
+ EPSG_DISPLAY_PROJECTION),
+ 'start_label');
+ }
+ if (settings.routing_end) methods.route();
+ },
+ // add a step point for routing
+ routingAddStep: function(){
+ $('#chimere_map_menu').hide();
+ settings.routing_panel_open();
+ $('#map_menu_clear').show();
+ settings.routing_steps.push(new OpenLayers.Marker(
+ settings.current_position.clone(),
+ settings.icon_step.clone()));
+ settings.layerRouteMarker.addMarker(
+ settings.routing_steps[settings.routing_steps.length-1]);
+
+ if (nominatim_url){
+ var current_itinerary_number = methods.add_step_fx();
+ helpers.updateNominatimName(settings.current_position.clone()
+ .transform(settings.map.getProjectionObject(),
+ EPSG_DISPLAY_PROJECTION),
+ 'step_'+current_itinerary_number+'_label');
+ }
+ if (settings.routing_end && settings.routing_start) methods.route();
+ },
+
+ // add a step on the interface
+ add_step_fx: function (){
+ settings.itinerary_step_number += 1;
+ var cloned = $("#id_start_div").clone();
+ var c_id = 'step_' + settings.itinerary_step_number;
+ cloned.attr('id', 'id_'+c_id+'_div');
+ cloned.children('label').html(step_label).addClass('step_label');
+ cloned.children("#nominatim_start_label").attr('id', c_id+'_label'
+ ).html('');
+ cloned.children('label.nominatim-label').attr('for', ""
+ ).removeClass('step_label');
+ var id_suffixes = ['_lat', '_lon', ''];
+ for (idx=0;idx < id_suffixes.length;idx+=1){
+ var suffix = id_suffixes[idx];
+ val = c_id + suffix;
+ cloned.children("#nominatim_start"+suffix).attr('id', val
+ ).attr('name', val);
+ }
+ if (settings.itinerary_step_number == 1){
+ $("#nominatim_end_label").after(cloned);
+ } else {
+ $("#step_"+(settings.itinerary_step_number-1)+"_label"
+ ).after(cloned);
+ }
+ $('#' + c_id).val(default_nominatim_lbl);
+ $('#' + c_id).click(function(){
+ $('#'+c_id).val('');
+ });
+ $(".nominatim-widget").autocomplete(nominatim_widget_options);
+ return settings.itinerary_step_number;
+ },
+
+ // set the finish point for routing
+ routingTo: function(){
+ $('#chimere_map_menu').hide();
+ settings.routing_panel_open();
+ $('#map_menu_clear').show();
+ settings.routing_end = new OpenLayers.Marker(
+ settings.current_position.clone(),
+ settings.icon_end);
+ settings.layerRouteMarker.addMarker(settings.routing_end);
+ if (nominatim_url){
+ helpers.updateNominatimName(settings.current_position.clone()
+ .transform(settings.map.getProjectionObject(),
+ EPSG_DISPLAY_PROJECTION),
+ 'end_label');
+ }
+ if (settings.routing_start) methods.route();
+ },
+
+ // clear the current itinerary
+ routingClear: function(){
+ $('#nominatim_start_lon').val('');
+ $('#nominatim_start_lat').val('');
+ $('#nominatim_start_label').html('');
+ $('#chimere_start_label').html('');
+ $('#nominatim_end_lon').val('');
+ $('#nominatim_end_lat').val('');
+ $('#nominatim_end_label').html('');
+ $('#chimere_end_label').html('');
+ $('.nominatim-widget').val(default_nominatim_lbl);
+ $('#chimere_map_menu').hide();
+ $('#map_menu_clear').hide();
+ $('#chimere_itinerary').hide();
+ $('#chimere_itinerary_form').show();
+ $('div[id^="id_step_"]').remove();
+ if($('#search_routing').length) $('#search_routing').button('disable');
+ settings.layerRoute.removeAllFeatures();
+ settings.layerRouteMarker.clearMarkers();
+ settings.routing_start = null;
+ settings.routing_end = null;
+ settings.routing_steps = new Array();
+ settings.current_itinerary_number = 0;
+ settings.current_route_feature = null;
+ settings.permalink.updateLink();
+ },
+ // display a route
+ route: function(){
+ if($('#search_routing').length) $('#search_routing').button('enable');
+ if (!settings.routing_start || !settings.routing_end){
+ return;
+ }
+ var steps = [settings.routing_start.lonlat.clone()]
+ for (var i = 0; i < settings.routing_steps.length; i++) {
+ steps.push(settings.routing_steps[i].lonlat.clone());
+ }
+ steps.push(settings.routing_end.lonlat.clone());
+ // create the appropriate URL
+ var uri = extra_url + "route/"
+ var transport = $('input[name=transport]:checked').val();
+ if(transport){
+ uri += transport + "/"
+ }
+ var speed = $('#id_speed option:selected').val();
+ if(!speed){
+ var speed = $('input[name=speed]:checked').val();
+ }
+ if(speed){
+ uri += speed.split('_')[1] + "/"
+ }
+ for (var i = 0; i < steps.length; i++) {
+ var step = steps[i].transform(
+ settings.map.getProjectionObject(),
+ EPSG_DISPLAY_PROJECTION);
+ if (i > 0){
+ uri += '_';
+ }
+ uri += step.lon + '_' + step.lat;
+ }
+ settings.permalink.updateLink();
+ $.ajax({url: uri,
+ dataType: "json",
+ success: function (data) {
+ settings.layerRoute.removeAllFeatures();
+ methods.redrawRoutingIcons();
+ methods.hideMessage();
+ if (!data.features.length){
+ methods.displayMessage(routing_fail_message);
+ return;
+ }
+ for (var i = 0; i < data.features.length; i++) {
+ var feat = data.features[i];
+ if(feat.type == 'LineString'){
+ settings.current_route_feature =
+ methods.putRoute(feat);
+ } else {
+ var lonlat = new OpenLayers.LonLat(
+ feat.geometry.coordinates[0],
+ feat.geometry.coordinates[1]);
+ lonlat.transform(EPSG_DISPLAY_PROJECTION,
+ settings.map.getProjectionObject());
+ var icon_height = feat.properties.icon_height;
+ var icon_width = feat.properties.icon_width;
+ var marker = new OpenLayers.Marker(lonlat,
+ new OpenLayers.Icon(
+ feat.properties.icon_path,
+ new OpenLayers.Size(icon_width,
+ icon_height),
+ new OpenLayers.Pixel(
+ -(icon_width/2),
+ -icon_height))
+ );
+ settings.layerRouteMarker.addMarker(marker);
+ }
+ }
+ if (data.message) methods.displayMessage(data.message);
+ settings.map.zoomToExtent(
+ settings.layerRoute.getDataExtent());
+ settings.map.zoomOut();
+ $('#id_transport_it').find('span'
+ ).removeClass('selected');
+ $('#id_transport_it_'+data.properties.transport
+ ).addClass('selected');
+ $('#chimere_total_label').html(
+ data.properties.total);
+ $('#chimere_itinerary_content').html(
+ data.properties.description);
+ $('#chimere_itinerary').show();
+ if(!settings.edition_type_is_route){
+ $('#chimere_itinerary_form').hide();
+ settings.routing_panel_open();
+ } else {
+ methods.updateRoutingInput();
+ }
+ },
+ error: function (jqXHR, textStatus, errorThrown) {
+ methods.redrawRoutingIcons();
+ methods.hideMessage();
+ console.log(errorThrown);
+ console.log(textStatus);
+ settings.layerRoute.removeAllFeatures();
+ methods.displayMessage(routing_fail_message);
+ }
+ });
+
+ },
+ /*
+ Put a route on the map
+ */
+ putRoute: function(polyline) {
+ var point_array = new Array();
+ for (i=0; i<polyline.coordinates.length; i++){
+ var point = new OpenLayers.Geometry.Point(polyline.coordinates[i][0],
+ polyline.coordinates[i][1]);
+ point_array.push(point);
+ }
+ var linestring = new OpenLayers.Geometry.LineString(point_array);
+ linestring.transform(EPSG_DISPLAY_PROJECTION, settings.map.getProjectionObject());
+ current_route = new OpenLayers.Feature.Vector();
+ var style = OpenLayers.Util.extend({},
+ OpenLayers.Feature.Vector.style['default']);
+ style.strokeWidth = 3;
+ current_route.style = style;
+ current_route.geometry = linestring;
+ settings.layerRoute.addFeatures([current_route]);
+ return current_route;
+ },
display_feature_detail: function (pk) {
/*
* update current detail panel with an AJAX request
@@ -480,25 +1264,34 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
uri += "getDetail/" + pk;
var params = {}
if (settings.simple) { params["simple"] = 1; }
- $.ajax({url: uri,
- data: params,
+ $.ajax({url: uri,
+ data: params,
+ dataType: "html",
success: function (data) {
- if ( settings.display_feature_detail_fx ) {
- // Custom function ?
- settings.display_feature_detail_fx(data, settings);
+ if ( settings.display_feature_detail_fx ) {
+ // Custom function ?
+ settings.display_feature_detail_fx(data, settings);
+ }
+ else {
+ if (!settings.popupContentFull) {
+ $('#detail').html(data).show();
}
else {
- if (!settings.simple) {
- $('#panel').addClass('panel-minified');
- $('#detail').html(data).show();
- }
- else {
- settings.current_popup.setContentHTML("<div class='cloud'>" + data + "</div>");
- }
+ settings.current_popup.setContentHTML("<div class='cloud'>" + data + "</div>");
}
}
+ }
});
},
+ displayMessage: function(message){
+ if (!$('#chimere_message').length) return;
+ $('#chimere_message').html(message);
+ $('#chimere_message').dialog('open');
+ },
+ hideMessage: function(message){
+ if (!$('#chimere_message').length) return;
+ $('#chimere_message').dialog('close');
+ },
center_on_feature: function(feature) {
var f = get_or_set(feature, settings.current_feature);
if (f)
@@ -520,28 +1313,64 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
var uri = extra_url + "getDescriptionDetail/" + category_id;
$.ajax({url:uri,
success: function (data) {
- $("#category_detail").html(data).dialog();
- $("#category_detail").dialog( "option", "title",
+ $("#category_description").html(data).dialog();
+ $("#category_description").dialog( "option", "title",
$("#category_title").html());
}
});
},
+ /*
+ * Load the subcategory description if available
+ */
+ subcategory_detail: function(category_id){
+ var uri = extra_url + "getCategory/" + category_id;
+
+ $.ajax({url: uri,
+ dataType: "json",
+ success: function (data) {
+ if (!data.description){return}
+ $('#category_description').html(data.description);
+ $("#category_description").dialog("option", "title",
+ data.name);
+ $('#category_description').dialog('open');
+ },
+ error: function (data) {
+ // fail silently
+ }
+ });
+ },
toggle_category: function (id) {
// TODO make this id DOM element customisable
// Check if element is currently visible or not
var was_visible = $("#maincategory_" + id).is(":visible");
// Close all categories
- $("#categories ul.subcategories").hide();
+ var category_plus = STATIC_URL + "chimere/img/plus.png";
+ var category_minus = STATIC_URL + "chimere/img/minus.png";
+ if (settings.category_accordion){
+ $("#categories ul.subcategories").hide();
+ $("#categories img.toggle_category").attr("src", category_plus);
+ $("#categories .main_category").addClass("toggle_plus");
+ $("#categories .main_category").removeClass("toggle_minus");
+ }
// Put a minus image
- $("#categories img.toggle_category").attr("src", STATIC_URL + "chimere/img/plus.png");
if (!was_visible)
{
// Show the subcategories
$("#maincategory_" + id).toggle();
+ $("#maincategory_" + id).parent().addClass("toggle_minus");
+ $("#maincategory_" + id).parent().removeClass("toggle_plus");
// Put a plus image
- $("#maincategory_img_" + id).attr("src", STATIC_URL + "chimere/img/minus.png");
+ $("#maincategory_img_" + id).attr("src", category_minus);
settings.current_category = id;
}
+ if (!settings.category_accordion && was_visible)
+ {
+ $("#maincategory_" + id).toggle();
+ $("#maincategory_" + id).parent().addClass("toggle_plus");
+ $("#maincategory_" + id).parent().removeClass("toggle_minus");
+ // Put a minus image
+ $("#maincategory_img_" + id).attr("src", category_plus);
+ }
},
zoomToCurrentExtent: function(){
/* zoom to current extent */
@@ -573,17 +1402,13 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
},
/* put the marker on the map and update latitude and longitude fields */
putEditMarker: function (lonlat, zoom){
- if (settings.current_feature) {
- settings.layerMarkers.removeMarker(settings.current_feature);
+ if (settings.current_edit_feature) {
+ settings.layerMarkers.removeMarker(settings.current_edit_feature);
}
- settings.current_feature = new OpenLayers.Marker(lonlat.clone(),
+ settings.current_edit_feature = new OpenLayers.Marker(lonlat.clone(),
settings.default_icon);
- settings.layerMarkers.addMarker(settings.current_feature);
- lonlat = lonlat.clone().transform(settings.map.getProjectionObject(),
- EPSG_DISPLAY_PROJECTION);
- $('#id_point').val('POINT(' + lonlat.lon + ' ' + lonlat.lat + ')');
- $('#live_latitude').val(lonlat.lat);
- $('#live_longitude').val(lonlat.lon);
+ settings.layerMarkers.addMarker(settings.current_edit_feature);
+ methods.updateMarkerInput();
/* zoom to the point */
if (zoom){
var bounds = settings.layerMarkers.getDataExtent();
@@ -591,6 +1416,28 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
}
return;
},
+ updateMarkerInput: function(){
+ if (!settings.current_edit_feature) {
+ return;
+ }
+ lonlat = settings.current_edit_feature.lonlat.clone().transform(
+ settings.map.getProjectionObject(),
+ EPSG_DISPLAY_PROJECTION);
+ $('#id_point').val('POINT(' + lonlat.lon + ' ' + lonlat.lat + ')');
+ if($('#live_latitude').length){
+ $('#live_latitude').val(lonlat.lat);
+ $('#live_longitude').val(lonlat.lon);
+ }
+
+ },
+ updateRoutingInput: function(){
+ if (!settings.current_route_feature) {
+ return;
+ }
+ var current_geo = settings.current_route_feature.geometry.clone();
+ current_geo.transform(EPSG_PROJECTION, EPSG_DISPLAY_PROJECTION);
+ jQuery('#id_route').val(current_geo);
+ },
activateCurrentControl: function(){
if (settings.current_control){
settings.current_control.activate();
@@ -646,19 +1493,25 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
if (bounds) settings.map.zoomToExtent(bounds);
},
hidePopup: function (evt) {
+ $('#'+settings.marker_hover_id).hide();
if (settings.hide_popup_fx) {
settings.hide_popup_fx(evt, settings)
}
else { // Default behaviour
if (settings.current_popup)
{
- settings.current_popup.hide();
if (!settings.simple){
- $('#panel').removeClass('panel-minified');
$('#detail').hide();
}
+ if (settings.current_popup.visible()){
+ settings.current_popup.hide();
+ if(evt)
+ settings.map.events.triggerEvent('click', evt);
+ return true;
+ }
}
}
+ return false;
},
saveExtent: function(){
var extent_key = 'MAP_EXTENT';
@@ -794,8 +1647,23 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
if (vertices){
jQuery('#id_point').val(vertices);
}
+ },
+ updateNominatimName:function(lonlat, response_id){
+ $.ajax({
+ url: nominatim_url.substring(0, nominatim_url.length-6) + 'reverse',
+ data: {
+ format: "json",
+ lat:lonlat.lat,
+ lon:lonlat.lon
+ },
+ dataType:'json',
+ success: function (vals) {
+ $('#'+response_id).html(vals.display_name);
+ $('#nominatim_'+response_id).html(vals.display_name);
+ $('#chimere_'+response_id).html(vals.display_name);
+ }
+ });
}
-
}; // End of helpers
$.fn.chimere = function (thing) {
@@ -822,7 +1690,6 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
else {
$.error( 'Method ' + thing + ' does not exist on jQuery.chimere' );
}
-
return this;
};
})( jQuery );
diff --git a/chimere/static/chimere/js/nominatim-widget.js b/chimere/static/chimere/js/nominatim-widget.js
new file mode 100644
index 0000000..99f7034
--- /dev/null
+++ b/chimere/static/chimere/js/nominatim-widget.js
@@ -0,0 +1,46 @@
+var default_nominatim_lbl = '';
+var nominatim_widget_options = {
+ source: function (request, response) {
+ $.ajax({
+ url: nominatim_url,
+ data: {
+ format: "json",
+ q: request.term,
+ },
+ dataType:'json',
+ success: function ( data ) {
+ response ( $.map(data, function(item) {
+ return {
+ label: item.display_name,
+ value: item.display_name,
+ lat: item.lat,
+ lon: item.lon
+ }
+ }));
+
+ }
+ })
+ },
+ minLength: 6,
+ delay: 1000,
+ select: function ( event, ui ) {
+ $('#'+$(this).attr('id')+'_lat').val(ui.item.lat);
+ $('#'+$(this).attr('id')+'_lon').val(ui.item.lon);
+ $('#'+$(this).attr('id')+'_label').html(ui.item.label);
+ $('#chimere_'+$(this).attr('id').substring(10)+'_label').html(
+ ui.item.label);
+ $('#'+$(this).attr('id')).val(default_nominatim_lbl);
+ jQuery("#map").chimere("routingInputChange", $(this).attr('id'));
+ return false;
+ },
+ open: function() {
+ $( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
+ },
+ close: function() {
+ $( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
+ }
+}
+
+$(function(){
+ $(".nominatim-widget").autocomplete(nominatim_widget_options);
+});
diff --git a/chimere/static/chimere/js/routing-widget.js b/chimere/static/chimere/js/routing-widget.js
new file mode 100644
index 0000000..34ca46c
--- /dev/null
+++ b/chimere/static/chimere/js/routing-widget.js
@@ -0,0 +1,47 @@
+var step_label = "Step";
+var add_step = null;
+
+$(document).ready(function() {
+ var itinerary_step_number = 0;
+ $("#add_step_link").click(function(){
+ $('#main-map').chimere('add_step_fx');
+ return false;
+ });
+ $('#search_routing').button({'disabled':true});
+ $('#routing_button').click(function(){
+ $('#chimere_itinerary_panel').dialog('open');
+ });
+ $('#chimere_itinerary_modify').click(function(){
+ $('#chimere_itinerary').hide();
+ $('#chimere_itinerary_form').show();
+ });
+ $('#chimere_itinerary_new').click(function(){
+ $('#map').chimere('routingClear');
+ });
+ $('#search_routing').click(function(){
+ $('#map').chimere('route');
+ });
+
+ var detached_speeds = Array();
+ function filter_speed(transport){
+ $("#id_speed_div").show();
+ for (i=0;i<detached_speeds.length;i+=1){
+ $("#id_speed_div ul").append(detached_speeds[i]);
+ }
+ detached_speeds = Array();
+ $("#id_speed_div input[type=radio]").each(function(){
+ if(!$(this).val().match(transport) && $(this).val()){
+ detached_speeds.push($(this).parent().parent().detach());
+ }
+ });
+ $('#id_speed_div').val('');
+ if($("#id_speed_div input[type=radio]").length == 1){
+ $("#id_speed_div").hide();
+ }
+ }
+ $('#id_transport label').click(function(){
+ checked_item = $("#"+$(this).attr('for'));
+ filter_speed(checked_item.val());
+ });
+ filter_speed($('#id_transport :checked').val());
+});
diff --git a/chimere/static/chimere/js/utils.js b/chimere/static/chimere/js/utils.js
index 80ab91a..460e843 100644
--- a/chimere/static/chimere/js/utils.js
+++ b/chimere/static/chimere/js/utils.js
@@ -236,6 +236,12 @@ function has_index(index, arr) {
function get_or_set(v, d){
return typeof v === "undefined" ? d : v;}
+/* email validity */
+function isValidEmailAddress(emailAddress) {
+ var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
+ return pattern.test(emailAddress);
+};
+
/* remove multiple, leading or trailing spaces */
function trim(s) {
s = s.replace(/(^\s*)|(\s*$)/gi,"");
diff --git a/chimere/tasks.py b/chimere/tasks.py
index a74dce8..02e32a4 100644
--- a/chimere/tasks.py
+++ b/chimere/tasks.py
@@ -33,7 +33,7 @@ from external_utils import OsmApi
def single_instance_task(timeout):
def task_exc(func):
def wrapper(*args, **kwargs):
- return func()
+ return func(*args, **kwargs)
return wrapper
return task_exc
diff --git a/chimere/templates/base.html b/chimere/templates/base.html
index 2a50fc3..619aa0b 100644
--- a/chimere/templates/base.html
+++ b/chimere/templates/base.html
@@ -2,30 +2,30 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
- <title>{% block title %}Chimère{% endblock %}</title>
+ <title>{% block title %}{{PROJECT_NAME}}{% endblock %}</title>
{% block extra_head %}
{% endblock %}
</head>
<body {% block body_id %}{% endblock %} {% block body_class %}{% endblock %}>
- {% block extrabody %}
+{% block extrabody %}
+{% endblock %}
+{% block body %}
+<div id="header">
+ {% block header %}
{% endblock %}
- {% block body %}
- <div id="header">
- {% block header %}
- {% endblock %}
- </div>
- <div id="sidebar">
- {% block sidebar %}
- {% endblock %}
- </div>
- <div id="content">
- {% block content %}
- {% endblock %}
- </div>
- <div id="footer">
- {% block footer %}
- {% endblock %}
- </div>
+</div>
+<div id="sidebar">
+ {% block sidebar %}
{% endblock %}
+</div>
+<div id="content">
+ {% block content %}
+ {% endblock %}
+</div>
+<div id="footer">
+ {% block footer %}
+ {% endblock %}
+</div>
+{% endblock %}
</body>
</html>
diff --git a/chimere/templates/chimere/base.html b/chimere/templates/chimere/base.html
index a1a0b39..620c84f 100644
--- a/chimere/templates/chimere/base.html
+++ b/chimere/templates/chimere/base.html
@@ -2,6 +2,7 @@
{% load chimere_tags i18n %}
{% block extra_head %}
<link rel="stylesheet" href="{{ STATIC_URL }}chimere/css/styles.css" />
+<link rel="stylesheet" href="{{ STATIC_URL }}chimere/css/print.css" media='print'/>
{% if css_area %}
<link rel="stylesheet" href="{{ css_area }}" />{% endif %}
{% endblock %}
diff --git a/chimere/templates/chimere/blocks/actions.html b/chimere/templates/chimere/blocks/actions.html
index 2806321..93debb0 100644
--- a/chimere/templates/chimere/blocks/actions.html
+++ b/chimere/templates/chimere/blocks/actions.html
@@ -2,7 +2,7 @@
<ul id='action' class='action'>
{% for action, subactions in actions %}
<li class='ui-widget ui-button ui-state-default ui-corner-all {% ifequal action.id action_selected.0 %} ui-state-active{% endifequal %}'>
- <a href='{{extra_url}}{{ action.path }}' onclick='jQuery("#map").chimere("saveExtent");'>{{ action.label }}</a>
+ <a href='{{ action.url }}' onclick='jQuery("#map").chimere("saveExtent");'>{{ action.label }}</a>
</li>
{% endfor %}
</ul>
@@ -11,7 +11,7 @@
{% ifequal action.id action_selected.0 %}{% if subactions %}
{% for subaction in subactions %}
<li class='ui-widget ui-button ui-state-default ui-corner-all{% ifequal subaction.id action_selected.1 %} ui-state-active{% endifequal %}'>
- <a href='{{extra_url}}{{ subaction.path }}' onclick='saveExtent();'>{{ subaction.label }}</a>
+ <a href='{{ subaction.url }}' onclick='saveExtent();'>{{ subaction.label }}</a>
</li>
{% endfor %}
{% endif %}{% endifequal %}
diff --git a/chimere/templates/chimere/blocks/alternate_multimedia.html b/chimere/templates/chimere/blocks/alternate_multimedia.html
index 0662750..50bddd5 100644
--- a/chimere/templates/chimere/blocks/alternate_multimedia.html
+++ b/chimere/templates/chimere/blocks/alternate_multimedia.html
@@ -14,13 +14,14 @@
{% for formset in formsets %}
{% for frm in formset%}
{% if not forloop.last %}
- <li>
+ <li class='{% if forloop.parentloop.counter0 %}picture{%else%}multimedia{%endif%}'>
{%if forloop.first %}{% for hidden in frm.hidden_fields %}
{{ hidden }}
{% endfor %}{% endif %}
{% for field in frm.visible_fields %}
{% if field.name == "name" %}
- <span class='value'>{{ field.field.value }}</span>
+ <span class='value'>{{ field.value }}</span>
+ <img class='remove-media' alt='Remove media' src='{{STATIC_URL}}chimere/img/close.png'/>
{% endif %}
<span class='hidden'>{{field}}</span>
{% endfor %}
@@ -31,7 +32,7 @@
</ul>
<button id='add_multimedia_list'>{% trans "Add" %}</button>
</div>
- <div id='multimedia_form' title="{% trans "Add multimedia from your computer or a site"%}">
+ <div id='multimedia_form' title="{% trans "Add multimedia from your computer or a website"%}">
<div class='notice'>{% trans "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu luctus ipsum. Donec vel urna a turpis consectetur consectetur. Vestibulum ut enim vel odio porta vulputate." %}
</div>
<div class="fieldWrapper">
@@ -51,6 +52,9 @@
</div>
<script text='text/javascript'>
$(function(){
+ $(".remove-media").click(function(){
+ $(this).parents('li').remove();
+ });
var current_image_number = 0;
var current_multi_number = 0;
$("#multimedia_form").dialog({autoOpen:false,
@@ -110,20 +114,33 @@
content += '<input type="hidden" name="'+prefix+'-DELETE" value=""/>\n';
content += '<input type="hidden" name="'+prefix+'-name" value="'+ $("#multimedia_name").val() +'"/>\n';
content += $("#multimedia_name").val();
- content += " <img class='remove-media' src='{{STATIC_URL}}chimere/img/close.png'/>";
+ content += " <img class='remove-media' alt='Remove media' src='{{STATIC_URL}}chimere/img/close.png'/>";
+ content += " <img class='remove-media' alt='Remove media' src='{{STATIC_URL}}chimere/img/close.png'/>";
content += '</li>';
contener.append(content);
if ($('#media_type_image:checked').val()
&& $("#picture-"+current_image_number+"-picture").val()){
- // the file item cannot be recopied - security issue
- // so it is hiden then a new one is added
- //$('#picture-'+current_image_number+'-picture').hide();
+ // the file field cannot be recopied - security issue
+ // so it is moved
var file_item = $('#picture-'+current_image_number+'-picture');
- //var cloned = file_item.clone(true);
- //file_item.hide();
- //cloned.insertAfter(file_item);
+ var cloned = file_item.clone(true);
+ file_item.hide();
+ cloned.insertAfter(file_item);
file_item.appendTo($("#multimedia_list_content li").last());
+ current_image_number += 1;
+ cloned.attr('id', 'picture-'+current_image_number+'-picture');
+ cloned.attr('name', 'picture-'+current_image_number+'-picture');
+ cloned.val('');
+ $('#id_picture-TOTAL_FORMS').val(current_image_number + 1);
+ } else {
+ current_multi_number += 1;
+ $('#id_multimedia-TOTAL_FORMS').val(current_multi_number + 1);
}
+ // empty the fields
+ $("#multimedia_name").val('');
+ $("#multimedia_url").val('');
+ $("#media_type_image").prop('checked', '');
+ $("#media_type_other").prop('checked', '');
$("#multimedia_form").dialog("close");
$(".remove-media").click(function(){
$(this).parents('li').remove();
diff --git a/chimere/templates/chimere/blocks/categories.html b/chimere/templates/chimere/blocks/categories.html
index 8c8a8f8..c273ae4 100644
--- a/chimere/templates/chimere/blocks/categories.html
+++ b/chimere/templates/chimere/blocks/categories.html
@@ -1,14 +1,14 @@
{% load i18n %}
<ul id='ul_categories'>
{% for category, lst_sub_categories in sub_categories %}
- <li>
+ <li class='main_category'>
<img class="control_image toggle_category" id="maincategory_img_{{category.id}}" alt="control" src="{{ STATIC_URL }}chimere/img/{% if category.selected %}minus.png{% else %}plus.png{% endif %}" />
<input type="checkbox" id='checkall_{{category.id}}'>
{% trans category.name %}
<img id="zoom_to_category_{{category.id}}" class="zoom_image zoom_to_category" alt='{% trans "Zoom to" %} {{category.name}}' src='{{ STATIC_URL }}chimere/img/zoom.png' />
<ul class='subcategories' id='maincategory_{{category.id}}'{% if not category.selected %} style='display:None'{% endif %}>
{% for sub_category in lst_sub_categories %}
- <li id='li_sub_{{sub_category.id}}'>
+ <li id='li_sub_{{sub_category.id}}' class='subcategory'>
<input type='checkbox' name='category_{{sub_category.id}}' id='category_{{sub_category.id}}'{% if sub_category.selected %} checked='checked'{% endif %}/>
<label for='category_{{sub_category.id}}'>
<img alt='{{ sub_category.name }}' src='{{ MEDIA_URL }}{{sub_category.icon.image}}'/>
diff --git a/chimere/templates/chimere/blocks/footer.html b/chimere/templates/chimere/blocks/footer.html
index f2961c3..d895f88 100644
--- a/chimere/templates/chimere/blocks/footer.html
+++ b/chimere/templates/chimere/blocks/footer.html
@@ -1,3 +1,3 @@
{% load i18n %}
-{% trans "This site uses Chimère"%} - <img src="{{STATIC_URL}}chimere/img/copyleft.png" alt="copyleft"/> 2008-2012 <a href='http://blog.peacefrogs.net/nim/chimere/'>Chimère project</a> - {% trans "Map"%} <img src="{{STATIC_URL}}chimere/img/copyleft.png" alt="copyleft"/> <a href='http://openstreetmap.org/'>OpenStreetMap</a>
+{% trans "This site uses Chimère"%} - <img src="{{STATIC_URL}}chimere/img/copyleft.png" alt="copyleft"/> 2008-2013 <a href='http://blog.peacefrogs.net/nim/chimere/'>Chimère project</a> - {% trans "Map"%} <img src="{{STATIC_URL}}chimere/img/copyleft.png" alt="copyleft"/> <a href='http://openstreetmap.org/'>OpenStreetMap</a>
diff --git a/chimere/templates/chimere/blocks/head_chimere.html b/chimere/templates/chimere/blocks/head_chimere.html
index 4031ac4..147d05b 100644
--- a/chimere/templates/chimere/blocks/head_chimere.html
+++ b/chimere/templates/chimere/blocks/head_chimere.html
@@ -1,16 +1,18 @@
{% for css_url in OSM_CSS_URLS %}
<link rel="stylesheet" href="{{ css_url }}" />{% endfor %}
{% for js_url in OSM_JS_URLS %}
-<script src="{{ js_url }}"></script>{% endfor %}
-<script src="{{ STATIC_URL }}chimere/js/jquery.chimere.js"></script>
+<script src="{{ js_url }}" type="text/javascript"></script>{% endfor %}
+{% if routing %}<script src="{{ STATIC_URL }}chimere/js/routing-widget.js" type="text/javascript"></script>{% endif %}
+<script src="{{ STATIC_URL }}chimere/js/clustering.js" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}chimere/js/jquery.chimere.js" type="text/javascript"></script>
<script type="text/javascript">
/* Global variables */
var STATIC_URL = static_url = "{{ STATIC_URL }}";
var MEDIA_URL = media_path = "{{ MEDIA_URL }}";
var extra_url = "{{ EXTRA_URL }}";
</script>
-<script src="{{ STATIC_URL }}chimere/js/utils.js"></script>
-<script src="{{ STATIC_URL }}chimere/js/base.js"></script>
+<script src="{{ STATIC_URL }}chimere/js/utils.js" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}chimere/js/base.js" type="text/javascript"></script>
<script type="text/javascript">
var DEFAULT_ZOOM = {{ DEFAULT_ZOOM }};
var EPSG_DISPLAY_PROJECTION = epsg_display_projection = new OpenLayers.Projection('EPSG:{{ EPSG_DISPLAY_PROJECTION }}');
@@ -23,8 +25,9 @@
var area_name = '{{ area_name }}';{% endif %}
$(function() {$( ".draggable" ).draggable({handle:"h2"});});
+ var get_share_url = '{% url chimere:get-share-url %}';
</script>
-<style>
+<style type="text/css">
.olControlPanPanel div {
background-image: url({{STATIC_URL}}chimere/img/pan-panel.png);
}
diff --git a/chimere/templates/chimere/blocks/head_form.html b/chimere/templates/chimere/blocks/head_form.html
new file mode 100644
index 0000000..032a711
--- /dev/null
+++ b/chimere/templates/chimere/blocks/head_form.html
@@ -0,0 +1,2 @@
+
+<script src="{{ TINYMCE_URL }}tiny_mce.js" type="text/javascript"></script>
diff --git a/chimere/templates/chimere/blocks/head_jme.html b/chimere/templates/chimere/blocks/head_jme.html
index a3fe683..bf31e6f 100644
--- a/chimere/templates/chimere/blocks/head_jme.html
+++ b/chimere/templates/chimere/blocks/head_jme.html
@@ -1,16 +1,16 @@
<script class="jwPlayer" type="application/swf" src="{{STATIC_URL}}jme/packages/player.swf"></script>
-<script src="{{STATIC_URL}}jme/packages/mm.full.min.js"></script>
-<script src="{{STATIC_URL}}jme/utils/jmeEmbedControls.js"></script>
+<script src="{{STATIC_URL}}jme/packages/mm.full.min.js" type="text/javascript"></script>
+<script src="{{STATIC_URL}}jme/utils/jmeEmbedControls.js" type="text/javascript"></script>
<link rel="stylesheet" href="{{STATIC_URL}}jme/css/player-controls.css" />
<!-- a11y-slider -->
-<script src="{{STATIC_URL}}jme/utils/a11y-slider.ext.js"></script>
+<script src="{{STATIC_URL}}jme/utils/a11y-slider.ext.js" type="text/javascript"></script>
<!-- workaround for flash bug in ie -->
-<script src="{{STATIC_URL}}jme/utils/reinitjme.js"></script>
+<script src="{{STATIC_URL}}jme/utils/reinitjme.js" type="text/javascript"></script>
<!-- fullwindow plugin -->
<script class="jme-jwPlayer" type="application/swf" src="{{STATIC_URL}}jme/packages/jmefs.swf"></script>
-<script src="{{STATIC_URL}}jme/plugins/fullwindow.js"></script>
+<script src="{{STATIC_URL}}jme/plugins/fullwindow.js" type="text/javascript"></script>
<!-- useractivity -->
-<script src="{{STATIC_URL}}jme/utils/useractivity.js"></script>
+<script src="{{STATIC_URL}}jme/utils/useractivity.js" type="text/javascript"></script>
<!-- prettyPhoto not jme but media -->
<link rel="stylesheet" href="{{STATIC_URL}}prettyPhoto/css/prettyPhoto.css" />
diff --git a/chimere/templates/chimere/blocks/live_coordinates.html b/chimere/templates/chimere/blocks/live_coordinates.html
index eb6c4c3..0199630 100644
--- a/chimere/templates/chimere/blocks/live_coordinates.html
+++ b/chimere/templates/chimere/blocks/live_coordinates.html
@@ -1,4 +1,6 @@
<script type='text/javascript'>
+ var resolutions;
+ var zoomOffset;
OpenLayers.ImgPath = '%schimere/img/';
var EPSG_DISPLAY_PROJECTION = epsg_display_projection = new OpenLayers.Projection('EPSG:%s');
var EPSG_PROJECTION = epsg_projection = new OpenLayers.Projection('EPSG:%s');
diff --git a/chimere/templates/chimere/blocks/map.html b/chimere/templates/chimere/blocks/map.html
index 9788528..e00ff8b 100644
--- a/chimere/templates/chimere/blocks/map.html
+++ b/chimere/templates/chimere/blocks/map.html
@@ -5,18 +5,25 @@
</script>
<div id="waiting">
<div id="waiting-content">
- <img src='{{STATIC_URL}}chimere/img/ajax-loader.gif'/>
+ <img alt='Ajax loader' src='{{STATIC_URL}}chimere/img/ajax-loader.gif'/>
<p>{% trans "Loading of the map in progress" %}</p>
</div>
</div>
+<div id="layer_selection">
+ <h4>{% trans "Display options" %}</h4>
+ <ul id='layer_list'>
+ <li class='head layer_map_type'>{% trans "Map type"%}</li>
+ </ul>
+</div>
<script type="text/javascript">
{% if single_category %}
$(function() {$('#panel').hide()});{% endif %}
var chimere_init_options = {};
chimere_init_options["default_icon"] = '{{STATIC_URL}}img/marker-green.png';
- chimere_init_options["map_layers"] = [{{map_layers|safe|escape}}];
+ chimere_init_options["map_layers"] = [{{js_map_layers|safe|escape}}];
chimere_init_options['permalink_label'] = '{%trans "Permalink"%}';
chimere_init_options['permalink_element'] = document.getElementById('permalink');
+ chimere_init_options['routing'] = {{routing}};
{% if dynamic_categories %}chimere_init_options['dynamic_categories'] = true;{% endif %}
{% if default_area %}
chimere_init_options["default_area"] = new Array({{default_area.upper_left_corner.x}}, {{default_area.upper_left_corner.y}}, {{default_area.lower_right_corner.x}}, {{default_area.lower_right_corner.y}});
@@ -24,11 +31,16 @@
{% if p_zoom %}chimere_init_options["zoom"] = {{ p_zoom }};{% endif %}
{% if p_lat %}chimere_init_options["lat"] = {{ p_lat }};{% endif %}
{% if p_lon %}chimere_init_options["lon"] = {{ p_lon }};{% endif %}
+ {% if p_routing_start_lon %}chimere_init_options["routing_start_lon"] = {{ p_routing_start_lon }};{% endif %}
+ {% if p_routing_start_lat %}chimere_init_options["routing_start_lat"] = {{ p_routing_start_lat }};{% endif %}
+ {% if p_routing_end_lon %}chimere_init_options["routing_end_lon"] = {{ p_routing_end_lon }};{% endif %}
+ {% if p_routing_end_lat %}chimere_init_options["routing_end_lat"] = {{ p_routing_end_lat }};{% endif %}
+ {% if p_routing_steps %}chimere_init_options["routing_steps_lonlat"] = [{{ p_routing_steps }}];{% endif %}
chimere_init_options["icon_offset"] = new OpenLayers.Pixel({{icon_offset_x}},
{{icon_offset_y}});
chimere_init_options["dynamic_categories"] = {{ dynamic_categories }};
{% if p_display_submited %}chimere_init_options["display_submited"] = {{ p_display_submited }};{% endif %}
- chimere_init_options["checked_categories"] = {{ p_checked_categories }};
+ chimere_init_options["checked_categories"] = [{% for cc in checked_categories %}{% if forloop.counter0 > 0 %}, {% endif %}{{cc}}{% endfor %}];
{% if area_id %}chimere_init_options['area_id'] = "{{area_id}}";{% endif %}
{% if p_current_feature %}
chimere_init_options["display_feature"] = {{ p_current_feature }};{% endif %}
@@ -44,5 +56,28 @@
{% if zoom %}
$('#maps').chimere('zoom', {'area':{{zoom}} });
{% endif %}
-</script>
+ // init layer selection
+ $(function() {
+ {% for layer_name, js, def in map_layers %}
+ $('#layer_list').append("<li><input type='radio' value='{{forloop.counter0}}' name='layer_type' id='layer_{{forloop.counter}}'{% if def %} checked='checked'{% endif %}><label for='layer_{{forloop.counter}}'>{{layer_name}}</li>");{% endfor %}
+ {% for subcat in subcat_layer %}
+ {% if not subcat.category %}
+ $('#layer_list').append("<li class='head layer_category'>{{subcat.name}}</li>");{% else %}
+ $('#layer_list').append("<li><input type='checkbox' name='layer_cat' value='category_{{subcat.pk}}' id='layer_cat_{{subcat.pk}}'{% if subcat.pk in checked_categories %} checked='checked'{% endif %}><label for='layer_cat_{{subcat.pk}}'>{{subcat.name}}</li>");{%endif%}{% endfor %}
+ $('#layer_selection h4').click(function(){
+ $('#layer_list').toggle();
+ });
+ $('#layer_list input[name=layer_type]').change(function(){
+ $('#{{map_id}}').chimere('changeMapLayer', $(this).val());
+ });
+ $('#layer_list input[name=layer_cat]').change(function(){
+ // the prop has to be called twice not to mess up with the triggered
+ // click
+ $('#'+$(this).val()).prop("checked", this.checked);
+ $('#'+$(this).val()).trigger('click');
+ $('#'+$(this).val()).prop("checked", this.checked);
+ });
+ });
+</script>
+<div id='marker_hover'><div id='marker_hover_content'></div></div>
diff --git a/chimere/templates/chimere/blocks/map_menu.html b/chimere/templates/chimere/blocks/map_menu.html
new file mode 100644
index 0000000..38fb4a8
--- /dev/null
+++ b/chimere/templates/chimere/blocks/map_menu.html
@@ -0,0 +1,14 @@
+{% load i18n %}
+<div id='chimere_map_menu'>
+ <ul>
+ {% if routing %}
+ <li id='map_menu_from' class='routing_item'>{% trans "From" context "routing" %}</li>
+ <li id='map_menu_step' class='routing_item'>{% trans "Add a step" context "routing" %}</li>
+ <li id='map_menu_to' class='routing_item'>{% trans "To" context "routing" %}</li>
+ <li id='map_menu_clear' class='routing_item'>{% trans "Clear the itinerary" context "routing" %}</li>
+ {% endif%}
+ <li id='map_menu_zoomin'>{% trans "Zoom in" %}</li>
+ <li id='map_menu_zoomout'>{% trans "Zoom out" %}</li>
+ <li id='map_menu_center'>{% trans "Center the map here" %}</li>
+ </ul>
+</div>
diff --git a/chimere/templates/chimere/blocks/multimedia_file.html b/chimere/templates/chimere/blocks/multimedia_file.html
index cc7c5d3..a360a9e 100644
--- a/chimere/templates/chimere/blocks/multimedia_file.html
+++ b/chimere/templates/chimere/blocks/multimedia_file.html
@@ -1,6 +1,6 @@
{% load i18n %}
{% if multimedia_item.picture %}
-<a rel="prettyPhoto" href='{{multimedia_item.picture.url}}' ><img class='media-img' alt="{{multimedia_item.name}}" src='{{multimedia_item.thumbnailfile.url}}'/></a>{% endif %}
+<a rel="prettyPhoto" href='{{multimedia_item.picture.url}}' ><img class='media-img thumbnail' alt="{{multimedia_item.name}}" src='{{multimedia_item.thumbnailfile.url}}'/></a>{% endif %}
{% if multimedia_item.url %}
{% if multimedia_item.multimedia_type.iframe %}
diff --git a/chimere/templates/chimere/blocks/news.html b/chimere/templates/chimere/blocks/news.html
new file mode 100644
index 0000000..fa581f7
--- /dev/null
+++ b/chimere/templates/chimere/blocks/news.html
@@ -0,0 +1,53 @@
+{% load i18n sanitize chimere_tags %}
+{% if news_lst %}
+<a href='#' id='news_button' class='ui-widget ui-button ui-state-default ui-corner-all'>{% trans "News"%}</a>
+<script type='text/javascript'>
+function display_news(){$("#welcome").dialog({title:"{% trans "News"%}",
+ width:360});}
+$("#news_button").bind('click', display_welcome);
+$(function(){
+ $('#news div.media-player').jmeEmbedControls();
+ $('#news video').each(function(index){$(this).pause()});
+ $('#news audio').each(function(index){$(this).pause()});
+ {% if display %}display_news();{%endif%}
+});
+</script>
+<div id='news' style='display:none'>
+ <div id='detail_content'>
+ <div class='news'>
+ {% if news_lst %}
+ {% for news in news_lst %}
+ <div class='info'>
+ {% if news.title %}
+ <h3>{{news.title}} &ndash; {{ news.date }}</h3>
+ <p>{{news.content|safe}}</p>
+ {% else %}
+ <h3>{{news.name}} &ndash; {{ news.start_date }}{% if news.end_date %} - {{ news.end_date }}{% endif %}</h3>
+ {% if news.default_pictures or news.default_pictures or news.default_multimedia_items%}
+ <div class='small-gallery'>
+ {% for picture in news.default_pictures %}
+ {% multimedia_render picture %}
+ {%endfor%}
+ {% for multimedia_item in news.default_multimedia_items %}
+ {% multimedia_render multimedia_item %}
+ {%endfor%}
+ </div>
+ {%endif%}
+ {% if news.description %}
+ <p class='description'>{{news.description|sanitize:"p b i br hr strong em span:style a:href:target ul li ol h1 h2 h3 h4 table td th tr"|safe}}</p>
+ {% endif %}
+ {% for property in news.getProperties %}
+ <p class='{{news.propertymodel.getNamedId}}'>{{ property.value|sanitize:"p b i br hr strong em span:style a:href:target ul li ol h1 h2 h3 h4 table td th tr"|safe }}</p>
+ {% endfor %}
+ <p class='marker_link'><a href='{% get_tinyfied_url news area_name %}'>{% trans "See it on the map"%}</a></p>
+ {% endif %}
+ </div>
+ {%endfor%}
+ {% endif %}
+ <div class='info'>
+ </div>
+ </div>
+ </div>
+</div>
+{% endif %}
+
diff --git a/chimere/templates/chimere/blocks/routing.html b/chimere/templates/chimere/blocks/routing.html
new file mode 100644
index 0000000..db97191
--- /dev/null
+++ b/chimere/templates/chimere/blocks/routing.html
@@ -0,0 +1,48 @@
+{% load i18n %}
+{# Don't forget to include routing-widget.js in your main template #}
+{% if routing %}
+{{itinerary_form.media}}
+<a href='#' id='routing_button' class='ui-widget ui-button ui-state-default ui-corner-all'>{% trans "Itinerary"%}</a>
+<div id='chimere_itinerary_panel'>
+ <div id='chimere_itinerary_form'>
+ {% for hidden in itinerary_form.hidden_fields %}
+ {{ hidden }}
+ {% endfor %}
+ {% for field in itinerary_form.visible_fields %}
+ <div id='{{field.auto_id}}_div'>
+ {% if field.label %}<label for='{{field.auto_id}}'>{{ field.label }}</label>{%endif%}
+ {{field}}</div>
+ {% endfor %}
+ <a id='add_step_link' href='#'>{% trans "Add a step" %}</a>
+ <span id='search_routing'>{% trans "Search" %}</span>
+ </div>
+ <div id='chimere_itinerary'>
+ <div id='chimere_itinerary_action'>
+ <ul class='action'>
+ <li class='ui-widget ui-button ui-state-default ui-corner-all'>
+ <a href='#' id='chimere_itinerary_modify'>{% trans "Modify" %}</a>
+ </li>
+ <li class='ui-widget ui-button ui-state-default ui-corner-all'>
+ <a href='#' id='chimere_itinerary_new'>{% trans "New search" %}</a>
+ </li>
+ </ul>
+ </div>
+ <div class='itinerary_label' id='total_label_div'>
+ <span id='chimere_total_label'></span>
+ </div>
+ <div class='itinerary_label'>
+ <span class='label'>{% trans "Start:"%}</span> <span id='chimere_start_label'></span></div>
+ <div id='chimere_itinerary_content'>
+ </div>
+ <div class='itinerary_label'>
+ <span class='label'>{% trans "Finish:"%}</span> <span id='chimere_end_label'></span>
+ </div>
+ </div>
+</div>
+<script language='javascript' type='text/javascript'>
+<!--
+var step_label = "{% trans "Step" %}";
+var routing_fail_message = "{{routing_fail_message|safe}}";
+// -->
+</script>
+{% endif%}
diff --git a/chimere/templates/chimere/blocks/share_bar.html b/chimere/templates/chimere/blocks/share_bar.html
new file mode 100644
index 0000000..e421a0f
--- /dev/null
+++ b/chimere/templates/chimere/blocks/share_bar.html
@@ -0,0 +1,39 @@
+{% load i18n %}
+ {% if share_networks %}
+ {% if simple %}{% trans "Share on"%}{% for share_network in share_networks %}
+ <a href='{{share_network.1}}'>{{share_network.0}}</a>
+ {% endfor %}{%else%}
+ <ul class='share'>
+ <li>{% trans "Share"%}</li>{% for share_network in share_networks %}
+ <li><a class='share_link share_id_{{share_network.0}}' href='{{share_network.1}}'><img src="{{share_network.2}}" alt="{{share_network.0}}"/></a></li>
+ {% endfor %}</ul>{% endif %}
+ <script language='text/javascript'>
+ $(function(){
+ $('.share_link').click(function(){
+ var href = $(this).attr('href');
+ var url = '{% url chimere:get-share-url %}';
+ var classes = $(this).attr('class').split(' ');
+ prefix = 'share_id_';
+ var share_id;
+ for (idx=0;idx<classes.length;idx++){
+ if(classes[idx].substring(0, prefix.length) == prefix){
+ var share_id = classes[idx].substring(prefix.length);
+ }
+ }
+ var params = $('#permalink a').attr('href').split('/');
+ url += share_id + params[params.length-1];
+ $.ajax({url: url,
+ dataType: "html",
+ success: function (url) {
+ window.open(url);
+ return false;
+ },
+ error: function(){
+ return false;
+ }
+ });
+ return false;
+ });
+ });
+ </script>
+ {% endif %}
diff --git a/chimere/templates/chimere/default_extra_page.html b/chimere/templates/chimere/default_extra_page.html
new file mode 100644
index 0000000..884d4cc
--- /dev/null
+++ b/chimere/templates/chimere/default_extra_page.html
@@ -0,0 +1,15 @@
+{% extends "chimere/base.html" %}
+{% load i18n chimere_tags %}
+{% block extra_head %}
+ {{ block.super }}
+ {{ form.media }}
+ {% head_jquery %}
+{% endblock %}
+{% block message_map %}{% endblock %}
+{% block message_edit%}{% endblock %}
+{% block content %}
+ {{ block.super }}
+ <h3>{{title}}</h3>
+ {{content|safe}}
+{% endblock %}
+
diff --git a/chimere/templates/chimere/detail.html b/chimere/templates/chimere/detail.html
index eec932c..ed0ea5c 100644
--- a/chimere/templates/chimere/detail.html
+++ b/chimere/templates/chimere/detail.html
@@ -34,18 +34,8 @@
{% if moderator_emails %}
<a href="mailto:?from={{moderator_emails}}&subject={% trans "Propose amendment" %}&body={% trans "I would like to propose an amendment for this item:"%} {{share_url}}">
{% trans "Propose amendment" %}
- </a>{%endif%}</p>
- {% if share_networks %}
- <p class='detail_share'>
- {% if simple %}{% trans "Share on"%}{% for share_network in share_networks %}
- <a href='{{share_network.1}}'>{{share_network.0}}</a>
- {% endfor %}{%else%}
- <ul class='share'>
- <li>{% trans "Share"%}</li>{% for share_network in share_networks %}
- <li><a href='{{share_network.1}}'><img src="{{share_network.2}}" alt="{{share_network.0}}"/></a></li>
- {% endfor %}</ul>{% endif %}
- </p>
-{% endif %}
+ </a>{%endif%}
+ {% share_bar marker.name %}
</div>
{% if marker.multimedia_items %}
<div id='gallery-{{time_now}}' class='gallery'>
diff --git a/chimere/templates/chimere/edit.html b/chimere/templates/chimere/edit.html
index 341f9b5..f9706d3 100644
--- a/chimere/templates/chimere/edit.html
+++ b/chimere/templates/chimere/edit.html
@@ -133,14 +133,15 @@
</div>
<div id='upload_in_progress'>
<p>{% trans "Upload in progress. Please wait..." %}</p>
- <p><img src='{{STATIC_URL}}chimere/img/ajax-loader.gif'/></p>
+ <p><img alt='Ajax loader' src='{{STATIC_URL}}chimere/img/ajax-loader.gif'/></p>
</div>
<script text='text/javascript'>
$( "#upload_in_progress" ).dialog({
modal: true,
resizable:false,
height:110,
- autoOpen:false
+ autoOpen:false,
+ dialogClass:'alert-box'
}
);
$(".ui-dialog-titlebar").hide();
diff --git a/chimere/templates/chimere/main_map.html b/chimere/templates/chimere/main_map.html
index 76f796d..b7aa868 100644
--- a/chimere/templates/chimere/main_map.html
+++ b/chimere/templates/chimere/main_map.html
@@ -4,7 +4,7 @@
{% head_jquery %}
{% head_chimere %}
{% head_jme %}
-<script src="{{ STATIC_URL }}chimere/js/jquery.chimere.js"></script>
+<script src="{{ STATIC_URL }}chimere/js/jquery.chimere.js" type="text/javascript"></script>
{{ block.super }}
{% endblock %}
{% block message_edit %}{% endblock %}
@@ -18,20 +18,36 @@
</form>
</div>
+ <div id='category_description'>
+ </div>
+ <script type='text/javascript'>
+ $(function(){$('#category_description').dialog({'autoOpen':false});});
+ </script>
+
<div id='utils-div' class='ui-widget ui-state-default ui-corner-all'>
{% if areas_visible %}
{% display_areas %}
{% endif %}
+ {% routing %}
+ {% display_welcome %}
{% display_news news_visible %}
<div id='permalink' class='ui-widget ui-button ui-state-default ui-corner-all'></div>
<a id='simple_button' class='ui-widget ui-button ui-state-default ui-corner-all' href='{% url chimere:simple_index area_name_slash %}'>{% trans "Simple map" %}</a>
</div>
<div id='detail' class='ui-widget ui-corner-all'></div>
- <div id='category_detail'></div>
{% endblock %}
{% block content %}
{{block.super}}
+ <div id='main-map'></div>
+<script type="text/javascript">
+ $("#main-map").show();
+</script>
+ {% map_menu %}
{% map 'main-map' %}
+ <div id='chimere_message'></div>
+ <script type='text/javascript'>
+ $(function(){$('#chimere_message').dialog({'autoOpen':false});});
+ </script>
{% endblock %}
{% block footer %}
<p class='map-footer'>{% include "chimere/blocks/footer.html" %}</p>
diff --git a/chimere/templatetags/chimere_tags.py b/chimere/templatetags/chimere_tags.py
index aadaa6b..a6b82c8 100644
--- a/chimere/templatetags/chimere_tags.py
+++ b/chimere/templatetags/chimere_tags.py
@@ -10,6 +10,8 @@ from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.db.models import Q, Count
+from django.template import defaultfilters
+from django.utils.translation import ugettext as _
from django.template.loader import render_to_string
from chimere.models import Marker, Area, News, SubCategory, MultimediaType
@@ -39,22 +41,9 @@ def submited(context):
return {"edit_url":reverse('chimere:edit'),
"index_url":reverse('chimere:index')}
-@register.inclusion_tag('chimere/blocks/welcome.html', takes_context=True)
-def display_news(context, display=False):
- """
- Welcome message and active news.
- """
- area = None
- context_data = {'display':display}
- if "area_name" in context:
- try:
- area = Area.objects.get(urn=context["area_name"])
- context_data['area_name'] = context['area_name']
- context_data['welcome_message'] = area.welcome_message
- except ObjectDoesNotExist:
- pass
+def get_news(area=None):
# Retrieve news
- news = News.objects.filter(available=True)
+ news = News.objects.filter(available=True, is_front_page=True)
if area:
news = news.filter(Q(areas__isnull=True)|Q(areas__in=[area.pk]))
news = list(news.all())
@@ -62,14 +51,50 @@ def display_news(context, display=False):
# Retrieve active markers
today = date.today()
after = today + timedelta(settings.CHIMERE_DAYS_BEFORE_EVENT)
- q = Marker.objects.filter(status='A').filter(start_date__lte=after
- ).filter(Q(end_date__gte=today)|
+ q = Marker.objects.filter(status='A').filter(start_date__lte=after,
+ is_front_page=True).filter(Q(end_date__gte=today)|
(Q(end_date__isnull=True) & Q(start_date__gte=today)))
if area:
q = q.filter(area.getIncludeMarker())
news += list(q)
- news.sort(key=lambda x:x.date)
- context_data['news_lst'] = news
+ news.sort(key=lambda x:x.date, reverse=True)
+ return news
+
+@register.inclusion_tag('chimere/blocks/welcome.html', takes_context=True)
+def display_welcome(context, display=False, title=''):
+ """
+ Welcome message and active news.
+ """
+ context_data = {'display':display}
+ area = None
+ if "area_name" in context:
+ try:
+ area = Area.objects.get(urn=context["area_name"])
+ context_data['area_name'] = context['area_name']
+ context_data['welcome_message'] = area.welcome_message
+ except ObjectDoesNotExist:
+ pass
+ context_data['news_lst'] = get_news(area)[:3]
+ context_data['STATIC_URL'] = settings.STATIC_URL
+ context_data['title'] = title if title \
+ else _(u"Welcome to the %s") % settings.PROJECT_NAME
+ return context_data
+
+@register.inclusion_tag('chimere/blocks/news.html', takes_context=True)
+def display_news(context, title=''):
+ """
+ All news.
+ """
+ area = None
+ context_data = {'STATIC_URL':settings.STATIC_URL}
+ if "area_name" in context:
+ try:
+ area = Area.objects.get(urn=context["area_name"])
+ context_data['area_name'] = context['area_name']
+ context_data['welcome_message'] = area.welcome_message
+ except ObjectDoesNotExist:
+ pass
+ context_data['news_lst'] = get_news(area)
return context_data
@register.inclusion_tag('chimere/blocks/head_jquery.html', takes_context=True)
@@ -118,9 +143,41 @@ def head_chimere(context):
"MAP_LAYER": settings.CHIMERE_DEFAULT_MAP_LAYER,
"OSM_CSS_URLS": settings.OSM_CSS_URLS,
"OSM_JS_URLS": settings.OSM_JS_URLS,
+ 'routing': settings.CHIMERE_ENABLE_ROUTING \
+ if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') else False
+ }
+ return context_data
+
+@register.inclusion_tag('chimere/blocks/head_form.html')
+def head_form():
+ """
+ Manualy add forms header (necessary in case of ajax load)
+ """
+ context_data = {
+ "TINYMCE_URL": settings.TINYMCE_URL,
}
return context_data
+@register.inclusion_tag('chimere/blocks/map_menu.html', takes_context=True)
+def map_menu(context):
+ context_data = {'routing': settings.CHIMERE_ENABLE_ROUTING \
+ if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') else False}
+ return context_data
+
+@register.inclusion_tag('chimere/blocks/routing.html', takes_context=True)
+def routing(context):
+ if not hasattr(settings, 'CHIMERE_ENABLE_ROUTING') or \
+ not settings.CHIMERE_ENABLE_ROUTING:
+ return {'routing':False}
+ context_data = {
+ 'routing':settings.CHIMERE_ENABLE_ROUTING,
+ 'itinerary_form':context['itinerary_form'],
+ 'routing_fail_message':_(settings.CHIMERE_ROUTING_FAIL_MESSAGE
+ ).replace('\n', '\\n'),
+ 'routing_transport':context['routing_transport']}
+ context_data['STATIC_URL'] = settings.STATIC_URL
+ return context_data
+
@register.inclusion_tag('chimere/blocks/map.html', takes_context=True)
def map(context, map_id='map'):
context_data = {'map_id':map_id,
@@ -129,12 +186,18 @@ def map(context, map_id='map'):
context_data['icon_offset_y'] = settings.CHIMERE_ICON_OFFSET_Y
context_data['icon_width'] = settings.CHIMERE_ICON_WIDTH
context_data['icon_height'] = settings.CHIMERE_ICON_HEIGHT
+ context_data['routing'] = 'true' \
+ if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') and \
+ settings.CHIMERE_ENABLE_ROUTING \
+ else 'false'
area_name = context['area_name'] if 'area_name' in context else 'area_name'
map_layers, default_area = get_map_layers(area_name)
- context_data['map_layers'] = ", ".join(map_layers)
+ context_data['js_map_layers'] = ", ".join(
+ [js for name, js, default in map_layers])
+ context_data['map_layers'] = map_layers
if default_area:
context_data['selected_map_layer'] = default_area
- context_data['p_checked_categories'] = None
+ context_data['checked_categories'] = []
area = None
if area_name:
try:
@@ -146,7 +209,10 @@ def map(context, map_id='map'):
area = Area.objects.get(default=True)
except ObjectDoesNotExist:
pass
+ subcat_layer = SubCategory.objects.filter(as_layer=True, available=True)
if area:
+ if area.subcategories.count():
+ subcat_layer = subcat_layer.filter(areas__pk=area.pk)
context_data['area_id'] = area_name
if 'zoomout' in context and context['zoomout']:
context_data['zoom'] = "[%s]" % ",".join((
@@ -156,11 +222,10 @@ def map(context, map_id='map'):
unicode(area.lower_right_corner.y)))
if area.subcategories.filter(available=True).count() == 1:
context_data['single_category'] = True
- context_data['p_checked_categories'] = "[%d]" % \
- area.subcategories.all()[0].pk
+ context_data['checked_categories'] = area.subcategories.all()[0].pk
elif area.default_subcategories.count():
- context_data['p_checked_categories'] = unicode([subcategory.pk
- for subcategory in area.default_subcategories.all()])
+ context_data['checked_categories'] = [s.pk
+ for s in area.default_subcategories.all()]
if area.restrict_to_extent:
context_data['restricted_extent'] = """
var bounds = new OpenLayers.Bounds();
@@ -168,17 +233,20 @@ bounds.extend(new OpenLayers.LonLat(%f, %f));
bounds.extend(new OpenLayers.LonLat(%f, %f));
""" % (area.upper_left_corner.x, area.upper_left_corner.y,
area.lower_right_corner.x, area.lower_right_corner.y)
-
+ context_data['subcat_layer'], c_cat = [], None
+ for subcat in subcat_layer.order_by('category__order', 'category').all():
+ if subcat.category != c_cat:
+ context_data['subcat_layer'].append(subcat.category)
+ c_cat = subcat.category
+ context_data['subcat_layer'].append(subcat)
if SubCategory.objects.filter(available=True).count() <= 1:
context_data['single_category'] = True
- if not context_data['p_checked_categories']:
+ if not context_data['checked_categories']:
cat = ''
if SubCategory.objects.filter(available=True).count():
cat = unicode(SubCategory.objects.filter(available=True
).all()[0].pk)
- context_data['p_checked_categories'] = "[%s]" % cat
- if not context_data['p_checked_categories']:
- context_data['p_checked_categories'] = "[]"
+ context_data['checked_categories'] = cat
context_data['dynamic_categories'] = 'true' \
if area and area.dynamic_categories else 'false'
if 'request' not in context:
@@ -188,7 +256,8 @@ bounds.extend(new OpenLayers.LonLat(%f, %f));
context_data['p_current_route'] = context.get('current_route')
if request.GET:
for key in ('zoom', 'lon', 'lat', 'display_submited',
- 'current_feature'):
+ 'current_feature', 'routing_start_lon', 'routing_start_lat',
+ 'routing_end_lon', 'routing_end_lat', 'routing_steps'):
if key in request.GET and request.GET[key]:
context_data['p_'+key] = request.GET[key]
else:
@@ -196,7 +265,7 @@ bounds.extend(new OpenLayers.LonLat(%f, %f));
if 'checked_categories' in request.GET \
and request.GET['checked_categories']:
cats = request.GET['checked_categories'].split('_')
- context_data['p_checked_categories'] = "[%s]" % ",".join(cats)
+ context_data['checked_categories'] = cats
return context_data
@register.inclusion_tag('chimere/blocks/multimedia_file.html',
@@ -218,6 +287,16 @@ def get_tinyfied_url(marker, area_name=''):
url = marker.get_absolute_url(area_name)
return url
+@register.inclusion_tag('chimere/blocks/share_bar.html',
+ takes_context=True)
+def share_bar(context, name='', email_only=False):
+ context['STATIC_URL'] = settings.STATIC_URL
+ context['name'] = name
+ context['email_only'] = email_only
+ context['share_networks'] = [(defaultfilters.slugify(name), url, icon)
+ for name, url, icon in settings.CHIMERE_SHARE_NETWORKS]
+ return context
+
@register.filter(name='ol_map')
def ol_map(item, arg='map_id'):
geom, geom_type = None, None
diff --git a/chimere/tests.py b/chimere/tests.py
index 54c1acd..fb48205 100644
--- a/chimere/tests.py
+++ b/chimere/tests.py
@@ -4,6 +4,7 @@
import datetime
import lxml.etree
import os
+import simplejson as json
test_path = os.path.abspath(__file__)
test_dir_path = os.path.dirname(test_path) + os.sep
@@ -90,12 +91,14 @@ def marker_setup(sub_categories=[]):
markers.append(marker_1)
marker_2 = Marker.objects.create(name="Marker 2", status='A',
point='SRID=4326;POINT(-3.5 48.4)',
+ is_front_page=True,
available_date=current_date,
start_date=current_date)
marker_2.categories.add(sub_categories[1])
markers.append(marker_2)
marker_3 = Marker.objects.create(name="Marker 3", status='A',
point='SRID=4326;POINT(-4.5 48.45)',
+ is_front_page=True,
available_date=current_date - datetime.timedelta(days=60),
start_date=current_date - datetime.timedelta(days=60),
end_date=current_date - datetime.timedelta(days=30))
@@ -259,8 +262,14 @@ class OSMImporterTest(TestCase, ImporterTest):
importer2 = Importer.objects.create(importer_type='OSM',
source=test_dir_path+'tests/sample_ways.osm')
importer2.categories.add(subcategories[1])
+ importer3 = Importer.objects.create(importer_type='OSM',
+ source='http://open.mapquestapi.com/xapi/api/0.6/way'\
+ '[highway=motorway]'\
+ '[bbox=2.0393839939136975,48.68908639634696,'\
+ '2.3140421970277316,48.790972349390415]')
- self.marker_importers = [(importer1, 19), (importer2, 8)]
+ self.marker_importers = [(importer1, 19), (importer2, 8),
+ (importer3, None)]
class GeoRSSImporterTest(TestCase, ImporterTest):
def setUp(self):
@@ -400,6 +409,13 @@ class DynamicCategoryTest(TestCase):
cats = self.areas[2].getCategories(status='A', filter_available=True)
self.assertEqual(len(cats), 2)
+ def test_get_all_categories(self):
+ url = reverse('chimere:get_all_categories')
+ response = self.client.get(url)
+ self.assertEqual(200, response.status_code)
+ cats = json.loads(response.content)['categories']
+ self.assertEqual(len(cats), 2)
+
class NewsTest(TestCase):
def setUp(self):
self.areas = areas_setup()
@@ -411,10 +427,10 @@ class NewsTest(TestCase):
start_date=current_date - datetime.timedelta(days=90),
end_date=None)
self.news = []
- self.news.append(News.objects.create(title=u"Test news 1",
- available=True))
- self.news.append(News.objects.create(title=u"Test news 2",
- available=False))
+ self.news.append(News.objects.create(is_front_page=True,
+ title=u"Test news 1", available=True))
+ self.news.append(News.objects.create(is_front_page=True,
+ title=u"Test news 2", available=False))
def test_news_display(self):
context = display_news(Context({}))
diff --git a/chimere/urls.py b/chimere/urls.py
index 9d4018a..164ef68 100644
--- a/chimere/urls.py
+++ b/chimere/urls.py
@@ -20,6 +20,7 @@
from django.conf import settings
from django.conf.urls.defaults import *
from django.contrib import admin
+from django.core.exceptions import ImproperlyConfigured
admin.autodiscover()
from chimere.models import Area
@@ -51,9 +52,26 @@ if settings.CHIMERE_FEEDS:
LatestPOIsByZoneID(), name='feeds-areaid'),
)
+if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') \
+ and settings.CHIMERE_ENABLE_ROUTING:
+ if not hasattr(settings, 'CHIMERE_ROUTING_TRANSPORT') \
+ or not settings.CHIMERE_ROUTING_TRANSPORT:
+ raise ImproperlyConfigured(u"CHIMERE_ROUTING_TRANSPORT must be set in"\
+ u" settings if you enable routing")
+ urlpatterns += patterns('chimere.views',
+ url(r'^(?P<area_name>[a-zA-Z0-9_-]*/)?route/'\
+ r'(?P<transport>(%s))/((?P<speed>[0-9][0-9]*)/)?'
+ r'(?P<lon1>[-]?[0-9]+[.]?[0-9]*)_(?P<lat1>[-]?[0-9]+[.]?[0-9]*)_'\
+ r'(?P<lonlat_steps>([-]?[0-9]+[.]?[0-9]*_[-]?[0-9]+[.]?[0-9]*_)*)'\
+ r'(?P<lon2>[-]?[0-9]+[.]?[0-9]*)_(?P<lat2>[-]?[0-9]+[.]?[0-9]*)$' %
+ ('|'.join([key for key, lbl in settings.CHIMERE_ROUTING_TRANSPORT])),
+ 'route', name="route"),
+ )
+
urlpatterns += patterns('chimere.views',
url(r'^charte/?$', 'charte', name="charte"),
- url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?contact/?$', 'contactus', name="contact"),
+ url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?contact/?$', 'contactus',
+ name="contact"),
url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?edit/$', 'edit',
name="edit"),
url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?edit/(?P<item_id>\w+)/(?P<submited>\w+)?$',
@@ -71,12 +89,20 @@ urlpatterns += patterns('chimere.views',
name="getgeoobjects"),
url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?getAvailableCategories/$',
'get_available_categories', name="get_categories"),
+ url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?getAllCategories/$',
+ 'get_all_categories', name="get_all_categories"),
+ url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?getCategory/(?P<category_id>\d+)/?$',
+ 'getCategory', name="get_category"),
+ url(r'^(?P<area_name>[a-zA-Z0-9_-]*/)?get-share-url/(?P<network>\w+)?$',
+ 'getShareUrl', name="get-share-url"),
url(r'^(?P<area_name>[a-zA-Z0-9_-]*/)?ty/(?P<tiny_urn>\w+)$',
'redirectFromTinyURN', name="tiny"),
url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?upload_file/((?P<category_id>\w+)/)?$',
'uploadFile', name='upload_file'),
url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?process_route_file/(?P<file_id>\d+)/$',
'processRouteFile', name='process_route_file'),
+ url(r'^(?P<area_name>[a-zA-Z0-9_-]+/)?dyn/(?P<page_id>\w+)/$',
+ 'extraPage', name='extra_page'),
# At the end, because it catches large
url(r'^(?P<area_name>[a-zA-Z0-9_-]+)?', 'index', name="index"),
)
diff --git a/chimere/utils.py b/chimere/utils.py
index b383eb0..f5379aa 100644
--- a/chimere/utils.py
+++ b/chimere/utils.py
@@ -86,6 +86,7 @@ class ImportManager(object):
'import_key__icontains':'%s:%s;' % (key, import_key),
'import_source':self.importer_instance.source}
try:
+ item = None
if pk:
ref_item = cls.objects.get(pk=pk)
else:
@@ -505,10 +506,10 @@ class CSVManager(ImportManager):
return (0, 0, msg)
reader = csv.reader(source, delimiter=';', quotechar='"')
prop_cols = []
- for pm in Marker.properties():
+ for pm in Marker.all_properties():
prop_cols.append((pm.name, pm.getAttrName(),
pm.getAttrName()+'_set'))
- cols = self.COLS + prop_cols
+ cols = list(self.COLS) + prop_cols
datas = []
for idx, row in enumerate(reader):
if not idx: # first row
@@ -538,7 +539,7 @@ class CSVManager(ImportManager):
dct['route'] = geom
else:
continue
- import_key = pk if pk else name
+ import_key = pk if pk else name.decode('utf-8')
item, updated, created = self.create_or_update_item(cls, dct,
import_key, pk=pk)
if updated:
@@ -556,8 +557,8 @@ class CSVManager(ImportManager):
def export(cls, queryset):
dct = {'description':unicode(datetime.date.today()), 'data':[]}
cls_name = queryset.model.__name__.lower()
- cols = cls.COLS
- for pm in queryset.model.properties():
+ cols = list(cls.COLS)
+ for pm in queryset.model.all_properties():
cols.append((pm.name, pm.getAttrName(), pm.getAttrName()+'_set'))
header = [col[0] for col in cols]
dct['data'].append(header)
diff --git a/chimere/views.py b/chimere/views.py
index 22bd50a..7c02216 100644
--- a/chimere/views.py
+++ b/chimere/views.py
@@ -29,27 +29,32 @@ from itertools import groupby
import re
from django.conf import settings
+from django.contrib.gis.geos import GEOSGeometry
+from django.contrib.gis.gdal.error import OGRException
+from django.contrib.gis.measure import D
from django.core import serializers
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import redirect, render_to_response
-from django.template import loader, RequestContext
-from django.utils import simplejson
+from django.template import loader, RequestContext, defaultfilters
+from django.utils import simplejson as json
from django.utils.http import urlquote
from django.utils.translation import ugettext as _
from chimere.actions import actions
-from chimere.models import Category, SubCategory, PropertyModel, \
- Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile, \
- get_users_by_area
+from chimere.models import Category, SubCategory, PropertyModel, Page,\
+ Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile,\
+ AggregatedRoute
from chimere.widgets import getMapJS, PointChooserWidget, \
RouteChooserWidget, AreaWidget
from chimere.forms import MarkerForm, RouteForm, ContactForm, FileForm, \
FullFileForm, MultimediaFileFormSet, PictureFileFormSet, notifySubmission,\
- notifyStaff, AreaForm
+ notifyStaff, AreaForm, RoutingForm, getStaffEmails
+
+from chimere.route import router
def get_base_uri(request):
base_uri = 'http://'
@@ -101,9 +106,36 @@ def get_base_response(area_name=""):
if area and area.dynamic_categories else False
base_response_dct['JQUERY_JS_URLS'] = settings.JQUERY_JS_URLS
base_response_dct['JQUERY_CSS_URLS'] = settings.JQUERY_CSS_URLS
+ base_response_dct['PROJECT_NAME'] = settings.PROJECT_NAME
return base_response_dct, None
-def index(request, area_name=None, default_area=None, simple=False):
+def getShareUrl(request, area_name='', network=''):
+ """
+ Get a share url
+ """
+ data = getTinyfiedUrl(request, request.GET.urlencode(), area_name)
+ for name, url, img in settings.CHIMERE_SHARE_NETWORKS:
+ if defaultfilters.slugify(name) == network:
+ return HttpResponse(url % {'text':data['text'], 'url':data['url']})
+ return HttpResponse('')
+
+def getShareNetwork(request, area_name='', marker=None):
+ """
+ Get URLs to share items
+ """
+ parameters = ""
+ if marker:
+ parameters = u'current_feature=%d' % marker.pk
+ parameters += u"&checked_categories=%s" % "_".join([str(m.id) \
+ for m in marker.categories.all()])
+ net_dct = getTinyfiedUrl(request, parameters, area_name)
+ share_networks = []
+ for network in settings.CHIMERE_SHARE_NETWORKS:
+ share_networks.append((network[0], network[1] % net_dct, network[2]))
+ return share_networks, net_dct
+
+def index(request, area_name=None, default_area=None, simple=False,
+ get_response=False):
"""
Main page
"""
@@ -123,6 +155,10 @@ def index(request, area_name=None, default_area=None, simple=False):
if request.GET and 'lat' in request.GET \
and 'lon' in request.GET:
zoomout = None
+ if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') and \
+ settings.CHIMERE_ENABLE_ROUTING:
+ response_dct['itinerary_form'] = RoutingForm()
+ response_dct['routing_transport'] = settings.CHIMERE_ROUTING_TRANSPORT
if request.GET and 'current_feature' in request.GET:
try:
m = Marker.objects.get(pk=request.GET['current_feature'])
@@ -131,18 +167,26 @@ def index(request, area_name=None, default_area=None, simple=False):
except:
pass
response_dct.update({
- 'actions':actions, 'action_selected':('view',),
+ 'actions':actions(response_dct['area_name']),
+ 'action_selected':('view',),
'error_message':'',
'news_visible': news_visible,
'areas_visible': settings.CHIMERE_DISPLAY_AREAS,
'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER,
'dynamic_categories':response_dct['dynamic_categories'],
+ 'zoomout':zoomout,
'has_default_area':Area.objects.filter(default=True).count(),
'zoomout':zoomout
})
+ if hasattr(settings, 'CONTACT_EMAIL') and settings.CONTACT_EMAIL:
+ response_dct['contact_email'] = settings.CONTACT_EMAIL
+ response_dct['share_networks'], net_dct = \
+ getShareNetwork(request, response_dct['area_name'])
tpl = 'chimere/main_map.html'
if simple:
tpl = 'chimere/main_map_simple.html'
+ if get_response:
+ return tpl, response_dct
return render_to_response(tpl, response_dct,
context_instance=RequestContext(request))
@@ -278,7 +322,7 @@ def edit(request, area_name="", item_id=None, submited=False):
if request.POST and request.POST.get('point'):
point_value = request.POST.get('point')
response_dct.update({
- 'actions':actions,
+ 'actions':actions(response_dct['area_name']),
'action_selected':('contribute', 'edit'),
'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER,
'form':form,
@@ -357,7 +401,7 @@ def processRouteFile(request, area_name='', file_id=None):
route = route_file.route
if not route:
return HttpResponse(status=500)
- return HttpResponse('('+simplejson.dumps({'wkt':route,
+ return HttpResponse('(' + json.dumps({'wkt':route,
'file_id':file_id})+')',
'application/javascript', status=200)
except OSError as e:
@@ -386,7 +430,7 @@ def editRoute(request, area_name="", item_id=None, submited=False):
if request.POST and request.POST.get('route'):
route_value = request.POST.get('route')
response_dct.update({
- 'actions':actions,
+ 'actions':actions(response_dct['area_name']),
'action_selected':('contribute', 'edit-route'),
'error_message':'',
'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER,
@@ -414,7 +458,8 @@ def submited(request, area_name="", action=""):
response_dct, redir = get_base_response(area_name)
if redir:
return redir
- response_dct.update({'actions':actions, 'action_selected':action,})
+ response_dct.update({'actions':actions(response_dct['area_name']),
+ 'action_selected':action,})
return render_to_response('chimere/submited.html', response_dct,
context_instance=RequestContext(request))
@@ -425,7 +470,8 @@ def charte(request, area_name=""):
response_dct, redir = get_base_response(area_name)
if redir:
return redir
- response_dct.update({'actions':actions, 'action_selected':('charte',)})
+ response_dct.update({'actions':actions(response_dct['area_name']),
+ 'action_selected':('charte',)})
return render_to_response('chimere/charte.html', response_dct,
context_instance=RequestContext(request))
@@ -453,11 +499,32 @@ def contactus(request, area_name=""):
response_dct, redir = get_base_response(area_name)
if redir:
return redir
- response_dct.update({'actions':actions, 'action_selected':('contact',),
+ response_dct.update({'actions':actions(response_dct['area_name']),
+ 'action_selected':('contact',),
'contact_form':form, 'message':msg})
return render_to_response('chimere/contactus.html', response_dct,
context_instance=RequestContext(request))
+def extraPage(request, area_name="", page_id=""):
+ """
+ Extra dynamic pages
+ """
+ try:
+ page = Page.objects.get(available=True, mnemonic=page_id)
+ except ObjectDoesNotExist:
+ return redirect(reverse('chimere:index'))
+ response_dct, redir = get_base_response(area_name)
+ if redir:
+ return redir
+ response_dct.update({'actions':actions(response_dct['area_name']),
+ 'action_selected':(page_id,),
+ 'content':page.content,
+ 'title':page.title})
+ tpl = page.template_path if page.template_path \
+ else 'chimere/default_extra_page.html'
+ return render_to_response(tpl, response_dct,
+ context_instance=RequestContext(request))
+
def getDetail(request, area_name, marker_id):
'''
Get the detail for a marker
@@ -474,15 +541,14 @@ def getDetail(request, area_name, marker_id):
if request.method == 'GET':
if 'simple' in request.GET and request.GET['simple']:
response_dct['simple'] = True
- parameters = u'current_feature=%s' % marker_id
- parameters += u"&checked_categories=%s" % "_".join([str(m.id) \
- for m in marker.categories.all()])
- net_dct = getTinyfiedUrl(request, parameters, response_dct['area_name'])
- share_networks = []
+ response_dct['share_networks'], net_dct = \
+ getShareNetwork(request, response_dct['area_name'], marker)
response_dct['share_url'] = net_dct['url']
- for network in settings.CHIMERE_SHARE_NETWORKS:
- share_networks.append((network[0], network[1] % net_dct, network[2]))
- response_dct['share_networks'] = share_networks
+ net_dct['to'] = settings.CONTACT_EMAIL
+ if net_dct['to']:
+ net_dct["body"] = _(settings.CHIMERE_MODIF_EMAIL)
+ response_dct['modif_by_email'] = 'mailto:?to=%(to)s&subject='\
+ '%(text)s&body=%(body)s%(url)s' % net_dct
# to be sure there is unique IDs during a browsing
response_dct['time_now'] = datetime.datetime.now().strftime('%H%M%S')
response_dct['dated'] = settings.CHIMERE_DAYS_BEFORE_EVENT \
@@ -528,17 +594,12 @@ def getGeoObjects(request, area_name, category_ids, status):
status = 'A'
status = status.split('_')
category_ids = category_ids.split('_')
- try:
- q = checkDate(Q(status__in=status, categories__in=category_ids))
- query = Route.objects.filter(q)
- except:
- return HttpResponse('no results')
- query.order_by('categories')
- routes = list(query)
+ query = AggregatedRoute.objects.filter(status__in=status,
+ subcategory__in=category_ids).order_by('subcategory')
jsons = []
current_cat, colors, idx = None, None, 0
- for route in routes:
- c_cat = route.categories.all()[0]
+ for route in query.all():
+ c_cat = route.subcategory
if not current_cat or current_cat != c_cat:
idx = 0
current_cat = c_cat
@@ -560,10 +621,28 @@ def getGeoObjects(request, area_name, category_ids, status):
data = '{"type": "FeatureCollection", "features":[%s]}' % ",".join(jsons)
return HttpResponse(data)
+def get_all_categories(request, area_name=None):
+ '''
+ Get all available categories in JSON
+ '''
+ context_data, redir = get_base_response(area_name)
+ area = context_data["area"]
+ subcategories = []
+ if area:
+ subcategories = list(area.getCategories('A',
+ area_name=context_data['area_name']))
+ else:
+ categories = SubCategory.getAvailable()
+ for cat, subcats in categories:
+ subcategories += subcats
+ subcats = [subcat.getJSONDict() for subcat in subcategories]
+ jsons = json.dumps({'categories':subcats})
+ return HttpResponse(jsons)
+
def get_available_categories(request, area_name=None, area=None, status='A',
force=None):
'''
- Get categories for a designed area
+ Get category menu for a designed area
'''
context_data, redir = get_base_response(area_name)
area = context_data["area"]
@@ -608,6 +687,16 @@ def get_available_categories(request, area_name=None, area=None, status='A',
return render_to_response('chimere/blocks/categories.html', context_data,
context_instance=RequestContext(request))
+def getCategory(request, area_name='', category_id=0):
+ '''
+ Get the JSON for a category (mainly in order to get the description)
+ '''
+ try:
+ category = SubCategory.objects.get(pk=category_id)
+ except ObjectDoesNotExist:
+ return HttpResponse('no results')
+ return HttpResponse(category.getJSON())
+
def getTinyfiedUrl(request, parameters, area_name=''):
'''
Get the tinyfied version of parameters
@@ -648,6 +737,72 @@ def redirectFromTinyURN(request, area_name='', tiny_urn=''):
return redir
return HttpResponseRedirect(response_dct['extra_url'] + parameters)
+def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2,
+ transport='foot', speed=''):
+ '''
+ Get the JSON for a route
+ '''
+ try:
+ lon1, lat1 = float(lon1), float(lat1)
+ lon2, lat2 = float(lon2), float(lat2)
+ steps = [float(lonlat) for lonlat in lonlat_steps.split('_') if lonlat]
+ # regroup by 2
+ steps = [(steps[i*2], steps[i*2+1]) for i in range(len(steps)/2)]
+ except ValueError:
+ return HttpResponse('no results')
+ jsons, desc, total = router.route(lon1, lat1, lon2, lat2, steps=steps,
+ transport=transport, speed=speed)
+ if not jsons:
+ return HttpResponse('no results')
+ jsonencoder = json.JSONEncoder()
+ total = jsonencoder.encode(total)
+ desc = jsonencoder.encode(desc)
+
+ # get associated POIs
+ try:
+ route = GEOSGeometry(jsons[0])
+ except OGRException:
+ return HttpResponse(_(u"Bad geometry"), status=500)
+ cats = SubCategory.objects.filter(routing_warn=True)
+ message = ''
+ if cats.count():
+ st_string = '{"type":"Feature", "geometry":{ "type": "Point", '\
+ '"coordinates": [ %f, %f ] }, "properties":{"icon_path":"%s",'\
+ '"icon_width":%d, "icon_height":%d}}'
+ points = [(m.point, m.categories.all()[0].icon)
+ for m in list(Marker.objects.filter(status='A',
+ categories__in=cats, point__distance_lte=(route, D(m=15))
+ ).all())]
+ for pt, icon in points:
+ st = st_string % (pt.x, pt.y, icon.image.url, icon.image.width,
+ icon.image.height)
+ jsons.append(st)
+ routes = Route.objects.filter(status='A', categories__in=cats,
+ route__crosses=route)
+ intersect = False
+ for rout in routes.intersection(route):
+ pts = rout.intersection
+ icon = rout.categories.all()[0].icon
+ if hasattr(pts, 'x'):
+ pts = [pts]
+ if pts:
+ pt = pts[0]
+ st = st_string % (pt.x, pt.y, icon.image.url, icon.image.width,
+ icon.image.height)
+ jsons.append(st)
+ if points or intersect:
+ message = getattr(settings, 'CHIMERE_ROUTING_WARN_MESSAGE', '')
+ if message:
+ message = ', "message":%s' % jsonencoder.encode(
+ "%s" % _(message))
+ else:
+ message = ''
+ data = '{"properties":{"transport":%s, "total":%s, "description":%s}, '\
+ '"type": "FeatureCollection", "features":[%s]%s}' % (
+ jsonencoder.encode(transport), total, desc, ",".join(jsons),
+ message)
+ return HttpResponse(data)
+
def rss(request, area_name=''):
'''
Redirect to RSS subscription page
@@ -655,7 +810,8 @@ def rss(request, area_name=''):
response_dct, redir = get_base_response(area_name)
if redir:
return redir
- response_dct.update({'actions':actions, 'action_selected':('rss',),
+ response_dct.update({'actions':actions(response_dct['area_name']),
+ 'action_selected':('rss',),
'category_rss_feed':'',})
# If the form has been submited
if request.method == "POST":
diff --git a/chimere/widgets.py b/chimere/widgets.py
index 2d0c189..4f09c62 100644
--- a/chimere/widgets.py
+++ b/chimere/widgets.py
@@ -27,6 +27,9 @@ from django.contrib.gis.db import models
from django.contrib.gis.geos import fromstr
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
+from django.forms.widgets import RadioInput, RadioFieldRenderer
+from django.utils.encoding import force_unicode
+from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
from django.template.loader import render_to_string
@@ -71,18 +74,23 @@ def get_map_layers(area_name=''):
pass
map_layers, default = [], None
if area and area.layers.count():
- map_layers = [layer.layer_code
+ map_layers = [[layer.name, layer.layer_code, False]
for layer in area.layers.order_by('arealayers__order').all()]
def_layer = area.layers.filter(arealayers__default=True)
if def_layer.count():
def_layer = def_layer.all()[0]
for order, map_layer in enumerate(map_layers):
- if map_layer == def_layer.layer_code:
+ if map_layer[1] == def_layer.layer_code:
default = order
+ map_layers[order][2] = True
+ else:
+ map_layers[0][2] = True
elif settings.CHIMERE_DEFAULT_MAP_LAYER:
- map_layers = [settings.CHIMERE_DEFAULT_MAP_LAYER]
+ map_layers = [(_(u"Default layer"), settings.CHIMERE_DEFAULT_MAP_LAYER,
+ True)]
else:
- map_layers = ["new OpenLayers.Layer.OSM.Mapnik('Mapnik')"]
+ map_layers = [(u"Mapnik", "new OpenLayers.Layer.OSM.Mapnik('Mapnik')",
+ True)]
return map_layers, default
class ChosenSelectWidget(forms.Select):
@@ -104,6 +112,41 @@ class ChosenSelectWidget(forms.Select):
u"</script>\n" % kwargs['attrs']['id']
return mark_safe(rendered)
+"""
+JQuery UI button select widget.
+"""
+class ButtonRadioInput(RadioInput):
+ def render(self, name=None, value=None, attrs=None, choices=()):
+ name = name or self.name
+ value = value or self.value
+ attrs = attrs or self.attrs
+ if 'id' in self.attrs:
+ label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
+ else:
+ label_for = ''
+ choice_label = conditional_escape(force_unicode(self.choice_label))
+ return mark_safe(u'%s <label%s>%s</label>' % (self.tag(), label_for,
+ choice_label))
+class ButtonRadioFieldRenderer(RadioFieldRenderer):
+ def __iter__(self):
+ for i, choice in enumerate(self.choices):
+ yield ButtonRadioInput(self.name, self.value, self.attrs.copy(),
+ choice, i)
+ def render(self):
+ return mark_safe(u'\n'.join([force_unicode(w) for w in self]))
+class ButtonSelectWidget(forms.RadioSelect):
+ def __init__(self, *args, **kwargs):
+ self.renderer = ButtonRadioFieldRenderer
+ super(ButtonSelectWidget, self).__init__(*args, **kwargs)
+
+ def render(self, *args, **kwargs):
+ rendered = "<div id='%s'>\n" % kwargs['attrs']['id']
+ rendered += super(ButtonSelectWidget, self).render(*args, **kwargs)
+ rendered += u"\n<script type='text/javascript'>\n"\
+ u" $('#%s').buttonset();\n"\
+ u"</script>\n</div>\n" % kwargs['attrs']['id']
+ return mark_safe(rendered)
+
class ImporterChoicesWidget(forms.Select):
'''
Importer select widget.
@@ -126,6 +169,33 @@ class TextareaWidgetBase(forms.Textarea):
rendered = super(TextareaWidgetBase, self).render(*args, **kwargs)
return mark_safe(rendered)
+class FullTextareaWidget(TextareaWidgetBase):
+ """
+ Manage the edition of a text using TinyMCE
+ """
+ class Media:
+ js = ["%stiny_mce.js" % settings.TINYMCE_URL]
+
+ def render(self, *args, **kwargs):
+ if 'attrs' not in kwargs:
+ kwargs['attrs'] = {}
+ if 'class' not in kwargs['attrs']:
+ kwargs['attrs']['class'] = ''
+ else:
+ kwargs['attrs']['class'] += ' '
+ kwargs['attrs']['class'] += 'mceEditor'
+ rendered = super(FullTextareaWidget, self).render(*args, **kwargs)
+ rendered += u"""<script type='text/javascript'>
+tinyMCE.init({
+ mode : "textareas",
+ theme : "advanced",
+ relative_urls : false,
+ editor_selector : "mceEditor"
+});
+</script>
+"""
+ return mark_safe(rendered)
+
class TextareaWidget(TextareaWidgetBase):
"""
Manage the edition of a text using TinyMCE
@@ -152,6 +222,27 @@ class DatePickerWidget(forms.TextInput):
u"</script>\n" % kwargs['attrs']['id']
return mark_safe(rendered)
+class NominatimWidget(forms.TextInput):
+ class Media:
+ js = ["%schimere/js/nominatim-widget.js" % settings.STATIC_URL]
+ def render(self, name, value, attrs=None, area_name=''):
+ tpl = u"""
+<input type='hidden' name='nominatim_%(id)s_lat' id='nominatim_%(id)s_lat'/>
+<input type='hidden' name='nominatim_%(id)s_lon' id='nominatim_%(id)s_lon'/>
+<input type='text' class='nominatim-widget' name='nominatim_%(id)s' id='nominatim_%(id)s' value=""/>
+<label class='nominatim-label' id='nominatim_%(id)s_label'>&nbsp;</label>
+<script type='text/javascript'>
+var default_nominatim_lbl = "%(label)s";
+var nominatim_url = "%(nominatim_url)s";
+$("#nominatim_%(id)s").val(default_nominatim_lbl);
+$("#nominatim_%(id)s").click(function(){
+ $("#nominatim_%(id)s").val('');
+});
+</script>
+""" % {'id':name, 'nominatim_url':settings.NOMINATIM_URL,
+ 'label':_(u"Street, City, Country")}
+ return mark_safe(tpl)
+
class PointChooserWidget(forms.TextInput):
"""
Manage the edition of point on a map
@@ -183,6 +274,7 @@ class PointChooserWidget(forms.TextInput):
else:
value = None
map_layers, default_area = get_map_layers(area_name)
+ map_layers = [js for n, js, default in map_layers]
#TODO: manage area
return mark_safe(
render_to_string('chimere/blocks/live_coordinates.html',
@@ -238,7 +330,11 @@ class RouteChooserWidget(forms.TextInput):
'''
tpl = getMapJS(area_name)
map_layers, default_area = get_map_layers(area_name)
+ map_layers = [js for nm, js, default in map_layers]
js = """
+ var resolutions;
+ var zoomOffset;
+
var extra_url = "%s";
OpenLayers.ImgPath = '%schimere/img/';
var EPSG_DISPLAY_PROJECTION = epsg_display_projection = new OpenLayers.Projection('EPSG:%s');
@@ -251,7 +347,7 @@ class RouteChooserWidget(forms.TextInput):
chimere_init_options['edition'] = true;
chimere_init_options['edition_type_is_route'] = true;
chimere_init_options["checked_categories"] = [];
- """ % ( reverse("chimere:index"), settings.STATIC_URL,
+ """ % (reverse("chimere:index"), settings.STATIC_URL,
settings.CHIMERE_EPSG_DISPLAY_PROJECTION,
settings.CHIMERE_EPSG_PROJECTION, settings.CHIMERE_DEFAULT_CENTER,
settings.CHIMERE_DEFAULT_ZOOM, ", ".join(map_layers))