summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorWookey <wookey@wookware.org>2011-07-11 02:10:22 +0100
committerWookey <wookey@wookware.org>2011-07-11 02:10:22 +0100
commitdc1327674c2676db02ccf525725019cd9115b699 (patch)
tree8b3a151a8512576ccfb6bb6578fe124c033c46c0 /core
parentc8ff8e3ef60c6eba0071e20664268c790c6a6aa6 (diff)
downloadtroggle-dc1327674c2676db02ccf525725019cd9115b699.tar.gz
troggle-dc1327674c2676db02ccf525725019cd9115b699.tar.bz2
troggle-dc1327674c2676db02ccf525725019cd9115b699.zip
remove all the DOS linefeeds
Diffstat (limited to 'core')
-rw-r--r--core/admin.py282
-rw-r--r--core/forms.py242
-rw-r--r--core/models.py1400
-rw-r--r--core/models_survex.py426
-rw-r--r--core/templatetags/link.py18
-rw-r--r--core/templatetags/survex_markup.py102
-rw-r--r--core/templatetags/wiki_markup.py338
-rw-r--r--core/view_surveys.py466
-rw-r--r--core/views.py16
-rw-r--r--core/views_caves.py282
-rw-r--r--core/views_logbooks.py504
-rw-r--r--core/views_other.py564
-rw-r--r--core/views_survex.py634
13 files changed, 2637 insertions, 2637 deletions
diff --git a/core/admin.py b/core/admin.py
index be4045a..fc43f23 100644
--- a/core/admin.py
+++ b/core/admin.py
@@ -1,141 +1,141 @@
-from troggle.core.models import *
-from django.contrib import admin
-from django.forms import ModelForm
-import django.forms as forms
-from django.http import HttpResponse
-from django.core import serializers
-from core.views_other import downloadLogbook
-#from troggle.reversion.admin import VersionAdmin #django-reversion version control
-
-
-class TroggleModelAdmin(admin.ModelAdmin):
-
- def save_model(self, request, obj, form, change):
- """overriding admin save to fill the new_since parsing_field"""
- obj.new_since_parsing=True
- obj.save()
-
- class Media:
- js = ('js/jquery.js','js/QM_helper.js')
-
-class RoleInline(admin.TabularInline):
- model = SurvexPersonRole
- extra = 4
-
-class SurvexBlockAdmin(TroggleModelAdmin):
- inlines = (RoleInline,)
-
-class ScannedImageInline(admin.TabularInline):
- model = ScannedImage
- extra = 4
-
-class OtherCaveInline(admin.TabularInline):
- model = OtherCaveName
- extra = 1
-
-class SurveyAdmin(TroggleModelAdmin):
- inlines = (ScannedImageInline,)
- search_fields = ('expedition__year','wallet_number')
-
-class QMsFoundInline(admin.TabularInline):
- model=QM
- fk_name='found_by'
- fields=('number','grade','location_description','comment')#need to add foreignkey to cave part
- extra=1
-
-class PhotoInline(admin.TabularInline):
- model = DPhoto
- exclude = ['is_mugshot' ]
- extra = 1
-
-class PersonTripInline(admin.TabularInline):
- model = PersonTrip
- raw_id_fields = ('personexpedition',)
- extra = 1
-
-#class LogbookEntryAdmin(VersionAdmin):
-class LogbookEntryAdmin(TroggleModelAdmin):
- prepopulated_fields = {'slug':("title",)}
- raw_id_fields = ('cave',)
- search_fields = ('title','expedition__year')
- date_heirarchy = ('date')
- inlines = (PersonTripInline, PhotoInline, QMsFoundInline)
- class Media:
- css = {
- "all": ("css/troggleadmin.css",)
- }
- actions=('export_logbook_entries_as_html','export_logbook_entries_as_txt')
-
- def export_logbook_entries_as_html(modeladmin, request, queryset):
- response=downloadLogbook(request=request, queryset=queryset, extension='html')
- return response
-
- def export_logbook_entries_as_txt(modeladmin, request, queryset):
- response=downloadLogbook(request=request, queryset=queryset, extension='txt')
- return response
-
-
-
-class PersonExpeditionInline(admin.TabularInline):
- model = PersonExpedition
- extra = 1
-
-class PersonAdmin(TroggleModelAdmin):
- search_fields = ('first_name','last_name')
- inlines = (PersonExpeditionInline,)
-
-class QMAdmin(TroggleModelAdmin):
- search_fields = ('found_by__cave__kataster_number','number','found_by__date')
- list_display = ('__unicode__','grade','found_by','ticked_off_by')
- list_display_links = ('__unicode__',)
- list_editable = ('found_by','ticked_off_by','grade')
- list_per_page = 20
- raw_id_fields=('found_by','ticked_off_by')
-
-class PersonExpeditionAdmin(TroggleModelAdmin):
- search_fields = ('person__first_name','expedition__year')
-
-class CaveAdmin(TroggleModelAdmin):
- search_fields = ('official_name','kataster_number','unofficial_number')
- inlines = (OtherCaveInline,)
- extra = 4
-
-class EntranceAdmin(TroggleModelAdmin):
- search_fields = ('caveandentrance__cave__kataster_number',)
-
-admin.site.register(DPhoto)
-admin.site.register(Cave, CaveAdmin)
-admin.site.register(Area)
-#admin.site.register(OtherCaveName)
-admin.site.register(CaveAndEntrance)
-admin.site.register(NewSubCave)
-admin.site.register(CaveDescription)
-admin.site.register(Entrance, EntranceAdmin)
-admin.site.register(SurvexBlock, SurvexBlockAdmin)
-admin.site.register(Expedition)
-admin.site.register(Person,PersonAdmin)
-admin.site.register(SurvexPersonRole)
-admin.site.register(PersonExpedition,PersonExpeditionAdmin)
-admin.site.register(LogbookEntry, LogbookEntryAdmin)
-#admin.site.register(PersonTrip)
-admin.site.register(QM, QMAdmin)
-admin.site.register(Survey, SurveyAdmin)
-admin.site.register(ScannedImage)
-
-admin.site.register(SurvexScansFolder)
-admin.site.register(SurvexScanSingle)
-
-def export_as_json(modeladmin, request, queryset):
- response = HttpResponse(mimetype="text/json")
- response['Content-Disposition'] = 'attachment; filename=troggle_output.json'
- serializers.serialize("json", queryset, stream=response)
- return response
-
-def export_as_xml(modeladmin, request, queryset):
- response = HttpResponse(mimetype="text/xml")
- response['Content-Disposition'] = 'attachment; filename=troggle_output.xml'
- serializers.serialize("xml", queryset, stream=response)
- return response
-
-#admin.site.add_action(export_as_xml)
-#admin.site.add_action(export_as_json)
+from troggle.core.models import *
+from django.contrib import admin
+from django.forms import ModelForm
+import django.forms as forms
+from django.http import HttpResponse
+from django.core import serializers
+from core.views_other import downloadLogbook
+#from troggle.reversion.admin import VersionAdmin #django-reversion version control
+
+
+class TroggleModelAdmin(admin.ModelAdmin):
+
+ def save_model(self, request, obj, form, change):
+ """overriding admin save to fill the new_since parsing_field"""
+ obj.new_since_parsing=True
+ obj.save()
+
+ class Media:
+ js = ('js/jquery.js','js/QM_helper.js')
+
+class RoleInline(admin.TabularInline):
+ model = SurvexPersonRole
+ extra = 4
+
+class SurvexBlockAdmin(TroggleModelAdmin):
+ inlines = (RoleInline,)
+
+class ScannedImageInline(admin.TabularInline):
+ model = ScannedImage
+ extra = 4
+
+class OtherCaveInline(admin.TabularInline):
+ model = OtherCaveName
+ extra = 1
+
+class SurveyAdmin(TroggleModelAdmin):
+ inlines = (ScannedImageInline,)
+ search_fields = ('expedition__year','wallet_number')
+
+class QMsFoundInline(admin.TabularInline):
+ model=QM
+ fk_name='found_by'
+ fields=('number','grade','location_description','comment')#need to add foreignkey to cave part
+ extra=1
+
+class PhotoInline(admin.TabularInline):
+ model = DPhoto
+ exclude = ['is_mugshot' ]
+ extra = 1
+
+class PersonTripInline(admin.TabularInline):
+ model = PersonTrip
+ raw_id_fields = ('personexpedition',)
+ extra = 1
+
+#class LogbookEntryAdmin(VersionAdmin):
+class LogbookEntryAdmin(TroggleModelAdmin):
+ prepopulated_fields = {'slug':("title",)}
+ raw_id_fields = ('cave',)
+ search_fields = ('title','expedition__year')
+ date_heirarchy = ('date')
+ inlines = (PersonTripInline, PhotoInline, QMsFoundInline)
+ class Media:
+ css = {
+ "all": ("css/troggleadmin.css",)
+ }
+ actions=('export_logbook_entries_as_html','export_logbook_entries_as_txt')
+
+ def export_logbook_entries_as_html(modeladmin, request, queryset):
+ response=downloadLogbook(request=request, queryset=queryset, extension='html')
+ return response
+
+ def export_logbook_entries_as_txt(modeladmin, request, queryset):
+ response=downloadLogbook(request=request, queryset=queryset, extension='txt')
+ return response
+
+
+
+class PersonExpeditionInline(admin.TabularInline):
+ model = PersonExpedition
+ extra = 1
+
+class PersonAdmin(TroggleModelAdmin):
+ search_fields = ('first_name','last_name')
+ inlines = (PersonExpeditionInline,)
+
+class QMAdmin(TroggleModelAdmin):
+ search_fields = ('found_by__cave__kataster_number','number','found_by__date')
+ list_display = ('__unicode__','grade','found_by','ticked_off_by')
+ list_display_links = ('__unicode__',)
+ list_editable = ('found_by','ticked_off_by','grade')
+ list_per_page = 20
+ raw_id_fields=('found_by','ticked_off_by')
+
+class PersonExpeditionAdmin(TroggleModelAdmin):
+ search_fields = ('person__first_name','expedition__year')
+
+class CaveAdmin(TroggleModelAdmin):
+ search_fields = ('official_name','kataster_number','unofficial_number')
+ inlines = (OtherCaveInline,)
+ extra = 4
+
+class EntranceAdmin(TroggleModelAdmin):
+ search_fields = ('caveandentrance__cave__kataster_number',)
+
+admin.site.register(DPhoto)
+admin.site.register(Cave, CaveAdmin)
+admin.site.register(Area)
+#admin.site.register(OtherCaveName)
+admin.site.register(CaveAndEntrance)
+admin.site.register(NewSubCave)
+admin.site.register(CaveDescription)
+admin.site.register(Entrance, EntranceAdmin)
+admin.site.register(SurvexBlock, SurvexBlockAdmin)
+admin.site.register(Expedition)
+admin.site.register(Person,PersonAdmin)
+admin.site.register(SurvexPersonRole)
+admin.site.register(PersonExpedition,PersonExpeditionAdmin)
+admin.site.register(LogbookEntry, LogbookEntryAdmin)
+#admin.site.register(PersonTrip)
+admin.site.register(QM, QMAdmin)
+admin.site.register(Survey, SurveyAdmin)
+admin.site.register(ScannedImage)
+
+admin.site.register(SurvexScansFolder)
+admin.site.register(SurvexScanSingle)
+
+def export_as_json(modeladmin, request, queryset):
+ response = HttpResponse(mimetype="text/json")
+ response['Content-Disposition'] = 'attachment; filename=troggle_output.json'
+ serializers.serialize("json", queryset, stream=response)
+ return response
+
+def export_as_xml(modeladmin, request, queryset):
+ response = HttpResponse(mimetype="text/xml")
+ response['Content-Disposition'] = 'attachment; filename=troggle_output.xml'
+ serializers.serialize("xml", queryset, stream=response)
+ return response
+
+#admin.site.add_action(export_as_xml)
+#admin.site.add_action(export_as_json)
diff --git a/core/forms.py b/core/forms.py
index ec639b0..7063f23 100644
--- a/core/forms.py
+++ b/core/forms.py
@@ -1,121 +1,121 @@
-from django.forms import ModelForm
-from models import Cave, Person, PersonExpedition, LogbookEntry, QM, Expedition
-import django.forms as forms
-from django.forms.formsets import formset_factory
-from django.contrib.admin.widgets import AdminDateWidget
-import string
-from datetime import date
-from tinymce.widgets import TinyMCE
-
-#class CaveForm(ModelForm):
-# class Meta:
-# model = Cave
-
-#class PersonForm(ModelForm):
-# class Meta:
-# model = Person
-
-#class LogbookEntryForm(ModelForm):
-# class Meta:
-# model = LogbookEntry#
-
-# def wikiLinkHints(LogbookEntry=None):
-# """
-# This function returns html-formatted paragraphs for each of the
-# wikilink types that are related to this logbookentry. Each paragraph
-# contains a list of all of the related wikilinks.
-#
-# Perhaps an admin javascript solution would be better.
-# """
-# res = ["Please use the following wikilinks, which are related to this logbook entry:"]
-#
-# res.append(r'</p><p style="float: left;"><b>QMs found:</b>')
-# for QM in LogbookEntry.instance.QMs_found.all():
-# res.append(QM.wiki_link())
-
-# res.append(r'</p><p style="float: left;"><b>QMs ticked off:</b>')
-# for QM in LogbookEntry.instance.QMs_ticked_off.all():
-# res.append(QM.wiki_link())
-
-# res.append(r'</p><p style="float: left; "><b>People</b>')
-# for persontrip in LogbookEntry.instance.persontrip_set.all():
-# res.append(persontrip.wiki_link())
-# res.append(r'</p>')
-
-# return string.join(res, r'<br />')
-
-# def __init__(self, *args, **kwargs):
-# super(LogbookEntryForm, self).__init__(*args, **kwargs)
-# self.fields['text'].help_text=self.wikiLinkHints()#
-
-class CaveForm(forms.Form):
- html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
-
-def getTripForm(expedition):
-
- class TripForm(forms.Form):
- date = forms.DateField()
- title = forms.CharField(max_length=200)
- caves = [cave.reference() for cave in Cave.objects.all()]
- caves.sort()
- caves = ["-----"] + caves
- cave = forms.ChoiceField([(c, c) for c in caves], required=False)
- location = forms.CharField(max_length=200, required=False)
- caveOrLocation = forms.ChoiceField([("cave", "Cave"), ("location", "Location")], widget = forms.widgets.RadioSelect())
- html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
-
- def clean(self):
- print dir(self)
- if self.cleaned_data.get("caveOrLocation") == "cave" and not self.cleaned_data.get("cave"):
- self._errors["cave"] = self.error_class(["This field is required"])
- if self.cleaned_data.get("caveOrLocation") == "location" and not self.cleaned_data.get("location"):
- self._errors["location"] = self.error_class(["This field is required"])
- return self.cleaned_data
-
- class PersonTripForm(forms.Form):
- names = [get_name(pe) for pe in PersonExpedition.objects.filter(expedition = expedition)]
- names.sort()
- names = ["-----"] + names
- name = forms.ChoiceField([(n, n) for n in names])
- TU = forms.FloatField(required=False)
- author = forms.BooleanField(required=False)
-
- PersonTripFormSet = formset_factory(PersonTripForm, extra=1)
-
- return PersonTripFormSet, TripForm
-
-def get_name(pe):
- if pe.nickname:
- return pe.nickname
- else:
- return pe.person.first_name
-
-class UploadFileForm(forms.Form):
- title = forms.CharField(max_length=50)
- file = forms.FileField()
- html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
- lon_utm = forms.FloatField(required=False)
- lat_utm = forms.FloatField(required=False)
- slug = forms.CharField(max_length=50)
- date = forms.DateField(required=False)
-
- caves = [cave.slug for cave in Cave.objects.all()]
- caves.sort()
- caves = ["-----"] + caves
- cave = forms.ChoiceField([(c, c) for c in caves], required=False)
-
- entrance = forms.ChoiceField([("-----", "Please select a cave"), ], required=False)
- qm = forms.ChoiceField([("-----", "Please select a cave"), ], required=False)
-
- expeditions = [e.year for e in Expedition.objects.all()]
- expeditions.sort()
- expeditions = ["-----"] + expeditions
- expedition = forms.ChoiceField([(e, e) for e in expeditions], required=False)
-
- logbookentry = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False)
-
- person = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False)
-
- survey_point = forms.CharField()
-
-
+from django.forms import ModelForm
+from models import Cave, Person, PersonExpedition, LogbookEntry, QM, Expedition
+import django.forms as forms
+from django.forms.formsets import formset_factory
+from django.contrib.admin.widgets import AdminDateWidget
+import string
+from datetime import date
+from tinymce.widgets import TinyMCE
+
+#class CaveForm(ModelForm):
+# class Meta:
+# model = Cave
+
+#class PersonForm(ModelForm):
+# class Meta:
+# model = Person
+
+#class LogbookEntryForm(ModelForm):
+# class Meta:
+# model = LogbookEntry#
+
+# def wikiLinkHints(LogbookEntry=None):
+# """
+# This function returns html-formatted paragraphs for each of the
+# wikilink types that are related to this logbookentry. Each paragraph
+# contains a list of all of the related wikilinks.
+#
+# Perhaps an admin javascript solution would be better.
+# """
+# res = ["Please use the following wikilinks, which are related to this logbook entry:"]
+#
+# res.append(r'</p><p style="float: left;"><b>QMs found:</b>')
+# for QM in LogbookEntry.instance.QMs_found.all():
+# res.append(QM.wiki_link())
+
+# res.append(r'</p><p style="float: left;"><b>QMs ticked off:</b>')
+# for QM in LogbookEntry.instance.QMs_ticked_off.all():
+# res.append(QM.wiki_link())
+
+# res.append(r'</p><p style="float: left; "><b>People</b>')
+# for persontrip in LogbookEntry.instance.persontrip_set.all():
+# res.append(persontrip.wiki_link())
+# res.append(r'</p>')
+
+# return string.join(res, r'<br />')
+
+# def __init__(self, *args, **kwargs):
+# super(LogbookEntryForm, self).__init__(*args, **kwargs)
+# self.fields['text'].help_text=self.wikiLinkHints()#
+
+class CaveForm(forms.Form):
+ html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
+
+def getTripForm(expedition):
+
+ class TripForm(forms.Form):
+ date = forms.DateField()
+ title = forms.CharField(max_length=200)
+ caves = [cave.reference() for cave in Cave.objects.all()]
+ caves.sort()
+ caves = ["-----"] + caves
+ cave = forms.ChoiceField([(c, c) for c in caves], required=False)
+ location = forms.CharField(max_length=200, required=False)
+ caveOrLocation = forms.ChoiceField([("cave", "Cave"), ("location", "Location")], widget = forms.widgets.RadioSelect())
+ html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
+
+ def clean(self):
+ print dir(self)
+ if self.cleaned_data.get("caveOrLocation") == "cave" and not self.cleaned_data.get("cave"):
+ self._errors["cave"] = self.error_class(["This field is required"])
+ if self.cleaned_data.get("caveOrLocation") == "location" and not self.cleaned_data.get("location"):
+ self._errors["location"] = self.error_class(["This field is required"])
+ return self.cleaned_data
+
+ class PersonTripForm(forms.Form):
+ names = [get_name(pe) for pe in PersonExpedition.objects.filter(expedition = expedition)]
+ names.sort()
+ names = ["-----"] + names
+ name = forms.ChoiceField([(n, n) for n in names])
+ TU = forms.FloatField(required=False)
+ author = forms.BooleanField(required=False)
+
+ PersonTripFormSet = formset_factory(PersonTripForm, extra=1)
+
+ return PersonTripFormSet, TripForm
+
+def get_name(pe):
+ if pe.nickname:
+ return pe.nickname
+ else:
+ return pe.person.first_name
+
+class UploadFileForm(forms.Form):
+ title = forms.CharField(max_length=50)
+ file = forms.FileField()
+ html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
+ lon_utm = forms.FloatField(required=False)
+ lat_utm = forms.FloatField(required=False)
+ slug = forms.CharField(max_length=50)
+ date = forms.DateField(required=False)
+
+ caves = [cave.slug for cave in Cave.objects.all()]
+ caves.sort()
+ caves = ["-----"] + caves
+ cave = forms.ChoiceField([(c, c) for c in caves], required=False)
+
+ entrance = forms.ChoiceField([("-----", "Please select a cave"), ], required=False)
+ qm = forms.ChoiceField([("-----", "Please select a cave"), ], required=False)
+
+ expeditions = [e.year for e in Expedition.objects.all()]
+ expeditions.sort()
+ expeditions = ["-----"] + expeditions
+ expedition = forms.ChoiceField([(e, e) for e in expeditions], required=False)
+
+ logbookentry = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False)
+
+ person = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False)
+
+ survey_point = forms.CharField()
+
+
diff --git a/core/models.py b/core/models.py
index 1c08a25..c82f448 100644
--- a/core/models.py
+++ b/core/models.py
@@ -1,700 +1,700 @@
-import urllib, urlparse, string, os, datetime, logging, re
-from django.forms import ModelForm
-from django.db import models
-from django.contrib import admin
-from django.core.files.storage import FileSystemStorage
-from django.contrib.auth.models import User
-from django.contrib.contenttypes.models import ContentType
-from django.db.models import Min, Max
-from django.conf import settings
-from decimal import Decimal, getcontext
-from django.core.urlresolvers import reverse
-from imagekit.models import ImageModel
-getcontext().prec=2 #use 2 significant figures for decimal calculations
-
-from models_survex import *
-
-
-def get_related_by_wikilinks(wiki_text):
- found=re.findall(settings.QM_PATTERN,wiki_text)
- res=[]
- for wikilink in found:
- qmdict={'urlroot':settings.URL_ROOT,'cave':wikilink[2],'year':wikilink[1],'number':wikilink[3]}
- try:
- qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
- found_by__date__year = qmdict['year'],
- number = qmdict['number'])
- res.append(qm)
- except QM.DoesNotExist:
- print 'fail on '+str(wikilink)
-
- return res
-
-logging.basicConfig(level=logging.DEBUG,
- filename=settings.LOGFILE,
- filemode='w')
-
-#This class is for adding fields and methods which all of our models will have.
-class TroggleModel(models.Model):
- new_since_parsing = models.BooleanField(default=False, editable=False)
- non_public = models.BooleanField(default=False)
- def object_name(self):
- return self._meta.object_name
-
- def get_admin_url(self):
- return urlparse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk))
-
- class Meta:
- abstract = True
-
-class TroggleImageModel(ImageModel):
- new_since_parsing = models.BooleanField(default=False, editable=False)
-
- def object_name(self):
- return self._meta.object_name
-
- def get_admin_url(self):
- return urlparse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk))
-
-
- class Meta:
- abstract = True
-
-#
-# single Expedition, usually seen by year
-#
-class Expedition(TroggleModel):
- year = models.CharField(max_length=20, unique=True)
- name = models.CharField(max_length=100)
-
- def __unicode__(self):
- return self.year
-
- class Meta:
- ordering = ('-year',)
- get_latest_by = 'year'
-
- def get_absolute_url(self):
- return urlparse.urljoin(settings.URL_ROOT, reverse('expedition', args=[self.year]))
-
- # construction function. should be moved out
- def get_expedition_day(self, date):
- expeditiondays = self.expeditionday_set.filter(date=date)
- if expeditiondays:
- assert len(expeditiondays) == 1
- return expeditiondays[0]
- res = ExpeditionDay(expedition=self, date=date)
- res.save()
- return res
-
- def day_min(self):
- res = self.expeditionday_set.all()
- return res and res[0] or None
-
- def day_max(self):
- res = self.expeditionday_set.all()
- return res and res[len(res) - 1] or None
-
-
-
-class ExpeditionDay(TroggleModel):
- expedition = models.ForeignKey("Expedition")
- date = models.DateField()
-
- class Meta:
- ordering = ('date',)
-
- def GetPersonTrip(self, personexpedition):
- personexpeditions = self.persontrip_set.filter(expeditionday=self)
- return personexpeditions and personexpeditions[0] or None
-
-
-#
-# single Person, can go on many years
-#
-class Person(TroggleModel):
- first_name = models.CharField(max_length=100)
- last_name = models.CharField(max_length=100)
- is_vfho = models.BooleanField(help_text="VFHO is the Vereines f&uuml;r H&ouml;hlenkunde in Obersteier, a nearby Austrian caving club.")
- mug_shot = models.CharField(max_length=100, blank=True,null=True)
- blurb = models.TextField(blank=True,null=True)
-
- #href = models.CharField(max_length=200)
- orderref = models.CharField(max_length=200) # for alphabetic
-
- #the below have been removed and made methods. I'm not sure what the b in bisnotable stands for. - AC 16 Feb
- #notability = models.FloatField() # for listing the top 20 people
- #bisnotable = models.BooleanField()
- user = models.OneToOneField(User, null=True, blank=True)
- def get_absolute_url(self):
- return urlparse.urljoin(settings.URL_ROOT,reverse('person',kwargs={'first_name':self.first_name,'last_name':self.last_name}))
-
- class Meta:
- verbose_name_plural = "People"
- class Meta:
- ordering = ('orderref',) # "Wookey" makes too complex for: ('last_name', 'first_name')
-
- def __unicode__(self):
- if self.last_name:
- return "%s %s" % (self.first_name, self.last_name)
- return self.first_name
-
-
- def notability(self):
- notability = Decimal(0)
- for personexpedition in self.personexpedition_set.all():
- if not personexpedition.is_guest:
- notability += Decimal(1) / (2012 - int(personexpedition.expedition.year))
- return notability
-
- def bisnotable(self):
- return self.notability() > Decimal(1)/Decimal(3)
-
- def surveyedleglength(self):
- return sum([personexpedition.surveyedleglength() for personexpedition in self.personexpedition_set.all()])
-
- def first(self):
- return self.personexpedition_set.order_by('-expedition')[0]
- def last(self):
- return self.personexpedition_set.order_by('expedition')[0]
-
- #def Sethref(self):
- #if self.last_name:
- #self.href = self.first_name.lower() + "_" + self.last_name.lower()
- #self.orderref = self.last_name + " " + self.first_name
- #else:
- # self.href = self.first_name.lower()
- #self.orderref = self.first_name
- #self.notability = 0.0 # set temporarily
-
-
-#
-# Person's attenance to one Expo
-#
-class PersonExpedition(TroggleModel):
- expedition = models.ForeignKey(Expedition)
- person = models.ForeignKey(Person)
- slugfield = models.SlugField(max_length=50,blank=True,null=True)
-
- is_guest = models.BooleanField(default=False)
- COMMITTEE_CHOICES = (
- ('leader','Expo leader'),
- ('medical','Expo medical officer'),
- ('treasurer','Expo treasurer'),
- ('sponsorship','Expo sponsorship coordinator'),
- ('research','Expo research coordinator'),
- )
- expo_committee_position = models.CharField(blank=True,null=True,choices=COMMITTEE_CHOICES,max_length=200)
- nickname = models.CharField(max_length=100,blank=True,null=True)
-
- def GetPersonroles(self):
- res = [ ]
- for personrole in self.personrole_set.order_by('survexblock'):
- if res and res[-1]['survexpath'] == personrole.survexblock.survexpath:
- res[-1]['roles'] += ", " + str(personrole.role)
- else:
- res.append({'date':personrole.survexblock.date, 'survexpath':personrole.survexblock.survexpath, 'roles':str(personrole.role)})
- return res
-
- class Meta:
- ordering = ('-expedition',)
- #order_with_respect_to = 'expedition'
-
- def __unicode__(self):
- return "%s: (%s)" % (self.person, self.expedition)
-
-
- #why is the below a function in personexpedition, rather than in person? - AC 14 Feb 09
- def name(self):
- if self.nickname:
- return "%s (%s) %s" % (self.person.first_name, self.nickname, self.person.last_name)
- if self.person.last_name:
- return "%s %s" % (self.person.first_name, self.person.last_name)
- return self.person.first_name
-
- def get_absolute_url(self):
- return urlparse.urljoin(settings.URL_ROOT, reverse('personexpedition',kwargs={'first_name':self.person.first_name,'last_name':self.person.last_name,'year':self.expedition.year}))
-
- def surveyedleglength(self):
- survexblocks = [personrole.survexblock for personrole in self.personrole_set.all() ]
- return sum([survexblock.totalleglength for survexblock in set(survexblocks)])
-
- # would prefer to return actual person trips so we could link to first and last ones
- def day_min(self):
- res = self.persontrip_set.aggregate(day_min=Min("expeditionday__date"))
- return res["day_min"]
-
- def day_max(self):
- res = self.persontrip_set.all().aggregate(day_max=Max("expeditionday__date"))
- return res["day_max"]
-
-#
-# Single parsed entry from Logbook
-#
-class LogbookEntry(TroggleModel):
- date = models.DateField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.
- expeditionday = models.ForeignKey("ExpeditionDay", null=True)#MJG wants to KILL THIS (redundant information)
- expedition = models.ForeignKey(Expedition,blank=True,null=True) # yes this is double-
- #author = models.ForeignKey(PersonExpedition,blank=True,null=True) # the person who writes it up doesn't have to have been on the trip.
- # Re: the above- so this field should be "typist" or something, not "author". - AC 15 jun 09
- #MJG wants to KILL THIS, as it is typically redundant with PersonTrip.is_logbook_entry_author, in the rare it was not redundanty and of actually interest it could be added to the text.
- title = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
- cave = models.ForeignKey('Cave',blank=True,null=True)
- place = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
- text = models.TextField()
- slug = models.SlugField(max_length=50)
- filename= models.CharField(max_length=200,null=True)
-
- class Meta:
- verbose_name_plural = "Logbook Entries"
- # several PersonTrips point in to this object
- ordering = ('-date',)
-
- def isLogbookEntry(self): # Function used in templates
- return True
-
- def get_absolute_url(self):
- return urlparse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug}))
-
- def __unicode__(self):
- return "%s: (%s)" % (self.date, self.title)
-
- def get_next_by_id(self):
- LogbookEntry.objects.get(id=self.id+1)
-
- def get_previous_by_id(self):
- LogbookEntry.objects.get(id=self.id-1)
-
- def new_QM_number(self):
- """Returns """
- if self.cave:
- nextQMnumber=self.cave.new_QM_number(self.date.year)
- else:
- return none
- return nextQMnumber
-
- def new_QM_found_link(self):
- """Produces a link to a new QM with the next number filled in and this LogbookEntry set as 'found by' """
- return settings.URL_ROOT + r'/admin/core/qm/add/?' + r'found_by=' + str(self.pk) +'&number=' + str(self.new_QM_number())
-
- def DayIndex(self):
- return list(self.expeditionday.logbookentry_set.all()).index(self)
-
-#
-# Single Person going on a trip, which may or may not be written up (accounts for different T/U for people in same logbook entry)
-#
-class PersonTrip(TroggleModel):
- personexpedition = models.ForeignKey("PersonExpedition",null=True)
-
- #expeditionday = models.ForeignKey("ExpeditionDay")#MJG wants to KILL THIS (redundant information)
- #date = models.DateField() #MJG wants to KILL THIS (redundant information)
- time_underground = models.FloatField(help_text="In decimal hours")
- logbook_entry = models.ForeignKey(LogbookEntry)
- is_logbook_entry_author = models.BooleanField()
-
-
- # sequencing by person (difficult to solve locally)
- #persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)#MJG wants to KILL THIS (and use funstion persontrip_next_auto)
- #persontrip_prev = models.ForeignKey('PersonTrip', related_name='pprev', blank=True,null=True)#MJG wants to KILL THIS(and use funstion persontrip_prev_auto)
-
- def persontrip_next(self):
- futurePTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__gt = self.logbook_entry.date).order_by('logbook_entry__date').all()
- if len(futurePTs) > 0:
- return futurePTs[0]
- else:
- return None
-
- def persontrip_prev(self):
- pastPTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__lt = self.logbook_entry.date).order_by('-logbook_entry__date').all()
- if len(pastPTs) > 0:
- return pastPTs[0]
- else:
- return None
-
- def place(self):
- return self.logbook_entry.cave and self.logbook_entry.cave or self.logbook_entry.place
-
- def __unicode__(self):
- return "%s (%s)" % (self.personexpedition, self.logbook_entry.date)
-
-
-
-##########################################
-# move following classes into models_cave
-##########################################
-
-class Area(TroggleModel):
- short_name = models.CharField(max_length=100)
- name = models.CharField(max_length=200, blank=True, null=True)
- description = models.TextField(blank=True,null=True)
- parent = models.ForeignKey('Area', blank=True, null=True)
- def __unicode__(self):
- if self.parent:
- return unicode(self.parent) + u" - " + unicode(self.short_name)
- else:
- return unicode(self.short_name)
- def kat_area(self):
- if self.short_name in ["1623", "1626"]:
- return self.short_name
- elif self.parent:
- return self.parent.kat_area()
-
-class CaveAndEntrance(TroggleModel):
- cave = models.ForeignKey('Cave')
- entrance = models.ForeignKey('Entrance')
- entrance_letter = models.CharField(max_length=20,blank=True,null=True)
- def __unicode__(self):
- return unicode(self.cave) + unicode(self.entrance_letter)
-
-class Cave(TroggleModel):
- # too much here perhaps
- slug = models.SlugField(max_length=50, unique = True)
- official_name = models.CharField(max_length=160)
- area = models.ManyToManyField(Area, blank=True, null=True)
- kataster_code = models.CharField(max_length=20,blank=True,null=True)
- kataster_number = models.CharField(max_length=10,blank=True, null=True)
- unofficial_number = models.CharField(max_length=60,blank=True, null=True)
- entrances = models.ManyToManyField('Entrance', through='CaveAndEntrance')
- explorers = models.TextField(blank=True,null=True)
- underground_description = models.TextField(blank=True,null=True)
- equipment = models.TextField(blank=True,null=True)
- references = models.TextField(blank=True,null=True)
- survey = models.TextField(blank=True,null=True)
- kataster_status = models.TextField(blank=True,null=True)
- underground_centre_line = models.TextField(blank=True,null=True)
- notes = models.TextField(blank=True,null=True)
- length = models.CharField(max_length=100,blank=True,null=True)
- depth = models.CharField(max_length=100,blank=True,null=True)
- extent = models.CharField(max_length=100,blank=True,null=True)
- survex_file = models.CharField(max_length=100,blank=True,null=True)
- description_file = models.CharField(max_length=200,blank=True,null=True)
- url = models.CharField(max_length=200,blank=True,null=True)
-
- #class Meta:
- # unique_together = (("area", "kataster_number"), ("area", "unofficial_number"))
- # FIXME Kataster Areas and CUCC defined sub areas need seperating
-
-
- #href = models.CharField(max_length=100)
-
- def reference(self):
- if self.kataster_number:
- return "%s-%s" % (self.kat_area(), self.kataster_number)
- else:
- return "%s-%s" % (self.kat_area(), self.unofficial_number)
-
- def get_absolute_url(self):
- if self.kataster_number:
- href = self.kataster_number
- elif self.unofficial_number:
- href = self.unofficial_number
- else:
- href = official_name.lower()
- #return settings.URL_ROOT + '/cave/' + href + '/'
- return urlparse.urljoin(settings.URL_ROOT, reverse('cave',kwargs={'cave_id':href,}))
-
- def __unicode__(self):
- if self.kataster_number:
- if self.kat_area():
- return self.kat_area() + u": " + self.kataster_number
- else:
- return unicode("l") + u": " + self.kataster_number
- else:
- if self.kat_area():
- return self.kat_area() + u": " + self.unofficial_number
- else:
- return self.unofficial_number
-
- def get_QMs(self):
- return QM.objects.filter(found_by__cave=self)
-
- def new_QM_number(self, year=datetime.date.today().year):
- """Given a cave and the current year, returns the next QM number."""
- try:
- res=QM.objects.filter(found_by__date__year=year, found_by__cave=self).order_by('-number')[0]
- except IndexError:
- return 1
- return res.number+1
-
- def kat_area(self):
- for a in self.area.all():
- if a.kat_area():
- return a.kat_area()
-
- def entrances(self):
- return CaveAndEntrance.objects.filter(cave=self)
-
- def entrancelist(self):
- rs = []
- res = ""
- for e in CaveAndEntrance.objects.filter(cave=self):
- rs.append(e.entrance_letter)
- rs.sort()
- prevR = None
- n = 0
- for r in rs:
- if prevR:
- if chr(ord(prevR) + 1 ) == r:
- prevR = r
- n += 1
- else:
- if n == 0:
- res += ", " + prevR
- else:
- res += "&ndash;" + prevR
- else:
- prevR = r
- n = 0
- res += r
- if n == 0:
- res += ", " + prevR
- else:
- res += "&ndash;" + prevR
- return res
-
-def getCaveByReference(reference):
- areaname, code = reference.split("-", 1)
- print areaname, code
- area = Area.objects.get(short_name = areaname)
- print area
- foundCaves = list(Cave.objects.filter(area = area, kataster_number = code).all()) + list(Cave.objects.filter(area = area, unofficial_number = code).all())
- print list(foundCaves)
- assert len(foundCaves) == 1
- return foundCaves[0]
-
-class OtherCaveName(TroggleModel):
- name = models.CharField(max_length=160)
- cave = models.ForeignKey(Cave)
- def __unicode__(self):
- return unicode(self.name)
-
-
-class Entrance(TroggleModel):
- slug = models.SlugField(max_length=50, unique = True)
- name = models.CharField(max_length=100, blank=True,null=True)
- entrance_description = models.TextField(blank=True,null=True)
- explorers = models.TextField(blank=True,null=True)
- map_description = models.TextField(blank=True,null=True)
- location_description = models.TextField(blank=True,null=True)
- approach = models.TextField(blank=True,null=True)
- underground_description = models.TextField(blank=True,null=True)
- photo = models.TextField(blank=True,null=True)
- MARKING_CHOICES = (
- ('P', 'Paint'),
- ('P?', 'Paint (?)'),
- ('T', 'Tag'),
- ('T?', 'Tag (?)'),
- ('R', 'Retagged'),
- ('S', 'Spit'),
- ('S?', 'Spit (?)'),
- ('U', 'Unmarked'),
- ('?', 'Unknown'))
- marking = models.CharField(max_length=2, choices=MARKING_CHOICES)
- marking_comment = models.TextField(blank=True,null=True)
- FINDABLE_CHOICES = (
- ('?', 'To be confirmed ...'),
- ('S', 'Surveyed'),
- ('L', 'Lost'),
- ('R', 'Refindable'))
- findability = models.CharField(max_length=1, choices=FINDABLE_CHOICES, blank=True, null=True)
- findability_description = models.TextField(blank=True,null=True)
- alt = models.TextField(blank=True, null=True)
- northing = models.TextField(blank=True, null=True)
- easting = models.TextField(blank=True, null=True)
- tag_station = models.TextField()
- exact_station = models.TextField()
- other_station = models.TextField()
- other_description = models.TextField(blank=True,null=True)
- bearings = models.TextField(blank=True,null=True)
- def __unicode__(self):
- a = CaveAndEntrance.objects.filter(entrance = self)
- name = u''
- if self.name:
- name = unicode(self.name) + u' '
- if len(a) == 1:
- return name + unicode(a[0])
- return name + unicode(a)
- def marking_val(self):
- for m in self.MARKING_CHOICES:
- if m[0] == self.marking:
- return m[1]
- def findability_val(self):
- for f in self.FINDABLE_CHOICES:
- if f[0] == self.findability:
- return f[1]
-
-
- def get_absolute_url(self):
-
- ancestor_titles='/'.join([subcave.title for subcave in self.get_ancestors()])
- if ancestor_titles:
- res = '/'.join((self.get_root().cave.get_absolute_url(), ancestor_titles, self.title))
-
- else:
- res = '/'.join((self.get_root().cave.get_absolute_url(), self.title))
-
- return res
-
-class CaveDescription(TroggleModel):
- short_name = models.CharField(max_length=50, unique = True)
- long_name = models.CharField(max_length=200, blank=True, null=True)
- description = models.TextField(blank=True,null=True)
- linked_subcaves = models.ManyToManyField("NewSubCave", blank=True,null=True)
- linked_entrances = models.ManyToManyField("Entrance", blank=True,null=True)
- linked_qms = models.ManyToManyField("QM", blank=True,null=True)
-
- def __unicode__(self):
- if self.long_name:
- return unicode(self.long_name)
- else:
- return unicode(self.short_name)
-
- def get_absolute_url(self):
- return urlparse.urljoin(settings.URL_ROOT, reverse('cavedescription', args=(self.short_name,)))
-
- def save(self):
- """
- Overridden save method which stores wikilinks in text as links in database.
- """
- super(CaveDescription, self).save()
- qm_list=get_related_by_wikilinks(self.description)
- for qm in qm_list:
- self.linked_qms.add(qm)
- super(CaveDescription, self).save()
-
-class NewSubCave(TroggleModel):
- name = models.CharField(max_length=200, unique = True)
- def __unicode__(self):
- return unicode(self.name)
-
-class QM(TroggleModel):
- #based on qm.csv in trunk/expoweb/smkridge/204 which has the fields:
- #"Number","Grade","Area","Description","Page reference","Nearest station","Completion description","Comment"
- found_by = models.ForeignKey(LogbookEntry, related_name='QMs_found',blank=True, null=True )
- ticked_off_by = models.ForeignKey(LogbookEntry, related_name='QMs_ticked_off',null=True,blank=True)
- #cave = models.ForeignKey(Cave)
- #expedition = models.ForeignKey(Expedition)
-
- number = models.IntegerField(help_text="this is the sequential number in the year", )
- GRADE_CHOICES=(
- ('A', 'A: Large obvious lead'),
- ('B', 'B: Average lead'),
- ('C', 'C: Tight unpromising lead'),
- ('D', 'D: Dig'),
- ('X', 'X: Unclimbable aven')
- )
- grade = models.CharField(max_length=1, choices=GRADE_CHOICES)
- location_description = models.TextField(blank=True)
- #should be a foreignkey to surveystation
- nearest_station_description = models.CharField(max_length=400,null=True,blank=True)
- nearest_station = models.CharField(max_length=200,blank=True,null=True)
- area = models.CharField(max_length=100,blank=True,null=True)
- completion_description = models.TextField(blank=True,null=True)
- comment=models.TextField(blank=True,null=True)
-
- def __unicode__(self):
- return u"%s %s" % (self.code(), self.grade)
-
- def code(self):
- return u"%s-%s-%s" % (unicode(self.found_by.cave)[6:], self.found_by.date.year, self.number)
-
- def get_absolute_url(self):
- #return settings.URL_ROOT + '/cave/' + self.found_by.cave.kataster_number + '/' + str(self.found_by.date.year) + '-' + '%02d' %self.number
- return urlparse.urljoin(settings.URL_ROOT, reverse('qm',kwargs={'cave_id':self.found_by.cave.kataster_number,'year':self.found_by.date.year,'qm_id':self.number,'grade':self.grade}))
-
- def get_next_by_id(self):
- return QM.objects.get(id=self.id+1)
-
- def get_previous_by_id(self):
- return QM.objects.get(id=self.id-1)
-
- def wiki_link(self):
- return u"%s%s%s" % ('[[QM:',self.code(),']]')
-
-photoFileStorage = FileSystemStorage(location=settings.PHOTOS_ROOT, base_url=settings.PHOTOS_URL)
-class DPhoto(TroggleImageModel):
- caption = models.CharField(max_length=1000,blank=True,null=True)
- contains_logbookentry = models.ForeignKey(LogbookEntry,blank=True,null=True)
- contains_person = models.ManyToManyField(Person,blank=True,null=True)
- file = models.ImageField(storage=photoFileStorage, upload_to='.',)
- is_mugshot = models.BooleanField(default=False)
- contains_cave = models.ForeignKey(Cave,blank=True,null=True)
- contains_entrance = models.ForeignKey(Entrance, related_name="photo_file",blank=True,null=True)
- #nearest_survey_point = models.ForeignKey(SurveyStation,blank=True,null=True)
- nearest_QM = models.ForeignKey(QM,blank=True,null=True)
- lon_utm = models.FloatField(blank=True,null=True)
- lat_utm = models.FloatField(blank=True,null=True)
-
- class IKOptions:
- spec_module = 'core.imagekit_specs'
- cache_dir = 'thumbs'
- image_field = 'file'
-
- #content_type = models.ForeignKey(ContentType)
- #object_id = models.PositiveIntegerField()
- #location = generic.GenericForeignKey('content_type', 'object_id')
-
- def __unicode__(self):
- return self.caption
-
-scansFileStorage = FileSystemStorage(location=settings.SURVEY_SCANS, base_url=settings.SURVEYS_URL)
-def get_scan_path(instance, filename):
- year=instance.survey.expedition.year
- print "WN: ", type(instance.survey.wallet_number), instance.survey.wallet_number
- number="%02d" % instance.survey.wallet_number + str(instance.survey.wallet_letter) #using %02d string formatting because convention was 2009#01
- return os.path.join('./',year,year+r'#'+number,instance.contents+str(instance.number_in_wallet)+r'.jpg')
-
-class ScannedImage(TroggleImageModel):
- file = models.ImageField(storage=scansFileStorage, upload_to=get_scan_path)
- scanned_by = models.ForeignKey(Person,blank=True, null=True)
- scanned_on = models.DateField(null=True)
- survey = models.ForeignKey('Survey')
- contents = models.CharField(max_length=20,choices=(('notes','notes'),('plan','plan_sketch'),('elevation','elevation_sketch')))
- number_in_wallet = models.IntegerField(null=True)
- lon_utm = models.FloatField(blank=True,null=True)
- lat_utm = models.FloatField(blank=True,null=True)
-
- class IKOptions:
- spec_module = 'core.imagekit_specs'
- cache_dir = 'thumbs'
- image_field = 'file'
- #content_type = models.ForeignKey(ContentType)
- #object_id = models.PositiveIntegerField()
- #location = generic.GenericForeignKey('content_type', 'object_id')
-
- #This is an ugly hack to deal with the #s in our survey scan paths. The correct thing is to write a custom file storage backend which calls urlencode on the name for making file.url but not file.path.
- def correctURL(self):
- return string.replace(self.file.url,r'#',r'%23')
-
- def __unicode__(self):
- return get_scan_path(self,'')
-
-class Survey(TroggleModel):
- expedition = models.ForeignKey('Expedition') #REDUNDANT (logbook_entry)
- wallet_number = models.IntegerField(blank=True,null=True)
- wallet_letter = models.CharField(max_length=1,blank=True,null=True)
- comments = models.TextField(blank=True,null=True)
- location = models.CharField(max_length=400,blank=True,null=True) #REDUNDANT
- subcave = models.ForeignKey('NewSubCave', blank=True, null=True)
- #notes_scan = models.ForeignKey('ScannedImage',related_name='notes_scan',blank=True, null=True) #Replaced by contents field of ScannedImage model
- survex_block = models.OneToOneField('SurvexBlock',blank=True, null=True)
- logbook_entry = models.ForeignKey('LogbookEntry')
- centreline_printed_on = models.DateField(blank=True, null=True)
- centreline_printed_by = models.ForeignKey('Person',related_name='centreline_printed_by',blank=True,null=True)
- #sketch_scan = models.ForeignKey(ScannedImage,blank=True, null=True) #Replaced by contents field of ScannedImage model
- tunnel_file = models.FileField(upload_to='surveyXMLfiles',blank=True, null=True)
- tunnel_main_sketch = models.ForeignKey('Survey',blank=True,null=True)
- integrated_into_main_sketch_on = models.DateField(blank=True,null=True)
- integrated_into_main_sketch_by = models.ForeignKey('Person' ,related_name='integrated_into_main_sketch_by', blank=True,null=True)
- rendered_image = models.ImageField(upload_to='renderedSurveys',blank=True,null=True)
- def __unicode__(self):
- return self.expedition.year+"#"+"%02d" % int(self.wallet_number)
-
- def notes(self):
- return self.scannedimage_set.filter(contents='notes')
-
- def plans(self):
- return self.scannedimage_set.filter(contents='plan')
-
- def elevations(self):
- return self.scannedimage_set.filter(contents='elevation')
+import urllib, urlparse, string, os, datetime, logging, re
+from django.forms import ModelForm
+from django.db import models
+from django.contrib import admin
+from django.core.files.storage import FileSystemStorage
+from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
+from django.db.models import Min, Max
+from django.conf import settings
+from decimal import Decimal, getcontext
+from django.core.urlresolvers import reverse
+from imagekit.models import ImageModel
+getcontext().prec=2 #use 2 significant figures for decimal calculations
+
+from models_survex import *
+
+
+def get_related_by_wikilinks(wiki_text):
+ found=re.findall(settings.QM_PATTERN,wiki_text)
+ res=[]
+ for wikilink in found:
+ qmdict={'urlroot':settings.URL_ROOT,'cave':wikilink[2],'year':wikilink[1],'number':wikilink[3]}
+ try:
+ qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
+ found_by__date__year = qmdict['year'],
+ number = qmdict['number'])
+ res.append(qm)
+ except QM.DoesNotExist:
+ print 'fail on '+str(wikilink)
+
+ return res
+
+logging.basicConfig(level=logging.DEBUG,
+ filename=settings.LOGFILE,
+ filemode='w')
+
+#This class is for adding fields and methods which all of our models will have.
+class TroggleModel(models.Model):
+ new_since_parsing = models.BooleanField(default=False, editable=False)
+ non_public = models.BooleanField(default=False)
+ def object_name(self):
+ return self._meta.object_name
+
+ def get_admin_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk))
+
+ class Meta:
+ abstract = True
+
+class TroggleImageModel(ImageModel):
+ new_since_parsing = models.BooleanField(default=False, editable=False)
+
+ def object_name(self):
+ return self._meta.object_name
+
+ def get_admin_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk))
+
+
+ class Meta:
+ abstract = True
+
+#
+# single Expedition, usually seen by year
+#
+class Expedition(TroggleModel):
+ year = models.CharField(max_length=20, unique=True)
+ name = models.CharField(max_length=100)
+
+ def __unicode__(self):
+ return self.year
+
+ class Meta:
+ ordering = ('-year',)
+ get_latest_by = 'year'
+
+ def get_absolute_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, reverse('expedition', args=[self.year]))
+
+ # construction function. should be moved out
+ def get_expedition_day(self, date):
+ expeditiondays = self.expeditionday_set.filter(date=date)
+ if expeditiondays:
+ assert len(expeditiondays) == 1
+ return expeditiondays[0]
+ res = ExpeditionDay(expedition=self, date=date)
+ res.save()
+ return res
+
+ def day_min(self):
+ res = self.expeditionday_set.all()
+ return res and res[0] or None
+
+ def day_max(self):
+ res = self.expeditionday_set.all()
+ return res and res[len(res) - 1] or None
+
+
+
+class ExpeditionDay(TroggleModel):
+ expedition = models.ForeignKey("Expedition")
+ date = models.DateField()
+
+ class Meta:
+ ordering = ('date',)
+
+ def GetPersonTrip(self, personexpedition):
+ personexpeditions = self.persontrip_set.filter(expeditionday=self)
+ return personexpeditions and personexpeditions[0] or None
+
+
+#
+# single Person, can go on many years
+#
+class Person(TroggleModel):
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+ is_vfho = models.BooleanField(help_text="VFHO is the Vereines f&uuml;r H&ouml;hlenkunde in Obersteier, a nearby Austrian caving club.")
+ mug_shot = models.CharField(max_length=100, blank=True,null=True)
+ blurb = models.TextField(blank=True,null=True)
+
+ #href = models.CharField(max_length=200)
+ orderref = models.CharField(max_length=200) # for alphabetic
+
+ #the below have been removed and made methods. I'm not sure what the b in bisnotable stands for. - AC 16 Feb
+ #notability = models.FloatField() # for listing the top 20 people
+ #bisnotable = models.BooleanField()
+ user = models.OneToOneField(User, null=True, blank=True)
+ def get_absolute_url(self):
+ return urlparse.urljoin(settings.URL_ROOT,reverse('person',kwargs={'first_name':self.first_name,'last_name':self.last_name}))
+
+ class Meta:
+ verbose_name_plural = "People"
+ class Meta:
+ ordering = ('orderref',) # "Wookey" makes too complex for: ('last_name', 'first_name')
+
+ def __unicode__(self):
+ if self.last_name:
+ return "%s %s" % (self.first_name, self.last_name)
+ return self.first_name
+
+
+ def notability(self):
+ notability = Decimal(0)
+ for personexpedition in self.personexpedition_set.all():
+ if not personexpedition.is_guest:
+ notability += Decimal(1) / (2012 - int(personexpedition.expedition.year))
+ return notability
+
+ def bisnotable(self):
+ return self.notability() > Decimal(1)/Decimal(3)
+
+ def surveyedleglength(self):
+ return sum([personexpedition.surveyedleglength() for personexpedition in self.personexpedition_set.all()])
+
+ def first(self):
+ return self.personexpedition_set.order_by('-expedition')[0]
+ def last(self):
+ return self.personexpedition_set.order_by('expedition')[0]
+
+ #def Sethref(self):
+ #if self.last_name:
+ #self.href = self.first_name.lower() + "_" + self.last_name.lower()
+ #self.orderref = self.last_name + " " + self.first_name
+ #else:
+ # self.href = self.first_name.lower()
+ #self.orderref = self.first_name
+ #self.notability = 0.0 # set temporarily
+
+
+#
+# Person's attenance to one Expo
+#
+class PersonExpedition(TroggleModel):
+ expedition = models.ForeignKey(Expedition)
+ person = models.ForeignKey(Person)
+ slugfield = models.SlugField(max_length=50,blank=True,null=True)
+
+ is_guest = models.BooleanField(default=False)
+ COMMITTEE_CHOICES = (
+ ('leader','Expo leader'),
+ ('medical','Expo medical officer'),
+ ('treasurer','Expo treasurer'),
+ ('sponsorship','Expo sponsorship coordinator'),
+ ('research','Expo research coordinator'),
+ )
+ expo_committee_position = models.CharField(blank=True,null=True,choices=COMMITTEE_CHOICES,max_length=200)
+ nickname = models.CharField(max_length=100,blank=True,null=True)
+
+ def GetPersonroles(self):
+ res = [ ]
+ for personrole in self.personrole_set.order_by('survexblock'):
+ if res and res[-1]['survexpath'] == personrole.survexblock.survexpath:
+ res[-1]['roles'] += ", " + str(personrole.role)
+ else:
+ res.append({'date':personrole.survexblock.date, 'survexpath':personrole.survexblock.survexpath, 'roles':str(personrole.role)})
+ return res
+
+ class Meta:
+ ordering = ('-expedition',)
+ #order_with_respect_to = 'expedition'
+
+ def __unicode__(self):
+ return "%s: (%s)" % (self.person, self.expedition)
+
+
+ #why is the below a function in personexpedition, rather than in person? - AC 14 Feb 09
+ def name(self):
+ if self.nickname:
+ return "%s (%s) %s" % (self.person.first_name, self.nickname, self.person.last_name)
+ if self.person.last_name:
+ return "%s %s" % (self.person.first_name, self.person.last_name)
+ return self.person.first_name
+
+ def get_absolute_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, reverse('personexpedition',kwargs={'first_name':self.person.first_name,'last_name':self.person.last_name,'year':self.expedition.year}))
+
+ def surveyedleglength(self):
+ survexblocks = [personrole.survexblock for personrole in self.personrole_set.all() ]
+ return sum([survexblock.totalleglength for survexblock in set(survexblocks)])
+
+ # would prefer to return actual person trips so we could link to first and last ones
+ def day_min(self):
+ res = self.persontrip_set.aggregate(day_min=Min("expeditionday__date"))
+ return res["day_min"]
+
+ def day_max(self):
+ res = self.persontrip_set.all().aggregate(day_max=Max("expeditionday__date"))
+ return res["day_max"]
+
+#
+# Single parsed entry from Logbook
+#
+class LogbookEntry(TroggleModel):
+ date = models.DateField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.
+ expeditionday = models.ForeignKey("ExpeditionDay", null=True)#MJG wants to KILL THIS (redundant information)
+ expedition = models.ForeignKey(Expedition,blank=True,null=True) # yes this is double-
+ #author = models.ForeignKey(PersonExpedition,blank=True,null=True) # the person who writes it up doesn't have to have been on the trip.
+ # Re: the above- so this field should be "typist" or something, not "author". - AC 15 jun 09
+ #MJG wants to KILL THIS, as it is typically redundant with PersonTrip.is_logbook_entry_author, in the rare it was not redundanty and of actually interest it could be added to the text.
+ title = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
+ cave = models.ForeignKey('Cave',blank=True,null=True)
+ place = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
+ text = models.TextField()
+ slug = models.SlugField(max_length=50)
+ filename= models.CharField(max_length=200,null=True)
+
+ class Meta:
+ verbose_name_plural = "Logbook Entries"
+ # several PersonTrips point in to this object
+ ordering = ('-date',)
+
+ def isLogbookEntry(self): # Function used in templates
+ return True
+
+ def get_absolute_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug}))
+
+ def __unicode__(self):
+ return "%s: (%s)" % (self.date, self.title)
+
+ def get_next_by_id(self):
+ LogbookEntry.objects.get(id=self.id+1)
+
+ def get_previous_by_id(self):
+ LogbookEntry.objects.get(id=self.id-1)
+
+ def new_QM_number(self):
+ """Returns """
+ if self.cave:
+ nextQMnumber=self.cave.new_QM_number(self.date.year)
+ else:
+ return none
+ return nextQMnumber
+
+ def new_QM_found_link(self):
+ """Produces a link to a new QM with the next number filled in and this LogbookEntry set as 'found by' """
+ return settings.URL_ROOT + r'/admin/core/qm/add/?' + r'found_by=' + str(self.pk) +'&number=' + str(self.new_QM_number())
+
+ def DayIndex(self):
+ return list(self.expeditionday.logbookentry_set.all()).index(self)
+
+#
+# Single Person going on a trip, which may or may not be written up (accounts for different T/U for people in same logbook entry)
+#
+class PersonTrip(TroggleModel):
+ personexpedition = models.ForeignKey("PersonExpedition",null=True)
+
+ #expeditionday = models.ForeignKey("ExpeditionDay")#MJG wants to KILL THIS (redundant information)
+ #date = models.DateField() #MJG wants to KILL THIS (redundant information)
+ time_underground = models.FloatField(help_text="In decimal hours")
+ logbook_entry = models.ForeignKey(LogbookEntry)
+ is_logbook_entry_author = models.BooleanField()
+
+
+ # sequencing by person (difficult to solve locally)
+ #persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)#MJG wants to KILL THIS (and use funstion persontrip_next_auto)
+ #persontrip_prev = models.ForeignKey('PersonTrip', related_name='pprev', blank=True,null=True)#MJG wants to KILL THIS(and use funstion persontrip_prev_auto)
+
+ def persontrip_next(self):
+ futurePTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__gt = self.logbook_entry.date).order_by('logbook_entry__date').all()
+ if len(futurePTs) > 0:
+ return futurePTs[0]
+ else:
+ return None
+
+ def persontrip_prev(self):
+ pastPTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__lt = self.logbook_entry.date).order_by('-logbook_entry__date').all()
+ if len(pastPTs) > 0:
+ return pastPTs[0]
+ else:
+ return None
+
+ def place(self):
+ return self.logbook_entry.cave and self.logbook_entry.cave or self.logbook_entry.place
+
+ def __unicode__(self):
+ return "%s (%s)" % (self.personexpedition, self.logbook_entry.date)
+
+
+
+##########################################
+# move following classes into models_cave
+##########################################
+
+class Area(TroggleModel):
+ short_name = models.CharField(max_length=100)
+ name = models.CharField(max_length=200, blank=True, null=True)
+ description = models.TextField(blank=True,null=True)
+ parent = models.ForeignKey('Area', blank=True, null=True)
+ def __unicode__(self):
+ if self.parent:
+ return unicode(self.parent) + u" - " + unicode(self.short_name)
+ else:
+ return unicode(self.short_name)
+ def kat_area(self):
+ if self.short_name in ["1623", "1626"]:
+ return self.short_name
+ elif self.parent:
+ return self.parent.kat_area()
+
+class CaveAndEntrance(TroggleModel):
+ cave = models.ForeignKey('Cave')
+ entrance = models.ForeignKey('Entrance')
+ entrance_letter = models.CharField(max_length=20,blank=True,null=True)
+ def __unicode__(self):
+ return unicode(self.cave) + unicode(self.entrance_letter)
+
+class Cave(TroggleModel):
+ # too much here perhaps
+ slug = models.SlugField(max_length=50, unique = True)
+ official_name = models.CharField(max_length=160)
+ area = models.ManyToManyField(Area, blank=True, null=True)
+ kataster_code = models.CharField(max_length=20,blank=True,null=True)
+ kataster_number = models.CharField(max_length=10,blank=True, null=True)
+ unofficial_number = models.CharField(max_length=60,blank=True, null=True)
+ entrances = models.ManyToManyField('Entrance', through='CaveAndEntrance')
+ explorers = models.TextField(blank=True,null=True)
+ underground_description = models.TextField(blank=True,null=True)
+ equipment = models.TextField(blank=True,null=True)
+ references = models.TextField(blank=True,null=True)
+ survey = models.TextField(blank=True,null=True)
+ kataster_status = models.TextField(blank=True,null=True)
+ underground_centre_line = models.TextField(blank=True,null=True)
+ notes = models.TextField(blank=True,null=True)
+ length = models.CharField(max_length=100,blank=True,null=True)
+ depth = models.CharField(max_length=100,blank=True,null=True)
+ extent = models.CharField(max_length=100,blank=True,null=True)
+ survex_file = models.CharField(max_length=100,blank=True,null=True)
+ description_file = models.CharField(max_length=200,blank=True,null=True)
+ url = models.CharField(max_length=200,blank=True,null=True)
+
+ #class Meta:
+ # unique_together = (("area", "kataster_number"), ("area", "unofficial_number"))
+ # FIXME Kataster Areas and CUCC defined sub areas need seperating
+
+
+ #href = models.CharField(max_length=100)
+
+ def reference(self):
+ if self.kataster_number:
+ return "%s-%s" % (self.kat_area(), self.kataster_number)
+ else:
+ return "%s-%s" % (self.kat_area(), self.unofficial_number)
+
+ def get_absolute_url(self):
+ if self.kataster_number:
+ href = self.kataster_number
+ elif self.unofficial_number:
+ href = self.unofficial_number
+ else:
+ href = official_name.lower()
+ #return settings.URL_ROOT + '/cave/' + href + '/'
+ return urlparse.urljoin(settings.URL_ROOT, reverse('cave',kwargs={'cave_id':href,}))
+
+ def __unicode__(self):
+ if self.kataster_number:
+ if self.kat_area():
+ return self.kat_area() + u": " + self.kataster_number
+ else:
+ return unicode("l") + u": " + self.kataster_number
+ else:
+ if self.kat_area():
+ return self.kat_area() + u": " + self.unofficial_number
+ else:
+ return self.unofficial_number
+
+ def get_QMs(self):
+ return QM.objects.filter(found_by__cave=self)
+
+ def new_QM_number(self, year=datetime.date.today().year):
+ """Given a cave and the current year, returns the next QM number."""
+ try:
+ res=QM.objects.filter(found_by__date__year=year, found_by__cave=self).order_by('-number')[0]
+ except IndexError:
+ return 1
+ return res.number+1
+
+ def kat_area(self):
+ for a in self.area.all():
+ if a.kat_area():
+ return a.kat_area()
+
+ def entrances(self):
+ return CaveAndEntrance.objects.filter(cave=self)
+
+ def entrancelist(self):
+ rs = []
+ res = ""
+ for e in CaveAndEntrance.objects.filter(cave=self):
+ rs.append(e.entrance_letter)
+ rs.sort()
+ prevR = None
+ n = 0
+ for r in rs:
+ if prevR:
+ if chr(ord(prevR) + 1 ) == r:
+ prevR = r
+ n += 1
+ else:
+ if n == 0:
+ res += ", " + prevR
+ else:
+ res += "&ndash;" + prevR
+ else:
+ prevR = r
+ n = 0
+ res += r
+ if n == 0:
+ res += ", " + prevR
+ else:
+ res += "&ndash;" + prevR
+ return res
+
+def getCaveByReference(reference):
+ areaname, code = reference.split("-", 1)
+ print areaname, code
+ area = Area.objects.get(short_name = areaname)
+ print area
+ foundCaves = list(Cave.objects.filter(area = area, kataster_number = code).all()) + list(Cave.objects.filter(area = area, unofficial_number = code).all())
+ print list(foundCaves)
+ assert len(foundCaves) == 1
+ return foundCaves[0]
+
+class OtherCaveName(TroggleModel):
+ name = models.CharField(max_length=160)
+ cave = models.ForeignKey(Cave)
+ def __unicode__(self):
+ return unicode(self.name)
+
+
+class Entrance(TroggleModel):
+ slug = models.SlugField(max_length=50, unique = True)
+ name = models.CharField(max_length=100, blank=True,null=True)
+ entrance_description = models.TextField(blank=True,null=True)
+ explorers = models.TextField(blank=True,null=True)
+ map_description = models.TextField(blank=True,null=True)
+ location_description = models.TextField(blank=True,null=True)
+ approach = models.TextField(blank=True,null=True)
+ underground_description = models.TextField(blank=True,null=True)
+ photo = models.TextField(blank=True,null=True)
+ MARKING_CHOICES = (
+ ('P', 'Paint'),
+ ('P?', 'Paint (?)'),
+ ('T', 'Tag'),
+ ('T?', 'Tag (?)'),
+ ('R', 'Retagged'),
+ ('S', 'Spit'),
+ ('S?', 'Spit (?)'),
+ ('U', 'Unmarked'),
+ ('?', 'Unknown'))
+ marking = models.CharField(max_length=2, choices=MARKING_CHOICES)
+ marking_comment = models.TextField(blank=True,null=True)
+ FINDABLE_CHOICES = (
+ ('?', 'To be confirmed ...'),
+ ('S', 'Surveyed'),
+ ('L', 'Lost'),
+ ('R', 'Refindable'))
+ findability = models.CharField(max_length=1, choices=FINDABLE_CHOICES, blank=True, null=True)
+ findability_description = models.TextField(blank=True,null=True)
+ alt = models.TextField(blank=True, null=True)
+ northing = models.TextField(blank=True, null=True)
+ easting = models.TextField(blank=True, null=True)
+ tag_station = models.TextField()
+ exact_station = models.TextField()
+ other_station = models.TextField()
+ other_description = models.TextField(blank=True,null=True)
+ bearings = models.TextField(blank=True,null=True)
+ def __unicode__(self):
+ a = CaveAndEntrance.objects.filter(entrance = self)
+ name = u''
+ if self.name:
+ name = unicode(self.name) + u' '
+ if len(a) == 1:
+ return name + unicode(a[0])
+ return name + unicode(a)
+ def marking_val(self):
+ for m in self.MARKING_CHOICES:
+ if m[0] == self.marking:
+ return m[1]
+ def findability_val(self):
+ for f in self.FINDABLE_CHOICES:
+ if f[0] == self.findability:
+ return f[1]
+
+
+ def get_absolute_url(self):
+
+ ancestor_titles='/'.join([subcave.title for subcave in self.get_ancestors()])
+ if ancestor_titles:
+ res = '/'.join((self.get_root().cave.get_absolute_url(), ancestor_titles, self.title))
+
+ else:
+ res = '/'.join((self.get_root().cave.get_absolute_url(), self.title))
+
+ return res
+
+class CaveDescription(TroggleModel):
+ short_name = models.CharField(max_length=50, unique = True)
+ long_name = models.CharField(max_length=200, blank=True, null=True)
+ description = models.TextField(blank=True,null=True)
+ linked_subcaves = models.ManyToManyField("NewSubCave", blank=True,null=True)
+ linked_entrances = models.ManyToManyField("Entrance", blank=True,null=True)
+ linked_qms = models.ManyToManyField("QM", blank=True,null=True)
+
+ def __unicode__(self):
+ if self.long_name:
+ return unicode(self.long_name)
+ else:
+ return unicode(self.short_name)
+
+ def get_absolute_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, reverse('cavedescription', args=(self.short_name,)))
+
+ def save(self):
+ """
+ Overridden save method which stores wikilinks in text as links in database.
+ """
+ super(CaveDescription, self).save()
+ qm_list=get_related_by_wikilinks(self.description)
+ for qm in qm_list:
+ self.linked_qms.add(qm)
+ super(CaveDescription, self).save()
+
+class NewSubCave(TroggleModel):
+ name = models.CharField(max_length=200, unique = True)
+ def __unicode__(self):
+ return unicode(self.name)
+
+class QM(TroggleModel):
+ #based on qm.csv in trunk/expoweb/smkridge/204 which has the fields:
+ #"Number","Grade","Area","Description","Page reference","Nearest station","Completion description","Comment"
+ found_by = models.ForeignKey(LogbookEntry, related_name='QMs_found',blank=True, null=True )
+ ticked_off_by = models.ForeignKey(LogbookEntry, related_name='QMs_ticked_off',null=True,blank=True)
+ #cave = models.ForeignKey(Cave)
+ #expedition = models.ForeignKey(Expedition)
+
+ number = models.IntegerField(help_text="this is the sequential number in the year", )
+ GRADE_CHOICES=(
+ ('A', 'A: Large obvious lead'),
+ ('B', 'B: Average lead'),
+ ('C', 'C: Tight unpromising lead'),
+ ('D', 'D: Dig'),
+ ('X', 'X: Unclimbable aven')
+ )
+ grade = models.CharField(max_length=1, choices=GRADE_CHOICES)
+ location_description = models.TextField(blank=True)
+ #should be a foreignkey to surveystation
+ nearest_station_description = models.CharField(max_length=400,null=True,blank=True)
+ nearest_station = models.CharField(max_length=200,blank=True,null=True)
+ area = models.CharField(max_length=100,blank=True,null=True)
+ completion_description = models.TextField(blank=True,null=True)
+ comment=models.TextField(blank=True,null=True)
+
+ def __unicode__(self):
+ return u"%s %s" % (self.code(), self.grade)
+
+ def code(self):
+ return u"%s-%s-%s" % (unicode(self.found_by.cave)[6:], self.found_by.date.year, self.number)
+
+ def get_absolute_url(self):
+ #return settings.URL_ROOT + '/cave/' + self.found_by.cave.kataster_number + '/' + str(self.found_by.date.year) + '-' + '%02d' %self.number
+ return urlparse.urljoin(settings.URL_ROOT, reverse('qm',kwargs={'cave_id':self.found_by.cave.kataster_number,'year':self.found_by.date.year,'qm_id':self.number,'grade':self.grade}))
+
+ def get_next_by_id(self):
+ return QM.objects.get(id=self.id+1)
+
+ def get_previous_by_id(self):
+ return QM.objects.get(id=self.id-1)
+
+ def wiki_link(self):
+ return u"%s%s%s" % ('[[QM:',self.code(),']]')
+
+photoFileStorage = FileSystemStorage(location=settings.PHOTOS_ROOT, base_url=settings.PHOTOS_URL)
+class DPhoto(TroggleImageModel):
+ caption = models.CharField(max_length=1000,blank=True,null=True)
+ contains_logbookentry = models.ForeignKey(LogbookEntry,blank=True,null=True)
+ contains_person = models.ManyToManyField(Person,blank=True,null=True)
+ file = models.ImageField(storage=photoFileStorage, upload_to='.',)
+ is_mugshot = models.BooleanField(default=False)
+ contains_cave = models.ForeignKey(Cave,blank=True,null=True)
+ contains_entrance = models.ForeignKey(Entrance, related_name="photo_file",blank=True,null=True)
+ #nearest_survey_point = models.ForeignKey(SurveyStation,blank=True,null=True)
+ nearest_QM = models.ForeignKey(QM,blank=True,null=True)
+ lon_utm = models.FloatField(blank=True,null=True)
+ lat_utm = models.FloatField(blank=True,null=True)
+
+ class IKOptions:
+ spec_module = 'core.imagekit_specs'
+ cache_dir = 'thumbs'
+ image_field = 'file'
+
+ #content_type = models.ForeignKey(ContentType)
+ #object_id = models.PositiveIntegerField()
+ #location = generic.GenericForeignKey('content_type', 'object_id')
+
+ def __unicode__(self):
+ return self.caption
+
+scansFileStorage = FileSystemStorage(location=settings.SURVEY_SCANS, base_url=settings.SURVEYS_URL)
+def get_scan_path(instance, filename):
+ year=instance.survey.expedition.year
+ print "WN: ", type(instance.survey.wallet_number), instance.survey.wallet_number
+ number="%02d" % instance.survey.wallet_number + str(instance.survey.wallet_letter) #using %02d string formatting because convention was 2009#01
+ return os.path.join('./',year,year+r'#'+number,instance.contents+str(instance.number_in_wallet)+r'.jpg')
+
+class ScannedImage(TroggleImageModel):
+ file = models.ImageField(storage=scansFileStorage, upload_to=get_scan_path)
+ scanned_by = models.ForeignKey(Person,blank=True, null=True)
+ scanned_on = models.DateField(null=True)
+ survey = models.ForeignKey('Survey')
+ contents = models.CharField(max_length=20,choices=(('notes','notes'),('plan','plan_sketch'),('elevation','elevation_sketch')))
+ number_in_wallet = models.IntegerField(null=True)
+ lon_utm = models.FloatField(blank=True,null=True)
+ lat_utm = models.FloatField(blank=True,null=True)
+
+ class IKOptions:
+ spec_module = 'core.imagekit_specs'
+ cache_dir = 'thumbs'
+ image_field = 'file'
+ #content_type = models.ForeignKey(ContentType)
+ #object_id = models.PositiveIntegerField()
+ #location = generic.GenericForeignKey('content_type', 'object_id')
+
+ #This is an ugly hack to deal with the #s in our survey scan paths. The correct thing is to write a custom file storage backend which calls urlencode on the name for making file.url but not file.path.
+ def correctURL(self):
+ return string.replace(self.file.url,r'#',r'%23')
+
+ def __unicode__(self):
+ return get_scan_path(self,'')
+
+class Survey(TroggleModel):
+ expedition = models.ForeignKey('Expedition') #REDUNDANT (logbook_entry)
+ wallet_number = models.IntegerField(blank=True,null=True)
+ wallet_letter = models.CharField(max_length=1,blank=True,null=True)
+ comments = models.TextField(blank=True,null=True)
+ location = models.CharField(max_length=400,blank=True,null=True) #REDUNDANT
+ subcave = models.ForeignKey('NewSubCave', blank=True, null=True)
+ #notes_scan = models.ForeignKey('ScannedImage',related_name='notes_scan',blank=True, null=True) #Replaced by contents field of ScannedImage model
+ survex_block = models.OneToOneField('SurvexBlock',blank=True, null=True)
+ logbook_entry = models.ForeignKey('LogbookEntry')
+ centreline_printed_on = models.DateField(blank=True, null=True)
+ centreline_printed_by = models.ForeignKey('Person',related_name='centreline_printed_by',blank=True,null=True)
+ #sketch_scan = models.ForeignKey(ScannedImage,blank=True, null=True) #Replaced by contents field of ScannedImage model
+ tunnel_file = models.FileField(upload_to='surveyXMLfiles',blank=True, null=True)
+ tunnel_main_sketch = models.ForeignKey('Survey',blank=True,null=True)
+ integrated_into_main_sketch_on = models.DateField(blank=True,null=True)
+ integrated_into_main_sketch_by = models.ForeignKey('Person' ,related_name='integrated_into_main_sketch_by', blank=True,null=True)
+ rendered_image = models.ImageField(upload_to='renderedSurveys',blank=True,null=True)
+ def __unicode__(self):
+ return self.expedition.year+"#"+"%02d" % int(self.wallet_number)
+
+ def notes(self):
+ return self.scannedimage_set.filter(contents='notes')
+
+ def plans(self):
+ return self.scannedimage_set.filter(contents='plan')
+
+ def elevations(self):
+ return self.scannedimage_set.filter(contents='elevation')
diff --git a/core/models_survex.py b/core/models_survex.py
index efd3022..1bf75ef 100644
--- a/core/models_survex.py
+++ b/core/models_survex.py
@@ -1,213 +1,213 @@
-from django.db import models
-from django.conf import settings
-import os
-import urlparse
-import re
-from django.core.urlresolvers import reverse
-
-
-###########################################################
-# These will allow browsing and editing of the survex data
-###########################################################
-# Needs to add:
-# Equates
-# reloading
-
-class SurvexDirectory(models.Model):
- path = models.CharField(max_length=200)
- cave = models.ForeignKey('Cave', blank=True, null=True)
- primarysurvexfile = models.ForeignKey('SurvexFile', related_name='primarysurvexfile', blank=True, null=True)
- # could also include files in directory but not referenced
-
- class Meta:
- ordering = ('id',)
-
-class SurvexFile(models.Model):
- path = models.CharField(max_length=200)
- survexdirectory = models.ForeignKey("SurvexDirectory", blank=True, null=True)
- cave = models.ForeignKey('Cave', blank=True, null=True)
-
- class Meta:
- ordering = ('id',)
-
- def exists(self):
- fname = os.path.join(settings.SURVEX_DATA, self.path + ".svx")
- return os.path.isfile(fname)
-
- def OpenFile(self):
- fname = os.path.join(settings.SURVEX_DATA, self.path + ".svx")
- return open(fname)
-
- def SetDirectory(self):
- dirpath = os.path.split(self.path)[0]
- survexdirectorylist = SurvexDirectory.objects.filter(cave=self.cave, path=dirpath)
- if survexdirectorylist:
- self.survexdirectory = survexdirectorylist[0]
- else:
- survexdirectory = SurvexDirectory(path=dirpath, cave=self.cave, primarysurvexfile=self)
- survexdirectory.save()
- self.survexdirectory = survexdirectory
- self.save()
-
-class SurvexEquate(models.Model):
- cave = models.ForeignKey('Cave', blank=True, null=True)
-
-class SurvexStationLookUpManager(models.Manager):
- def lookup(self, name):
- blocknames, sep, stationname = name.rpartition(".")
- return self.get(block = SurvexBlock.objects.lookup(blocknames),
- name = stationname)
-
-class SurvexStation(models.Model):
- name = models.CharField(max_length=20)
- block = models.ForeignKey('SurvexBlock')
- equate = models.ForeignKey('SurvexEquate', blank=True, null=True)
- objects = SurvexStationLookUpManager()
- x = models.FloatField(blank=True, null=True)
- y = models.FloatField(blank=True, null=True)
- z = models.FloatField(blank=True, null=True)
-
-class SurvexLeg(models.Model):
- block = models.ForeignKey('SurvexBlock')
- #title = models.ForeignKey('SurvexTitle')
- stationfrom = models.ForeignKey('SurvexStation', related_name='stationfrom')
- stationto = models.ForeignKey('SurvexStation', related_name='stationto')
- tape = models.FloatField()
- compass = models.FloatField()
- clino = models.FloatField()
-
-
-#
-# Single SurvexBlock
-#
-class SurvexBlockLookUpManager(models.Manager):
- def lookup(self, name):
- blocknames = name.split(".")
- block = SurvexBlock.objects.get(parent=None, survexfile__path="all")
- for blockname in blocknames:
- block = SurvexBlock.objects.get(parent=block, name=blockname)
- return block
-
-class SurvexBlock(models.Model):
- objects = SurvexBlockLookUpManager()
- name = models.CharField(max_length=100)
- parent = models.ForeignKey('SurvexBlock', blank=True, null=True)
- text = models.TextField()
- cave = models.ForeignKey('Cave', blank=True, null=True)
-
- date = models.DateField(blank=True, null=True)
- expeditionday = models.ForeignKey("ExpeditionDay", null=True)
- expedition = models.ForeignKey('Expedition', blank=True, null=True)
-
- survexfile = models.ForeignKey("SurvexFile", blank=True, null=True)
- begin_char = models.IntegerField() # code for where in the survex data files this block sits
- survexpath = models.CharField(max_length=200) # the path for the survex stations
-
- survexscansfolder = models.ForeignKey("SurvexScansFolder", null=True)
- #refscandir = models.CharField(max_length=100)
-
- totalleglength = models.FloatField()
-
- class Meta:
- ordering = ('id',)
-
- def isSurvexBlock(self): # Function used in templates
- return True
-
- def __unicode__(self):
- return self.name and unicode(self.name) or 'no name'
-
- def GetPersonroles(self):
- res = [ ]
- for personrole in self.personrole_set.order_by('personexpedition'):
- if res and res[-1]['person'] == personrole.personexpedition.person:
- res[-1]['roles'] += ", " + str(personrole.role)
- else:
- res.append({'person':personrole.personexpedition.person, 'expeditionyear':personrole.personexpedition.expedition.year, 'roles':str(personrole.role)})
- return res
-
- def MakeSurvexStation(self, name):
- ssl = self.survexstation_set.filter(name=name)
- if ssl:
- assert len(ssl) == 1
- return ssl[0]
- ss = SurvexStation(name=name, block=self)
- ss.save()
- return ss
-
- def DayIndex(self):
- return list(self.expeditionday.survexblock_set.all()).index(self)
-
-
-class SurvexTitle(models.Model):
- survexblock = models.ForeignKey('SurvexBlock')
- title = models.CharField(max_length=200)
- cave = models.ForeignKey('Cave', blank=True, null=True)
-
-#
-# member of a SurvexBlock
-#
-ROLE_CHOICES = (
- ('insts','Instruments'),
- ('dog','Other'),
- ('notes','Notes'),
- ('pics','Pictures'),
- ('tape','Tape measure'),
- ('useless','Useless'),
- ('helper','Helper'),
- ('disto','Disto'),
- ('consultant','Consultant'),
- )
-
-class SurvexPersonRole(models.Model):
- survexblock = models.ForeignKey('SurvexBlock')
- nrole = models.CharField(choices=ROLE_CHOICES, max_length=200, blank=True, null=True)
- # increasing levels of precision
- personname = models.CharField(max_length=100)
- person = models.ForeignKey('Person', blank=True, null=True)
- personexpedition = models.ForeignKey('PersonExpedition', blank=True, null=True)
- persontrip = models.ForeignKey('PersonTrip', blank=True, null=True)
- expeditionday = models.ForeignKey("ExpeditionDay", null=True)
-
- def __unicode__(self):
- return unicode(self.person) + " - " + unicode(self.survexblock) + " - " + unicode(self.nrole)
-
-
-class SurvexScansFolder(models.Model):
- fpath = models.CharField(max_length=200)
- walletname = models.CharField(max_length=200)
-
- class Meta:
- ordering = ('walletname',)
-
- def get_absolute_url(self):
- return urlparse.urljoin(settings.URL_ROOT, reverse('surveyscansfolder', kwargs={"path":re.sub("#", "%23", self.walletname)}))
-
-class SurvexScanSingle(models.Model):
- ffile = models.CharField(max_length=200)
- name = models.CharField(max_length=200)
- survexscansfolder = models.ForeignKey("SurvexScansFolder", null=True)
-
- class Meta:
- ordering = ('name',)
-
- def get_absolute_url(self):
- return urlparse.urljoin(settings.URL_ROOT, reverse('surveyscansingle', kwargs={"path":re.sub("#", "%23", self.survexscansfolder.walletname), "file":self.name}))
-
-
-class TunnelFile(models.Model):
- tunnelpath = models.CharField(max_length=200)
- tunnelname = models.CharField(max_length=200)
- bfontcolours = models.BooleanField()
- survexscansfolders = models.ManyToManyField("SurvexScansFolder")
- survexscans = models.ManyToManyField("SurvexScanSingle")
- survexblocks = models.ManyToManyField("SurvexBlock")
- tunnelcontains = models.ManyToManyField("TunnelFile") # case when its a frame type
- filesize = models.IntegerField(default=0)
- npaths = models.IntegerField(default=0)
- survextitles = models.ManyToManyField("SurvexTitle")
-
-
- class Meta:
- ordering = ('tunnelpath',)
-
+from django.db import models
+from django.conf import settings
+import os
+import urlparse
+import re
+from django.core.urlresolvers import reverse
+
+
+###########################################################
+# These will allow browsing and editing of the survex data
+###########################################################
+# Needs to add:
+# Equates
+# reloading
+
+class SurvexDirectory(models.Model):
+ path = models.CharField(max_length=200)
+ cave = models.ForeignKey('Cave', blank=True, null=True)
+ primarysurvexfile = models.ForeignKey('SurvexFile', related_name='primarysurvexfile', blank=True, null=True)
+ # could also include files in directory but not referenced
+
+ class Meta:
+ ordering = ('id',)
+
+class SurvexFile(models.Model):
+ path = models.CharField(max_length=200)
+ survexdirectory = models.ForeignKey("SurvexDirectory", blank=True, null=True)
+ cave = models.ForeignKey('Cave', blank=True, null=True)
+
+ class Meta:
+ ordering = ('id',)
+
+ def exists(self):
+ fname = os.path.join(settings.SURVEX_DATA, self.path + ".svx")
+ return os.path.isfile(fname)
+
+ def OpenFile(self):
+ fname = os.path.join(settings.SURVEX_DATA, self.path + ".svx")
+ return open(fname)
+
+ def SetDirectory(self):
+ dirpath = os.path.split(self.path)[0]
+ survexdirectorylist = SurvexDirectory.objects.filter(cave=self.cave, path=dirpath)
+ if survexdirectorylist:
+ self.survexdirectory = survexdirectorylist[0]
+ else:
+ survexdirectory = SurvexDirectory(path=dirpath, cave=self.cave, primarysurvexfile=self)
+ survexdirectory.save()
+ self.survexdirectory = survexdirectory
+ self.save()
+
+class SurvexEquate(models.Model):
+ cave = models.ForeignKey('Cave', blank=True, null=True)
+
+class SurvexStationLookUpManager(models.Manager):
+ def lookup(self, name):
+ blocknames, sep, stationname = name.rpartition(".")
+ return self.get(block = SurvexBlock.objects.lookup(blocknames),
+ name = stationname)
+
+class SurvexStation(models.Model):
+ name = models.CharField(max_length=20)
+ block = models.ForeignKey('SurvexBlock')
+ equate = models.ForeignKey('SurvexEquate', blank=True, null=True)
+ objects = SurvexStationLookUpManager()
+ x = models.FloatField(blank=True, null=True)
+ y = models.FloatField(blank=True, null=True)
+ z = models.FloatField(blank=True, null=True)
+
+class SurvexLeg(models.Model):
+ block = models.ForeignKey('SurvexBlock')
+ #title = models.ForeignKey('SurvexTitle')
+ stationfrom = models.ForeignKey('SurvexStation', related_name='stationfrom')
+ stationto = models.ForeignKey('SurvexStation', related_name='stationto')
+ tape = models.FloatField()
+ compass = models.FloatField()
+ clino = models.FloatField()
+
+
+#
+# Single SurvexBlock
+#
+class SurvexBlockLookUpManager(models.Manager):
+ def lookup(self, name):
+ blocknames = name.split(".")
+ block = SurvexBlock.objects.get(parent=None, survexfile__path="all")
+ for blockname in blocknames:
+ block = SurvexBlock.objects.get(parent=block, name=blockname)
+ return block
+
+class SurvexBlock(models.Model):
+ objects = SurvexBlockLookUpManager()
+ name = models.CharField(max_length=100)
+ parent = models.ForeignKey('SurvexBlock', blank=True, null=True)
+ text = models.TextField()
+ cave = models.ForeignKey('Cave', blank=True, null=True)
+
+ date = models.DateField(blank=True, null=True)
+ expeditionday = models.ForeignKey("ExpeditionDay", null=True)
+ expedition = models.ForeignKey('Expedition', blank=True, null=True)
+
+ survexfile = models.ForeignKey("SurvexFile", blank=True, null=True)
+ begin_char = models.IntegerField() # code for where in the survex data files this block sits
+ survexpath = models.CharField(max_length=200) # the path for the survex stations
+
+ survexscansfolder = models.ForeignKey("SurvexScansFolder", null=True)
+ #refscandir = models.CharField(max_length=100)
+
+ totalleglength = models.FloatField()
+
+ class Meta:
+ ordering = ('id',)
+
+ def isSurvexBlock(self): # Function used in templates
+ return True
+
+ def __unicode__(self):
+ return self.name and unicode(self.name) or 'no name'
+
+ def GetPersonroles(self):
+ res = [ ]
+ for personrole in self.personrole_set.order_by('personexpedition'):
+ if res and res[-1]['person'] == personrole.personexpedition.person:
+ res[-1]['roles'] += ", " + str(personrole.role)
+ else:
+ res.append({'person':personrole.personexpedition.person, 'expeditionyear':personrole.personexpedition.expedition.year, 'roles':str(personrole.role)})
+ return res
+
+ def MakeSurvexStation(self, name):
+ ssl = self.survexstation_set.filter(name=name)
+ if ssl:
+ assert len(ssl) == 1
+ return ssl[0]
+ ss = SurvexStation(name=name, block=self)
+ ss.save()
+ return ss
+
+ def DayIndex(self):
+ return list(self.expeditionday.survexblock_set.all()).index(self)
+
+
+class SurvexTitle(models.Model):
+ survexblock = models.ForeignKey('SurvexBlock')
+ title = models.CharField(max_length=200)
+ cave = models.ForeignKey('Cave', blank=True, null=True)
+
+#
+# member of a SurvexBlock
+#
+ROLE_CHOICES = (
+ ('insts','Instruments'),
+ ('dog','Other'),
+ ('notes','Notes'),
+ ('pics','Pictures'),
+ ('tape','Tape measure'),
+ ('useless','Useless'),
+ ('helper','Helper'),
+ ('disto','Disto'),
+ ('consultant','Consultant'),
+ )
+
+class SurvexPersonRole(models.Model):
+ survexblock = models.ForeignKey('SurvexBlock')
+ nrole = models.CharField(choices=ROLE_CHOICES, max_length=200, blank=True, null=True)
+ # increasing levels of precision
+ personname = models.CharField(max_length=100)
+ person = models.ForeignKey('Person', blank=True, null=True)
+ personexpedition = models.ForeignKey('PersonExpedition', blank=True, null=True)
+ persontrip = models.ForeignKey('PersonTrip', blank=True, null=True)
+ expeditionday = models.ForeignKey("ExpeditionDay", null=True)
+
+ def __unicode__(self):
+ return unicode(self.person) + " - " + unicode(self.survexblock) + " - " + unicode(self.nrole)
+
+
+class SurvexScansFolder(models.Model):
+ fpath = models.CharField(max_length=200)
+ walletname = models.CharField(max_length=200)
+
+ class Meta:
+ ordering = ('walletname',)
+
+ def get_absolute_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, reverse('surveyscansfolder', kwargs={"path":re.sub("#", "%23", self.walletname)}))
+
+class SurvexScanSingle(models.Model):
+ ffile = models.CharField(max_length=200)
+ name = models.CharField(max_length=200)
+ survexscansfolder = models.ForeignKey("SurvexScansFolder", null=True)
+
+ class Meta:
+ ordering = ('name',)
+
+ def get_absolute_url(self):
+ return urlparse.urljoin(settings.URL_ROOT, reverse('surveyscansingle', kwargs={"path":re.sub("#", "%23", self.survexscansfolder.walletname), "file":self.name}))
+
+
+class TunnelFile(models.Model):
+ tunnelpath = models.CharField(max_length=200)
+ tunnelname = models.CharField(max_length=200)
+ bfontcolours = models.BooleanField()
+ survexscansfolders = models.ManyToManyField("SurvexScansFolder")
+ survexscans = models.ManyToManyField("SurvexScanSingle")
+ survexblocks = models.ManyToManyField("SurvexBlock")
+ tunnelcontains = models.ManyToManyField("TunnelFile") # case when its a frame type
+ filesize = models.IntegerField(default=0)
+ npaths = models.IntegerField(default=0)
+ survextitles = models.ManyToManyField("SurvexTitle")
+
+
+ class Meta:
+ ordering = ('tunnelpath',)
+
diff --git a/core/templatetags/link.py b/core/templatetags/link.py
index 63e2dac..cb861ad 100644
--- a/core/templatetags/link.py
+++ b/core/templatetags/link.py
@@ -1,9 +1,9 @@
-from django import template
-from django.utils.safestring import mark_safe
-
-register = template.Library()
-
-@register.filter()
-def link(value):
- return mark_safe("<a href=\'%s\'>"%value.get_absolute_url()+unicode(value)+"</a>")
-
+from django import template
+from django.utils.safestring import mark_safe
+
+register = template.Library()
+
+@register.filter()
+def link(value):
+ return mark_safe("<a href=\'%s\'>"%value.get_absolute_url()+unicode(value)+"</a>")
+
diff --git a/core/templatetags/survex_markup.py b/core/templatetags/survex_markup.py
index 464a04b..5b9aa36 100644
--- a/core/templatetags/survex_markup.py
+++ b/core/templatetags/survex_markup.py
@@ -1,52 +1,52 @@
-from django import template
-from django.utils.html import conditional_escape
-from django.template.defaultfilters import stringfilter
-from django.utils.safestring import mark_safe
-import re
-
-register = template.Library()
-
-# seems to add extra lines between the commented lines, which isn't so great.
-regexes = []
-regexes.append((re.compile(r"(;.*)$", re.IGNORECASE|re.MULTILINE),
- r'<span class = "comment">\1</span>\n'))
-regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)(.svx)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3<a href="\4.index">\4\5</a>'))
-regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3<a href="\4.index">\4</a>'))
-regexes.append((re.compile(r"^(\s*)(\*team\s+(?:notes|tape|insts|pics))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*(?:begin|end|copyright|date|entrance|equate|export|fix|prefix|require|SOLVE|title|truncate))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*calibrate\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|X|Y|Z)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*data\s+(?:DEFAULT|NORMAL|DIVING|CARTESIAN|TOPOFIL|CYLPOLAR|NOSURVEY|passage)(?:\s+station|\s+from|\s+to|\s+FROMDEPTH|\s+TODEPTH|\s+DEPTHCHANGE|\s+newline|\s+direction|\s+tape|\s+compass|\s+clino|\s+northing|\s+easting|\s+altitude|\s+length|\s+bearing|\s+gradient|\s+ignoreall|\sleft|\sright|\sup|\sdown)*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>'))
-regexes.append((re.compile(r"^(\s*)(\*default\s+(?:CALIBRATE|DATA|UNITS)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*flags\s+(?:DUPLICATE|SPLAY|SURFACE|not DUPLICATE|not SPLAY|not SURFACE))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*infer\s+(?:plumbs|equates|exports))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*sd\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|DX|DY|DZ))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*set\s+(?:BLANK|COMMENT|DECIMAL|EOL|KEYWORD|MINUS|NAMES|OMIT|PLUS|ROOT|SEPARATOR))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*units\s+(?:TAPE|LENGTH|COMPASS|BEARING|CLINO|GRADIENT|COUNTER|DEPTH|DECLINATION|X|Y|Z))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(.*)$", re.IGNORECASE|re.MULTILINE),
- r'<div>\1&nbsp;</div>\n'))
-
-@register.filter()
-@stringfilter
-def survex_to_html(value, autoescape=None):
- if autoescape:
- value = conditional_escape(value)
- for regex, sub in regexes:
- print sub
- value = regex.sub(sub, value)
+from django import template
+from django.utils.html import conditional_escape
+from django.template.defaultfilters import stringfilter
+from django.utils.safestring import mark_safe
+import re
+
+register = template.Library()
+
+# seems to add extra lines between the commented lines, which isn't so great.
+regexes = []
+regexes.append((re.compile(r"(;.*)$", re.IGNORECASE|re.MULTILINE),
+ r'<span class = "comment">\1</span>\n'))
+regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)(.svx)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3<a href="\4.index">\4\5</a>'))
+regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3<a href="\4.index">\4</a>'))
+regexes.append((re.compile(r"^(\s*)(\*team\s+(?:notes|tape|insts|pics))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*(?:begin|end|copyright|date|entrance|equate|export|fix|prefix|require|SOLVE|title|truncate))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*calibrate\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|X|Y|Z)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*data\s+(?:DEFAULT|NORMAL|DIVING|CARTESIAN|TOPOFIL|CYLPOLAR|NOSURVEY|passage)(?:\s+station|\s+from|\s+to|\s+FROMDEPTH|\s+TODEPTH|\s+DEPTHCHANGE|\s+newline|\s+direction|\s+tape|\s+compass|\s+clino|\s+northing|\s+easting|\s+altitude|\s+length|\s+bearing|\s+gradient|\s+ignoreall|\sleft|\sright|\sup|\sdown)*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>'))
+regexes.append((re.compile(r"^(\s*)(\*default\s+(?:CALIBRATE|DATA|UNITS)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*flags\s+(?:DUPLICATE|SPLAY|SURFACE|not DUPLICATE|not SPLAY|not SURFACE))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*infer\s+(?:plumbs|equates|exports))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*sd\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|DX|DY|DZ))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*set\s+(?:BLANK|COMMENT|DECIMAL|EOL|KEYWORD|MINUS|NAMES|OMIT|PLUS|ROOT|SEPARATOR))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(\s*)(\*units\s+(?:TAPE|LENGTH|COMPASS|BEARING|CLINO|GRADIENT|COUNTER|DEPTH|DECLINATION|X|Y|Z))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'\1<span class = "command">\2</span>\3\4'))
+regexes.append((re.compile(r"^(.*)$", re.IGNORECASE|re.MULTILINE),
+ r'<div>\1&nbsp;</div>\n'))
+
+@register.filter()
+@stringfilter
+def survex_to_html(value, autoescape=None):
+ if autoescape:
+ value = conditional_escape(value)
+ for regex, sub in regexes:
+ print sub
+ value = regex.sub(sub, value)
return mark_safe(value) \ No newline at end of file
diff --git a/core/templatetags/wiki_markup.py b/core/templatetags/wiki_markup.py
index 810634b..4087b12 100644
--- a/core/templatetags/wiki_markup.py
+++ b/core/templatetags/wiki_markup.py
@@ -1,169 +1,169 @@
-from django import template
-from django.utils.html import conditional_escape
-from django.template.defaultfilters import stringfilter
-from django.utils.safestring import mark_safe
-from django.conf import settings
-from core.models import QM, DPhoto, LogbookEntry, Cave
-import re, urlparse
-
-register = template.Library()
-
-
-@register.filter()
-def plusone(n):
- return n + 1
-
-
-def wiki_list(line, listdepth):
- l = ""
- for d in listdepth:
- l += d
- mstar = re.match(l + "\*(.*)", line)
- if mstar:
- listdepth.append("\*")
- return ("<ul>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mstar.groups()[0], listdepth)
- mhash = re.match(l + "#(.*)", line)
- if mhash:
- listdepth.append("#")
- return ("<ol>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mhash.groups()[0], listdepth)
- mflat = re.match(l + "(.*)", line)
- if mflat and listdepth:
- return (" " * len(listdepth) + "<li>%s</li>\n" % mflat.groups()[0], listdepth)
- if listdepth:
- prev = listdepth.pop()
- if prev == "\*":
- t, l = wiki_list(line, listdepth)
- return ("</ul>\n" + t, l)
- if prev == "#":
- t, l = wiki_list(line, listdepth)
- return ("</ol>\n" + t, l)
- return (line, listdepth)
-
-@register.filter()
-@stringfilter
-def wiki_to_html(value, autoescape=None):
- """
- This is the tag which turns wiki syntax into html. It is intended for long pieces of wiki.
- Hence it splits the wiki into HTML paragraphs based on double line feeds.
- """
- #find paragraphs
- outValue = ""
- for paragraph in re.split("\n\s*?\n", value, re.DOTALL):
- outValue += "<p>"
- outValue += wiki_to_html_short(paragraph, autoescape)
- outValue += "</p>\n"
- return mark_safe(outValue)
-
-@register.filter()
-@stringfilter
-def wiki_to_html_short(value, autoescape=None):
- """
- This is the tag which turns wiki syntax into html. It is intended for short pieces of wiki.
- Hence it is not split the wiki into paragraphs using where it finds double line feeds.
- """
- if autoescape:
- value = conditional_escape(value)
- #deescape doubly escaped characters
- value = re.sub("&amp;(.*?);", r"&\1;", value, re.DOTALL)
- #italics and bold
- value = re.sub("&#39;&#39;&#39;&#39;([^']+)&#39;&#39;&#39;&#39;", r"<b><i>\1</i></b>", value, re.DOTALL)
- value = re.sub("&#39;b&#39;&#39;([^']+)&#39;&#39;&#39;", r"<b>\1</b>", value, re.DOTALL)
- value = re.sub("&#39;&#39;([^']+)&#39;&#39;", r"<i>\1</i>", value, re.DOTALL)
-
- #make headers
- def headerrepl(matchobj):
- number=len(matchobj.groups()[0])
- num=str(number)
- if number>1:
- return '<h'+num+'>'+matchobj.groups()[1]+'</h'+num+'>'
- else:
- print 'morethanone'
- return matchobj.group()
- value = re.sub(r"(?m)^(=+)([^=]+)(=+)$",headerrepl,value)
-
- #make qm links. this takes a little doing
- qmMatchPattern=settings.QM_PATTERN
- def qmrepl(matchobj):
- """
- A function for replacing wikicode qm links with html qm links.
- Given a matchobj matching a wikilink in the format
- [[QM:C204-1999-24]]
- If the QM does not exist, the function will return a link for creating it.
- """
- qmdict={'urlroot':settings.URL_ROOT,'cave':matchobj.groups()[2],'year':matchobj.groups()[1],'number':matchobj.groups()[3]}
- try:
- qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
- found_by__date__year = qmdict['year'],
- number = qmdict['number'])
- return r'<a href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm))
- except QM.DoesNotExist: #bother aaron to make him clean up the below code - AC
- try:
- placeholder=LogbookEntry.objects.get(date__year=qmdict['year'],cave__kataster_number=qmdict['cave'], title__icontains='placeholder')
- except LogbookEntry.DoesNotExist:
- placeholder=LogbookEntry(
- date='01-01'+qmdict['year'],
- cave=Cave.objects.get(kataster_number=qmdict['cave']),
- title='placeholder'
- )
- qm=QM(found_by = placeholder, number = qmdict['number'])
- return r'<a class="redtext" href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm))
-
- value = re.sub(qmMatchPattern,qmrepl, value, re.DOTALL)
-
- #make photo links for [[photo:filename]] or [[photo:filename linktext]], and
- #insert photos for [[display:left photo:filename]]
- photoLinkPattern="\[\[\s*photo:(?P<photoName>[^\s]+)\s*(?P<linkText>.*)\]\]"
- photoSrcPattern="\[\[\s*display:(?P<style>[^\s]+) photo:(?P<photoName>[^\s]+)\s*\]\]"
- def photoLinkRepl(matchobj):
- matchdict=matchobj.groupdict()
- try:
- linkText=matchdict['linkText']
- except KeyError:
- linkText=None
-
- try:
- photo=DPhoto.objects.get(file=matchdict['photoName'])
- if not linkText:
- linkText=str(photo)
- res=r'<a href=' + photo.get_admin_url() +'>' + linkText + '</a>'
- except Photo.DoesNotExist:
- res = r'<a class="redtext" href="">make new photo</a>'
- return res
-
- def photoSrcRepl(matchobj):
- matchdict=matchobj.groupdict()
- style=matchdict['style']
- try:
- photo=Photo.objects.get(file=matchdict['photoName'])
- res=r'<a href='+photo.file.url+'><img src=' + photo.thumbnail_image.url +' class='+style+' /></a>'
- except Photo.DoesNotExist:
- res = r'<a class="redtext" href="">make new photo</a>'
- return res
- value = re.sub(photoLinkPattern,photoLinkRepl, value, re.DOTALL)
- value = re.sub(photoSrcPattern,photoSrcRepl, value, re.DOTALL)
-
- #make cave links
- value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%scave/\1/">\1</a>' % settings.URL_ROOT, value, re.DOTALL)
- #make people links
- value = re.sub("\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%sperson/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
- #make subcave links
- value = re.sub("\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%ssubcave/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
- #make cavedescription links
- value = re.sub("\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%scavedescription/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
-
-
-
- #Make lists from lines starting with lists of [stars and hashes]
- outValue = ""
- listdepth = []
- for line in value.split("\n"):
- t, listdepth = wiki_list(line, listdepth)
- outValue += t
- for item in listdepth:
- if item == "\*":
- outValue += "</ul>\n"
- elif item == "#":
- outValue += "</ol>\n"
- return mark_safe(outValue)
-
-wiki_to_html.needs_autoescape = True
+from django import template
+from django.utils.html import conditional_escape
+from django.template.defaultfilters import stringfilter
+from django.utils.safestring import mark_safe
+from django.conf import settings
+from core.models import QM, DPhoto, LogbookEntry, Cave
+import re, urlparse
+
+register = template.Library()
+
+
+@register.filter()
+def plusone(n):
+ return n + 1
+
+
+def wiki_list(line, listdepth):
+ l = ""
+ for d in listdepth:
+ l += d
+ mstar = re.match(l + "\*(.*)", line)
+ if mstar:
+ listdepth.append("\*")
+ return ("<ul>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mstar.groups()[0], listdepth)
+ mhash = re.match(l + "#(.*)", line)
+ if mhash:
+ listdepth.append("#")
+ return ("<ol>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mhash.groups()[0], listdepth)
+ mflat = re.match(l + "(.*)", line)
+ if mflat and listdepth:
+ return (" " * len(listdepth) + "<li>%s</li>\n" % mflat.groups()[0], listdepth)
+ if listdepth:
+ prev = listdepth.pop()
+ if prev == "\*":
+ t, l = wiki_list(line, listdepth)
+ return ("</ul>\n" + t, l)
+ if prev == "#":
+ t, l = wiki_list(line, listdepth)
+ return ("</ol>\n" + t, l)
+ return (line, listdepth)
+
+@register.filter()
+@stringfilter
+def wiki_to_html(value, autoescape=None):
+ """
+ This is the tag which turns wiki syntax into html. It is intended for long pieces of wiki.
+ Hence it splits the wiki into HTML paragraphs based on double line feeds.
+ """
+ #find paragraphs
+ outValue = ""
+ for paragraph in re.split("\n\s*?\n", value, re.DOTALL):
+ outValue += "<p>"
+ outValue += wiki_to_html_short(paragraph, autoescape)
+ outValue += "</p>\n"
+ return mark_safe(outValue)
+
+@register.filter()
+@stringfilter
+def wiki_to_html_short(value, autoescape=None):
+ """
+ This is the tag which turns wiki syntax into html. It is intended for short pieces of wiki.
+ Hence it is not split the wiki into paragraphs using where it finds double line feeds.
+ """
+ if autoescape:
+ value = conditional_escape(value)
+ #deescape doubly escaped characters
+ value = re.sub("&amp;(.*?);", r"&\1;", value, re.DOTALL)
+ #italics and bold
+ value = re.sub("&#39;&#39;&#39;&#39;([^']+)&#39;&#39;&#39;&#39;", r"<b><i>\1</i></b>", value, re.DOTALL)
+ value = re.sub("&#39;b&#39;&#39;([^']+)&#39;&#39;&#39;", r"<b>\1</b>", value, re.DOTALL)
+ value = re.sub("&#39;&#39;([^']+)&#39;&#39;", r"<i>\1</i>", value, re.DOTALL)
+
+ #make headers
+ def headerrepl(matchobj):
+ number=len(matchobj.groups()[0])
+ num=str(number)
+ if number>1:
+ return '<h'+num+'>'+matchobj.groups()[1]+'</h'+num+'>'
+ else:
+ print 'morethanone'
+ return matchobj.group()
+ value = re.sub(r"(?m)^(=+)([^=]+)(=+)$",headerrepl,value)
+
+ #make qm links. this takes a little doing
+ qmMatchPattern=settings.QM_PATTERN
+ def qmrepl(matchobj):
+ """
+ A function for replacing wikicode qm links with html qm links.
+ Given a matchobj matching a wikilink in the format
+ [[QM:C204-1999-24]]
+ If the QM does not exist, the function will return a link for creating it.
+ """
+ qmdict={'urlroot':settings.URL_ROOT,'cave':matchobj.groups()[2],'year':matchobj.groups()[1],'number':matchobj.groups()[3]}
+ try:
+ qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
+ found_by__date__year = qmdict['year'],
+ number = qmdict['number'])
+ return r'<a href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm))
+ except QM.DoesNotExist: #bother aaron to make him clean up the below code - AC
+ try:
+ placeholder=LogbookEntry.objects.get(date__year=qmdict['year'],cave__kataster_number=qmdict['cave'], title__icontains='placeholder')
+ except LogbookEntry.DoesNotExist:
+ placeholder=LogbookEntry(
+ date='01-01'+qmdict['year'],
+ cave=Cave.objects.get(kataster_number=qmdict['cave']),
+ title='placeholder'
+ )
+ qm=QM(found_by = placeholder, number = qmdict['number'])
+ return r'<a class="redtext" href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm))
+
+ value = re.sub(qmMatchPattern,qmrepl, value, re.DOTALL)
+
+ #make photo links for [[photo:filename]] or [[photo:filename linktext]], and
+ #insert photos for [[display:left photo:filename]]
+ photoLinkPattern="\[\[\s*photo:(?P<photoName>[^\s]+)\s*(?P<linkText>.*)\]\]"
+ photoSrcPattern="\[\[\s*display:(?P<style>[^\s]+) photo:(?P<photoName>[^\s]+)\s*\]\]"
+ def photoLinkRepl(matchobj):
+ matchdict=matchobj.groupdict()
+ try:
+ linkText=matchdict['linkText']
+ except KeyError:
+ linkText=None
+
+ try:
+ photo=DPhoto.objects.get(file=matchdict['photoName'])
+ if not linkText:
+ linkText=str(photo)
+ res=r'<a href=' + photo.get_admin_url() +'>' + linkText + '</a>'
+ except Photo.DoesNotExist:
+ res = r'<a class="redtext" href="">make new photo</a>'
+ return res
+
+ def photoSrcRepl(matchobj):
+ matchdict=matchobj.groupdict()
+ style=matchdict['style']
+ try:
+ photo=Photo.objects.get(file=matchdict['photoName'])
+ res=r'<a href='+photo.file.url+'><img src=' + photo.thumbnail_image.url +' class='+style+' /></a>'
+ except Photo.DoesNotExist:
+ res = r'<a class="redtext" href="">make new photo</a>'
+ return res
+ value = re.sub(photoLinkPattern,photoLinkRepl, value, re.DOTALL)
+ value = re.sub(photoSrcPattern,photoSrcRepl, value, re.DOTALL)
+
+ #make cave links
+ value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%scave/\1/">\1</a>' % settings.URL_ROOT, value, re.DOTALL)
+ #make people links
+ value = re.sub("\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%sperson/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
+ #make subcave links
+ value = re.sub("\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%ssubcave/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
+ #make cavedescription links
+ value = re.sub("\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%scavedescription/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
+
+
+
+ #Make lists from lines starting with lists of [stars and hashes]
+ outValue = ""
+ listdepth = []
+ for line in value.split("\n"):
+ t, listdepth = wiki_list(line, listdepth)
+ outValue += t
+ for item in listdepth:
+ if item == "\*":
+ outValue += "</ul>\n"
+ elif item == "#":
+ outValue += "</ol>\n"
+ return mark_safe(outValue)
+
+wiki_to_html.needs_autoescape = True
diff --git a/core/view_surveys.py b/core/view_surveys.py
index 66aa1ed..a6df780 100644
--- a/core/view_surveys.py
+++ b/core/view_surveys.py
@@ -1,233 +1,233 @@
-from django.conf import settings
-import fileAbstraction
-from django.shortcuts import render_to_response
-from django.http import HttpResponse, Http404
-import os, stat
-import re
-from troggle.core.models import SurvexScansFolder, SurvexScanSingle, SurvexBlock, TunnelFile
-import parsers.surveys
-
-# inline fileabstraction into here if it's not going to be useful anywhere else
-# keep things simple and ignore exceptions everywhere for now
-
-
-def getMimeType(extension):
- try:
- return {"txt": "text/plain",
- "html": "text/html",
- }[extension]
- except:
- print "unknown file type"
- return "text/plain"
-
-
-def listdir(request, path):
- #try:
- return HttpResponse(fileAbstraction.listdir(path), mimetype = "text/plain")
- #except:
- # raise Http404
-
-def upload(request, path):
- pass
-
-def download(request, path):
- #try:
-
- return HttpResponse(fileAbstraction.readFile(path), mimetype=getMimeType(path.split(".")[-1]))
- #except:
- # raise Http404
-
-
-#
-# julian's quick hack for something that works
-# could signal directories by ending with /, and forward cases where it's missing
-#
-extmimetypes = {".txt": "text/plain",
- ".html": "text/html",
- ".png": "image/png",
- ".jpg": "image/jpeg",
- }
-
-# dead
-def jgtfile(request, f):
- fp = os.path.join(settings.SURVEYS, f)
- # could also surf through SURVEX_DATA
-
- # directory listing
- if os.path.isdir(fp):
- listdirfiles = [ ]
- listdirdirs = [ ]
-
- for lf in sorted(os.listdir(fp)):
- hpath = os.path.join(f, lf) # not absolute path
- if lf[0] == "." or lf[-1] == "~":
- continue
-
- hpath = hpath.replace("\\", "/") # for windows users
- href = hpath.replace("#", "%23") # '#' in file name annoyance
-
- flf = os.path.join(fp, lf)
- if os.path.isdir(flf):
- nfiles = len([sf for sf in os.listdir(flf) if sf[0] != "."])
- listdirdirs.append((href, hpath + "/", nfiles))
- else:
- listdirfiles.append((href, hpath, os.path.getsize(flf)))
-
- upperdirs = [ ]
- lf = f
- while lf:
- hpath = lf.replace("\\", "/") # for windows users
- if hpath[-1] != "/":
- hpath += "/"
- href = hpath.replace("#", "%23")
- lf = os.path.split(lf)[0]
- upperdirs.append((href, hpath))
- upperdirs.append(("", "/"))
-
- return render_to_response('listdir.html', {'file':f, 'listdirfiles':listdirfiles, 'listdirdirs':listdirdirs, 'upperdirs':upperdirs, 'settings': settings})
-
- # flat output of file when loaded
- if os.path.isfile(fp):
- ext = os.path.splitext(fp)[1].lower()
- mimetype = extmimetypes.get(ext, "text/plain")
- fin = open(fp)
- ftext = fin.read()
- fin.close()
- return HttpResponse(ftext, mimetype=mimetype)
-
- return HttpResponse("unknown file::%s::" % f, mimetype = "text/plain")
-
-
-def UniqueFile(fname):
- while True:
- if not os.path.exists(fname):
- break
- mname = re.match("(.*?)(?:-(\d+))?\.(png|jpg|jpeg)$(?i)", fname)
- if mname:
- fname = "%s-%d.%s" % (mname.group(1), int(mname.group(2) or "0") + 1, mname.group(3))
- return fname
-
-
-# join it all up and then split them off for the directories that don't exist
-# anyway, this mkdir doesn't work
-def SaveImageInDir(name, imgdir, project, fdata, bbinary):
- print ("hihihihi", fdata, settings.SURVEYS)
- fimgdir = os.path.join(settings.SURVEYS, imgdir)
- if not os.path.isdir(fimgdir):
- print "*** Making directory", fimgdir
- os.path.mkdir(fimgdir)
- fprojdir = os.path.join(fimgdir, project)
- if not os.path.isdir(fprojdir):
- print "*** Making directory", fprojdir
- os.path.mkdir(fprojdir)
- print "hhh"
-
- fname = os.path.join(fprojdir, name)
- print fname, "fff"
- fname = UniqueFile(fname)
-
- p2, p1 = os.path.split(fname)
- p3, p2 = os.path.split(p2)
- p4, p3 = os.path.split(p3)
- res = os.path.join(p3, p2, p1)
-
- print "saving file", fname
- fout = open(fname, (bbinary and "wb" or "w"))
- fout.write(fdata.read())
- fout.close()
- res = os.path.join(imgdir, name)
- return res.replace("\\", "/")
-
-
-# do we want to consider saving project/field rather than field/project
-def jgtuploadfile(request):
- filesuploaded = [ ]
- project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"]
- print (project, user, tunnelversion)
- for uploadedfile in request.FILES.values():
- if uploadedfile.field_name in ["tileimage", "backgroundimage"] and \
- uploadedfile.content_type in ["image/png", "image/jpeg"]:
- fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
- print fname
- fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, True)
- filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
- if uploadedfile.field_name in ["sketch"] and \
- uploadedfile.content_type in ["text/plain"]:
- fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
- print fname
- fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, False)
- filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
- #print "FF", request.FILES
- #print ("FFF", request.FILES.values())
- message = ""
- print "gothere"
- return render_to_response('fileupload.html', {'message':message, 'filesuploaded':filesuploaded, 'settings': settings})
-
-def surveyscansfolder(request, path):
- #print [ s.walletname for s in SurvexScansFolder.objects.all() ]
- survexscansfolder = SurvexScansFolder.objects.get(walletname=path)
- return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings })
-
-def surveyscansingle(request, path, file):
- survexscansfolder = SurvexScansFolder.objects.get(walletname=path)
- survexscansingle = SurvexScanSingle.objects.get(survexscansfolder=survexscansfolder, name=file)
- return HttpResponse(content=open(survexscansingle.ffile), mimetype="image/png")
- #return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings })
-
-def surveyscansfolders(request):
- survexscansfolders = SurvexScansFolder.objects.all()
- return render_to_response('survexscansfolders.html', { 'survexscansfolders':survexscansfolders, 'settings': settings })
-
-
-def tunneldata(request):
- tunnelfiles = TunnelFile.objects.all()
- return render_to_response('tunnelfiles.html', { 'tunnelfiles':tunnelfiles, 'settings': settings })
-
-
-def tunnelfile(request, path):
- tunnelfile = TunnelFile.objects.get(tunnelpath=path)
- tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath)
- return HttpResponse(content=open(tfile), mimetype="text/plain")
-
-def tunnelfileupload(request, path):
- tunnelfile = TunnelFile.objects.get(tunnelpath=path)
- tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath)
-
- project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"]
- print (project, user, tunnelversion)
-
-
- assert len(request.FILES.values()) == 1, "only one file to upload"
-
- uploadedfile = request.FILES.values()[0]
-
- if uploadedfile.field_name != "sketch":
- return HttpResponse(content="Error: non-sketch file uploaded", mimetype="text/plain")
- if uploadedfile.content_type != "text/plain":
- return HttpResponse(content="Error: non-plain content type", mimetype="text/plain")
-
- # could use this to add new files
- if os.path.split(path)[1] != uploadedfile.name:
- return HttpResponse(content="Error: name disagrees", mimetype="text/plain")
-
- orgsize = tunnelfile.filesize # = os.stat(tfile)[stat.ST_SIZE]
-
- ttext = uploadedfile.read()
-
- # could check that the user and projects agree here
-
- fout = open(tfile, "w")
- fout.write(ttext)
- fout.close()
-
- # redo its settings of
- parsers.surveys.SetTunnelfileInfo(tunnelfile)
- tunnelfile.save()
-
- uploadedfile.close()
- message = "File size %d overwritten with size %d" % (orgsize, tunnelfile.filesize)
- return HttpResponse(content=message, mimetype="text/plain")
-
-
-
-
+from django.conf import settings
+import fileAbstraction
+from django.shortcuts import render_to_response
+from django.http import HttpResponse, Http404
+import os, stat
+import re
+from troggle.core.models import SurvexScansFolder, SurvexScanSingle, SurvexBlock, TunnelFile
+import parsers.surveys
+
+# inline fileabstraction into here if it's not going to be useful anywhere else
+# keep things simple and ignore exceptions everywhere for now
+
+
+def getMimeType(extension):
+ try:
+ return {"txt": "text/plain",
+ "html": "text/html",
+ }[extension]
+ except:
+ print "unknown file type"
+ return "text/plain"
+
+
+def listdir(request, path):
+ #try:
+ return HttpResponse(fileAbstraction.listdir(path), mimetype = "text/plain")
+ #except:
+ # raise Http404
+
+def upload(request, path):
+ pass
+
+def download(request, path):
+ #try:
+
+ return HttpResponse(fileAbstraction.readFile(path), mimetype=getMimeType(path.split(".")[-1]))
+ #except:
+ # raise Http404
+
+
+#
+# julian's quick hack for something that works
+# could signal directories by ending with /, and forward cases where it's missing
+#
+extmimetypes = {".txt": "text/plain",
+ ".html": "text/html",
+ ".png": "image/png",
+ ".jpg": "image/jpeg",
+ }
+
+# dead
+def jgtfile(request, f):
+ fp = os.path.join(settings.SURVEYS, f)
+ # could also surf through SURVEX_DATA
+
+ # directory listing
+ if os.path.isdir(fp):
+ listdirfiles = [ ]
+ listdirdirs = [ ]
+
+ for lf in sorted(os.listdir(fp)):
+ hpath = os.path.join(f, lf) # not absolute path
+ if lf[0] == "." or lf[-1] == "~":
+ continue
+
+ hpath = hpath.replace("\\", "/") # for windows users
+ href = hpath.replace("#", "%23") # '#' in file name annoyance
+
+ flf = os.path.join(fp, lf)
+ if os.path.isdir(flf):
+ nfiles = len([sf for sf in os.listdir(flf) if sf[0] != "."])
+ listdirdirs.append((href, hpath + "/", nfiles))
+ else:
+ listdirfiles.append((href, hpath, os.path.getsize(flf)))
+
+ upperdirs = [ ]
+ lf = f
+ while lf:
+ hpath = lf.replace("\\", "/") # for windows users
+ if hpath[-1] != "/":
+ hpath += "/"
+ href = hpath.replace("#", "%23")
+ lf = os.path.split(lf)[0]
+ upperdirs.append((href, hpath))
+ upperdirs.append(("", "/"))
+
+ return render_to_response('listdir.html', {'file':f, 'listdirfiles':listdirfiles, 'listdirdirs':listdirdirs, 'upperdirs':upperdirs, 'settings': settings})
+
+ # flat output of file when loaded
+ if os.path.isfile(fp):
+ ext = os.path.splitext(fp)[1].lower()
+ mimetype = extmimetypes.get(ext, "text/plain")
+ fin = open(fp)
+ ftext = fin.read()
+ fin.close()
+ return HttpResponse(ftext, mimetype=mimetype)
+
+ return HttpResponse("unknown file::%s::" % f, mimetype = "text/plain")
+
+
+def UniqueFile(fname):
+ while True:
+ if not os.path.exists(fname):
+ break
+ mname = re.match("(.*?)(?:-(\d+))?\.(png|jpg|jpeg)$(?i)", fname)
+ if mname:
+ fname = "%s-%d.%s" % (mname.group(1), int(mname.group(2) or "0") + 1, mname.group(3))
+ return fname
+
+
+# join it all up and then split them off for the directories that don't exist
+# anyway, this mkdir doesn't work
+def SaveImageInDir(name, imgdir, project, fdata, bbinary):
+ print ("hihihihi", fdata, settings.SURVEYS)
+ fimgdir = os.path.join(settings.SURVEYS, imgdir)
+ if not os.path.isdir(fimgdir):
+ print "*** Making directory", fimgdir
+ os.path.mkdir(fimgdir)
+ fprojdir = os.path.join(fimgdir, project)
+ if not os.path.isdir(fprojdir):
+ print "*** Making directory", fprojdir
+ os.path.mkdir(fprojdir)
+ print "hhh"
+
+ fname = os.path.join(fprojdir, name)
+ print fname, "fff"
+ fname = UniqueFile(fname)
+
+ p2, p1 = os.path.split(fname)
+ p3, p2 = os.path.split(p2)
+ p4, p3 = os.path.split(p3)
+ res = os.path.join(p3, p2, p1)
+
+ print "saving file", fname
+ fout = open(fname, (bbinary and "wb" or "w"))
+ fout.write(fdata.read())
+ fout.close()
+ res = os.path.join(imgdir, name)
+ return res.replace("\\", "/")
+
+
+# do we want to consider saving project/field rather than field/project
+def jgtuploadfile(request):
+ filesuploaded = [ ]
+ project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"]
+ print (project, user, tunnelversion)
+ for uploadedfile in request.FILES.values():
+ if uploadedfile.field_name in ["tileimage", "backgroundimage"] and \
+ uploadedfile.content_type in ["image/png", "image/jpeg"]:
+ fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
+ print fname
+ fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, True)
+ filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
+ if uploadedfile.field_name in ["sketch"] and \
+ uploadedfile.content_type in ["text/plain"]:
+ fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
+ print fname
+ fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, False)
+ filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
+ #print "FF", request.FILES
+ #print ("FFF", request.FILES.values())
+ message = ""
+ print "gothere"
+ return render_to_response('fileupload.html', {'message':message, 'filesuploaded':filesuploaded, 'settings': settings})
+
+def surveyscansfolder(request, path):
+ #print [ s.walletname for s in SurvexScansFolder.objects.all() ]
+ survexscansfolder = SurvexScansFolder.objects.get(walletname=path)
+ return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings })
+
+def surveyscansingle(request, path, file):
+ survexscansfolder = SurvexScansFolder.objects.get(walletname=path)
+ survexscansingle = SurvexScanSingle.objects.get(survexscansfolder=survexscansfolder, name=file)
+ return HttpResponse(content=open(survexscansingle.ffile), mimetype="image/png")
+ #return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings })
+
+def surveyscansfolders(request):
+ survexscansfolders = SurvexScansFolder.objects.all()
+ return render_to_response('survexscansfolders.html', { 'survexscansfolders':survexscansfolders, 'settings': settings })
+
+
+def tunneldata(request):
+ tunnelfiles = TunnelFile.objects.all()
+ return render_to_response('tunnelfiles.html', { 'tunnelfiles':tunnelfiles, 'settings': settings })
+
+
+def tunnelfile(request, path):
+ tunnelfile = TunnelFile.objects.get(tunnelpath=path)
+ tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath)
+ return HttpResponse(content=open(tfile), mimetype="text/plain")
+
+def tunnelfileupload(request, path):
+ tunnelfile = TunnelFile.objects.get(tunnelpath=path)
+ tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath)
+
+ project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"]
+ print (project, user, tunnelversion)
+
+
+ assert len(request.FILES.values()) == 1, "only one file to upload"
+
+ uploadedfile = request.FILES.values()[0]
+
+ if uploadedfile.field_name != "sketch":
+ return HttpResponse(content="Error: non-sketch file uploaded", mimetype="text/plain")
+ if uploadedfile.content_type != "text/plain":
+ return HttpResponse(content="Error: non-plain content type", mimetype="text/plain")
+
+ # could use this to add new files
+ if os.path.split(path)[1] != uploadedfile.name:
+ return HttpResponse(content="Error: name disagrees", mimetype="text/plain")
+
+ orgsize = tunnelfile.filesize # = os.stat(tfile)[stat.ST_SIZE]
+
+ ttext = uploadedfile.read()
+
+ # could check that the user and projects agree here
+
+ fout = open(tfile, "w")
+ fout.write(ttext)
+ fout.close()
+
+ # redo its settings of
+ parsers.surveys.SetTunnelfileInfo(tunnelfile)
+ tunnelfile.save()
+
+ uploadedfile.close()
+ message = "File size %d overwritten with size %d" % (orgsize, tunnelfile.filesize)
+ return HttpResponse(content=message, mimetype="text/plain")
+
+
+
+
diff --git a/core/views.py b/core/views.py
index 337989a..26c2e52 100644
--- a/core/views.py
+++ b/core/views.py
@@ -1,8 +1,8 @@
-# primary namespace
-
-import view_surveys
-import views_caves
-import views_survex
-import views_logbooks
-import views_other
-
+# primary namespace
+
+import view_surveys
+import views_caves
+import views_survex
+import views_logbooks
+import views_other
+
diff --git a/core/views_caves.py b/core/views_caves.py
index d078338..4a79652 100644
--- a/core/views_caves.py
+++ b/core/views_caves.py
@@ -1,141 +1,141 @@
-from troggle.core.models import Cave, CaveAndEntrance, Survey, Expedition, QM, CaveDescription
-from troggle.core.forms import CaveForm
-import troggle.core.models as models
-import troggle.settings as settings
-from troggle.helper import login_required_if_public
-
-from django.forms.models import formset_factory
-from django.core.urlresolvers import reverse
-from utils import render_with_context # see views_logbooks for explanation on this.
-from django.http import HttpResponseRedirect
-from django.conf import settings
-import re, urlparse
-from django.shortcuts import get_object_or_404
-
-def getCave(cave_id):
- """Returns a cave object when given a cave name or number. It is used by views including cavehref, ent, and qm."""
- try:
- cave = Cave.objects.get(kataster_number=cave_id)
- except Cave.DoesNotExist:
- cave = Cave.objects.get(unofficial_number=cave_id)
- return cave
-
-def caveindex(request):
- caves = Cave.objects.all()
- notablecavehrefs = [ "161", "204", "258", "76" ] # could detect notability by trips and notability of people who have been down them
- notablecaves = [Cave.objects.get(kataster_number=kataster_number) for kataster_number in notablecavehrefs ]
- caves1623 = Cave.objects.filter(area__short_name = "1623")
- caves1626 = Cave.objects.filter(area__short_name = "1626")
- return render_with_context(request,'caveindex.html', {'caves1623': caves1623, 'caves1626': caves1626, 'notablecaves':notablecaves, 'cavepage': True})
-
-def cave(request, cave_id='', offical_name=''):
- cave=getCave(cave_id)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave, 'cavepage': True})
- else:
- return render_with_context(request,'cave.html', {'cave': cave, 'cavepage': True})
-
-def caveEntrance(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_entrances.html', {'cave': cave})
-def caveDescription(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_uground_description.html', {'cave': cave})
-def caveQMs(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_qms.html', {'cave': cave})
-def caveLogbook(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_logbook.html', {'cave': cave})
-
-def caveSlug(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave.html', {'cave': cave})
-
-@login_required_if_public
-def editCave(request, slug=None):
- form = CaveForm()
- return render_with_context(request,
- 'editcave.html',
- {'form': form})
-
-def qm(request,cave_id,qm_id,year,grade=None):
- year=int(year)
- try:
- qm=getCave(cave_id).get_QMs().get(number=qm_id,found_by__date__year=year)
- return render_with_context(request,'qm.html',locals())
-
- except QM.DoesNotExist:
- url=urlparse.urljoin(settings.URL_ROOT, r'/admin/core/qm/add/'+'?'+ r'number=' + qm_id)
- if grade:
- url += r'&grade=' + grade
- return HttpResponseRedirect(url)
-
-
-
-def ent(request, cave_id, ent_letter):
- cave = Cave.objects.filter(kataster_number = cave_id)[0]
- cave_and_ent = CaveAndEntrance.objects.filter(cave = cave).filter(entrance_letter = ent_letter)[0]
- return render_with_context(request,'entrance.html', {'cave': cave,
- 'entrance': cave_and_ent.entrance,
- 'letter': cave_and_ent.entrance_letter,})
-
-def entranceSlug(request, slug):
- entrance = Entrance.objects.get(slug = slug)
- if entrance.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': entrance})
- else:
- return render_with_context(request,'entranceslug.html', {'entrance': entrance})
-
-def survexblock(request, survexpath):
- survexpath = re.sub("/", ".", survexpath)
- print "jjjjjj", survexpath
- survexblock = models.SurvexBlock.objects.get(survexpath=survexpath)
- #ftext = survexblock.filecontents()
- ftext = survexblock.text
- return render_with_context(request,'survexblock.html', {'survexblock':survexblock, 'ftext':ftext, })
-
-def surveyindex(request):
- surveys=Survey.objects.all()
- expeditions=Expedition.objects.order_by("-year")
- return render_with_context(request,'survey.html',locals())
-
-def survey(request,year,wallet_number):
- surveys=Survey.objects.all()
- expeditions=Expedition.objects.order_by("-year")
- current_expedition=Expedition.objects.filter(year=year)[0]
-
- if wallet_number!='':
- current_survey=Survey.objects.filter(expedition=current_expedition,wallet_number=wallet_number)[0]
- notes=current_survey.scannedimage_set.filter(contents='notes')
- planSketches=current_survey.scannedimage_set.filter(contents='plan')
- elevationSketches=current_survey.scannedimage_set.filter(contents='elevation')
-
- return render_with_context(request,'survey.html', locals())
-
-def cave_description(request, cavedescription_name):
- cave_description = get_object_or_404(CaveDescription, short_name = cavedescription_name)
- return render_with_context(request,'cave_description.html', locals())
-
-def get_entrances(request, caveslug):
- cave = Cave.objects.get(slug = caveslug)
- return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]})
-
-def get_qms(request, caveslug):
- cave = Cave.objects.get(slug = caveslug)
- return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]})
+from troggle.core.models import Cave, CaveAndEntrance, Survey, Expedition, QM, CaveDescription
+from troggle.core.forms import CaveForm
+import troggle.core.models as models
+import troggle.settings as settings
+from troggle.helper import login_required_if_public
+
+from django.forms.models import formset_factory
+from django.core.urlresolvers import reverse
+from utils import render_with_context # see views_logbooks for explanation on this.
+from django.http import HttpResponseRedirect
+from django.conf import settings
+import re, urlparse
+from django.shortcuts import get_object_or_404
+
+def getCave(cave_id):
+ """Returns a cave object when given a cave name or number. It is used by views including cavehref, ent, and qm."""
+ try:
+ cave = Cave.objects.get(kataster_number=cave_id)
+ except Cave.DoesNotExist:
+ cave = Cave.objects.get(unofficial_number=cave_id)
+ return cave
+
+def caveindex(request):
+ caves = Cave.objects.all()
+ notablecavehrefs = [ "161", "204", "258", "76" ] # could detect notability by trips and notability of people who have been down them
+ notablecaves = [Cave.objects.get(kataster_number=kataster_number) for kataster_number in notablecavehrefs ]
+ caves1623 = Cave.objects.filter(area__short_name = "1623")
+ caves1626 = Cave.objects.filter(area__short_name = "1626")
+ return render_with_context(request,'caveindex.html', {'caves1623': caves1623, 'caves1626': caves1626, 'notablecaves':notablecaves, 'cavepage': True})
+
+def cave(request, cave_id='', offical_name=''):
+ cave=getCave(cave_id)
+ if cave.non_public and not request.user.is_authenticated():
+ return render_with_context(request,'nonpublic.html', {'instance': cave, 'cavepage': True})
+ else:
+ return render_with_context(request,'cave.html', {'cave': cave, 'cavepage': True})
+
+def caveEntrance(request, slug):
+ cave = Cave.objects.get(slug = slug)
+ if cave.non_public and not request.user.is_authenticated():
+ return render_with_context(request,'nonpublic.html', {'instance': cave})
+ else:
+ return render_with_context(request,'cave_entrances.html', {'cave': cave})
+def caveDescription(request, slug):
+ cave = Cave.objects.get(slug = slug)
+ if cave.non_public and not request.user.is_authenticated():
+ return render_with_context(request,'nonpublic.html', {'instance': cave})
+ else:
+ return render_with_context(request,'cave_uground_description.html', {'cave': cave})
+def caveQMs(request, slug):
+ cave = Cave.objects.get(slug = slug)
+ if cave.non_public and not request.user.is_authenticated():
+ return render_with_context(request,'nonpublic.html', {'instance': cave})
+ else:
+ return render_with_context(request,'cave_qms.html', {'cave': cave})
+def caveLogbook(request, slug):
+ cave = Cave.objects.get(slug = slug)
+ if cave.non_public and not request.user.is_authenticated():
+ return render_with_context(request,'nonpublic.html', {'instance': cave})
+ else:
+ return render_with_context(request,'cave_logbook.html', {'cave': cave})
+
+def caveSlug(request, slug):
+ cave = Cave.objects.get(slug = slug)
+ if cave.non_public and not request.user.is_authenticated():
+ return render_with_context(request,'nonpublic.html', {'instance': cave})
+ else:
+ return render_with_context(request,'cave.html', {'cave': cave})
+
+@login_required_if_public
+def editCave(request, slug=None):
+ form = CaveForm()
+ return render_with_context(request,
+ 'editcave.html',
+ {'form': form})
+
+def qm(request,cave_id,qm_id,year,grade=None):
+ year=int(year)
+ try:
+ qm=getCave(cave_id).get_QMs().get(number=qm_id,found_by__date__year=year)
+ return render_with_context(request,'qm.html',locals())
+
+ except QM.DoesNotExist:
+ url=urlparse.urljoin(settings.URL_ROOT, r'/admin/core/qm/add/'+'?'+ r'number=' + qm_id)
+ if grade:
+ url += r'&grade=' + grade
+ return HttpResponseRedirect(url)
+
+
+
+def ent(request, cave_id, ent_letter):
+ cave = Cave.objects.filter(kataster_number = cave_id)[0]
+ cave_and_ent = CaveAndEntrance.objects.filter(cave = cave).filter(entrance_letter = ent_letter)[0]
+ return render_with_context(request,'entrance.html', {'cave': cave,
+ 'entrance': cave_and_ent.entrance,
+ 'letter': cave_and_ent.entrance_letter,})
+
+def entranceSlug(request, slug):
+ entrance = Entrance.objects.get(slug = slug)
+ if entrance.non_public and not request.user.is_authenticated():
+ return render_with_context(request,'nonpublic.html', {'instance': entrance})
+ else:
+ return render_with_context(request,'entranceslug.html', {'entrance': entrance})
+
+def survexblock(request, survexpath):
+ survexpath = re.sub("/", ".", survexpath)
+ print "jjjjjj", survexpath
+ survexblock = models.SurvexBlock.objects.get(survexpath=survexpath)
+ #ftext = survexblock.filecontents()
+ ftext = survexblock.text
+ return render_with_context(request,'survexblock.html', {'survexblock':survexblock, 'ftext':ftext, })
+
+def surveyindex(request):
+ surveys=Survey.objects.all()
+ expeditions=Expedition.objects.order_by("-year")
+ return render_with_context(request,'survey.html',locals())
+
+def survey(request,year,wallet_number):
+ surveys=Survey.objects.all()
+ expeditions=Expedition.objects.order_by("-year")
+ current_expedition=Expedition.objects.filter(year=year)[0]
+
+ if wallet_number!='':
+ current_survey=Survey.objects.filter(expedition=current_expedition,wallet_number=wallet_number)[0]
+ notes=current_survey.scannedimage_set.filter(contents='notes')
+ planSketches=current_survey.scannedimage_set.filter(contents='plan')
+ elevationSketches=current_survey.scannedimage_set.filter(contents='elevation')
+
+ return render_with_context(request,'survey.html', locals())
+
+def cave_description(request, cavedescription_name):
+ cave_description = get_object_or_404(CaveDescription, short_name = cavedescription_name)
+ return render_with_context(request,'cave_description.html', locals())
+
+def get_entrances(request, caveslug):
+ cave = Cave.objects.get(slug = caveslug)
+ return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]})
+
+def get_qms(request, caveslug):
+ cave = Cave.objects.get(slug = caveslug)
+ return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]})
diff --git a/core/views_logbooks.py b/core/views_logbooks.py
index 007086f..2cf9163 100644
--- a/core/views_logbooks.py
+++ b/core/views_logbooks.py
@@ -1,252 +1,252 @@
-from django.shortcuts import render_to_response
-from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, SurvexBlock
-import troggle.core.models as models
-import troggle.settings as settings
-import django.db.models
-from troggle.parsers.logbooks import LoadLogbookForExpedition
-from troggle.parsers.people import GetPersonExpeditionNameLookup
-#from troggle.core.forms import PersonForm, getTripForm, get_name
-from django.core.urlresolvers import reverse
-from django.http import HttpResponseRedirect, HttpResponse
-from django.template import Context, loader
-from utils import render_with_context
-import os.path
-import troggle.parsers.logbooks as logbookparsers
-from django.template.defaultfilters import slugify
-from troggle.helper import login_required_if_public
-import datetime
-
-
-# Django uses Context, not RequestContext when you call render_to_response. We always want to use RequestContext, so that django adds the context from settings.TEMPLATE_CONTEXT_PROCESSORS. This way we automatically get necessary settings variables passed to each template. So we use a custom method, render_response instead of render_to_response. Hopefully future Django releases will make this unnecessary.
-#from troggle.alwaysUseRequestContext import render_response
-
-import re
-
-@django.db.models.permalink #this allows the nice get_absolute_url syntax we are using
-
-def getNotablePersons():
- notablepersons = []
- for person in Person.objects.all():
- if person.bisnotable():
- notablepersons.append(person)
- return notablepersons
-
-
-def personindex(request):
- persons = Person.objects.all()
- # From what I can tell, "persons" seems to be the table rows, while "personss" is the table columns. - AC 16 Feb 09
- personss = [ ]
- ncols = 4
- nc = (len(persons) + ncols - 1) / ncols
- for i in range(ncols):
- personss.append(persons[i * nc: (i + 1) * nc])
-
- notablepersons = []
- for person in Person.objects.all():
- if person.bisnotable():
- notablepersons.append(person)
-
- return render_with_context(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, })
-
-
-def expedition(request, expeditionname):
- expedition = Expedition.objects.get(year=int(expeditionname))
- expeditions = Expedition.objects.all()
- personexpeditiondays = [ ]
- dateditems = list(expedition.logbookentry_set.all()) + list(expedition.survexblock_set.all())
- dates = list(set([item.date for item in dateditems]))
- dates.sort()
- for personexpedition in expedition.personexpedition_set.all():
- prow = [ ]
- for date in dates:
- pcell = { "persontrips": PersonTrip.objects.filter(personexpedition=personexpedition,
- logbook_entry__date=date) }
- pcell["survexblocks"] = set(SurvexBlock.objects.filter(survexpersonrole__personexpedition=personexpedition,
- date = date))
- prow.append(pcell)
- personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
-
- message = ""
- if "reload" in request.GET:
- message = LoadLogbookForExpedition(expedition)
- return render_with_context(request,'expedition.html', {'expedition': expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'message':message, 'settings':settings, 'dateditems': dateditems })
-
- def get_absolute_url(self):
- return ('expedition', (expedition.year))
-
-
-def person(request, first_name='', last_name='', ):
- person = Person.objects.get(first_name = first_name, last_name = last_name)
-
- #This is for removing the reference to the user's profile, in case they set it to the wrong person
- if request.method == 'GET':
- if request.GET.get('clear_profile')=='True':
- person.user=None
- person.save()
- return HttpResponseRedirect(reverse('profiles_select_profile'))
-
- return render_with_context(request,'person.html', {'person': person, })
-
-
-def GetPersonChronology(personexpedition):
- res = { }
- for persontrip in personexpedition.persontrip_set.all():
- a = res.setdefault(persontrip.date, { })
- a.setdefault("persontrips", [ ]).append(persontrip)
-
- for personrole in personexpedition.survexpersonrole_set.all():
- a = res.setdefault(personrole.survexblock.date, { })
- a.setdefault("personroles", [ ]).append(personrole.survexblock)
-
- # build up the tables
- rdates = res.keys()
- rdates.sort()
-
-
- res2 = [ ]
- for rdate in rdates:
- persontrips = res[rdate].get("persontrips", [])
- personroles = res[rdate].get("personroles", [])
- for n in range(max(len(persontrips), len(personroles))):
- res2.append(((n == 0 and rdate or "--"), (n < len(persontrips) and persontrips[n]), (n < len(personroles) and personroles[n])))
-
- return res2
-
-
-def personexpedition(request, first_name='', last_name='', year=''):
- person = Person.objects.get(first_name = first_name, last_name = last_name)
- expedition = Expedition.objects.get(year=year)
- personexpedition = person.personexpedition_set.get(expedition=expedition)
- personchronology = GetPersonChronology(personexpedition)
- return render_with_context(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})
-
-
-def logbookentry(request, date, slug):
- logbookentry = LogbookEntry.objects.filter(date=date, slug=slug)
-
- if len(logbookentry)>1:
- return render_with_context(request, 'object_list.html',{'object_list':logbookentry})
- else:
- logbookentry=logbookentry[0]
- return render_with_context(request, 'logbookentry.html', {'logbookentry': logbookentry})
-
-
-def logbookSearch(request, extra):
- query_string = ''
- found_entries = None
- if ('q' in request.GET) and request.GET['q'].strip():
- query_string = request.GET['q']
- entry_query = search.get_query(query_string, ['text','title',])
- found_entries = LogbookEntry.objects.filter(entry_query)
-
- return render_with_context(request,'logbooksearch.html',
- { 'query_string': query_string, 'found_entries': found_entries, })
- #context_instance=RequestContext(request))
-
-def personForm(request,pk):
- person=Person.objects.get(pk=pk)
- form=PersonForm(instance=person)
- return render_with_context(request,'personform.html', {'form':form,})
-
-
-def experimental(request):
- legsbyexpo = [ ]
- for expedition in Expedition.objects.all():
- survexblocks = expedition.survexblock_set.all()
- survexlegs = [ ]
- survexleglength = 0.0
- for survexblock in survexblocks:
- survexlegs.extend(survexblock.survexleg_set.all())
- survexleglength += survexblock.totalleglength
- legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength}))
- legsbyexpo.reverse()
-
- survexlegs = models.SurvexLeg.objects.all()
- totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs])
- return render_with_context(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
-
-@login_required_if_public
-def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None):
- expedition = Expedition.objects.get(year=expeditionyear)
- PersonTripFormSet, TripForm = getTripForm(expedition)
- if pslug and pdate:
- previousdate = datetime.date(*[int(x) for x in pdate.split("-")])
- previouslbe = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition)
- assert previouslbe.filename
- if request.method == 'POST': # If the form has been submitted...
- tripForm = TripForm(request.POST) # A form bound to the POST data
- personTripFormSet = PersonTripFormSet(request.POST)
- if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
- dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d")
- directory = os.path.join(settings.EXPOWEB,
- "years",
- expedition.year,
- "autologbook")
- filename = os.path.join(directory,
- dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html")
- if not os.path.isdir(directory):
- os.mkdir(directory)
- if pslug and pdate:
- delLogbookEntry(previouslbe)
- f = open(filename, "w")
- template = loader.get_template('dataformat/logbookentry.html')
- context = Context({'trip': tripForm.cleaned_data,
- 'persons': personTripFormSet.cleaned_data,
- 'date': dateStr,
- 'expeditionyear': expeditionyear})
- f.write(template.render(context))
- f.close()
- print logbookparsers.parseAutoLogBookEntry(filename)
- return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
- else:
- if pslug and pdate:
- if previouslbe.cave:
- tripForm = TripForm(initial={"date": previousdate,
- "title": previouslbe.title,
- "cave": previouslbe.cave.reference(),
- "location": None,
- "caveOrLocation": "cave",
- "html": previouslbe.text})
- else:
- tripForm = TripForm(initial={"date": previousdate,
- "title": previouslbe.title,
- "cave": None,
- "location": previouslbe.place,
- "caveOrLocation": "location",
- "html": previouslbe.text})
- personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition),
- "TU": py.time_underground,
- "author": py.is_logbook_entry_author}
- for py in previouslbe.persontrip_set.all()])
- else:
- tripForm = TripForm() # An unbound form
- personTripFormSet = PersonTripFormSet()
-
- return render_with_context(request, 'newlogbookentry.html', {
- 'tripForm': tripForm,
- 'personTripFormSet': personTripFormSet,
-
- })
-
-@login_required_if_public
-def deleteLogbookEntry(request, expeditionyear, date = None, slug = None):
- expedition = Expedition.objects.get(year=expeditionyear)
- previousdate = datetime.date(*[int(x) for x in date.split("-")])
- previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition)
- delLogbookEntry(previouslbe)
- return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
-
-def delLogbookEntry(lbe):
- for pt in lbe.persontrip_set.all():
- pt.delete()
- lbe.delete()
- os.remove(lbe.filename)
-
-def get_people(request, expeditionslug):
- exp = Expedition.objects.get(year = expeditionslug)
- return render_with_context(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]})
-
-def get_logbook_entries(request, expeditionslug):
- exp = Expedition.objects.get(year = expeditionslug)
- return render_with_context(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]})
-
+from django.shortcuts import render_to_response
+from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, SurvexBlock
+import troggle.core.models as models
+import troggle.settings as settings
+import django.db.models
+from troggle.parsers.logbooks import LoadLogbookForExpedition
+from troggle.parsers.people import GetPersonExpeditionNameLookup
+#from troggle.core.forms import PersonForm, getTripForm, get_name
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect, HttpResponse
+from django.template import Context, loader
+from utils import render_with_context
+import os.path
+import troggle.parsers.logbooks as logbookparsers
+from django.template.defaultfilters import slugify
+from troggle.helper import login_required_if_public
+import datetime
+
+
+# Django uses Context, not RequestContext when you call render_to_response. We always want to use RequestContext, so that django adds the context from settings.TEMPLATE_CONTEXT_PROCESSORS. This way we automatically get necessary settings variables passed to each template. So we use a custom method, render_response instead of render_to_response. Hopefully future Django releases will make this unnecessary.
+#from troggle.alwaysUseRequestContext import render_response
+
+import re
+
+@django.db.models.permalink #this allows the nice get_absolute_url syntax we are using
+
+def getNotablePersons():
+ notablepersons = []
+ for person in Person.objects.all():
+ if person.bisnotable():
+ notablepersons.append(person)
+ return notablepersons
+
+
+def personindex(request):
+ persons = Person.objects.all()
+ # From what I can tell, "persons" seems to be the table rows, while "personss" is the table columns. - AC 16 Feb 09
+ personss = [ ]
+ ncols = 4
+ nc = (len(persons) + ncols - 1) / ncols
+ for i in range(ncols):
+ personss.append(persons[i * nc: (i + 1) * nc])
+
+ notablepersons = []
+ for person in Person.objects.all():
+ if person.bisnotable():
+ notablepersons.append(person)
+
+ return render_with_context(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, })
+
+
+def expedition(request, expeditionname):
+ expedition = Expedition.objects.get(year=int(expeditionname))
+ expeditions = Expedition.objects.all()
+ personexpeditiondays = [ ]
+ dateditems = list(expedition.logbookentry_set.all()) + list(expedition.survexblock_set.all())
+ dates = list(set([item.date for item in dateditems]))
+ dates.sort()
+ for personexpedition in expedition.personexpedition_set.all():
+ prow = [ ]
+ for date in dates:
+ pcell = { "persontrips": PersonTrip.objects.filter(personexpedition=personexpedition,
+ logbook_entry__date=date) }
+ pcell["survexblocks"] = set(SurvexBlock.objects.filter(survexpersonrole__personexpedition=personexpedition,
+ date = date))
+ prow.append(pcell)
+ personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
+
+ message = ""
+ if "reload" in request.GET:
+ message = LoadLogbookForExpedition(expedition)
+ return render_with_context(request,'expedition.html', {'expedition': expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'message':message, 'settings':settings, 'dateditems': dateditems })
+
+ def get_absolute_url(self):
+ return ('expedition', (expedition.year))
+
+
+def person(request, first_name='', last_name='', ):
+ person = Person.objects.get(first_name = first_name, last_name = last_name)
+
+ #This is for removing the reference to the user's profile, in case they set it to the wrong person
+ if request.method == 'GET':
+ if request.GET.get('clear_profile')=='True':
+ person.user=None
+ person.save()
+ return HttpResponseRedirect(reverse('profiles_select_profile'))
+
+ return render_with_context(request,'person.html', {'person': person, })
+
+
+def GetPersonChronology(personexpedition):
+ res = { }
+ for persontrip in personexpedition.persontrip_set.all():
+ a = res.setdefault(persontrip.date, { })
+ a.setdefault("persontrips", [ ]).append(persontrip)
+
+ for personrole in personexpedition.survexpersonrole_set.all():
+ a = res.setdefault(personrole.survexblock.date, { })
+ a.setdefault("personroles", [ ]).append(personrole.survexblock)
+
+ # build up the tables
+ rdates = res.keys()
+ rdates.sort()
+
+
+ res2 = [ ]
+ for rdate in rdates:
+ persontrips = res[rdate].get("persontrips", [])
+ personroles = res[rdate].get("personroles", [])
+ for n in range(max(len(persontrips), len(personroles))):
+ res2.append(((n == 0 and rdate or "--"), (n < len(persontrips) and persontrips[n]), (n < len(personroles) and personroles[n])))
+
+ return res2
+
+
+def personexpedition(request, first_name='', last_name='', year=''):
+ person = Person.objects.get(first_name = first_name, last_name = last_name)
+ expedition = Expedition.objects.get(year=year)
+ personexpedition = person.personexpedition_set.get(expedition=expedition)
+ personchronology = GetPersonChronology(personexpedition)
+ return render_with_context(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})
+
+
+def logbookentry(request, date, slug):
+ logbookentry = LogbookEntry.objects.filter(date=date, slug=slug)
+
+ if len(logbookentry)>1:
+ return render_with_context(request, 'object_list.html',{'object_list':logbookentry})
+ else:
+ logbookentry=logbookentry[0]
+ return render_with_context(request, 'logbookentry.html', {'logbookentry': logbookentry})
+
+
+def logbookSearch(request, extra):
+ query_string = ''
+ found_entries = None
+ if ('q' in request.GET) and request.GET['q'].strip():
+ query_string = request.GET['q']
+ entry_query = search.get_query(query_string, ['text','title',])
+ found_entries = LogbookEntry.objects.filter(entry_query)
+
+ return render_with_context(request,'logbooksearch.html',
+ { 'query_string': query_string, 'found_entries': found_entries, })
+ #context_instance=RequestContext(request))
+
+def personForm(request,pk):
+ person=Person.objects.get(pk=pk)
+ form=PersonForm(instance=person)
+ return render_with_context(request,'personform.html', {'form':form,})
+
+
+def experimental(request):
+ legsbyexpo = [ ]
+ for expedition in Expedition.objects.all():
+ survexblocks = expedition.survexblock_set.all()
+ survexlegs = [ ]
+ survexleglength = 0.0
+ for survexblock in survexblocks:
+ survexlegs.extend(survexblock.survexleg_set.all())
+ survexleglength += survexblock.totalleglength
+ legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength}))
+ legsbyexpo.reverse()
+
+ survexlegs = models.SurvexLeg.objects.all()
+ totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs])
+ return render_with_context(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
+
+@login_required_if_public
+def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None):
+ expedition = Expedition.objects.get(year=expeditionyear)
+ PersonTripFormSet, TripForm = getTripForm(expedition)
+ if pslug and pdate:
+ previousdate = datetime.date(*[int(x) for x in pdate.split("-")])
+ previouslbe = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition)
+ assert previouslbe.filename
+ if request.method == 'POST': # If the form has been submitted...
+ tripForm = TripForm(request.POST) # A form bound to the POST data
+ personTripFormSet = PersonTripFormSet(request.POST)
+ if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
+ dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d")
+ directory = os.path.join(settings.EXPOWEB,
+ "years",
+ expedition.year,
+ "autologbook")
+ filename = os.path.join(directory,
+ dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html")
+ if not os.path.isdir(directory):
+ os.mkdir(directory)
+ if pslug and pdate:
+ delLogbookEntry(previouslbe)
+ f = open(filename, "w")
+ template = loader.get_template('dataformat/logbookentry.html')
+ context = Context({'trip': tripForm.cleaned_data,
+ 'persons': personTripFormSet.cleaned_data,
+ 'date': dateStr,
+ 'expeditionyear': expeditionyear})
+ f.write(template.render(context))
+ f.close()
+ print logbookparsers.parseAutoLogBookEntry(filename)
+ return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
+ else:
+ if pslug and pdate:
+ if previouslbe.cave:
+ tripForm = TripForm(initial={"date": previousdate,
+ "title": previouslbe.title,
+ "cave": previouslbe.cave.reference(),
+ "location": None,
+ "caveOrLocation": "cave",
+ "html": previouslbe.text})
+ else:
+ tripForm = TripForm(initial={"date": previousdate,
+ "title": previouslbe.title,
+ "cave": None,
+ "location": previouslbe.place,
+ "caveOrLocation": "location",
+ "html": previouslbe.text})
+ personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition),
+ "TU": py.time_underground,
+ "author": py.is_logbook_entry_author}
+ for py in previouslbe.persontrip_set.all()])
+ else:
+ tripForm = TripForm() # An unbound form
+ personTripFormSet = PersonTripFormSet()
+
+ return render_with_context(request, 'newlogbookentry.html', {
+ 'tripForm': tripForm,
+ 'personTripFormSet': personTripFormSet,
+
+ })
+
+@login_required_if_public
+def deleteLogbookEntry(request, expeditionyear, date = None, slug = None):
+ expedition = Expedition.objects.get(year=expeditionyear)
+ previousdate = datetime.date(*[int(x) for x in date.split("-")])
+ previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition)
+ delLogbookEntry(previouslbe)
+ return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
+
+def delLogbookEntry(lbe):
+ for pt in lbe.persontrip_set.all():
+ pt.delete()
+ lbe.delete()
+ os.remove(lbe.filename)
+
+def get_people(request, expeditionslug):
+ exp = Expedition.objects.get(year = expeditionslug)
+ return render_with_context(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]})
+
+def get_logbook_entries(request, expeditionslug):
+ exp = Expedition.objects.get(year = expeditionslug)
+ return render_with_context(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]})
+
diff --git a/core/views_other.py b/core/views_other.py
index d840a30..beecc46 100644
--- a/core/views_other.py
+++ b/core/views_other.py
@@ -1,282 +1,282 @@
-from troggle.core.models import Cave, Expedition, Person, LogbookEntry, PersonExpedition, PersonTrip, DPhoto, QM
-from troggle.core.forms import UploadFileForm
-from django.conf import settings
-from django import forms
-from django.template import loader, Context
-from django.db.models import Q
-import databaseReset
-import re
-from django.http import HttpResponse, HttpResponseRedirect
-from django.core.urlresolvers import reverse
-from utils import render_with_context
-from core.models import *
-from troggle.helper import login_required_if_public
-
-def showrequest(request):
- return HttpResponse(request.GET)
-
-def stats(request):
- statsDict={}
- statsDict['expoCount'] = int(Expedition.objects.count())
- statsDict['caveCount'] = int(Cave.objects.count())
- statsDict['personCount'] = int(Person.objects.count())
- statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count())
- return render_with_context(request,'statistics.html', statsDict)
-
-def frontpage(request):
- if request.user.is_authenticated():
- return render_with_context(request,'tasks.html')
-
- expeditions = Expedition.objects.order_by("-year")
- logbookentry = LogbookEntry
- cave = Cave
- photo = DPhoto
- from django.contrib.admin.templatetags import log
- return render_with_context(request,'frontpage.html', locals())
-
-def todo(request):
- message = "no test message" #reverse('personn', kwargs={"name":"hkjhjh"})
- if "reloadexpos" in request.GET:
- message = LoadPersonsExpos()
- message = "Reloaded personexpos"
- if "reloadsurvex" in request.POST:
- message = LoadAllSurvexBlocks()
- message = "Reloaded survexblocks"
-
- expeditions = Expedition.objects.order_by("-year")
- totallogbookentries = LogbookEntry.objects.count()
- return render_with_context(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message})
-
-
-def controlPanel(request):
- jobs_completed=[]
- if request.method=='POST':
- if request.user.is_superuser:
-
- #importlist is mostly here so that things happen in the correct order.
- #http post data seems to come in an unpredictable order, so we do it this way.
- importlist=['reload_db', 'import_people', 'import_cavetab', 'import_logbooks', 'import_surveys', 'import_QMs']
- databaseReset.make_dirs()
- for item in importlist:
- if item in request.POST:
- print "running"+ " databaseReset."+item+"()"
- exec "databaseReset."+item+"()"
- jobs_completed.append(item)
- else:
- if request.user.is_authenticated(): #The user is logged in, but is not a superuser.
- return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'error':'You must be a superuser to use that feature.'})
- else:
- return HttpResponseRedirect(reverse('auth_login'))
-
- return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'expeditions':Expedition.objects.all(),'jobs_completed':jobs_completed})
-
-def downloadCavetab(request):
- from export import tocavetab
- response = HttpResponse(mimetype='text/csv')
- response['Content-Disposition'] = 'attachment; filename=CAVETAB2.CSV'
- tocavetab.writeCaveTab(response)
- return response
-
-def downloadSurveys(request):
- from export import tosurveys
- response = HttpResponse(mimetype='text/csv')
- response['Content-Disposition'] = 'attachment; filename=Surveys.csv'
- tosurveys.writeCaveTab(response)
- return response
-
-def downloadLogbook(request,year=None,extension=None,queryset=None):
-
- if year:
- expedition=Expedition.objects.get(year=year)
- logbook_entries=LogbookEntry.objects.filter(expedition=expedition)
- filename='logbook'+year
- elif queryset:
- logbook_entries=queryset
- filename='logbook'
- else:
- return response(r"Error: Logbook downloader doesn't know what year you want")
-
- if 'year' in request.GET:
- year=request.GET['year']
- if 'extension' in request.GET:
- extension=request.GET['extension']
-
-
-
- if extension =='txt':
- response = HttpResponse(mimetype='text/plain')
- style='2008'
- elif extension == 'html':
- response = HttpResponse(mimetype='text/html')
- style='2005'
-
- template='logbook'+style+'style.'+extension
- response['Content-Disposition'] = 'attachment; filename='+filename+'.'+extension
- t=loader.get_template(template)
- c=Context({'logbook_entries':logbook_entries})
- response.write(t.render(c))
- return response
-
-
-def downloadQMs(request):
- # Note to self: use get_cave method for the below
- if request.method=='GET':
- try:
- cave=Cave.objects.get(kataster_number=request.GET['cave_id'])
- except Cave.DoesNotExist:
- cave=Cave.objects.get(name=cave_id)
-
- from export import toqms
-
- response = HttpResponse(mimetype='text/csv')
- response['Content-Disposition'] = 'attachment; filename=qm.csv'
- toqms.writeQmTable(response,cave)
- return response
-
-def ajax_test(request):
- post_text = request.POST['post_data']
- return HttpResponse("{'response_text': '"+post_text+" recieved.'}",
- mimetype="application/json")
-
-def eyecandy(request):
- return
-
-def ajax_QM_number(request):
- if request.method=='POST':
- cave=Cave.objects.get(id=request.POST['cave'])
- print cave
- exp=Expedition.objects.get(pk=request.POST['year'])
- print exp
- res=cave.new_QM_number(exp.year)
-
- return HttpResponse(res)
-
-def logbook_entry_suggestions(request):
- """
- Generates a html box with suggestions about what to do with QMs
- in logbook entry text.
- """
- unwiki_QM_pattern=r"(?P<whole>(?P<explorer_code>[ABC]?)(?P<cave>\d*)-?(?P<year>\d\d\d?\d?)-(?P<number>\d\d)(?P<grade>[ABCDXV]?))"
- unwiki_QM_pattern=re.compile(unwiki_QM_pattern)
- #wikilink_QM_pattern=settings.QM_PATTERN
-
- slug=request.POST['slug']
- date=request.POST['date']
- lbo=LogbookEntry.objects.get(slug=slug, date=date)
-
- #unwiki_QMs=re.findall(unwiki_QM_pattern,lbo.text)
- unwiki_QMs=[m.groupdict() for m in unwiki_QM_pattern.finditer(lbo.text)]
-
- print unwiki_QMs
- for qm in unwiki_QMs:
- #try:
- if len(qm['year'])==2:
- if int(qm['year'])<50:
- qm['year']='20'+qm['year']
- else:
- qm['year']='19'+qm['year']
-
- if lbo.date.year!=int(qm['year']):
- try:
- lbo=LogbookEntry.objects.get(date__year=qm['year'],title__icontains="placeholder for QMs in")
- except:
- print "failed to get placeholder for year "+str(qm['year'])
-
- temp_QM=QM(found_by=lbo,number=qm['number'],grade=qm['grade'])
- temp_QM.grade=qm['grade']
- qm['wikilink']=temp_QM.wiki_link()
- #except:
- #print 'failed'
-
- print unwiki_QMs
-
-
- #wikilink_QMs=re.findall(wikilink_QM_pattern,lbo.text)
- attached_QMs=lbo.QMs_found.all()
- unmentioned_attached_QMs=''#not implemented, fill this in by subtracting wiklink_QMs from attached_QMs
-
- #Find unattached_QMs. We only look at the QMs with a proper wiki link.
- #for qm in wikilink_QMs:
- #Try to look up the QM.
-
- print 'got 208'
- any_suggestions=True
- print 'got 210'
- return render_with_context(request,'suggestions.html',
- {
- 'unwiki_QMs':unwiki_QMs,
- 'any_suggestions':any_suggestions
- })
-
-@login_required_if_public
-def newFile(request, pslug = None):
-# if pslug:
-# previousfile = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition)
-# assert previousfile.filename
- if request.method == 'POST': # If the form has been submitted...
- tripForm = TripForm(request.POST) # A form bound to the POST data
-# personTripFormSet = PersonTripFormSet(request.POST)
-# if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
-# dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d")
-# directory = os.path.join(settings.EXPOWEB,
-# "years",
-# expedition.year,
-# "autologbook")
-# filename = os.path.join(directory,
-# dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html")
-# if not os.path.isdir(directory):
-# os.mkdir(directory)
-# if pslug and pdate:
-# delLogbookEntry(previouslbe)
-# f = open(filename, "w")
-# template = loader.get_template('dataformat/logbookentry.html')
-# context = Context({'trip': tripForm.cleaned_data,
-# 'persons': personTripFormSet.cleaned_data,
-# 'date': dateStr,
-# 'expeditionyear': expeditionyear})
-# f.write(template.render(context))
-# f.close()
-# print logbookparsers.parseAutoLogBookEntry(filename)
-# return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
- else:
- if pslug:
- pass
-# if previouslbe.cave:
-# tripForm = TripForm(initial={"date": previousdate,
-# "title": previouslbe.title,
-# "cave": previouslbe.cave.reference(),
-# "location": None,
-# "caveOrLocation": "cave",
-# "html": previouslbe.text})
-# else:
-# tripForm = TripForm(initial={"date": previousdate,
-# "title": previouslbe.title,
-# "cave": None,
-# "location": previouslbe.place,
-# "caveOrLocation": "location",
-# "html": previouslbe.text})
-# personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition),
-# "TU": py.time_underground,
-# "author": py.is_logbook_entry_author}
-# for py in previouslbe.persontrip_set.all()])
- else:
- fileform = UploadFileForm() # An unbound form
-
- return render_with_context(request, 'editfile.html', {
- 'fileForm': fileform,
-
- })
-
-@login_required_if_public
-def deleteFile(request, expeditionyear, date = None, slug = None):
- expedition = Expedition.objects.get(year=expeditionyear)
- previousdate = datetime.date(*[int(x) for x in date.split("-")])
- previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition)
- delLogbookEntry(previouslbe)
- return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
-
-def delFile(f):
- for pt in lbe.persontrip_set.all():
- pt.delete()
- lbe.delete()
- os.remove(lbe.filename)
+from troggle.core.models import Cave, Expedition, Person, LogbookEntry, PersonExpedition, PersonTrip, DPhoto, QM
+from troggle.core.forms import UploadFileForm
+from django.conf import settings
+from django import forms
+from django.template import loader, Context
+from django.db.models import Q
+import databaseReset
+import re
+from django.http import HttpResponse, HttpResponseRedirect
+from django.core.urlresolvers import reverse
+from utils import render_with_context
+from core.models import *
+from troggle.helper import login_required_if_public
+
+def showrequest(request):
+ return HttpResponse(request.GET)
+
+def stats(request):
+ statsDict={}
+ statsDict['expoCount'] = int(Expedition.objects.count())
+ statsDict['caveCount'] = int(Cave.objects.count())
+ statsDict['personCount'] = int(Person.objects.count())
+ statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count())
+ return render_with_context(request,'statistics.html', statsDict)
+
+def frontpage(request):
+ if request.user.is_authenticated():
+ return render_with_context(request,'tasks.html')
+
+ expeditions = Expedition.objects.order_by("-year")
+ logbookentry = LogbookEntry
+ cave = Cave
+ photo = DPhoto
+ from django.contrib.admin.templatetags import log
+ return render_with_context(request,'frontpage.html', locals())
+
+def todo(request):
+ message = "no test message" #reverse('personn', kwargs={"name":"hkjhjh"})
+ if "reloadexpos" in request.GET:
+ message = LoadPersonsExpos()
+ message = "Reloaded personexpos"
+ if "reloadsurvex" in request.POST:
+ message = LoadAllSurvexBlocks()
+ message = "Reloaded survexblocks"
+
+ expeditions = Expedition.objects.order_by("-year")
+ totallogbookentries = LogbookEntry.objects.count()
+ return render_with_context(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message})
+
+
+def controlPanel(request):
+ jobs_completed=[]
+ if request.method=='POST':
+ if request.user.is_superuser:
+
+ #importlist is mostly here so that things happen in the correct order.
+ #http post data seems to come in an unpredictable order, so we do it this way.
+ importlist=['reload_db', 'import_people', 'import_cavetab', 'import_logbooks', 'import_surveys', 'import_QMs']
+ databaseReset.make_dirs()
+ for item in importlist:
+ if item in request.POST:
+ print "running"+ " databaseReset."+item+"()"
+ exec "databaseReset."+item+"()"
+ jobs_completed.append(item)
+ else:
+ if request.user.is_authenticated(): #The user is logged in, but is not a superuser.
+ return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'error':'You must be a superuser to use that feature.'})
+ else:
+ return HttpResponseRedirect(reverse('auth_login'))
+
+ return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'expeditions':Expedition.objects.all(),'jobs_completed':jobs_completed})
+
+def downloadCavetab(request):
+ from export import tocavetab
+ response = HttpResponse(mimetype='text/csv')
+ response['Content-Disposition'] = 'attachment; filename=CAVETAB2.CSV'
+ tocavetab.writeCaveTab(response)
+ return response
+
+def downloadSurveys(request):
+ from export import tosurveys
+ response = HttpResponse(mimetype='text/csv')
+ response['Content-Disposition'] = 'attachment; filename=Surveys.csv'
+ tosurveys.writeCaveTab(response)
+ return response
+
+def downloadLogbook(request,year=None,extension=None,queryset=None):
+
+ if year:
+ expedition=Expedition.objects.get(year=year)
+ logbook_entries=LogbookEntry.objects.filter(expedition=expedition)
+ filename='logbook'+year
+ elif queryset:
+ logbook_entries=queryset
+ filename='logbook'
+ else:
+ return response(r"Error: Logbook downloader doesn't know what year you want")
+
+ if 'year' in request.GET:
+ year=request.GET['year']
+ if 'extension' in request.GET:
+ extension=request.GET['extension']
+
+
+
+ if extension =='txt':
+ response = HttpResponse(mimetype='text/plain')
+ style='2008'
+ elif extension == 'html':
+ response = HttpResponse(mimetype='text/html')
+ style='2005'
+
+ template='logbook'+style+'style.'+extension
+ response['Content-Disposition'] = 'attachment; filename='+filename+'.'+extension
+ t=loader.get_template(template)
+ c=Context({'logbook_entries':logbook_entries})
+ response.write(t.render(c))
+ return response
+
+
+def downloadQMs(request):
+ # Note to self: use get_cave method for the below
+ if request.method=='GET':
+ try:
+ cave=Cave.objects.get(kataster_number=request.GET['cave_id'])
+ except Cave.DoesNotExist:
+ cave=Cave.objects.get(name=cave_id)
+
+ from export import toqms
+
+ response = HttpResponse(mimetype='text/csv')
+ response['Content-Disposition'] = 'attachment; filename=qm.csv'
+ toqms.writeQmTable(response,cave)
+ return response
+
+def ajax_test(request):
+ post_text = request.POST['post_data']
+ return HttpResponse("{'response_text': '"+post_text+" recieved.'}",
+ mimetype="application/json")
+
+def eyecandy(request):
+ return
+
+def ajax_QM_number(request):
+ if request.method=='POST':
+ cave=Cave.objects.get(id=request.POST['cave'])
+ print cave
+ exp=Expedition.objects.get(pk=request.POST['year'])
+ print exp
+ res=cave.new_QM_number(exp.year)
+
+ return HttpResponse(res)
+
+def logbook_entry_suggestions(request):
+ """
+ Generates a html box with suggestions about what to do with QMs
+ in logbook entry text.
+ """
+ unwiki_QM_pattern=r"(?P<whole>(?P<explorer_code>[ABC]?)(?P<cave>\d*)-?(?P<year>\d\d\d?\d?)-(?P<number>\d\d)(?P<grade>[ABCDXV]?))"
+ unwiki_QM_pattern=re.compile(unwiki_QM_pattern)
+ #wikilink_QM_pattern=settings.QM_PATTERN
+
+ slug=request.POST['slug']
+ date=request.POST['date']
+ lbo=LogbookEntry.objects.get(slug=slug, date=date)
+
+ #unwiki_QMs=re.findall(unwiki_QM_pattern,lbo.text)
+ unwiki_QMs=[m.groupdict() for m in unwiki_QM_pattern.finditer(lbo.text)]
+
+ print unwiki_QMs
+ for qm in unwiki_QMs:
+ #try:
+ if len(qm['year'])==2:
+ if int(qm['year'])<50:
+ qm['year']='20'+qm['year']
+ else:
+ qm['year']='19'+qm['year']
+
+ if lbo.date.year!=int(qm['year']):
+ try:
+ lbo=LogbookEntry.objects.get(date__year=qm['year'],title__icontains="placeholder for QMs in")
+ except:
+ print "failed to get placeholder for year "+str(qm['year'])
+
+ temp_QM=QM(found_by=lbo,number=qm['number'],grade=qm['grade'])
+ temp_QM.grade=qm['grade']
+ qm['wikilink']=temp_QM.wiki_link()
+ #except:
+ #print 'failed'
+
+ print unwiki_QMs
+
+
+ #wikilink_QMs=re.findall(wikilink_QM_pattern,lbo.text)
+ attached_QMs=lbo.QMs_found.all()
+ unmentioned_attached_QMs=''#not implemented, fill this in by subtracting wiklink_QMs from attached_QMs
+
+ #Find unattached_QMs. We only look at the QMs with a proper wiki link.
+ #for qm in wikilink_QMs:
+ #Try to look up the QM.
+
+ print 'got 208'
+ any_suggestions=True
+ print 'got 210'
+ return render_with_context(request,'suggestions.html',
+ {
+ 'unwiki_QMs':unwiki_QMs,
+ 'any_suggestions':any_suggestions
+ })
+
+@login_required_if_public
+def newFile(request, pslug = None):
+# if pslug:
+# previousfile = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition)
+# assert previousfile.filename
+ if request.method == 'POST': # If the form has been submitted...
+ tripForm = TripForm(request.POST) # A form bound to the POST data
+# personTripFormSet = PersonTripFormSet(request.POST)
+# if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
+# dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d")
+# directory = os.path.join(settings.EXPOWEB,
+# "years",
+# expedition.year,
+# "autologbook")
+# filename = os.path.join(directory,
+# dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html")
+# if not os.path.isdir(directory):
+# os.mkdir(directory)
+# if pslug and pdate:
+# delLogbookEntry(previouslbe)
+# f = open(filename, "w")
+# template = loader.get_template('dataformat/logbookentry.html')
+# context = Context({'trip': tripForm.cleaned_data,
+# 'persons': personTripFormSet.cleaned_data,
+# 'date': dateStr,
+# 'expeditionyear': expeditionyear})
+# f.write(template.render(context))
+# f.close()
+# print logbookparsers.parseAutoLogBookEntry(filename)
+# return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
+ else:
+ if pslug:
+ pass
+# if previouslbe.cave:
+# tripForm = TripForm(initial={"date": previousdate,
+# "title": previouslbe.title,
+# "cave": previouslbe.cave.reference(),
+# "location": None,
+# "caveOrLocation": "cave",
+# "html": previouslbe.text})
+# else:
+# tripForm = TripForm(initial={"date": previousdate,
+# "title": previouslbe.title,
+# "cave": None,
+# "location": previouslbe.place,
+# "caveOrLocation": "location",
+# "html": previouslbe.text})
+# personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition),
+# "TU": py.time_underground,
+# "author": py.is_logbook_entry_author}
+# for py in previouslbe.persontrip_set.all()])
+ else:
+ fileform = UploadFileForm() # An unbound form
+
+ return render_with_context(request, 'editfile.html', {
+ 'fileForm': fileform,
+
+ })
+
+@login_required_if_public
+def deleteFile(request, expeditionyear, date = None, slug = None):
+ expedition = Expedition.objects.get(year=expeditionyear)
+ previousdate = datetime.date(*[int(x) for x in date.split("-")])
+ previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition)
+ delLogbookEntry(previouslbe)
+ return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
+
+def delFile(f):
+ for pt in lbe.persontrip_set.all():
+ pt.delete()
+ lbe.delete()
+ os.remove(lbe.filename)
diff --git a/core/views_survex.py b/core/views_survex.py
index b6b5aba..8e7ac1e 100644
--- a/core/views_survex.py
+++ b/core/views_survex.py
@@ -1,318 +1,318 @@
-from django import forms
-from django.http import HttpResponseRedirect, HttpResponse
-from django.shortcuts import render_to_response
-from django.http import HttpResponse, Http404
-import re
-import os
-import datetime
-import difflib
-
-from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, Cave
-from troggle.core.models import SurvexBlock, SurvexPersonRole, SurvexFile, SurvexDirectory, SurvexTitle
-from parsers.people import GetPersonExpeditionNameLookup
-
-import troggle.settings as settings
-import parsers.survex
-
-survextemplatefile = """; Locn: Totes Gebirge, Austria - Loser/Augst-Eck Plateau (kataster group 1623)
-; Cave:
-
-*begin [surveyname]
-
-*export [connecting stations]
-
-*title "area title"
-*date 2999.99.99
-*team Insts [Caver]
-*team Insts [Caver]
-*team Notes [Caver]
-*instrument [set number]
-
-;ref.: 2009#NN
-
-*calibrate tape +0.0 ; +ve if tape was too short, -ve if too long
-
-*data normal from to tape compass clino
-1 2 3.90 298 -20
-
-*data passage station left right up down ignoreall
-1 [L] [R] [U] [D] comment
-
-*end [surveyname]"""
-
-
-def ReplaceTabs(stext):
- res = [ ]
- nsl = 0
- for s in re.split("(\t|\n)", stext):
- if s == "\t":
- res.append(" " * (4 - (nsl % 4)))
- nsl = 0
- continue
- if s == "\n":
- nsl = 0
- else:
- nsl += len(s)
- res.append(s)
- return "".join(res)
-
-
-class SvxForm(forms.Form):
- dirname = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
- filename = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
- datetime = forms.DateTimeField(widget=forms.TextInput(attrs={"readonly":True}))
- outputtype = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
- code = forms.CharField(widget=forms.Textarea(attrs={"cols":150, "rows":18}))
-
- def GetDiscCode(self):
- fname = settings.SURVEX_DATA + self.data['filename'] + ".svx"
- if not os.path.isfile(fname):
- return survextemplatefile
- fin = open(fname, "rb")
- svxtext = fin.read().decode("latin1") # unicode(a, "latin1")
- svxtext = ReplaceTabs(svxtext).strip()
- fin.close()
- return svxtext
-
- def DiffCode(self, rcode):
- code = self.GetDiscCode()
- difftext = difflib.unified_diff(code.splitlines(), rcode.splitlines())
- difflist = [ diffline.strip() for diffline in difftext if not re.match("\s*$", diffline) ]
- return difflist
-
- def SaveCode(self, rcode):
- fname = settings.SURVEX_DATA + self.data['filename'] + ".svx"
- if not os.path.isfile(fname):
- # only save if appears valid
- if re.search("\[|\]", rcode):
- return "Error: clean up all []s from the text"
- mbeginend = re.search("(?s)\*begin\s+(\w+).*?\*end\s+(\w+)", rcode)
- if not mbeginend:
- return "Error: no begin/end block here"
- if mbeginend.group(1) != mbeginend.group(2):
- return "Error: mismatching beginend"
-
- fout = open(fname, "w")
- res = fout.write(rcode.encode("latin1"))
- fout.close()
- return "SAVED"
-
- def Process(self):
- print "....\n\n\n....Processing\n\n\n"
- cwd = os.getcwd()
- os.chdir(os.path.split(settings.SURVEX_DATA + self.data['filename'])[0])
- os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + self.data['filename'] + ".svx")
- os.chdir(cwd)
- fin = open(settings.SURVEX_DATA + self.data['filename'] + ".log", "rb")
- log = fin.read()
- fin.close()
- log = re.sub("(?s).*?(Survey contains)", "\\1", log)
- return log
-
-
-def svx(request, survex_file):
- # get the basic data from the file given in the URL
- dirname = os.path.split(survex_file)[0]
- dirname += "/"
- nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- outputtype = "normal"
- form = SvxForm({'filename':survex_file, 'dirname':dirname, 'datetime':nowtime, 'outputtype':outputtype})
-
- # if the form has been returned
- difflist = [ ]
- logmessage = ""
- message = ""
-
- if request.method == 'POST': # If the form has been submitted...
- rform = SvxForm(request.POST) #
- if rform.is_valid(): # All validation rules pass (how do we check it against the filename and users?)
- rcode = rform.cleaned_data['code']
- outputtype = rform.cleaned_data['outputtype']
- difflist = form.DiffCode(rcode)
- #print "ssss", rform.data
-
- if "revert" in rform.data:
- pass
- if "process" in rform.data:
- if not difflist:
- message = "OUTPUT FROM PROCESSING"
- logmessage = form.Process()
- print logmessage
- else:
- message = "SAVE FILE FIRST"
- form.data['code'] = rcode
- if "save" in rform.data:
- if request.user.is_authenticated():
- #print "sssavvving"
- message = form.SaveCode(rcode)
- else:
- message = "You do not have authority to save this file"
- if message != "SAVED":
- form.data['code'] = rcode
- if "diff" in rform.data:
- form.data['code'] = rcode
-
-
- #process(survex_file)
- if 'code' not in form.data:
- form.data['code'] = form.GetDiscCode()
-
- if not difflist:
- difflist.append("none")
- if message:
- difflist.insert(0, message)
-
- #print [ form.data['code'] ]
- svxincludes = re.findall('\*include\s+(\S+)(?i)', form.data['code'] or "")
-
- vmap = {'settings': settings,
- 'has_3d': os.path.isfile(settings.SURVEX_DATA + survex_file + ".3d"),
- 'title': survex_file,
- 'svxincludes': svxincludes,
- 'difflist': difflist,
- 'logmessage':logmessage,
- 'form':form}
- if outputtype == "ajax":
- return render_to_response('svxfiledifflistonly.html', vmap)
- return render_to_response('svxfile.html', vmap)
-
-def svxraw(request, survex_file):
- svx = open(os.path.join(settings.SURVEX_DATA, survex_file+".svx"), "rb")
- return HttpResponse(svx, mimetype="text")
-
-
-# The cavern running function
-def process(survex_file):
- cwd = os.getcwd()
- os.chdir(os.path.split(settings.SURVEX_DATA + survex_file)[0])
- os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + survex_file + ".svx")
- os.chdir(cwd)
-
-
-def threed(request, survex_file):
- process(survex_file)
- try:
- threed = open(settings.SURVEX_DATA + survex_file + ".3d", "rb")
- return HttpResponse(threed, mimetype="model/3d")
- except:
- log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
- return HttpResponse(log, mimetype="text")
-
-def log(request, survex_file):
- process(survex_file)
- log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
- return HttpResponse(log, mimetype="text")
-
-def err(request, survex_file):
- process(survex_file)
- err = open(settings.SURVEX_DATA + survex_file + ".err", "rb")
- return HttpResponse(err, mimetype="text")
-
-
-
-def identifycavedircontents(gcavedir):
- name = os.path.split(gcavedir)[1]
- subdirs = [ ]
- subsvx = [ ]
- primesvx = None
- for f in os.listdir(gcavedir):
- if name == "204" and (f in ["skel.svx", "template.svx", "204withents.svx"]):
- pass
- elif name == "136" and (f in ["136-noents.svx"]):
- pass
- elif name == "115" and (f in ["115cufix.svx", "115fix.svx"]):
- pass
-
- elif os.path.isdir(os.path.join(gcavedir, f)):
- if f[0] != ".":
- subdirs.append(f)
- elif f[-4:] == ".svx":
- nf = f[:-4]
-
- if nf.lower() == name.lower() or nf[:3] == "all" or (name, nf) in [("144arge", "144"), ("resurvey2005", "145-2005"), ("cucc", "cu115")]:
- if primesvx:
- if nf[:3] == "all":
- assert primesvx[:3] != "all", (name, nf, primesvx, gcavedir, subsvx)
- primesvx = nf
- else:
- assert primesvx[:3] == "all", (name, nf, primesvx, gcavedir, subsvx)
- else:
- primesvx = nf
- else:
- subsvx.append(nf)
- else:
- assert re.match(".*?(?:.3d|.log|.err|.txt|.tmp|.diff|.e?spec|~)$", f), (gcavedir, f)
- subsvx.sort()
- assert primesvx, (gcavedir, subsvx)
- if primesvx:
- subsvx.insert(0, primesvx)
- return subdirs, subsvx
-
-
-
-# direct local non-database browsing through the svx file repositories
-# perhaps should use the database and have a reload button for it
-def survexcaveslist(request):
- cavesdir = os.path.join(settings.SURVEX_DATA, "caves")
- cavesdircontents = { }
-
- onefilecaves = [ ]
- multifilecaves = [ ]
- subdircaves = [ ]
-
- # first sort the file list
- fnumlist = [ (-int(re.match("\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir) ]
- fnumlist.sort()
-
- # go through the list and identify the contents of each cave directory
- for num, cavedir in fnumlist:
- if cavedir in ["144", "40"]:
- continue
-
- gcavedir = os.path.join(cavesdir, cavedir)
- if os.path.isdir(gcavedir) and cavedir[0] != ".":
- subdirs, subsvx = identifycavedircontents(gcavedir)
- survdirobj = [ ]
-
- for lsubsvx in subsvx:
- survdirobj.append(("caves/"+cavedir+"/"+lsubsvx, lsubsvx))
-
- # caves with subdirectories
- if subdirs:
- subsurvdirs = [ ]
- for subdir in subdirs:
- dsubdirs, dsubsvx = identifycavedircontents(os.path.join(gcavedir, subdir))
- assert not dsubdirs
- lsurvdirobj = [ ]
- for lsubsvx in dsubsvx:
- lsurvdirobj.append(("caves/"+cavedir+"/"+subdir+"/"+lsubsvx, lsubsvx))
- subsurvdirs.append((lsurvdirobj[0], lsurvdirobj[1:]))
- subdircaves.append((cavedir, (survdirobj[0], survdirobj[1:]), subsurvdirs))
-
- # multifile caves
- elif len(survdirobj) > 1:
- multifilecaves.append((survdirobj[0], survdirobj[1:]))
- # single file caves
- else:
- onefilecaves.append(survdirobj[0])
-
- return render_to_response('svxfilecavelist.html', {'settings': settings, "onefilecaves":onefilecaves, "multifilecaves":multifilecaves, "subdircaves":subdircaves })
-
-
-
-
-
-
-# parsing all the survex files of a single cave and showing that it's consistent and can find all the files and people
-# doesn't use recursion. just writes it twice
-def survexcavesingle(request, survex_cave):
- breload = False
- cave = Cave.objects.get(kataster_number=survex_cave)
- if breload:
- parsers.survex.ReloadSurvexCave(survex_cave)
- return render_to_response('svxcavesingle.html', {'settings': settings, "cave":cave })
-
-
-
-
+from django import forms
+from django.http import HttpResponseRedirect, HttpResponse
+from django.shortcuts import render_to_response
+from django.http import HttpResponse, Http404
+import re
+import os
+import datetime
+import difflib
+
+from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, Cave
+from troggle.core.models import SurvexBlock, SurvexPersonRole, SurvexFile, SurvexDirectory, SurvexTitle
+from parsers.people import GetPersonExpeditionNameLookup
+
+import troggle.settings as settings
+import parsers.survex
+
+survextemplatefile = """; Locn: Totes Gebirge, Austria - Loser/Augst-Eck Plateau (kataster group 1623)
+; Cave:
+
+*begin [surveyname]
+
+*export [connecting stations]
+
+*title "area title"
+*date 2999.99.99
+*team Insts [Caver]
+*team Insts [Caver]
+*team Notes [Caver]
+*instrument [set number]
+
+;ref.: 2009#NN
+
+*calibrate tape +0.0 ; +ve if tape was too short, -ve if too long
+
+*data normal from to tape compass clino
+1 2 3.90 298 -20
+
+*data passage station left right up down ignoreall
+1 [L] [R] [U] [D] comment
+
+*end [surveyname]"""
+
+
+def ReplaceTabs(stext):
+ res = [ ]
+ nsl = 0
+ for s in re.split("(\t|\n)", stext):
+ if s == "\t":
+ res.append(" " * (4 - (nsl % 4)))
+ nsl = 0
+ continue
+ if s == "\n":
+ nsl = 0
+ else:
+ nsl += len(s)
+ res.append(s)
+ return "".join(res)
+
+
+class SvxForm(forms.Form):
+ dirname = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
+ filename = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
+ datetime = forms.DateTimeField(widget=forms.TextInput(attrs={"readonly":True}))
+ outputtype = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
+ code = forms.CharField(widget=forms.Textarea(attrs={"cols":150, "rows":18}))
+
+ def GetDiscCode(self):
+ fname = settings.SURVEX_DATA + self.data['filename'] + ".svx"
+ if not os.path.isfile(fname):
+ return survextemplatefile
+ fin = open(fname, "rb")
+ svxtext = fin.read().decode("latin1") # unicode(a, "latin1")
+ svxtext = ReplaceTabs(svxtext).strip()
+ fin.close()
+ return svxtext
+
+ def DiffCode(self, rcode):
+ code = self.GetDiscCode()
+ difftext = difflib.unified_diff(code.splitlines(), rcode.splitlines())
+ difflist = [ diffline.strip() for diffline in difftext if not re.match("\s*$", diffline) ]
+ return difflist
+
+ def SaveCode(self, rcode):
+ fname = settings.SURVEX_DATA + self.data['filename'] + ".svx"
+ if not os.path.isfile(fname):
+ # only save if appears valid
+ if re.search("\[|\]", rcode):
+ return "Error: clean up all []s from the text"
+ mbeginend = re.search("(?s)\*begin\s+(\w+).*?\*end\s+(\w+)", rcode)
+ if not mbeginend:
+ return "Error: no begin/end block here"
+ if mbeginend.group(1) != mbeginend.group(2):
+ return "Error: mismatching beginend"
+
+ fout = open(fname, "w")
+ res = fout.write(rcode.encode("latin1"))
+ fout.close()
+ return "SAVED"
+
+ def Process(self):
+ print "....\n\n\n....Processing\n\n\n"
+ cwd = os.getcwd()
+ os.chdir(os.path.split(settings.SURVEX_DATA + self.data['filename'])[0])
+ os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + self.data['filename'] + ".svx")
+ os.chdir(cwd)
+ fin = open(settings.SURVEX_DATA + self.data['filename'] + ".log", "rb")
+ log = fin.read()
+ fin.close()
+ log = re.sub("(?s).*?(Survey contains)", "\\1", log)
+ return log
+
+
+def svx(request, survex_file):
+ # get the basic data from the file given in the URL
+ dirname = os.path.split(survex_file)[0]
+ dirname += "/"
+ nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+ outputtype = "normal"
+ form = SvxForm({'filename':survex_file, 'dirname':dirname, 'datetime':nowtime, 'outputtype':outputtype})
+
+ # if the form has been returned
+ difflist = [ ]
+ logmessage = ""
+ message = ""
+
+ if request.method == 'POST': # If the form has been submitted...
+ rform = SvxForm(request.POST) #
+ if rform.is_valid(): # All validation rules pass (how do we check it against the filename and users?)
+ rcode = rform.cleaned_data['code']
+ outputtype = rform.cleaned_data['outputtype']
+ difflist = form.DiffCode(rcode)
+ #print "ssss", rform.data
+
+ if "revert" in rform.data:
+ pass
+ if "process" in rform.data:
+ if not difflist:
+ message = "OUTPUT FROM PROCESSING"
+ logmessage = form.Process()
+ print logmessage
+ else:
+ message = "SAVE FILE FIRST"
+ form.data['code'] = rcode
+ if "save" in rform.data:
+ if request.user.is_authenticated():
+ #print "sssavvving"
+ message = form.SaveCode(rcode)
+ else:
+ message = "You do not have authority to save this file"
+ if message != "SAVED":
+ form.data['code'] = rcode
+ if "diff" in rform.data:
+ form.data['code'] = rcode
+
+
+ #process(survex_file)
+ if 'code' not in form.data:
+ form.data['code'] = form.GetDiscCode()
+
+ if not difflist:
+ difflist.append("none")
+ if message:
+ difflist.insert(0, message)
+
+ #print [ form.data['code'] ]
+ svxincludes = re.findall('\*include\s+(\S+)(?i)', form.data['code'] or "")
+
+ vmap = {'settings': settings,
+ 'has_3d': os.path.isfile(settings.SURVEX_DATA + survex_file + ".3d"),
+ 'title': survex_file,
+ 'svxincludes': svxincludes,
+ 'difflist': difflist,
+ 'logmessage':logmessage,
+ 'form':form}
+ if outputtype == "ajax":
+ return render_to_response('svxfiledifflistonly.html', vmap)
+ return render_to_response('svxfile.html', vmap)
+
+def svxraw(request, survex_file):
+ svx = open(os.path.join(settings.SURVEX_DATA, survex_file+".svx"), "rb")
+ return HttpResponse(svx, mimetype="text")
+
+
+# The cavern running function
+def process(survex_file):
+ cwd = os.getcwd()
+ os.chdir(os.path.split(settings.SURVEX_DATA + survex_file)[0])
+ os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + survex_file + ".svx")
+ os.chdir(cwd)
+
+
+def threed(request, survex_file):
+ process(survex_file)
+ try:
+ threed = open(settings.SURVEX_DATA + survex_file + ".3d", "rb")
+ return HttpResponse(threed, mimetype="model/3d")
+ except:
+ log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
+ return HttpResponse(log, mimetype="text")
+
+def log(request, survex_file):
+ process(survex_file)
+ log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
+ return HttpResponse(log, mimetype="text")
+
+def err(request, survex_file):
+ process(survex_file)
+ err = open(settings.SURVEX_DATA + survex_file + ".err", "rb")
+ return HttpResponse(err, mimetype="text")
+
+
+
+def identifycavedircontents(gcavedir):
+ name = os.path.split(gcavedir)[1]
+ subdirs = [ ]
+ subsvx = [ ]
+ primesvx = None
+ for f in os.listdir(gcavedir):
+ if name == "204" and (f in ["skel.svx", "template.svx", "204withents.svx"]):
+ pass
+ elif name == "136" and (f in ["136-noents.svx"]):
+ pass
+ elif name == "115" and (f in ["115cufix.svx", "115fix.svx"]):
+ pass
+
+ elif os.path.isdir(os.path.join(gcavedir, f)):
+ if f[0] != ".":
+ subdirs.append(f)
+ elif f[-4:] == ".svx":
+ nf = f[:-4]
+
+ if nf.lower() == name.lower() or nf[:3] == "all" or (name, nf) in [("144arge", "144"), ("resurvey2005", "145-2005"), ("cucc", "cu115")]:
+ if primesvx:
+ if nf[:3] == "all":
+ assert primesvx[:3] != "all", (name, nf, primesvx, gcavedir, subsvx)
+ primesvx = nf
+ else:
+ assert primesvx[:3] == "all", (name, nf, primesvx, gcavedir, subsvx)
+ else:
+ primesvx = nf
+ else:
+ subsvx.append(nf)
+ else:
+ assert re.match(".*?(?:.3d|.log|.err|.txt|.tmp|.diff|.e?spec|~)$", f), (gcavedir, f)
+ subsvx.sort()
+ assert primesvx, (gcavedir, subsvx)
+ if primesvx:
+ subsvx.insert(0, primesvx)
+ return subdirs, subsvx
+
+
+
+# direct local non-database browsing through the svx file repositories
+# perhaps should use the database and have a reload button for it
+def survexcaveslist(request):
+ cavesdir = os.path.join(settings.SURVEX_DATA, "caves")
+ cavesdircontents = { }
+
+ onefilecaves = [ ]
+ multifilecaves = [ ]
+ subdircaves = [ ]
+
+ # first sort the file list
+ fnumlist = [ (-int(re.match("\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir) ]
+ fnumlist.sort()
+
+ # go through the list and identify the contents of each cave directory
+ for num, cavedir in fnumlist:
+ if cavedir in ["144", "40"]:
+ continue
+
+ gcavedir = os.path.join(cavesdir, cavedir)
+ if os.path.isdir(gcavedir) and cavedir[0] != ".":
+ subdirs, subsvx = identifycavedircontents(gcavedir)
+ survdirobj = [ ]
+
+ for lsubsvx in subsvx:
+ survdirobj.append(("caves/"+cavedir+"/"+lsubsvx, lsubsvx))
+
+ # caves with subdirectories
+ if subdirs:
+ subsurvdirs = [ ]
+ for subdir in subdirs:
+ dsubdirs, dsubsvx = identifycavedircontents(os.path.join(gcavedir, subdir))
+ assert not dsubdirs
+ lsurvdirobj = [ ]
+ for lsubsvx in dsubsvx:
+ lsurvdirobj.append(("caves/"+cavedir+"/"+subdir+"/"+lsubsvx, lsubsvx))
+ subsurvdirs.append((lsurvdirobj[0], lsurvdirobj[1:]))
+ subdircaves.append((cavedir, (survdirobj[0], survdirobj[1:]), subsurvdirs))
+
+ # multifile caves
+ elif len(survdirobj) > 1:
+ multifilecaves.append((survdirobj[0], survdirobj[1:]))
+ # single file caves
+ else:
+ onefilecaves.append(survdirobj[0])
+
+ return render_to_response('svxfilecavelist.html', {'settings': settings, "onefilecaves":onefilecaves, "multifilecaves":multifilecaves, "subdircaves":subdircaves })
+
+
+
+
+
+
+# parsing all the survex files of a single cave and showing that it's consistent and can find all the files and people
+# doesn't use recursion. just writes it twice
+def survexcavesingle(request, survex_cave):
+ breload = False
+ cave = Cave.objects.get(kataster_number=survex_cave)
+ if breload:
+ parsers.survex.ReloadSurvexCave(survex_cave)
+ return render_to_response('svxcavesingle.html', {'settings': settings, "cave":cave })
+
+
+
+
\ No newline at end of file