diff options
Diffstat (limited to 'chimere/main')
| -rw-r--r-- | chimere/main/forms.py | 25 | ||||
| -rw-r--r-- | chimere/main/models.py | 46 | ||||
| -rw-r--r-- | chimere/main/views.py | 52 | ||||
| -rw-r--r-- | chimere/main/widgets.py | 5 |
4 files changed, 114 insertions, 14 deletions
diff --git a/chimere/main/forms.py b/chimere/main/forms.py index 1ecd348..dc1fbad 100644 --- a/chimere/main/forms.py +++ b/chimere/main/forms.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2008-2010 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2008-2011 É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 @@ -106,9 +106,9 @@ class MarkerAdminForm(forms.ModelForm): """ # declare properties for property in PropertyModel.objects.filter(available=True): - exec('property_%d_%d = forms.CharField(label="%s", widget=%s, \ -required=False)' % (property.order, property.id, property.name, - PropertyModel.TYPE_WIDGET[property.type])) + exec('property_%d_%d = forms.CharField(label="%s", widget=%s, '\ + 'required=False)' % (property.order, property.id, property.name, + PropertyModel.TYPE_WIDGET[property.type])) class Meta: model = Marker @@ -219,9 +219,9 @@ class RouteForm(RouteAdminForm): exclude = ('status',) # marker properties for property in PropertyModel.objects.filter(available=True): - exec('property_%d_%d = forms.CharField(label="%s", widget=%s, \ -required=False)' % (property.order, property.id, property.name, - PropertyModel.TYPE_WIDGET[property.type])) + exec('property_%d_%d = forms.CharField(label="%s", widget=%s, '\ + 'required=False)' % (property.order, property.id, property.name, + PropertyModel.TYPE_WIDGET[property.type])) def save(self, *args, **keys): """ @@ -246,6 +246,17 @@ required=False)' % (property.order, property.id, property.name, new_marker.saveProperties(properties) return new_route +class FileForm(forms.Form): + raw_file = forms.FileField() + + def clean_raw_file(self): + data = self.cleaned_data['raw_file'] + if '.' not in data.name or \ + data.name.split('.')[-1].lower() not in ('kml', 'gpx'): + raise forms.ValidationError(_(u"Bad file format: this must be a "\ + u"GPX or KML file")) + return data + class AreaAdminForm(forms.ModelForm): """ Admin page to create an area diff --git a/chimere/main/models.py b/chimere/main/models.py index 3897fe9..5ab45f6 100644 --- a/chimere/main/models.py +++ b/chimere/main/models.py @@ -20,7 +20,12 @@ """ Models description """ +import os, string +import lxml.etree as ElementTree from datetime import datetime, timedelta +from subprocess import Popen, PIPE + +from django.core.files import File from django.utils.translation import ugettext_lazy as _ @@ -317,6 +322,46 @@ class RouteFile(models.Model): def __unicode__(self): return self.name + def process(self): + if self.simplified_file: + return + input_name = settings.MEDIA_ROOT + self.raw_file.name + output_name = settings.MEDIA_ROOT + self.raw_file.name[:-4] + \ + "_simplified" + ".gpx" + cli_args = [settings.GPSBABEL, '-i'] + if self.file_type == 'K': + cli_args.append('kml') + elif self.file_type == 'G': + cli_args.append('gpx') + cli_args += ['-f', input_name, '-x', settings.GPSBABEL_OPTIONS, + '-o', 'gpx', '-F', output_name] + p = Popen(cli_args, stderr=PIPE) + p.wait() + if p.returncode: + print p.stderr.read() + #logger.error(p.stderr.read()) + else: + self.simplified_file = File(open(output_name)) + self.save() + os.remove(output_name) + + @property + def route(self): + if not self.simplified_file: + return + mainNS = string.Template("{http://www.topografix.com/GPX/1/0}$tag") + trkpt = mainNS.substitute(tag="trkpt") + file_name = settings.MEDIA_ROOT + self.simplified_file.name + et = ElementTree.parse(open(file_name)) + pts = [] + for pt in et.findall("//" + trkpt): + pts.append((pt.get("lon"), pt.get("lat"))) + geojson_tpl = u'{"type":"Feature", "geometry":{ "type": "LineString", '\ + '"coordinates":[%s]}}' + wkt_tpl = u'LINESTRING(%s)' + return wkt_tpl % u','.join([u'%s %s' % (pt[0], pt[1]) \ + for pt in pts]) + class Route(models.Model): '''Route on the map ''' @@ -385,6 +430,7 @@ class Route(models.Model): return u'{"type":"Feature", "geometry":%(geometry)s, '\ u'"properties":{"pk": %(id)d, "name": "%(name)s", '\ u'"color":"%(color)s"}}' % attributes + def getTinyUrl(self): parameters = 'current_feature=%d&checked_categories=%s' % (self.id, self.categories[0].id) diff --git a/chimere/main/views.py b/chimere/main/views.py index 2f80ea8..812fff6 100644 --- a/chimere/main/views.py +++ b/chimere/main/views.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2008-2010 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2008-2011 É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 @@ -31,16 +31,17 @@ from django.http import HttpResponseRedirect, HttpResponse from django.core import serializers from django.utils.http import urlquote from django.db.models import Q +from django.utils import simplejson from chimere import settings from chimere.main.actions import actions -from chimere.main.models import Category, SubCategory, PropertyModel, Marker, \ - Route, News, SimpleArea, Area, Color, TinyUrl +from chimere.main.models import Category, SubCategory, PropertyModel, \ + Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile from chimere.main.widgets import getMapJS, PointChooserWidget, \ RouteChooserWidget, URL_OSM_JS, URL_OSM_CSS from chimere.main.forms import MarkerForm, RouteForm, ContactForm, \ - notifySubmission, notifyStaff + FileForm, notifySubmission, notifyStaff def get_base_response(area_name=""): """ @@ -58,6 +59,7 @@ def get_base_response(area_name=""): if settings.CSS_AREAS and area_name: base_response_dct['css_area'] = area_name + ".css" base_response_dct['area_name'] = area_name + base_response_dct['JQUERY_URL'] = settings.JQUERY_URL return base_response_dct def index(request, area_name=None, default_area=None, simple=False): @@ -124,7 +126,7 @@ def edit(request, area_name=""): notifySubmission(marker) response_dct = get_base_response(area_name) return HttpResponseRedirect(response_dct['extra_url'] + \ -'submited/edit') + 'submited/edit') else: # An unbound form form = MarkerForm() @@ -149,6 +151,44 @@ def edit(request, area_name=""): response_dct['current_category'] = int(form.data['subcategory']) return render_to_response('edit.html', response_dct) +def uploadFile(request, area_name=''): + response_dct = get_base_response(area_name) + # If the form has been submited + if request.method == 'POST': + form = FileForm(request.POST, request.FILES) + # All validation rules pass + if form.is_valid(): + raw_file = form.cleaned_data['raw_file'] + name = raw_file.name.split('.')[0] + file_type = raw_file.name.split('.')[-1][0].upper() + routefile = RouteFile(raw_file=raw_file, name=name, + file_type=file_type) + routefile.save() + response_dct = get_base_response(area_name) + response_dct['gpx_id'] = routefile.pk + return render_to_response('uploadFile.html', response_dct) + else: + # An unbound form + form = FileForm() + response_dct.update({'form':form}) + return render_to_response('uploadFile.html', response_dct) + +def processRouteFile(request, area_name='', file_id=None): + if file_id: + try: + route_file = RouteFile.objects.get(pk=file_id) + route_file.process() + route = route_file.route + if not route: + return HttpResponse(status=500) + return HttpResponse(simplejson.dumps({'wkt':route}), + 'application/javascript', status=200) + except: + return HttpResponse(status=500) + else: + return HttpResponse(status=400) + + def editRoute(request, area_name=""): """ Route edition page @@ -165,7 +205,7 @@ def editRoute(request, area_name=""): notifySubmission(route) response_dct = get_base_response(area_name) return HttpResponseRedirect(response_dct['extra_url'] + \ -'submited/edit') + 'submited/edit') else: # An unbound form form = RouteForm() diff --git a/chimere/main/widgets.py b/chimere/main/widgets.py index 06c75c6..caac0ea 100644 --- a/chimere/main/widgets.py +++ b/chimere/main/widgets.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2008-2011 É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 @@ -212,6 +212,9 @@ initFeature(geometry);""" % val.json tpl += """ // --></script> """ + tpl += u'<a href="#" class="add-button" '\ + u'onclick="open_window(\'%supload_file\');">%s</a>' % ( + settings.BASE_URL, _(u"Upload a route file (GPX or KML)")) return mark_safe(tpl) class RouteField(models.LineStringField): |
