Added close_to and far_from filters in HistoryForm
authorJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Mon, 18 Apr 2011 12:19:01 +0000 (12:19 +0000)
committerJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Mon, 18 Apr 2011 12:19:01 +0000 (12:19 +0000)
Escape command parameters in that form

bin/djais/views.py

index a2c1d98546628587c6d08588883a2697bd2186fc..8f7ecb95cdd54f1e063a949473501f068b336f2d 100644 (file)
@@ -172,11 +172,13 @@ class HistoryForm(forms.Form):
     grain = SecondsField(label='One position every', initial=3600)
     filter_area = forms.ChoiceField(required=False, label='Only in area',
         choices=[ (u'', u'(Not filtered)') ] + [ (fn[1], fn[0]) for fn in list_areas() ] )
+    reference_latitude = forms.CharField(required=False)
+    reference_longitude = forms.CharField(required=False)
+    filter_close_to = forms.FloatField(required=False, label=u'Only if closer than n miles from reference point')
+    filter_far_from = forms.FloatField(required=False, label=u'Only if farther than n miles from reference point')
     filter_sog_le = forms.FloatField(required=False, label=u'Only if speed ≤ (knots)')
     filter_sog_ge = forms.FloatField(required=False, label=u'Only if speed ≥ (knots)')
     filter_destination = forms.CharField(required=False, label=u'Only if destination starts with', max_length=20, help_text=u'Use AIS upper case letters')
-    #reference_latitude = forms.CharField(required=False)
-    #reference_longitude = forms.CharField(required=False)
 
     def clean_start_date(self):
         period_type = self.cleaned_data.get('period_type', None)
@@ -234,65 +236,120 @@ class HistoryForm(forms.Form):
         if period_type == u'date_date' and start_date is not None and end_date is not None:
             if start_date >= end_date:
                 self._errors["start_date"] = self.error_class(['Start date must be before end date.'])
+        reference_latitude = self.cleaned_data.get('reference_latitude', None)
+        reference_longitude = self.cleaned_data.get('reference_longitude', None)
+        filter_close_to = self.cleaned_data.get('filter_close_to', None)
+        filter_far_from = self.cleaned_data.get('filter_far_from', None)
+        if filter_close_to is not None:
+            if reference_latitude is None:
+                self._errors['reference_latitude'] = self.error_class([u'Field required when using close_to filter'])
+            if reference_longitude is None:
+                self._errors['reference_longitude'] = self.error_class([u'Field required when using close_to filter'])
+        if filter_far_from is not None:
+            if reference_latitude is None:
+                self._errors['reference_latitude'] = self.error_class([u'Field required when using far_from filter'])
+            if reference_longitude is None:
+                self._errors['reference_longitude'] = self.error_class([u'Field required when using far_from filter'])
         return cleaned_data
     
     def get_cmdext(self):
         '''
         Must not be called unless is_valid
         Returns (command, extension)
-        FIXME escape!
         '''
+        def escape_cmd_arg(txt):
+            txt = unicode(txt)
+            isclean = True
+            for c in txt:
+                if c.upper() not in '+-./0123456789=@^_ABCDEFGHIJKLMNOPQRSTUVWXYZ':
+                    isclean = False
+                    break
+            if isclean:
+                return txt
+            result = u'"'
+            for c in txt:
+                if c in u'"\\':
+                    result += u'\\'
+                result += c
+            return result + u'"'
+
+        def addparam(txt):
+            command.append(escape_cmd_arg(txt))
+            
         data = self.cleaned_data
         format = data['format']
 
         if format == u'track':
-            command = u'show_targets_ships'
-            command += u' --format=track'
+            command = [ u'show_targets_ships' ]
+            addparam(u'--format=track')
             extension = u'kmz'
 
         elif format == u'animation':
-            command = u'show_targets_ships'
-            command += u' --format=animation'
+            command = [ u'show_targets_ships' ]
+            addparam(u'--format=animation')
             extension = u'kmz'
         
         elif format == u'csv':
-            command = u'common'
+            command = [ u'common' ]
             extension = u'csv'
         else:
             raise Http404(u'Invalid archive format')
        
         date_start = data.get('start_date', None)
         if date_start:
-            command += u' --start \'' + date_start.strftime('%Y%m%d') + u'\''
+            addparam(u'--format=animation')
+            addparam(u'--start')
+            addparam(date_start.strftime('%Y%m%d'))
 
         date_end = data.get('end_date', None)
         if date_end:
-            command += u' --end \'' + date_end.strftime('%Y%m%d') + u'\''
+            addparam(u'--end')
+            addparam(date_end.strftime('%Y%m%d'))
 
         duration = data.get('duration', None)
         if duration:
-            command += u' --duration \'' + unicode(duration) + u'\''
+            addparam(u'--duration')
+            addparam(duration)
 
         grain = data['grain']
-        command += u' --granularity ' + unicode(grain)
+        addparam(u'--granularity')
+        addparam(grain)
 
         filter_area = data.get('filter_area', None)
         if filter_area:
-            command += u' --filter-area \'' + filter_area + u'\''
+            addparam(u'--filter-area')
+            addparam(filter_area)
 
         filter_sog_le = data.get('filter_sog_le', None)
         if filter_sog_le:
-            command += u' --filter-sog-le ' + unicode(filter_sog_le)
+            addparam(u'--filter-sog-le')
+            addparam(filter_sog_le)
 
         filter_sog_ge = data.get('filter_sog_ge', None)
         if filter_sog_ge:
-            command += u' --filter-sog-ge ' + unicode(filter_sog_ge)
+            addparam(u'--filter-sog-ge')
+            addparam(filter_sog_ge)
 
         filter_destination = data.get('filter_destination', None)
         if filter_destination:
-            command += u' --filter-destination \'' + filter_destination + u'\''
-
-        return command, extension
+            addparam(u'--filter-destination')
+            addparam(filter_destination)
+
+        reference_latitude = self.cleaned_data.get('reference_latitude', None)
+        reference_longitude = self.cleaned_data.get('reference_longitude', None)
+        filter_close_to = self.cleaned_data.get('filter_close_to', None)
+        filter_far_from = self.cleaned_data.get('filter_far_from', None)
+        if filter_close_to and reference_latitude and reference_longitude:
+            addparam(u'--filter-closeto')
+            addparam(reference_latitude)
+            addparam(reference_longitude)
+            addparam(filter_close_to)
+        if filter_far_from and reference_latitude and reference_longitude:
+            addparam(u'--filter-farfrom')
+            addparam(reference_latitude)
+            addparam(reference_longitude)
+            addparam(filter_far_from)
+        return u' '.join(command), extension
 
 
 @http_authenticate(auth, 'ais')