From dc1327674c2676db02ccf525725019cd9115b699 Mon Sep 17 00:00:00 2001 From: Wookey Date: Mon, 11 Jul 2011 02:10:22 +0100 Subject: [PATCH] remove all the DOS linefeeds --- README.txt | 78 +- core/admin.py | 282 ++-- core/forms.py | 242 +-- core/models.py | 1400 ++++++++--------- core/models_survex.py | 426 ++--- core/templatetags/link.py | 18 +- core/templatetags/survex_markup.py | 102 +- core/templatetags/wiki_markup.py | 338 ++-- core/view_surveys.py | 466 +++--- core/views.py | 16 +- core/views_caves.py | 282 ++-- core/views_logbooks.py | 504 +++--- core/views_other.py | 564 +++---- core/views_survex.py | 634 ++++---- databaseReset.py | 434 ++--- export/tocavetab.py | 98 +- export/toqms.py | 56 +- localsettingswindows.py | 116 +- manage.py | 22 +- middleware.py | 98 +- parsers/cavetab.py | 506 +++--- parsers/descriptions.py | 88 +- parsers/logbooks.py | 864 +++++----- parsers/subcaves.py | 112 +- parsers/surveys.py | 602 +++---- templates/admin/base_site.html | 20 +- templates/base.html | 222 +-- templates/cave.html | 86 +- templates/cave_description.html | 36 +- templates/cavebase.html | 52 +- templates/caveindex.html | 74 +- templates/controlPanel.html | 312 ++-- templates/editfile.html | 192 +-- templates/entrance.html | 160 +- templates/expedition.html | 174 +- templates/eyecandy.html | 4 +- templates/fileupload.html | 36 +- templates/frontpage.html | 134 +- templates/index.html | 118 +- templates/listdir.html | 44 +- templates/logbook2005style.html | 52 +- templates/logbook2008style.txt | 10 +- templates/logbookentry.html | 154 +- templates/newlogbookentry.html | 166 +- templates/nonpublic.html | 16 +- templates/object_list.html | 28 +- templates/person.html | 86 +- templates/personForm.html | 10 +- templates/personexpedition.html | 114 +- templates/personindex.html | 88 +- templates/profiles/create_profile.html | 24 +- templates/profiles/edit_profile.html | 24 +- templates/profiles/profile_detail.html | 26 +- templates/profiles/select_profile.html | 78 +- templates/qm.html | 98 +- templates/registration/activate.html | 48 +- templates/registration/activation_email.html | 20 +- templates/registration/activation_email.txt | 18 +- templates/registration/login.html | 40 +- templates/registration/logout.html | 6 +- .../registration/registration_activate.html | 10 +- .../registration/registration_complete.html | 24 +- templates/statistics.html | 14 +- templates/subcave.html | 116 +- templates/survexblock.html | 98 +- templates/survexscansfolder.html | 66 +- templates/survexscansfolders.html | 48 +- templates/survey.html | 386 ++--- templates/svxcavesingle.html | 162 +- templates/svxfile.html | 152 +- templates/svxfilecavelist.html | 132 +- templates/svxfiledifflistonly.html | 36 +- templates/tasks.html | 78 +- templates/todo.html | 122 +- templates/tunnelfiles.html | 84 +- 75 files changed, 6323 insertions(+), 6323 deletions(-) diff --git a/README.txt b/README.txt index 93de045..2913653 100644 --- a/README.txt +++ b/README.txt @@ -1,39 +1,39 @@ -Troggle is an application for caving expedition data management, originally created for use on Cambridge University Caving Club expeditions and licensed under the GNU Lesser General Public License. - -Troggle setup -========== - -Python, Django, and Database setup ------------------------------------ -Troggle requires Django 1.1 or greater, and any version of Python that works with it. As of writing this readme, there was no actual Django 1.1 release, so Troggle required the SVN version of Django. Check Django out to somewhere on your PYTHONPATH with the following command: - -svn co http://code.djangoproject.com/svn/django/trunk/ - -If you have an older installation of Django installed on your system, the easiest way to make sure troggle is using the newest version of Django is to simply checkout into your top troggle directory, into a folder called django. - -If you want to use MySQL or Postgresql, download and install them. However, you can also use Django with Sqlite3, which is included in Python and thus requires no extra installation. - - - -Troggle itself -------------- -Choose a directory where you will keep troggle, and svn check out Troggle into it using the following command: - -svn co http://troggle.googlecode.com/svn/ - -If you want to work on the source code and be able to commit, you will need to use https instead of http, and your google account will need to be added to the troggle project members list. Contact aaron dot curtis at cantab dot net to get this set up. - -Next, you need to fill in your local settings. Copy either localsettingsubuntu.py or localsettingsserver.py to a new file called localsettings.py. Follow the instructions contained in the file to fill out your settings. - -Setting up tables and importing legacy data ------------------------------------------- -Run "python databaseReset.py reset" from the troggle directory. - -Once troggle is running, you can also log in and then go to "Import / export" data under "admin" on the menu. - -Running a Troggle server ------------------------- -For high volume use, Troggle should be run using a web server like apache. However, a quick way to get started is to use the development server built into Django. - -To do this, run "python manage.py runserver" from the troggle directory. - +Troggle is an application for caving expedition data management, originally created for use on Cambridge University Caving Club expeditions and licensed under the GNU Lesser General Public License. + +Troggle setup +========== + +Python, Django, and Database setup +----------------------------------- +Troggle requires Django 1.1 or greater, and any version of Python that works with it. As of writing this readme, there was no actual Django 1.1 release, so Troggle required the SVN version of Django. Check Django out to somewhere on your PYTHONPATH with the following command: + +svn co http://code.djangoproject.com/svn/django/trunk/ + +If you have an older installation of Django installed on your system, the easiest way to make sure troggle is using the newest version of Django is to simply checkout into your top troggle directory, into a folder called django. + +If you want to use MySQL or Postgresql, download and install them. However, you can also use Django with Sqlite3, which is included in Python and thus requires no extra installation. + + + +Troggle itself +------------- +Choose a directory where you will keep troggle, and svn check out Troggle into it using the following command: + +svn co http://troggle.googlecode.com/svn/ + +If you want to work on the source code and be able to commit, you will need to use https instead of http, and your google account will need to be added to the troggle project members list. Contact aaron dot curtis at cantab dot net to get this set up. + +Next, you need to fill in your local settings. Copy either localsettingsubuntu.py or localsettingsserver.py to a new file called localsettings.py. Follow the instructions contained in the file to fill out your settings. + +Setting up tables and importing legacy data +------------------------------------------ +Run "python databaseReset.py reset" from the troggle directory. + +Once troggle is running, you can also log in and then go to "Import / export" data under "admin" on the menu. + +Running a Troggle server +------------------------ +For high volume use, Troggle should be run using a web server like apache. However, a quick way to get started is to use the development server built into Django. + +To do this, run "python manage.py runserver" from the troggle directory. + 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'

QMs found:') -# for QM in LogbookEntry.instance.QMs_found.all(): -# res.append(QM.wiki_link()) - -# res.append(r'

QMs ticked off:') -# for QM in LogbookEntry.instance.QMs_ticked_off.all(): -# res.append(QM.wiki_link()) - -# res.append(r'

People') -# for persontrip in LogbookEntry.instance.persontrip_set.all(): -# res.append(persontrip.wiki_link()) -# res.append(r'

') - -# return string.join(res, r'
') - -# 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'

QMs found:') +# for QM in LogbookEntry.instance.QMs_found.all(): +# res.append(QM.wiki_link()) + +# res.append(r'

QMs ticked off:') +# for QM in LogbookEntry.instance.QMs_ticked_off.all(): +# res.append(QM.wiki_link()) + +# res.append(r'

People') +# for persontrip in LogbookEntry.instance.persontrip_set.all(): +# res.append(persontrip.wiki_link()) +# res.append(r'

') + +# return string.join(res, r'
') + +# 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ür Hö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 += "–" + prevR - else: - prevR = r - n = 0 - res += r - if n == 0: - res += ", " + prevR - else: - res += "–" + 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ür Hö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 += "–" + prevR + else: + prevR = r + n = 0 + res += r + if n == 0: + res += ", " + prevR + else: + res += "–" + 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(""%value.get_absolute_url()+unicode(value)+"") - +from django import template +from django.utils.safestring import mark_safe + +register = template.Library() + +@register.filter() +def link(value): + return mark_safe(""%value.get_absolute_url()+unicode(value)+"") + 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'\1\n')) -regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)(.svx)$", re.IGNORECASE|re.MULTILINE), - r'\1\2\3\4\5')) -regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)$", re.IGNORECASE|re.MULTILINE), - r'\1\2\3\4')) -regexes.append((re.compile(r"^(\s*)(\*team\s+(?:notes|tape|insts|pics))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), - r'\1\2\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\2\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\2\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\2')) -regexes.append((re.compile(r"^(\s*)(\*default\s+(?:CALIBRATE|DATA|UNITS)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), - r'\1\2\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\2\3\4')) -regexes.append((re.compile(r"^(\s*)(\*infer\s+(?:plumbs|equates|exports))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), - r'\1\2\3\4')) -regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), - r'\1\2\3\4')) -regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), - r'\1\2\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\2\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\2\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\2\3\4')) -regexes.append((re.compile(r"^(.*)$", re.IGNORECASE|re.MULTILINE), - r'
\1 
\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'\1\n')) +regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)(.svx)$", re.IGNORECASE|re.MULTILINE), + r'\1\2\3\4\5')) +regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)$", re.IGNORECASE|re.MULTILINE), + r'\1\2\3\4')) +regexes.append((re.compile(r"^(\s*)(\*team\s+(?:notes|tape|insts|pics))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1\2\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\2\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\2\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\2')) +regexes.append((re.compile(r"^(\s*)(\*default\s+(?:CALIBRATE|DATA|UNITS)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1\2\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\2\3\4')) +regexes.append((re.compile(r"^(\s*)(\*infer\s+(?:plumbs|equates|exports))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1\2\3\4')) +regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1\2\3\4')) +regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1\2\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\2\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\2\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\2\3\4')) +regexes.append((re.compile(r"^(.*)$", re.IGNORECASE|re.MULTILINE), + r'
\1 
\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 ("\n" + t, l) - if prev == "#": - t, l = wiki_list(line, listdepth) - return ("\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 += "

" - outValue += wiki_to_html_short(paragraph, autoescape) - outValue += "

\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("&(.*?);", r"&\1;", value, re.DOTALL) - #italics and bold - value = re.sub("''''([^']+)''''", r"\1", value, re.DOTALL) - value = re.sub("'b''([^']+)'''", r"\1", value, re.DOTALL) - value = re.sub("''([^']+)''", r"\1", value, re.DOTALL) - - #make headers - def headerrepl(matchobj): - number=len(matchobj.groups()[0]) - num=str(number) - if number>1: - return ''+matchobj.groups()[1]+'' - 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'%s' % (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'%s' % (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[^\s]+)\s*(?P.*)\]\]" - photoSrcPattern="\[\[\s*display:(?P - - -

Expo {{logbook_entries.0.expedition}}

- -{%for logbook_entry in logbook_entries%} -
- -
{{logbook_entry.date}}
-
{{logbook_entry.author.person}} -{% for persontrip in logbook_entry.persontrip_set.all %}{{ persontrip.personexpedition.person }} {{ persontrip.personexpedition.time_underground }}, {% endfor %} -
- -
{{logbook_entry.place}} - {{logbook_entry.title}}
- -{{logbook_entry.text|safe}} -{% endfor %} + +{{logbook_entries.0.expedition}} Expo Logbook + + + + +

Expo {{logbook_entries.0.expedition}}

+ +{%for logbook_entry in logbook_entries%} +
+ +
{{logbook_entry.date}}
+
{{logbook_entry.author.person}} +{% for persontrip in logbook_entry.persontrip_set.all %}{{ persontrip.personexpedition.person }} {{ persontrip.personexpedition.time_underground }}, {% endfor %} +
+ +
{{logbook_entry.place}} - {{logbook_entry.title}}
+ +{{logbook_entry.text|safe}} +{% endfor %} diff --git a/templates/logbook2008style.txt b/templates/logbook2008style.txt index a7fbea7..2725995 100644 --- a/templates/logbook2008style.txt +++ b/templates/logbook2008style.txt @@ -1,6 +1,6 @@ -=Expo {{logbook_entries.0.expedition}} logbook == -{%for logbook_entry in logbook_entries%} -==={{logbook_entry.date}} | {{logbook_entry.place}} - {{logbook_entry.title}} | {% for persontrip in logbook_entry.persontrip_set.all %}{{ persontrip.person_expedition.person }} {{ persontrip.person_expedition.time_underground }}, {% endfor %}=== - -{{logbook_entry.text|safe}} +=Expo {{logbook_entries.0.expedition}} logbook == +{%for logbook_entry in logbook_entries%} +==={{logbook_entry.date}} | {{logbook_entry.place}} - {{logbook_entry.title}} | {% for persontrip in logbook_entry.persontrip_set.all %}{{ persontrip.person_expedition.person }} {{ persontrip.person_expedition.time_underground }}, {% endfor %}=== + +{{logbook_entry.text|safe}} {% endfor %} \ No newline at end of file diff --git a/templates/logbookentry.html b/templates/logbookentry.html index 04229fb..a3ffc3d 100644 --- a/templates/logbookentry.html +++ b/templates/logbookentry.html @@ -1,77 +1,77 @@ -{% extends "base.html" %} -{% load wiki_markup %} - -{% block title %}Logbook {{logbookentry.id}}{% endblock %} -{% block editLink %}Edit logbook entry {{logbookentry|wiki_to_html_short}}{% endblock %} -{% block content %} - -{% block related %}{% endblock %} -{% block nav %}{% endblock %} -

{{logbookentry.title}}

- - - -
-
-{{logbookentry.date}} - {{logbookentry.text|wiki_to_html}}
-
- - -{% if logbookentry.filename %}Edit Delete{%endif%} - - -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Logbook {{logbookentry.id}}{% endblock %} +{% block editLink %}Edit logbook entry {{logbookentry|wiki_to_html_short}}{% endblock %} +{% block content %} + +{% block related %}{% endblock %} +{% block nav %}{% endblock %} +

{{logbookentry.title}}

+ + + +
+
+{{logbookentry.date}} + {{logbookentry.text|wiki_to_html}}
+
+ + +{% if logbookentry.filename %}Edit Delete{%endif%} + + +{% endblock %} diff --git a/templates/newlogbookentry.html b/templates/newlogbookentry.html index 4e8eda6..36e8591 100644 --- a/templates/newlogbookentry.html +++ b/templates/newlogbookentry.html @@ -1,83 +1,83 @@ -{% extends "base.html" %} -{% load csrffaker %} -{% block title %}Logbook {{logbookentry.id}}{% endblock %} -{% block head %} - - - - - -{{ tripForm.media }} -{% endblock %} -{% block content %} - -
{% csrf_token %} - {{ tripForm.non_field_errors }} -
- {{ tripForm.title.errors }} - - {{ tripForm.title }} -
-
- {{ tripForm.date.errors }} - - {{ tripForm.date }} -
-
- {{ tripForm.caveOrLocation.errors }} - - {{ tripForm.caveOrLocation }} -
-
- {{ tripForm.cave.errors }} - - {{ tripForm.cave }} -
-
- {{ tripForm.location.errors }} - - {{ tripForm.location }} -
- - - - - - - - - {% for form in personTripFormSet.forms %} - - - - - - {{ form.non_field_errors }} - - {% endfor %} - -
PersonTU /hoursAuthor
{{ form.name.errors }}{{ form.name }}{{ form.TU.errors }}{{ form.TU }}{{ form.author.errors }}{{ form.author }}
- {{ personTripFormSet.management_form }} -
- {{ tripForm.html.errors }} - - {{ tripForm.html }} -
-

-
- -{% endblock %} +{% extends "base.html" %} +{% load csrffaker %} +{% block title %}Logbook {{logbookentry.id}}{% endblock %} +{% block head %} + + + + + +{{ tripForm.media }} +{% endblock %} +{% block content %} + +
{% csrf_token %} + {{ tripForm.non_field_errors }} +
+ {{ tripForm.title.errors }} + + {{ tripForm.title }} +
+
+ {{ tripForm.date.errors }} + + {{ tripForm.date }} +
+
+ {{ tripForm.caveOrLocation.errors }} + + {{ tripForm.caveOrLocation }} +
+
+ {{ tripForm.cave.errors }} + + {{ tripForm.cave }} +
+
+ {{ tripForm.location.errors }} + + {{ tripForm.location }} +
+ + + + + + + + + {% for form in personTripFormSet.forms %} + + + + + + {{ form.non_field_errors }} + + {% endfor %} + +
PersonTU /hoursAuthor
{{ form.name.errors }}{{ form.name }}{{ form.TU.errors }}{{ form.TU }}{{ form.author.errors }}{{ form.author }}
+ {{ personTripFormSet.management_form }} +
+ {{ tripForm.html.errors }} + + {{ tripForm.html }} +
+

+
+ +{% endblock %} diff --git a/templates/nonpublic.html b/templates/nonpublic.html index 5befc4c..5e44abc 100644 --- a/templates/nonpublic.html +++ b/templates/nonpublic.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} -{% block title %} -{{instance}} is non-public -{% endblock %} - -{% block content %} -

Non-public object requested by anonymous user

-The object you requested, {{instance}}, is only viewable for logged-in users. This may be due to copyright or privacy concerns. +{% extends "base.html" %} +{% block title %} +{{instance}} is non-public +{% endblock %} + +{% block content %} +

Non-public object requested by anonymous user

+The object you requested, {{instance}}, is only viewable for logged-in users. This may be due to copyright or privacy concerns. {% endblock %} \ No newline at end of file diff --git a/templates/object_list.html b/templates/object_list.html index 7db63e0..803703f 100644 --- a/templates/object_list.html +++ b/templates/object_list.html @@ -1,15 +1,15 @@ -{% extends "base.html" %} -{% load link %} -{% block title %}Troggle: {{object_list.1.meta.object_name}} objects{%endblock%} - -{% block contentheader %} -

{{object_list.0.object_name}} objects

-{% endblock contentheader %} - -{% block content %} -
    - {% for object in object_list %} - | {{ object|link }} - {% endfor %} | -
+{% extends "base.html" %} +{% load link %} +{% block title %}Troggle: {{object_list.1.meta.object_name}} objects{%endblock%} + +{% block contentheader %} +

{{object_list.0.object_name}} objects

+{% endblock contentheader %} + +{% block content %} +
    + {% for object in object_list %} + | {{ object|link }} + {% endfor %} | +
{% endblock content %} \ No newline at end of file diff --git a/templates/person.html b/templates/person.html index bfc9c5c..48dafb7 100644 --- a/templates/person.html +++ b/templates/person.html @@ -1,43 +1,43 @@ -{% extends "base.html" %} -{% load wiki_markup %} - -{% block title %}Person {{person|wiki_to_html_short}}{% endblock %} - -{% block editLink %}| Edit person {{person|wiki_to_html_short}}{% endblock %} - -{% block contentheader %} -

{{person|wiki_to_html_short}}

-{% endblock %} - -{% block content %} -{% if person.blurb %} -{{person.blurb|safe}} -{% endif %} - -{% for pic in person.photo_set.all %} -{% if pic.is_mugshot %} -
-

-

{{ pic.caption }}

-

edit {{pic}} -

-

-
-{% endif %} -{% endfor %} -
- -

{{person|wiki_to_html_short}} has been on expo in the following years:

-

-

-

- - -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Person {{person|wiki_to_html_short}}{% endblock %} + +{% block editLink %}| Edit person {{person|wiki_to_html_short}}{% endblock %} + +{% block contentheader %} +

{{person|wiki_to_html_short}}

+{% endblock %} + +{% block content %} +{% if person.blurb %} +{{person.blurb|safe}} +{% endif %} + +{% for pic in person.photo_set.all %} +{% if pic.is_mugshot %} +
+

+

{{ pic.caption }}

+

edit {{pic}} +

+

+
+{% endif %} +{% endfor %} +
+ +

{{person|wiki_to_html_short}} has been on expo in the following years:

+

+

+

+ + +{% endblock %} diff --git a/templates/personForm.html b/templates/personForm.html index 84ee7b7..4577239 100644 --- a/templates/personForm.html +++ b/templates/personForm.html @@ -1,6 +1,6 @@ -{% extends "base.html" %} -{% block content %} - -{{ form }} - +{% extends "base.html" %} +{% block content %} + +{{ form }} + {% endblock %} \ No newline at end of file diff --git a/templates/personexpedition.html b/templates/personexpedition.html index 78018db..b88f44e 100644 --- a/templates/personexpedition.html +++ b/templates/personexpedition.html @@ -1,57 +1,57 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load link %} - -{% block title %}Person {{personexpedition.person|wiki_to_html_short}} for {{personexpedition.expedition}}{% endblock %} - - -{% block content %} -

- {{personexpedition.person}} : - {{personexpedition.expedition}} -

- -

{{message}}

- -

Other years: -{% for otherpersonexpedition in personexpedition.person.personexpedition_set.all %} - {% ifequal otherpersonexpedition personexpedition %} - | {{otherpersonexpedition.expedition.year}} - {% else %} - | {{ otherpersonexpedition.expedition.year }} - {% endifequal %} -{% endfor %} -

- -

Table of all trips and surveys aligned by date

-
- - -{% for persondate in personchronology %} - - - - {% if persondate.1 %} - - - {% else %} - - {% endif %} - - {% if persondate.2 %} - - - {% else %} - - {% endif %} - - -{% endfor %} -
DateTripsSurveys
{{persondate.0}}{{persondate.1.logbook_entry.title|safe}}{{persondate.1.place|safe}} {{persondate.2}} - {% for survexpersonrole in persondate.2.survexpersonrole_set.all %} - {{survexpersonrole.nrole}} - {% endfor %} -
-
- -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}Person {{personexpedition.person|wiki_to_html_short}} for {{personexpedition.expedition}}{% endblock %} + + +{% block content %} +

+ {{personexpedition.person}} : + {{personexpedition.expedition}} +

+ +

{{message}}

+ +

Other years: +{% for otherpersonexpedition in personexpedition.person.personexpedition_set.all %} + {% ifequal otherpersonexpedition personexpedition %} + | {{otherpersonexpedition.expedition.year}} + {% else %} + | {{ otherpersonexpedition.expedition.year }} + {% endifequal %} +{% endfor %} +

+ +

Table of all trips and surveys aligned by date

+
+ + +{% for persondate in personchronology %} + + + + {% if persondate.1 %} + + + {% else %} + + {% endif %} + + {% if persondate.2 %} + + + {% else %} + + {% endif %} + + +{% endfor %} +
DateTripsSurveys
{{persondate.0}}{{persondate.1.logbook_entry.title|safe}}{{persondate.1.place|safe}} {{persondate.2}} + {% for survexpersonrole in persondate.2.survexpersonrole_set.all %} + {{survexpersonrole.nrole}} + {% endfor %} +
+
+ +{% endblock %} diff --git a/templates/personindex.html b/templates/personindex.html index 8daffc0..a6196a6 100644 --- a/templates/personindex.html +++ b/templates/personindex.html @@ -1,44 +1,44 @@ -{% extends "base.html" %} -{% load wiki_markup %} - -{% block title %}Person Index{% endblock %} - -{% block content %} - -

Notable expoers

- - -{% for person in notablepersons %} - - - - - - -{% endfor %} -
PersonFirstLastNotability
{{person|wiki_to_html_short}}{{ person.first.expedition.year }}{{ person.last.expedition.year }}{{person.notability}}
- - -

All expoers

- - -{% for persons in personss %} - -{% endfor %} - -
- - - -{% for person in persons %} - - - - - - -{% endfor %} -
PersonFirstLastSurveyed length
{{person|wiki_to_html_short}}{{person.first.expedition.year}}{{person.last.expedition.year}}{{ person.surveyedleglength }}
-
- -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Person Index{% endblock %} + +{% block content %} + +

Notable expoers

+ + +{% for person in notablepersons %} + + + + + + +{% endfor %} +
PersonFirstLastNotability
{{person|wiki_to_html_short}}{{ person.first.expedition.year }}{{ person.last.expedition.year }}{{person.notability}}
+ + +

All expoers

+ + +{% for persons in personss %} + +{% endfor %} + +
+ + + +{% for person in persons %} + + + + + + +{% endfor %} +
PersonFirstLastSurveyed length
{{person|wiki_to_html_short}}{{person.first.expedition.year}}{{person.last.expedition.year}}{{ person.surveyedleglength }}
+
+ +{% endblock %} diff --git a/templates/profiles/create_profile.html b/templates/profiles/create_profile.html index 7e32597..a147160 100644 --- a/templates/profiles/create_profile.html +++ b/templates/profiles/create_profile.html @@ -1,13 +1,13 @@ -{% extends "base.html" %} - -{% block content %} - -
-{{ form.as_p }} - -
- -{% if form.errors %} -

Please correct the errors below

-{% endif %} +{% extends "base.html" %} + +{% block content %} + +
+{{ form.as_p }} + +
+ +{% if form.errors %} +

Please correct the errors below

+{% endif %} {% endblock %} \ No newline at end of file diff --git a/templates/profiles/edit_profile.html b/templates/profiles/edit_profile.html index 7e32597..a147160 100644 --- a/templates/profiles/edit_profile.html +++ b/templates/profiles/edit_profile.html @@ -1,13 +1,13 @@ -{% extends "base.html" %} - -{% block content %} - -
-{{ form.as_p }} - -
- -{% if form.errors %} -

Please correct the errors below

-{% endif %} +{% extends "base.html" %} + +{% block content %} + +
+{{ form.as_p }} + +
+ +{% if form.errors %} +

Please correct the errors below

+{% endif %} {% endblock %} \ No newline at end of file diff --git a/templates/profiles/profile_detail.html b/templates/profiles/profile_detail.html index baf3fae..cf2fb76 100644 --- a/templates/profiles/profile_detail.html +++ b/templates/profiles/profile_detail.html @@ -1,14 +1,14 @@ -{% extends "base.html" %} - -{% block contentheader %} -

Profile for {{ profile }}

-{% endblock %} - -{% block content %} - -{{ profile }} - -{% if form.errors %} -

Please correct the errors below

-{% endif %} +{% extends "base.html" %} + +{% block contentheader %} +

Profile for {{ profile }}

+{% endblock %} + +{% block content %} + +{{ profile }} + +{% if form.errors %} +

Please correct the errors below

+{% endif %} {% endblock %} \ No newline at end of file diff --git a/templates/profiles/select_profile.html b/templates/profiles/select_profile.html index 810efd2..e18191b 100644 --- a/templates/profiles/select_profile.html +++ b/templates/profiles/select_profile.html @@ -1,40 +1,40 @@ -{% extends "base.html" %} - -{% block content %} - -

Troggle profile selection page

- -Hello, {{ user }}. - -

- -{% if user.person %} -This is where you go to associate a new user account with a pre-existing profile from old expo data. - -

- -However, you already have a profile- your name should be {{user.person.first_name}} {{user.person.last_name}}. If you don't believe me, go see it at:

{{ user.person.get_absolute_url }}

or edit it at: -

{{ user.person.get_admin_url }} .

- -If your account is associated with the wrong person's profile due to inebriation or incompetance during account setup, click here to dissasociate your profile from your user account. - -{% else %} - -You have an account in the system, but no profile. If you have been on expo before, please choose yourself from the list below. -

- -
-{{ form.as_p }} - -
-
- -Yes, you could choose the wrong person if you want. That would be lame. Instead, do something that's actually funny. For example, fry a random object or maybe take some mac and cheese somewhere it doesn't usually get to go. Perhaps you can start a new tradition of laminating the expo leader. - - -{% endif %} - -{% if form.errors %} -

Please correct the errors below

-{% endif %} +{% extends "base.html" %} + +{% block content %} + +

Troggle profile selection page

+ +Hello, {{ user }}. + +

+ +{% if user.person %} +This is where you go to associate a new user account with a pre-existing profile from old expo data. + +

+ +However, you already have a profile- your name should be {{user.person.first_name}} {{user.person.last_name}}. If you don't believe me, go see it at:

{{ user.person.get_absolute_url }}

or edit it at: +

{{ user.person.get_admin_url }} .

+ +If your account is associated with the wrong person's profile due to inebriation or incompetance during account setup, click here to dissasociate your profile from your user account. + +{% else %} + +You have an account in the system, but no profile. If you have been on expo before, please choose yourself from the list below. +

+ +
+{{ form.as_p }} + +
+
+ +Yes, you could choose the wrong person if you want. That would be lame. Instead, do something that's actually funny. For example, fry a random object or maybe take some mac and cheese somewhere it doesn't usually get to go. Perhaps you can start a new tradition of laminating the expo leader. + + +{% endif %} + +{% if form.errors %} +

Please correct the errors below

+{% endif %} {% endblock %} \ No newline at end of file diff --git a/templates/qm.html b/templates/qm.html index 6e2a2fb..f960197 100644 --- a/templates/qm.html +++ b/templates/qm.html @@ -1,49 +1,49 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load link %} - -{% block title %} QM: {{qm|wiki_to_html_short}} {% endblock %} - -{% block editLink %}| Edit QM {{qm|wiki_to_html_short}}{% endblock %} - - - -{% block contentheader %} - - - - - - -
Previous{{qm|wiki_to_html_short}}Next
-{% endblock %} - -{% block related %} - -{% endblock %} -

Related items

- -Parent cave: {{qm.found_by.cave|link}} -(todo: add parent survey and parent subcave) -{% block content %} - -

Location

-{{qm.location_description}} - - -

Creation

-Found by {{qm.found_by}} on {{qm.found_by.date}}. - -

Completion

-{% if ticked_off_by %} -{{qm.completion_description}} -Ticked off by: {{qm.ticked_off_by}}
-Description: {{qm.completion_description}} -{% else %} -None yet- STILL EXTANT. -{% endif %} - -

Comment

-{{qm.comment}} - -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %} QM: {{qm|wiki_to_html_short}} {% endblock %} + +{% block editLink %}| Edit QM {{qm|wiki_to_html_short}}{% endblock %} + + + +{% block contentheader %} + + + + + + +
Previous{{qm|wiki_to_html_short}}Next
+{% endblock %} + +{% block related %} + +{% endblock %} +

Related items

+ +Parent cave: {{qm.found_by.cave|link}} +(todo: add parent survey and parent subcave) +{% block content %} + +

Location

+{{qm.location_description}} + + +

Creation

+Found by {{qm.found_by}} on {{qm.found_by.date}}. + +

Completion

+{% if ticked_off_by %} +{{qm.completion_description}} +Ticked off by: {{qm.ticked_off_by}}
+Description: {{qm.completion_description}} +{% else %} +None yet- STILL EXTANT. +{% endif %} + +

Comment

+{{qm.comment}} + +{% endblock %} diff --git a/templates/registration/activate.html b/templates/registration/activate.html index ba6be92..3f95a18 100644 --- a/templates/registration/activate.html +++ b/templates/registration/activate.html @@ -1,25 +1,25 @@ -{% extends "base.html" %} - -{% block title %} -New troggle account registered -{% endblock %} - -{% block header %} -

activate.html

-{% endblock %} - -{% block content %} - -{% if account %} -

-Hello, {{ account }}! Your account is now activated. Now you can log in with the password you chose. Use the links in the upper right to control this in the future. -

- -

-If you have been on the expedition in the past, you already have a profile in the system; click here to find it and link it to your account. Otherwise, please create yourself a new profile. -

-{% else %} - -The activation key you entered has already been used or was invalid. -{% endif %} +{% extends "base.html" %} + +{% block title %} +New troggle account registered +{% endblock %} + +{% block header %} +

activate.html

+{% endblock %} + +{% block content %} + +{% if account %} +

+Hello, {{ account }}! Your account is now activated. Now you can log in with the password you chose. Use the links in the upper right to control this in the future. +

+ +

+If you have been on the expedition in the past, you already have a profile in the system; click here to find it and link it to your account. Otherwise, please create yourself a new profile. +

+{% else %} + +The activation key you entered has already been used or was invalid. +{% endif %} {% endblock %} diff --git a/templates/registration/activation_email.html b/templates/registration/activation_email.html index 3d56009..abb0ad1 100644 --- a/templates/registration/activation_email.html +++ b/templates/registration/activation_email.html @@ -1,10 +1,10 @@ -

Hello {{ form.user }},

- -

Glad you're joining the CUCC EXPO team! Please go to

- -

{{ site }}{% url registration_activate activation_key %}

- -

to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again.

- -

Yours,
-The magical troggle

+

Hello {{ form.user }},

+ +

Glad you're joining the CUCC EXPO team! Please go to

+ +

{{ site }}{% url registration_activate activation_key %}

+ +

to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again.

+ +

Yours,
+The magical troggle

diff --git a/templates/registration/activation_email.txt b/templates/registration/activation_email.txt index 20aad5f..9b240c2 100644 --- a/templates/registration/activation_email.txt +++ b/templates/registration/activation_email.txt @@ -1,10 +1,10 @@ -Hello {{ form.user }}, - -Glad you're joining the CUCC EXPO team! Please go to - -{{ site }}{% url registration_activate activation_key %} - -to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again. - -Yours, +Hello {{ form.user }}, + +Glad you're joining the CUCC EXPO team! Please go to + +{{ site }}{% url registration_activate activation_key %} + +to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again. + +Yours, The magical troggle \ No newline at end of file diff --git a/templates/registration/login.html b/templates/registration/login.html index b93e4d8..388d41b 100644 --- a/templates/registration/login.html +++ b/templates/registration/login.html @@ -1,20 +1,20 @@ -{% extends "base.html" %} -{% load csrffaker %} - -{% block content %} - -{% if form.errors %} -

Your username and password didn't match. Please try again.

-{% endif %} - -
{% csrf_token %} - - - -
{{ form.username.label_tag }}{{ form.username }}
{{ form.password.label_tag }}{{ form.password }}
- - - -
- -{% endblock %} +{% extends "base.html" %} +{% load csrffaker %} + +{% block content %} + +{% if form.errors %} +

Your username and password didn't match. Please try again.

+{% endif %} + +
{% csrf_token %} + + + +
{{ form.username.label_tag }}{{ form.username }}
{{ form.password.label_tag }}{{ form.password }}
+ + + +
+ +{% endblock %} diff --git a/templates/registration/logout.html b/templates/registration/logout.html index 9e40c20..ef2a3b2 100644 --- a/templates/registration/logout.html +++ b/templates/registration/logout.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} -{% block content %} - You have been logged out. +{% extends "base.html" %} +{% block content %} + You have been logged out. {% endblock %} \ No newline at end of file diff --git a/templates/registration/registration_activate.html b/templates/registration/registration_activate.html index cbd540e..6566bf4 100644 --- a/templates/registration/registration_activate.html +++ b/templates/registration/registration_activate.html @@ -1,6 +1,6 @@ -{% extends “base.html” %} -{% block body %} -Hello {{ account }}! - -Check your email to confirm the activation. There are {{ expiration_days }} days left to do it. +{% extends “base.html” %} +{% block body %} +Hello {{ account }}! + +Check your email to confirm the activation. There are {{ expiration_days }} days left to do it. {% endblock %} \ No newline at end of file diff --git a/templates/registration/registration_complete.html b/templates/registration/registration_complete.html index 78684fe..4dac94b 100644 --- a/templates/registration/registration_complete.html +++ b/templates/registration/registration_complete.html @@ -1,13 +1,13 @@ -{% extends "base.html" %} - -{% block title %} -{{ block.super }}: registration complete -{% endblock %} - -{% block contentheader %} -

Registration Complete

-{% endblock %} - -{% block content %} -

Thank you for signing up. An email with the activation code has been sent to your inbox.

+{% extends "base.html" %} + +{% block title %} +{{ block.super }}: registration complete +{% endblock %} + +{% block contentheader %} +

Registration Complete

+{% endblock %} + +{% block content %} +

Thank you for signing up. An email with the activation code has been sent to your inbox.

{% endblock %} \ No newline at end of file diff --git a/templates/statistics.html b/templates/statistics.html index 1fddd67..daca752 100644 --- a/templates/statistics.html +++ b/templates/statistics.html @@ -1,8 +1,8 @@ -{% extends "base.html" %} -{% load wiki_markup %} - -{% block title %}Database statistics{% endblock %} - -{% block content %} -Over the course of {{ expoCount }} expeditions, {{ personCount }} people have contributed {{ caveCount }} caves and {{ logbookEntryCount }} logbook entries. +{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Database statistics{% endblock %} + +{% block content %} +Over the course of {{ expoCount }} expeditions, {{ personCount }} people have contributed {{ caveCount }} caves and {{ logbookEntryCount }} logbook entries. {% endblock %} \ No newline at end of file diff --git a/templates/subcave.html b/templates/subcave.html index fbb8d1d..41fb2d0 100644 --- a/templates/subcave.html +++ b/templates/subcave.html @@ -1,59 +1,59 @@ -{% extends "cavebase.html" %} -{% load wiki_markup %} -{% load mptt_tags %} -{% block title %} Subcave {{subcave}} {% endblock title %} -{% block editLink %}Edit subcave {{subcave|wiki_to_html_short}}{% endblock %} - -{% block contentheader %} - {{subcave.title}} -{% endblock contentheader %} - - - -{% block content %} -{% block related %} - -

Related places

- -

Parent

- - - -

Connected subareas

- -
    - {% for sibling in subcave.adjoining.all%} -
  • {{silbling}}
  • - {% endfor %} -
- -

Children

- -
    - {% for child in subcave.children.all %} -
  • {{child}}
  • - {% endfor %} -
- - -{% endblock %} - -ok here comes the drilldown
-{% drilldown_tree_for_node subcave as drilldown %} -{% for each in drilldown %} -{{ each }}> -{% endfor %} - - -

{{subcave}}

-

- {{subcave.description}} -

- +{% extends "cavebase.html" %} +{% load wiki_markup %} +{% load mptt_tags %} +{% block title %} Subcave {{subcave}} {% endblock title %} +{% block editLink %}Edit subcave {{subcave|wiki_to_html_short}}{% endblock %} + +{% block contentheader %} + {{subcave.title}} +{% endblock contentheader %} + + + +{% block content %} +{% block related %} + +

Related places

+ +

Parent

+ + + +

Connected subareas

+ +
    + {% for sibling in subcave.adjoining.all%} +
  • {{silbling}}
  • + {% endfor %} +
+ +

Children

+ +
    + {% for child in subcave.children.all %} +
  • {{child}}
  • + {% endfor %} +
+ + +{% endblock %} + +ok here comes the drilldown
+{% drilldown_tree_for_node subcave as drilldown %} +{% for each in drilldown %} +{{ each }}> +{% endfor %} + + +

{{subcave}}

+

+ {{subcave.description}} +

+ {% endblock content %} \ No newline at end of file diff --git a/templates/survexblock.html b/templates/survexblock.html index 31958c0..c4c1066 100644 --- a/templates/survexblock.html +++ b/templates/survexblock.html @@ -1,49 +1,49 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load survex_markup %} - - -{% block title %}Survex Block{% endblock %} - -{% block content %} -

Survex Block {{survexblock.survexpath}}

- -

Link to {{survexblock.survexfile.path}}

- -

Needs duplicates removed from right hand column

-

Needs links to survex file presentation

-

Needs to start dealing with misspellings of names (prob by editing the originals)

- -
- -{% if survexblock.parent %} -

Survey block above:

-

{{survexblock.parent.survexpath}}

-{% endif %} - -{% if survexblock.survexblock_set.all %} -

Survey blocks below:

- {% for survexblockdown in survexblock.survexblock_set.all %} -

{{survexblockdown.survexpath}}

- {% endfor %} -{% endif %} - -

Date: {{survexblock.date}}

- - -{% for personrole in survexblock.GetPersonroles %} - - - - -{% endfor %} -
{{personrole.person}}{{personrole.roles}}
- - -
- -
- {{ftext|survex_to_html}} -
- -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + + +{% block title %}Survex Block{% endblock %} + +{% block content %} +

Survex Block {{survexblock.survexpath}}

+ +

Link to {{survexblock.survexfile.path}}

+ +

Needs duplicates removed from right hand column

+

Needs links to survex file presentation

+

Needs to start dealing with misspellings of names (prob by editing the originals)

+ +
+ +{% if survexblock.parent %} +

Survey block above:

+

{{survexblock.parent.survexpath}}

+{% endif %} + +{% if survexblock.survexblock_set.all %} +

Survey blocks below:

+ {% for survexblockdown in survexblock.survexblock_set.all %} +

{{survexblockdown.survexpath}}

+ {% endfor %} +{% endif %} + +

Date: {{survexblock.date}}

+ + +{% for personrole in survexblock.GetPersonroles %} + + + + +{% endfor %} +
{{personrole.person}}{{personrole.roles}}
+ + +
+ +
+ {{ftext|survex_to_html}} +
+ +{% endblock %} diff --git a/templates/survexscansfolder.html b/templates/survexscansfolder.html index 6f8bd3a..fe21916 100644 --- a/templates/survexscansfolder.html +++ b/templates/survexscansfolder.html @@ -1,33 +1,33 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load survex_markup %} - -{% block title %}Survex Scans Folder{% endblock %} - -{% block content %} - -

Survex Scans in: {{survexscansfolder.walletname}}

- -{% for survexscansingle in survexscansfolder.survexscansingle_set.all %} - - - - -{% endfor %} -
{{survexscansingle.name}} - {% for survexblock in survexscansingle.survexblock_set.all %} - {{survexblock}} - {% endfor %} -
- -

Surveys referring to this wallet

- - -{% for survexblock in survexscansfolder.survexblock_set.all %} - - - -{% endfor %} -
{{survexblock}}
- -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + +{% block title %}Survex Scans Folder{% endblock %} + +{% block content %} + +

Survex Scans in: {{survexscansfolder.walletname}}

+ +{% for survexscansingle in survexscansfolder.survexscansingle_set.all %} + + + + +{% endfor %} +
{{survexscansingle.name}} + {% for survexblock in survexscansingle.survexblock_set.all %} + {{survexblock}} + {% endfor %} +
+ +

Surveys referring to this wallet

+ + +{% for survexblock in survexscansfolder.survexblock_set.all %} + + + +{% endfor %} +
{{survexblock}}
+ +{% endblock %} diff --git a/templates/survexscansfolders.html b/templates/survexscansfolders.html index 195b898..597bacf 100644 --- a/templates/survexscansfolders.html +++ b/templates/survexscansfolders.html @@ -1,25 +1,25 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load survex_markup %} - -{% block title %}All Survex scans folders{% endblock %} - -{% block content %} - -

All Survex scans folders

- - -{% for survexscansfolder in survexscansfolders %} - - - - - -{% endfor %} -
Scans folderFilesSurvex blocks
{{survexscansfolder.walletname}}{{survexscansfolder.survexscansingle_set.all|length}} - {% for survexblock in survexscansfolder.survexblock_set.all %} - {{survexblock}} - {% endfor %} -
- +{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + +{% block title %}All Survex scans folders{% endblock %} + +{% block content %} + +

All Survex scans folders

+ + +{% for survexscansfolder in survexscansfolders %} + + + + + +{% endfor %} +
Scans folderFilesSurvex blocks
{{survexscansfolder.walletname}}{{survexscansfolder.survexscansingle_set.all|length}} + {% for survexblock in survexscansfolder.survexblock_set.all %} + {{survexblock}} + {% endfor %} +
+ {% endblock %} \ No newline at end of file diff --git a/templates/survey.html b/templates/survey.html index 37b2dfe..9dca0df 100644 --- a/templates/survey.html +++ b/templates/survey.html @@ -1,193 +1,193 @@ -{% extends "base.html" %} -{% load wiki_markup %} - - -{% block title %}CUCC Virtual Survey Binder: {{ current_expedition }}{{ current_survey }}{%endblock%} -{% block head %} - - - - - -{% endblock %} - -
- CUCC Expo virtual survey binder: - {% if current_survey %} - {{current_survey}} - {% else %} - {{current_expedition}} - {% endif %} -
- -{% block nav %} -
- -

Choose a year

-
- -
- -
- - -
-{% if current_expedition %} -

Choose a wallet number

-
- - -
-

Click to toggle:

-
- - - - - - -
- -{% endif %} -{% endblock %} - - -{% block content %} -
- -
-

Survey progress table for {{ current_expedition }}

- {% if current_expedition.survey_set.all %} - - - - {% for survey in current_expedition.survey_set.all %} - - {% endfor %} - - - {% for survey in current_expedition.survey_set.all %} - - {% endfor %} - - - {% for survey in current_expedition.survey_set.all %} - - {% endfor %} - - - {% for survey in current_expedition.survey_set.all %} - - {% endfor %} - - - {% for survey in current_expedition.survey_set.all %} - - {% endfor %} -
{{ survey.wallet_number }}
Notes {% if survey.notes %} - ✓ - {% endif %}
Survex file {% if survey.survex_file %} - ✓ - {% endif %}
Plans {% if survey.plans %} - ✓ - {% endif %}
Elevations {% if survey.elevations %} - ✓ - {% endif %}
- {% else %} -
[ There are no surveys in the database for this year. Put link in to add one. ]
- {% endif %} -
-
-

Scanned notes for {{ current_survey }}.

- {% for noteItem in notes %} -
-

-

File at: {{ noteItem.file.name }}
- Scanned by: {{ noteItem.scanned_by }}
- On: {{ noteItem.scanned_on }}
-

-

-
- {% endfor %} - -
-
-
survex file editor, keeping file in original structure
- who entered by
-
centreline
-
-

Scanned plan sketch files for {{ current_survey }}.

- {% for sketchItem in planSketches %} -
-

-

File at: {{ sketchItem.file.name }}
- Scanned by: {{ sketchItem.scanned_by }}
- On: {{ sketchItem.scanned_on }}
-

-

-
- {% endfor %} - -
-
link to tunnel xml file. potentially instance of tunnel applet...
-
link to main sketch file
- -
-
- -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} + + +{% block title %}CUCC Virtual Survey Binder: {{ current_expedition }}{{ current_survey }}{%endblock%} +{% block head %} + + + + + +{% endblock %} + +
+ CUCC Expo virtual survey binder: + {% if current_survey %} + {{current_survey}} + {% else %} + {{current_expedition}} + {% endif %} +
+ +{% block nav %} +
+ +

Choose a year

+
+ +
+ +
+ + +
+{% if current_expedition %} +

Choose a wallet number

+
+ + +
+

Click to toggle:

+
+ + + + + + +
+ +{% endif %} +{% endblock %} + + +{% block content %} +
+ +
+

Survey progress table for {{ current_expedition }}

+ {% if current_expedition.survey_set.all %} + + + + {% for survey in current_expedition.survey_set.all %} + + {% endfor %} + + + {% for survey in current_expedition.survey_set.all %} + + {% endfor %} + + + {% for survey in current_expedition.survey_set.all %} + + {% endfor %} + + + {% for survey in current_expedition.survey_set.all %} + + {% endfor %} + + + {% for survey in current_expedition.survey_set.all %} + + {% endfor %} +
{{ survey.wallet_number }}
Notes {% if survey.notes %} + ✓ + {% endif %}
Survex file {% if survey.survex_file %} + ✓ + {% endif %}
Plans {% if survey.plans %} + ✓ + {% endif %}
Elevations {% if survey.elevations %} + ✓ + {% endif %}
+ {% else %} +
[ There are no surveys in the database for this year. Put link in to add one. ]
+ {% endif %} +
+
+

Scanned notes for {{ current_survey }}.

+ {% for noteItem in notes %} +
+

+

File at: {{ noteItem.file.name }}
+ Scanned by: {{ noteItem.scanned_by }}
+ On: {{ noteItem.scanned_on }}
+

+

+
+ {% endfor %} + +
+
+
survex file editor, keeping file in original structure
+ who entered by
+
centreline
+
+

Scanned plan sketch files for {{ current_survey }}.

+ {% for sketchItem in planSketches %} +
+

+

File at: {{ sketchItem.file.name }}
+ Scanned by: {{ sketchItem.scanned_by }}
+ On: {{ sketchItem.scanned_on }}
+

+

+
+ {% endfor %} + +
+
link to tunnel xml file. potentially instance of tunnel applet...
+
link to main sketch file
+ +
+
+ +{% endblock %} diff --git a/templates/svxcavesingle.html b/templates/svxcavesingle.html index 123e92a..1d24466 100644 --- a/templates/svxcavesingle.html +++ b/templates/svxcavesingle.html @@ -1,81 +1,81 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load link %} - -{% block title %}List of survex files{% endblock %} - -{% block content %} - -

Surveys for {{cave}}

- -

-{% for survexdirectory in cave.survexdirectory_set.all %} - {{survexdirectory.path}} -{% endfor %} -

- -{% for survexdirectory in cave.survexdirectory_set.all %} -

{{survexdirectory.path}}

- - - - -{% for survexfile in survexdirectory.survexfile_set.all %} - - {% if survexfile.exists %} - - - -{% for survexblock in survexfile.survexblock_set.all %} - - - - - - - - - - - - -{% endfor %} -{% endfor %} -
Survex fileBlockDateExplorerslengthTitlesScans
- {% else %} - - {% endif %} - - {% ifequal survexfile survexdirectory.primarysurvexfile %} - {{survexfile.path}} - {% else %} - {{survexfile.path}} - {% endifequal %} -
{{survexblock.name}} - {% if survexblock.expedition %} - {{survexblock.date}} - {% else %} - {{survexblock.date}} - {% endif %} - - {% for personrole in survexblock.personrole_set.all %} - {% if personrole.personexpedition %} - {{personrole.personname}} - {% else %} - {{personrole.personname}} - {% endif %} - {% endfor %} - {{survexblock.totalleglength}} - {% for survextitle in survexblock.survextitle_set.all %} - {{survextitle.title}} - {% endfor %} - - {% if survexblock.survexscansfolder %} - {{survexblock.survexscansfolder.walletname}} - {% endif %} -
- -{% endfor %} - -{% endblock %} - +{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}List of survex files{% endblock %} + +{% block content %} + +

Surveys for {{cave}}

+ +

+{% for survexdirectory in cave.survexdirectory_set.all %} + {{survexdirectory.path}} +{% endfor %} +

+ +{% for survexdirectory in cave.survexdirectory_set.all %} +

{{survexdirectory.path}}

+ + + + +{% for survexfile in survexdirectory.survexfile_set.all %} + + {% if survexfile.exists %} + + + +{% for survexblock in survexfile.survexblock_set.all %} + + + + + + + + + + + + +{% endfor %} +{% endfor %} +
Survex fileBlockDateExplorerslengthTitlesScans
+ {% else %} + + {% endif %} + + {% ifequal survexfile survexdirectory.primarysurvexfile %} + {{survexfile.path}} + {% else %} + {{survexfile.path}} + {% endifequal %} +
{{survexblock.name}} + {% if survexblock.expedition %} + {{survexblock.date}} + {% else %} + {{survexblock.date}} + {% endif %} + + {% for personrole in survexblock.personrole_set.all %} + {% if personrole.personexpedition %} + {{personrole.personname}} + {% else %} + {{personrole.personname}} + {% endif %} + {% endfor %} + {{survexblock.totalleglength}} + {% for survextitle in survexblock.survextitle_set.all %} + {{survextitle.title}} + {% endfor %} + + {% if survexblock.survexscansfolder %} + {{survexblock.survexscansfolder.walletname}} + {% endif %} +
+ +{% endfor %} + +{% endblock %} + diff --git a/templates/svxfile.html b/templates/svxfile.html index ed4318d..bf9f1c3 100644 --- a/templates/svxfile.html +++ b/templates/svxfile.html @@ -1,76 +1,76 @@ -{% extends "base.html" %} -{% load survex_markup %} - -{% block title %}{{ title }}{% endblock %} - -{% block head %} - - - - - -{% endblock %} - -{% block content %} -

Survex File: {{ title }}

- -{% if svxincludes %} -

Included files: -{% for svxinclude in svxincludes %} - {{svxinclude}} -{% endfor %} -

-{% endif %} - -
-
{{form.code}}
-
{{form.filename}} {{form.dirname}} {{form.datetime}} {{form.outputtype}}
- - - -
- -
-
-{% for diffline in difflist %}{{diffline}}
-{% endfor %}
-
- -{% if logmessage %} -{% if has_3d %} -

3d file

-{% else %} -

No 3d file

-{% endif %} -
-LOGMESSAGES
-{{logmessage}}
-
-{% endif %} -
- -{% endblock %} +{% extends "base.html" %} +{% load survex_markup %} + +{% block title %}{{ title }}{% endblock %} + +{% block head %} + + + + + +{% endblock %} + +{% block content %} +

Survex File: {{ title }}

+ +{% if svxincludes %} +

Included files: +{% for svxinclude in svxincludes %} + {{svxinclude}} +{% endfor %} +

+{% endif %} + +
+
{{form.code}}
+
{{form.filename}} {{form.dirname}} {{form.datetime}} {{form.outputtype}}
+ + + +
+ +
+
+{% for diffline in difflist %}{{diffline}}
+{% endfor %}
+
+ +{% if logmessage %} +{% if has_3d %} +

3d file

+{% else %} +

No 3d file

+{% endif %} +
+LOGMESSAGES
+{{logmessage}}
+
+{% endif %} +
+ +{% endblock %} diff --git a/templates/svxfilecavelist.html b/templates/svxfilecavelist.html index a0db893..52c8e83 100644 --- a/templates/svxfilecavelist.html +++ b/templates/svxfilecavelist.html @@ -1,66 +1,66 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load link %} - -{% block title %}List of survex files{% endblock %} - -{% block content %} -

caves with subdirectories | caves with multiple files | caves with single files

- -

Link to all.svx for processing

- -

Caves with subdirectories

- -{% for subdircave, cavefiles, subsurvdirs in subdircaves %} -

{{cavefiles.0.1}} - dates and explorers

- - - - - - -{% for primarycavefile, subcavefiles in subsurvdirs %} - - - - -{% endfor %} -
{{cavefiles.0.1}} - {% for cavepath, cavename in cavefiles.1 %} - {{cavename}} - {% endfor %} -
{{primarycavefile.1}} - {% for cavepath, cavename in subcavefiles %} - {{cavename}} - {% endfor %} -
- -{% endfor %} - - -

Caves of multiple files

- - -{% for primarycavefile, subcavefiles in multifilecaves %} - - - - -{% endfor %} -
Dates and explorersSurvex files
- {{primarycavefile.1}} - - {{primarycavefile.1}} - - {% for cavepath, cavename in subcavefiles %} - {{cavename}} - {% endfor %} -
- -

Caves of one file

-

-{% for cavepath, cavename in onefilecaves %} - {{cavename}} -{% endfor %} -

- -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}List of survex files{% endblock %} + +{% block content %} +

caves with subdirectories | caves with multiple files | caves with single files

+ +

Link to all.svx for processing

+ +

Caves with subdirectories

+ +{% for subdircave, cavefiles, subsurvdirs in subdircaves %} +

{{cavefiles.0.1}} - dates and explorers

+ + + + + + +{% for primarycavefile, subcavefiles in subsurvdirs %} + + + + +{% endfor %} +
{{cavefiles.0.1}} + {% for cavepath, cavename in cavefiles.1 %} + {{cavename}} + {% endfor %} +
{{primarycavefile.1}} + {% for cavepath, cavename in subcavefiles %} + {{cavename}} + {% endfor %} +
+ +{% endfor %} + + +

Caves of multiple files

+ + +{% for primarycavefile, subcavefiles in multifilecaves %} + + + + +{% endfor %} +
Dates and explorersSurvex files
+ {{primarycavefile.1}} + + {{primarycavefile.1}} - + {% for cavepath, cavename in subcavefiles %} + {{cavename}} + {% endfor %} +
+ +

Caves of one file

+

+{% for cavepath, cavename in onefilecaves %} + {{cavename}} +{% endfor %} +

+ +{% endblock %} diff --git a/templates/svxfiledifflistonly.html b/templates/svxfiledifflistonly.html index f51744e..835125b 100644 --- a/templates/svxfiledifflistonly.html +++ b/templates/svxfiledifflistonly.html @@ -1,18 +1,18 @@ -
- using difflistonly.html
-{% for diffline in difflist %}{{diffline}}
-{% endfor %}
-
- -{% if logmessage %} -{% if has_3d %} -

3d file

-{% else %} -

No 3d file

-{% endif %} -
-LOGMESSAGES
-{{logmessage}}
-
-{% endif %} - +
+ using difflistonly.html
+{% for diffline in difflist %}{{diffline}}
+{% endfor %}
+
+ +{% if logmessage %} +{% if has_3d %} +

3d file

+{% else %} +

No 3d file

+{% endif %} +
+LOGMESSAGES
+{{logmessage}}
+
+{% endif %} + diff --git a/templates/tasks.html b/templates/tasks.html index a429bd5..36d35f4 100644 --- a/templates/tasks.html +++ b/templates/tasks.html @@ -1,39 +1,39 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load link %} - -{% block title %}Cambridge Expeditions to Austria{% endblock %} - -{% block content %} -

Expo member tasks

- -

Add new data

- -
  • Upload a photo
  • -
  • Record a new trip
  • - -

    Your unfinished business

    - {% for survey in surveys_unfinished %} -
  • {{survey|link}}
  • - {% endfor %} - -

    General unfinished business

    -add wikilinks - -

    Caving recommendations

    - {% for qm in qms_recommended %} -
  • {{qm|link}}
  • - {% endfor %} - -

    Profile tasks

    - -
  • Dates present on expo
  • -
  • Mugshot
  • -
  • Blurb
  • - -{% endblock content %} - -{% block margins %} - - -{% endblock margins %} +{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}Cambridge Expeditions to Austria{% endblock %} + +{% block content %} +

    Expo member tasks

    + +

    Add new data

    + +
  • Upload a photo
  • +
  • Record a new trip
  • + +

    Your unfinished business

    + {% for survey in surveys_unfinished %} +
  • {{survey|link}}
  • + {% endfor %} + +

    General unfinished business

    +add wikilinks + +

    Caving recommendations

    + {% for qm in qms_recommended %} +
  • {{qm|link}}
  • + {% endfor %} + +

    Profile tasks

    + +
  • Dates present on expo
  • +
  • Mugshot
  • +
  • Blurb
  • + +{% endblock content %} + +{% block margins %} + + +{% endblock margins %} diff --git a/templates/todo.html b/templates/todo.html index 0aafadb..a678f50 100644 --- a/templates/todo.html +++ b/templates/todo.html @@ -1,61 +1,61 @@ -{% extends "base.html" %} -{% load wiki_markup %} - -{% block title %}Cambridge Expeditions to Austria{% endblock %} - -{% block content %} - -

    The unfinished front page

    - - -

    Further work

    - -

    Please see the issues tracker on google code. You can contribute new feature requests and bug reports.

    - -

    Julian's work: -

    parse 1992-1976 logbooks; (esp top 161)

    -

    detect T/U on log entries;

    -

    name matching and spelling in survex files;

    -

    Improve logbook wikihtml text

    - -

    Other work:

    -

    surf through the tunnel sketches and images

    -

    bugs with all.svx block (double dot) -

    render bitmap view of every survex block as a thumbnail

    -

    upload tunnel images and tunnel sketches

    -

    where are the subcaves;

    -

    cave section entrance match for logbook entries

    -

    simplify the survex parsing code (if necessary);

    -

    wiki survex stop linegap between comment lins

    -

    links between logbooks and survex blocks to cave things;

    -

    mini-tree of survexblocks;

    -

    connect sketches to caves to survey blocks and render thumbnailwise;

    -

    all images to start appearing in pages; and so on

    - -

    {{message}}

    - -
    - - -
    - -
      -{% for expedition in expeditions %} -
    • - {{expedition.name}} - - {{expedition.logbookentry_set.count}} logbook entries -
    • -{% endfor %} -
    - -{% endblock %} +{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Cambridge Expeditions to Austria{% endblock %} + +{% block content %} + +

    The unfinished front page

    + + +

    Further work

    + +

    Please see the issues tracker on google code. You can contribute new feature requests and bug reports.

    + +

    Julian's work: +

    parse 1992-1976 logbooks; (esp top 161)

    +

    detect T/U on log entries;

    +

    name matching and spelling in survex files;

    +

    Improve logbook wikihtml text

    + +

    Other work:

    +

    surf through the tunnel sketches and images

    +

    bugs with all.svx block (double dot) +

    render bitmap view of every survex block as a thumbnail

    +

    upload tunnel images and tunnel sketches

    +

    where are the subcaves;

    +

    cave section entrance match for logbook entries

    +

    simplify the survex parsing code (if necessary);

    +

    wiki survex stop linegap between comment lins

    +

    links between logbooks and survex blocks to cave things;

    +

    mini-tree of survexblocks;

    +

    connect sketches to caves to survey blocks and render thumbnailwise;

    +

    all images to start appearing in pages; and so on

    + +

    {{message}}

    + +
    + + +
    + +
      +{% for expedition in expeditions %} +
    • + {{expedition.name}} + - {{expedition.logbookentry_set.count}} logbook entries +
    • +{% endfor %} +
    + +{% endblock %} diff --git a/templates/tunnelfiles.html b/templates/tunnelfiles.html index 3d49e5d..caa3895 100644 --- a/templates/tunnelfiles.html +++ b/templates/tunnelfiles.html @@ -1,43 +1,43 @@ -{% extends "base.html" %} -{% load wiki_markup %} -{% load survex_markup %} - -{% block title %}Tunnel files{% endblock %} - -{% block content %} - -

    All Tunnel files

    - - -{% for tunnelfile in tunnelfiles %} - - - - - - - - - - - - - - - -{% endfor %} -
    FileFontSurvexBlocksSizePathsScans folderScan filesFrames
    {{tunnelfile.tunnelpath}}{{tunnelfile.bfontcolours}}{{tunnelfile.filesize}}{{tunnelfile.npaths}} - {% for survexscansfolder in tunnelfile.survexscansfolders.all %} - {{survexscansfolder.walletname}} - {% endfor %} - - {% for survexscansingle in tunnelfile.survexscans.all %} - {{survexscansingle.name}} - {% endfor %} - - {% for rtunnelfile in tunnelfile.tunnelcontains.all %} - {{rtunnelfile.tunnelpath}} - {% endfor %} -
    - +{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + +{% block title %}Tunnel files{% endblock %} + +{% block content %} + +

    All Tunnel files

    + + +{% for tunnelfile in tunnelfiles %} + + + + + + + + + + + + + + + +{% endfor %} +
    FileFontSurvexBlocksSizePathsScans folderScan filesFrames
    {{tunnelfile.tunnelpath}}{{tunnelfile.bfontcolours}}{{tunnelfile.filesize}}{{tunnelfile.npaths}} + {% for survexscansfolder in tunnelfile.survexscansfolders.all %} + {{survexscansfolder.walletname}} + {% endfor %} + + {% for survexscansingle in tunnelfile.survexscans.all %} + {{survexscansingle.name}} + {% endfor %} + + {% for rtunnelfile in tunnelfile.tunnelcontains.all %} + {{rtunnelfile.tunnelpath}} + {% endfor %} +
    + {% endblock %} \ No newline at end of file