diff options
77 files changed, 6650 insertions, 6652 deletions
@@ -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'</p><p style="float: left;"><b>QMs found:</b>')
-# for QM in LogbookEntry.instance.QMs_found.all():
-# res.append(QM.wiki_link())
-
-# res.append(r'</p><p style="float: left;"><b>QMs ticked off:</b>')
-# for QM in LogbookEntry.instance.QMs_ticked_off.all():
-# res.append(QM.wiki_link())
-
-# res.append(r'</p><p style="float: left; "><b>People</b>')
-# for persontrip in LogbookEntry.instance.persontrip_set.all():
-# res.append(persontrip.wiki_link())
-# res.append(r'</p>')
-
-# return string.join(res, r'<br />')
-
-# def __init__(self, *args, **kwargs):
-# super(LogbookEntryForm, self).__init__(*args, **kwargs)
-# self.fields['text'].help_text=self.wikiLinkHints()#
-
-class CaveForm(forms.Form):
- html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
-
-def getTripForm(expedition):
-
- class TripForm(forms.Form):
- date = forms.DateField()
- title = forms.CharField(max_length=200)
- caves = [cave.reference() for cave in Cave.objects.all()]
- caves.sort()
- caves = ["-----"] + caves
- cave = forms.ChoiceField([(c, c) for c in caves], required=False)
- location = forms.CharField(max_length=200, required=False)
- caveOrLocation = forms.ChoiceField([("cave", "Cave"), ("location", "Location")], widget = forms.widgets.RadioSelect())
- html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
-
- def clean(self):
- print dir(self)
- if self.cleaned_data.get("caveOrLocation") == "cave" and not self.cleaned_data.get("cave"):
- self._errors["cave"] = self.error_class(["This field is required"])
- if self.cleaned_data.get("caveOrLocation") == "location" and not self.cleaned_data.get("location"):
- self._errors["location"] = self.error_class(["This field is required"])
- return self.cleaned_data
-
- class PersonTripForm(forms.Form):
- names = [get_name(pe) for pe in PersonExpedition.objects.filter(expedition = expedition)]
- names.sort()
- names = ["-----"] + names
- name = forms.ChoiceField([(n, n) for n in names])
- TU = forms.FloatField(required=False)
- author = forms.BooleanField(required=False)
-
- PersonTripFormSet = formset_factory(PersonTripForm, extra=1)
-
- return PersonTripFormSet, TripForm
-
-def get_name(pe):
- if pe.nickname:
- return pe.nickname
- else:
- return pe.person.first_name
-
-class UploadFileForm(forms.Form):
- title = forms.CharField(max_length=50)
- file = forms.FileField()
- html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
- lon_utm = forms.FloatField(required=False)
- lat_utm = forms.FloatField(required=False)
- slug = forms.CharField(max_length=50)
- date = forms.DateField(required=False)
-
- caves = [cave.slug for cave in Cave.objects.all()]
- caves.sort()
- caves = ["-----"] + caves
- cave = forms.ChoiceField([(c, c) for c in caves], required=False)
-
- entrance = forms.ChoiceField([("-----", "Please select a cave"), ], required=False)
- qm = forms.ChoiceField([("-----", "Please select a cave"), ], required=False)
-
- expeditions = [e.year for e in Expedition.objects.all()]
- expeditions.sort()
- expeditions = ["-----"] + expeditions
- expedition = forms.ChoiceField([(e, e) for e in expeditions], required=False)
-
- logbookentry = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False)
-
- person = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False)
-
- survey_point = forms.CharField()
-
-
+from django.forms import ModelForm +from models import Cave, Person, PersonExpedition, LogbookEntry, QM, Expedition +import django.forms as forms +from django.forms.formsets import formset_factory +from django.contrib.admin.widgets import AdminDateWidget +import string +from datetime import date +from tinymce.widgets import TinyMCE + +#class CaveForm(ModelForm): +# class Meta: +# model = Cave + +#class PersonForm(ModelForm): +# class Meta: +# model = Person + +#class LogbookEntryForm(ModelForm): +# class Meta: +# model = LogbookEntry# + +# def wikiLinkHints(LogbookEntry=None): +# """ +# This function returns html-formatted paragraphs for each of the +# wikilink types that are related to this logbookentry. Each paragraph +# contains a list of all of the related wikilinks. +# +# Perhaps an admin javascript solution would be better. +# """ +# res = ["Please use the following wikilinks, which are related to this logbook entry:"] +# +# res.append(r'</p><p style="float: left;"><b>QMs found:</b>') +# for QM in LogbookEntry.instance.QMs_found.all(): +# res.append(QM.wiki_link()) + +# res.append(r'</p><p style="float: left;"><b>QMs ticked off:</b>') +# for QM in LogbookEntry.instance.QMs_ticked_off.all(): +# res.append(QM.wiki_link()) + +# res.append(r'</p><p style="float: left; "><b>People</b>') +# for persontrip in LogbookEntry.instance.persontrip_set.all(): +# res.append(persontrip.wiki_link()) +# res.append(r'</p>') + +# return string.join(res, r'<br />') + +# def __init__(self, *args, **kwargs): +# super(LogbookEntryForm, self).__init__(*args, **kwargs) +# self.fields['text'].help_text=self.wikiLinkHints()# + +class CaveForm(forms.Form): + html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30})) + +def getTripForm(expedition): + + class TripForm(forms.Form): + date = forms.DateField() + title = forms.CharField(max_length=200) + caves = [cave.reference() for cave in Cave.objects.all()] + caves.sort() + caves = ["-----"] + caves + cave = forms.ChoiceField([(c, c) for c in caves], required=False) + location = forms.CharField(max_length=200, required=False) + caveOrLocation = forms.ChoiceField([("cave", "Cave"), ("location", "Location")], widget = forms.widgets.RadioSelect()) + html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30})) + + def clean(self): + print dir(self) + if self.cleaned_data.get("caveOrLocation") == "cave" and not self.cleaned_data.get("cave"): + self._errors["cave"] = self.error_class(["This field is required"]) + if self.cleaned_data.get("caveOrLocation") == "location" and not self.cleaned_data.get("location"): + self._errors["location"] = self.error_class(["This field is required"]) + return self.cleaned_data + + class PersonTripForm(forms.Form): + names = [get_name(pe) for pe in PersonExpedition.objects.filter(expedition = expedition)] + names.sort() + names = ["-----"] + names + name = forms.ChoiceField([(n, n) for n in names]) + TU = forms.FloatField(required=False) + author = forms.BooleanField(required=False) + + PersonTripFormSet = formset_factory(PersonTripForm, extra=1) + + return PersonTripFormSet, TripForm + +def get_name(pe): + if pe.nickname: + return pe.nickname + else: + return pe.person.first_name + +class UploadFileForm(forms.Form): + title = forms.CharField(max_length=50) + file = forms.FileField() + html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30})) + lon_utm = forms.FloatField(required=False) + lat_utm = forms.FloatField(required=False) + slug = forms.CharField(max_length=50) + date = forms.DateField(required=False) + + caves = [cave.slug for cave in Cave.objects.all()] + caves.sort() + caves = ["-----"] + caves + cave = forms.ChoiceField([(c, c) for c in caves], required=False) + + entrance = forms.ChoiceField([("-----", "Please select a cave"), ], required=False) + qm = forms.ChoiceField([("-----", "Please select a cave"), ], required=False) + + expeditions = [e.year for e in Expedition.objects.all()] + expeditions.sort() + expeditions = ["-----"] + expeditions + expedition = forms.ChoiceField([(e, e) for e in expeditions], required=False) + + logbookentry = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False) + + person = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False) + + survey_point = forms.CharField() + + diff --git a/core/models.py b/core/models.py index d199073..c82f448 100644 --- a/core/models.py +++ b/core/models.py @@ -1,701 +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):
- return urlparse.urljoin(settings.URL_ROOT, self.url)
- #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("<a href=\'%s\'>"%value.get_absolute_url()+unicode(value)+"</a>")
-
+from django import template +from django.utils.safestring import mark_safe + +register = template.Library() + +@register.filter() +def link(value): + return mark_safe("<a href=\'%s\'>"%value.get_absolute_url()+unicode(value)+"</a>") + diff --git a/core/templatetags/survex_markup.py b/core/templatetags/survex_markup.py index 464a04b..5b9aa36 100644 --- a/core/templatetags/survex_markup.py +++ b/core/templatetags/survex_markup.py @@ -1,52 +1,52 @@ -from django import template
-from django.utils.html import conditional_escape
-from django.template.defaultfilters import stringfilter
-from django.utils.safestring import mark_safe
-import re
-
-register = template.Library()
-
-# seems to add extra lines between the commented lines, which isn't so great.
-regexes = []
-regexes.append((re.compile(r"(;.*)$", re.IGNORECASE|re.MULTILINE),
- r'<span class = "comment">\1</span>\n'))
-regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)(.svx)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3<a href="\4.index">\4\5</a>'))
-regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3<a href="\4.index">\4</a>'))
-regexes.append((re.compile(r"^(\s*)(\*team\s+(?:notes|tape|insts|pics))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*(?:begin|end|copyright|date|entrance|equate|export|fix|prefix|require|SOLVE|title|truncate))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*calibrate\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|X|Y|Z)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*data\s+(?:DEFAULT|NORMAL|DIVING|CARTESIAN|TOPOFIL|CYLPOLAR|NOSURVEY|passage)(?:\s+station|\s+from|\s+to|\s+FROMDEPTH|\s+TODEPTH|\s+DEPTHCHANGE|\s+newline|\s+direction|\s+tape|\s+compass|\s+clino|\s+northing|\s+easting|\s+altitude|\s+length|\s+bearing|\s+gradient|\s+ignoreall|\sleft|\sright|\sup|\sdown)*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>'))
-regexes.append((re.compile(r"^(\s*)(\*default\s+(?:CALIBRATE|DATA|UNITS)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*flags\s+(?:DUPLICATE|SPLAY|SURFACE|not DUPLICATE|not SPLAY|not SURFACE))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*infer\s+(?:plumbs|equates|exports))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*sd\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|DX|DY|DZ))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*set\s+(?:BLANK|COMMENT|DECIMAL|EOL|KEYWORD|MINUS|NAMES|OMIT|PLUS|ROOT|SEPARATOR))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*units\s+(?:TAPE|LENGTH|COMPASS|BEARING|CLINO|GRADIENT|COUNTER|DEPTH|DECLINATION|X|Y|Z))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1<span class = "command">\2</span>\3\4'))
-regexes.append((re.compile(r"^(.*)$", re.IGNORECASE|re.MULTILINE),
- r'<div>\1 </div>\n'))
-
-@register.filter()
-@stringfilter
-def survex_to_html(value, autoescape=None):
- if autoescape:
- value = conditional_escape(value)
- for regex, sub in regexes:
- print sub
- value = regex.sub(sub, value)
+from django import template +from django.utils.html import conditional_escape +from django.template.defaultfilters import stringfilter +from django.utils.safestring import mark_safe +import re + +register = template.Library() + +# seems to add extra lines between the commented lines, which isn't so great. +regexes = [] +regexes.append((re.compile(r"(;.*)$", re.IGNORECASE|re.MULTILINE), + r'<span class = "comment">\1</span>\n')) +regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)(.svx)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3<a href="\4.index">\4\5</a>')) +regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3<a href="\4.index">\4</a>')) +regexes.append((re.compile(r"^(\s*)(\*team\s+(?:notes|tape|insts|pics))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*(?:begin|end|copyright|date|entrance|equate|export|fix|prefix|require|SOLVE|title|truncate))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*calibrate\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|X|Y|Z)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*data\s+(?:DEFAULT|NORMAL|DIVING|CARTESIAN|TOPOFIL|CYLPOLAR|NOSURVEY|passage)(?:\s+station|\s+from|\s+to|\s+FROMDEPTH|\s+TODEPTH|\s+DEPTHCHANGE|\s+newline|\s+direction|\s+tape|\s+compass|\s+clino|\s+northing|\s+easting|\s+altitude|\s+length|\s+bearing|\s+gradient|\s+ignoreall|\sleft|\sright|\sup|\sdown)*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>')) +regexes.append((re.compile(r"^(\s*)(\*default\s+(?:CALIBRATE|DATA|UNITS)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*flags\s+(?:DUPLICATE|SPLAY|SURFACE|not DUPLICATE|not SPLAY|not SURFACE))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*infer\s+(?:plumbs|equates|exports))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*sd\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|DX|DY|DZ))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*set\s+(?:BLANK|COMMENT|DECIMAL|EOL|KEYWORD|MINUS|NAMES|OMIT|PLUS|ROOT|SEPARATOR))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(\s*)(\*units\s+(?:TAPE|LENGTH|COMPASS|BEARING|CLINO|GRADIENT|COUNTER|DEPTH|DECLINATION|X|Y|Z))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE), + r'\1<span class = "command">\2</span>\3\4')) +regexes.append((re.compile(r"^(.*)$", re.IGNORECASE|re.MULTILINE), + r'<div>\1 </div>\n')) + +@register.filter() +@stringfilter +def survex_to_html(value, autoescape=None): + if autoescape: + value = conditional_escape(value) + for regex, sub in regexes: + print sub + value = regex.sub(sub, value) return mark_safe(value)
\ No newline at end of file diff --git a/core/templatetags/wiki_markup.py b/core/templatetags/wiki_markup.py index 810634b..4087b12 100644 --- a/core/templatetags/wiki_markup.py +++ b/core/templatetags/wiki_markup.py @@ -1,169 +1,169 @@ -from django import template
-from django.utils.html import conditional_escape
-from django.template.defaultfilters import stringfilter
-from django.utils.safestring import mark_safe
-from django.conf import settings
-from core.models import QM, DPhoto, LogbookEntry, Cave
-import re, urlparse
-
-register = template.Library()
-
-
-@register.filter()
-def plusone(n):
- return n + 1
-
-
-def wiki_list(line, listdepth):
- l = ""
- for d in listdepth:
- l += d
- mstar = re.match(l + "\*(.*)", line)
- if mstar:
- listdepth.append("\*")
- return ("<ul>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mstar.groups()[0], listdepth)
- mhash = re.match(l + "#(.*)", line)
- if mhash:
- listdepth.append("#")
- return ("<ol>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mhash.groups()[0], listdepth)
- mflat = re.match(l + "(.*)", line)
- if mflat and listdepth:
- return (" " * len(listdepth) + "<li>%s</li>\n" % mflat.groups()[0], listdepth)
- if listdepth:
- prev = listdepth.pop()
- if prev == "\*":
- t, l = wiki_list(line, listdepth)
- return ("</ul>\n" + t, l)
- if prev == "#":
- t, l = wiki_list(line, listdepth)
- return ("</ol>\n" + t, l)
- return (line, listdepth)
-
-@register.filter()
-@stringfilter
-def wiki_to_html(value, autoescape=None):
- """
- This is the tag which turns wiki syntax into html. It is intended for long pieces of wiki.
- Hence it splits the wiki into HTML paragraphs based on double line feeds.
- """
- #find paragraphs
- outValue = ""
- for paragraph in re.split("\n\s*?\n", value, re.DOTALL):
- outValue += "<p>"
- outValue += wiki_to_html_short(paragraph, autoescape)
- outValue += "</p>\n"
- return mark_safe(outValue)
-
-@register.filter()
-@stringfilter
-def wiki_to_html_short(value, autoescape=None):
- """
- This is the tag which turns wiki syntax into html. It is intended for short pieces of wiki.
- Hence it is not split the wiki into paragraphs using where it finds double line feeds.
- """
- if autoescape:
- value = conditional_escape(value)
- #deescape doubly escaped characters
- value = re.sub("&(.*?);", r"&\1;", value, re.DOTALL)
- #italics and bold
- value = re.sub("''''([^']+)''''", r"<b><i>\1</i></b>", value, re.DOTALL)
- value = re.sub("'b''([^']+)'''", r"<b>\1</b>", value, re.DOTALL)
- value = re.sub("''([^']+)''", r"<i>\1</i>", value, re.DOTALL)
-
- #make headers
- def headerrepl(matchobj):
- number=len(matchobj.groups()[0])
- num=str(number)
- if number>1:
- return '<h'+num+'>'+matchobj.groups()[1]+'</h'+num+'>'
- else:
- print 'morethanone'
- return matchobj.group()
- value = re.sub(r"(?m)^(=+)([^=]+)(=+)$",headerrepl,value)
-
- #make qm links. this takes a little doing
- qmMatchPattern=settings.QM_PATTERN
- def qmrepl(matchobj):
- """
- A function for replacing wikicode qm links with html qm links.
- Given a matchobj matching a wikilink in the format
- [[QM:C204-1999-24]]
- If the QM does not exist, the function will return a link for creating it.
- """
- qmdict={'urlroot':settings.URL_ROOT,'cave':matchobj.groups()[2],'year':matchobj.groups()[1],'number':matchobj.groups()[3]}
- try:
- qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
- found_by__date__year = qmdict['year'],
- number = qmdict['number'])
- return r'<a href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm))
- except QM.DoesNotExist: #bother aaron to make him clean up the below code - AC
- try:
- placeholder=LogbookEntry.objects.get(date__year=qmdict['year'],cave__kataster_number=qmdict['cave'], title__icontains='placeholder')
- except LogbookEntry.DoesNotExist:
- placeholder=LogbookEntry(
- date='01-01'+qmdict['year'],
- cave=Cave.objects.get(kataster_number=qmdict['cave']),
- title='placeholder'
- )
- qm=QM(found_by = placeholder, number = qmdict['number'])
- return r'<a class="redtext" href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm))
-
- value = re.sub(qmMatchPattern,qmrepl, value, re.DOTALL)
-
- #make photo links for [[photo:filename]] or [[photo:filename linktext]], and
- #insert photos for [[display:left photo:filename]]
- photoLinkPattern="\[\[\s*photo:(?P<photoName>[^\s]+)\s*(?P<linkText>.*)\]\]"
- photoSrcPattern="\[\[\s*display:(?P<style>[^\s]+) photo:(?P<photoName>[^\s]+)\s*\]\]"
- def photoLinkRepl(matchobj):
- matchdict=matchobj.groupdict()
- try:
- linkText=matchdict['linkText']
- except KeyError:
- linkText=None
-
- try:
- photo=DPhoto.objects.get(file=matchdict['photoName'])
- if not linkText:
- linkText=str(photo)
- res=r'<a href=' + photo.get_admin_url() +'>' + linkText + '</a>'
- except Photo.DoesNotExist:
- res = r'<a class="redtext" href="">make new photo</a>'
- return res
-
- def photoSrcRepl(matchobj):
- matchdict=matchobj.groupdict()
- style=matchdict['style']
- try:
- photo=Photo.objects.get(file=matchdict['photoName'])
- res=r'<a href='+photo.file.url+'><img src=' + photo.thumbnail_image.url +' class='+style+' /></a>'
- except Photo.DoesNotExist:
- res = r'<a class="redtext" href="">make new photo</a>'
- return res
- value = re.sub(photoLinkPattern,photoLinkRepl, value, re.DOTALL)
- value = re.sub(photoSrcPattern,photoSrcRepl, value, re.DOTALL)
-
- #make cave links
- value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%scave/\1/">\1</a>' % settings.URL_ROOT, value, re.DOTALL)
- #make people links
- value = re.sub("\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%sperson/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
- #make subcave links
- value = re.sub("\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%ssubcave/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
- #make cavedescription links
- value = re.sub("\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%scavedescription/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
-
-
-
- #Make lists from lines starting with lists of [stars and hashes]
- outValue = ""
- listdepth = []
- for line in value.split("\n"):
- t, listdepth = wiki_list(line, listdepth)
- outValue += t
- for item in listdepth:
- if item == "\*":
- outValue += "</ul>\n"
- elif item == "#":
- outValue += "</ol>\n"
- return mark_safe(outValue)
-
-wiki_to_html.needs_autoescape = True
+from django import template +from django.utils.html import conditional_escape +from django.template.defaultfilters import stringfilter +from django.utils.safestring import mark_safe +from django.conf import settings +from core.models import QM, DPhoto, LogbookEntry, Cave +import re, urlparse + +register = template.Library() + + +@register.filter() +def plusone(n): + return n + 1 + + +def wiki_list(line, listdepth): + l = "" + for d in listdepth: + l += d + mstar = re.match(l + "\*(.*)", line) + if mstar: + listdepth.append("\*") + return ("<ul>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mstar.groups()[0], listdepth) + mhash = re.match(l + "#(.*)", line) + if mhash: + listdepth.append("#") + return ("<ol>\n" + " " * len(listdepth) + "<li>%s</li>\n" % mhash.groups()[0], listdepth) + mflat = re.match(l + "(.*)", line) + if mflat and listdepth: + return (" " * len(listdepth) + "<li>%s</li>\n" % mflat.groups()[0], listdepth) + if listdepth: + prev = listdepth.pop() + if prev == "\*": + t, l = wiki_list(line, listdepth) + return ("</ul>\n" + t, l) + if prev == "#": + t, l = wiki_list(line, listdepth) + return ("</ol>\n" + t, l) + return (line, listdepth) + +@register.filter() +@stringfilter +def wiki_to_html(value, autoescape=None): + """ + This is the tag which turns wiki syntax into html. It is intended for long pieces of wiki. + Hence it splits the wiki into HTML paragraphs based on double line feeds. + """ + #find paragraphs + outValue = "" + for paragraph in re.split("\n\s*?\n", value, re.DOTALL): + outValue += "<p>" + outValue += wiki_to_html_short(paragraph, autoescape) + outValue += "</p>\n" + return mark_safe(outValue) + +@register.filter() +@stringfilter +def wiki_to_html_short(value, autoescape=None): + """ + This is the tag which turns wiki syntax into html. It is intended for short pieces of wiki. + Hence it is not split the wiki into paragraphs using where it finds double line feeds. + """ + if autoescape: + value = conditional_escape(value) + #deescape doubly escaped characters + value = re.sub("&(.*?);", r"&\1;", value, re.DOTALL) + #italics and bold + value = re.sub("''''([^']+)''''", r"<b><i>\1</i></b>", value, re.DOTALL) + value = re.sub("'b''([^']+)'''", r"<b>\1</b>", value, re.DOTALL) + value = re.sub("''([^']+)''", r"<i>\1</i>", value, re.DOTALL) + + #make headers + def headerrepl(matchobj): + number=len(matchobj.groups()[0]) + num=str(number) + if number>1: + return '<h'+num+'>'+matchobj.groups()[1]+'</h'+num+'>' + else: + print 'morethanone' + return matchobj.group() + value = re.sub(r"(?m)^(=+)([^=]+)(=+)$",headerrepl,value) + + #make qm links. this takes a little doing + qmMatchPattern=settings.QM_PATTERN + def qmrepl(matchobj): + """ + A function for replacing wikicode qm links with html qm links. + Given a matchobj matching a wikilink in the format + [[QM:C204-1999-24]] + If the QM does not exist, the function will return a link for creating it. + """ + qmdict={'urlroot':settings.URL_ROOT,'cave':matchobj.groups()[2],'year':matchobj.groups()[1],'number':matchobj.groups()[3]} + try: + qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'], + found_by__date__year = qmdict['year'], + number = qmdict['number']) + return r'<a href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm)) + except QM.DoesNotExist: #bother aaron to make him clean up the below code - AC + try: + placeholder=LogbookEntry.objects.get(date__year=qmdict['year'],cave__kataster_number=qmdict['cave'], title__icontains='placeholder') + except LogbookEntry.DoesNotExist: + placeholder=LogbookEntry( + date='01-01'+qmdict['year'], + cave=Cave.objects.get(kataster_number=qmdict['cave']), + title='placeholder' + ) + qm=QM(found_by = placeholder, number = qmdict['number']) + return r'<a class="redtext" href="%s" id="q%s">%s</a>' % (qm.get_absolute_url(), qm.code, unicode(qm)) + + value = re.sub(qmMatchPattern,qmrepl, value, re.DOTALL) + + #make photo links for [[photo:filename]] or [[photo:filename linktext]], and + #insert photos for [[display:left photo:filename]] + photoLinkPattern="\[\[\s*photo:(?P<photoName>[^\s]+)\s*(?P<linkText>.*)\]\]" + photoSrcPattern="\[\[\s*display:(?P<style>[^\s]+) photo:(?P<photoName>[^\s]+)\s*\]\]" + def photoLinkRepl(matchobj): + matchdict=matchobj.groupdict() + try: + linkText=matchdict['linkText'] + except KeyError: + linkText=None + + try: + photo=DPhoto.objects.get(file=matchdict['photoName']) + if not linkText: + linkText=str(photo) + res=r'<a href=' + photo.get_admin_url() +'>' + linkText + '</a>' + except Photo.DoesNotExist: + res = r'<a class="redtext" href="">make new photo</a>' + return res + + def photoSrcRepl(matchobj): + matchdict=matchobj.groupdict() + style=matchdict['style'] + try: + photo=Photo.objects.get(file=matchdict['photoName']) + res=r'<a href='+photo.file.url+'><img src=' + photo.thumbnail_image.url +' class='+style+' /></a>' + except Photo.DoesNotExist: + res = r'<a class="redtext" href="">make new photo</a>' + return res + value = re.sub(photoLinkPattern,photoLinkRepl, value, re.DOTALL) + value = re.sub(photoSrcPattern,photoSrcRepl, value, re.DOTALL) + + #make cave links + value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%scave/\1/">\1</a>' % settings.URL_ROOT, value, re.DOTALL) + #make people links + value = re.sub("\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%sperson/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL) + #make subcave links + value = re.sub("\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%ssubcave/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL) + #make cavedescription links + value = re.sub("\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%scavedescription/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL) + + + + #Make lists from lines starting with lists of [stars and hashes] + outValue = "" + listdepth = [] + for line in value.split("\n"): + t, listdepth = wiki_list(line, listdepth) + outValue += t + for item in listdepth: + if item == "\*": + outValue += "</ul>\n" + elif item == "#": + outValue += "</ol>\n" + return mark_safe(outValue) + +wiki_to_html.needs_autoescape = True diff --git a/core/view_surveys.py b/core/view_surveys.py index 66aa1ed..a6df780 100644 --- a/core/view_surveys.py +++ b/core/view_surveys.py @@ -1,233 +1,233 @@ -from django.conf import settings
-import fileAbstraction
-from django.shortcuts import render_to_response
-from django.http import HttpResponse, Http404
-import os, stat
-import re
-from troggle.core.models import SurvexScansFolder, SurvexScanSingle, SurvexBlock, TunnelFile
-import parsers.surveys
-
-# inline fileabstraction into here if it's not going to be useful anywhere else
-# keep things simple and ignore exceptions everywhere for now
-
-
-def getMimeType(extension):
- try:
- return {"txt": "text/plain",
- "html": "text/html",
- }[extension]
- except:
- print "unknown file type"
- return "text/plain"
-
-
-def listdir(request, path):
- #try:
- return HttpResponse(fileAbstraction.listdir(path), mimetype = "text/plain")
- #except:
- # raise Http404
-
-def upload(request, path):
- pass
-
-def download(request, path):
- #try:
-
- return HttpResponse(fileAbstraction.readFile(path), mimetype=getMimeType(path.split(".")[-1]))
- #except:
- # raise Http404
-
-
-#
-# julian's quick hack for something that works
-# could signal directories by ending with /, and forward cases where it's missing
-#
-extmimetypes = {".txt": "text/plain",
- ".html": "text/html",
- ".png": "image/png",
- ".jpg": "image/jpeg",
- }
-
-# dead
-def jgtfile(request, f):
- fp = os.path.join(settings.SURVEYS, f)
- # could also surf through SURVEX_DATA
-
- # directory listing
- if os.path.isdir(fp):
- listdirfiles = [ ]
- listdirdirs = [ ]
-
- for lf in sorted(os.listdir(fp)):
- hpath = os.path.join(f, lf) # not absolute path
- if lf[0] == "." or lf[-1] == "~":
- continue
-
- hpath = hpath.replace("\\", "/") # for windows users
- href = hpath.replace("#", "%23") # '#' in file name annoyance
-
- flf = os.path.join(fp, lf)
- if os.path.isdir(flf):
- nfiles = len([sf for sf in os.listdir(flf) if sf[0] != "."])
- listdirdirs.append((href, hpath + "/", nfiles))
- else:
- listdirfiles.append((href, hpath, os.path.getsize(flf)))
-
- upperdirs = [ ]
- lf = f
- while lf:
- hpath = lf.replace("\\", "/") # for windows users
- if hpath[-1] != "/":
- hpath += "/"
- href = hpath.replace("#", "%23")
- lf = os.path.split(lf)[0]
- upperdirs.append((href, hpath))
- upperdirs.append(("", "/"))
-
- return render_to_response('listdir.html', {'file':f, 'listdirfiles':listdirfiles, 'listdirdirs':listdirdirs, 'upperdirs':upperdirs, 'settings': settings})
-
- # flat output of file when loaded
- if os.path.isfile(fp):
- ext = os.path.splitext(fp)[1].lower()
- mimetype = extmimetypes.get(ext, "text/plain")
- fin = open(fp)
- ftext = fin.read()
- fin.close()
- return HttpResponse(ftext, mimetype=mimetype)
-
- return HttpResponse("unknown file::%s::" % f, mimetype = "text/plain")
-
-
-def UniqueFile(fname):
- while True:
- if not os.path.exists(fname):
- break
- mname = re.match("(.*?)(?:-(\d+))?\.(png|jpg|jpeg)$(?i)", fname)
- if mname:
- fname = "%s-%d.%s" % (mname.group(1), int(mname.group(2) or "0") + 1, mname.group(3))
- return fname
-
-
-# join it all up and then split them off for the directories that don't exist
-# anyway, this mkdir doesn't work
-def SaveImageInDir(name, imgdir, project, fdata, bbinary):
- print ("hihihihi", fdata, settings.SURVEYS)
- fimgdir = os.path.join(settings.SURVEYS, imgdir)
- if not os.path.isdir(fimgdir):
- print "*** Making directory", fimgdir
- os.path.mkdir(fimgdir)
- fprojdir = os.path.join(fimgdir, project)
- if not os.path.isdir(fprojdir):
- print "*** Making directory", fprojdir
- os.path.mkdir(fprojdir)
- print "hhh"
-
- fname = os.path.join(fprojdir, name)
- print fname, "fff"
- fname = UniqueFile(fname)
-
- p2, p1 = os.path.split(fname)
- p3, p2 = os.path.split(p2)
- p4, p3 = os.path.split(p3)
- res = os.path.join(p3, p2, p1)
-
- print "saving file", fname
- fout = open(fname, (bbinary and "wb" or "w"))
- fout.write(fdata.read())
- fout.close()
- res = os.path.join(imgdir, name)
- return res.replace("\\", "/")
-
-
-# do we want to consider saving project/field rather than field/project
-def jgtuploadfile(request):
- filesuploaded = [ ]
- project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"]
- print (project, user, tunnelversion)
- for uploadedfile in request.FILES.values():
- if uploadedfile.field_name in ["tileimage", "backgroundimage"] and \
- uploadedfile.content_type in ["image/png", "image/jpeg"]:
- fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
- print fname
- fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, True)
- filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
- if uploadedfile.field_name in ["sketch"] and \
- uploadedfile.content_type in ["text/plain"]:
- fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
- print fname
- fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, False)
- filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
- #print "FF", request.FILES
- #print ("FFF", request.FILES.values())
- message = ""
- print "gothere"
- return render_to_response('fileupload.html', {'message':message, 'filesuploaded':filesuploaded, 'settings': settings})
-
-def surveyscansfolder(request, path):
- #print [ s.walletname for s in SurvexScansFolder.objects.all() ]
- survexscansfolder = SurvexScansFolder.objects.get(walletname=path)
- return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings })
-
-def surveyscansingle(request, path, file):
- survexscansfolder = SurvexScansFolder.objects.get(walletname=path)
- survexscansingle = SurvexScanSingle.objects.get(survexscansfolder=survexscansfolder, name=file)
- return HttpResponse(content=open(survexscansingle.ffile), mimetype="image/png")
- #return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings })
-
-def surveyscansfolders(request):
- survexscansfolders = SurvexScansFolder.objects.all()
- return render_to_response('survexscansfolders.html', { 'survexscansfolders':survexscansfolders, 'settings': settings })
-
-
-def tunneldata(request):
- tunnelfiles = TunnelFile.objects.all()
- return render_to_response('tunnelfiles.html', { 'tunnelfiles':tunnelfiles, 'settings': settings })
-
-
-def tunnelfile(request, path):
- tunnelfile = TunnelFile.objects.get(tunnelpath=path)
- tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath)
- return HttpResponse(content=open(tfile), mimetype="text/plain")
-
-def tunnelfileupload(request, path):
- tunnelfile = TunnelFile.objects.get(tunnelpath=path)
- tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath)
-
- project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"]
- print (project, user, tunnelversion)
-
-
- assert len(request.FILES.values()) == 1, "only one file to upload"
-
- uploadedfile = request.FILES.values()[0]
-
- if uploadedfile.field_name != "sketch":
- return HttpResponse(content="Error: non-sketch file uploaded", mimetype="text/plain")
- if uploadedfile.content_type != "text/plain":
- return HttpResponse(content="Error: non-plain content type", mimetype="text/plain")
-
- # could use this to add new files
- if os.path.split(path)[1] != uploadedfile.name:
- return HttpResponse(content="Error: name disagrees", mimetype="text/plain")
-
- orgsize = tunnelfile.filesize # = os.stat(tfile)[stat.ST_SIZE]
-
- ttext = uploadedfile.read()
-
- # could check that the user and projects agree here
-
- fout = open(tfile, "w")
- fout.write(ttext)
- fout.close()
-
- # redo its settings of
- parsers.surveys.SetTunnelfileInfo(tunnelfile)
- tunnelfile.save()
-
- uploadedfile.close()
- message = "File size %d overwritten with size %d" % (orgsize, tunnelfile.filesize)
- return HttpResponse(content=message, mimetype="text/plain")
-
-
-
-
+from django.conf import settings +import fileAbstraction +from django.shortcuts import render_to_response +from django.http import HttpResponse, Http404 +import os, stat +import re +from troggle.core.models import SurvexScansFolder, SurvexScanSingle, SurvexBlock, TunnelFile +import parsers.surveys + +# inline fileabstraction into here if it's not going to be useful anywhere else +# keep things simple and ignore exceptions everywhere for now + + +def getMimeType(extension): + try: + return {"txt": "text/plain", + "html": "text/html", + }[extension] + except: + print "unknown file type" + return "text/plain" + + +def listdir(request, path): + #try: + return HttpResponse(fileAbstraction.listdir(path), mimetype = "text/plain") + #except: + # raise Http404 + +def upload(request, path): + pass + +def download(request, path): + #try: + + return HttpResponse(fileAbstraction.readFile(path), mimetype=getMimeType(path.split(".")[-1])) + #except: + # raise Http404 + + +# +# julian's quick hack for something that works +# could signal directories by ending with /, and forward cases where it's missing +# +extmimetypes = {".txt": "text/plain", + ".html": "text/html", + ".png": "image/png", + ".jpg": "image/jpeg", + } + +# dead +def jgtfile(request, f): + fp = os.path.join(settings.SURVEYS, f) + # could also surf through SURVEX_DATA + + # directory listing + if os.path.isdir(fp): + listdirfiles = [ ] + listdirdirs = [ ] + + for lf in sorted(os.listdir(fp)): + hpath = os.path.join(f, lf) # not absolute path + if lf[0] == "." or lf[-1] == "~": + continue + + hpath = hpath.replace("\\", "/") # for windows users + href = hpath.replace("#", "%23") # '#' in file name annoyance + + flf = os.path.join(fp, lf) + if os.path.isdir(flf): + nfiles = len([sf for sf in os.listdir(flf) if sf[0] != "."]) + listdirdirs.append((href, hpath + "/", nfiles)) + else: + listdirfiles.append((href, hpath, os.path.getsize(flf))) + + upperdirs = [ ] + lf = f + while lf: + hpath = lf.replace("\\", "/") # for windows users + if hpath[-1] != "/": + hpath += "/" + href = hpath.replace("#", "%23") + lf = os.path.split(lf)[0] + upperdirs.append((href, hpath)) + upperdirs.append(("", "/")) + + return render_to_response('listdir.html', {'file':f, 'listdirfiles':listdirfiles, 'listdirdirs':listdirdirs, 'upperdirs':upperdirs, 'settings': settings}) + + # flat output of file when loaded + if os.path.isfile(fp): + ext = os.path.splitext(fp)[1].lower() + mimetype = extmimetypes.get(ext, "text/plain") + fin = open(fp) + ftext = fin.read() + fin.close() + return HttpResponse(ftext, mimetype=mimetype) + + return HttpResponse("unknown file::%s::" % f, mimetype = "text/plain") + + +def UniqueFile(fname): + while True: + if not os.path.exists(fname): + break + mname = re.match("(.*?)(?:-(\d+))?\.(png|jpg|jpeg)$(?i)", fname) + if mname: + fname = "%s-%d.%s" % (mname.group(1), int(mname.group(2) or "0") + 1, mname.group(3)) + return fname + + +# join it all up and then split them off for the directories that don't exist +# anyway, this mkdir doesn't work +def SaveImageInDir(name, imgdir, project, fdata, bbinary): + print ("hihihihi", fdata, settings.SURVEYS) + fimgdir = os.path.join(settings.SURVEYS, imgdir) + if not os.path.isdir(fimgdir): + print "*** Making directory", fimgdir + os.path.mkdir(fimgdir) + fprojdir = os.path.join(fimgdir, project) + if not os.path.isdir(fprojdir): + print "*** Making directory", fprojdir + os.path.mkdir(fprojdir) + print "hhh" + + fname = os.path.join(fprojdir, name) + print fname, "fff" + fname = UniqueFile(fname) + + p2, p1 = os.path.split(fname) + p3, p2 = os.path.split(p2) + p4, p3 = os.path.split(p3) + res = os.path.join(p3, p2, p1) + + print "saving file", fname + fout = open(fname, (bbinary and "wb" or "w")) + fout.write(fdata.read()) + fout.close() + res = os.path.join(imgdir, name) + return res.replace("\\", "/") + + +# do we want to consider saving project/field rather than field/project +def jgtuploadfile(request): + filesuploaded = [ ] + project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"] + print (project, user, tunnelversion) + for uploadedfile in request.FILES.values(): + if uploadedfile.field_name in ["tileimage", "backgroundimage"] and \ + uploadedfile.content_type in ["image/png", "image/jpeg"]: + fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \ + print fname + fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, True) + filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded) + if uploadedfile.field_name in ["sketch"] and \ + uploadedfile.content_type in ["text/plain"]: + fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \ + print fname + fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, False) + filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded) + #print "FF", request.FILES + #print ("FFF", request.FILES.values()) + message = "" + print "gothere" + return render_to_response('fileupload.html', {'message':message, 'filesuploaded':filesuploaded, 'settings': settings}) + +def surveyscansfolder(request, path): + #print [ s.walletname for s in SurvexScansFolder.objects.all() ] + survexscansfolder = SurvexScansFolder.objects.get(walletname=path) + return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings }) + +def surveyscansingle(request, path, file): + survexscansfolder = SurvexScansFolder.objects.get(walletname=path) + survexscansingle = SurvexScanSingle.objects.get(survexscansfolder=survexscansfolder, name=file) + return HttpResponse(content=open(survexscansingle.ffile), mimetype="image/png") + #return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings }) + +def surveyscansfolders(request): + survexscansfolders = SurvexScansFolder.objects.all() + return render_to_response('survexscansfolders.html', { 'survexscansfolders':survexscansfolders, 'settings': settings }) + + +def tunneldata(request): + tunnelfiles = TunnelFile.objects.all() + return render_to_response('tunnelfiles.html', { 'tunnelfiles':tunnelfiles, 'settings': settings }) + + +def tunnelfile(request, path): + tunnelfile = TunnelFile.objects.get(tunnelpath=path) + tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath) + return HttpResponse(content=open(tfile), mimetype="text/plain") + +def tunnelfileupload(request, path): + tunnelfile = TunnelFile.objects.get(tunnelpath=path) + tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath) + + project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"] + print (project, user, tunnelversion) + + + assert len(request.FILES.values()) == 1, "only one file to upload" + + uploadedfile = request.FILES.values()[0] + + if uploadedfile.field_name != "sketch": + return HttpResponse(content="Error: non-sketch file uploaded", mimetype="text/plain") + if uploadedfile.content_type != "text/plain": + return HttpResponse(content="Error: non-plain content type", mimetype="text/plain") + + # could use this to add new files + if os.path.split(path)[1] != uploadedfile.name: + return HttpResponse(content="Error: name disagrees", mimetype="text/plain") + + orgsize = tunnelfile.filesize # = os.stat(tfile)[stat.ST_SIZE] + + ttext = uploadedfile.read() + + # could check that the user and projects agree here + + fout = open(tfile, "w") + fout.write(ttext) + fout.close() + + # redo its settings of + parsers.surveys.SetTunnelfileInfo(tunnelfile) + tunnelfile.save() + + uploadedfile.close() + message = "File size %d overwritten with size %d" % (orgsize, tunnelfile.filesize) + return HttpResponse(content=message, mimetype="text/plain") + + + + diff --git a/core/views.py b/core/views.py index 337989a..26c2e52 100644 --- a/core/views.py +++ b/core/views.py @@ -1,8 +1,8 @@ -# primary namespace
-
-import view_surveys
-import views_caves
-import views_survex
-import views_logbooks
-import views_other
-
+# primary namespace + +import view_surveys +import views_caves +import views_survex +import views_logbooks +import views_other + diff --git a/core/views_caves.py b/core/views_caves.py index d078338..4a79652 100644 --- a/core/views_caves.py +++ b/core/views_caves.py @@ -1,141 +1,141 @@ -from troggle.core.models import Cave, CaveAndEntrance, Survey, Expedition, QM, CaveDescription
-from troggle.core.forms import CaveForm
-import troggle.core.models as models
-import troggle.settings as settings
-from troggle.helper import login_required_if_public
-
-from django.forms.models import formset_factory
-from django.core.urlresolvers import reverse
-from utils import render_with_context # see views_logbooks for explanation on this.
-from django.http import HttpResponseRedirect
-from django.conf import settings
-import re, urlparse
-from django.shortcuts import get_object_or_404
-
-def getCave(cave_id):
- """Returns a cave object when given a cave name or number. It is used by views including cavehref, ent, and qm."""
- try:
- cave = Cave.objects.get(kataster_number=cave_id)
- except Cave.DoesNotExist:
- cave = Cave.objects.get(unofficial_number=cave_id)
- return cave
-
-def caveindex(request):
- caves = Cave.objects.all()
- notablecavehrefs = [ "161", "204", "258", "76" ] # could detect notability by trips and notability of people who have been down them
- notablecaves = [Cave.objects.get(kataster_number=kataster_number) for kataster_number in notablecavehrefs ]
- caves1623 = Cave.objects.filter(area__short_name = "1623")
- caves1626 = Cave.objects.filter(area__short_name = "1626")
- return render_with_context(request,'caveindex.html', {'caves1623': caves1623, 'caves1626': caves1626, 'notablecaves':notablecaves, 'cavepage': True})
-
-def cave(request, cave_id='', offical_name=''):
- cave=getCave(cave_id)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave, 'cavepage': True})
- else:
- return render_with_context(request,'cave.html', {'cave': cave, 'cavepage': True})
-
-def caveEntrance(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_entrances.html', {'cave': cave})
-def caveDescription(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_uground_description.html', {'cave': cave})
-def caveQMs(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_qms.html', {'cave': cave})
-def caveLogbook(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave_logbook.html', {'cave': cave})
-
-def caveSlug(request, slug):
- cave = Cave.objects.get(slug = slug)
- if cave.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': cave})
- else:
- return render_with_context(request,'cave.html', {'cave': cave})
-
-@login_required_if_public
-def editCave(request, slug=None):
- form = CaveForm()
- return render_with_context(request,
- 'editcave.html',
- {'form': form})
-
-def qm(request,cave_id,qm_id,year,grade=None):
- year=int(year)
- try:
- qm=getCave(cave_id).get_QMs().get(number=qm_id,found_by__date__year=year)
- return render_with_context(request,'qm.html',locals())
-
- except QM.DoesNotExist:
- url=urlparse.urljoin(settings.URL_ROOT, r'/admin/core/qm/add/'+'?'+ r'number=' + qm_id)
- if grade:
- url += r'&grade=' + grade
- return HttpResponseRedirect(url)
-
-
-
-def ent(request, cave_id, ent_letter):
- cave = Cave.objects.filter(kataster_number = cave_id)[0]
- cave_and_ent = CaveAndEntrance.objects.filter(cave = cave).filter(entrance_letter = ent_letter)[0]
- return render_with_context(request,'entrance.html', {'cave': cave,
- 'entrance': cave_and_ent.entrance,
- 'letter': cave_and_ent.entrance_letter,})
-
-def entranceSlug(request, slug):
- entrance = Entrance.objects.get(slug = slug)
- if entrance.non_public and not request.user.is_authenticated():
- return render_with_context(request,'nonpublic.html', {'instance': entrance})
- else:
- return render_with_context(request,'entranceslug.html', {'entrance': entrance})
-
-def survexblock(request, survexpath):
- survexpath = re.sub("/", ".", survexpath)
- print "jjjjjj", survexpath
- survexblock = models.SurvexBlock.objects.get(survexpath=survexpath)
- #ftext = survexblock.filecontents()
- ftext = survexblock.text
- return render_with_context(request,'survexblock.html', {'survexblock':survexblock, 'ftext':ftext, })
-
-def surveyindex(request):
- surveys=Survey.objects.all()
- expeditions=Expedition.objects.order_by("-year")
- return render_with_context(request,'survey.html',locals())
-
-def survey(request,year,wallet_number):
- surveys=Survey.objects.all()
- expeditions=Expedition.objects.order_by("-year")
- current_expedition=Expedition.objects.filter(year=year)[0]
-
- if wallet_number!='':
- current_survey=Survey.objects.filter(expedition=current_expedition,wallet_number=wallet_number)[0]
- notes=current_survey.scannedimage_set.filter(contents='notes')
- planSketches=current_survey.scannedimage_set.filter(contents='plan')
- elevationSketches=current_survey.scannedimage_set.filter(contents='elevation')
-
- return render_with_context(request,'survey.html', locals())
-
-def cave_description(request, cavedescription_name):
- cave_description = get_object_or_404(CaveDescription, short_name = cavedescription_name)
- return render_with_context(request,'cave_description.html', locals())
-
-def get_entrances(request, caveslug):
- cave = Cave.objects.get(slug = caveslug)
- return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]})
-
-def get_qms(request, caveslug):
- cave = Cave.objects.get(slug = caveslug)
- return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]})
+from troggle.core.models import Cave, CaveAndEntrance, Survey, Expedition, QM, CaveDescription +from troggle.core.forms import CaveForm +import troggle.core.models as models +import troggle.settings as settings +from troggle.helper import login_required_if_public + +from django.forms.models import formset_factory +from django.core.urlresolvers import reverse +from utils import render_with_context # see views_logbooks for explanation on this. +from django.http import HttpResponseRedirect +from django.conf import settings +import re, urlparse +from django.shortcuts import get_object_or_404 + +def getCave(cave_id): + """Returns a cave object when given a cave name or number. It is used by views including cavehref, ent, and qm.""" + try: + cave = Cave.objects.get(kataster_number=cave_id) + except Cave.DoesNotExist: + cave = Cave.objects.get(unofficial_number=cave_id) + return cave + +def caveindex(request): + caves = Cave.objects.all() + notablecavehrefs = [ "161", "204", "258", "76" ] # could detect notability by trips and notability of people who have been down them + notablecaves = [Cave.objects.get(kataster_number=kataster_number) for kataster_number in notablecavehrefs ] + caves1623 = Cave.objects.filter(area__short_name = "1623") + caves1626 = Cave.objects.filter(area__short_name = "1626") + return render_with_context(request,'caveindex.html', {'caves1623': caves1623, 'caves1626': caves1626, 'notablecaves':notablecaves, 'cavepage': True}) + +def cave(request, cave_id='', offical_name=''): + cave=getCave(cave_id) + if cave.non_public and not request.user.is_authenticated(): + return render_with_context(request,'nonpublic.html', {'instance': cave, 'cavepage': True}) + else: + return render_with_context(request,'cave.html', {'cave': cave, 'cavepage': True}) + +def caveEntrance(request, slug): + cave = Cave.objects.get(slug = slug) + if cave.non_public and not request.user.is_authenticated(): + return render_with_context(request,'nonpublic.html', {'instance': cave}) + else: + return render_with_context(request,'cave_entrances.html', {'cave': cave}) +def caveDescription(request, slug): + cave = Cave.objects.get(slug = slug) + if cave.non_public and not request.user.is_authenticated(): + return render_with_context(request,'nonpublic.html', {'instance': cave}) + else: + return render_with_context(request,'cave_uground_description.html', {'cave': cave}) +def caveQMs(request, slug): + cave = Cave.objects.get(slug = slug) + if cave.non_public and not request.user.is_authenticated(): + return render_with_context(request,'nonpublic.html', {'instance': cave}) + else: + return render_with_context(request,'cave_qms.html', {'cave': cave}) +def caveLogbook(request, slug): + cave = Cave.objects.get(slug = slug) + if cave.non_public and not request.user.is_authenticated(): + return render_with_context(request,'nonpublic.html', {'instance': cave}) + else: + return render_with_context(request,'cave_logbook.html', {'cave': cave}) + +def caveSlug(request, slug): + cave = Cave.objects.get(slug = slug) + if cave.non_public and not request.user.is_authenticated(): + return render_with_context(request,'nonpublic.html', {'instance': cave}) + else: + return render_with_context(request,'cave.html', {'cave': cave}) + +@login_required_if_public +def editCave(request, slug=None): + form = CaveForm() + return render_with_context(request, + 'editcave.html', + {'form': form}) + +def qm(request,cave_id,qm_id,year,grade=None): + year=int(year) + try: + qm=getCave(cave_id).get_QMs().get(number=qm_id,found_by__date__year=year) + return render_with_context(request,'qm.html',locals()) + + except QM.DoesNotExist: + url=urlparse.urljoin(settings.URL_ROOT, r'/admin/core/qm/add/'+'?'+ r'number=' + qm_id) + if grade: + url += r'&grade=' + grade + return HttpResponseRedirect(url) + + + +def ent(request, cave_id, ent_letter): + cave = Cave.objects.filter(kataster_number = cave_id)[0] + cave_and_ent = CaveAndEntrance.objects.filter(cave = cave).filter(entrance_letter = ent_letter)[0] + return render_with_context(request,'entrance.html', {'cave': cave, + 'entrance': cave_and_ent.entrance, + 'letter': cave_and_ent.entrance_letter,}) + +def entranceSlug(request, slug): + entrance = Entrance.objects.get(slug = slug) + if entrance.non_public and not request.user.is_authenticated(): + return render_with_context(request,'nonpublic.html', {'instance': entrance}) + else: + return render_with_context(request,'entranceslug.html', {'entrance': entrance}) + +def survexblock(request, survexpath): + survexpath = re.sub("/", ".", survexpath) + print "jjjjjj", survexpath + survexblock = models.SurvexBlock.objects.get(survexpath=survexpath) + #ftext = survexblock.filecontents() + ftext = survexblock.text + return render_with_context(request,'survexblock.html', {'survexblock':survexblock, 'ftext':ftext, }) + +def surveyindex(request): + surveys=Survey.objects.all() + expeditions=Expedition.objects.order_by("-year") + return render_with_context(request,'survey.html',locals()) + +def survey(request,year,wallet_number): + surveys=Survey.objects.all() + expeditions=Expedition.objects.order_by("-year") + current_expedition=Expedition.objects.filter(year=year)[0] + + if wallet_number!='': + current_survey=Survey.objects.filter(expedition=current_expedition,wallet_number=wallet_number)[0] + notes=current_survey.scannedimage_set.filter(contents='notes') + planSketches=current_survey.scannedimage_set.filter(contents='plan') + elevationSketches=current_survey.scannedimage_set.filter(contents='elevation') + + return render_with_context(request,'survey.html', locals()) + +def cave_description(request, cavedescription_name): + cave_description = get_object_or_404(CaveDescription, short_name = cavedescription_name) + return render_with_context(request,'cave_description.html', locals()) + +def get_entrances(request, caveslug): + cave = Cave.objects.get(slug = caveslug) + return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]}) + +def get_qms(request, caveslug): + cave = Cave.objects.get(slug = caveslug) + return render_with_context(request,'options.html', {"items": [(e.entrance.slug, e.entrance.slug) for e in cave.entrances()]}) diff --git a/core/views_logbooks.py b/core/views_logbooks.py index 007086f..2cf9163 100644 --- a/core/views_logbooks.py +++ b/core/views_logbooks.py @@ -1,252 +1,252 @@ -from django.shortcuts import render_to_response
-from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, SurvexBlock
-import troggle.core.models as models
-import troggle.settings as settings
-import django.db.models
-from troggle.parsers.logbooks import LoadLogbookForExpedition
-from troggle.parsers.people import GetPersonExpeditionNameLookup
-#from troggle.core.forms import PersonForm, getTripForm, get_name
-from django.core.urlresolvers import reverse
-from django.http import HttpResponseRedirect, HttpResponse
-from django.template import Context, loader
-from utils import render_with_context
-import os.path
-import troggle.parsers.logbooks as logbookparsers
-from django.template.defaultfilters import slugify
-from troggle.helper import login_required_if_public
-import datetime
-
-
-# Django uses Context, not RequestContext when you call render_to_response. We always want to use RequestContext, so that django adds the context from settings.TEMPLATE_CONTEXT_PROCESSORS. This way we automatically get necessary settings variables passed to each template. So we use a custom method, render_response instead of render_to_response. Hopefully future Django releases will make this unnecessary.
-#from troggle.alwaysUseRequestContext import render_response
-
-import re
-
-@django.db.models.permalink #this allows the nice get_absolute_url syntax we are using
-
-def getNotablePersons():
- notablepersons = []
- for person in Person.objects.all():
- if person.bisnotable():
- notablepersons.append(person)
- return notablepersons
-
-
-def personindex(request):
- persons = Person.objects.all()
- # From what I can tell, "persons" seems to be the table rows, while "personss" is the table columns. - AC 16 Feb 09
- personss = [ ]
- ncols = 4
- nc = (len(persons) + ncols - 1) / ncols
- for i in range(ncols):
- personss.append(persons[i * nc: (i + 1) * nc])
-
- notablepersons = []
- for person in Person.objects.all():
- if person.bisnotable():
- notablepersons.append(person)
-
- return render_with_context(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, })
-
-
-def expedition(request, expeditionname):
- expedition = Expedition.objects.get(year=int(expeditionname))
- expeditions = Expedition.objects.all()
- personexpeditiondays = [ ]
- dateditems = list(expedition.logbookentry_set.all()) + list(expedition.survexblock_set.all())
- dates = list(set([item.date for item in dateditems]))
- dates.sort()
- for personexpedition in expedition.personexpedition_set.all():
- prow = [ ]
- for date in dates:
- pcell = { "persontrips": PersonTrip.objects.filter(personexpedition=personexpedition,
- logbook_entry__date=date) }
- pcell["survexblocks"] = set(SurvexBlock.objects.filter(survexpersonrole__personexpedition=personexpedition,
- date = date))
- prow.append(pcell)
- personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
-
- message = ""
- if "reload" in request.GET:
- message = LoadLogbookForExpedition(expedition)
- return render_with_context(request,'expedition.html', {'expedition': expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'message':message, 'settings':settings, 'dateditems': dateditems })
-
- def get_absolute_url(self):
- return ('expedition', (expedition.year))
-
-
-def person(request, first_name='', last_name='', ):
- person = Person.objects.get(first_name = first_name, last_name = last_name)
-
- #This is for removing the reference to the user's profile, in case they set it to the wrong person
- if request.method == 'GET':
- if request.GET.get('clear_profile')=='True':
- person.user=None
- person.save()
- return HttpResponseRedirect(reverse('profiles_select_profile'))
-
- return render_with_context(request,'person.html', {'person': person, })
-
-
-def GetPersonChronology(personexpedition):
- res = { }
- for persontrip in personexpedition.persontrip_set.all():
- a = res.setdefault(persontrip.date, { })
- a.setdefault("persontrips", [ ]).append(persontrip)
-
- for personrole in personexpedition.survexpersonrole_set.all():
- a = res.setdefault(personrole.survexblock.date, { })
- a.setdefault("personroles", [ ]).append(personrole.survexblock)
-
- # build up the tables
- rdates = res.keys()
- rdates.sort()
-
-
- res2 = [ ]
- for rdate in rdates:
- persontrips = res[rdate].get("persontrips", [])
- personroles = res[rdate].get("personroles", [])
- for n in range(max(len(persontrips), len(personroles))):
- res2.append(((n == 0 and rdate or "--"), (n < len(persontrips) and persontrips[n]), (n < len(personroles) and personroles[n])))
-
- return res2
-
-
-def personexpedition(request, first_name='', last_name='', year=''):
- person = Person.objects.get(first_name = first_name, last_name = last_name)
- expedition = Expedition.objects.get(year=year)
- personexpedition = person.personexpedition_set.get(expedition=expedition)
- personchronology = GetPersonChronology(personexpedition)
- return render_with_context(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})
-
-
-def logbookentry(request, date, slug):
- logbookentry = LogbookEntry.objects.filter(date=date, slug=slug)
-
- if len(logbookentry)>1:
- return render_with_context(request, 'object_list.html',{'object_list':logbookentry})
- else:
- logbookentry=logbookentry[0]
- return render_with_context(request, 'logbookentry.html', {'logbookentry': logbookentry})
-
-
-def logbookSearch(request, extra):
- query_string = ''
- found_entries = None
- if ('q' in request.GET) and request.GET['q'].strip():
- query_string = request.GET['q']
- entry_query = search.get_query(query_string, ['text','title',])
- found_entries = LogbookEntry.objects.filter(entry_query)
-
- return render_with_context(request,'logbooksearch.html',
- { 'query_string': query_string, 'found_entries': found_entries, })
- #context_instance=RequestContext(request))
-
-def personForm(request,pk):
- person=Person.objects.get(pk=pk)
- form=PersonForm(instance=person)
- return render_with_context(request,'personform.html', {'form':form,})
-
-
-def experimental(request):
- legsbyexpo = [ ]
- for expedition in Expedition.objects.all():
- survexblocks = expedition.survexblock_set.all()
- survexlegs = [ ]
- survexleglength = 0.0
- for survexblock in survexblocks:
- survexlegs.extend(survexblock.survexleg_set.all())
- survexleglength += survexblock.totalleglength
- legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength}))
- legsbyexpo.reverse()
-
- survexlegs = models.SurvexLeg.objects.all()
- totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs])
- return render_with_context(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
-
-@login_required_if_public
-def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None):
- expedition = Expedition.objects.get(year=expeditionyear)
- PersonTripFormSet, TripForm = getTripForm(expedition)
- if pslug and pdate:
- previousdate = datetime.date(*[int(x) for x in pdate.split("-")])
- previouslbe = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition)
- assert previouslbe.filename
- if request.method == 'POST': # If the form has been submitted...
- tripForm = TripForm(request.POST) # A form bound to the POST data
- personTripFormSet = PersonTripFormSet(request.POST)
- if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
- dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d")
- directory = os.path.join(settings.EXPOWEB,
- "years",
- expedition.year,
- "autologbook")
- filename = os.path.join(directory,
- dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html")
- if not os.path.isdir(directory):
- os.mkdir(directory)
- if pslug and pdate:
- delLogbookEntry(previouslbe)
- f = open(filename, "w")
- template = loader.get_template('dataformat/logbookentry.html')
- context = Context({'trip': tripForm.cleaned_data,
- 'persons': personTripFormSet.cleaned_data,
- 'date': dateStr,
- 'expeditionyear': expeditionyear})
- f.write(template.render(context))
- f.close()
- print logbookparsers.parseAutoLogBookEntry(filename)
- return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
- else:
- if pslug and pdate:
- if previouslbe.cave:
- tripForm = TripForm(initial={"date": previousdate,
- "title": previouslbe.title,
- "cave": previouslbe.cave.reference(),
- "location": None,
- "caveOrLocation": "cave",
- "html": previouslbe.text})
- else:
- tripForm = TripForm(initial={"date": previousdate,
- "title": previouslbe.title,
- "cave": None,
- "location": previouslbe.place,
- "caveOrLocation": "location",
- "html": previouslbe.text})
- personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition),
- "TU": py.time_underground,
- "author": py.is_logbook_entry_author}
- for py in previouslbe.persontrip_set.all()])
- else:
- tripForm = TripForm() # An unbound form
- personTripFormSet = PersonTripFormSet()
-
- return render_with_context(request, 'newlogbookentry.html', {
- 'tripForm': tripForm,
- 'personTripFormSet': personTripFormSet,
-
- })
-
-@login_required_if_public
-def deleteLogbookEntry(request, expeditionyear, date = None, slug = None):
- expedition = Expedition.objects.get(year=expeditionyear)
- previousdate = datetime.date(*[int(x) for x in date.split("-")])
- previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition)
- delLogbookEntry(previouslbe)
- return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
-
-def delLogbookEntry(lbe):
- for pt in lbe.persontrip_set.all():
- pt.delete()
- lbe.delete()
- os.remove(lbe.filename)
-
-def get_people(request, expeditionslug):
- exp = Expedition.objects.get(year = expeditionslug)
- return render_with_context(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]})
-
-def get_logbook_entries(request, expeditionslug):
- exp = Expedition.objects.get(year = expeditionslug)
- return render_with_context(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]})
-
+from django.shortcuts import render_to_response +from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, SurvexBlock +import troggle.core.models as models +import troggle.settings as settings +import django.db.models +from troggle.parsers.logbooks import LoadLogbookForExpedition +from troggle.parsers.people import GetPersonExpeditionNameLookup +#from troggle.core.forms import PersonForm, getTripForm, get_name +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect, HttpResponse +from django.template import Context, loader +from utils import render_with_context +import os.path +import troggle.parsers.logbooks as logbookparsers +from django.template.defaultfilters import slugify +from troggle.helper import login_required_if_public +import datetime + + +# Django uses Context, not RequestContext when you call render_to_response. We always want to use RequestContext, so that django adds the context from settings.TEMPLATE_CONTEXT_PROCESSORS. This way we automatically get necessary settings variables passed to each template. So we use a custom method, render_response instead of render_to_response. Hopefully future Django releases will make this unnecessary. +#from troggle.alwaysUseRequestContext import render_response + +import re + +@django.db.models.permalink #this allows the nice get_absolute_url syntax we are using + +def getNotablePersons(): + notablepersons = [] + for person in Person.objects.all(): + if person.bisnotable(): + notablepersons.append(person) + return notablepersons + + +def personindex(request): + persons = Person.objects.all() + # From what I can tell, "persons" seems to be the table rows, while "personss" is the table columns. - AC 16 Feb 09 + personss = [ ] + ncols = 4 + nc = (len(persons) + ncols - 1) / ncols + for i in range(ncols): + personss.append(persons[i * nc: (i + 1) * nc]) + + notablepersons = [] + for person in Person.objects.all(): + if person.bisnotable(): + notablepersons.append(person) + + return render_with_context(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, }) + + +def expedition(request, expeditionname): + expedition = Expedition.objects.get(year=int(expeditionname)) + expeditions = Expedition.objects.all() + personexpeditiondays = [ ] + dateditems = list(expedition.logbookentry_set.all()) + list(expedition.survexblock_set.all()) + dates = list(set([item.date for item in dateditems])) + dates.sort() + for personexpedition in expedition.personexpedition_set.all(): + prow = [ ] + for date in dates: + pcell = { "persontrips": PersonTrip.objects.filter(personexpedition=personexpedition, + logbook_entry__date=date) } + pcell["survexblocks"] = set(SurvexBlock.objects.filter(survexpersonrole__personexpedition=personexpedition, + date = date)) + prow.append(pcell) + personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow}) + + message = "" + if "reload" in request.GET: + message = LoadLogbookForExpedition(expedition) + return render_with_context(request,'expedition.html', {'expedition': expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'message':message, 'settings':settings, 'dateditems': dateditems }) + + def get_absolute_url(self): + return ('expedition', (expedition.year)) + + +def person(request, first_name='', last_name='', ): + person = Person.objects.get(first_name = first_name, last_name = last_name) + + #This is for removing the reference to the user's profile, in case they set it to the wrong person + if request.method == 'GET': + if request.GET.get('clear_profile')=='True': + person.user=None + person.save() + return HttpResponseRedirect(reverse('profiles_select_profile')) + + return render_with_context(request,'person.html', {'person': person, }) + + +def GetPersonChronology(personexpedition): + res = { } + for persontrip in personexpedition.persontrip_set.all(): + a = res.setdefault(persontrip.date, { }) + a.setdefault("persontrips", [ ]).append(persontrip) + + for personrole in personexpedition.survexpersonrole_set.all(): + a = res.setdefault(personrole.survexblock.date, { }) + a.setdefault("personroles", [ ]).append(personrole.survexblock) + + # build up the tables + rdates = res.keys() + rdates.sort() + + + res2 = [ ] + for rdate in rdates: + persontrips = res[rdate].get("persontrips", []) + personroles = res[rdate].get("personroles", []) + for n in range(max(len(persontrips), len(personroles))): + res2.append(((n == 0 and rdate or "--"), (n < len(persontrips) and persontrips[n]), (n < len(personroles) and personroles[n]))) + + return res2 + + +def personexpedition(request, first_name='', last_name='', year=''): + person = Person.objects.get(first_name = first_name, last_name = last_name) + expedition = Expedition.objects.get(year=year) + personexpedition = person.personexpedition_set.get(expedition=expedition) + personchronology = GetPersonChronology(personexpedition) + return render_with_context(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology}) + + +def logbookentry(request, date, slug): + logbookentry = LogbookEntry.objects.filter(date=date, slug=slug) + + if len(logbookentry)>1: + return render_with_context(request, 'object_list.html',{'object_list':logbookentry}) + else: + logbookentry=logbookentry[0] + return render_with_context(request, 'logbookentry.html', {'logbookentry': logbookentry}) + + +def logbookSearch(request, extra): + query_string = '' + found_entries = None + if ('q' in request.GET) and request.GET['q'].strip(): + query_string = request.GET['q'] + entry_query = search.get_query(query_string, ['text','title',]) + found_entries = LogbookEntry.objects.filter(entry_query) + + return render_with_context(request,'logbooksearch.html', + { 'query_string': query_string, 'found_entries': found_entries, }) + #context_instance=RequestContext(request)) + +def personForm(request,pk): + person=Person.objects.get(pk=pk) + form=PersonForm(instance=person) + return render_with_context(request,'personform.html', {'form':form,}) + + +def experimental(request): + legsbyexpo = [ ] + for expedition in Expedition.objects.all(): + survexblocks = expedition.survexblock_set.all() + survexlegs = [ ] + survexleglength = 0.0 + for survexblock in survexblocks: + survexlegs.extend(survexblock.survexleg_set.all()) + survexleglength += survexblock.totalleglength + legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength})) + legsbyexpo.reverse() + + survexlegs = models.SurvexLeg.objects.all() + totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs]) + return render_with_context(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo }) + +@login_required_if_public +def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None): + expedition = Expedition.objects.get(year=expeditionyear) + PersonTripFormSet, TripForm = getTripForm(expedition) + if pslug and pdate: + previousdate = datetime.date(*[int(x) for x in pdate.split("-")]) + previouslbe = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition) + assert previouslbe.filename + if request.method == 'POST': # If the form has been submitted... + tripForm = TripForm(request.POST) # A form bound to the POST data + personTripFormSet = PersonTripFormSet(request.POST) + if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass + dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d") + directory = os.path.join(settings.EXPOWEB, + "years", + expedition.year, + "autologbook") + filename = os.path.join(directory, + dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html") + if not os.path.isdir(directory): + os.mkdir(directory) + if pslug and pdate: + delLogbookEntry(previouslbe) + f = open(filename, "w") + template = loader.get_template('dataformat/logbookentry.html') + context = Context({'trip': tripForm.cleaned_data, + 'persons': personTripFormSet.cleaned_data, + 'date': dateStr, + 'expeditionyear': expeditionyear}) + f.write(template.render(context)) + f.close() + print logbookparsers.parseAutoLogBookEntry(filename) + return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST + else: + if pslug and pdate: + if previouslbe.cave: + tripForm = TripForm(initial={"date": previousdate, + "title": previouslbe.title, + "cave": previouslbe.cave.reference(), + "location": None, + "caveOrLocation": "cave", + "html": previouslbe.text}) + else: + tripForm = TripForm(initial={"date": previousdate, + "title": previouslbe.title, + "cave": None, + "location": previouslbe.place, + "caveOrLocation": "location", + "html": previouslbe.text}) + personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition), + "TU": py.time_underground, + "author": py.is_logbook_entry_author} + for py in previouslbe.persontrip_set.all()]) + else: + tripForm = TripForm() # An unbound form + personTripFormSet = PersonTripFormSet() + + return render_with_context(request, 'newlogbookentry.html', { + 'tripForm': tripForm, + 'personTripFormSet': personTripFormSet, + + }) + +@login_required_if_public +def deleteLogbookEntry(request, expeditionyear, date = None, slug = None): + expedition = Expedition.objects.get(year=expeditionyear) + previousdate = datetime.date(*[int(x) for x in date.split("-")]) + previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition) + delLogbookEntry(previouslbe) + return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST + +def delLogbookEntry(lbe): + for pt in lbe.persontrip_set.all(): + pt.delete() + lbe.delete() + os.remove(lbe.filename) + +def get_people(request, expeditionslug): + exp = Expedition.objects.get(year = expeditionslug) + return render_with_context(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]}) + +def get_logbook_entries(request, expeditionslug): + exp = Expedition.objects.get(year = expeditionslug) + return render_with_context(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]}) + diff --git a/core/views_other.py b/core/views_other.py index d840a30..beecc46 100644 --- a/core/views_other.py +++ b/core/views_other.py @@ -1,282 +1,282 @@ -from troggle.core.models import Cave, Expedition, Person, LogbookEntry, PersonExpedition, PersonTrip, DPhoto, QM
-from troggle.core.forms import UploadFileForm
-from django.conf import settings
-from django import forms
-from django.template import loader, Context
-from django.db.models import Q
-import databaseReset
-import re
-from django.http import HttpResponse, HttpResponseRedirect
-from django.core.urlresolvers import reverse
-from utils import render_with_context
-from core.models import *
-from troggle.helper import login_required_if_public
-
-def showrequest(request):
- return HttpResponse(request.GET)
-
-def stats(request):
- statsDict={}
- statsDict['expoCount'] = int(Expedition.objects.count())
- statsDict['caveCount'] = int(Cave.objects.count())
- statsDict['personCount'] = int(Person.objects.count())
- statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count())
- return render_with_context(request,'statistics.html', statsDict)
-
-def frontpage(request):
- if request.user.is_authenticated():
- return render_with_context(request,'tasks.html')
-
- expeditions = Expedition.objects.order_by("-year")
- logbookentry = LogbookEntry
- cave = Cave
- photo = DPhoto
- from django.contrib.admin.templatetags import log
- return render_with_context(request,'frontpage.html', locals())
-
-def todo(request):
- message = "no test message" #reverse('personn', kwargs={"name":"hkjhjh"})
- if "reloadexpos" in request.GET:
- message = LoadPersonsExpos()
- message = "Reloaded personexpos"
- if "reloadsurvex" in request.POST:
- message = LoadAllSurvexBlocks()
- message = "Reloaded survexblocks"
-
- expeditions = Expedition.objects.order_by("-year")
- totallogbookentries = LogbookEntry.objects.count()
- return render_with_context(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message})
-
-
-def controlPanel(request):
- jobs_completed=[]
- if request.method=='POST':
- if request.user.is_superuser:
-
- #importlist is mostly here so that things happen in the correct order.
- #http post data seems to come in an unpredictable order, so we do it this way.
- importlist=['reload_db', 'import_people', 'import_cavetab', 'import_logbooks', 'import_surveys', 'import_QMs']
- databaseReset.make_dirs()
- for item in importlist:
- if item in request.POST:
- print "running"+ " databaseReset."+item+"()"
- exec "databaseReset."+item+"()"
- jobs_completed.append(item)
- else:
- if request.user.is_authenticated(): #The user is logged in, but is not a superuser.
- return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'error':'You must be a superuser to use that feature.'})
- else:
- return HttpResponseRedirect(reverse('auth_login'))
-
- return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'expeditions':Expedition.objects.all(),'jobs_completed':jobs_completed})
-
-def downloadCavetab(request):
- from export import tocavetab
- response = HttpResponse(mimetype='text/csv')
- response['Content-Disposition'] = 'attachment; filename=CAVETAB2.CSV'
- tocavetab.writeCaveTab(response)
- return response
-
-def downloadSurveys(request):
- from export import tosurveys
- response = HttpResponse(mimetype='text/csv')
- response['Content-Disposition'] = 'attachment; filename=Surveys.csv'
- tosurveys.writeCaveTab(response)
- return response
-
-def downloadLogbook(request,year=None,extension=None,queryset=None):
-
- if year:
- expedition=Expedition.objects.get(year=year)
- logbook_entries=LogbookEntry.objects.filter(expedition=expedition)
- filename='logbook'+year
- elif queryset:
- logbook_entries=queryset
- filename='logbook'
- else:
- return response(r"Error: Logbook downloader doesn't know what year you want")
-
- if 'year' in request.GET:
- year=request.GET['year']
- if 'extension' in request.GET:
- extension=request.GET['extension']
-
-
-
- if extension =='txt':
- response = HttpResponse(mimetype='text/plain')
- style='2008'
- elif extension == 'html':
- response = HttpResponse(mimetype='text/html')
- style='2005'
-
- template='logbook'+style+'style.'+extension
- response['Content-Disposition'] = 'attachment; filename='+filename+'.'+extension
- t=loader.get_template(template)
- c=Context({'logbook_entries':logbook_entries})
- response.write(t.render(c))
- return response
-
-
-def downloadQMs(request):
- # Note to self: use get_cave method for the below
- if request.method=='GET':
- try:
- cave=Cave.objects.get(kataster_number=request.GET['cave_id'])
- except Cave.DoesNotExist:
- cave=Cave.objects.get(name=cave_id)
-
- from export import toqms
-
- response = HttpResponse(mimetype='text/csv')
- response['Content-Disposition'] = 'attachment; filename=qm.csv'
- toqms.writeQmTable(response,cave)
- return response
-
-def ajax_test(request):
- post_text = request.POST['post_data']
- return HttpResponse("{'response_text': '"+post_text+" recieved.'}",
- mimetype="application/json")
-
-def eyecandy(request):
- return
-
-def ajax_QM_number(request):
- if request.method=='POST':
- cave=Cave.objects.get(id=request.POST['cave'])
- print cave
- exp=Expedition.objects.get(pk=request.POST['year'])
- print exp
- res=cave.new_QM_number(exp.year)
-
- return HttpResponse(res)
-
-def logbook_entry_suggestions(request):
- """
- Generates a html box with suggestions about what to do with QMs
- in logbook entry text.
- """
- unwiki_QM_pattern=r"(?P<whole>(?P<explorer_code>[ABC]?)(?P<cave>\d*)-?(?P<year>\d\d\d?\d?)-(?P<number>\d\d)(?P<grade>[ABCDXV]?))"
- unwiki_QM_pattern=re.compile(unwiki_QM_pattern)
- #wikilink_QM_pattern=settings.QM_PATTERN
-
- slug=request.POST['slug']
- date=request.POST['date']
- lbo=LogbookEntry.objects.get(slug=slug, date=date)
-
- #unwiki_QMs=re.findall(unwiki_QM_pattern,lbo.text)
- unwiki_QMs=[m.groupdict() for m in unwiki_QM_pattern.finditer(lbo.text)]
-
- print unwiki_QMs
- for qm in unwiki_QMs:
- #try:
- if len(qm['year'])==2:
- if int(qm['year'])<50:
- qm['year']='20'+qm['year']
- else:
- qm['year']='19'+qm['year']
-
- if lbo.date.year!=int(qm['year']):
- try:
- lbo=LogbookEntry.objects.get(date__year=qm['year'],title__icontains="placeholder for QMs in")
- except:
- print "failed to get placeholder for year "+str(qm['year'])
-
- temp_QM=QM(found_by=lbo,number=qm['number'],grade=qm['grade'])
- temp_QM.grade=qm['grade']
- qm['wikilink']=temp_QM.wiki_link()
- #except:
- #print 'failed'
-
- print unwiki_QMs
-
-
- #wikilink_QMs=re.findall(wikilink_QM_pattern,lbo.text)
- attached_QMs=lbo.QMs_found.all()
- unmentioned_attached_QMs=''#not implemented, fill this in by subtracting wiklink_QMs from attached_QMs
-
- #Find unattached_QMs. We only look at the QMs with a proper wiki link.
- #for qm in wikilink_QMs:
- #Try to look up the QM.
-
- print 'got 208'
- any_suggestions=True
- print 'got 210'
- return render_with_context(request,'suggestions.html',
- {
- 'unwiki_QMs':unwiki_QMs,
- 'any_suggestions':any_suggestions
- })
-
-@login_required_if_public
-def newFile(request, pslug = None):
-# if pslug:
-# previousfile = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition)
-# assert previousfile.filename
- if request.method == 'POST': # If the form has been submitted...
- tripForm = TripForm(request.POST) # A form bound to the POST data
-# personTripFormSet = PersonTripFormSet(request.POST)
-# if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
-# dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d")
-# directory = os.path.join(settings.EXPOWEB,
-# "years",
-# expedition.year,
-# "autologbook")
-# filename = os.path.join(directory,
-# dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html")
-# if not os.path.isdir(directory):
-# os.mkdir(directory)
-# if pslug and pdate:
-# delLogbookEntry(previouslbe)
-# f = open(filename, "w")
-# template = loader.get_template('dataformat/logbookentry.html')
-# context = Context({'trip': tripForm.cleaned_data,
-# 'persons': personTripFormSet.cleaned_data,
-# 'date': dateStr,
-# 'expeditionyear': expeditionyear})
-# f.write(template.render(context))
-# f.close()
-# print logbookparsers.parseAutoLogBookEntry(filename)
-# return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
- else:
- if pslug:
- pass
-# if previouslbe.cave:
-# tripForm = TripForm(initial={"date": previousdate,
-# "title": previouslbe.title,
-# "cave": previouslbe.cave.reference(),
-# "location": None,
-# "caveOrLocation": "cave",
-# "html": previouslbe.text})
-# else:
-# tripForm = TripForm(initial={"date": previousdate,
-# "title": previouslbe.title,
-# "cave": None,
-# "location": previouslbe.place,
-# "caveOrLocation": "location",
-# "html": previouslbe.text})
-# personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition),
-# "TU": py.time_underground,
-# "author": py.is_logbook_entry_author}
-# for py in previouslbe.persontrip_set.all()])
- else:
- fileform = UploadFileForm() # An unbound form
-
- return render_with_context(request, 'editfile.html', {
- 'fileForm': fileform,
-
- })
-
-@login_required_if_public
-def deleteFile(request, expeditionyear, date = None, slug = None):
- expedition = Expedition.objects.get(year=expeditionyear)
- previousdate = datetime.date(*[int(x) for x in date.split("-")])
- previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition)
- delLogbookEntry(previouslbe)
- return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
-
-def delFile(f):
- for pt in lbe.persontrip_set.all():
- pt.delete()
- lbe.delete()
- os.remove(lbe.filename)
+from troggle.core.models import Cave, Expedition, Person, LogbookEntry, PersonExpedition, PersonTrip, DPhoto, QM +from troggle.core.forms import UploadFileForm +from django.conf import settings +from django import forms +from django.template import loader, Context +from django.db.models import Q +import databaseReset +import re +from django.http import HttpResponse, HttpResponseRedirect +from django.core.urlresolvers import reverse +from utils import render_with_context +from core.models import * +from troggle.helper import login_required_if_public + +def showrequest(request): + return HttpResponse(request.GET) + +def stats(request): + statsDict={} + statsDict['expoCount'] = int(Expedition.objects.count()) + statsDict['caveCount'] = int(Cave.objects.count()) + statsDict['personCount'] = int(Person.objects.count()) + statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count()) + return render_with_context(request,'statistics.html', statsDict) + +def frontpage(request): + if request.user.is_authenticated(): + return render_with_context(request,'tasks.html') + + expeditions = Expedition.objects.order_by("-year") + logbookentry = LogbookEntry + cave = Cave + photo = DPhoto + from django.contrib.admin.templatetags import log + return render_with_context(request,'frontpage.html', locals()) + +def todo(request): + message = "no test message" #reverse('personn', kwargs={"name":"hkjhjh"}) + if "reloadexpos" in request.GET: + message = LoadPersonsExpos() + message = "Reloaded personexpos" + if "reloadsurvex" in request.POST: + message = LoadAllSurvexBlocks() + message = "Reloaded survexblocks" + + expeditions = Expedition.objects.order_by("-year") + totallogbookentries = LogbookEntry.objects.count() + return render_with_context(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message}) + + +def controlPanel(request): + jobs_completed=[] + if request.method=='POST': + if request.user.is_superuser: + + #importlist is mostly here so that things happen in the correct order. + #http post data seems to come in an unpredictable order, so we do it this way. + importlist=['reload_db', 'import_people', 'import_cavetab', 'import_logbooks', 'import_surveys', 'import_QMs'] + databaseReset.make_dirs() + for item in importlist: + if item in request.POST: + print "running"+ " databaseReset."+item+"()" + exec "databaseReset."+item+"()" + jobs_completed.append(item) + else: + if request.user.is_authenticated(): #The user is logged in, but is not a superuser. + return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'error':'You must be a superuser to use that feature.'}) + else: + return HttpResponseRedirect(reverse('auth_login')) + + return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'expeditions':Expedition.objects.all(),'jobs_completed':jobs_completed}) + +def downloadCavetab(request): + from export import tocavetab + response = HttpResponse(mimetype='text/csv') + response['Content-Disposition'] = 'attachment; filename=CAVETAB2.CSV' + tocavetab.writeCaveTab(response) + return response + +def downloadSurveys(request): + from export import tosurveys + response = HttpResponse(mimetype='text/csv') + response['Content-Disposition'] = 'attachment; filename=Surveys.csv' + tosurveys.writeCaveTab(response) + return response + +def downloadLogbook(request,year=None,extension=None,queryset=None): + + if year: + expedition=Expedition.objects.get(year=year) + logbook_entries=LogbookEntry.objects.filter(expedition=expedition) + filename='logbook'+year + elif queryset: + logbook_entries=queryset + filename='logbook' + else: + return response(r"Error: Logbook downloader doesn't know what year you want") + + if 'year' in request.GET: + year=request.GET['year'] + if 'extension' in request.GET: + extension=request.GET['extension'] + + + + if extension =='txt': + response = HttpResponse(mimetype='text/plain') + style='2008' + elif extension == 'html': + response = HttpResponse(mimetype='text/html') + style='2005' + + template='logbook'+style+'style.'+extension + response['Content-Disposition'] = 'attachment; filename='+filename+'.'+extension + t=loader.get_template(template) + c=Context({'logbook_entries':logbook_entries}) + response.write(t.render(c)) + return response + + +def downloadQMs(request): + # Note to self: use get_cave method for the below + if request.method=='GET': + try: + cave=Cave.objects.get(kataster_number=request.GET['cave_id']) + except Cave.DoesNotExist: + cave=Cave.objects.get(name=cave_id) + + from export import toqms + + response = HttpResponse(mimetype='text/csv') + response['Content-Disposition'] = 'attachment; filename=qm.csv' + toqms.writeQmTable(response,cave) + return response + +def ajax_test(request): + post_text = request.POST['post_data'] + return HttpResponse("{'response_text': '"+post_text+" recieved.'}", + mimetype="application/json") + +def eyecandy(request): + return + +def ajax_QM_number(request): + if request.method=='POST': + cave=Cave.objects.get(id=request.POST['cave']) + print cave + exp=Expedition.objects.get(pk=request.POST['year']) + print exp + res=cave.new_QM_number(exp.year) + + return HttpResponse(res) + +def logbook_entry_suggestions(request): + """ + Generates a html box with suggestions about what to do with QMs + in logbook entry text. + """ + unwiki_QM_pattern=r"(?P<whole>(?P<explorer_code>[ABC]?)(?P<cave>\d*)-?(?P<year>\d\d\d?\d?)-(?P<number>\d\d)(?P<grade>[ABCDXV]?))" + unwiki_QM_pattern=re.compile(unwiki_QM_pattern) + #wikilink_QM_pattern=settings.QM_PATTERN + + slug=request.POST['slug'] + date=request.POST['date'] + lbo=LogbookEntry.objects.get(slug=slug, date=date) + + #unwiki_QMs=re.findall(unwiki_QM_pattern,lbo.text) + unwiki_QMs=[m.groupdict() for m in unwiki_QM_pattern.finditer(lbo.text)] + + print unwiki_QMs + for qm in unwiki_QMs: + #try: + if len(qm['year'])==2: + if int(qm['year'])<50: + qm['year']='20'+qm['year'] + else: + qm['year']='19'+qm['year'] + + if lbo.date.year!=int(qm['year']): + try: + lbo=LogbookEntry.objects.get(date__year=qm['year'],title__icontains="placeholder for QMs in") + except: + print "failed to get placeholder for year "+str(qm['year']) + + temp_QM=QM(found_by=lbo,number=qm['number'],grade=qm['grade']) + temp_QM.grade=qm['grade'] + qm['wikilink']=temp_QM.wiki_link() + #except: + #print 'failed' + + print unwiki_QMs + + + #wikilink_QMs=re.findall(wikilink_QM_pattern,lbo.text) + attached_QMs=lbo.QMs_found.all() + unmentioned_attached_QMs=''#not implemented, fill this in by subtracting wiklink_QMs from attached_QMs + + #Find unattached_QMs. We only look at the QMs with a proper wiki link. + #for qm in wikilink_QMs: + #Try to look up the QM. + + print 'got 208' + any_suggestions=True + print 'got 210' + return render_with_context(request,'suggestions.html', + { + 'unwiki_QMs':unwiki_QMs, + 'any_suggestions':any_suggestions + }) + +@login_required_if_public +def newFile(request, pslug = None): +# if pslug: +# previousfile = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition) +# assert previousfile.filename + if request.method == 'POST': # If the form has been submitted... + tripForm = TripForm(request.POST) # A form bound to the POST data +# personTripFormSet = PersonTripFormSet(request.POST) +# if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass +# dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d") +# directory = os.path.join(settings.EXPOWEB, +# "years", +# expedition.year, +# "autologbook") +# filename = os.path.join(directory, +# dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html") +# if not os.path.isdir(directory): +# os.mkdir(directory) +# if pslug and pdate: +# delLogbookEntry(previouslbe) +# f = open(filename, "w") +# template = loader.get_template('dataformat/logbookentry.html') +# context = Context({'trip': tripForm.cleaned_data, +# 'persons': personTripFormSet.cleaned_data, +# 'date': dateStr, +# 'expeditionyear': expeditionyear}) +# f.write(template.render(context)) +# f.close() +# print logbookparsers.parseAutoLogBookEntry(filename) +# return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST + else: + if pslug: + pass +# if previouslbe.cave: +# tripForm = TripForm(initial={"date": previousdate, +# "title": previouslbe.title, +# "cave": previouslbe.cave.reference(), +# "location": None, +# "caveOrLocation": "cave", +# "html": previouslbe.text}) +# else: +# tripForm = TripForm(initial={"date": previousdate, +# "title": previouslbe.title, +# "cave": None, +# "location": previouslbe.place, +# "caveOrLocation": "location", +# "html": previouslbe.text}) +# personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition), +# "TU": py.time_underground, +# "author": py.is_logbook_entry_author} +# for py in previouslbe.persontrip_set.all()]) + else: + fileform = UploadFileForm() # An unbound form + + return render_with_context(request, 'editfile.html', { + 'fileForm': fileform, + + }) + +@login_required_if_public +def deleteFile(request, expeditionyear, date = None, slug = None): + expedition = Expedition.objects.get(year=expeditionyear) + previousdate = datetime.date(*[int(x) for x in date.split("-")]) + previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition) + delLogbookEntry(previouslbe) + return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST + +def delFile(f): + for pt in lbe.persontrip_set.all(): + pt.delete() + lbe.delete() + os.remove(lbe.filename) diff --git a/core/views_survex.py b/core/views_survex.py index b6b5aba..8e7ac1e 100644 --- a/core/views_survex.py +++ b/core/views_survex.py @@ -1,318 +1,318 @@ -from django import forms
-from django.http import HttpResponseRedirect, HttpResponse
-from django.shortcuts import render_to_response
-from django.http import HttpResponse, Http404
-import re
-import os
-import datetime
-import difflib
-
-from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, Cave
-from troggle.core.models import SurvexBlock, SurvexPersonRole, SurvexFile, SurvexDirectory, SurvexTitle
-from parsers.people import GetPersonExpeditionNameLookup
-
-import troggle.settings as settings
-import parsers.survex
-
-survextemplatefile = """; Locn: Totes Gebirge, Austria - Loser/Augst-Eck Plateau (kataster group 1623)
-; Cave:
-
-*begin [surveyname]
-
-*export [connecting stations]
-
-*title "area title"
-*date 2999.99.99
-*team Insts [Caver]
-*team Insts [Caver]
-*team Notes [Caver]
-*instrument [set number]
-
-;ref.: 2009#NN
-
-*calibrate tape +0.0 ; +ve if tape was too short, -ve if too long
-
-*data normal from to tape compass clino
-1 2 3.90 298 -20
-
-*data passage station left right up down ignoreall
-1 [L] [R] [U] [D] comment
-
-*end [surveyname]"""
-
-
-def ReplaceTabs(stext):
- res = [ ]
- nsl = 0
- for s in re.split("(\t|\n)", stext):
- if s == "\t":
- res.append(" " * (4 - (nsl % 4)))
- nsl = 0
- continue
- if s == "\n":
- nsl = 0
- else:
- nsl += len(s)
- res.append(s)
- return "".join(res)
-
-
-class SvxForm(forms.Form):
- dirname = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
- filename = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
- datetime = forms.DateTimeField(widget=forms.TextInput(attrs={"readonly":True}))
- outputtype = forms.CharField(widget=forms.TextInput(attrs={"readonly":True}))
- code = forms.CharField(widget=forms.Textarea(attrs={"cols":150, "rows":18}))
-
- def GetDiscCode(self):
- fname = settings.SURVEX_DATA + self.data['filename'] + ".svx"
- if not os.path.isfile(fname):
- return survextemplatefile
- fin = open(fname, "rb")
- svxtext = fin.read().decode("latin1") # unicode(a, "latin1")
- svxtext = ReplaceTabs(svxtext).strip()
- fin.close()
- return svxtext
-
- def DiffCode(self, rcode):
- code = self.GetDiscCode()
- difftext = difflib.unified_diff(code.splitlines(), rcode.splitlines())
- difflist = [ diffline.strip() for diffline in difftext if not re.match("\s*$", diffline) ]
- return difflist
-
- def SaveCode(self, rcode):
- fname = settings.SURVEX_DATA + self.data['filename'] + ".svx"
- if not os.path.isfile(fname):
- # only save if appears valid
- if re.search("\[|\]", rcode):
- return "Error: clean up all []s from the text"
- mbeginend = re.search("(?s)\*begin\s+(\w+).*?\*end\s+(\w+)", rcode)
- if not mbeginend:
- return "Error: no begin/end block here"
- if mbeginend.group(1) != mbeginend.group(2):
- return "Error: mismatching beginend"
-
- fout = open(fname, "w")
- res = fout.write(rcode.encode("latin1"))
- fout.close()
- return "SAVED"
-
- def Process(self):
- print "....\n\n\n....Processing\n\n\n"
- cwd = os.getcwd()
- os.chdir(os.path.split(settings.SURVEX_DATA + self.data['filename'])[0])
- os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + self.data['filename'] + ".svx")
- os.chdir(cwd)
- fin = open(settings.SURVEX_DATA + self.data['filename'] + ".log", "rb")
- log = fin.read()
- fin.close()
- log = re.sub("(?s).*?(Survey contains)", "\\1", log)
- return log
-
-
-def svx(request, survex_file):
- # get the basic data from the file given in the URL
- dirname = os.path.split(survex_file)[0]
- dirname += "/"
- nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- outputtype = "normal"
- form = SvxForm({'filename':survex_file, 'dirname':dirname, 'datetime':nowtime, 'outputtype':outputtype})
-
- # if the form has been returned
- difflist = [ ]
- logmessage = ""
- message = ""
-
- if request.method == 'POST': # If the form has been submitted...
- rform = SvxForm(request.POST) #
- if rform.is_valid(): # All validation rules pass (how do we check it against the filename and users?)
- rcode = rform.cleaned_data['code']
- outputtype = rform.cleaned_data['outputtype']
- difflist = form.DiffCode(rcode)
- #print "ssss", rform.data
-
- if "revert" in rform.data:
- pass
- if "process" in rform.data:
- if not difflist:
- message = "OUTPUT FROM PROCESSING"
- logmessage = form.Process()
- print logmessage
- else:
- message = "SAVE FILE FIRST"
- form.data['code'] = rcode
- if "save" in rform.data:
- if request.user.is_authenticated():
- #print "sssavvving"
- message = form.SaveCode(rcode)
- else:
- message = "You do not have authority to save this file"
- if message != "SAVED":
- form.data['code'] = rcode
- if "diff" in rform.data:
- form.data['code'] = rcode
-
-
- #process(survex_file)
- if 'code' not in form.data:
- form.data['code'] = form.GetDiscCode()
-
- if not difflist:
- difflist.append("none")
- if message:
- difflist.insert(0, message)
-
- #print [ form.data['code'] ]
- svxincludes = re.findall('\*include\s+(\S+)(?i)', form.data['code'] or "")
-
- vmap = {'settings': settings,
- 'has_3d': os.path.isfile(settings.SURVEX_DATA + survex_file + ".3d"),
- 'title': survex_file,
- 'svxincludes': svxincludes,
- 'difflist': difflist,
- 'logmessage':logmessage,
- 'form':form}
- if outputtype == "ajax":
- return render_to_response('svxfiledifflistonly.html', vmap)
- return render_to_response('svxfile.html', vmap)
-
-def svxraw(request, survex_file):
- svx = open(os.path.join(settings.SURVEX_DATA, survex_file+".svx"), "rb")
- return HttpResponse(svx, mimetype="text")
-
-
-# The cavern running function
-def process(survex_file):
- cwd = os.getcwd()
- os.chdir(os.path.split(settings.SURVEX_DATA + survex_file)[0])
- os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + survex_file + ".svx")
- os.chdir(cwd)
-
-
-def threed(request, survex_file):
- process(survex_file)
- try:
- threed = open(settings.SURVEX_DATA + survex_file + ".3d", "rb")
- return HttpResponse(threed, mimetype="model/3d")
- except:
- log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
- return HttpResponse(log, mimetype="text")
-
-def log(request, survex_file):
- process(survex_file)
- log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
- return HttpResponse(log, mimetype="text")
-
-def err(request, survex_file):
- process(survex_file)
- err = open(settings.SURVEX_DATA + survex_file + ".err", "rb")
- return HttpResponse(err, mimetype="text")
-
-
-
-def identifycavedircontents(gcavedir):
- name = os.path.split(gcavedir)[1]
- subdirs = [ ]
- subsvx = [ ]
- primesvx = None
- for f in os.listdir(gcavedir):
- if name == "204" and (f in ["skel.svx", "template.svx", "204withents.svx"]):
- pass
- elif name == "136" and (f in ["136-noents.svx"]):
- pass
- elif name == "115" and (f in ["115cufix.svx", "115fix.svx"]):
- pass
-
- elif os.path.isdir(os.path.join(gcavedir, f)):
- if f[0] != ".":
- subdirs.append(f)
- elif f[-4:] == ".svx":
- nf = f[:-4]
-
- if nf.lower() == name.lower() or nf[:3] == "all" or (name, nf) in [("144arge", "144"), ("resurvey2005", "145-2005"), ("cucc", "cu115")]:
- if primesvx:
- if nf[:3] == "all":
- assert primesvx[:3] != "all", (name, nf, primesvx, gcavedir, subsvx)
- primesvx = nf
- else:
- assert primesvx[:3] == "all", (name, nf, primesvx, gcavedir, subsvx)
- else:
- primesvx = nf
- else:
- subsvx.append(nf)
- else:
- assert re.match(".*?(?:.3d|.log|.err|.txt|.tmp|.diff|.e?spec|~)$", f), (gcavedir, f)
- subsvx.sort()
- assert primesvx, (gcavedir, subsvx)
- if primesvx:
- subsvx.insert(0, primesvx)
- return subdirs, subsvx
-
-
-
-# direct local non-database browsing through the svx file repositories
-# perhaps should use the database and have a reload button for it
-def survexcaveslist(request):
- cavesdir = os.path.join(settings.SURVEX_DATA, "caves")
- cavesdircontents = { }
-
- onefilecaves = [ ]
- multifilecaves = [ ]
- subdircaves = [ ]
-
- # first sort the file list
- fnumlist = [ (-int(re.match("\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir) ]
- fnumlist.sort()
-
- # go through the list and identify the contents of each cave directory
- for num, cavedir in fnumlist:
- if cavedir in ["144", "40"]:
- continue
-
- gcavedir = os.path.join(cavesdir, cavedir)
- if os.path.isdir(gcavedir) and cavedir[0] != ".":
- subdirs, subsvx = identifycavedircontents(gcavedir)
- survdirobj = [ ]
-
- for lsubsvx in subsvx:
- survdirobj.append(("caves/"+cavedir+"/"+lsubsvx, lsubsvx))
-
- # caves with subdirectories
- if subdirs:
- subsurvdirs = [ ]
- for subdir in subdirs:
- dsubdirs, dsubsvx = identifycavedircontents(os.path.join(gcavedir, subdir))
- assert not dsubdirs
- lsurvdirobj = [ ]
- for lsubsvx in dsubsvx:
- lsurvdirobj.append(("caves/"+cavedir+"/"+subdir+"/"+lsubsvx, lsubsvx))
- subsurvdirs.append((lsurvdirobj[0], lsurvdirobj[1:]))
- subdircaves.append((cavedir, (survdirobj[0], survdirobj[1:]), subsurvdirs))
-
- # multifile caves
- elif len(survdirobj) > 1:
- multifilecaves.append((survdirobj[0], survdirobj[1:]))
- # single file caves
- else:
- onefilecaves.append(survdirobj[0])
-
- return render_to_response('svxfilecavelist.html', {'settings': settings, "onefilecaves":onefilecaves, "multifilecaves":multifilecaves, "subdircaves":subdircaves })
-
-
-
-
-
-
-# parsing all the survex files of a single cave and showing that it's consistent and can find all the files and people
-# doesn't use recursion. just writes it twice
-def survexcavesingle(request, survex_cave):
- breload = False
- cave = Cave.objects.get(kataster_number=survex_cave)
- if breload:
- parsers.survex.ReloadSurvexCave(survex_cave)
- return render_to_response('svxcavesingle.html', {'settings': settings, "cave":cave })
-
-
-
-
+from django import forms +from django.http import HttpResponseRedirect, HttpResponse +from django.shortcuts import render_to_response +from django.http import HttpResponse, Http404 +import re +import os +import datetime +import difflib + +from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, Cave +from troggle.core.models import SurvexBlock, SurvexPersonRole, SurvexFile, SurvexDirectory, SurvexTitle +from parsers.people import GetPersonExpeditionNameLookup + +import troggle.settings as settings +import parsers.survex + +survextemplatefile = """; Locn: Totes Gebirge, Austria - Loser/Augst-Eck Plateau (kataster group 1623) +; Cave: + +*begin [surveyname] + +*export [connecting stations] + +*title "area title" +*date 2999.99.99 +*team Insts [Caver] +*team Insts [Caver] +*team Notes [Caver] +*instrument [set number] + +;ref.: 2009#NN + +*calibrate tape +0.0 ; +ve if tape was too short, -ve if too long + +*data normal from to tape compass clino +1 2 3.90 298 -20 + +*data passage station left right up down ignoreall +1 [L] [R] [U] [D] comment + +*end [surveyname]""" + + +def ReplaceTabs(stext): + res = [ ] + nsl = 0 + for s in re.split("(\t|\n)", stext): + if s == "\t": + res.append(" " * (4 - (nsl % 4))) + nsl = 0 + continue + if s == "\n": + nsl = 0 + else: + nsl += len(s) + res.append(s) + return "".join(res) + + +class SvxForm(forms.Form): + dirname = forms.CharField(widget=forms.TextInput(attrs={"readonly":True})) + filename = forms.CharField(widget=forms.TextInput(attrs={"readonly":True})) + datetime = forms.DateTimeField(widget=forms.TextInput(attrs={"readonly":True})) + outputtype = forms.CharField(widget=forms.TextInput(attrs={"readonly":True})) + code = forms.CharField(widget=forms.Textarea(attrs={"cols":150, "rows":18})) + + def GetDiscCode(self): + fname = settings.SURVEX_DATA + self.data['filename'] + ".svx" + if not os.path.isfile(fname): + return survextemplatefile + fin = open(fname, "rb") + svxtext = fin.read().decode("latin1") # unicode(a, "latin1") + svxtext = ReplaceTabs(svxtext).strip() + fin.close() + return svxtext + + def DiffCode(self, rcode): + code = self.GetDiscCode() + difftext = difflib.unified_diff(code.splitlines(), rcode.splitlines()) + difflist = [ diffline.strip() for diffline in difftext if not re.match("\s*$", diffline) ] + return difflist + + def SaveCode(self, rcode): + fname = settings.SURVEX_DATA + self.data['filename'] + ".svx" + if not os.path.isfile(fname): + # only save if appears valid + if re.search("\[|\]", rcode): + return "Error: clean up all []s from the text" + mbeginend = re.search("(?s)\*begin\s+(\w+).*?\*end\s+(\w+)", rcode) + if not mbeginend: + return "Error: no begin/end block here" + if mbeginend.group(1) != mbeginend.group(2): + return "Error: mismatching beginend" + + fout = open(fname, "w") + res = fout.write(rcode.encode("latin1")) + fout.close() + return "SAVED" + + def Process(self): + print "....\n\n\n....Processing\n\n\n" + cwd = os.getcwd() + os.chdir(os.path.split(settings.SURVEX_DATA + self.data['filename'])[0]) + os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + self.data['filename'] + ".svx") + os.chdir(cwd) + fin = open(settings.SURVEX_DATA + self.data['filename'] + ".log", "rb") + log = fin.read() + fin.close() + log = re.sub("(?s).*?(Survey contains)", "\\1", log) + return log + + +def svx(request, survex_file): + # get the basic data from the file given in the URL + dirname = os.path.split(survex_file)[0] + dirname += "/" + nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + outputtype = "normal" + form = SvxForm({'filename':survex_file, 'dirname':dirname, 'datetime':nowtime, 'outputtype':outputtype}) + + # if the form has been returned + difflist = [ ] + logmessage = "" + message = "" + + if request.method == 'POST': # If the form has been submitted... + rform = SvxForm(request.POST) # + if rform.is_valid(): # All validation rules pass (how do we check it against the filename and users?) + rcode = rform.cleaned_data['code'] + outputtype = rform.cleaned_data['outputtype'] + difflist = form.DiffCode(rcode) + #print "ssss", rform.data + + if "revert" in rform.data: + pass + if "process" in rform.data: + if not difflist: + message = "OUTPUT FROM PROCESSING" + logmessage = form.Process() + print logmessage + else: + message = "SAVE FILE FIRST" + form.data['code'] = rcode + if "save" in rform.data: + if request.user.is_authenticated(): + #print "sssavvving" + message = form.SaveCode(rcode) + else: + message = "You do not have authority to save this file" + if message != "SAVED": + form.data['code'] = rcode + if "diff" in rform.data: + form.data['code'] = rcode + + + #process(survex_file) + if 'code' not in form.data: + form.data['code'] = form.GetDiscCode() + + if not difflist: + difflist.append("none") + if message: + difflist.insert(0, message) + + #print [ form.data['code'] ] + svxincludes = re.findall('\*include\s+(\S+)(?i)', form.data['code'] or "") + + vmap = {'settings': settings, + 'has_3d': os.path.isfile(settings.SURVEX_DATA + survex_file + ".3d"), + 'title': survex_file, + 'svxincludes': svxincludes, + 'difflist': difflist, + 'logmessage':logmessage, + 'form':form} + if outputtype == "ajax": + return render_to_response('svxfiledifflistonly.html', vmap) + return render_to_response('svxfile.html', vmap) + +def svxraw(request, survex_file): + svx = open(os.path.join(settings.SURVEX_DATA, survex_file+".svx"), "rb") + return HttpResponse(svx, mimetype="text") + + +# The cavern running function +def process(survex_file): + cwd = os.getcwd() + os.chdir(os.path.split(settings.SURVEX_DATA + survex_file)[0]) + os.system(settings.CAVERN + " --log " + settings.SURVEX_DATA + survex_file + ".svx") + os.chdir(cwd) + + +def threed(request, survex_file): + process(survex_file) + try: + threed = open(settings.SURVEX_DATA + survex_file + ".3d", "rb") + return HttpResponse(threed, mimetype="model/3d") + except: + log = open(settings.SURVEX_DATA + survex_file + ".log", "rb") + return HttpResponse(log, mimetype="text") + +def log(request, survex_file): + process(survex_file) + log = open(settings.SURVEX_DATA + survex_file + ".log", "rb") + return HttpResponse(log, mimetype="text") + +def err(request, survex_file): + process(survex_file) + err = open(settings.SURVEX_DATA + survex_file + ".err", "rb") + return HttpResponse(err, mimetype="text") + + + +def identifycavedircontents(gcavedir): + name = os.path.split(gcavedir)[1] + subdirs = [ ] + subsvx = [ ] + primesvx = None + for f in os.listdir(gcavedir): + if name == "204" and (f in ["skel.svx", "template.svx", "204withents.svx"]): + pass + elif name == "136" and (f in ["136-noents.svx"]): + pass + elif name == "115" and (f in ["115cufix.svx", "115fix.svx"]): + pass + + elif os.path.isdir(os.path.join(gcavedir, f)): + if f[0] != ".": + subdirs.append(f) + elif f[-4:] == ".svx": + nf = f[:-4] + + if nf.lower() == name.lower() or nf[:3] == "all" or (name, nf) in [("144arge", "144"), ("resurvey2005", "145-2005"), ("cucc", "cu115")]: + if primesvx: + if nf[:3] == "all": + assert primesvx[:3] != "all", (name, nf, primesvx, gcavedir, subsvx) + primesvx = nf + else: + assert primesvx[:3] == "all", (name, nf, primesvx, gcavedir, subsvx) + else: + primesvx = nf + else: + subsvx.append(nf) + else: + assert re.match(".*?(?:.3d|.log|.err|.txt|.tmp|.diff|.e?spec|~)$", f), (gcavedir, f) + subsvx.sort() + assert primesvx, (gcavedir, subsvx) + if primesvx: + subsvx.insert(0, primesvx) + return subdirs, subsvx + + + +# direct local non-database browsing through the svx file repositories +# perhaps should use the database and have a reload button for it +def survexcaveslist(request): + cavesdir = os.path.join(settings.SURVEX_DATA, "caves") + cavesdircontents = { } + + onefilecaves = [ ] + multifilecaves = [ ] + subdircaves = [ ] + + # first sort the file list + fnumlist = [ (-int(re.match("\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir) ] + fnumlist.sort() + + # go through the list and identify the contents of each cave directory + for num, cavedir in fnumlist: + if cavedir in ["144", "40"]: + continue + + gcavedir = os.path.join(cavesdir, cavedir) + if os.path.isdir(gcavedir) and cavedir[0] != ".": + subdirs, subsvx = identifycavedircontents(gcavedir) + survdirobj = [ ] + + for lsubsvx in subsvx: + survdirobj.append(("caves/"+cavedir+"/"+lsubsvx, lsubsvx)) + + # caves with subdirectories + if subdirs: + subsurvdirs = [ ] + for subdir in subdirs: + dsubdirs, dsubsvx = identifycavedircontents(os.path.join(gcavedir, subdir)) + assert not dsubdirs + lsurvdirobj = [ ] + for lsubsvx in dsubsvx: + lsurvdirobj.append(("caves/"+cavedir+"/"+subdir+"/"+lsubsvx, lsubsvx)) + subsurvdirs.append((lsurvdirobj[0], lsurvdirobj[1:])) + subdircaves.append((cavedir, (survdirobj[0], survdirobj[1:]), subsurvdirs)) + + # multifile caves + elif len(survdirobj) > 1: + multifilecaves.append((survdirobj[0], survdirobj[1:])) + # single file caves + else: + onefilecaves.append(survdirobj[0]) + + return render_to_response('svxfilecavelist.html', {'settings': settings, "onefilecaves":onefilecaves, "multifilecaves":multifilecaves, "subdircaves":subdircaves }) + + + + + + +# parsing all the survex files of a single cave and showing that it's consistent and can find all the files and people +# doesn't use recursion. just writes it twice +def survexcavesingle(request, survex_cave): + breload = False + cave = Cave.objects.get(kataster_number=survex_cave) + if breload: + parsers.survex.ReloadSurvexCave(survex_cave) + return render_to_response('svxcavesingle.html', {'settings': settings, "cave":cave }) + + + +
\ No newline at end of file diff --git a/databaseReset.py b/databaseReset.py index 52a646c..4a7aeb4 100644 --- a/databaseReset.py +++ b/databaseReset.py @@ -1,217 +1,217 @@ -import os
-import time
-import settings
-os.environ['PYTHONPATH'] = settings.PYTHON_PATH
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-from django.core import management
-from django.db import connection
-from django.contrib.auth.models import User
-from django.http import HttpResponse
-from django.core.urlresolvers import reverse
-import flatpages.models
-
-
-
-def reload_db():
- if settings.DATABASE_ENGINE == 'sqlite3':
- try:
- os.remove(settings.DATABASE_NAME)
- except OSError:
- pass
- else:
- cursor = connection.cursor()
- cursor.execute("DROP DATABASE %s" % settings.DATABASE_NAME)
- cursor.execute("CREATE DATABASE %s" % settings.DATABASE_NAME)
- cursor.execute("ALTER DATABASE %s CHARACTER SET=utf8" % settings.DATABASE_NAME)
- cursor.execute("USE %s" % settings.DATABASE_NAME)
- management.call_command('syncdb', interactive=False)
- user = User.objects.create_user('expo', 'goatchurch@gmail.com', 'gosser')
- user.is_staff = True
- user.is_superuser = True
- user.save()
-
-def make_dirs():
- """Make directories that troggle requires"""
- #should also deal with permissions here.
- if not os.path.isdir(settings.PHOTOS_ROOT):
- os.mkdir(settings.PHOTOS_ROOT)
-
-
-
-def import_cavetab():
- import parsers.cavetab
- print "importing cavetab"
- parsers.cavetab.LoadCaveTab()
-
-def import_people():
- import parsers.people
- parsers.people.LoadPersonsExpos()
-
-def import_logbooks():
- # The below line was causing errors I didn't understand (it said LOGFILE was a string), and I couldn't be bothered to figure
- # what was going on so I just catch the error with a try. - AC 21 May
- try:
- settings.LOGFILE.write('\nBegun importing logbooks at ' + time.asctime() +'\n'+'-'*60)
- except:
- pass
-
- import parsers.logbooks
- parsers.logbooks.LoadLogbooks()
-
-def import_survex():
- import parsers.survex
- parsers.survex.LoadAllSurvexBlocks()
- parsers.survex.LoadPos()
-
-def import_QMs():
- import parsers.QMs
-
-def import_surveys():
- import parsers.surveys
- parsers.surveys.parseSurveys(logfile=settings.LOGFILE)
-
-def import_surveyscans():
- import parsers.surveys
- parsers.surveys.LoadListScans()
-
-
-def import_descriptions():
- import parsers.descriptions
- parsers.descriptions.getDescriptions()
-
-def parse_descriptions():
- import parsers.descriptions
- parsers.descriptions.parseDescriptions()
- parsers.descriptions.parseDescriptionsOnCaveObjects()
-
-def import_tunnelfiles():
- import parsers.surveys
- parsers.surveys.LoadTunnelFiles()
-
-
-def reset():
- """ Wipe the troggle database and import everything from legacy data
- """
- reload_db()
- make_dirs()
- pageredirects()
- import_cavetab()
- import_people()
- import_surveyscans()
- import_survex()
- import_logbooks()
- import_QMs()
- import_tunnelfiles()
-
- import_surveys()
- import_descriptions()
- parse_descriptions()
-
-def resetdesc():
- """ Wipe the troggle database and import descriptions
- """
- import core.models
- for desc in core.models.CaveDescription.objects.all():
- desc.delete()
- import_descriptions()
- parse_descriptions()
-
-def export_cavetab():
- from export import tocavetab
- outfile=file(os.path.join(settings.EXPOWEB, "noinfo", "CAVETAB2.CSV"),'w')
- tocavetab.writeCaveTab(outfile)
- outfile.close()
-
-def import_auto_logbooks():
- import parsers.logbooks
- import os
- for pt in core.models.PersonTrip.objects.all():
- pt.delete()
- for lbe in core.models.LogbookEntry.objects.all():
- lbe.delete()
- for expedition in core.models.Expedition.objects.all():
- directory = os.path.join(settings.EXPOWEB,
- "years",
- expedition.year,
- "autologbook")
- for root, dirs, filenames in os.walk(directory):
- for filename in filenames:
- print os.path.join(root, filename)
- parsers.logbooks.parseAutoLogBookEntry(os.path.join(root, filename))
-
-#Temporary function until definative source of data transfered.
-from django.template.defaultfilters import slugify
-from django.template import Context, loader
-def dumplogbooks():
- def get_name(pe):
- if pe.nickname:
- return pe.nickname
- else:
- return pe.person.first_name
- for lbe in core.models.LogbookEntry.objects.all():
- dateStr = lbe.date.strftime("%Y-%m-%d")
- directory = os.path.join(settings.EXPOWEB,
- "years",
- lbe.expedition.year,
- "autologbook")
- if not os.path.isdir(directory):
- os.mkdir(directory)
- filename = os.path.join(directory,
- dateStr + "." + slugify(lbe.title)[:50] + ".html")
- if lbe.cave:
- print lbe.cave.reference()
- trip = {"title": lbe.title, "html":lbe.text, "cave": lbe.cave.reference(), "caveOrLocation": "cave"}
- else:
- trip = {"title": lbe.title, "html":lbe.text, "location":lbe.place, "caveOrLocation": "location"}
- pts = [pt for pt in lbe.persontrip_set.all() if pt.personexpedition]
- persons = [{"name": get_name(pt.personexpedition), "TU": pt.time_underground, "author": pt.is_logbook_entry_author} for pt in pts]
- f = open(filename, "wb")
- template = loader.get_template('dataformat/logbookentry.html')
- context = Context({'trip': trip,
- 'persons': persons,
- 'date': dateStr,
- 'expeditionyear': lbe.expedition.year})
- output = template.render(context)
- f.write(unicode(output).encode( "utf-8" ))
- f.close()
-
-def pageredirects():
- for oldURL, newURL in [("indxal.htm", reverse("caveindex"))]:
- f = flatpages.models.Redirect(originalURL = oldURL, newURL = newURL)
- f.save()
-
-if __name__ == "__main__":
- import core.models
- import sys
- if "desc" in sys.argv:
- resetdesc()
- elif "scans" in sys.argv:
- import_surveyscans()
- elif "caves" in sys.argv:
- reload_db()
- make_dirs()
- pageredirects()
- import_cavetab()
- elif "QMs" in sys.argv:
- import_QMs()
- elif "tunnel" in sys.argv:
- import_tunnelfiles()
- elif "reset" in sys.argv:
- reset()
- elif "survex" in sys.argv:
- management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex
- import_survex()
-
- elif "logbooks" in sys.argv:
- management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex
- import_logbooks()
- elif "autologbooks" in sys.argv:
- import_auto_logbooks()
- elif "dumplogbooks" in sys.argv:
- dumplogbooks()
- else:
- print "Do 'python databaseReset.py reset'"
-
-
-
-
+import os +import time +import settings +os.environ['PYTHONPATH'] = settings.PYTHON_PATH +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' +from django.core import management +from django.db import connection +from django.contrib.auth.models import User +from django.http import HttpResponse +from django.core.urlresolvers import reverse +import flatpages.models + + + +def reload_db(): + if settings.DATABASE_ENGINE == 'sqlite3': + try: + os.remove(settings.DATABASE_NAME) + except OSError: + pass + else: + cursor = connection.cursor() + cursor.execute("DROP DATABASE %s" % settings.DATABASE_NAME) + cursor.execute("CREATE DATABASE %s" % settings.DATABASE_NAME) + cursor.execute("ALTER DATABASE %s CHARACTER SET=utf8" % settings.DATABASE_NAME) + cursor.execute("USE %s" % settings.DATABASE_NAME) + management.call_command('syncdb', interactive=False) + user = User.objects.create_user('expo', 'goatchurch@gmail.com', 'gosser') + user.is_staff = True + user.is_superuser = True + user.save() + +def make_dirs(): + """Make directories that troggle requires""" + #should also deal with permissions here. + if not os.path.isdir(settings.PHOTOS_ROOT): + os.mkdir(settings.PHOTOS_ROOT) + + + +def import_cavetab(): + import parsers.cavetab + print "importing cavetab" + parsers.cavetab.LoadCaveTab() + +def import_people(): + import parsers.people + parsers.people.LoadPersonsExpos() + +def import_logbooks(): + # The below line was causing errors I didn't understand (it said LOGFILE was a string), and I couldn't be bothered to figure + # what was going on so I just catch the error with a try. - AC 21 May + try: + settings.LOGFILE.write('\nBegun importing logbooks at ' + time.asctime() +'\n'+'-'*60) + except: + pass + + import parsers.logbooks + parsers.logbooks.LoadLogbooks() + +def import_survex(): + import parsers.survex + parsers.survex.LoadAllSurvexBlocks() + parsers.survex.LoadPos() + +def import_QMs(): + import parsers.QMs + +def import_surveys(): + import parsers.surveys + parsers.surveys.parseSurveys(logfile=settings.LOGFILE) + +def import_surveyscans(): + import parsers.surveys + parsers.surveys.LoadListScans() + + +def import_descriptions(): + import parsers.descriptions + parsers.descriptions.getDescriptions() + +def parse_descriptions(): + import parsers.descriptions + parsers.descriptions.parseDescriptions() + parsers.descriptions.parseDescriptionsOnCaveObjects() + +def import_tunnelfiles(): + import parsers.surveys + parsers.surveys.LoadTunnelFiles() + + +def reset(): + """ Wipe the troggle database and import everything from legacy data + """ + reload_db() + make_dirs() + pageredirects() + import_cavetab() + import_people() + import_surveyscans() + import_survex() + import_logbooks() + import_QMs() + import_tunnelfiles() + + import_surveys() + import_descriptions() + parse_descriptions() + +def resetdesc(): + """ Wipe the troggle database and import descriptions + """ + import core.models + for desc in core.models.CaveDescription.objects.all(): + desc.delete() + import_descriptions() + parse_descriptions() + +def export_cavetab(): + from export import tocavetab + outfile=file(os.path.join(settings.EXPOWEB, "noinfo", "CAVETAB2.CSV"),'w') + tocavetab.writeCaveTab(outfile) + outfile.close() + +def import_auto_logbooks(): + import parsers.logbooks + import os + for pt in core.models.PersonTrip.objects.all(): + pt.delete() + for lbe in core.models.LogbookEntry.objects.all(): + lbe.delete() + for expedition in core.models.Expedition.objects.all(): + directory = os.path.join(settings.EXPOWEB, + "years", + expedition.year, + "autologbook") + for root, dirs, filenames in os.walk(directory): + for filename in filenames: + print os.path.join(root, filename) + parsers.logbooks.parseAutoLogBookEntry(os.path.join(root, filename)) + +#Temporary function until definative source of data transfered. +from django.template.defaultfilters import slugify +from django.template import Context, loader +def dumplogbooks(): + def get_name(pe): + if pe.nickname: + return pe.nickname + else: + return pe.person.first_name + for lbe in core.models.LogbookEntry.objects.all(): + dateStr = lbe.date.strftime("%Y-%m-%d") + directory = os.path.join(settings.EXPOWEB, + "years", + lbe.expedition.year, + "autologbook") + if not os.path.isdir(directory): + os.mkdir(directory) + filename = os.path.join(directory, + dateStr + "." + slugify(lbe.title)[:50] + ".html") + if lbe.cave: + print lbe.cave.reference() + trip = {"title": lbe.title, "html":lbe.text, "cave": lbe.cave.reference(), "caveOrLocation": "cave"} + else: + trip = {"title": lbe.title, "html":lbe.text, "location":lbe.place, "caveOrLocation": "location"} + pts = [pt for pt in lbe.persontrip_set.all() if pt.personexpedition] + persons = [{"name": get_name(pt.personexpedition), "TU": pt.time_underground, "author": pt.is_logbook_entry_author} for pt in pts] + f = open(filename, "wb") + template = loader.get_template('dataformat/logbookentry.html') + context = Context({'trip': trip, + 'persons': persons, + 'date': dateStr, + 'expeditionyear': lbe.expedition.year}) + output = template.render(context) + f.write(unicode(output).encode( "utf-8" )) + f.close() + +def pageredirects(): + for oldURL, newURL in [("indxal.htm", reverse("caveindex"))]: + f = flatpages.models.Redirect(originalURL = oldURL, newURL = newURL) + f.save() + +if __name__ == "__main__": + import core.models + import sys + if "desc" in sys.argv: + resetdesc() + elif "scans" in sys.argv: + import_surveyscans() + elif "caves" in sys.argv: + reload_db() + make_dirs() + pageredirects() + import_cavetab() + elif "QMs" in sys.argv: + import_QMs() + elif "tunnel" in sys.argv: + import_tunnelfiles() + elif "reset" in sys.argv: + reset() + elif "survex" in sys.argv: + management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex + import_survex() + + elif "logbooks" in sys.argv: + management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex + import_logbooks() + elif "autologbooks" in sys.argv: + import_auto_logbooks() + elif "dumplogbooks" in sys.argv: + dumplogbooks() + else: + print "Do 'python databaseReset.py reset'" + + + + diff --git a/export/tocavetab.py b/export/tocavetab.py index bf0170d..f55032d 100644 --- a/export/tocavetab.py +++ b/export/tocavetab.py @@ -1,49 +1,49 @@ -import troggle.core.models as models
-from django.conf import settings
-
-import csv, re, os
-
-#format of CAVETAB2.CSV is
-headers=['KatasterNumber','KatStatusCode','Entrances','UnofficialNumber','MultipleEntrances','AutogenFile','LinkFile','LinkEntrance','Name','UnofficialName',
- 'Comment','Area','Explorers','UndergroundDescription','Equipment','QMList','KatasterStatus','References','UndergroundCentreLine','UndergroundDrawnSurvey',
- 'SurvexFile','Length','Depth','Extent','Notes','EntranceName','TagPoint','OtherPoint','DescriptionOfOtherPoint','ExactEntrance','TypeOfFix','GPSpreSA',
- 'GPSpostSA','Northing','Easting','Altitude','Bearings','Map','Location','Approach','EntranceDescription','PhotoOfLocation','Marking','MarkingComment',
- 'Findability','FindabilityComment']
-
-def cavetabRow(cave):
- #mapping of troggle models to table columns is: (guess this could just be a tuple of tuples rather than a dictionary actually)
- columnsToModelFields={
- 'Name':cave.official_name,
- 'Area':cave.kat_area(),
- 'KatStatusCode':cave.kataster_code,
- 'KatasterNumber':cave.kataster_number,
- 'UnofficialNumber':cave.unofficial_number,
- #'' : cave.entrances This is a multiple foreignkey now, may be tricky to dump back into csv. Work on this.
- 'Explorers':cave.explorers,
- 'UndergroundDescription':cave.underground_description,
- 'Equipment':cave.equipment,
- 'References':cave.references,
- 'UndergroundDrawnSurvey':cave.survey,
- 'KatasterStatus':cave.kataster_status,
- 'UndergroundCentreLine':cave.underground_centre_line,
- 'Notes':cave.notes,
- 'Length':cave.length,
- 'Depth':cave.depth,
- 'Extent':cave.extent,
- 'SurvexFile':cave.survex_file,
- }
-
- caveRow=['' for x in range(len(headers))]
- for column, modelField in columnsToModelFields.items():
- if modelField:
- # Very sorry about the atrocious replace below. I will fix this soon if noone beats me to it. - AC
- caveRow[headers.index(column)]=modelField.replace(u'\xd7','x').replace(u'\u201c','').replace(u'\u2013','').replace(u'\xbd','')
- return caveRow
-
-def writeCaveTab(outfile):
- cavewriter=csv.writer(outfile,lineterminator='\r')
- cavewriter.writerow(headers)
- for cave in models.Cave.objects.all():
- cavewriter.writerow(cavetabRow(cave))
-
-
+import troggle.core.models as models +from django.conf import settings + +import csv, re, os + +#format of CAVETAB2.CSV is +headers=['KatasterNumber','KatStatusCode','Entrances','UnofficialNumber','MultipleEntrances','AutogenFile','LinkFile','LinkEntrance','Name','UnofficialName', + 'Comment','Area','Explorers','UndergroundDescription','Equipment','QMList','KatasterStatus','References','UndergroundCentreLine','UndergroundDrawnSurvey', + 'SurvexFile','Length','Depth','Extent','Notes','EntranceName','TagPoint','OtherPoint','DescriptionOfOtherPoint','ExactEntrance','TypeOfFix','GPSpreSA', + 'GPSpostSA','Northing','Easting','Altitude','Bearings','Map','Location','Approach','EntranceDescription','PhotoOfLocation','Marking','MarkingComment', + 'Findability','FindabilityComment'] + +def cavetabRow(cave): + #mapping of troggle models to table columns is: (guess this could just be a tuple of tuples rather than a dictionary actually) + columnsToModelFields={ + 'Name':cave.official_name, + 'Area':cave.kat_area(), + 'KatStatusCode':cave.kataster_code, + 'KatasterNumber':cave.kataster_number, + 'UnofficialNumber':cave.unofficial_number, + #'' : cave.entrances This is a multiple foreignkey now, may be tricky to dump back into csv. Work on this. + 'Explorers':cave.explorers, + 'UndergroundDescription':cave.underground_description, + 'Equipment':cave.equipment, + 'References':cave.references, + 'UndergroundDrawnSurvey':cave.survey, + 'KatasterStatus':cave.kataster_status, + 'UndergroundCentreLine':cave.underground_centre_line, + 'Notes':cave.notes, + 'Length':cave.length, + 'Depth':cave.depth, + 'Extent':cave.extent, + 'SurvexFile':cave.survex_file, + } + + caveRow=['' for x in range(len(headers))] + for column, modelField in columnsToModelFields.items(): + if modelField: + # Very sorry about the atrocious replace below. I will fix this soon if noone beats me to it. - AC + caveRow[headers.index(column)]=modelField.replace(u'\xd7','x').replace(u'\u201c','').replace(u'\u2013','').replace(u'\xbd','') + return caveRow + +def writeCaveTab(outfile): + cavewriter=csv.writer(outfile,lineterminator='\r') + cavewriter.writerow(headers) + for cave in models.Cave.objects.all(): + cavewriter.writerow(cavetabRow(cave)) + + diff --git a/export/toqms.py b/export/toqms.py index a6a264a..2564094 100644 --- a/export/toqms.py +++ b/export/toqms.py @@ -1,16 +1,16 @@ -import troggle.core.models as models
-from django.conf import settings
-
-import csv
-import re
-import os
-
-#format of QM tables
-headers=['Number','Grade','Area','Description','Page reference','Nearest station','Completion description','Comment']
-
-def qmRow(qm):
- #mapping of troggle models to table columns is: (guess this could just be a tuple of tuples rather than a dictionary actually)
- columnsToModelFields={
+import troggle.core.models as models +from django.conf import settings + +import csv +import re +import os + +#format of QM tables +headers=['Number','Grade','Area','Description','Page reference','Nearest station','Completion description','Comment'] + +def qmRow(qm): + #mapping of troggle models to table columns is: (guess this could just be a tuple of tuples rather than a dictionary actually) + columnsToModelFields={ 'Number':str(qm.number), 'Grade':qm.grade, 'Area':qm.area, @@ -18,19 +18,19 @@ def qmRow(qm): #'Page reference': #not implemented 'Nearest station':qm.nearest_station_description, 'Completion description':qm.completion_description, - 'Comment':qm.comment
- }
-
- qmRow=['' for x in range(len(headers))]
- for column, modelField in columnsToModelFields.items():
- if modelField:
- # Very sorry about the atrocious replace below. I will fix this soon if noone beats me to it. - AC
- qmRow[headers.index(column)]=modelField.replace(u'\xd7','x').replace(u'\u201c','').replace(u'\u2013','').replace(u'\xbd','')
- return qmRow
-
-def writeQmTable(outfile,cave):
- cavewriter=csv.writer(outfile,lineterminator='\r')
- cavewriter.writerow(headers)
- for qm in cave.get_QMs():
- cavewriter.writerow(qmRow(qm))
+ 'Comment':qm.comment + } + + qmRow=['' for x in range(len(headers))] + for column, modelField in columnsToModelFields.items(): + if modelField: + # Very sorry about the atrocious replace below. I will fix this soon if noone beats me to it. - AC + qmRow[headers.index(column)]=modelField.replace(u'\xd7','x').replace(u'\u201c','').replace(u'\u2013','').replace(u'\xbd','') + return qmRow + +def writeQmTable(outfile,cave): + cavewriter=csv.writer(outfile,lineterminator='\r') + cavewriter.writerow(headers) + for qm in cave.get_QMs(): + cavewriter.writerow(qmRow(qm))
\ No newline at end of file diff --git a/localsettingswindows.py b/localsettingswindows.py index c5cb682..c9f67e4 100644 --- a/localsettingswindows.py +++ b/localsettingswindows.py @@ -1,58 +1,58 @@ -DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-DATABASE_NAME = '' # Or path to database file if using sqlite3.
-DATABASE_USER = '' # Not used with sqlite3.
-DATABASE_PASSWORD = '' # Not used with sqlite3.
-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
-
-SURVEX_DATA = 'c:\\Expo\\loser\\'
-CAVERN = 'cavern'
-THREEDTOPOS = '3dtopos'
-EXPOWEB = 'C:\\Expo\\expoweb\\'
-SURVEYS = 'E:\\surveys\\'
-SURVEY_SCANS = 'E:\\surveys\\surveyscans'
-
-EXPOWEB_URL = 'http://expo.survex.com/'
-
-LOGFILE = EXPOWEB+'troggle\\parsing_log.txt'
-
-PHOTOS = 'C:\\Expo\\expoweb\\photos'
-
-URL_ROOT = 'http://127.0.0.1:8000'
-DIR_ROOT = ''#this should end in / if a value is given
-PUBLIC_SITE = False
-
-TINY_MCE_MEDIA_ROOT = '/usr/share/tinymce/www/'
-TINY_MCE_MEDIA_URL = URL_ROOT + DIR_ROOT + 'tinymce_media/'
-
-PYTHON_PATH = 'C:\\expoweb\\troggle\\'
-
-MEDIA_ROOT = 'C:/Expo/expoweb/troggle/media/'
-MEDIA_URL = URL_ROOT + DIR_ROOT + 'site_media/'
-
-#FILES = "http://framos.lawoftheland.co.uk/troggle/survey_files/"
-
-EMAIL_HOST = "smtp.gmail.com"
-
-EMAIL_HOST_USER = "cuccexpo@gmail.com"
-
-EMAIL_HOST_PASSWORD = ""
-
-EMAIL_PORT=587
-
-EMAIL_USE_TLS = True
-
-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
-# trailing slash if there is a path component (optional in other cases).
-# Examples: "http://media.lawrence.com", "http://example.com/media/"
-
-
-
-
-TEMPLATE_DIRS = (
- "C:/Expo/expoweb/troggle/templates",
-
- # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
- # Always use forward slashes, even on Windows.
- # Don't forget to use absolute paths, not relative paths.
-)
+DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. +DATABASE_NAME = '' # Or path to database file if using sqlite3. +DATABASE_USER = '' # Not used with sqlite3. +DATABASE_PASSWORD = '' # Not used with sqlite3. +DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. +DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. + +SURVEX_DATA = 'c:\\Expo\\loser\\' +CAVERN = 'cavern' +THREEDTOPOS = '3dtopos' +EXPOWEB = 'C:\\Expo\\expoweb\\' +SURVEYS = 'E:\\surveys\\' +SURVEY_SCANS = 'E:\\surveys\\surveyscans' + +EXPOWEB_URL = 'http://expo.survex.com/' + +LOGFILE = EXPOWEB+'troggle\\parsing_log.txt' + +PHOTOS = 'C:\\Expo\\expoweb\\photos' + +URL_ROOT = 'http://127.0.0.1:8000' +DIR_ROOT = ''#this should end in / if a value is given +PUBLIC_SITE = False + +TINY_MCE_MEDIA_ROOT = '/usr/share/tinymce/www/' +TINY_MCE_MEDIA_URL = URL_ROOT + DIR_ROOT + 'tinymce_media/' + +PYTHON_PATH = 'C:\\expoweb\\troggle\\' + +MEDIA_ROOT = 'C:/Expo/expoweb/troggle/media/' +MEDIA_URL = URL_ROOT + DIR_ROOT + 'site_media/' + +#FILES = "http://framos.lawoftheland.co.uk/troggle/survey_files/" + +EMAIL_HOST = "smtp.gmail.com" + +EMAIL_HOST_USER = "cuccexpo@gmail.com" + +EMAIL_HOST_PASSWORD = "" + +EMAIL_PORT=587 + +EMAIL_USE_TLS = True + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash if there is a path component (optional in other cases). +# Examples: "http://media.lawrence.com", "http://example.com/media/" + + + + +TEMPLATE_DIRS = ( + "C:/Expo/expoweb/troggle/templates", + + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) @@ -1,11 +1,11 @@ -#!/usr/bin/env python
-from django.core.management import execute_manager
-try:
- import settings # Assumed to be in the same directory.
-except ImportError:
- import sys
- sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
- sys.exit(1)
-
-if __name__ == "__main__":
- execute_manager(settings)
+#!/usr/bin/env python +from django.core.management import execute_manager +try: + import settings # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.exit(1) + +if __name__ == "__main__": + execute_manager(settings) diff --git a/middleware.py b/middleware.py index 40e14ed..15dd039 100644 --- a/middleware.py +++ b/middleware.py @@ -1,49 +1,49 @@ -from django.conf import settings
-from django import http
-from django.core.urlresolvers import resolve
-
-class SmartAppendSlashMiddleware(object):
- """
- "SmartAppendSlash" middleware for taking care of URL rewriting.
-
- This middleware appends a missing slash, if:
- * the SMART_APPEND_SLASH setting is True
- * the URL without the slash does not exist
- * the URL with an appended slash does exist.
- Otherwise it won't touch the URL.
- """
-
- def process_request(self, request):
- """
- Rewrite the URL based on settings.SMART_APPEND_SLASH
- """
-
- # Check for a redirect based on settings.SMART_APPEND_SLASH
- host = http.get_host(request)
- old_url = [host, request.path]
- new_url = old_url[:]
- # Append a slash if SMART_APPEND_SLASH is set and the resulting URL
- # resolves.
- if settings.SMART_APPEND_SLASH and (not old_url[1].endswith('/')) and not _resolves(old_url[1]) and _resolves(old_url[1] + '/'):
- new_url[1] = new_url[1] + '/'
- if settings.DEBUG and request.method == 'POST':
- raise RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have SMART_APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to %s%s (note the trailing slash), or set SMART_APPEND_SLASH=False in your Django settings." % (new_url[0], new_url[1])
- if new_url != old_url:
- # Redirect
- if new_url[0]:
- newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1])
- else:
- newurl = new_url[1]
- if request.GET:
- newurl += '?' + request.GET.urlencode()
- return http.HttpResponsePermanentRedirect(newurl)
-
- return None
-
-def _resolves(url):
- try:
- resolve(url)
- return True
- except http.Http404:
- return False
-
+from django.conf import settings +from django import http +from django.core.urlresolvers import resolve + +class SmartAppendSlashMiddleware(object): + """ + "SmartAppendSlash" middleware for taking care of URL rewriting. + + This middleware appends a missing slash, if: + * the SMART_APPEND_SLASH setting is True + * the URL without the slash does not exist + * the URL with an appended slash does exist. + Otherwise it won't touch the URL. + """ + + def process_request(self, request): + """ + Rewrite the URL based on settings.SMART_APPEND_SLASH + """ + + # Check for a redirect based on settings.SMART_APPEND_SLASH + host = http.get_host(request) + old_url = [host, request.path] + new_url = old_url[:] + # Append a slash if SMART_APPEND_SLASH is set and the resulting URL + # resolves. + if settings.SMART_APPEND_SLASH and (not old_url[1].endswith('/')) and not _resolves(old_url[1]) and _resolves(old_url[1] + '/'): + new_url[1] = new_url[1] + '/' + if settings.DEBUG and request.method == 'POST': + raise RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have SMART_APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to %s%s (note the trailing slash), or set SMART_APPEND_SLASH=False in your Django settings." % (new_url[0], new_url[1]) + if new_url != old_url: + # Redirect + if new_url[0]: + newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1]) + else: + newurl = new_url[1] + if request.GET: + newurl += '?' + request.GET.urlencode() + return http.HttpResponsePermanentRedirect(newurl) + + return None + +def _resolves(url): + try: + resolve(url) + return True + except http.Http404: + return False + diff --git a/parsers/cavetab.py b/parsers/cavetab.py index 814b3a0..d76a280 100644 --- a/parsers/cavetab.py +++ b/parsers/cavetab.py @@ -1,254 +1,253 @@ -# -*- coding: utf-8 -*-
-import troggle.core.models as models
-from django.conf import settings
-import csv, time, re, os, logging
-from utils import save_carefully
-from django.core.urlresolvers import reverse
-import flatpages.models
-
-##format of CAVETAB2.CSV is
-KatasterNumber = 0
-KatStatusCode = 1
-Entrances = 2
-UnofficialNumber = 3
-MultipleEntrances = 4
-AutogenFile = 5
-LinkFile = 6
-LinkEntrance = 7
-Name = 8
-UnofficialName = 9
-Comment = 10
-Area = 11
-Explorers = 12
-UndergroundDescription = 13
-Equipment = 14
-QMList = 15
-KatasterStatus = 16
-References = 17
-UndergroundCentreLine = 18
-UndergroundDrawnSurvey = 19
-SurvexFile = 20
-Length = 21
-Depth = 22
-Extent = 23
-Notes = 24
-EntranceName = 25
-TagPoint = 26
-OtherPoint = 27
-DescriptionOfOtherPoint = 28
-ExactEntrance = 29
-TypeOfFix = 30
-GPSpreSA = 31
-GPSpostSA = 32
-Northing = 33
-Easting = 34
-Altitude = 35
-Bearings = 36
-Map = 37
-Location = 38
-Approach = 39
-EntranceDescription = 40
-PhotoOfLocation = 41
-Marking = 42
-MarkingComment = 43
-Findability = 44
-FindabilityComment = 45
-
-def LoadCaveTab():
-
- cavetab = open(os.path.join(settings.EXPOWEB, "noinfo", "CAVETAB2.CSV"),'rU')
- caveReader = csv.reader(cavetab)
- caveReader.next() # Strip out column headers
-
- logging.info("Beginning to import caves from "+str(cavetab)+"\n"+"-"*60+"\n")
-
- for katArea in ['1623', '1626']:
- if not models.Area.objects.filter(short_name = katArea):
- newArea = models.Area(short_name = katArea)
- newArea.save()
- logging.info("Added area "+str(newArea.short_name)+"\n")
- area1626 = models.Area.objects.filter(short_name = '1626')[0]
- area1623 = models.Area.objects.filter(short_name = '1623')[0]
-
- counter=0
- for line in caveReader :
- if line[Area] == 'nonexistent':
- continue
- entranceLetters=[] #Used in caves that have mulitlple entrances, which are not described on seperate lines
- if line[MultipleEntrances] == 'yes' or line[MultipleEntrances]=='': #When true, this line contains an actual cave, otherwise it is an extra entrance.
- args = {}
- defaultArgs = {}
-
- def addToArgs(CSVname, modelName):
- if line[CSVname]:
- args[modelName] = line[CSVname]
-
- def addToDefaultArgs(CSVname, modelName): #This has to do with the non-destructive import. These arguments will be passed as the "default" dictionary in a get_or_create
- if line[CSVname]:
- defaultArgs[modelName] = line[CSVname]
-
- # The attributes added using "addToArgs" will be used to look up an existing cave. Those added using "addToDefaultArgs" will not.
- addToArgs(KatasterNumber, "kataster_number")
- addToDefaultArgs(KatStatusCode, "kataster_code")
- addToArgs(UnofficialNumber, "unofficial_number")
- addToArgs(Name, "official_name")
- addToDefaultArgs(Comment, "notes")
- addToDefaultArgs(Explorers, "explorers")
- addToDefaultArgs(UndergroundDescription, "underground_description")
- addToDefaultArgs(Equipment, "equipment")
- addToDefaultArgs(KatasterStatus, "kataster_status")
- addToDefaultArgs(References, "references")
- addToDefaultArgs(UndergroundCentreLine, "underground_centre_line")
- addToDefaultArgs(UndergroundDrawnSurvey, "survey")
- addToDefaultArgs(Length, "length")
- addToDefaultArgs(Depth, "depth")
- addToDefaultArgs(Extent, "extent")
- addToDefaultArgs(SurvexFile, "survex_file")
- addToDefaultArgs(Notes, "notes")
- addToDefaultArgs(AutogenFile, "url")
- if line[Area] == "1626":
- if line[KatasterNumber] != "":
- args["slug"] = line[Area] + "-" + line[KatasterNumber]
- else:
- args["slug"] = line[Area] + "-" + line[UnofficialNumber]
- else:
- if line[KatasterNumber] != "":
- args["slug"] = "1623" + "-" + line[KatasterNumber]
- else:
- args["slug"] = "1623" + "-" + line[UnofficialNumber]
- #The following adds the legacy_file_path. This is always in either Autogen file or Link file
- for header in (AutogenFile,LinkFile):
- if line[header]:
- addToDefaultArgs(header,"description_file")
- break
-
-
- #The following checks if this cave is non-public i.e. we don't have rights to display it online.
- #Noinfo was the name of the old password protected directory, so if it has that then we will
- #set the non_public field of the model instance to true.
- defaultArgs["non_public"]=line[AutogenFile].startswith('noinfo') or line[LinkFile].startswith('noinfo')
-
- newCave, created=save_carefully(models.Cave, lookupAttribs=args, nonLookupAttribs=defaultArgs)
- logging.info("Added cave "+str(newCave)+"\n")
-
- #If we created a new cave, add the area to it. This does mean that if a cave's identifying features have not changed, areas will not be updated from csv.
- if created and line[Area]:
- if line[Area] == "1626":
- newCave.area.add(area1626)
- else:
- area = models.Area.objects.filter(short_name = line[Area])
- if area:
- newArea = area[0]
- else:
- newArea = models.Area(short_name = line[Area], parent = area1623)
- newArea.save()
- newCave.area.add(newArea)
- newCave.area.add(area1623)
- elif created:
- newCave.area.add(area1623)
-
- newCave.save()
-
- logging.info("Added area "+line[Area]+" to cave "+str(newCave)+"\n")
-
- if created and line[UnofficialName]:
- newUnofficialName = models.OtherCaveName(cave = newCave, name = line[UnofficialName])
- newUnofficialName.save()
-
- logging.info("Added unofficial name "+str(newUnofficialName)+" to cave "+str(newCave)+"\n")
-
-
- if created and line[MultipleEntrances] == '' or \
- line[MultipleEntrances] == 'entrance' or \
- line[MultipleEntrances] == 'last entrance':
- args = {}
-
- if line[Entrances]:
- entrance_letter = line[Entrances]
- else:
- entrance_letter = ''
-
- def addToArgs(CSVname, modelName):
- if line[CSVname]:
- args[modelName] = line[CSVname]
- def addToArgsViaDict(CSVname, modelName, dictionary):
- if line[CSVname]:
- args[modelName] = dictionary[line[CSVname]]
- addToArgs(EntranceName, 'name')
- addToArgs(Explorers, 'explorers')
- addToArgs(Map, 'map_description')
- addToArgs(Location, 'location_description')
- addToArgs(Approach, 'approach')
- addToArgs(EntranceDescription, 'entrance_description')
- addToArgs(UndergroundDescription, 'underground_description')
- addToArgs(PhotoOfLocation, 'photo')
- addToArgsViaDict(Marking, 'marking', {"Paint": "P",
- "Paint (?)": "P?",
- "Tag": "T",
- "Tag (?)": "T?",
- "Retagged": "R",
- "Retag": "R",
- "Spit": "S",
- "Spit (?)": "S?",
- "Unmarked": "U",
- "": "?",
- })
-
- addToArgs(MarkingComment, 'marking_comment')
- addToArgsViaDict(Findability, 'findability', {"Surveyed": "S",
- "Lost": "L",
- "Refindable": "R",
- "": "?",
- "?": "?",
- })
- addToArgs(FindabilityComment, 'findability_description')
- addToArgs(Easting, 'easting')
- addToArgs(Northing, 'northing')
- addToArgs(Altitude, 'alt')
- addToArgs(DescriptionOfOtherPoint, 'other_description')
- addToArgs(TagPoint, 'tag_station')
- addToArgs(ExactEntrance, 'exact_station')
- addToArgs(OtherPoint, 'other_station')
- addToArgs(OtherPoint, 'other_description')
- if line[GPSpreSA]:
- addToArgs(GPSpreSA, 'other_station')
- args['other_description'] = 'pre selective availability GPS'
- if line[GPSpostSA]:
- addToArgs(GPSpostSA, 'other_station')
- args['other_description'] = 'post selective availability GPS'
- addToArgs(Bearings, 'bearings')
- args['slug'] = newCave.slug + entrance_letter
- newEntrance = models.Entrance(**args)
- newEntrance.save()
-
- logging.info("Added entrance "+str(newEntrance)+"\n")
-
-
- newCaveAndEntrance = models.CaveAndEntrance(cave = newCave, entrance = newEntrance, entrance_letter = entrance_letter)
- newCaveAndEntrance.save()
-
- logging.info("Added CaveAndEntrance "+str(newCaveAndEntrance)+"\n")
- if line[AutogenFile] != "":
- f = flatpages.models.EntranceRedirect(originalURL = line[AutogenFile], entrance = newEntrance)
- f.save()
-
-
-# lookup function modelled on GetPersonExpeditionNameLookup
-Gcavelookup = None
-def GetCaveLookup():
- global Gcavelookup
- if Gcavelookup:
- return Gcavelookup
- Gcavelookup = {"NONEPLACEHOLDER":None}
- for cave in models.Cave.objects.all():
- Gcavelookup[cave.official_name.lower()] = cave
- if cave.kataster_number:
- Gcavelookup[cave.kataster_number] = cave
- if cave.unofficial_number:
- Gcavelookup[cave.unofficial_number] = cave
-
- Gcavelookup["tunnocks"] = Gcavelookup["258"]
- Gcavelookup["hauchhole"] = Gcavelookup["234"]
- return Gcavelookup
-
-
+# -*- coding: utf-8 -*- +import troggle.core.models as models +from django.conf import settings +import csv, time, re, os, logging +from utils import save_carefully +from django.core.urlresolvers import reverse +import flatpages.models + +##format of CAVETAB2.CSV is +KatasterNumber = 0 +KatStatusCode = 1 +Entrances = 2 +UnofficialNumber = 3 +MultipleEntrances = 4 +AutogenFile = 5 +LinkFile = 6 +LinkEntrance = 7 +Name = 8 +UnofficialName = 9 +Comment = 10 +Area = 11 +Explorers = 12 +UndergroundDescription = 13 +Equipment = 14 +QMList = 15 +KatasterStatus = 16 +References = 17 +UndergroundCentreLine = 18 +UndergroundDrawnSurvey = 19 +SurvexFile = 20 +Length = 21 +Depth = 22 +Extent = 23 +Notes = 24 +EntranceName = 25 +TagPoint = 26 +OtherPoint = 27 +DescriptionOfOtherPoint = 28 +ExactEntrance = 29 +TypeOfFix = 30 +GPSpreSA = 31 +GPSpostSA = 32 +Northing = 33 +Easting = 34 +Altitude = 35 +Bearings = 36 +Map = 37 +Location = 38 +Approach = 39 +EntranceDescription = 40 +PhotoOfLocation = 41 +Marking = 42 +MarkingComment = 43 +Findability = 44 +FindabilityComment = 45 + +def LoadCaveTab(): + + cavetab = open(os.path.join(settings.EXPOWEB, "noinfo", "CAVETAB2.CSV"),'rU') + caveReader = csv.reader(cavetab) + caveReader.next() # Strip out column headers + + logging.info("Beginning to import caves from "+str(cavetab)+"\n"+"-"*60+"\n") + + for katArea in ['1623', '1626']: + if not models.Area.objects.filter(short_name = katArea): + newArea = models.Area(short_name = katArea) + newArea.save() + logging.info("Added area "+str(newArea.short_name)+"\n") + area1626 = models.Area.objects.filter(short_name = '1626')[0] + area1623 = models.Area.objects.filter(short_name = '1623')[0] + + counter=0 + for line in caveReader : + if line[Area] == 'nonexistent': + continue + entranceLetters=[] #Used in caves that have mulitlple entrances, which are not described on seperate lines + if line[MultipleEntrances] == 'yes' or line[MultipleEntrances]=='': #When true, this line contains an actual cave, otherwise it is an extra entrance. + args = {} + defaultArgs = {} + + def addToArgs(CSVname, modelName): + if line[CSVname]: + args[modelName] = line[CSVname] + + def addToDefaultArgs(CSVname, modelName): #This has to do with the non-destructive import. These arguments will be passed as the "default" dictionary in a get_or_create + if line[CSVname]: + defaultArgs[modelName] = line[CSVname] + + # The attributes added using "addToArgs" will be used to look up an existing cave. Those added using "addToDefaultArgs" will not. + addToArgs(KatasterNumber, "kataster_number") + addToDefaultArgs(KatStatusCode, "kataster_code") + addToArgs(UnofficialNumber, "unofficial_number") + addToArgs(Name, "official_name") + addToDefaultArgs(Comment, "notes") + addToDefaultArgs(Explorers, "explorers") + addToDefaultArgs(UndergroundDescription, "underground_description") + addToDefaultArgs(Equipment, "equipment") + addToDefaultArgs(KatasterStatus, "kataster_status") + addToDefaultArgs(References, "references") + addToDefaultArgs(UndergroundCentreLine, "underground_centre_line") + addToDefaultArgs(UndergroundDrawnSurvey, "survey") + addToDefaultArgs(Length, "length") + addToDefaultArgs(Depth, "depth") + addToDefaultArgs(Extent, "extent") + addToDefaultArgs(SurvexFile, "survex_file") + addToDefaultArgs(Notes, "notes") + addToDefaultArgs(AutogenFile, "url") + if line[Area] == "1626": + if line[KatasterNumber] != "": + args["slug"] = line[Area] + "-" + line[KatasterNumber] + else: + args["slug"] = line[Area] + "-" + line[UnofficialNumber] + else: + if line[KatasterNumber] != "": + args["slug"] = "1623" + "-" + line[KatasterNumber] + else: + args["slug"] = "1623" + "-" + line[UnofficialNumber] + #The following adds the legacy_file_path. This is always in either Autogen file or Link file + for header in (AutogenFile,LinkFile): + if line[header]: + addToDefaultArgs(header,"description_file") + break + + #The following checks if this cave is non-public i.e. we don't have rights to display it online. + #Noinfo was the name of the old password protected directory, so if it has that then we will + #set the non_public field of the model instance to true. + defaultArgs["non_public"]=line[AutogenFile].startswith('noinfo') or line[LinkFile].startswith('noinfo') + + newCave, created=save_carefully(models.Cave, lookupAttribs=args, nonLookupAttribs=defaultArgs) + logging.info("Added cave "+str(newCave)+"\n") + + #If we created a new cave, add the area to it. This does mean that if a cave's identifying features have not changed, areas will not be updated from csv. + if created and line[Area]: + if line[Area] == "1626": + newCave.area.add(area1626) + else: + area = models.Area.objects.filter(short_name = line[Area]) + if area: + newArea = area[0] + else: + newArea = models.Area(short_name = line[Area], parent = area1623) + newArea.save() + newCave.area.add(newArea) + newCave.area.add(area1623) + elif created: + newCave.area.add(area1623) + + newCave.save() + + logging.info("Added area "+line[Area]+" to cave "+str(newCave)+"\n") + + if created and line[UnofficialName]: + newUnofficialName = models.OtherCaveName(cave = newCave, name = line[UnofficialName]) + newUnofficialName.save() + + logging.info("Added unofficial name "+str(newUnofficialName)+" to cave "+str(newCave)+"\n") + + + if created and line[MultipleEntrances] == '' or \ + line[MultipleEntrances] == 'entrance' or \ + line[MultipleEntrances] == 'last entrance': + args = {} + + if line[Entrances]: + entrance_letter = line[Entrances] + else: + entrance_letter = '' + + def addToArgs(CSVname, modelName): + if line[CSVname]: + args[modelName] = line[CSVname] + def addToArgsViaDict(CSVname, modelName, dictionary): + if line[CSVname]: + args[modelName] = dictionary[line[CSVname]] + addToArgs(EntranceName, 'name') + addToArgs(Explorers, 'explorers') + addToArgs(Map, 'map_description') + addToArgs(Location, 'location_description') + addToArgs(Approach, 'approach') + addToArgs(EntranceDescription, 'entrance_description') + addToArgs(UndergroundDescription, 'underground_description') + addToArgs(PhotoOfLocation, 'photo') + addToArgsViaDict(Marking, 'marking', {"Paint": "P", + "Paint (?)": "P?", + "Tag": "T", + "Tag (?)": "T?", + "Retagged": "R", + "Retag": "R", + "Spit": "S", + "Spit (?)": "S?", + "Unmarked": "U", + "": "?", + }) + + addToArgs(MarkingComment, 'marking_comment') + addToArgsViaDict(Findability, 'findability', {"Surveyed": "S", + "Lost": "L", + "Refindable": "R", + "": "?", + "?": "?", + }) + addToArgs(FindabilityComment, 'findability_description') + addToArgs(Easting, 'easting') + addToArgs(Northing, 'northing') + addToArgs(Altitude, 'alt') + addToArgs(DescriptionOfOtherPoint, 'other_description') + addToArgs(TagPoint, 'tag_station') + addToArgs(ExactEntrance, 'exact_station') + addToArgs(OtherPoint, 'other_station') + addToArgs(OtherPoint, 'other_description') + if line[GPSpreSA]: + addToArgs(GPSpreSA, 'other_station') + args['other_description'] = 'pre selective availability GPS' + if line[GPSpostSA]: + addToArgs(GPSpostSA, 'other_station') + args['other_description'] = 'post selective availability GPS' + addToArgs(Bearings, 'bearings') + args['slug'] = newCave.slug + entrance_letter + newEntrance = models.Entrance(**args) + newEntrance.save() + + logging.info("Added entrance "+str(newEntrance)+"\n") + + + newCaveAndEntrance = models.CaveAndEntrance(cave = newCave, entrance = newEntrance, entrance_letter = entrance_letter) + newCaveAndEntrance.save() + + logging.info("Added CaveAndEntrance "+str(newCaveAndEntrance)+"\n") + if line[AutogenFile] != "": + f = flatpages.models.EntranceRedirect(originalURL = line[AutogenFile], entrance = newEntrance) + f.save() + + +# lookup function modelled on GetPersonExpeditionNameLookup +Gcavelookup = None +def GetCaveLookup(): + global Gcavelookup + if Gcavelookup: + return Gcavelookup + Gcavelookup = {"NONEPLACEHOLDER":None} + for cave in models.Cave.objects.all(): + Gcavelookup[cave.official_name.lower()] = cave + if cave.kataster_number: + Gcavelookup[cave.kataster_number] = cave + if cave.unofficial_number: + Gcavelookup[cave.unofficial_number] = cave + + Gcavelookup["tunnocks"] = Gcavelookup["258"] + Gcavelookup["hauchhole"] = Gcavelookup["234"] + return Gcavelookup + + diff --git a/parsers/descriptions.py b/parsers/descriptions.py index 2bca267..cf744fe 100644 --- a/parsers/descriptions.py +++ b/parsers/descriptions.py @@ -1,45 +1,45 @@ -from django.conf import settings
-import core.models as models
-import os
-from utils import html_to_wiki, get_html_body, get_html_title
-
-pages = [(["smkridge", "204", "ariston-rigging.html"], "ariston-rigging"),
- (["smkridge", "204", "ariston.html"], "ariston"),
- (["smkridge", "204", "bivvy.html"], "bivvy"),
- (["smkridge", "204", "bridge.html"], "bridge"),
- (["smkridge", "204", "entrance-rigging.html"], "entrance-rigging"),
- (["smkridge", "204", "entrance.html"], "entrance"),
- (["smkridge", "204", "midlevel.html"], "midlevel"),
- (["smkridge", "204", "millennium.html"], "millennium"),
- (["smkridge", "204", "nopain.html"], "nopain"),
- (["smkridge", "204", "razordance.html"], "razordance"),
- (["smkridge", "204", "rhino.html"], "rhino"),
- (["smkridge", "204", "sbview.html"], "sbview"),
- (["smkridge", "204", "subway.html"], "subway"),
- (["smkridge", "204", "swings.html"], "swings"),
- (["smkridge", "204", "treeumphant.html"], "treeumphant"),
- (["smkridge", "204", "uworld.html"], "uworld"), ]
-
-
-def getDescriptions():
- """Creates objects in the database for each item in the list 'pages' . """
- for filelocation, name in pages:
- f = open(os.path.join(settings.EXPOWEB, *filelocation), "r")
- html = f.read()
-
- cd = models.CaveDescription(short_name = name,
- long_name = unicode(get_html_title(html), "latin1"),
- description = unicode(get_html_body(html), "latin1"))
- cd.save()
-
-def parseDescriptions():
- """Turns the HTML in each cave description into wikicode"""
- for cd in models.CaveDescription.objects.all():
- cd.description = html_to_wiki(cd.description)
-
- cd.save()
-
-def parseDescriptionsOnCaveObjects():
- for cave in models.Cave.objects.all():
- cave.underground_description=html_to_wiki(unicode(cave.underground_description))
+from django.conf import settings +import core.models as models +import os +from utils import html_to_wiki, get_html_body, get_html_title + +pages = [(["smkridge", "204", "ariston-rigging.html"], "ariston-rigging"), + (["smkridge", "204", "ariston.html"], "ariston"), + (["smkridge", "204", "bivvy.html"], "bivvy"), + (["smkridge", "204", "bridge.html"], "bridge"), + (["smkridge", "204", "entrance-rigging.html"], "entrance-rigging"), + (["smkridge", "204", "entrance.html"], "entrance"), + (["smkridge", "204", "midlevel.html"], "midlevel"), + (["smkridge", "204", "millennium.html"], "millennium"), + (["smkridge", "204", "nopain.html"], "nopain"), + (["smkridge", "204", "razordance.html"], "razordance"), + (["smkridge", "204", "rhino.html"], "rhino"), + (["smkridge", "204", "sbview.html"], "sbview"), + (["smkridge", "204", "subway.html"], "subway"), + (["smkridge", "204", "swings.html"], "swings"), + (["smkridge", "204", "treeumphant.html"], "treeumphant"), + (["smkridge", "204", "uworld.html"], "uworld"), ] + + +def getDescriptions(): + """Creates objects in the database for each item in the list 'pages' . """ + for filelocation, name in pages: + f = open(os.path.join(settings.EXPOWEB, *filelocation), "r") + html = f.read() + + cd = models.CaveDescription(short_name = name, + long_name = unicode(get_html_title(html), "latin1"), + description = unicode(get_html_body(html), "latin1")) + cd.save() + +def parseDescriptions(): + """Turns the HTML in each cave description into wikicode""" + for cd in models.CaveDescription.objects.all(): + cd.description = html_to_wiki(cd.description) + + cd.save() + +def parseDescriptionsOnCaveObjects(): + for cave in models.Cave.objects.all(): + cave.underground_description=html_to_wiki(unicode(cave.underground_description)) cave.save()
\ No newline at end of file diff --git a/parsers/logbooks.py b/parsers/logbooks.py index af01f46..c794f9f 100644 --- a/parsers/logbooks.py +++ b/parsers/logbooks.py @@ -1,432 +1,432 @@ -#.-*- coding: utf-8 -*-
-
-from django.conf import settings
-import core.models as models
-
-from parsers.people import GetPersonExpeditionNameLookup
-from parsers.cavetab import GetCaveLookup
-
-from django.template.defaultfilters import slugify
-
-import csv
-import re
-import datetime
-import os
-
-from utils import save_carefully
-
-#
-# When we edit logbook entries, allow a "?" after any piece of data to say we've frigged it and
-# it can be checked up later from the hard-copy if necessary; or it's not possible to determin (name, trip place, etc)
-#
-
-#
-# the logbook loading section
-#
-def GetTripPersons(trippeople, expedition, logtime_underground):
- res = [ ]
- author = None
- for tripperson in re.split(",|\+|&|&(?!\w+;)| and ", trippeople):
- tripperson = tripperson.strip()
- mul = re.match("<u>(.*?)</u>$(?i)", tripperson)
- if mul:
- tripperson = mul.group(1).strip()
- if tripperson and tripperson[0] != '*':
- #assert tripperson in personyearmap, "'%s' << %s\n\n %s" % (tripperson, trippeople, personyearmap)
- personyear = GetPersonExpeditionNameLookup(expedition).get(tripperson.lower())
- if not personyear:
- print "NoMatchFor: '%s'" % tripperson
- res.append((personyear, logtime_underground))
- if mul:
- author = personyear
- if not author:
- if not res:
- return None, None
- author = res[-1][0]
- return res, author
-
-def GetTripCave(place): #need to be fuzzier about matching here. Already a very slow function...
-# print "Getting cave for " , place
- try:
- katastNumRes=[]
- katastNumRes=list(models.Cave.objects.filter(kataster_number=int(place)))
- except ValueError:
- pass
- officialNameRes=list(models.Cave.objects.filter(official_name=place))
- tripCaveRes=officialNameRes+katastNumRes
-
- if len(tripCaveRes)==1:
-# print "Place " , place , "entered as" , tripCaveRes[0]
- return tripCaveRes[0]
-
- elif models.OtherCaveName.objects.filter(name=place):
- tripCaveRes=models.OtherCaveName.objects.filter(name__icontains=place)[0].cave
-# print "Place " , place , "entered as" , tripCaveRes
- return tripCaveRes
-
- elif len(tripCaveRes)>1:
- print "Ambiguous place " + str(place) + " entered. Choose from " + str(tripCaveRes)
- correctIndex=input("type list index of correct cave")
- return tripCaveRes[correctIndex]
- else:
- print "No cave found for place " , place
- return
-
-
-noncaveplaces = [ "Journey", "Loser Plateau" ]
-def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_underground):
- """ saves a logbook entry and related persontrips """
- trippersons, author = GetTripPersons(trippeople, expedition, logtime_underground)
- if not author:
- print "skipping logentry", title
- return
-
-# tripCave = GetTripCave(place)
- #
- lplace = place.lower()
- if lplace not in noncaveplaces:
- cave=GetCaveLookup().get(lplace)
-
- #Check for an existing copy of the current entry, and save
- expeditionday = expedition.get_expedition_day(date)
- lookupAttribs={'date':date, 'title':title}
- nonLookupAttribs={'place':place, 'text':text, 'expedition':expedition, 'cave':cave, 'slug':slugify(title)[:50]}
- lbo, created=save_carefully(models.LogbookEntry, lookupAttribs, nonLookupAttribs)
-
- for tripperson, time_underground in trippersons:
- lookupAttribs={'personexpedition':tripperson, 'logbook_entry':lbo}
- nonLookupAttribs={'time_underground':time_underground, 'is_logbook_entry_author':(tripperson == author)}
- #print nonLookupAttribs
- save_carefully(models.PersonTrip, lookupAttribs, nonLookupAttribs)
-
-
-def ParseDate(tripdate, year):
- """ Interprets dates in the expo logbooks and returns a correct datetime.date object """
- mdatestandard = re.match("(\d\d\d\d)-(\d\d)-(\d\d)", tripdate)
- mdategoof = re.match("(\d\d?)/0?(\d)/(20|19)?(\d\d)", tripdate)
- if mdatestandard:
- assert mdatestandard.group(1) == year, (tripdate, year)
- year, month, day = int(mdatestandard.group(1)), int(mdatestandard.group(2)), int(mdatestandard.group(3))
- elif mdategoof:
- assert not mdategoof.group(3) or mdategoof.group(3) == year[:2], mdategoof.groups()
- yadd = int(year[:2]) * 100
- day, month, year = int(mdategoof.group(1)), int(mdategoof.group(2)), int(mdategoof.group(4)) + yadd
- else:
- assert False, tripdate
- return datetime.date(year, month, day)
-
-# 2007, 2008, 2006
-def Parselogwikitxt(year, expedition, txt):
- trippara = re.findall("===(.*?)===([\s\S]*?)(?====)", txt)
- for triphead, triptext in trippara:
- tripheadp = triphead.split("|")
- #print "ttt", tripheadp
- assert len(tripheadp) == 3, (tripheadp, triptext)
- tripdate, tripplace, trippeople = tripheadp
- tripsplace = tripplace.split(" - ")
- tripcave = tripsplace[0].strip()
-
- tul = re.findall("T/?U:?\s*(\d+(?:\.\d*)?|unknown)\s*(hrs|hours)?", triptext)
- if tul:
- #assert len(tul) <= 1, (triphead, triptext)
- #assert tul[0][1] in ["hrs", "hours"], (triphead, triptext)
- tu = tul[0][0]
- else:
- tu = ""
- #assert tripcave == "Journey", (triphead, triptext)
-
- #print tripdate
- ldate = ParseDate(tripdate.strip(), year)
- #print "\n", tripcave, "--- ppp", trippeople, len(triptext)
- EnterLogIntoDbase(date = ldate, place = tripcave, title = tripplace, text = triptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
-
-# 2002, 2004, 2005
-def Parseloghtmltxt(year, expedition, txt):
- tripparas = re.findall("<hr\s*/>([\s\S]*?)(?=<hr)", txt)
- for trippara in tripparas:
-
- s = re.match('''(?x)(?:\s*<div\sclass="tripdate"\sid=".*?">.*?</div>\s*<p>)? # second date
- \s*(?:<a\s+id="(.*?)"\s*/>\s*</a>)?
- \s*<div\s+class="tripdate"\s*(?:id="(.*?)")?>(.*?)</div>(?:<p>)?
- \s*<div\s+class="trippeople">\s*(.*?)</div>
- \s*<div\s+class="triptitle">\s*(.*?)</div>
- ([\s\S]*?)
- \s*(?:<div\s+class="timeug">\s*(.*?)</div>)?
- \s*$
- ''', trippara)
- if not s:
- if not re.search("Rigging Guide", trippara):
- print "can't parse: ", trippara # this is 2007 which needs editing
- #assert s, trippara
- continue
-
- tripid, tripid1, tripdate, trippeople, triptitle, triptext, tu = s.groups()
- ldate = ParseDate(tripdate.strip(), year)
- #assert tripid[:-1] == "t" + tripdate, (tripid, tripdate)
- trippeople = re.sub("Ol(?!l)", "Olly", trippeople)
- trippeople = re.sub("Wook(?!e)", "Wookey", trippeople)
- triptitles = triptitle.split(" - ")
- if len(triptitles) >= 2:
- tripcave = triptitles[0]
- else:
- tripcave = "UNKNOWN"
- #print "\n", tripcave, "--- ppp", trippeople, len(triptext)
- ltriptext = re.sub("</p>", "", triptext)
- ltriptext = re.sub("\s*?\n\s*", " ", ltriptext)
- ltriptext = re.sub("<p>", "\n\n", ltriptext).strip()
- EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle, text = ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
-
-
-# main parser for pre-2001. simpler because the data has been hacked so much to fit it
-def Parseloghtml01(year, expedition, txt):
- tripparas = re.findall("<hr[\s/]*>([\s\S]*?)(?=<hr)", txt)
- for trippara in tripparas:
- s = re.match(u"(?s)\s*(?:<p>)?(.*?)</?p>(.*)$(?i)", trippara)
- assert s, trippara[:300]
- tripheader, triptext = s.group(1), s.group(2)
- mtripid = re.search('<a id="(.*?)"', tripheader)
- tripid = mtripid and mtripid.group(1) or ""
- tripheader = re.sub("</?(?:[ab]|span)[^>]*>", "", tripheader)
-
- #print " ", [tripheader]
- #continue
-
- tripdate, triptitle, trippeople = tripheader.split("|")
- ldate = ParseDate(tripdate.strip(), year)
-
- mtu = re.search('<p[^>]*>(T/?U.*)', triptext)
- if mtu:
- tu = mtu.group(1)
- triptext = triptext[:mtu.start(0)] + triptext[mtu.end():]
- else:
- tu = ""
-
- triptitles = triptitle.split(" - ")
- tripcave = triptitles[0].strip()
-
- ltriptext = triptext
-
- mtail = re.search('(?:<a href="[^"]*">[^<]*</a>|\s|/|-|&|</?p>|\((?:same day|\d+)\))*$', ltriptext)
- if mtail:
- #print mtail.group(0)
- ltriptext = ltriptext[:mtail.start(0)]
- ltriptext = re.sub("</p>", "", ltriptext)
- ltriptext = re.sub("\s*?\n\s*", " ", ltriptext)
- ltriptext = re.sub("<p>|<br>", "\n\n", ltriptext).strip()
- #ltriptext = re.sub("[^\s0-9a-zA-Z\-.,:;'!]", "NONASCII", ltriptext)
- ltriptext = re.sub("</?u>", "_", ltriptext)
- ltriptext = re.sub("</?i>", "''", ltriptext)
- ltriptext = re.sub("</?b>", "'''", ltriptext)
-
-
- #print ldate, trippeople.strip()
- # could includ the tripid (url link for cross referencing)
- EnterLogIntoDbase(date=ldate, place=tripcave, title=triptitle, text=ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
-
-
-def Parseloghtml03(year, expedition, txt):
- tripparas = re.findall("<hr\s*/>([\s\S]*?)(?=<hr)", txt)
- for trippara in tripparas:
- s = re.match(u"(?s)\s*<p>(.*?)</p>(.*)$", trippara)
- assert s, trippara
- tripheader, triptext = s.group(1), s.group(2)
- tripheader = re.sub(" ", " ", tripheader)
- tripheader = re.sub("\s+", " ", tripheader).strip()
- sheader = tripheader.split(" -- ")
- tu = ""
- if re.match("T/U|Time underwater", sheader[-1]):
- tu = sheader.pop()
- if len(sheader) != 3:
- print "header not three pieces", sheader
- tripdate, triptitle, trippeople = sheader
- ldate = ParseDate(tripdate.strip(), year)
- triptitles = triptitle.split(" , ")
- if len(triptitles) >= 2:
- tripcave = triptitles[0]
- else:
- tripcave = "UNKNOWN"
- #print tripcave, "--- ppp", triptitle, trippeople, len(triptext)
- ltriptext = re.sub("</p>", "", triptext)
- ltriptext = re.sub("\s*?\n\s*", " ", ltriptext)
- ltriptext = re.sub("<p>", "\n\n", ltriptext).strip()
- ltriptext = re.sub("[^\s0-9a-zA-Z\-.,:;'!&()\[\]<>?=+*%]", "_NONASCII_", ltriptext)
- EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle, text = ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
-
-yearlinks = [
- ("2009", "2009/2009logbook.txt", Parselogwikitxt),
- ("2008", "2008/2008logbook.txt", Parselogwikitxt),
- ("2007", "2007/logbook.html", Parseloghtmltxt),
- ("2006", "2006/logbook/logbook_06.txt", Parselogwikitxt),
- ("2005", "2005/logbook.html", Parseloghtmltxt),
- ("2004", "2004/logbook.html", Parseloghtmltxt),
- ("2003", "2003/logbook.html", Parseloghtml03),
- ("2002", "2002/logbook.html", Parseloghtmltxt),
- ("2001", "2001/log.htm", Parseloghtml01),
- ("2000", "2000/log.htm", Parseloghtml01),
- ("1999", "1999/log.htm", Parseloghtml01),
- ("1998", "1998/log.htm", Parseloghtml01),
- ("1997", "1997/log.htm", Parseloghtml01),
- ("1996", "1996/log.htm", Parseloghtml01),
- ("1995", "1995/log.htm", Parseloghtml01),
- ("1994", "1994/log.htm", Parseloghtml01),
- ("1993", "1993/log.htm", Parseloghtml01),
- ("1992", "1992/log.htm", Parseloghtml01),
- ("1991", "1991/log.htm", Parseloghtml01),
- ]
-
-def SetDatesFromLogbookEntries(expedition):
- """
- Sets the date_from and date_to field for an expedition based on persontrips.
- Then sets the expedition date_from and date_to based on the personexpeditions.
- """
- for personexpedition in expedition.personexpedition_set.all():
- persontrips = personexpedition.persontrip_set.order_by('logbook_entry__date')
- # sequencing is difficult to do
- lprevpersontrip = None
- for persontrip in persontrips:
- persontrip.persontrip_prev = lprevpersontrip
- if lprevpersontrip:
- lprevpersontrip.persontrip_next = persontrip
- lprevpersontrip.save()
- persontrip.persontrip_next = None
- lprevpersontrip = persontrip
- persontrip.save()
-
-
-
-def LoadLogbookForExpedition(expedition):
- """ Parses all logbook entries for one expedition """
-
- expowebbase = os.path.join(settings.EXPOWEB, "years")
- year = str(expedition.year)
- for lyear, lloc, parsefunc in yearlinks:
- if lyear == year:
- break
- fin = open(os.path.join(expowebbase, lloc))
- print "opennning", lloc
- txt = fin.read().decode("latin1")
- fin.close()
- parsefunc(year, expedition, txt)
- SetDatesFromLogbookEntries(expedition)
- return "TOLOAD: " + year + " " + str(expedition.personexpedition_set.all()[1].logbookentry_set.count()) + " " + str(models.PersonTrip.objects.filter(personexpedition__expedition=expedition).count())
-
-
-def LoadLogbooks():
- """ This is the master function for parsing all logbooks into the Troggle database. Requires yearlinks, which is a list of tuples for each expedition with expedition year, logbook path, and parsing function. """
-
- #Deletion has been moved to a seperate function to enable the non-destructive importing
- #models.LogbookEntry.objects.all().delete()
- expowebbase = os.path.join(settings.EXPOWEB, "years")
- #yearlinks = [ ("2001", "2001/log.htm", Parseloghtml01), ] #overwrite
- #yearlinks = [ ("1996", "1996/log.htm", Parseloghtml01),] # overwrite
-
- for year, lloc, parsefunc in yearlinks:
- expedition = models.Expedition.objects.filter(year = year)[0]
- fin = open(os.path.join(expowebbase, lloc))
- txt = fin.read().decode("latin1")
- fin.close()
- parsefunc(year, expedition, txt)
- SetDatesFromLogbookEntries(expedition)
-
-dateRegex = re.compile('<span\s+class="date">(\d\d\d\d)-(\d\d)-(\d\d)</span>', re.S)
-expeditionYearRegex = re.compile('<span\s+class="expeditionyear">(.*?)</span>', re.S)
-titleRegex = re.compile('<H1>(.*?)</H1>', re.S)
-reportRegex = re.compile('<div\s+class="report">(.*)</div>\s*</body>', re.S)
-personRegex = re.compile('<div\s+class="person">(.*?)</div>', re.S)
-nameAuthorRegex = re.compile('<span\s+class="name(,author|)">(.*?)</span>', re.S)
-TURegex = re.compile('<span\s+class="TU">([0-9]*\.?[0-9]+)</span>', re.S)
-locationRegex = re.compile('<span\s+class="location">(.*?)</span>', re.S)
-caveRegex = re.compile('<span\s+class="cave">(.*?)</span>', re.S)
-
-def parseAutoLogBookEntry(filename):
- errors = []
- f = open(filename, "r")
- contents = f.read()
- f.close()
-
- dateMatch = dateRegex.search(contents)
- if dateMatch:
- year, month, day = [int(x) for x in dateMatch.groups()]
- date = datetime.date(year, month, day)
- else:
- errors.append("Date could not be found")
-
- expeditionYearMatch = expeditionYearRegex.search(contents)
- if expeditionYearMatch:
- try:
- expedition = models.Expedition.objects.get(year = expeditionYearMatch.groups()[0])
- personExpeditionNameLookup = GetPersonExpeditionNameLookup(expedition)
- except models.Expedition.DoesNotExist:
- errors.append("Expedition not in database")
- else:
- errors.append("Expediton Year could not be parsed")
-
- titleMatch = titleRegex.search(contents)
- if titleMatch:
- title, = titleMatch.groups()
- if len(title) > settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH:
- errors.append("Title too long")
- else:
- errors.append("Title could not be found")
-
- caveMatch = caveRegex.search(contents)
- if caveMatch:
- caveRef, = caveMatch.groups()
- try:
- cave = models.getCaveByReference(caveRef)
- except AssertionError:
- cave = None
- errors.append("Cave not found in database")
- else:
- cave = None
-
- locationMatch = locationRegex.search(contents)
- if locationMatch:
- location, = locationMatch.groups()
- else:
- location = None
-
- if cave is None and location is None:
- errors.append("Location nor cave could not be found")
-
- reportMatch = reportRegex.search(contents)
- if reportMatch:
- report, = reportMatch.groups()
- else:
- errors.append("Contents could not be found")
- if errors:
- return errors # Easiest to bail out at this point as we need to make sure that we know which expedition to look for people from.
- people = []
- for personMatch in personRegex.findall(contents):
- nameAuthorMatch = nameAuthorRegex.search(contents)
- if nameAuthorMatch:
- author, name = nameAuthorMatch.groups()
- if name.lower() in personExpeditionNameLookup:
- personExpo = personExpeditionNameLookup[name.lower()]
- else:
- errors.append("Person could not be found in database")
- author = bool(author)
- else:
- errors.append("Persons name could not be found")
-
- TUMatch = TURegex.search(contents)
- if TUMatch:
- TU, = TUMatch.groups()
- else:
- errors.append("TU could not be found")
- if not errors:
- people.append((name, author, TU))
- if errors:
- return errors # Bail out before commiting to the database
- logbookEntry = models.LogbookEntry(date = date,
- expedition = expedition,
- title = title, cave = cave, place = location,
- text = report, slug = slugify(title)[:50],
- filename = filename)
- logbookEntry.save()
- for name, author, TU in people:
- models.PersonTrip(personexpedition = personExpo,
- time_underground = TU,
- logbook_entry = logbookEntry,
- is_logbook_entry_author = author).save()
- print logbookEntry
+#.-*- coding: utf-8 -*- + +from django.conf import settings +import core.models as models + +from parsers.people import GetPersonExpeditionNameLookup +from parsers.cavetab import GetCaveLookup + +from django.template.defaultfilters import slugify + +import csv +import re +import datetime +import os + +from utils import save_carefully + +# +# When we edit logbook entries, allow a "?" after any piece of data to say we've frigged it and +# it can be checked up later from the hard-copy if necessary; or it's not possible to determin (name, trip place, etc) +# + +# +# the logbook loading section +# +def GetTripPersons(trippeople, expedition, logtime_underground): + res = [ ] + author = None + for tripperson in re.split(",|\+|&|&(?!\w+;)| and ", trippeople): + tripperson = tripperson.strip() + mul = re.match("<u>(.*?)</u>$(?i)", tripperson) + if mul: + tripperson = mul.group(1).strip() + if tripperson and tripperson[0] != '*': + #assert tripperson in personyearmap, "'%s' << %s\n\n %s" % (tripperson, trippeople, personyearmap) + personyear = GetPersonExpeditionNameLookup(expedition).get(tripperson.lower()) + if not personyear: + print "NoMatchFor: '%s'" % tripperson + res.append((personyear, logtime_underground)) + if mul: + author = personyear + if not author: + if not res: + return None, None + author = res[-1][0] + return res, author + +def GetTripCave(place): #need to be fuzzier about matching here. Already a very slow function... +# print "Getting cave for " , place + try: + katastNumRes=[] + katastNumRes=list(models.Cave.objects.filter(kataster_number=int(place))) + except ValueError: + pass + officialNameRes=list(models.Cave.objects.filter(official_name=place)) + tripCaveRes=officialNameRes+katastNumRes + + if len(tripCaveRes)==1: +# print "Place " , place , "entered as" , tripCaveRes[0] + return tripCaveRes[0] + + elif models.OtherCaveName.objects.filter(name=place): + tripCaveRes=models.OtherCaveName.objects.filter(name__icontains=place)[0].cave +# print "Place " , place , "entered as" , tripCaveRes + return tripCaveRes + + elif len(tripCaveRes)>1: + print "Ambiguous place " + str(place) + " entered. Choose from " + str(tripCaveRes) + correctIndex=input("type list index of correct cave") + return tripCaveRes[correctIndex] + else: + print "No cave found for place " , place + return + + +noncaveplaces = [ "Journey", "Loser Plateau" ] +def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_underground): + """ saves a logbook entry and related persontrips """ + trippersons, author = GetTripPersons(trippeople, expedition, logtime_underground) + if not author: + print "skipping logentry", title + return + +# tripCave = GetTripCave(place) + # + lplace = place.lower() + if lplace not in noncaveplaces: + cave=GetCaveLookup().get(lplace) + + #Check for an existing copy of the current entry, and save + expeditionday = expedition.get_expedition_day(date) + lookupAttribs={'date':date, 'title':title} + nonLookupAttribs={'place':place, 'text':text, 'expedition':expedition, 'cave':cave, 'slug':slugify(title)[:50]} + lbo, created=save_carefully(models.LogbookEntry, lookupAttribs, nonLookupAttribs) + + for tripperson, time_underground in trippersons: + lookupAttribs={'personexpedition':tripperson, 'logbook_entry':lbo} + nonLookupAttribs={'time_underground':time_underground, 'is_logbook_entry_author':(tripperson == author)} + #print nonLookupAttribs + save_carefully(models.PersonTrip, lookupAttribs, nonLookupAttribs) + + +def ParseDate(tripdate, year): + """ Interprets dates in the expo logbooks and returns a correct datetime.date object """ + mdatestandard = re.match("(\d\d\d\d)-(\d\d)-(\d\d)", tripdate) + mdategoof = re.match("(\d\d?)/0?(\d)/(20|19)?(\d\d)", tripdate) + if mdatestandard: + assert mdatestandard.group(1) == year, (tripdate, year) + year, month, day = int(mdatestandard.group(1)), int(mdatestandard.group(2)), int(mdatestandard.group(3)) + elif mdategoof: + assert not mdategoof.group(3) or mdategoof.group(3) == year[:2], mdategoof.groups() + yadd = int(year[:2]) * 100 + day, month, year = int(mdategoof.group(1)), int(mdategoof.group(2)), int(mdategoof.group(4)) + yadd + else: + assert False, tripdate + return datetime.date(year, month, day) + +# 2007, 2008, 2006 +def Parselogwikitxt(year, expedition, txt): + trippara = re.findall("===(.*?)===([\s\S]*?)(?====)", txt) + for triphead, triptext in trippara: + tripheadp = triphead.split("|") + #print "ttt", tripheadp + assert len(tripheadp) == 3, (tripheadp, triptext) + tripdate, tripplace, trippeople = tripheadp + tripsplace = tripplace.split(" - ") + tripcave = tripsplace[0].strip() + + tul = re.findall("T/?U:?\s*(\d+(?:\.\d*)?|unknown)\s*(hrs|hours)?", triptext) + if tul: + #assert len(tul) <= 1, (triphead, triptext) + #assert tul[0][1] in ["hrs", "hours"], (triphead, triptext) + tu = tul[0][0] + else: + tu = "" + #assert tripcave == "Journey", (triphead, triptext) + + #print tripdate + ldate = ParseDate(tripdate.strip(), year) + #print "\n", tripcave, "--- ppp", trippeople, len(triptext) + EnterLogIntoDbase(date = ldate, place = tripcave, title = tripplace, text = triptext, trippeople=trippeople, expedition=expedition, logtime_underground=0) + +# 2002, 2004, 2005 +def Parseloghtmltxt(year, expedition, txt): + tripparas = re.findall("<hr\s*/>([\s\S]*?)(?=<hr)", txt) + for trippara in tripparas: + + s = re.match('''(?x)(?:\s*<div\sclass="tripdate"\sid=".*?">.*?</div>\s*<p>)? # second date + \s*(?:<a\s+id="(.*?)"\s*/>\s*</a>)? + \s*<div\s+class="tripdate"\s*(?:id="(.*?)")?>(.*?)</div>(?:<p>)? + \s*<div\s+class="trippeople">\s*(.*?)</div> + \s*<div\s+class="triptitle">\s*(.*?)</div> + ([\s\S]*?) + \s*(?:<div\s+class="timeug">\s*(.*?)</div>)? + \s*$ + ''', trippara) + if not s: + if not re.search("Rigging Guide", trippara): + print "can't parse: ", trippara # this is 2007 which needs editing + #assert s, trippara + continue + + tripid, tripid1, tripdate, trippeople, triptitle, triptext, tu = s.groups() + ldate = ParseDate(tripdate.strip(), year) + #assert tripid[:-1] == "t" + tripdate, (tripid, tripdate) + trippeople = re.sub("Ol(?!l)", "Olly", trippeople) + trippeople = re.sub("Wook(?!e)", "Wookey", trippeople) + triptitles = triptitle.split(" - ") + if len(triptitles) >= 2: + tripcave = triptitles[0] + else: + tripcave = "UNKNOWN" + #print "\n", tripcave, "--- ppp", trippeople, len(triptext) + ltriptext = re.sub("</p>", "", triptext) + ltriptext = re.sub("\s*?\n\s*", " ", ltriptext) + ltriptext = re.sub("<p>", "\n\n", ltriptext).strip() + EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle, text = ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0) + + +# main parser for pre-2001. simpler because the data has been hacked so much to fit it +def Parseloghtml01(year, expedition, txt): + tripparas = re.findall("<hr[\s/]*>([\s\S]*?)(?=<hr)", txt) + for trippara in tripparas: + s = re.match(u"(?s)\s*(?:<p>)?(.*?)</?p>(.*)$(?i)", trippara) + assert s, trippara[:300] + tripheader, triptext = s.group(1), s.group(2) + mtripid = re.search('<a id="(.*?)"', tripheader) + tripid = mtripid and mtripid.group(1) or "" + tripheader = re.sub("</?(?:[ab]|span)[^>]*>", "", tripheader) + + #print " ", [tripheader] + #continue + + tripdate, triptitle, trippeople = tripheader.split("|") + ldate = ParseDate(tripdate.strip(), year) + + mtu = re.search('<p[^>]*>(T/?U.*)', triptext) + if mtu: + tu = mtu.group(1) + triptext = triptext[:mtu.start(0)] + triptext[mtu.end():] + else: + tu = "" + + triptitles = triptitle.split(" - ") + tripcave = triptitles[0].strip() + + ltriptext = triptext + + mtail = re.search('(?:<a href="[^"]*">[^<]*</a>|\s|/|-|&|</?p>|\((?:same day|\d+)\))*$', ltriptext) + if mtail: + #print mtail.group(0) + ltriptext = ltriptext[:mtail.start(0)] + ltriptext = re.sub("</p>", "", ltriptext) + ltriptext = re.sub("\s*?\n\s*", " ", ltriptext) + ltriptext = re.sub("<p>|<br>", "\n\n", ltriptext).strip() + #ltriptext = re.sub("[^\s0-9a-zA-Z\-.,:;'!]", "NONASCII", ltriptext) + ltriptext = re.sub("</?u>", "_", ltriptext) + ltriptext = re.sub("</?i>", "''", ltriptext) + ltriptext = re.sub("</?b>", "'''", ltriptext) + + + #print ldate, trippeople.strip() + # could includ the tripid (url link for cross referencing) + EnterLogIntoDbase(date=ldate, place=tripcave, title=triptitle, text=ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0) + + +def Parseloghtml03(year, expedition, txt): + tripparas = re.findall("<hr\s*/>([\s\S]*?)(?=<hr)", txt) + for trippara in tripparas: + s = re.match(u"(?s)\s*<p>(.*?)</p>(.*)$", trippara) + assert s, trippara + tripheader, triptext = s.group(1), s.group(2) + tripheader = re.sub(" ", " ", tripheader) + tripheader = re.sub("\s+", " ", tripheader).strip() + sheader = tripheader.split(" -- ") + tu = "" + if re.match("T/U|Time underwater", sheader[-1]): + tu = sheader.pop() + if len(sheader) != 3: + print "header not three pieces", sheader + tripdate, triptitle, trippeople = sheader + ldate = ParseDate(tripdate.strip(), year) + triptitles = triptitle.split(" , ") + if len(triptitles) >= 2: + tripcave = triptitles[0] + else: + tripcave = "UNKNOWN" + #print tripcave, "--- ppp", triptitle, trippeople, len(triptext) + ltriptext = re.sub("</p>", "", triptext) + ltriptext = re.sub("\s*?\n\s*", " ", ltriptext) + ltriptext = re.sub("<p>", "\n\n", ltriptext).strip() + ltriptext = re.sub("[^\s0-9a-zA-Z\-.,:;'!&()\[\]<>?=+*%]", "_NONASCII_", ltriptext) + EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle, text = ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0) + +yearlinks = [ + ("2009", "2009/2009logbook.txt", Parselogwikitxt), + ("2008", "2008/2008logbook.txt", Parselogwikitxt), + ("2007", "2007/logbook.html", Parseloghtmltxt), + ("2006", "2006/logbook/logbook_06.txt", Parselogwikitxt), + ("2005", "2005/logbook.html", Parseloghtmltxt), + ("2004", "2004/logbook.html", Parseloghtmltxt), + ("2003", "2003/logbook.html", Parseloghtml03), + ("2002", "2002/logbook.html", Parseloghtmltxt), + ("2001", "2001/log.htm", Parseloghtml01), + ("2000", "2000/log.htm", Parseloghtml01), + ("1999", "1999/log.htm", Parseloghtml01), + ("1998", "1998/log.htm", Parseloghtml01), + ("1997", "1997/log.htm", Parseloghtml01), + ("1996", "1996/log.htm", Parseloghtml01), + ("1995", "1995/log.htm", Parseloghtml01), + ("1994", "1994/log.htm", Parseloghtml01), + ("1993", "1993/log.htm", Parseloghtml01), + ("1992", "1992/log.htm", Parseloghtml01), + ("1991", "1991/log.htm", Parseloghtml01), + ] + +def SetDatesFromLogbookEntries(expedition): + """ + Sets the date_from and date_to field for an expedition based on persontrips. + Then sets the expedition date_from and date_to based on the personexpeditions. + """ + for personexpedition in expedition.personexpedition_set.all(): + persontrips = personexpedition.persontrip_set.order_by('logbook_entry__date') + # sequencing is difficult to do + lprevpersontrip = None + for persontrip in persontrips: + persontrip.persontrip_prev = lprevpersontrip + if lprevpersontrip: + lprevpersontrip.persontrip_next = persontrip + lprevpersontrip.save() + persontrip.persontrip_next = None + lprevpersontrip = persontrip + persontrip.save() + + + +def LoadLogbookForExpedition(expedition): + """ Parses all logbook entries for one expedition """ + + expowebbase = os.path.join(settings.EXPOWEB, "years") + year = str(expedition.year) + for lyear, lloc, parsefunc in yearlinks: + if lyear == year: + break + fin = open(os.path.join(expowebbase, lloc)) + print "opennning", lloc + txt = fin.read().decode("latin1") + fin.close() + parsefunc(year, expedition, txt) + SetDatesFromLogbookEntries(expedition) + return "TOLOAD: " + year + " " + str(expedition.personexpedition_set.all()[1].logbookentry_set.count()) + " " + str(models.PersonTrip.objects.filter(personexpedition__expedition=expedition).count()) + + +def LoadLogbooks(): + """ This is the master function for parsing all logbooks into the Troggle database. Requires yearlinks, which is a list of tuples for each expedition with expedition year, logbook path, and parsing function. """ + + #Deletion has been moved to a seperate function to enable the non-destructive importing + #models.LogbookEntry.objects.all().delete() + expowebbase = os.path.join(settings.EXPOWEB, "years") + #yearlinks = [ ("2001", "2001/log.htm", Parseloghtml01), ] #overwrite + #yearlinks = [ ("1996", "1996/log.htm", Parseloghtml01),] # overwrite + + for year, lloc, parsefunc in yearlinks: + expedition = models.Expedition.objects.filter(year = year)[0] + fin = open(os.path.join(expowebbase, lloc)) + txt = fin.read().decode("latin1") + fin.close() + parsefunc(year, expedition, txt) + SetDatesFromLogbookEntries(expedition) + +dateRegex = re.compile('<span\s+class="date">(\d\d\d\d)-(\d\d)-(\d\d)</span>', re.S) +expeditionYearRegex = re.compile('<span\s+class="expeditionyear">(.*?)</span>', re.S) +titleRegex = re.compile('<H1>(.*?)</H1>', re.S) +reportRegex = re.compile('<div\s+class="report">(.*)</div>\s*</body>', re.S) +personRegex = re.compile('<div\s+class="person">(.*?)</div>', re.S) +nameAuthorRegex = re.compile('<span\s+class="name(,author|)">(.*?)</span>', re.S) +TURegex = re.compile('<span\s+class="TU">([0-9]*\.?[0-9]+)</span>', re.S) +locationRegex = re.compile('<span\s+class="location">(.*?)</span>', re.S) +caveRegex = re.compile('<span\s+class="cave">(.*?)</span>', re.S) + +def parseAutoLogBookEntry(filename): + errors = [] + f = open(filename, "r") + contents = f.read() + f.close() + + dateMatch = dateRegex.search(contents) + if dateMatch: + year, month, day = [int(x) for x in dateMatch.groups()] + date = datetime.date(year, month, day) + else: + errors.append("Date could not be found") + + expeditionYearMatch = expeditionYearRegex.search(contents) + if expeditionYearMatch: + try: + expedition = models.Expedition.objects.get(year = expeditionYearMatch.groups()[0]) + personExpeditionNameLookup = GetPersonExpeditionNameLookup(expedition) + except models.Expedition.DoesNotExist: + errors.append("Expedition not in database") + else: + errors.append("Expediton Year could not be parsed") + + titleMatch = titleRegex.search(contents) + if titleMatch: + title, = titleMatch.groups() + if len(title) > settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH: + errors.append("Title too long") + else: + errors.append("Title could not be found") + + caveMatch = caveRegex.search(contents) + if caveMatch: + caveRef, = caveMatch.groups() + try: + cave = models.getCaveByReference(caveRef) + except AssertionError: + cave = None + errors.append("Cave not found in database") + else: + cave = None + + locationMatch = locationRegex.search(contents) + if locationMatch: + location, = locationMatch.groups() + else: + location = None + + if cave is None and location is None: + errors.append("Location nor cave could not be found") + + reportMatch = reportRegex.search(contents) + if reportMatch: + report, = reportMatch.groups() + else: + errors.append("Contents could not be found") + if errors: + return errors # Easiest to bail out at this point as we need to make sure that we know which expedition to look for people from. + people = [] + for personMatch in personRegex.findall(contents): + nameAuthorMatch = nameAuthorRegex.search(contents) + if nameAuthorMatch: + author, name = nameAuthorMatch.groups() + if name.lower() in personExpeditionNameLookup: + personExpo = personExpeditionNameLookup[name.lower()] + else: + errors.append("Person could not be found in database") + author = bool(author) + else: + errors.append("Persons name could not be found") + + TUMatch = TURegex.search(contents) + if TUMatch: + TU, = TUMatch.groups() + else: + errors.append("TU could not be found") + if not errors: + people.append((name, author, TU)) + if errors: + return errors # Bail out before commiting to the database + logbookEntry = models.LogbookEntry(date = date, + expedition = expedition, + title = title, cave = cave, place = location, + text = report, slug = slugify(title)[:50], + filename = filename) + logbookEntry.save() + for name, author, TU in people: + models.PersonTrip(personexpedition = personExpo, + time_underground = TU, + logbook_entry = logbookEntry, + is_logbook_entry_author = author).save() + print logbookEntry diff --git a/parsers/subcaves.py b/parsers/subcaves.py index bdd64a1..6905d0a 100644 --- a/parsers/subcaves.py +++ b/parsers/subcaves.py @@ -1,56 +1,56 @@ -'''
-This module is the part of troggle that parses descriptions of cave parts (subcaves) from the legacy html files and saves them in the troggle database as instances of the model Subcave. Unfortunately, this parser can not be very flexible because the legacy format is poorly structured.
-'''
-
-import sys, os
-
-import os, re, logging
-from django.conf import settings
-from core.models import Subcave, Cave
-from utils import save_carefully
-
-def getLinksInCaveDescription(cave):
- '''
- Returns all HTML <a href> tags from a given cave as a list of tuples
- in the format ('filename.html','Description')
- '''
- pattern='<a href=\"(.*?)\">(.*?)</a>'
- if cave.underground_description:
- return re.findall(pattern,cave.underground_description)
- else:
- return []
-
-def importSubcaves(cave):
- for link in getLinksInCaveDescription(cave):
- try:
- subcaveFilePath=os.path.join(
- settings.EXPOWEB,
- os.path.dirname(cave.description_file),
- link[0])
- subcaveFile=open(subcaveFilePath,'r')
- description=subcaveFile.read().decode('iso-8859-1').encode('utf-8')
-
- lookupAttribs={'title':link[1], 'cave':cave}
- nonLookupAttribs={'description':description}
- newSubcave=save_carefully(Subcave,lookupAttribs=lookupAttribs,nonLookupAttribs=nonLookupAttribs)
-
- logging.info("Added " + unicode(newSubcave) + " to " + unicode(cave))
- except IOError:
- logging.info("Subcave import couldn't open "+subcaveFilePath)
-
-def getLinksInSubcaveDescription(subcave):
- pattern='<a href=\"(.*?)\">(.*?)</a>'
- if subcave.description:
- return re.findall(pattern,subcave.description)
- else:
- return []
-
-def getLinksInAllSubcaves():
- bigList=[]
- for subcave in Subcave.objects.all():
- bigList+=getLinksInSubcaveDescription(subcave)
- return bigList
-
-def importAllSubcaves():
- for cave in Cave.objects.all():
- importSubcaves(cave)
+''' +This module is the part of troggle that parses descriptions of cave parts (subcaves) from the legacy html files and saves them in the troggle database as instances of the model Subcave. Unfortunately, this parser can not be very flexible because the legacy format is poorly structured. +''' + +import sys, os + +import os, re, logging +from django.conf import settings +from core.models import Subcave, Cave +from utils import save_carefully + +def getLinksInCaveDescription(cave): + ''' + Returns all HTML <a href> tags from a given cave as a list of tuples + in the format ('filename.html','Description') + ''' + pattern='<a href=\"(.*?)\">(.*?)</a>' + if cave.underground_description: + return re.findall(pattern,cave.underground_description) + else: + return [] + +def importSubcaves(cave): + for link in getLinksInCaveDescription(cave): + try: + subcaveFilePath=os.path.join( + settings.EXPOWEB, + os.path.dirname(cave.description_file), + link[0]) + subcaveFile=open(subcaveFilePath,'r') + description=subcaveFile.read().decode('iso-8859-1').encode('utf-8') + + lookupAttribs={'title':link[1], 'cave':cave} + nonLookupAttribs={'description':description} + newSubcave=save_carefully(Subcave,lookupAttribs=lookupAttribs,nonLookupAttribs=nonLookupAttribs) + + logging.info("Added " + unicode(newSubcave) + " to " + unicode(cave)) + except IOError: + logging.info("Subcave import couldn't open "+subcaveFilePath) + +def getLinksInSubcaveDescription(subcave): + pattern='<a href=\"(.*?)\">(.*?)</a>' + if subcave.description: + return re.findall(pattern,subcave.description) + else: + return [] + +def getLinksInAllSubcaves(): + bigList=[] + for subcave in Subcave.objects.all(): + bigList+=getLinksInSubcaveDescription(subcave) + return bigList + +def importAllSubcaves(): + for cave in Cave.objects.all(): + importSubcaves(cave) diff --git a/parsers/surveys.py b/parsers/surveys.py index 4ac5067..0c6eb4b 100644 --- a/parsers/surveys.py +++ b/parsers/surveys.py @@ -1,301 +1,301 @@ -import sys, os, types, logging, stat
-#sys.path.append('C:\\Expo\\expoweb')
-#from troggle import *
-#os.environ['DJANGO_SETTINGS_MODULE']='troggle.settings'
-import settings
-from core.models import *
-from PIL import Image
-#import settings
-#import core.models as models
-import csv
-import re
-import datetime
-from utils import save_carefully
-
-def get_or_create_placeholder(year):
- """ All surveys must be related to a logbookentry. We don't have a way to
- automatically figure out which survey went with which logbookentry,
- so we create a survey placeholder logbook entry for each year. This
- function always returns such a placeholder, and creates it if it doesn't
- exist yet.
- """
- lookupAttribs={'date__year':int(year), 'title':"placeholder for surveys",}
- nonLookupAttribs={'text':"surveys temporarily attached to this should be re-attached to their actual trips", 'date':datetime.date(int(year),1,1)}
- placeholder_logbook_entry, newly_created = save_carefully(LogbookEntry, lookupAttribs, nonLookupAttribs)
- return placeholder_logbook_entry
-
-# dead
-def readSurveysFromCSV():
- try: # could probably combine these two
- surveytab = open(os.path.join(settings.SURVEY_SCANS, "Surveys.csv"))
- except IOError:
- import cStringIO, urllib
- surveytab = cStringIO.StringIO(urllib.urlopen(settings.SURVEY_SCANS + "/Surveys.csv").read())
- dialect=csv.Sniffer().sniff(surveytab.read())
- surveytab.seek(0,0)
- surveyreader = csv.reader(surveytab,dialect=dialect)
- headers = surveyreader.next()
- header = dict(zip(headers, range(len(headers)))) #set up a dictionary where the indexes are header names and the values are column numbers
-
- # test if the expeditions have been added yet
- if Expedition.objects.count()==0:
- print "There are no expeditions in the database. Please run the logbook parser."
- sys.exit()
-
-
- logging.info("Deleting all scanned images")
- ScannedImage.objects.all().delete()
-
-
- logging.info("Deleting all survey objects")
- Survey.objects.all().delete()
-
-
- logging.info("Beginning to import surveys from "+str(os.path.join(settings.SURVEYS, "Surveys.csv"))+"\n"+"-"*60+"\n")
-
- for survey in surveyreader:
- #I hate this, but some surveys have a letter eg 2000#34a. The next line deals with that.
- walletNumberLetter = re.match(r'(?P<number>\d*)(?P<letter>[a-zA-Z]*)',survey[header['Survey Number']])
- # print walletNumberLetter.groups()
- year=survey[header['Year']]
-
-
- surveyobj = Survey(
- expedition = Expedition.objects.filter(year=year)[0],
- wallet_number = walletNumberLetter.group('number'),
- logbook_entry = get_or_create_placeholder(year),
- comments = survey[header['Comments']],
- location = survey[header['Location']]
- )
- surveyobj.wallet_letter = walletNumberLetter.group('letter')
- if survey[header['Finished']]=='Yes':
- #try and find the sketch_scan
- pass
- surveyobj.save()
-
-
- logging.info("added survey " + survey[header['Year']] + "#" + surveyobj.wallet_number + "\r")
-
-# dead
-def listdir(*directories):
- try:
- return os.listdir(os.path.join(settings.SURVEYS, *directories))
- except:
- import urllib
- url = settings.SURVEYS + reduce(lambda x, y: x + "/" + y, ["listdir"] + list(directories))
- folders = urllib.urlopen(url.replace("#", "%23")).readlines()
- return [folder.rstrip(r"/") for folder in folders]
-
-# add survey scans
-def parseSurveyScans(year, logfile=None):
-# yearFileList = listdir(year.year)
- yearPath=os.path.join(settings.SURVEY_SCANS, "years", year.year)
- yearFileList=os.listdir(yearPath)
- print yearFileList
- for surveyFolder in yearFileList:
- try:
- surveyNumber=re.match(r'\d\d\d\d#0*(\d+)',surveyFolder).groups()
-# scanList = listdir(year.year, surveyFolder)
- scanList=os.listdir(os.path.join(yearPath,surveyFolder))
- except AttributeError:
- print surveyFolder + " ignored",
- continue
-
- for scan in scanList:
- try:
- scanChopped=re.match(r'(?i).*(notes|elev|plan|elevation|extend)(\d*)\.(png|jpg|jpeg)',scan).groups()
- scanType,scanNumber,scanFormat=scanChopped
- except AttributeError:
- print scan + " ignored \r",
- continue
- if scanType == 'elev' or scanType == 'extend':
- scanType = 'elevation'
-
- if scanNumber=='':
- scanNumber=1
-
- if type(surveyNumber)==types.TupleType:
- surveyNumber=surveyNumber[0]
- try:
- placeholder=get_or_create_placeholder(year=int(year.year))
- survey=Survey.objects.get_or_create(wallet_number=surveyNumber, expedition=year, defaults={'logbook_entry':placeholder})[0]
- except Survey.MultipleObjectsReturned:
- survey=Survey.objects.filter(wallet_number=surveyNumber, expedition=year)[0]
- file=os.path.join(year.year, surveyFolder, scan)
- scanObj = ScannedImage(
- file=file,
- contents=scanType,
- number_in_wallet=scanNumber,
- survey=survey,
- new_since_parsing=False,
- )
- #print "Added scanned image at " + str(scanObj)
- if scanFormat=="png":
- if isInterlacedPNG(os.path.join(settings.SURVEY_SCANS,file)):
- print file + " is an interlaced PNG. No can do."
- continue
- scanObj.save()
-
-# dead
-def parseSurveys(logfile=None):
- readSurveysFromCSV()
- for year in Expedition.objects.filter(year__gte=2000): #expos since 2000, because paths and filenames were nonstandard before then
- parseSurveyScans(year)
-
-# dead
-def isInterlacedPNG(filePath): #We need to check for interlaced PNGs because the thumbnail engine can't handle them (uses PIL)
- file=Image.open(filePath)
- print filePath
- if 'interlace' in file.info:
- return file.info['interlace']
- else:
- return False
-
-
-# handles url or file, so we can refer to a set of scans on another server
-def GetListDir(sdir):
- res = [ ]
- if sdir[:7] == "http://":
- assert False, "Not written"
- s = urllib.urlopen(sdir)
- else:
- for f in os.listdir(sdir):
- if f[0] != ".":
- ff = os.path.join(sdir, f)
- res.append((f, ff, os.path.isdir(ff)))
- return res
-
-
-
-
-
-def LoadListScansFile(survexscansfolder):
- gld = [ ]
-
- # flatten out any directories in these book files
- for (fyf, ffyf, fisdiryf) in GetListDir(survexscansfolder.fpath):
- if fisdiryf:
- gld.extend(GetListDir(ffyf))
- else:
- gld.append((fyf, ffyf, fisdiryf))
-
- for (fyf, ffyf, fisdiryf) in gld:
- assert not fisdiryf, ffyf
- if re.search("\.(?:png|jpg|jpeg)(?i)$", fyf):
- survexscansingle = SurvexScanSingle(ffile=ffyf, name=fyf, survexscansfolder=survexscansfolder)
- survexscansingle.save()
-
-
-# this iterates through the scans directories (either here or on the remote server)
-# and builds up the models we can access later
-def LoadListScans():
- SurvexScanSingle.objects.all().delete()
- SurvexScansFolder.objects.all().delete()
-
- # first do the smkhs (large kh survey scans) directory
- survexscansfoldersmkhs = SurvexScansFolder(fpath=os.path.join(settings.SURVEY_SCANS, "smkhs"), walletname="smkhs")
- if os.path.isdir(survexscansfoldersmkhs.fpath):
- survexscansfoldersmkhs.save()
- LoadListScansFile(survexscansfoldersmkhs)
-
-
- # iterate into the surveyscans directory
- for f, ff, fisdir in GetListDir(os.path.join(settings.SURVEY_SCANS, "surveyscans")):
- if not fisdir:
- continue
-
- # do the year folders
- if re.match("\d\d\d\d$", f):
- for fy, ffy, fisdiry in GetListDir(ff):
- if fisdiry:
- assert fisdiry, ffy
- survexscansfolder = SurvexScansFolder(fpath=ffy, walletname=fy)
- survexscansfolder.save()
- LoadListScansFile(survexscansfolder)
-
- # do the
- elif f != "thumbs":
- survexscansfolder = SurvexScansFolder(fpath=ff, walletname=f)
- survexscansfolder.save()
- LoadListScansFile(survexscansfolder)
-
-
-def FindTunnelScan(tunnelfile, path):
- scansfolder, scansfile = None, None
- mscansdir = re.search("(\d\d\d\d#\d+\w?|1995-96kh|92-94Surveybookkh|1991surveybook|smkhs)/(.*?(?:png|jpg))$", path)
- if mscansdir:
- scansfolderl = SurvexScansFolder.objects.filter(walletname=mscansdir.group(1))
- if len(scansfolderl):
- assert len(scansfolderl) == 1
- scansfolder = scansfolderl[0]
- if scansfolder:
- scansfilel = scansfolder.survexscansingle_set.filter(name=mscansdir.group(2))
- if len(scansfilel):
- assert len(scansfilel) == 1
- scansfile = scansfilel[0]
-
- if scansfolder:
- tunnelfile.survexscansfolders.add(scansfolder)
- if scansfile:
- tunnelfile.survexscans.add(scansfile)
-
- elif path and not re.search("\.(?:png|jpg)$(?i)", path):
- name = os.path.split(path)[1]
- print "ttt", tunnelfile.tunnelpath, path, name
- rtunnelfilel = TunnelFile.objects.filter(tunnelname=name)
- if len(rtunnelfilel):
- assert len(rtunnelfilel) == 1, ("two paths with name of", path, "need more discrimination coded")
- rtunnelfile = rtunnelfilel[0]
- #print "ttt", tunnelfile.tunnelpath, path, name, rtunnelfile.tunnelpath
- tunnelfile.tunnelcontains.add(rtunnelfile)
-
- tunnelfile.save()
-
-
-def SetTunnelfileInfo(tunnelfile):
- ff = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath)
- tunnelfile.filesize = os.stat(ff)[stat.ST_SIZE]
- fin = open(ff)
- ttext = fin.read()
- fin.close()
-
- mtype = re.search("<(fontcolours|sketch)", ttext)
- assert mtype, ff
- tunnelfile.bfontcolours = (mtype.group(1)=="fontcolours")
- tunnelfile.npaths = len(re.findall("<skpath", ttext))
- tunnelfile.save()
-
- # <tunnelxml tunnelversion="version2009-06-21 Matienzo" tunnelproject="ireby" tunneluser="goatchurch" tunneldate="2009-06-29 23:22:17">
- # <pcarea area_signal="frame" sfscaledown="12.282584" sfrotatedeg="-90.76982" sfxtrans="11.676667377221136" sfytrans="-15.677173422877454" sfsketch="204description/scans/plan(38).png" sfstyle="" nodeconnzsetrelative="0.0">
- for path, style in re.findall('<pcarea area_signal="frame".*?sfsketch="([^"]*)" sfstyle="([^"]*)"', ttext):
- FindTunnelScan(tunnelfile, path)
-
- # should also scan and look for survex blocks that might have been included
- # and also survex titles as well.
-
- tunnelfile.save()
-
-
-def LoadTunnelFiles():
- tunneldatadir = settings.TUNNEL_DATA
- TunnelFile.objects.all().delete()
- tunneldirs = [ "" ]
- while tunneldirs:
- tunneldir = tunneldirs.pop()
- for f in os.listdir(os.path.join(tunneldatadir, tunneldir)):
- if f[0] == "." or f[-1] == "~":
- continue
- lf = os.path.join(tunneldir, f)
- ff = os.path.join(tunneldatadir, lf)
- if os.path.isdir(ff):
- tunneldirs.append(lf)
- elif f[-4:] == ".xml":
- tunnelfile = TunnelFile(tunnelpath=lf, tunnelname=os.path.split(f[:-4])[1])
- tunnelfile.save()
-
- for tunnelfile in TunnelFile.objects.all():
- SetTunnelfileInfo(tunnelfile)
-
-
-
-
+import sys, os, types, logging, stat +#sys.path.append('C:\\Expo\\expoweb') +#from troggle import * +#os.environ['DJANGO_SETTINGS_MODULE']='troggle.settings' +import settings +from core.models import * +from PIL import Image +#import settings +#import core.models as models +import csv +import re +import datetime +from utils import save_carefully + +def get_or_create_placeholder(year): + """ All surveys must be related to a logbookentry. We don't have a way to + automatically figure out which survey went with which logbookentry, + so we create a survey placeholder logbook entry for each year. This + function always returns such a placeholder, and creates it if it doesn't + exist yet. + """ + lookupAttribs={'date__year':int(year), 'title':"placeholder for surveys",} + nonLookupAttribs={'text':"surveys temporarily attached to this should be re-attached to their actual trips", 'date':datetime.date(int(year),1,1)} + placeholder_logbook_entry, newly_created = save_carefully(LogbookEntry, lookupAttribs, nonLookupAttribs) + return placeholder_logbook_entry + +# dead +def readSurveysFromCSV(): + try: # could probably combine these two + surveytab = open(os.path.join(settings.SURVEY_SCANS, "Surveys.csv")) + except IOError: + import cStringIO, urllib + surveytab = cStringIO.StringIO(urllib.urlopen(settings.SURVEY_SCANS + "/Surveys.csv").read()) + dialect=csv.Sniffer().sniff(surveytab.read()) + surveytab.seek(0,0) + surveyreader = csv.reader(surveytab,dialect=dialect) + headers = surveyreader.next() + header = dict(zip(headers, range(len(headers)))) #set up a dictionary where the indexes are header names and the values are column numbers + + # test if the expeditions have been added yet + if Expedition.objects.count()==0: + print "There are no expeditions in the database. Please run the logbook parser." + sys.exit() + + + logging.info("Deleting all scanned images") + ScannedImage.objects.all().delete() + + + logging.info("Deleting all survey objects") + Survey.objects.all().delete() + + + logging.info("Beginning to import surveys from "+str(os.path.join(settings.SURVEYS, "Surveys.csv"))+"\n"+"-"*60+"\n") + + for survey in surveyreader: + #I hate this, but some surveys have a letter eg 2000#34a. The next line deals with that. + walletNumberLetter = re.match(r'(?P<number>\d*)(?P<letter>[a-zA-Z]*)',survey[header['Survey Number']]) + # print walletNumberLetter.groups() + year=survey[header['Year']] + + + surveyobj = Survey( + expedition = Expedition.objects.filter(year=year)[0], + wallet_number = walletNumberLetter.group('number'), + logbook_entry = get_or_create_placeholder(year), + comments = survey[header['Comments']], + location = survey[header['Location']] + ) + surveyobj.wallet_letter = walletNumberLetter.group('letter') + if survey[header['Finished']]=='Yes': + #try and find the sketch_scan + pass + surveyobj.save() + + + logging.info("added survey " + survey[header['Year']] + "#" + surveyobj.wallet_number + "\r") + +# dead +def listdir(*directories): + try: + return os.listdir(os.path.join(settings.SURVEYS, *directories)) + except: + import urllib + url = settings.SURVEYS + reduce(lambda x, y: x + "/" + y, ["listdir"] + list(directories)) + folders = urllib.urlopen(url.replace("#", "%23")).readlines() + return [folder.rstrip(r"/") for folder in folders] + +# add survey scans +def parseSurveyScans(year, logfile=None): +# yearFileList = listdir(year.year) + yearPath=os.path.join(settings.SURVEY_SCANS, "years", year.year) + yearFileList=os.listdir(yearPath) + print yearFileList + for surveyFolder in yearFileList: + try: + surveyNumber=re.match(r'\d\d\d\d#0*(\d+)',surveyFolder).groups() +# scanList = listdir(year.year, surveyFolder) + scanList=os.listdir(os.path.join(yearPath,surveyFolder)) + except AttributeError: + print surveyFolder + " ignored", + continue + + for scan in scanList: + try: + scanChopped=re.match(r'(?i).*(notes|elev|plan|elevation|extend)(\d*)\.(png|jpg|jpeg)',scan).groups() + scanType,scanNumber,scanFormat=scanChopped + except AttributeError: + print scan + " ignored \r", + continue + if scanType == 'elev' or scanType == 'extend': + scanType = 'elevation' + + if scanNumber=='': + scanNumber=1 + + if type(surveyNumber)==types.TupleType: + surveyNumber=surveyNumber[0] + try: + placeholder=get_or_create_placeholder(year=int(year.year)) + survey=Survey.objects.get_or_create(wallet_number=surveyNumber, expedition=year, defaults={'logbook_entry':placeholder})[0] + except Survey.MultipleObjectsReturned: + survey=Survey.objects.filter(wallet_number=surveyNumber, expedition=year)[0] + file=os.path.join(year.year, surveyFolder, scan) + scanObj = ScannedImage( + file=file, + contents=scanType, + number_in_wallet=scanNumber, + survey=survey, + new_since_parsing=False, + ) + #print "Added scanned image at " + str(scanObj) + if scanFormat=="png": + if isInterlacedPNG(os.path.join(settings.SURVEY_SCANS,file)): + print file + " is an interlaced PNG. No can do." + continue + scanObj.save() + +# dead +def parseSurveys(logfile=None): + readSurveysFromCSV() + for year in Expedition.objects.filter(year__gte=2000): #expos since 2000, because paths and filenames were nonstandard before then + parseSurveyScans(year) + +# dead +def isInterlacedPNG(filePath): #We need to check for interlaced PNGs because the thumbnail engine can't handle them (uses PIL) + file=Image.open(filePath) + print filePath + if 'interlace' in file.info: + return file.info['interlace'] + else: + return False + + +# handles url or file, so we can refer to a set of scans on another server +def GetListDir(sdir): + res = [ ] + if sdir[:7] == "http://": + assert False, "Not written" + s = urllib.urlopen(sdir) + else: + for f in os.listdir(sdir): + if f[0] != ".": + ff = os.path.join(sdir, f) + res.append((f, ff, os.path.isdir(ff))) + return res + + + + + +def LoadListScansFile(survexscansfolder): + gld = [ ] + + # flatten out any directories in these book files + for (fyf, ffyf, fisdiryf) in GetListDir(survexscansfolder.fpath): + if fisdiryf: + gld.extend(GetListDir(ffyf)) + else: + gld.append((fyf, ffyf, fisdiryf)) + + for (fyf, ffyf, fisdiryf) in gld: + assert not fisdiryf, ffyf + if re.search("\.(?:png|jpg|jpeg)(?i)$", fyf): + survexscansingle = SurvexScanSingle(ffile=ffyf, name=fyf, survexscansfolder=survexscansfolder) + survexscansingle.save() + + +# this iterates through the scans directories (either here or on the remote server) +# and builds up the models we can access later +def LoadListScans(): + SurvexScanSingle.objects.all().delete() + SurvexScansFolder.objects.all().delete() + + # first do the smkhs (large kh survey scans) directory + survexscansfoldersmkhs = SurvexScansFolder(fpath=os.path.join(settings.SURVEY_SCANS, "smkhs"), walletname="smkhs") + if os.path.isdir(survexscansfoldersmkhs.fpath): + survexscansfoldersmkhs.save() + LoadListScansFile(survexscansfoldersmkhs) + + + # iterate into the surveyscans directory + for f, ff, fisdir in GetListDir(os.path.join(settings.SURVEY_SCANS, "surveyscans")): + if not fisdir: + continue + + # do the year folders + if re.match("\d\d\d\d$", f): + for fy, ffy, fisdiry in GetListDir(ff): + if fisdiry: + assert fisdiry, ffy + survexscansfolder = SurvexScansFolder(fpath=ffy, walletname=fy) + survexscansfolder.save() + LoadListScansFile(survexscansfolder) + + # do the + elif f != "thumbs": + survexscansfolder = SurvexScansFolder(fpath=ff, walletname=f) + survexscansfolder.save() + LoadListScansFile(survexscansfolder) + + +def FindTunnelScan(tunnelfile, path): + scansfolder, scansfile = None, None + mscansdir = re.search("(\d\d\d\d#\d+\w?|1995-96kh|92-94Surveybookkh|1991surveybook|smkhs)/(.*?(?:png|jpg))$", path) + if mscansdir: + scansfolderl = SurvexScansFolder.objects.filter(walletname=mscansdir.group(1)) + if len(scansfolderl): + assert len(scansfolderl) == 1 + scansfolder = scansfolderl[0] + if scansfolder: + scansfilel = scansfolder.survexscansingle_set.filter(name=mscansdir.group(2)) + if len(scansfilel): + assert len(scansfilel) == 1 + scansfile = scansfilel[0] + + if scansfolder: + tunnelfile.survexscansfolders.add(scansfolder) + if scansfile: + tunnelfile.survexscans.add(scansfile) + + elif path and not re.search("\.(?:png|jpg)$(?i)", path): + name = os.path.split(path)[1] + print "ttt", tunnelfile.tunnelpath, path, name + rtunnelfilel = TunnelFile.objects.filter(tunnelname=name) + if len(rtunnelfilel): + assert len(rtunnelfilel) == 1, ("two paths with name of", path, "need more discrimination coded") + rtunnelfile = rtunnelfilel[0] + #print "ttt", tunnelfile.tunnelpath, path, name, rtunnelfile.tunnelpath + tunnelfile.tunnelcontains.add(rtunnelfile) + + tunnelfile.save() + + +def SetTunnelfileInfo(tunnelfile): + ff = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath) + tunnelfile.filesize = os.stat(ff)[stat.ST_SIZE] + fin = open(ff) + ttext = fin.read() + fin.close() + + mtype = re.search("<(fontcolours|sketch)", ttext) + assert mtype, ff + tunnelfile.bfontcolours = (mtype.group(1)=="fontcolours") + tunnelfile.npaths = len(re.findall("<skpath", ttext)) + tunnelfile.save() + + # <tunnelxml tunnelversion="version2009-06-21 Matienzo" tunnelproject="ireby" tunneluser="goatchurch" tunneldate="2009-06-29 23:22:17"> + # <pcarea area_signal="frame" sfscaledown="12.282584" sfrotatedeg="-90.76982" sfxtrans="11.676667377221136" sfytrans="-15.677173422877454" sfsketch="204description/scans/plan(38).png" sfstyle="" nodeconnzsetrelative="0.0"> + for path, style in re.findall('<pcarea area_signal="frame".*?sfsketch="([^"]*)" sfstyle="([^"]*)"', ttext): + FindTunnelScan(tunnelfile, path) + + # should also scan and look for survex blocks that might have been included + # and also survex titles as well. + + tunnelfile.save() + + +def LoadTunnelFiles(): + tunneldatadir = settings.TUNNEL_DATA + TunnelFile.objects.all().delete() + tunneldirs = [ "" ] + while tunneldirs: + tunneldir = tunneldirs.pop() + for f in os.listdir(os.path.join(tunneldatadir, tunneldir)): + if f[0] == "." or f[-1] == "~": + continue + lf = os.path.join(tunneldir, f) + ff = os.path.join(tunneldatadir, lf) + if os.path.isdir(ff): + tunneldirs.append(lf) + elif f[-4:] == ".xml": + tunnelfile = TunnelFile(tunnelpath=lf, tunnelname=os.path.split(f[:-4])[1]) + tunnelfile.save() + + for tunnelfile in TunnelFile.objects.all(): + SetTunnelfileInfo(tunnelfile) + + + + diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html index 100ae6c..83c59a2 100644 --- a/templates/admin/base_site.html +++ b/templates/admin/base_site.html @@ -1,10 +1,10 @@ -{% extends "admin/base.html" %}
-{% load i18n %}
-
-{% block title %}{{ title }} | {% trans 'Troggle site admin' %}{% endblock %}
-
-{% block branding %}
-<h1 id="site-name">{% trans 'Troggle administration' %}</h1>
-{% endblock %}
-
-{% block nav-global %}{% endblock %}
+{% extends "admin/base.html" %} +{% load i18n %} + +{% block title %}{{ title }} | {% trans 'Troggle site admin' %}{% endblock %} + +{% block branding %} +<h1 id="site-name">{% trans 'Troggle administration' %}</h1> +{% endblock %} + +{% block nav-global %}{% endblock %} diff --git a/templates/base.html b/templates/base.html index d3341b2..0d12d45 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,111 +1,111 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
-<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/main3.css" title="eyeCandy"/>
-<link rel="alternate stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/mainplain.css" title="plain"/>
-<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/dropdownNavStyle.css" />
-<title>{% block title %}Troggle{% endblock %}</title>
-<script src="{{ settings.MEDIA_URL }}js/jquery.js" type="text/javascript"></script>
-<script src="{{ settings.MEDIA_URL }}js/jquery.quicksearch.js" type="text/javascript"></script>
-<script src="{{ settings.MEDIA_URL }}js/base.js" type="text/javascript"></script>
-<script src="{{ settings.MEDIA_URL }}js/jquery.dropdownPlain.js" type="text/javascript"></script>
-
-{% block head %}{% endblock %}
-</head>
-<body onLoad="contentHeight();">
-
-<div id="header">
- <h1>CUCC Expeditions to Austria: 1976 - 2009</h1>
- <div id="editLinks"> {% block loginInfo %}
- <a href="{{ settings.EXPOWEB_URL }}">ExpoWeb</a> |
- <a href="{{ settings.URL_ROOT }}">Home</a> |
- {% if user.username %}
- You are logged in as {{ user.username }}
- {% if user.person %}(<a href="{{ user.person.get_absolute_url }}">{{ user.person }}</a>)
- {% else %}<a href={% url profiles_select_profile %}>sort your profile</a>
- {% endif %}.
- | <a href="{% url auth_logout %}">Log out</a> {% else %} <a href="{% url registration_register %}">Sign up</a> | <a href="{% url auth_login %}">Log in</a> {% endif %}
- {% endblock%}
- {% block editLink %}
-
- {% endblock %}
- </div>
-</div>
-<div class="toolbarlinks">
- <a href="{% url survexcaveslist %}">All Survex</a> |
- <a href="{% url surveyscansfolders %}">Scans</a> |
- <a href="{% url tunneldata %}">Tunneldata</a> |
- <a href="{% url survexcavessingle 161 %}">161</a> |
- <a href="{% url survexcavessingle 204 %}">204</a> |
- <a href="{% url survexcavessingle 258 %}">258</a> |
- <a href="{% url expedition 2009 %}">Expo2009</a> |
- <a href="{% url expedition 2010 %}">Expo2010</a> |
- <a href="{% url expedition 2011 %}">Expo2011</a> |
- <a href="/admin">Django admin</a>
-</div>
-
-<div id="nav">
-
- {% block nav %}
- <!-- Use id="nav" for the left side menu -->
- {% endblock %}
-</div>
-
-
-
-<div id="content" >
-
- {% block contentheader %}
- {% endblock %}
-
-<div id="related">
-{% block related %}
-<script language="javascript">
- $('#related').remove()
- /*This is a hack to stop a line appearing because of the empty div border*/
-</script>
-{% endblock %}
-</div>
-
- {% block content %}
- REPLACE : The content
- {% endblock %}
-
- </div>
-
- <div class="footer">
- <ul class="dropdown" id="footerLinks">
-
- <li><a href="#">External links</a>
- <ul class="sub_menu">
- <li><a id="cuccLink" href="http://www.srcf.ucam.org/caving/wiki/Main_Page">CUCC website</a></li>
- <li><a id="expoWebsiteLink" href="http://cucc.survex.com/expo">Expedition website</a></li>
- </ul>
- </li>
- <li><a href="{% url frontpage %}">Troggle front page</a></li>
- <li><a id="cavesLink" href="{% url caveindex %}">caves</a></li>
- <li><a id="caversLink" href="{% url personindex %}">cavers</a></li>
- <li><a href="#">expeditions</a>
- <ul class="sub_menu">
- <li><a id="expeditionsLink" href="{{ Expedition.objects.latest.get_absolute_url }}">newest</a></li>
- <li><a id="expeditionsLink" href="{% url expeditions %}">list all</a></li>
- </ul>
- </li>
- <li><a id="surveyBinderLink" href="{% url survey %}">survey binder</a></li>
- <li><a href="#">diversions</a>
- <ul class="sub_menu">
- <li><a href="{% url stats %}">statistics</a></li>
- </ul>
- </li>
- <li><a href="#">admin</a>
- <ul class="sub_menu">
- <li><a id="cuccLink" href="{% url controlpanel %}">Import / export data</a></li>
- <li><a id="expoWebsiteLink" href="{{ settings.URL_ROOT }}admin">Troggle administration pages</a></li>
- </ul>
- <li class="toggleMenu"><a href="#">hide menu</a></li>
-
- </ul>
- </div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<html lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/main3.css" title="eyeCandy"/> +<link rel="alternate stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/mainplain.css" title="plain"/> +<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/dropdownNavStyle.css" /> +<title>{% block title %}Troggle{% endblock %}</title> +<script src="{{ settings.MEDIA_URL }}js/jquery.js" type="text/javascript"></script> +<script src="{{ settings.MEDIA_URL }}js/jquery.quicksearch.js" type="text/javascript"></script> +<script src="{{ settings.MEDIA_URL }}js/base.js" type="text/javascript"></script> +<script src="{{ settings.MEDIA_URL }}js/jquery.dropdownPlain.js" type="text/javascript"></script> + +{% block head %}{% endblock %} +</head> +<body onLoad="contentHeight();"> + +<div id="header"> + <h1>CUCC Expeditions to Austria: 1976 - 2009</h1> + <div id="editLinks"> {% block loginInfo %} + <a href="{{ settings.EXPOWEB_URL }}/index.htm">ExpoWeb</a> | + <a href="{{ settings.URL_ROOT }}">Home</a> | + {% if user.username %} + You are logged in as {{ user.username }} + {% if user.person %}(<a href="{{ user.person.get_absolute_url }}">{{ user.person }}</a>) + {% else %}<a href={% url profiles_select_profile %}>sort your profile</a> + {% endif %}. + | <a href="{% url auth_logout %}">Log out</a> {% else %} <a href="{% url registration_register %}">Sign up</a> | <a href="{% url auth_login %}">Log in</a> {% endif %} + {% endblock%} + {% block editLink %} + + {% endblock %} + </div> +</div> +<div class="toolbarlinks"> + <a href="{% url survexcaveslist %}">All Survex</a> | + <a href="{% url surveyscansfolders %}">Scans</a> | + <a href="{% url tunneldata %}">Tunneldata</a> | + <a href="{% url survexcavessingle 161 %}">161</a> | + <a href="{% url survexcavessingle 204 %}">204</a> | + <a href="{% url survexcavessingle 258 %}">258</a> | + <a href="{% url expedition 2009 %}">Expo2009</a> | + <a href="{% url expedition 2010 %}">Expo2010</a> | + <a href="{% url expedition 2011 %}">Expo2011</a> | + <a href="/admin">Django admin</a> +</div> + +<div id="nav"> + + {% block nav %} + <!-- Use id="nav" for the left side menu --> + {% endblock %} +</div> + + + +<div id="content" > + + {% block contentheader %} + {% endblock %} + +<div id="related"> +{% block related %} +<script language="javascript"> + $('#related').remove() + /*This is a hack to stop a line appearing because of the empty div border*/ +</script> +{% endblock %} +</div> + + {% block content %} + REPLACE : The content + {% endblock %} + + </div> + + <div class="footer"> + <ul class="dropdown" id="footerLinks"> + + <li><a href="#">External links</a> + <ul class="sub_menu"> + <li><a id="cuccLink" href="http://www.srcf.ucam.org/caving/wiki/Main_Page">CUCC website</a></li> + <li><a id="expoWebsiteLink" href="http://cucc.survex.com/expo">Expedition website</a></li> + </ul> + </li> + <li><a href="{% url frontpage %}">Troggle front page</a></li> + <li><a id="cavesLink" href="{% url caveindex %}">caves</a></li> + <li><a id="caversLink" href="{% url personindex %}">cavers</a></li> + <li><a href="#">expeditions</a> + <ul class="sub_menu"> + <li><a id="expeditionsLink" href="{{ Expedition.objects.latest.get_absolute_url }}">newest</a></li> + <li><a id="expeditionsLink" href="{% url expeditions %}">list all</a></li> + </ul> + </li> + <li><a id="surveyBinderLink" href="{% url survey %}">survey binder</a></li> + <li><a href="#">diversions</a> + <ul class="sub_menu"> + <li><a href="{% url stats %}">statistics</a></li> + </ul> + </li> + <li><a href="#">admin</a> + <ul class="sub_menu"> + <li><a id="cuccLink" href="{% url controlpanel %}">Import / export data</a></li> + <li><a id="expoWebsiteLink" href="{{ settings.URL_ROOT }}admin">Troggle administration pages</a></li> + </ul> + <li class="toggleMenu"><a href="#">hide menu</a></li> + + </ul> + </div> +</body> +</html> diff --git a/templates/cave.html b/templates/cave.html index d90f10b..5f761b7 100644 --- a/templates/cave.html +++ b/templates/cave.html @@ -1,43 +1,43 @@ -{% extends "cavebase.html" %}
-
-
-{% block content %}
-{% block contentheader %}
-<table id="cavepage">
-<tr>
- <th id="kat_no">
- {% if cave.kataster_number %}
- {{ cave.kataster_number|safe }}
- {% if cave.entrancelist %}
- - {{ cave.entrancelist|safe }}
- {% endif %}
- {% if cave.unofficial_number %}
- <br />({{ cave.unofficial_number|safe }})
- {% endif %}
- {% endif %}
- </th>
- <th id="name">
- {{ cave.official_name|safe }}
- </th>
- <th id="status">
- {{ cave.kataster_code|safe }}
- </th>
-</tr>
-</table>
-{% block related %}
-{% endblock %}{% endblock %}
-
-<div id="tabs">
- <ul>
- <li><a href="/cave/description/{{cave.slug}}">Description</a></li>
- <li><a href="/cave/entrance/{{cave.slug}}">Entrances</a></li>
- <li><a href="/cave/logbook/{{cave.slug}}">Logbook</a></li>
- <li><a href="/cave/qms/{{cave.slug}}">QMs</a></li>
- </ul>
- <div id="qms">
-
- </div>
-</div>
-
-
-{% endblock %}
+{% extends "cavebase.html" %} + + +{% block content %} +{% block contentheader %} +<table id="cavepage"> +<tr> + <th id="kat_no"> + {% if cave.kataster_number %} + {{ cave.kataster_number|safe }} + {% if cave.entrancelist %} + - {{ cave.entrancelist|safe }} + {% endif %} + {% if cave.unofficial_number %} + <br />({{ cave.unofficial_number|safe }}) + {% endif %} + {% endif %} + </th> + <th id="name"> + {{ cave.official_name|safe }} + </th> + <th id="status"> + {{ cave.kataster_code|safe }} + </th> +</tr> +</table> +{% block related %} +{% endblock %}{% endblock %} + +<div id="tabs"> + <ul> + <li><a href="/cave/description/{{cave.slug}}">Description</a></li> + <li><a href="/cave/entrance/{{cave.slug}}">Entrances</a></li> + <li><a href="/cave/logbook/{{cave.slug}}">Logbook</a></li> + <li><a href="/cave/qms/{{cave.slug}}">QMs</a></li> + </ul> + <div id="qms"> + + </div> +</div> + + +{% endblock %} diff --git a/templates/cave_description.html b/templates/cave_description.html index 572de78..7105963 100644 --- a/templates/cave_description.html +++ b/templates/cave_description.html @@ -1,19 +1,19 @@ -{% extends "cavebase.html" %}
-{% load wiki_markup %}
-{% block title %} {{cave_description}} {% endblock title %}
-{% block editLink %}<a href={{cave_description.get_admin_url}}>Edit description {{cave_description}}</a>{% endblock %}
-
-{% block contentheader %}
- {{cave_description.long_name}}
-{% endblock contentheader %}
-
-
-
-{% block content %}
-
-<h1>{{cave_description.long_name}}</h1>
-<p>
- {{cave_description.description|wiki_to_html}}
-</p>
-
+{% extends "cavebase.html" %} +{% load wiki_markup %} +{% block title %} {{cave_description}} {% endblock title %} +{% block editLink %}<a href={{cave_description.get_admin_url}}>Edit description {{cave_description}}</a>{% endblock %} + +{% block contentheader %} + {{cave_description.long_name}} +{% endblock contentheader %} + + + +{% block content %} + +<h1>{{cave_description.long_name}}</h1> +<p> + {{cave_description.description|wiki_to_html}} +</p> + {% endblock content %}
\ No newline at end of file diff --git a/templates/cavebase.html b/templates/cavebase.html index 6e27111..7e83151 100644 --- a/templates/cavebase.html +++ b/templates/cavebase.html @@ -1,26 +1,26 @@ -<html>
-<head>
-
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
-<title>{% block title %}{{ cave.official_name|safe }}{% endblock %}
-</title>
-<link rel="stylesheet" type="text/css" href="/css/main2.css" />
-<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/redmond/jquery-ui-1.8.14.custom.css" />
-<script src="{{ settings.MEDIA_URL }}js/jquery.js" type="text/javascript"></script>
-<script src="{{ settings.MEDIA_URL }}js/jquery-ui-1.8.14.custom.min.js" type="text/javascript"></script>
-<script type="text/javascript">
- $(function() {
- $( "#tabs" ).tabs();
- });
-</script>
-</head>
-<body>
-{% block content %}{% endblock %}
-{% block menu %}
-<ul id="links">
-<li>Back to <a href="/index.htm">Expedition home page</a></li>
-<li>Back to <a href="http://cucc.survex.com/">CUCC home page</a></li>
-</ul>
-{% endblock %}
-</body>
-</html>
+<html> +<head> + +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> +<title>{% block title %}{{ cave.official_name|safe }}{% endblock %} +</title> +<link rel="stylesheet" type="text/css" href="/css/main2.css" /> +<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/redmond/jquery-ui-1.8.14.custom.css" /> +<script src="{{ settings.MEDIA_URL }}js/jquery.js" type="text/javascript"></script> +<script src="{{ settings.MEDIA_URL }}js/jquery-ui-1.8.14.custom.min.js" type="text/javascript"></script> +<script type="text/javascript"> + $(function() { + $( "#tabs" ).tabs(); + }); +</script> +</head> +<body> +{% block content %}{% endblock %} +{% block menu %} +<ul id="links"> +<li>Back to <a href="/index.htm">Expedition home page</a></li> +<li>Back to <a href="http://cucc.survex.com/">CUCC home page</a></li> +</ul> +{% endblock %} +</body> +</html> diff --git a/templates/caveindex.html b/templates/caveindex.html index ac67559..8f16e87 100644 --- a/templates/caveindex.html +++ b/templates/caveindex.html @@ -1,37 +1,37 @@ -{% extends "cavebase.html" %}
-{% load wiki_markup %}
-
-{% block title %}Cave Index{% endblock %}
-
-{% block content %}
-
-<h1>Cave Index</h1>
-
-<h3>Notable caves</h3>
-<ul>
-{% for cave in notablecaves %}
- <li> <a href="{{ cave.get_absolute_url }}">{% if cave.kataster_number %}{{ cave.kataster_number }}{% else %}{{cave.unofficial_number }}{%endif %} {{cave.official_name|safe}}</a> </li>
-{% endfor %}
-</ul>
-
-<h3>1623</h3>
-
-<ul class="searchable">
-{% for cave in caves1623 %}
-
- <li> <a href="{{ cave.get_absolute_url }}">{% if cave.kataster_number %}{{ cave.kataster_number }}{% else %}{{cave.unofficial_number }}{%endif %} {{cave.official_name|safe}}</a> </li>
-
-{% endfor %}
-</ul>
-
-<h3>1626</h3>
-
-<ul class="searchable">
-{% for cave in caves1626 %}
-
- <li> <a href="{{ cave.get_absolute_url }}">{% if cave.kataster_number %}{{ cave.kataster_number }}{% else %}{{cave.unofficial_number }}{%endif %} {{cave.official_name|safe}}</a> </li>
-
-{% endfor %}
-</ul>
-
-{% endblock %}
+{% extends "cavebase.html" %} +{% load wiki_markup %} + +{% block title %}Cave Index{% endblock %} + +{% block content %} + +<h1>Cave Index</h1> + +<h3>Notable caves</h3> +<ul> +{% for cave in notablecaves %} + <li> <a href="{{ cave.get_absolute_url }}">{% if cave.kataster_number %}{{ cave.kataster_number }}{% else %}{{cave.unofficial_number }}{%endif %} {{cave.official_name|safe}}</a> </li> +{% endfor %} +</ul> + +<h3>1623</h3> + +<ul class="searchable"> +{% for cave in caves1623 %} + + <li> <a href="{{ cave.get_absolute_url }}">{% if cave.kataster_number %}{{ cave.kataster_number }}{% else %}{{cave.unofficial_number }}{%endif %} {{cave.official_name|safe}}</a> </li> + +{% endfor %} +</ul> + +<h3>1626</h3> + +<ul class="searchable"> +{% for cave in caves1626 %} + + <li> <a href="{{ cave.get_absolute_url }}">{% if cave.kataster_number %}{{ cave.kataster_number }}{% else %}{{cave.unofficial_number }}{%endif %} {{cave.official_name|safe}}</a> </li> + +{% endfor %} +</ul> + +{% endblock %} diff --git a/templates/controlPanel.html b/templates/controlPanel.html index efaee62..7d37887 100644 --- a/templates/controlPanel.html +++ b/templates/controlPanel.html @@ -1,157 +1,157 @@ -{% extends "base.html" %}
-{% block content %}
-
-{% if jobs_completed %}
- <div class="noticeBox">
- Just finished running:
- <ul>
- {% for job in jobs_completed %}
- <li>{{ job }}</li>
- {% endfor %}
- </ul>
- {% if settings.LOGFILE %}See the logfile at {{settings.LOGFILE}} for more information.{% endif %}
- <a href="#" class="closeDiv">dismiss this message</a>
- </div>
-{% endif %}
-
-{% if error %}
- <div class="noticeBox">
- {{ error }}
- <a href="#" class="closeDiv">dismiss this message</a>
- </div>
-{% endif %}
-
-
-<form name="reset" method="post" action="">
-<h3>Wipe:</h3>
-
-<table>
-<tr><td>Wipe entire database and recreate tables: </td><td><input type="checkbox" name="reload_db" /></td><td> <input type="submit" id="Import" value="I really want to delete all information in troggle, and accept all responsibility."></td></tr>
-</table>
-</form>
-<h3>Import (non-destructive):</h3>
-<form name="import" method="post" action="">
-<table>
-<tr><td>people from folk.csv using parsers\people.py</td><td><input type="checkbox" name="import_people"/></td></tr>
-<tr><td>caves from cavetab2.csv using parsers\cavetab.py</td><td> <input type="checkbox" class="parser" name="import_cavetab"/></td></tr>
-<tr><td>logbook entries using parsers\logbooks.py</td><td><input type="checkbox" name="import_logbooks"/></td></tr>
-<tr><td>QMs using parsers\QMs.py</td><td><input type="checkbox" name="import_QMs" /></td></tr>
-<tr><td>survey scans using parsers\surveys.py</td><td><input type="checkbox" name="import_surveys" /></td></tr>
-<tr><td>survex data using parsers\survex.py</td><td><input type="checkbox" name="import_survex" /></td></tr>
-
-</table>
-
-
- <p>
- <input type="submit" id="Import" value="Import">
-
- <input type="submit" name="check_all_import" id="check_all_import" value="Check all" disabled >
- </p>
-</form>
-
-
-<h3>Export to legacy formats:</h3>
-<table>
-
-<th>
- <td>Export onto server</td>
- <td>Export and Download</td>
-</th>
-<tr>
- <td>
- caves to cavetab2.csv
- </td>
- <td>
- <form name="export" method="post" action="">
- <p>Overwrite the existing CAVETAB2.CSV file with one generated by Troggle.</p>
- <input name="export_cavetab" type="submit" value="Update {{settings.EXPOWEB}}noinfo/CAVETAB2.CSV" />
- </form>
- </td>
- <td>
- <form name="export" method="get" action="{% url downloadcavetab %}">
- <p>Download a CAVETAB2.CSV file which is dynamically generated by Troggle.</p>
- <input name="download_cavetab" type="submit" value="Download CAVETAB2.CSV" />
- </form>
- </td>
-</tr>
-
-<tr>
- <td>
- surveys to Surveys.csv
- </td>
- <td>
-
- </td>
- <td>
- <form name="export" method="get" action={% url downloadlogbook %}>
- <p>Download a logbook file which is dynamically generated by Troggle.</p>
-
- <p>
- Expedition year:
- <select name="year">
- {% for expedition in expeditions %}
- <option value="{{expedition}}"> {{expedition}} </option>
- {% endfor %}
- </select>
- </p>
-
- <p>
- Output style:
- <select name="extension">
- <option value="txt">.txt file with MediaWiki markup - 2008 style</option>
- <option value="html">.html file - 2005 style</option>
- </select>
- </p>
- <p>
- <input name="download_logbook" type="submit" value="Download logbook" />
- </p>
- </form>
- </td>
-</tr>
-
-<tr>
- <td>
- surveys to Surveys.csv
- </td>
- <td>
- <form name="export" method="post" action="">
- <p>Overwrite the existing Surveys.csv file with one generated by Troggle.</p>
- <input disabled name="export_surveys" type="submit" value="Update {{settings.SURVEYS}}noinfo/Surveys.csv" />
- </form>
- </td>
- <td>
- <form name="export" method="get" action={% url downloadsurveys %}>
- <p>Download a Surveys.csv file which is dynamically generated by Troggle.</p>
- <input disabled name="download_surveys" type="submit" value="Download Surveys.csv" />
- </form>
- </td>
-</tr>
-
-<tr>
- <td>qms to qms.csv</td><td>
- <form name="export_qms" method="get" action="downloadqms">
-
-<!--This is for choosing caves by area (drilldown).
-
- <select id="qmcaveareachooser" class="searchable" >
- </select>
-
- -->
-
- Choose a cave.
- <select name="cave_id" id="qmcavechooser">
-
- {% for cave in caves %}
- <option value="{{cave.kataster_number}}">{{cave}}
- </option>
- {% endfor %}
-
- </select>
-
- <input type="submit" value="Download"/>
- </form>
- </td></tr>
-</table>
-</form>
-
+{% extends "base.html" %} +{% block content %} + +{% if jobs_completed %} + <div class="noticeBox"> + Just finished running: + <ul> + {% for job in jobs_completed %} + <li>{{ job }}</li> + {% endfor %} + </ul> + {% if settings.LOGFILE %}See the logfile at {{settings.LOGFILE}} for more information.{% endif %} + <a href="#" class="closeDiv">dismiss this message</a> + </div> +{% endif %} + +{% if error %} + <div class="noticeBox"> + {{ error }} + <a href="#" class="closeDiv">dismiss this message</a> + </div> +{% endif %} + + +<form name="reset" method="post" action=""> +<h3>Wipe:</h3> + +<table> +<tr><td>Wipe entire database and recreate tables: </td><td><input type="checkbox" name="reload_db" /></td><td> <input type="submit" id="Import" value="I really want to delete all information in troggle, and accept all responsibility."></td></tr> +</table> +</form> +<h3>Import (non-destructive):</h3> +<form name="import" method="post" action=""> +<table> +<tr><td>people from folk.csv using parsers\people.py</td><td><input type="checkbox" name="import_people"/></td></tr> +<tr><td>caves from cavetab2.csv using parsers\cavetab.py</td><td> <input type="checkbox" class="parser" name="import_cavetab"/></td></tr> +<tr><td>logbook entries using parsers\logbooks.py</td><td><input type="checkbox" name="import_logbooks"/></td></tr> +<tr><td>QMs using parsers\QMs.py</td><td><input type="checkbox" name="import_QMs" /></td></tr> +<tr><td>survey scans using parsers\surveys.py</td><td><input type="checkbox" name="import_surveys" /></td></tr> +<tr><td>survex data using parsers\survex.py</td><td><input type="checkbox" name="import_survex" /></td></tr> + +</table> + + + <p> + <input type="submit" id="Import" value="Import"> + + <input type="submit" name="check_all_import" id="check_all_import" value="Check all" disabled > + </p> +</form> + + +<h3>Export to legacy formats:</h3> +<table> + +<th> + <td>Export onto server</td> + <td>Export and Download</td> +</th> +<tr> + <td> + caves to cavetab2.csv + </td> + <td> + <form name="export" method="post" action=""> + <p>Overwrite the existing CAVETAB2.CSV file with one generated by Troggle.</p> + <input name="export_cavetab" type="submit" value="Update {{settings.EXPOWEB}}noinfo/CAVETAB2.CSV" /> + </form> + </td> + <td> + <form name="export" method="get" action="{% url downloadcavetab %}"> + <p>Download a CAVETAB2.CSV file which is dynamically generated by Troggle.</p> + <input name="download_cavetab" type="submit" value="Download CAVETAB2.CSV" /> + </form> + </td> +</tr> + +<tr> + <td> + surveys to Surveys.csv + </td> + <td> + + </td> + <td> + <form name="export" method="get" action={% url downloadlogbook %}> + <p>Download a logbook file which is dynamically generated by Troggle.</p> + + <p> + Expedition year: + <select name="year"> + {% for expedition in expeditions %} + <option value="{{expedition}}"> {{expedition}} </option> + {% endfor %} + </select> + </p> + + <p> + Output style: + <select name="extension"> + <option value="txt">.txt file with MediaWiki markup - 2008 style</option> + <option value="html">.html file - 2005 style</option> + </select> + </p> + <p> + <input name="download_logbook" type="submit" value="Download logbook" /> + </p> + </form> + </td> +</tr> + +<tr> + <td> + surveys to Surveys.csv + </td> + <td> + <form name="export" method="post" action=""> + <p>Overwrite the existing Surveys.csv file with one generated by Troggle.</p> + <input disabled name="export_surveys" type="submit" value="Update {{settings.SURVEYS}}noinfo/Surveys.csv" /> + </form> + </td> + <td> + <form name="export" method="get" action={% url downloadsurveys %}> + <p>Download a Surveys.csv file which is dynamically generated by Troggle.</p> + <input disabled name="download_surveys" type="submit" value="Download Surveys.csv" /> + </form> + </td> +</tr> + +<tr> + <td>qms to qms.csv</td><td> + <form name="export_qms" method="get" action="downloadqms"> + +<!--This is for choosing caves by area (drilldown). + + <select id="qmcaveareachooser" class="searchable" > + </select> + + --> + + Choose a cave. + <select name="cave_id" id="qmcavechooser"> + + {% for cave in caves %} + <option value="{{cave.kataster_number}}">{{cave}} + </option> + {% endfor %} + + </select> + + <input type="submit" value="Download"/> + </form> + </td></tr> +</table> +</form> + {% endblock %}
\ No newline at end of file diff --git a/templates/editfile.html b/templates/editfile.html index d3a29ec..954a1c4 100644 --- a/templates/editfile.html +++ b/templates/editfile.html @@ -1,96 +1,96 @@ -{% extends "base.html" %}
-{% load csrffaker %}
-{% block title %}File{% endblock %}
-{% block head %}
-<script>
- $(function() {
- $("#id_date").datepicker({dateFormat: "yy-mm-dd"});
- $("#id_cave").change(function() {
- $('#id_entrance').load('{% url get_entrances caveslug="" %}' + this.value);
- });
- $("#id_cave").change(function() {
- $('#id_qm').load('{% url get_qms caveslug="" %}' + this.value);
- });
- $("#id_expedition").change(function() {
- $('#id_logbookentry').load('{% url get_logbook_entries expeditionslug="" %}' + this.value);
- });
- $("#id_expedition").change(function() {
- $('#id_person').load('{% url get_people expeditionslug="" %}' + this.value);
- });
- });
-
-</script>
-<link rel="stylesheet" href="{{ settings.MEDIA_URL }}css/ui-lightness/jquery-ui-1.8.12.custom.css" type="text/css" media="all" />
-<script src="{{ settings.MEDIA_URL }}js/jquery-ui-1.8.12.custom.min.js" type="text/javascript"></script>
-<script src="{{ settings.MEDIA_URL }}js/jquery.formset.min.js" type="text/javascript"></script>
-<script src="{{ settings.TINY_MCE_MEDIA_URL }}tiny_mce.js" type="text/javascript"></script>
-{{ fileForm.media }}
-{% endblock %}
-{% block content %}
-
-<form action="" method="post">{% csrf_token %}
- {{ fileForm.non_field_errors }}
- <div class="fieldWrapper">
- {{ fileForm.title.errors }}
- <label for="id_title">Title:</label>
- {{ fileForm.title }}
- </div>
- <div class="fieldWrapper">
- {{ fileForm.slug.errors }}
- <label for="id_slug">Slug:</label>
- {{ fileForm.slug }}
- </div>
- <div class="fieldWrapper">
- {{ fileForm.date.errors }}
- <label for="id_date">Date:</label>
- {{ fileForm.date }}
- </div>
- <div class="fieldWrapper" id="lon_utm">
- {{ fileForm.lon_utm.errors }}
- <label for="id_lon_utm">Longitude:</label>
- {{ fileForm.lon_utm }}
- </div>
- <div class="fieldWrapper" id="lat_utm">
- {{ fileForm.lat_utm.errors }}
- <label for="id_lat_utm">Latitude:</label>
- {{ fileForm.lat_utm }}
- </div>
- <div class="fieldWrapper" id="cave">
- {{ fileForm.cave.errors }}
- <label for="id_cave">Cave:</label>
- {{ fileForm.cave }}
- </div>
- <div class="fieldWrapper" id="entrance">
- {{ fileForm.entrance.errors }}
- <label for="id_entrance">Entrance:</label>
- {{ fileForm.entrance }}
- </div>
- <div class="fieldWrapper" id="qm">
- {{ fileForm.qm.errors }}
- <label for="id_cavem">QM:</label>
- {{ fileForm.qm }}
- </div>
- <div class="fieldWrapper" id="expedition">
- {{ fileForm.expedition.errors }}
- <label for="id_expediton">Expedition:</label>
- {{ fileForm.expedition }}
- </div>
- <div class="fieldWrapper" id="logbookentry">
- {{ fileForm.logbookentry.errors }}
- <label for="id_logbookentry">Logbook Entry:</label>
- {{ fileForm.logbookentry }}
- </div>
- <div class="fieldWrapper" id="person">
- {{ fileForm.person.errors }}
- <label for="id_expediton">Person:</label>
- {{ fileForm.person }}
- </div>
- <div class="fieldWrapper">
- {{ fileForm.html.errors }}
- <label for="id_date">Content:</label>
- {{ fileForm.html }}
- </div>
- <p><input type="submit" value="Sumbit Trip Report" /></p>
-</form>
-
-{% endblock %}
+{% extends "base.html" %} +{% load csrffaker %} +{% block title %}File{% endblock %} +{% block head %} +<script> + $(function() { + $("#id_date").datepicker({dateFormat: "yy-mm-dd"}); + $("#id_cave").change(function() { + $('#id_entrance').load('{% url get_entrances caveslug="" %}' + this.value); + }); + $("#id_cave").change(function() { + $('#id_qm').load('{% url get_qms caveslug="" %}' + this.value); + }); + $("#id_expedition").change(function() { + $('#id_logbookentry').load('{% url get_logbook_entries expeditionslug="" %}' + this.value); + }); + $("#id_expedition").change(function() { + $('#id_person').load('{% url get_people expeditionslug="" %}' + this.value); + }); + }); + +</script> +<link rel="stylesheet" href="{{ settings.MEDIA_URL }}css/ui-lightness/jquery-ui-1.8.12.custom.css" type="text/css" media="all" /> +<script src="{{ settings.MEDIA_URL }}js/jquery-ui-1.8.12.custom.min.js" type="text/javascript"></script> +<script src="{{ settings.MEDIA_URL }}js/jquery.formset.min.js" type="text/javascript"></script> +<script src="{{ settings.TINY_MCE_MEDIA_URL }}tiny_mce.js" type="text/javascript"></script> +{{ fileForm.media }} +{% endblock %} +{% block content %} + +<form action="" method="post">{% csrf_token %} + {{ fileForm.non_field_errors }} + <div class="fieldWrapper"> + {{ fileForm.title.errors }} + <label for="id_title">Title:</label> + {{ fileForm.title }} + </div> + <div class="fieldWrapper"> + {{ fileForm.slug.errors }} + <label for="id_slug">Slug:</label> + {{ fileForm.slug }} + </div> + <div class="fieldWrapper"> + {{ fileForm.date.errors }} + <label for="id_date">Date:</label> + {{ fileForm.date }} + </div> + <div class="fieldWrapper" id="lon_utm"> + {{ fileForm.lon_utm.errors }} + <label for="id_lon_utm">Longitude:</label> + {{ fileForm.lon_utm }} + </div> + <div class="fieldWrapper" id="lat_utm"> + {{ fileForm.lat_utm.errors }} + <label for="id_lat_utm">Latitude:</label> + {{ fileForm.lat_utm }} + </div> + <div class="fieldWrapper" id="cave"> + {{ fileForm.cave.errors }} + <label for="id_cave">Cave:</label> + {{ fileForm.cave }} + </div> + <div class="fieldWrapper" id="entrance"> + {{ fileForm.entrance.errors }} + <label for="id_entrance">Entrance:</label> + {{ fileForm.entrance }} + </div> + <div class="fieldWrapper" id="qm"> + {{ fileForm.qm.errors }} + <label for="id_cavem">QM:</label> + {{ fileForm.qm }} + </div> + <div class="fieldWrapper" id="expedition"> + {{ fileForm.expedition.errors }} + <label for="id_expediton">Expedition:</label> + {{ fileForm.expedition }} + </div> + <div class="fieldWrapper" id="logbookentry"> + {{ fileForm.logbookentry.errors }} + <label for="id_logbookentry">Logbook Entry:</label> + {{ fileForm.logbookentry }} + </div> + <div class="fieldWrapper" id="person"> + {{ fileForm.person.errors }} + <label for="id_expediton">Person:</label> + {{ fileForm.person }} + </div> + <div class="fieldWrapper"> + {{ fileForm.html.errors }} + <label for="id_date">Content:</label> + {{ fileForm.html }} + </div> + <p><input type="submit" value="Sumbit Trip Report" /></p> +</form> + +{% endblock %} diff --git a/templates/entrance.html b/templates/entrance.html index 7aa7fe8..29d0131 100644 --- a/templates/entrance.html +++ b/templates/entrance.html @@ -1,80 +1,80 @@ -{% extends "base.html" %}
-{% load wiki_markup %}
-
-
-{% block title %}{{ cave.official_name|wiki_to_html }} - {{ entrance_letter|wiki_to_html }}{% endblock %}
-
-{% block content %}
-<table id="cavepage">
-<tr>
- <th id="kat_no">
- {% if cave.kataster_number %}
- {{ cave.kataster_number|wiki_to_html }}{{ letter|wiki_to_html }}
- {% if cave.unofficial_number %}
- <br />({{ cave.unofficial_number|wiki_to_html }})
- {% endif %}
- {% endif %}
- </th>
- <th id="name">
- {% if entrance.name %}
- {{ entrance.name|wiki_to_html }}
- {% else %}
- Unnamed
- {% endif %} - {{ cave.official_name|wiki_to_html }}
- </th>
- <th id="status">
- {{ cave.kataster_code|wiki_to_html }}
- </th>
-</tr>
-</table>
-
-{% if entrance.entrance_description %}
- <h2>Entrance Description</h2>
- {{ entrance.entrance_description|wiki_to_html }}
-{% endif %}
-{% if entrance.explorers %}
- <h2>Explorers</h2>
- {{ entrance.explorers|wiki_to_html }}
-{% endif %}
-{% if entrance.map_description %}
- <h2>Map</h2>
- {{ entrance.map_description|wiki_to_html }}
-{% endif %}
-{% if entrance.explorers %}
- <h2>Entrance Description</h2>
- {{ entrance.entrance_description|wiki_to_html }}
-{% endif %}
-{% if entrance.location_description %}
- <h2>Location Description</h2>
- {{ entrance.location_description|wiki_to_html }}
-{% endif %}
-{% if entrance.approach %}
- <h2>Approach</h2>
- {{ entrance.approach|wiki_to_html }}
-{% endif %}
-{% if entrance.underground_description %}
- <h2>Underground Description</h2>
- {{ entrance.underground_description|wiki_to_html }}
-{% endif %}
-{% if entrance.photo %}
- <h2>Photo</h2>
- {{ entrance.photo|wiki_to_html }}
-{% endif %}
-{% if entrance.marking %}
- <h2>Marking - {{ entrance.marking_val|wiki_to_html }}</h2>
- {% if entrance.marking_comment %}
- {{ entrance.marking_comment|wiki_to_html }}
- {% endif %}
-{% endif %}
-{% if entrance.findability %}
- <h2>Findability - {{ entrance.findability_val|wiki_to_html }}</h2>
- {% if entrance.findability_description %}
- {{ entrance.findability_description|wiki_to_html }}
- {% endif %}
-{% endif %}
-{% if entrance.bearings %}
- <h2>Bearings</h2>
- {{ entrance.bearings|wiki_to_html }}
-{% endif %}
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} + + +{% block title %}{{ cave.official_name|wiki_to_html }} - {{ entrance_letter|wiki_to_html }}{% endblock %} + +{% block content %} +<table id="cavepage"> +<tr> + <th id="kat_no"> + {% if cave.kataster_number %} + {{ cave.kataster_number|wiki_to_html }}{{ letter|wiki_to_html }} + {% if cave.unofficial_number %} + <br />({{ cave.unofficial_number|wiki_to_html }}) + {% endif %} + {% endif %} + </th> + <th id="name"> + {% if entrance.name %} + {{ entrance.name|wiki_to_html }} + {% else %} + Unnamed + {% endif %} - {{ cave.official_name|wiki_to_html }} + </th> + <th id="status"> + {{ cave.kataster_code|wiki_to_html }} + </th> +</tr> +</table> + +{% if entrance.entrance_description %} + <h2>Entrance Description</h2> + {{ entrance.entrance_description|wiki_to_html }} +{% endif %} +{% if entrance.explorers %} + <h2>Explorers</h2> + {{ entrance.explorers|wiki_to_html }} +{% endif %} +{% if entrance.map_description %} + <h2>Map</h2> + {{ entrance.map_description|wiki_to_html }} +{% endif %} +{% if entrance.explorers %} + <h2>Entrance Description</h2> + {{ entrance.entrance_description|wiki_to_html }} +{% endif %} +{% if entrance.location_description %} + <h2>Location Description</h2> + {{ entrance.location_description|wiki_to_html }} +{% endif %} +{% if entrance.approach %} + <h2>Approach</h2> + {{ entrance.approach|wiki_to_html }} +{% endif %} +{% if entrance.underground_description %} + <h2>Underground Description</h2> + {{ entrance.underground_description|wiki_to_html }} +{% endif %} +{% if entrance.photo %} + <h2>Photo</h2> + {{ entrance.photo|wiki_to_html }} +{% endif %} +{% if entrance.marking %} + <h2>Marking - {{ entrance.marking_val|wiki_to_html }}</h2> + {% if entrance.marking_comment %} + {{ entrance.marking_comment|wiki_to_html }} + {% endif %} +{% endif %} +{% if entrance.findability %} + <h2>Findability - {{ entrance.findability_val|wiki_to_html }}</h2> + {% if entrance.findability_description %} + {{ entrance.findability_description|wiki_to_html }} + {% endif %} +{% endif %} +{% if entrance.bearings %} + <h2>Bearings</h2> + {{ entrance.bearings|wiki_to_html }} +{% endif %} + +{% endblock %} diff --git a/templates/expedition.html b/templates/expedition.html index 814b77e..4fab025 100644 --- a/templates/expedition.html +++ b/templates/expedition.html @@ -1,87 +1,87 @@ -{% extends "base.html" %}
-{% load wiki_markup %}
-{% load link %}
-
-{% block title %}Expedition {{expedition.name}}{% endblock %}
-{% block editLink %}<a href={{expedition.get_admin_url}}>Edit expedition {{expedition|wiki_to_html_short}}</a>{% endblock %}
-
-{% block related %}
-{% endblock %}
-
-{% block content %}
-
-{% if message %}
-<p>debug message: {{message}}</p>
-{% endif %}
-
-<h2>{{expedition.name}}</h2>
-
-<p><b>Other years:</b>
-{% for otherexpedition in expeditions %}
- {% ifequal otherexpedition expedition %}
- | <b>{{otherexpedition.year}}</b>
- {% else %}
- | <a href="{{otherexpedition.get_absolute_url}}">{{ otherexpedition.year }}</a>
- {% endifequal %}
-{% endfor %}
-</p>
-
-<p><b>At a single glance:</b> The table shows all expo cavers and their recorded trips.
-The columns are the date in the month (July or August), with a "T" for a logbook entry, and
-an "S" for a survey trip. The colours are the same for people on the same trip.</p>
-
-<table class="expeditionpersonlist">
-<tr>
-<th>Caver</th>
-{% for expeditionday in expedition.expeditionday_set.all %}
-<th>
- {{expeditionday.date.day}}
-</th>
-{% endfor %}
-</tr>
-{% for personexpeditionday in personexpeditiondays %}
- <tr>
- <td><a href="{{ personexpeditionday.personexpedition.get_absolute_url }}">{{personexpeditionday.personexpedition.person}}</a></td>
- {% for persondayactivities in personexpeditionday.personrow %}
-
- {% if persondayactivities.persontrips or persondayactivities.survexblocks %}
- <td class="persondayactivity">
- {% for persontrip in persondayactivities.persontrips %}
- <a href="{{persontrip.logbook_entry.get_absolute_url}}" class="dayindexlog-{{persontrip.logbook_entry.DayIndex}}">T</a>
- {% endfor %}
- <br/>
- {% for survexblock in persondayactivities.survexblocks %}
- <a href="{% url svx survexblock.survexfile.path %}" class="dayindexsurvex-{{survexblock.DayIndex}}">S</a>
- {% endfor %}
- </td>
- {% else %}
- <td class="persondayactivity-nothing">
- </td>
- {% endif %}
-
- {% endfor %}
- </tr>
-{% endfor %}
-</table>
-
-<form action="" method="GET"><input type="submit" name="reload" value="Reload"></form>
-
-<h3>Logbooks and survey trips per day</h3>
-<a href="{% url newLogBookEntry expeditionyear=expedition.year %}">New logbook entry</a>
-<table class="expeditionlogbooks">
-<tr><th>Date</th><th>Logged trips</th><th>Surveys</th></tr>
-{% regroup dateditems|dictsort:"date" by date as dates %}
-{% for date in dates %}
-<tr>
-<td>{{date.grouper}}</td>
-<td>{% for item in date.list %}
- {% if item.isLogbookEntry %}<a href="{{ item.get_absolute_url }}">{{item.title|safe}}</a><br/>{% endif %}
- {% endfor %}</td>
-<td>{% for item in date.list %}
- {% if item.isSurvexBlock %}<a href="{% url svx item.survexfile.path %}">{{item.name}}</a><br/>{% endif %}
- {% endfor %}</td>
-</tr>
-{% endfor %}
-</table>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}Expedition {{expedition.name}}{% endblock %} +{% block editLink %}<a href={{expedition.get_admin_url}}>Edit expedition {{expedition|wiki_to_html_short}}</a>{% endblock %} + +{% block related %} +{% endblock %} + +{% block content %} + +{% if message %} +<p>debug message: {{message}}</p> +{% endif %} + +<h2>{{expedition.name}}</h2> + +<p><b>Other years:</b> +{% for otherexpedition in expeditions %} + {% ifequal otherexpedition expedition %} + | <b>{{otherexpedition.year}}</b> + {% else %} + | <a href="{{otherexpedition.get_absolute_url}}">{{ otherexpedition.year }}</a> + {% endifequal %} +{% endfor %} +</p> + +<p><b>At a single glance:</b> The table shows all expo cavers and their recorded trips. +The columns are the date in the month (July or August), with a "T" for a logbook entry, and +an "S" for a survey trip. The colours are the same for people on the same trip.</p> + +<table class="expeditionpersonlist"> +<tr> +<th>Caver</th> +{% for expeditionday in expedition.expeditionday_set.all %} +<th> + {{expeditionday.date.day}} +</th> +{% endfor %} +</tr> +{% for personexpeditionday in personexpeditiondays %} + <tr> + <td><a href="{{ personexpeditionday.personexpedition.get_absolute_url }}">{{personexpeditionday.personexpedition.person}}</a></td> + {% for persondayactivities in personexpeditionday.personrow %} + + {% if persondayactivities.persontrips or persondayactivities.survexblocks %} + <td class="persondayactivity"> + {% for persontrip in persondayactivities.persontrips %} + <a href="{{persontrip.logbook_entry.get_absolute_url}}" class="dayindexlog-{{persontrip.logbook_entry.DayIndex}}">T</a> + {% endfor %} + <br/> + {% for survexblock in persondayactivities.survexblocks %} + <a href="{% url svx survexblock.survexfile.path %}" class="dayindexsurvex-{{survexblock.DayIndex}}">S</a> + {% endfor %} + </td> + {% else %} + <td class="persondayactivity-nothing"> + </td> + {% endif %} + + {% endfor %} + </tr> +{% endfor %} +</table> + +<form action="" method="GET"><input type="submit" name="reload" value="Reload"></form> + +<h3>Logbooks and survey trips per day</h3> +<a href="{% url newLogBookEntry expeditionyear=expedition.year %}">New logbook entry</a> +<table class="expeditionlogbooks"> +<tr><th>Date</th><th>Logged trips</th><th>Surveys</th></tr> +{% regroup dateditems|dictsort:"date" by date as dates %} +{% for date in dates %} +<tr> +<td>{{date.grouper}}</td> +<td>{% for item in date.list %} + {% if item.isLogbookEntry %}<a href="{{ item.get_absolute_url }}">{{item.title|safe}}</a><br/>{% endif %} + {% endfor %}</td> +<td>{% for item in date.list %} + {% if item.isSurvexBlock %}<a href="{% url svx item.survexfile.path %}">{{item.name}}</a><br/>{% endif %} + {% endfor %}</td> +</tr> +{% endfor %} +</table> + +{% endblock %} diff --git a/templates/eyecandy.html b/templates/eyecandy.html index a1b9b3f..1e8def6 100644 --- a/templates/eyecandy.html +++ b/templates/eyecandy.html @@ -1,3 +1,3 @@ -<img id="richardBanner" class="footer" src="{{ settings.MEDIA_URL }}expoBanner.gif" style="display: none;"/>
-<img id="timeMachine" class="footer" src="{{ settings.MEDIA_URL }}timemachine.gif" style="display: none;"/>
+<img id="richardBanner" class="footer" src="{{ settings.MEDIA_URL }}expoBanner.gif" style="display: none;"/> +<img id="timeMachine" class="footer" src="{{ settings.MEDIA_URL }}timemachine.gif" style="display: none;"/> <img id="surveyHover" class="footer" src="{{ settings.MEDIA_URL }}surveyHover.gif" style="display: none;"/>
\ No newline at end of file diff --git a/templates/fileupload.html b/templates/fileupload.html index d1db6ca..f71760d 100644 --- a/templates/fileupload.html +++ b/templates/fileupload.html @@ -1,18 +1,18 @@ -<h2>Fileupload</h2>
-
-<ul>
-{% for fileuploaded in filesuploaded %}
-<li>UPLOADEDFILE: {{fileuploaded}}
-</li>
-{% endfor %}
-</ul>
-<p>MESSAGE: {{message}}
-</p>
-
-{% if not filesuploaded %}
-<form action="" method="POST">
- <p>file to upload</p>
- <p><input type="file" name="file1"/></p>
- <p><input type="submit" name="submit" value="Submit" /></p>
-</form>
-{% endif %}
+<h2>Fileupload</h2> + +<ul> +{% for fileuploaded in filesuploaded %} +<li>UPLOADEDFILE: {{fileuploaded}} +</li> +{% endfor %} +</ul> +<p>MESSAGE: {{message}} +</p> + +{% if not filesuploaded %} +<form action="" method="POST"> + <p>file to upload</p> + <p><input type="file" name="file1"/></p> + <p><input type="submit" name="submit" value="Submit" /></p> +</form> +{% endif %} diff --git a/templates/frontpage.html b/templates/frontpage.html index 873f198..2c1456c 100644 --- a/templates/frontpage.html +++ b/templates/frontpage.html @@ -1,68 +1,68 @@ -{% extends "base.html" %}
-{% load wiki_markup %}
-
-{% block title %}Cambridge Expeditions to Austria{% endblock %}
-
- {% block related %}
- <h2>Recent Actions</h2>
- {% load log %}
- {% get_admin_log 10 as admin_log %}
- {% if not admin_log %}
- <p>No recent actions</p>
- {% else %}
- <ul class="actionlist">
- {% for entry in admin_log %}
- <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
- {% if entry.is_deletion %}
- {{ entry.object_repr }}
- {% else %}
- <a href="admin/{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
- {% endif %}
- <br/>
- {% if entry.content_type %}
- <span class="mini quiet">{% filter capfirst %}{{entry.content_type.name}}{% endfilter %}</span>
- {% else %}
- <span class="mini quiet">Unknown content</span>
- {% endif %}
- </li>
- {% endfor %}
- </ul>
- {% endif %}
- {% endblock %}
-
-{% block content %}
-
-
-
-
-<div id="col1">
-<h3>Welcome</h3>
-<p class="indent">
-This is Troggle, the information portal for Cambridge University Caving Club's Expeditions to Austria.
-</p>
-
-<p class="indent">
-Here you will find information about the {{expedition.objects.count}} expeditions the club has undertaken since 1976. Browse survey information, photos, and description wikis for {{cave.objects.count}} caves, {{subcave.objects.count}} areas within those caves, and {{extantqms.count}} going leads yet to be explored. We have {{photo.objects.count}} photos and {{logbookentry.objects.count}} logbook entries.
-</p>
-
-<p class="indent">
-If you are an expedition member, please sign up using the link to the top right and begin editing.
-</p>
-
-<h3>News</h3>
-
-<p class="indent">
-Everyone is gearing up for the 2009 expedition; please see the link below for the main expedition website.
-</p>
-
-<h3>Troggle development</h3>
-<p class="indent">
-Troggle is still under development. Check out the <a href="http://troggle.googlecode.com">development page</a> on google code, where you can file bug reports, make suggestions, and help develop the code. There is also an old todo list at <a href="{%url todo%}">here</a>.
-</p>
-</div>
-{% endblock content %}
-
-{% block margins %}
-<img class="leftMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}eieshole.jpg">
-<img class="rightMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}goesser.jpg">
+{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Cambridge Expeditions to Austria{% endblock %} + + {% block related %} + <h2>Recent Actions</h2> + {% load log %} + {% get_admin_log 10 as admin_log %} + {% if not admin_log %} + <p>No recent actions</p> + {% else %} + <ul class="actionlist"> + {% for entry in admin_log %} + <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}"> + {% if entry.is_deletion %} + {{ entry.object_repr }} + {% else %} + <a href="admin/{{ entry.get_admin_url }}">{{ entry.object_repr }}</a> + {% endif %} + <br/> + {% if entry.content_type %} + <span class="mini quiet">{% filter capfirst %}{{entry.content_type.name}}{% endfilter %}</span> + {% else %} + <span class="mini quiet">Unknown content</span> + {% endif %} + </li> + {% endfor %} + </ul> + {% endif %} + {% endblock %} + +{% block content %} + + + + +<div id="col1"> +<h3>Welcome</h3> +<p class="indent"> +This is Troggle, the information portal for Cambridge University Caving Club's Expeditions to Austria. +</p> + +<p class="indent"> +Here you will find information about the {{expedition.objects.count}} expeditions the club has undertaken since 1976. Browse survey information, photos, and description wikis for {{cave.objects.count}} caves, {{subcave.objects.count}} areas within those caves, and {{extantqms.count}} going leads yet to be explored. We have {{photo.objects.count}} photos and {{logbookentry.objects.count}} logbook entries. +</p> + +<p class="indent"> +If you are an expedition member, please sign up using the link to the top right and begin editing. +</p> + +<h3>News</h3> + +<p class="indent"> +Everyone is gearing up for the 2009 expedition; please see the link below for the main expedition website. +</p> + +<h3>Troggle development</h3> +<p class="indent"> +Troggle is still under development. Check out the <a href="http://troggle.googlecode.com">development page</a> on google code, where you can file bug reports, make suggestions, and help develop the code. There is also an old todo list at <a href="{%url todo%}">here</a>. +</p> +</div> +{% endblock content %} + +{% block margins %} +<img class="leftMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}eieshole.jpg"> +<img class="rightMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}goesser.jpg"> {% endblock margins %}
\ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 525b2d9..c0974e8 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,59 +1,59 @@ -{% extends "base.html" %}
-{% load wiki_markup %}
-
-{% block title %}Cambridge Expeditions to Austria{% endblock %}
-
-{% block content %}
-
-<h2>The unfinished front page</h2>
-<ul>
- <li><b>About {{totallogbookentries}} logbook entries have been loaded</b></li>
- <li><b><a href="{% url personindex %}">List of People</a></b></li>
- <li><b><a href="{% url caveindex %}">List of Caves</a></b></li>
- <li><a href="{% url jgtfile aaaa %}">JGT list of files</a> (temporary simple file list and tunnel use)</li>
- <li><a href="{% url survey %}">Survey files</a></li>
- <li><a href="{% url svx all %}">Survex directory</a></li>
- <li><a href="{% url expedition 2008 %}">Expedition 2008</a></li>
- <li><a href="{% url expedition 2007 %}">Expedition 2007</a></li>
- <li><a href="{% url expedition 1992 %}">Expedition 1992</a> (earliest parsed)</li>
-</ul>
-
-<h2>Further work</h2>
-
-<p>Julian's work:
-<p>parse 1976-1991 logbooks; (esp top 161)</p>
-<p>detect T/U on log entries; </p>
-<p>name matching and spelling in survex files; </p>
-<p>Improve logbook wikihtml text</p>
-
-<p>Other work:</p>
-<p>surf through the tunnel sketches and images</p>
-<p>bugs with all.svx block (double dot)
-<p>render bitmap view of every survex block as a thumbnail</p>
-<p>upload tunnel images and tunnel sketches</p>
-<p>where are the subcaves; </p>
-<p>cave section entrance match for logbook entries</p>
-<p>simplify the survex parsing code (if necessary); </p>
-<p>wiki survex stop linegap between comment lins</p>
-<p>links between logbooks and survex blocks to cave things; </p>
-<p>mini-tree of survexblocks; </p>
-<p>connect sketches to caves to survey blocks and render thumbnailwise; </p>
-<p>all images to start appearing in pages; and so on</p>
-
-<h3>{{message}}</h3>
-
-<form action="" method="GET">
- <input type="submit" name="reloadexpos" value="Reload Expos">
- <input type="submit" name="reloadsurvex" value="Reload Survex">
-</form>
-
-<ul id="expeditionlist">
-{% for expedition in expeditions %}
-<li>
- <a href="{% url expedition expedition.year %}">{{expedition.name}}</a>
- - <b>{{expedition.logbookentry_set.count}}</b> logbook entries
-</li>
-{% endfor %}
-</ul>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Cambridge Expeditions to Austria{% endblock %} + +{% block content %} + +<h2>The unfinished front page</h2> +<ul> + <li><b>About {{totallogbookentries}} logbook entries have been loaded</b></li> + <li><b><a href="{% url personindex %}">List of People</a></b></li> + <li><b><a href="{% url caveindex %}">List of Caves</a></b></li> + <li><a href="{% url jgtfile aaaa %}">JGT list of files</a> (temporary simple file list and tunnel use)</li> + <li><a href="{% url survey %}">Survey files</a></li> + <li><a href="{% url svx all %}">Survex directory</a></li> + <li><a href="{% url expedition 2008 %}">Expedition 2008</a></li> + <li><a href="{% url expedition 2007 %}">Expedition 2007</a></li> + <li><a href="{% url expedition 1992 %}">Expedition 1992</a> (earliest parsed)</li> +</ul> + +<h2>Further work</h2> + +<p>Julian's work: +<p>parse 1976-1991 logbooks; (esp top 161)</p> +<p>detect T/U on log entries; </p> +<p>name matching and spelling in survex files; </p> +<p>Improve logbook wikihtml text</p> + +<p>Other work:</p> +<p>surf through the tunnel sketches and images</p> +<p>bugs with all.svx block (double dot) +<p>render bitmap view of every survex block as a thumbnail</p> +<p>upload tunnel images and tunnel sketches</p> +<p>where are the subcaves; </p> +<p>cave section entrance match for logbook entries</p> +<p>simplify the survex parsing code (if necessary); </p> +<p>wiki survex stop linegap between comment lins</p> +<p>links between logbooks and survex blocks to cave things; </p> +<p>mini-tree of survexblocks; </p> +<p>connect sketches to caves to survey blocks and render thumbnailwise; </p> +<p>all images to start appearing in pages; and so on</p> + +<h3>{{message}}</h3> + +<form action="" method="GET"> + <input type="submit" name="reloadexpos" value="Reload Expos"> + <input type="submit" name="reloadsurvex" value="Reload Survex"> +</form> + +<ul id="expeditionlist"> +{% for expedition in expeditions %} +<li> + <a href="{% url expedition expedition.year %}">{{expedition.name}}</a> + - <b>{{expedition.logbookentry_set.count}}</b> logbook entries +</li> +{% endfor %} +</ul> + +{% endblock %} diff --git a/templates/listdir.html b/templates/listdir.html index a3b677f..7f83b5a 100644 --- a/templates/listdir.html +++ b/templates/listdir.html @@ -1,22 +1,22 @@ -<h2>List file :{{file}}:</h2>
-
-<h3>Files</h3>
-<ul>
-{% for lf in listdirfiles %}
-<li><a href="{% url jgtfile lf.0 %}">{{lf.1}}</a> ({{lf.2}} bytes)</li>
-{% endfor %}
-</ul>
-
-<h3>Upperdirectories</h3>
-<ul>
-{% for lf in upperdirs %}
-<li><a href="{% url jgtfile lf.0 %}">{{lf.1}}</a></li>
-{% endfor %}
-</ul>
-
-<h3>Subdirectories</h3>
-<ul>
-{% for lf in listdirdirs %}
-<li><a href="{% url jgtfile lf.0 %}">{{lf.1}}</a> ({{lf.2}} files)</li>
-{% endfor %}
-</ul>
+<h2>List file :{{file}}:</h2> + +<h3>Files</h3> +<ul> +{% for lf in listdirfiles %} +<li><a href="{% url jgtfile lf.0 %}">{{lf.1}}</a> ({{lf.2}} bytes)</li> +{% endfor %} +</ul> + +<h3>Upperdirectories</h3> +<ul> +{% for lf in upperdirs %} +<li><a href="{% url jgtfile lf.0 %}">{{lf.1}}</a></li> +{% endfor %} +</ul> + +<h3>Subdirectories</h3> +<ul> +{% for lf in listdirdirs %} +<li><a href="{% url jgtfile lf.0 %}">{{lf.1}}</a> ({{lf.2}} files)</li> +{% endfor %} +</ul> diff --git a/templates/logbook2005style.html b/templates/logbook2005style.html index b0cb240..af320a3 100644 --- a/templates/logbook2005style.html +++ b/templates/logbook2005style.html @@ -1,26 +1,26 @@ -<html>
-<head><title>{{logbook_entries.0.expedition}} Expo Logbook</title></head>
-<link rel="stylesheet" type="text/css" href="../../css/main2.css" />
-<style type="text/css">
-.tripdate { float: left;}
-.trippeople { float: right;}
-.triptitle { font-size: 120%; text-align: center; font-weight: bold; clear: both }
-.timeug { text-align: right; font-weight: bold }
-p { clear: both }
-</style>
-<body>
-
-<h1>Expo {{logbook_entries.0.expedition}}</h1>
-
-{%for logbook_entry in logbook_entries%}
-<hr />
-
-<div class="tripdate" id="t{{logbook_entry.date}}A">{{logbook_entry.date}}</div>
-<div class="trippeople"><u>{{logbook_entry.author.person}}</u>
-{% for persontrip in logbook_entry.persontrip_set.all %}{{ persontrip.personexpedition.person }} {{ persontrip.personexpedition.time_underground }}, {% endfor %}
-</div>
-
-<div class="triptitle">{{logbook_entry.place}} - {{logbook_entry.title}}</div>
-
-{{logbook_entry.text|safe}}
-{% endfor %}
+<html> +<head><title>{{logbook_entries.0.expedition}} Expo Logbook</title></head> +<link rel="stylesheet" type="text/css" href="../../css/main2.css" /> +<style type="text/css"> +.tripdate { float: left;} +.trippeople { float: right;} +.triptitle { font-size: 120%; text-align: center; font-weight: bold; clear: both } +.timeug { text-align: right; font-weight: bold } +p { clear: both } +</style> +<body> + +<h1>Expo {{logbook_entries.0.expedition}}</h1> + +{%for logbook_entry in logbook_entries%} +<hr /> + +<div class="tripdate" id="t{{logbook_entry.date}}A">{{logbook_entry.date}}</div> +<div class="trippeople"><u>{{logbook_entry.author.person}}</u> +{% for persontrip in logbook_entry.persontrip_set.all %}{{ persontrip.personexpedition.person }} {{ persontrip.personexpedition.time_underground }}, {% endfor %} +</div> + +<div class="triptitle">{{logbook_entry.place}} - {{logbook_entry.title}}</div> + +{{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 %}<a href={{logbookentry.get_admin_url}}>Edit logbook entry {{logbookentry|wiki_to_html_short}}</a>{% endblock %}
-{% block content %}
-
-{% block related %}{% endblock %}
-{% block nav %}{% endblock %}
-<h2>{{logbookentry.title}}</h2>
-
-<div id="related">
-<p><a href="{{ logbookentry.expedition.get_absolute_url }}">{{logbookentry.expedition.name}}</a></p>
-
-{% if logbookentry.cave %}
- <p>place: <a href="{{ logbookentry.cave.get_absolute_url }}">{{logbookentry.place}}</p>
-{% else %}
- <p>{{logbookentry.place}}</p>
-{% endif %}
-
-<p>
- {% if logbookentry.get_previous_by_date %}
- <a href="{{ logbookentry.get_previous_by_date.get_absolute_url }}">{{logbookentry.get_previous_by_date.date}}</a>
- {% endif %}
- {% if logbookentry.get_next_by_date %}
- <a href="{{ logbookentry.get_next_by_date.get_absolute_url }}">{{logbookentry.get_next_by_date.date}}</a>
- {% endif %}
-</p>
-
-<table class="cavers">
-<tr><th>Caver</th><th>T/U</th><th>Prev</th><th>Next</th></tr>
-{% for persontrip in logbookentry.persontrip_set.all %}
-<tr>
- {% ifequal persontrip.personexpedition logbookentry.author %}
- <td class="author">
- {% else %}
- <td>
- {% endifequal %}
- <a href="{{ persontrip.personexpedition.get_absolute_url }}">{{persontrip.personexpedition.person}}</a>
- </td>
-
- <td>
- {% if persontrip.timeunderground %}
- - T/U {{persontrip.timeunderground}}</p>
- {% endif %}
- </td>
-
- <td>
- {% if persontrip.persontrip_prev %}
- <a href="{{ persontrip.persontrip_prev.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_prev.logbook_entry.date}}</a>
- {% endif %}
- </td>
- <td>
- {% if persontrip.persontrip_next %}
- <a href="{{ persontrip.persontrip_next.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_next.logbook_entry.date}}</a>
- {% endif %}
- </td>
-
-</tr>
-{% endfor %}
-</table>
-{% if newQMlink %}
-<a href="{{newQMlink}}">Add QM found on this trip</a>
-{% endif %}
-</div>
-
-<div id="col1">
-<div class="logbookentry">
-<b>{{logbookentry.date}}</b>
- {{logbookentry.text|wiki_to_html}}</div>
-</div>
-</div>
-
-{% if logbookentry.filename %}<a href="{% url editLogBookEntry expeditionyear=logbookentry.expedition.year pdate=logbookentry.date pslug=logbookentry.slug %}">Edit</a> <a href="{% url deleteLogBookEntry expeditionyear=logbookentry.expedition.year date=logbookentry.date slug=logbookentry.slug %}">Delete</a>{%endif%}
-
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Logbook {{logbookentry.id}}{% endblock %} +{% block editLink %}<a href={{logbookentry.get_admin_url}}>Edit logbook entry {{logbookentry|wiki_to_html_short}}</a>{% endblock %} +{% block content %} + +{% block related %}{% endblock %} +{% block nav %}{% endblock %} +<h2>{{logbookentry.title}}</h2> + +<div id="related"> +<p><a href="{{ logbookentry.expedition.get_absolute_url }}">{{logbookentry.expedition.name}}</a></p> + +{% if logbookentry.cave %} + <p>place: <a href="{{ logbookentry.cave.get_absolute_url }}">{{logbookentry.place}}</p> +{% else %} + <p>{{logbookentry.place}}</p> +{% endif %} + +<p> + {% if logbookentry.get_previous_by_date %} + <a href="{{ logbookentry.get_previous_by_date.get_absolute_url }}">{{logbookentry.get_previous_by_date.date}}</a> + {% endif %} + {% if logbookentry.get_next_by_date %} + <a href="{{ logbookentry.get_next_by_date.get_absolute_url }}">{{logbookentry.get_next_by_date.date}}</a> + {% endif %} +</p> + +<table class="cavers"> +<tr><th>Caver</th><th>T/U</th><th>Prev</th><th>Next</th></tr> +{% for persontrip in logbookentry.persontrip_set.all %} +<tr> + {% ifequal persontrip.personexpedition logbookentry.author %} + <td class="author"> + {% else %} + <td> + {% endifequal %} + <a href="{{ persontrip.personexpedition.get_absolute_url }}">{{persontrip.personexpedition.person}}</a> + </td> + + <td> + {% if persontrip.timeunderground %} + - T/U {{persontrip.timeunderground}}</p> + {% endif %} + </td> + + <td> + {% if persontrip.persontrip_prev %} + <a href="{{ persontrip.persontrip_prev.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_prev.logbook_entry.date}}</a> + {% endif %} + </td> + <td> + {% if persontrip.persontrip_next %} + <a href="{{ persontrip.persontrip_next.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_next.logbook_entry.date}}</a> + {% endif %} + </td> + +</tr> +{% endfor %} +</table> +{% if newQMlink %} +<a href="{{newQMlink}}">Add QM found on this trip</a> +{% endif %} +</div> + +<div id="col1"> +<div class="logbookentry"> +<b>{{logbookentry.date}}</b> + {{logbookentry.text|wiki_to_html}}</div> +</div> +</div> + +{% if logbookentry.filename %}<a href="{% url editLogBookEntry expeditionyear=logbookentry.expedition.year pdate=logbookentry.date pslug=logbookentry.slug %}">Edit</a> <a href="{% url deleteLogBookEntry expeditionyear=logbookentry.expedition.year date=logbookentry.date slug=logbookentry.slug %}">Delete</a>{%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 %}
-<script>
- $(function() {
- $("#id_date").datepicker({dateFormat: "yy-mm-dd"});
- $('.persontrips tbody tr').formset();
- $(":radio[name*='caveOrLocation']").change(setLocationType);
- $(setLocationType());
- function setLocationType () {
- $("#cave").hide();
- $("#location").hide();
- $("#" + $(":radio[name*='caveOrLocation']:checked")[0].value).show();
- };
-
- });
-
-</script>
-<link rel="stylesheet" href="{{ settings.MEDIA_URL }}css/ui-lightness/jquery-ui-1.8.12.custom.css" type="text/css" media="all" />
-<script src="{{ settings.MEDIA_URL }}js/jquery-ui-1.8.12.custom.min.js" type="text/javascript"></script>
-<script src="{{ settings.MEDIA_URL }}js/jquery.formset.min.js" type="text/javascript"></script>
-<script src="{{ settings.TINY_MCE_MEDIA_URL }}tiny_mce.js" type="text/javascript"></script>
-{{ tripForm.media }}
-{% endblock %}
-{% block content %}
-
-<form action="" method="post">{% csrf_token %}
- {{ tripForm.non_field_errors }}
- <div class="fieldWrapper">
- {{ tripForm.title.errors }}
- <label for="id_title">Title:</label>
- {{ tripForm.title }}
- </div>
- <div class="fieldWrapper">
- {{ tripForm.date.errors }}
- <label for="id_date">Date:</label>
- {{ tripForm.date }}
- </div>
- <div class="fieldWrapper">
- {{ tripForm.caveOrLocation.errors }}
- <label for="id_caveOrLocation">Location Type:</label>
- {{ tripForm.caveOrLocation }}
- </div>
- <div class="fieldWrapper" id="cave">
- {{ tripForm.cave.errors }}
- <label for="id_cave">Cave:</label>
- {{ tripForm.cave }}
- </div>
- <div class="fieldWrapper" id="location">
- {{ tripForm.location.errors }}
- <label for="id_location">Location:</label>
- {{ tripForm.location }}
- </div>
- <table class="persontrips" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <th>Person</th>
- <th>TU /hours</th>
- <th>Author</th>
- <th></th>
- </tr>
- {% for form in personTripFormSet.forms %}
- <tr>
- <td>{{ form.name.errors }}{{ form.name }}</td>
- <td>{{ form.TU.errors }}{{ form.TU }}</td>
- <td>{{ form.author.errors }}{{ form.author }}</td>
- <td></td>
- {{ form.non_field_errors }}
- </tr>
- {% endfor %}
- </tbody>
- </table>
- {{ personTripFormSet.management_form }}
- <div class="fieldWrapper">
- {{ tripForm.html.errors }}
- <label for="id_date">Content:</label>
- {{ tripForm.html }}
- </div>
- <p><input type="submit" value="Sumbit Trip Report" /></p>
-</form>
-
-{% endblock %}
+{% extends "base.html" %} +{% load csrffaker %} +{% block title %}Logbook {{logbookentry.id}}{% endblock %} +{% block head %} +<script> + $(function() { + $("#id_date").datepicker({dateFormat: "yy-mm-dd"}); + $('.persontrips tbody tr').formset(); + $(":radio[name*='caveOrLocation']").change(setLocationType); + $(setLocationType()); + function setLocationType () { + $("#cave").hide(); + $("#location").hide(); + $("#" + $(":radio[name*='caveOrLocation']:checked")[0].value).show(); + }; + + }); + +</script> +<link rel="stylesheet" href="{{ settings.MEDIA_URL }}css/ui-lightness/jquery-ui-1.8.12.custom.css" type="text/css" media="all" /> +<script src="{{ settings.MEDIA_URL }}js/jquery-ui-1.8.12.custom.min.js" type="text/javascript"></script> +<script src="{{ settings.MEDIA_URL }}js/jquery.formset.min.js" type="text/javascript"></script> +<script src="{{ settings.TINY_MCE_MEDIA_URL }}tiny_mce.js" type="text/javascript"></script> +{{ tripForm.media }} +{% endblock %} +{% block content %} + +<form action="" method="post">{% csrf_token %} + {{ tripForm.non_field_errors }} + <div class="fieldWrapper"> + {{ tripForm.title.errors }} + <label for="id_title">Title:</label> + {{ tripForm.title }} + </div> + <div class="fieldWrapper"> + {{ tripForm.date.errors }} + <label for="id_date">Date:</label> + {{ tripForm.date }} + </div> + <div class="fieldWrapper"> + {{ tripForm.caveOrLocation.errors }} + <label for="id_caveOrLocation">Location Type:</label> + {{ tripForm.caveOrLocation }} + </div> + <div class="fieldWrapper" id="cave"> + {{ tripForm.cave.errors }} + <label for="id_cave">Cave:</label> + {{ tripForm.cave }} + </div> + <div class="fieldWrapper" id="location"> + {{ tripForm.location.errors }} + <label for="id_location">Location:</label> + {{ tripForm.location }} + </div> + <table class="persontrips" border="0" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <th>Person</th> + <th>TU /hours</th> + <th>Author</th> + <th></th> + </tr> + {% for form in personTripFormSet.forms %} + <tr> + <td>{{ form.name.errors }}{{ form.name }}</td> + <td>{{ form.TU.errors }}{{ form.TU }}</td> + <td>{{ form.author.errors }}{{ form.author }}</td> + <td></td> + {{ form.non_field_errors }} + </tr> + {% endfor %} + </tbody> + </table> + {{ personTripFormSet.management_form }} + <div class="fieldWrapper"> + {{ tripForm.html.errors }} + <label for="id_date">Content:</label> + {{ tripForm.html }} + </div> + <p><input type="submit" value="Sumbit Trip Report" /></p> +</form> + +{% 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 %}
-<h3>Non-public object requested by anonymous user</h3>
-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 %} +<h3>Non-public object requested by anonymous user</h3> +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 %}
-<h1>{{object_list.0.object_name}} objects</h1>
-{% endblock contentheader %}
-
-{% block content %}
- <ul>
- {% for object in object_list %}
- | {{ object|link }}
- {% endfor %} |
- </ul>
+{% extends "base.html" %} +{% load link %} +{% block title %}Troggle: {{object_list.1.meta.object_name}} objects{%endblock%} + +{% block contentheader %} +<h1>{{object_list.0.object_name}} objects</h1> +{% endblock contentheader %} + +{% block content %} + <ul> + {% for object in object_list %} + | {{ object|link }} + {% endfor %} | + </ul> {% 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 %}| <a href={{person.get_admin_url}}>Edit person {{person|wiki_to_html_short}}</a>{% endblock %}
-
-{% block contentheader %}
-<h2> {{person|wiki_to_html_short}} </h2>
-{% endblock %}
-
-{% block content %}
-{% if person.blurb %}
-{{person.blurb|safe}}
-{% endif %}
-
-{% for pic in person.photo_set.all %}
-{% if pic.is_mugshot %}
- <div class="figure">
- <p> <img src="{{ pic.thumbnail_image.url }}" class="thumbnail" />
- <p> {{ pic.caption }}</p>
- <p> <a href="{{ pic.get_admin_url }}">edit {{pic}}</a> </>
- </p>
- </p>
- </div>
-{% endif %}
-{% endfor %}
-<br class="clearfloat" />
-
-<h3>{{person|wiki_to_html_short}} has been on expo in the following years:</h3>
-<p>
-<ul>
-{% for personexpedition in person.personexpedition_set.all %}
- <li> <a href="{{ personexpedition.get_absolute_url }}">{{personexpedition.expedition.year}}</a>
- <span style="padding-left:{{personexpedition.persontrip_set.all|length}}0px; background-color:red"></span>
- {{personexpedition.persontrip_set.all|length}} trips
-</li>
-{% endfor %}
-</ul>
-</p>
-
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Person {{person|wiki_to_html_short}}{% endblock %} + +{% block editLink %}| <a href={{person.get_admin_url}}>Edit person {{person|wiki_to_html_short}}</a>{% endblock %} + +{% block contentheader %} +<h2> {{person|wiki_to_html_short}} </h2> +{% endblock %} + +{% block content %} +{% if person.blurb %} +{{person.blurb|safe}} +{% endif %} + +{% for pic in person.photo_set.all %} +{% if pic.is_mugshot %} + <div class="figure"> + <p> <img src="{{ pic.thumbnail_image.url }}" class="thumbnail" /> + <p> {{ pic.caption }}</p> + <p> <a href="{{ pic.get_admin_url }}">edit {{pic}}</a> </> + </p> + </p> + </div> +{% endif %} +{% endfor %} +<br class="clearfloat" /> + +<h3>{{person|wiki_to_html_short}} has been on expo in the following years:</h3> +<p> +<ul> +{% for personexpedition in person.personexpedition_set.all %} + <li> <a href="{{ personexpedition.get_absolute_url }}">{{personexpedition.expedition.year}}</a> + <span style="padding-left:{{personexpedition.persontrip_set.all|length}}0px; background-color:red"></span> + {{personexpedition.persontrip_set.all|length}} trips +</li> +{% endfor %} +</ul> +</p> + + +{% 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 %}
-<h1>
- <a href="{{personexpedition.person.get_absolute_url}}">{{personexpedition.person}}</a> :
- <a href="{{personexpedition.expedition.get_absolute_url}}">{{personexpedition.expedition}}</a>
-</h1>
-
-<p>{{message}}</p>
-
-<p><b>Other years:</b>
-{% for otherpersonexpedition in personexpedition.person.personexpedition_set.all %}
- {% ifequal otherpersonexpedition personexpedition %}
- | <b>{{otherpersonexpedition.expedition.year}}</b>
- {% else %}
- | <a href="{{otherpersonexpedition.get_absolute_url}}">{{ otherpersonexpedition.expedition.year }}</a>
- {% endifequal %}
-{% endfor %}
-</p>
-
-<h3>Table of all trips and surveys aligned by date</h3>
-<div>
-<table class="survexcontibutions">
-<tr><th>Date</th><th colspan="2">Trips</th><th colspan="2">Surveys</th></tr>
-{% for persondate in personchronology %}
-<tr>
- <td class="date">{{persondate.0}}</td>
-
- {% if persondate.1 %}
- <td class="trip"><a href="{{ persondate.1.logbook_entry.get_absolute_url }}">{{persondate.1.logbook_entry.title|safe}}</a></td>
- <td><a href="{{ persondate.1.logbook_entry.cave.get_absolute_url }}">{{persondate.1.place|safe}}</a></td>
- {% else %}
- <td colspan="2"> </td>
- {% endif %}
-
- {% if persondate.2 %}
- <td class="survexblock"><a href="{% url svx persondate.2.survexfile.path %}">{{persondate.2}}</a></td>
- <td class="roles">
- {% for survexpersonrole in persondate.2.survexpersonrole_set.all %}
- {{survexpersonrole.nrole}}
- {% endfor %}
- </td>
- {% else %}
- <td colspan="2"> </td>
- {% endif %}
-
-</tr>
-{% endfor %}
-</table>
-</div>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}Person {{personexpedition.person|wiki_to_html_short}} for {{personexpedition.expedition}}{% endblock %} + + +{% block content %} +<h1> + <a href="{{personexpedition.person.get_absolute_url}}">{{personexpedition.person}}</a> : + <a href="{{personexpedition.expedition.get_absolute_url}}">{{personexpedition.expedition}}</a> +</h1> + +<p>{{message}}</p> + +<p><b>Other years:</b> +{% for otherpersonexpedition in personexpedition.person.personexpedition_set.all %} + {% ifequal otherpersonexpedition personexpedition %} + | <b>{{otherpersonexpedition.expedition.year}}</b> + {% else %} + | <a href="{{otherpersonexpedition.get_absolute_url}}">{{ otherpersonexpedition.expedition.year }}</a> + {% endifequal %} +{% endfor %} +</p> + +<h3>Table of all trips and surveys aligned by date</h3> +<div> +<table class="survexcontibutions"> +<tr><th>Date</th><th colspan="2">Trips</th><th colspan="2">Surveys</th></tr> +{% for persondate in personchronology %} +<tr> + <td class="date">{{persondate.0}}</td> + + {% if persondate.1 %} + <td class="trip"><a href="{{ persondate.1.logbook_entry.get_absolute_url }}">{{persondate.1.logbook_entry.title|safe}}</a></td> + <td><a href="{{ persondate.1.logbook_entry.cave.get_absolute_url }}">{{persondate.1.place|safe}}</a></td> + {% else %} + <td colspan="2"> </td> + {% endif %} + + {% if persondate.2 %} + <td class="survexblock"><a href="{% url svx persondate.2.survexfile.path %}">{{persondate.2}}</a></td> + <td class="roles"> + {% for survexpersonrole in persondate.2.survexpersonrole_set.all %} + {{survexpersonrole.nrole}} + {% endfor %} + </td> + {% else %} + <td colspan="2"> </td> + {% endif %} + +</tr> +{% endfor %} +</table> +</div> + +{% 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 %}
-
-<h2>Notable expoers</h2>
-<table class="searchable">
-<tr><th>Person</th><th>First</th><th>Last</th><th>Notability</th></tr>
-{% for person in notablepersons %}
-<tr>
- <td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td>
- <td><a href="{{ person.first.get_absolute_url }}">{{ person.first.expedition.year }}</a></td>
- <td><a href="{{ person.last.get_absolute_url }}">{{ person.last.expedition.year }}</a></td>
- <td>{{person.notability}}</td>
-</tr>
-{% endfor %}
-</table>
-
-
-<h2>All expoers</h2>
-<table class="searchable">
-<tr>
-{% for persons in personss %}
-<td>
-
-<table>
-<tr><th>Person</th><th>First</th><th>Last</th><th>Surveyed length</th></tr>
-{% for person in persons %}
-<tr>
- <td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td>
- <td><a href="{{ person.first.get_absolute_url }}">{{person.first.expedition.year}}</a></td>
- <td><a href="{{ person.last.get_absolute_url }}">{{person.last.expedition.year}}</a></td>
- <td>{{ person.surveyedleglength }}</td>
-</tr>
-{% endfor %}
-</table>
-</td>
-{% endfor %}
-</tr>
-</table>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Person Index{% endblock %} + +{% block content %} + +<h2>Notable expoers</h2> +<table class="searchable"> +<tr><th>Person</th><th>First</th><th>Last</th><th>Notability</th></tr> +{% for person in notablepersons %} +<tr> + <td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td> + <td><a href="{{ person.first.get_absolute_url }}">{{ person.first.expedition.year }}</a></td> + <td><a href="{{ person.last.get_absolute_url }}">{{ person.last.expedition.year }}</a></td> + <td>{{person.notability}}</td> +</tr> +{% endfor %} +</table> + + +<h2>All expoers</h2> +<table class="searchable"> +<tr> +{% for persons in personss %} +<td> + +<table> +<tr><th>Person</th><th>First</th><th>Last</th><th>Surveyed length</th></tr> +{% for person in persons %} +<tr> + <td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td> + <td><a href="{{ person.first.get_absolute_url }}">{{person.first.expedition.year}}</a></td> + <td><a href="{{ person.last.get_absolute_url }}">{{person.last.expedition.year}}</a></td> + <td>{{ person.surveyedleglength }}</td> +</tr> +{% endfor %} +</table> +</td> +{% endfor %} +</tr> +</table> + +{% 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 method="post">
-{{ form.as_p }}
-<input type="submit" />
-</form>
-
-{% if form.errors %}
- <p class="errornote">Please correct the errors below</p>
-{% endif %}
+{% extends "base.html" %} + +{% block content %} + +<form method="post"> +{{ form.as_p }} +<input type="submit" /> +</form> + +{% if form.errors %} + <p class="errornote">Please correct the errors below</p> +{% 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 method="post">
-{{ form.as_p }}
-<input type="submit" />
-</form>
-
-{% if form.errors %}
- <p class="errornote">Please correct the errors below</p>
-{% endif %}
+{% extends "base.html" %} + +{% block content %} + +<form method="post"> +{{ form.as_p }} +<input type="submit" /> +</form> + +{% if form.errors %} + <p class="errornote">Please correct the errors below</p> +{% 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 %}
-<h1>Profile for {{ profile }}</h1>
-{% endblock %}
-
-{% block content %}
-
-{{ profile }}
-
-{% if form.errors %}
- <p class="errornote">Please correct the errors below</p>
-{% endif %}
+{% extends "base.html" %} + +{% block contentheader %} +<h1>Profile for {{ profile }}</h1> +{% endblock %} + +{% block content %} + +{{ profile }} + +{% if form.errors %} + <p class="errornote">Please correct the errors below</p> +{% 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 %}
-
-<h2>Troggle profile selection page</h2>
-
-Hello, {{ user }}.
-
-<br /><br />
-
-{% if user.person %}
-This is where you go to associate a new user account with a pre-existing profile from old expo data.
-
-<br /><br />
-
-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: <br /><br /> <a href= {{ user.person.get_absolute_url }}> {{ user.person.get_absolute_url }} </a> <br /><br /> or edit it at:
-<br /><br /> <a href= {{ user.person.get_admin_url }}> {{ user.person.get_admin_url }} </a>.<br /><br />
-
-If your account is associated with the wrong person's profile due to inebriation or incompetance during account setup, click <a href="{{ user.person.get_absolute_url }}/?clear_profile=True">here</a> 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.
-<br /><br />
-
-<form method="post">
-{{ form.as_p }}
-<input name="" type="submit" value="This is me!" />
-</form>
-<br />
-
-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 %}
- <p class="errornote">Please correct the errors below</p>
-{% endif %}
+{% extends "base.html" %} + +{% block content %} + +<h2>Troggle profile selection page</h2> + +Hello, {{ user }}. + +<br /><br /> + +{% if user.person %} +This is where you go to associate a new user account with a pre-existing profile from old expo data. + +<br /><br /> + +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: <br /><br /> <a href= {{ user.person.get_absolute_url }}> {{ user.person.get_absolute_url }} </a> <br /><br /> or edit it at: +<br /><br /> <a href= {{ user.person.get_admin_url }}> {{ user.person.get_admin_url }} </a>.<br /><br /> + +If your account is associated with the wrong person's profile due to inebriation or incompetance during account setup, click <a href="{{ user.person.get_absolute_url }}/?clear_profile=True">here</a> 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. +<br /><br /> + +<form method="post"> +{{ form.as_p }} +<input name="" type="submit" value="This is me!" /> +</form> +<br /> + +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 %} + <p class="errornote">Please correct the errors below</p> +{% 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 %}| <a href={{qm.get_admin_url}}>Edit QM {{qm|wiki_to_html_short}}</a>{% endblock %}
-
-
-
-{% block contentheader %}
-<table id="cavepage">
-<tr>
-<th id="kat_no"><a href="{{qm.get_previous_by_id.get_absolute_url}}">Previous</a></th>
-<th id="name">{{qm|wiki_to_html_short}}</th>
-<th id="status"><a href="{{qm.get_next_by_id.get_absolute_url}}">Next</a></th>
-</tr>
-</table>
-{% endblock %}
-
-{% block related %}
-
-{% endblock %}
-<h2>Related items</h2>
-
-Parent cave: {{qm.found_by.cave|link}}
-(todo: add parent survey and parent subcave)
-{% block content %}
-
-<h3>Location</h3>
-{{qm.location_description}}
-
-
-<h3>Creation</h3>
-Found by <a href="{{qm.found_by.get_absolute_url}}">{{qm.found_by}}</a> on {{qm.found_by.date}}.
-
-<h3>Completion</h3>
-{% if ticked_off_by %}
-{{qm.completion_description}}
-Ticked off by: <a href="{{qm.ticked_off_by.get_absolute_url}}">{{qm.ticked_off_by}}</a><br />
-Description: {{qm.completion_description}}
-{% else %}
-None yet- STILL EXTANT.
-{% endif %}
-
-<h3>Comment</h3>
-{{qm.comment}}
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %} QM: {{qm|wiki_to_html_short}} {% endblock %} + +{% block editLink %}| <a href={{qm.get_admin_url}}>Edit QM {{qm|wiki_to_html_short}}</a>{% endblock %} + + + +{% block contentheader %} +<table id="cavepage"> +<tr> +<th id="kat_no"><a href="{{qm.get_previous_by_id.get_absolute_url}}">Previous</a></th> +<th id="name">{{qm|wiki_to_html_short}}</th> +<th id="status"><a href="{{qm.get_next_by_id.get_absolute_url}}">Next</a></th> +</tr> +</table> +{% endblock %} + +{% block related %} + +{% endblock %} +<h2>Related items</h2> + +Parent cave: {{qm.found_by.cave|link}} +(todo: add parent survey and parent subcave) +{% block content %} + +<h3>Location</h3> +{{qm.location_description}} + + +<h3>Creation</h3> +Found by <a href="{{qm.found_by.get_absolute_url}}">{{qm.found_by}}</a> on {{qm.found_by.date}}. + +<h3>Completion</h3> +{% if ticked_off_by %} +{{qm.completion_description}} +Ticked off by: <a href="{{qm.ticked_off_by.get_absolute_url}}">{{qm.ticked_off_by}}</a><br /> +Description: {{qm.completion_description}} +{% else %} +None yet- STILL EXTANT. +{% endif %} + +<h3>Comment</h3> +{{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 %}
-<h1>activate.html</h1>
-{% endblock %}
-
-{% block content %}
-
-{% if account %}
-<p>
-Hello, {{ account }}! Your account is now activated. Now you can <a href="{%url auth_login%}">log in</a> with the password you chose. Use the links in the upper right to control this in the future.
-</p>
-
-<p>
-If you have been on the expedition in the past, you already have a profile in the system; <a href={% url profiles_select_profile %}>click here </a> to find it and link it to your account. Otherwise, please <a href={% url profiles_create_profile %}> create yourself a new profile</a>.
-</p>
-{% 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 %} +<h1>activate.html</h1> +{% endblock %} + +{% block content %} + +{% if account %} +<p> +Hello, {{ account }}! Your account is now activated. Now you can <a href="{%url auth_login%}">log in</a> with the password you chose. Use the links in the upper right to control this in the future. +</p> + +<p> +If you have been on the expedition in the past, you already have a profile in the system; <a href={% url profiles_select_profile %}>click here </a> to find it and link it to your account. Otherwise, please <a href={% url profiles_create_profile %}> create yourself a new profile</a>. +</p> +{% 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 @@ -<P>Hello {{ form.user }},</P>
-
-<P>Glad you're joining the CUCC EXPO team! Please go to</P>
-
-<P><a href="{{ site }}{% url registration_activate activation_key %}">{{ site }}{% url registration_activate activation_key %}</a></P>
-
-<P>to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again.</P>
-
-<P>Yours,<BR>
-The magical troggle</P>
+<P>Hello {{ form.user }},</P> + +<P>Glad you're joining the CUCC EXPO team! Please go to</P> + +<P><a href="{{ site }}{% url registration_activate activation_key %}">{{ site }}{% url registration_activate activation_key %}</a></P> + +<P>to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again.</P> + +<P>Yours,<BR> +The magical troggle</P> 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 %}
-<p>Your username and password didn't match. Please try again.</p>
-{% endif %}
-
-<form method="post" action=".">{% csrf_token %}
-<table>
-<tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr>
-<tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr>
-</table>
-
-<input type="submit" value="login" />
-<input type="hidden" name="next" value="{{ next }}" />
-</form>
-
-{% endblock %}
+{% extends "base.html" %} +{% load csrffaker %} + +{% block content %} + +{% if form.errors %} +<p>Your username and password didn't match. Please try again.</p> +{% endif %} + +<form method="post" action=".">{% csrf_token %} +<table> +<tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr> +<tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr> +</table> + +<input type="submit" value="login" /> +<input type="hidden" name="next" value="{{ next }}" /> +</form> + +{% 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 %}
-<h1>Registration Complete</h1>
-{% endblock %}
-
-{% block content %}
-<p>Thank you for signing up. An email with the activation code has been sent to your inbox. </p>
+{% extends "base.html" %} + +{% block title %} +{{ block.super }}: registration complete +{% endblock %} + +{% block contentheader %} +<h1>Registration Complete</h1> +{% endblock %} + +{% block content %} +<p>Thank you for signing up. An email with the activation code has been sent to your inbox. </p> {% 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 %}<a href={{subcave.get_admin_url}}>Edit subcave {{subcave|wiki_to_html_short}}</a>{% endblock %}
-
-{% block contentheader %}
- {{subcave.title}}
-{% endblock contentheader %}
-
-
-
-{% block content %}
-{% block related %}
-
- <h2>Related places</h2>
-
- <h3>Parent</h3>
-
- <ul>
- {% if subcave.parent %}
- <li><a href="{{subcave.parent.get_absolute_url}}">{{subcave.parent}}</a></li>
- {% else %}
- <li><a href="{{subcave.cave.get_absolute_url}}">{{subcave.cave}}</a></li>
- {% endif %}
- </ul>
-
- <h3>Connected subareas</h3>
-
- <ul>
- {% for sibling in subcave.adjoining.all%}
- <li><a href="{{sibling.get_absolute_url}}">{{silbling}}</a></li>
- {% endfor %}
- </ul>
-
- <h3>Children</h3>
-
- <ul>
- {% for child in subcave.children.all %}
- <li><a href="{{child.get_absolute_url}}">{{child}}</a></li>
- {% endfor %}
- </ul>
-
-
-{% endblock %}
-
-ok here comes the drilldown<br />
-{% drilldown_tree_for_node subcave as drilldown %}
-{% for each in drilldown %}
-{{ each }}>
-{% endfor %}
-
-
-<h2>{{subcave}}</h2>
-<p>
- {{subcave.description}}
-</p>
-
+{% extends "cavebase.html" %} +{% load wiki_markup %} +{% load mptt_tags %} +{% block title %} Subcave {{subcave}} {% endblock title %} +{% block editLink %}<a href={{subcave.get_admin_url}}>Edit subcave {{subcave|wiki_to_html_short}}</a>{% endblock %} + +{% block contentheader %} + {{subcave.title}} +{% endblock contentheader %} + + + +{% block content %} +{% block related %} + + <h2>Related places</h2> + + <h3>Parent</h3> + + <ul> + {% if subcave.parent %} + <li><a href="{{subcave.parent.get_absolute_url}}">{{subcave.parent}}</a></li> + {% else %} + <li><a href="{{subcave.cave.get_absolute_url}}">{{subcave.cave}}</a></li> + {% endif %} + </ul> + + <h3>Connected subareas</h3> + + <ul> + {% for sibling in subcave.adjoining.all%} + <li><a href="{{sibling.get_absolute_url}}">{{silbling}}</a></li> + {% endfor %} + </ul> + + <h3>Children</h3> + + <ul> + {% for child in subcave.children.all %} + <li><a href="{{child.get_absolute_url}}">{{child}}</a></li> + {% endfor %} + </ul> + + +{% endblock %} + +ok here comes the drilldown<br /> +{% drilldown_tree_for_node subcave as drilldown %} +{% for each in drilldown %} +{{ each }}> +{% endfor %} + + +<h2>{{subcave}}</h2> +<p> + {{subcave.description}} +</p> + {% 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 %}
-<h2>Survex Block {{survexblock.survexpath}}</h2>
-
-<p>Link to <a href="{% url svx survexblock.survexfile.path %}">{{survexblock.survexfile.path}}</a></p>
-
-<p>Needs duplicates removed from right hand column</p>
-<p>Needs links to survex file presentation</p>
-<p>Needs to start dealing with misspellings of names (prob by editing the originals)</p>
-
-<div id="col2">
-
-{% if survexblock.parent %}
- <p>Survey block above:</p>
- <p class="indent"><a href="{% url survexblock survexblock.parent.survexpath %}">{{survexblock.parent.survexpath}}</a></p>
-{% endif %}
-
-{% if survexblock.survexblock_set.all %}
- <p>Survey blocks below:</p>
- {% for survexblockdown in survexblock.survexblock_set.all %}
- <p class="indent"><a href="{% url survexblock survexblockdown.survexpath %}">{{survexblockdown.survexpath}}</a></p>
- {% endfor %}
-{% endif %}
-
-<p>Date: {{survexblock.date}}</p>
-
-<table>
-{% for personrole in survexblock.GetPersonroles %}
-<tr>
- <td><a href="{{personrole.person.get_absolute_url}}">{{personrole.person}}</a></td>
- <td>{{personrole.roles}}</td>
-</tr>
-{% endfor %}
-</table>
-
-
-</div>
-
-<div class="survexblock">
- {{ftext|survex_to_html}}
-</div>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + + +{% block title %}Survex Block{% endblock %} + +{% block content %} +<h2>Survex Block {{survexblock.survexpath}}</h2> + +<p>Link to <a href="{% url svx survexblock.survexfile.path %}">{{survexblock.survexfile.path}}</a></p> + +<p>Needs duplicates removed from right hand column</p> +<p>Needs links to survex file presentation</p> +<p>Needs to start dealing with misspellings of names (prob by editing the originals)</p> + +<div id="col2"> + +{% if survexblock.parent %} + <p>Survey block above:</p> + <p class="indent"><a href="{% url survexblock survexblock.parent.survexpath %}">{{survexblock.parent.survexpath}}</a></p> +{% endif %} + +{% if survexblock.survexblock_set.all %} + <p>Survey blocks below:</p> + {% for survexblockdown in survexblock.survexblock_set.all %} + <p class="indent"><a href="{% url survexblock survexblockdown.survexpath %}">{{survexblockdown.survexpath}}</a></p> + {% endfor %} +{% endif %} + +<p>Date: {{survexblock.date}}</p> + +<table> +{% for personrole in survexblock.GetPersonroles %} +<tr> + <td><a href="{{personrole.person.get_absolute_url}}">{{personrole.person}}</a></td> + <td>{{personrole.roles}}</td> +</tr> +{% endfor %} +</table> + + +</div> + +<div class="survexblock"> + {{ftext|survex_to_html}} +</div> + +{% 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 %}
-
-<h3>Survex Scans in: {{survexscansfolder.walletname}}</h3>
-<table>
-{% for survexscansingle in survexscansfolder.survexscansingle_set.all %}
- <tr>
- <td class="survexscansingle"><a href="{{survexscansingle.get_absolute_url}}">{{survexscansingle.name}}</a></td>
- <td>
- {% for survexblock in survexscansingle.survexblock_set.all %}
- {{survexblock}}
- {% endfor %}
- </td>
- </tr>
-{% endfor %}
-</table>
-
-<h3>Surveys referring to this wallet</h3>
-
-<table>
-{% for survexblock in survexscansfolder.survexblock_set.all %}
- <tr>
- <td><a href="{% url svx survexblock.survexfile.path %}">{{survexblock}}</a></td>
- </tr>
-{% endfor %}
-</table>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + +{% block title %}Survex Scans Folder{% endblock %} + +{% block content %} + +<h3>Survex Scans in: {{survexscansfolder.walletname}}</h3> +<table> +{% for survexscansingle in survexscansfolder.survexscansingle_set.all %} + <tr> + <td class="survexscansingle"><a href="{{survexscansingle.get_absolute_url}}">{{survexscansingle.name}}</a></td> + <td> + {% for survexblock in survexscansingle.survexblock_set.all %} + {{survexblock}} + {% endfor %} + </td> + </tr> +{% endfor %} +</table> + +<h3>Surveys referring to this wallet</h3> + +<table> +{% for survexblock in survexscansfolder.survexblock_set.all %} + <tr> + <td><a href="{% url svx survexblock.survexfile.path %}">{{survexblock}}</a></td> + </tr> +{% endfor %} +</table> + +{% 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 %}
-
-<h3>All Survex scans folders</h3>
-<table>
-<tr><th>Scans folder</th><th>Files</th><th>Survex blocks</th></tr>
-{% for survexscansfolder in survexscansfolders %}
- <tr>
- <td><a href="{{survexscansfolder.get_absolute_url}}">{{survexscansfolder.walletname}}</a></td>
- <td>{{survexscansfolder.survexscansingle_set.all|length}}</td>
- <td>
- {% for survexblock in survexscansfolder.survexblock_set.all %}
- <a href="{% url svx survexblock.survexfile.path %}">{{survexblock}}</a>
- {% endfor %}
- </td>
- </tr>
-{% endfor %}
-</table>
-
+{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + +{% block title %}All Survex scans folders{% endblock %} + +{% block content %} + +<h3>All Survex scans folders</h3> +<table> +<tr><th>Scans folder</th><th>Files</th><th>Survex blocks</th></tr> +{% for survexscansfolder in survexscansfolders %} + <tr> + <td><a href="{{survexscansfolder.get_absolute_url}}">{{survexscansfolder.walletname}}</a></td> + <td>{{survexscansfolder.survexscansingle_set.all|length}}</td> + <td> + {% for survexblock in survexscansfolder.survexblock_set.all %} + <a href="{% url svx survexblock.survexfile.path %}">{{survexblock}}</a> + {% endfor %} + </td> + </tr> +{% endfor %} +</table> + {% 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 %}
-
-<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/nav.css" />
-
-<script language="javascript">
- blankColor = "rgb(153, 153, 153)"
- highlightedColor = "rgb(125, 125, 125)"
- chosenColor = "rgb(255, 255, 255)"
-
- $(document).ready(function() {
- $(".menuBarItem").click(function() {
- $("#"+this.id+"Content").toggle();
- if ($(this).hasClass('on')){
- $(this).removeClass('on');}
- else {
- $(this).addClass('on');
- }
- });
- });
-
- function redirectSurvey(){
- window.location = "{% url survey %}" + '/' + document.getElementById("expeditionChooser").value + "%23" + document.getElementById("surveyChooser").value;
- }
-
- function redirectYear(){
- window.location = "{% url survey %}" + '/' + document.getElementById("expeditionChooser").value + "%23";
- }
-</script>
-
-{% endblock %}
-
-<div id="currentLocation">
- CUCC Expo virtual survey binder:
- {% if current_survey %}
- {{current_survey}}
- {% else %}
- {{current_expedition}}
- {% endif %}
-</div>
-
-{% block nav %}
- <br />
-
- <h3>Choose a year</h3>
- <center>
- <select id="expeditionChooser" class="centre" onChange="redirectYear()">
-
- <option value=""/>
- {% for expedition in expeditions %}
- <option label="{{ expedition }}" value="{{ expedition }}" {% ifequal expedition current_expedition %}selected{% endifequal %}>
-
- {{ expedition }}
-
- </option>
- {% endfor %}
-
- </select>
- </center>
-
- <div>
-<!-- <h4>Click to toggle:</h4>-->
- <div id="progressTable" class="menuBarItem"> {% if current_expedition.survey_set.all %}✓{% endif %}
- survey progress table </div>
- </div>
-{% if current_expedition %}
- <h3>Choose a wallet number </h3>
- <center>
- <select id="surveyChooser" class="centre" onChange="redirectSurvey()">
- <option label="show all" value="">
-
- </option>
- {% for survey in current_expedition.survey_set.all %}
-
- <option label="{{ survey }}" value="{{ survey.wallet_number }}"
- {% ifequal survey current_survey %}
- selected
- {% endifequal %}>
- {{ survey }}
- </option>
-
- {% endfor %}
-
- <option label="add" value="add">
- </select>
-
- </center>
- <h4>Click to toggle:</h4>
- <div id="surveyWalletNav">
- <div id="notes" class="menuBarItem"> {% if notes %}✓{% endif %}
- scanned notes </div>
- <div id="survexFile" class="menuBarItem"> {% if current_survey.survex_file %}✓{% endif %}
- survex file </div>
- <div id="printedCentreline" class="menuBarItem"> {% if current_survey.centreline_printed_on %}✓{% endif %}
- printed centreline </div>
- <div id="scannedPassageSketch" class="menuBarItem"> {% if planSketches %}✓{% endif %}
- scanned passage sketch </div>
- <div id="tunnelXMLfile" class="menuBarItem">tunnel xml file</div>
- <div id="mainSketchIntegration" class="menuBarItem">add to main sketch</div>
- </div>
- </div>
-{% endif %}
-{% endblock %}
-
-
-{% block content %}
-<div id="mainContent" style="background:white">
-
- <div id="progressTableContent" class="behind">
- <h3>Survey progress table for {{ current_expedition }}</h3>
- {% if current_expedition.survey_set.all %} <!-- if there are any surveys in the expedition, make the table -->
- <table class="centre">
- <tr>
- <th> </th>
- {% for survey in current_expedition.survey_set.all %}
- <th> {{ survey.wallet_number }} </th>
- {% endfor %} </tr>
- <tr>
- <td> Notes </td>
- {% for survey in current_expedition.survey_set.all %}
- <td> {% if survey.notes %}
- ✓
- {% endif %} </td>
- {% endfor %} </tr>
- <tr>
- <td> Survex file </td>
- {% for survey in current_expedition.survey_set.all %}
- <td> {% if survey.survex_file %}
- ✓
- {% endif %} </td>
- {% endfor %} </tr>
- <tr>
- <td> Plans </td>
- {% for survey in current_expedition.survey_set.all %}
- <td> {% if survey.plans %}
- ✓
- {% endif %} </td>
- {% endfor %} </tr>
- <tr>
- <td> Elevations </td>
- {% for survey in current_expedition.survey_set.all %}
- <td> {% if survey.elevations %}
- ✓
- {% endif %} </td>
- {% endfor %} </tr>
- </table>
- {% else %}
- <center>[ There are no surveys in the database for this year. Put link in to add one. ]</center>
- {% endif %}
- </div>
- <div id="notesContent" class="behind" >
- <h3>Scanned notes for {{ current_survey }}.</h3>
- {% for noteItem in notes %}
- <div class="figure">
- <p> <img src="{{ noteItem.thumbnail_image.url }}" class="thumbnail">
- <p> File at: <a href="{{ noteItem.correctURL }}"> {{ noteItem.file.name }} </a> <br />
- Scanned by: {{ noteItem.scanned_by }} <br />
- On: {{ noteItem.scanned_on }} <br />
- </p>
- </p>
- </div>
- {% endfor %}
- <div class="figure"> <a href="{{ settings.URL_ROOT }}/admin/expo/scannedimage/add/"> <img src="{{ settings.URL_ROOT }}{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_addlink.gif" /> Add a new scanned notes page. </a> </div>
- </div>
- <br class="clearfloat" />
- <div id="survexFileContent" class="behind"> survex file editor, keeping file in original structure <br />
- who entered by </div>
- <div id="printedCentrelineContent" class="behind"> centreline </div>
- <div id="scannedPassageSketchContent" class="behind">
- <h3>Scanned plan sketch files for {{ current_survey }}.</h3>
- {% for sketchItem in planSketches %}
- <div class="figure">
- <p> <img src="{{ sketchItem.thumbnail_image.url }}" class="thumbnail" />
- <p> File at: <a href="{{ sketchItem.correctURL }}"> {{ sketchItem.file.name }} </a> <br />
- Scanned by: {{ sketchItem.scanned_by }} <br />
- On: {{ sketchItem.scanned_on }} <br />
- </p>
- </p>
- </div>
- {% endfor %}
- <div class="figure"> <a href="{{ settings.URL_ROOT }}/admin/expo/scannedimage/add/"> <img src="{{ settings.URL_ROOT }}{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_addlink.gif" /> Add a new scanned sketch. </a> </div>
- </div>
- <div id="tunnelXMLfileContent" class="behind"> link to tunnel xml file. potentially instance of tunnel applet... </div>
- <div id="mainSketchIntegrationContent" class="behind"> link to main sketch file </div>
- <!-- end #mainContent -->
-</div>
-<br class="clearfloat" />
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} + + +{% block title %}CUCC Virtual Survey Binder: {{ current_expedition }}{{ current_survey }}{%endblock%} +{% block head %} + +<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/nav.css" /> + +<script language="javascript"> + blankColor = "rgb(153, 153, 153)" + highlightedColor = "rgb(125, 125, 125)" + chosenColor = "rgb(255, 255, 255)" + + $(document).ready(function() { + $(".menuBarItem").click(function() { + $("#"+this.id+"Content").toggle(); + if ($(this).hasClass('on')){ + $(this).removeClass('on');} + else { + $(this).addClass('on'); + } + }); + }); + + function redirectSurvey(){ + window.location = "{% url survey %}" + '/' + document.getElementById("expeditionChooser").value + "%23" + document.getElementById("surveyChooser").value; + } + + function redirectYear(){ + window.location = "{% url survey %}" + '/' + document.getElementById("expeditionChooser").value + "%23"; + } +</script> + +{% endblock %} + +<div id="currentLocation"> + CUCC Expo virtual survey binder: + {% if current_survey %} + {{current_survey}} + {% else %} + {{current_expedition}} + {% endif %} +</div> + +{% block nav %} + <br /> + + <h3>Choose a year</h3> + <center> + <select id="expeditionChooser" class="centre" onChange="redirectYear()"> + + <option value=""/> + {% for expedition in expeditions %} + <option label="{{ expedition }}" value="{{ expedition }}" {% ifequal expedition current_expedition %}selected{% endifequal %}> + + {{ expedition }} + + </option> + {% endfor %} + + </select> + </center> + + <div> +<!-- <h4>Click to toggle:</h4>--> + <div id="progressTable" class="menuBarItem"> {% if current_expedition.survey_set.all %}✓{% endif %} + survey progress table </div> + </div> +{% if current_expedition %} + <h3>Choose a wallet number </h3> + <center> + <select id="surveyChooser" class="centre" onChange="redirectSurvey()"> + <option label="show all" value=""> + + </option> + {% for survey in current_expedition.survey_set.all %} + + <option label="{{ survey }}" value="{{ survey.wallet_number }}" + {% ifequal survey current_survey %} + selected + {% endifequal %}> + {{ survey }} + </option> + + {% endfor %} + + <option label="add" value="add"> + </select> + + </center> + <h4>Click to toggle:</h4> + <div id="surveyWalletNav"> + <div id="notes" class="menuBarItem"> {% if notes %}✓{% endif %} + scanned notes </div> + <div id="survexFile" class="menuBarItem"> {% if current_survey.survex_file %}✓{% endif %} + survex file </div> + <div id="printedCentreline" class="menuBarItem"> {% if current_survey.centreline_printed_on %}✓{% endif %} + printed centreline </div> + <div id="scannedPassageSketch" class="menuBarItem"> {% if planSketches %}✓{% endif %} + scanned passage sketch </div> + <div id="tunnelXMLfile" class="menuBarItem">tunnel xml file</div> + <div id="mainSketchIntegration" class="menuBarItem">add to main sketch</div> + </div> + </div> +{% endif %} +{% endblock %} + + +{% block content %} +<div id="mainContent" style="background:white"> + + <div id="progressTableContent" class="behind"> + <h3>Survey progress table for {{ current_expedition }}</h3> + {% if current_expedition.survey_set.all %} <!-- if there are any surveys in the expedition, make the table --> + <table class="centre"> + <tr> + <th> </th> + {% for survey in current_expedition.survey_set.all %} + <th> {{ survey.wallet_number }} </th> + {% endfor %} </tr> + <tr> + <td> Notes </td> + {% for survey in current_expedition.survey_set.all %} + <td> {% if survey.notes %} + ✓ + {% endif %} </td> + {% endfor %} </tr> + <tr> + <td> Survex file </td> + {% for survey in current_expedition.survey_set.all %} + <td> {% if survey.survex_file %} + ✓ + {% endif %} </td> + {% endfor %} </tr> + <tr> + <td> Plans </td> + {% for survey in current_expedition.survey_set.all %} + <td> {% if survey.plans %} + ✓ + {% endif %} </td> + {% endfor %} </tr> + <tr> + <td> Elevations </td> + {% for survey in current_expedition.survey_set.all %} + <td> {% if survey.elevations %} + ✓ + {% endif %} </td> + {% endfor %} </tr> + </table> + {% else %} + <center>[ There are no surveys in the database for this year. Put link in to add one. ]</center> + {% endif %} + </div> + <div id="notesContent" class="behind" > + <h3>Scanned notes for {{ current_survey }}.</h3> + {% for noteItem in notes %} + <div class="figure"> + <p> <img src="{{ noteItem.thumbnail_image.url }}" class="thumbnail"> + <p> File at: <a href="{{ noteItem.correctURL }}"> {{ noteItem.file.name }} </a> <br /> + Scanned by: {{ noteItem.scanned_by }} <br /> + On: {{ noteItem.scanned_on }} <br /> + </p> + </p> + </div> + {% endfor %} + <div class="figure"> <a href="{{ settings.URL_ROOT }}/admin/expo/scannedimage/add/"> <img src="{{ settings.URL_ROOT }}{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_addlink.gif" /> Add a new scanned notes page. </a> </div> + </div> + <br class="clearfloat" /> + <div id="survexFileContent" class="behind"> survex file editor, keeping file in original structure <br /> + who entered by </div> + <div id="printedCentrelineContent" class="behind"> centreline </div> + <div id="scannedPassageSketchContent" class="behind"> + <h3>Scanned plan sketch files for {{ current_survey }}.</h3> + {% for sketchItem in planSketches %} + <div class="figure"> + <p> <img src="{{ sketchItem.thumbnail_image.url }}" class="thumbnail" /> + <p> File at: <a href="{{ sketchItem.correctURL }}"> {{ sketchItem.file.name }} </a> <br /> + Scanned by: {{ sketchItem.scanned_by }} <br /> + On: {{ sketchItem.scanned_on }} <br /> + </p> + </p> + </div> + {% endfor %} + <div class="figure"> <a href="{{ settings.URL_ROOT }}/admin/expo/scannedimage/add/"> <img src="{{ settings.URL_ROOT }}{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_addlink.gif" /> Add a new scanned sketch. </a> </div> + </div> + <div id="tunnelXMLfileContent" class="behind"> link to tunnel xml file. potentially instance of tunnel applet... </div> + <div id="mainSketchIntegrationContent" class="behind"> link to main sketch file </div> + <!-- end #mainContent --> +</div> +<br class="clearfloat" /> + +{% 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 %}
-
-<h1>Surveys for {{cave}}</h1>
-
-<p>
-{% for survexdirectory in cave.survexdirectory_set.all %}
- <a href="#T_{{survexdirectory.primarysurvexfile.path}}">{{survexdirectory.path}}</a>
-{% endfor %}
-</p>
-
-{% for survexdirectory in cave.survexdirectory_set.all %}
-<h3 id="T_{{survexdirectory.primarysurvexfile.path}}">{{survexdirectory.path}}</h3>
-
-<table>
-<tr><th>Survex file</th><th>Block</th><th>Date</th><th>Explorers</th><th>length</th><th>Titles</th><th>Scans</th></tr>
-
-{% for survexfile in survexdirectory.survexfile_set.all %}
-<tr>
- {% if survexfile.exists %}
- <td rowspan="{{survexfile.survexblock_set.all|length|plusone}}">
- {% else %}
- <td class="survexnewfile" rowspan="{{survexfile.survexblock_set.all|length|plusone}}">
- {% endif %}
-
- {% ifequal survexfile survexdirectory.primarysurvexfile %}
- <a href="{% url svx survexfile.path %}"><b>{{survexfile.path}}</b></a>
- {% else %}
- <a href="{% url svx survexfile.path %}">{{survexfile.path}}</a>
- {% endifequal %}
- </td>
-</tr>
-
-{% for survexblock in survexfile.survexblock_set.all %}
-<tr>
- <td>{{survexblock.name}}</td>
- <td>
- {% if survexblock.expedition %}
- <a href="{{survexblock.expedition.get_absolute_url}}">{{survexblock.date}}</a>
- {% else %}
- {{survexblock.date}}
- {% endif %}
- </td>
-
- <td>
- {% for personrole in survexblock.personrole_set.all %}
- {% if personrole.personexpedition %}
- <a href="{{personrole.personexpedition.get_absolute_url}}">{{personrole.personname}}</a>
- {% else %}
- {{personrole.personname}}
- {% endif %}
- {% endfor %}
- </td>
-
- <td>{{survexblock.totalleglength}}</td>
-
- <td>
- {% for survextitle in survexblock.survextitle_set.all %}
- {{survextitle.title}}
- {% endfor %}
- </td>
-
- <td>
- {% if survexblock.survexscansfolder %}
- <b><a href="{{survexblock.survexscansfolder.get_absolute_url}}">{{survexblock.survexscansfolder.walletname}}</a></b>
- {% endif %}
- </td>
-</tr>
-{% endfor %}
-{% endfor %}
-</table>
-
-{% endfor %}
-
-{% endblock %}
-
+{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}List of survex files{% endblock %} + +{% block content %} + +<h1>Surveys for {{cave}}</h1> + +<p> +{% for survexdirectory in cave.survexdirectory_set.all %} + <a href="#T_{{survexdirectory.primarysurvexfile.path}}">{{survexdirectory.path}}</a> +{% endfor %} +</p> + +{% for survexdirectory in cave.survexdirectory_set.all %} +<h3 id="T_{{survexdirectory.primarysurvexfile.path}}">{{survexdirectory.path}}</h3> + +<table> +<tr><th>Survex file</th><th>Block</th><th>Date</th><th>Explorers</th><th>length</th><th>Titles</th><th>Scans</th></tr> + +{% for survexfile in survexdirectory.survexfile_set.all %} +<tr> + {% if survexfile.exists %} + <td rowspan="{{survexfile.survexblock_set.all|length|plusone}}"> + {% else %} + <td class="survexnewfile" rowspan="{{survexfile.survexblock_set.all|length|plusone}}"> + {% endif %} + + {% ifequal survexfile survexdirectory.primarysurvexfile %} + <a href="{% url svx survexfile.path %}"><b>{{survexfile.path}}</b></a> + {% else %} + <a href="{% url svx survexfile.path %}">{{survexfile.path}}</a> + {% endifequal %} + </td> +</tr> + +{% for survexblock in survexfile.survexblock_set.all %} +<tr> + <td>{{survexblock.name}}</td> + <td> + {% if survexblock.expedition %} + <a href="{{survexblock.expedition.get_absolute_url}}">{{survexblock.date}}</a> + {% else %} + {{survexblock.date}} + {% endif %} + </td> + + <td> + {% for personrole in survexblock.personrole_set.all %} + {% if personrole.personexpedition %} + <a href="{{personrole.personexpedition.get_absolute_url}}">{{personrole.personname}}</a> + {% else %} + {{personrole.personname}} + {% endif %} + {% endfor %} + </td> + + <td>{{survexblock.totalleglength}}</td> + + <td> + {% for survextitle in survexblock.survextitle_set.all %} + {{survextitle.title}} + {% endfor %} + </td> + + <td> + {% if survexblock.survexscansfolder %} + <b><a href="{{survexblock.survexscansfolder.get_absolute_url}}">{{survexblock.survexscansfolder.walletname}}</a></b> + {% endif %} + </td> +</tr> +{% endfor %} +{% endfor %} +</table> + +{% 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 %}
-<script src="{{ settings.MEDIA_URL }}js/base.js" type="text/javascript"></script>
-<script type="text/javascript" src="{{settings.MEDIA_URL}}js/jquery.form.js"></script>
-<script type="text/javascript" src="{{settings.MEDIA_URL}}CodeMirror-0.62/js/codemirror.js"></script>
-
-<script type="text/javascript">
-var codeeditor;
-$(document).ready(function()
-{
- codeeditor = CodeMirror.fromTextArea("id_code",
- {
- parserfile: ["parsesurvex.js"],
- stylesheet: "{{settings.MEDIA_URL}}CodeMirror-0.62/css/survexcolors.css",
- path: "{{settings.MEDIA_URL}}CodeMirror-0.62/js/",
- textWrapping: false,
- lineNumbers: false,
- indentUnit: 4,
- tabMode: "spaces"
- });
- $("#id_outputtype").val("ajax");
- var options =
- {
- target: '#difflistajax',
- beforeSubmit: function() { $("textarea#id_code").value = codeeditor.getCode().length; },
- success: function() { codeeditor.focus(); }
- };
- $('#codewikiform').ajaxForm(options); // bind form using 'ajaxForm'
-});
-
-</script>
-{% endblock %}
-
-{% block content %}
-<h1>Survex File: {{ title }}</h1>
-
-{% if svxincludes %}
-<p><b>Included files:</b>
-{% for svxinclude in svxincludes %}
- <a href="{{svxinclude}}.svx">{{svxinclude}}</a>
-{% endfor %}
-</p>
-{% endif %}
-
-<form id="codewikiform" action="" method="POST">
- <div class="codeframebit">{{form.code}}</div>
- <div style="display:none">{{form.filename}} {{form.dirname}} {{form.datetime}} {{form.outputtype}}</div>
- <input type="submit" name="diff" value="Diffy" />
- <input type="submit" name="save" value="Save"/>
- <input type="submit" name="process" value="Process" title="executes cavern"/>
-</form>
-
-<div id="difflistajax">
-<pre>
-{% for diffline in difflist %}{{diffline}}
-{% endfor %}
-</pre>
-
-{% if logmessage %}
-{% if has_3d %}
-<p><a href="{% url threed title %}">3d file</a></p>
-{% else %}
-<p><b>No 3d file</b></p>
-{% endif %}
-<pre>
-LOGMESSAGES
-{{logmessage}}
-</pre>
-{% endif %}
-</div>
-
-{% endblock %}
+{% extends "base.html" %} +{% load survex_markup %} + +{% block title %}{{ title }}{% endblock %} + +{% block head %} +<script src="{{ settings.MEDIA_URL }}js/base.js" type="text/javascript"></script> +<script type="text/javascript" src="{{settings.MEDIA_URL}}js/jquery.form.js"></script> +<script type="text/javascript" src="{{settings.MEDIA_URL}}CodeMirror-0.62/js/codemirror.js"></script> + +<script type="text/javascript"> +var codeeditor; +$(document).ready(function() +{ + codeeditor = CodeMirror.fromTextArea("id_code", + { + parserfile: ["parsesurvex.js"], + stylesheet: "{{settings.MEDIA_URL}}CodeMirror-0.62/css/survexcolors.css", + path: "{{settings.MEDIA_URL}}CodeMirror-0.62/js/", + textWrapping: false, + lineNumbers: false, + indentUnit: 4, + tabMode: "spaces" + }); + $("#id_outputtype").val("ajax"); + var options = + { + target: '#difflistajax', + beforeSubmit: function() { $("textarea#id_code").value = codeeditor.getCode().length; }, + success: function() { codeeditor.focus(); } + }; + $('#codewikiform').ajaxForm(options); // bind form using 'ajaxForm' +}); + +</script> +{% endblock %} + +{% block content %} +<h1>Survex File: {{ title }}</h1> + +{% if svxincludes %} +<p><b>Included files:</b> +{% for svxinclude in svxincludes %} + <a href="{{svxinclude}}.svx">{{svxinclude}}</a> +{% endfor %} +</p> +{% endif %} + +<form id="codewikiform" action="" method="POST"> + <div class="codeframebit">{{form.code}}</div> + <div style="display:none">{{form.filename}} {{form.dirname}} {{form.datetime}} {{form.outputtype}}</div> + <input type="submit" name="diff" value="Diffy" /> + <input type="submit" name="save" value="Save"/> + <input type="submit" name="process" value="Process" title="executes cavern"/> +</form> + +<div id="difflistajax"> +<pre> +{% for diffline in difflist %}{{diffline}} +{% endfor %} +</pre> + +{% if logmessage %} +{% if has_3d %} +<p><a href="{% url threed title %}">3d file</a></p> +{% else %} +<p><b>No 3d file</b></p> +{% endif %} +<pre> +LOGMESSAGES +{{logmessage}} +</pre> +{% endif %} +</div> + +{% 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 %}
-<p><a href="#cdir">caves with subdirectories</a> | <a href="#cmult">caves with multiple files</a> | <a href="#csing">caves with single files</a></p>
-
-<h3><a href="/survexfile/all.svx">Link to all.svx for processing</a></h3>
-
-<h2 id="cdir">Caves with subdirectories</h2>
-
-{% for subdircave, cavefiles, subsurvdirs in subdircaves %}
-<h3>{{cavefiles.0.1}} - <a href="{% url survexcavessingle cavefiles.0.1 %}">dates and explorers</a></h3>
-<table>
-<tr>
- <td><b><a href="{% url svx cavefiles.0.0 %}">{{cavefiles.0.1}}</a></b></td>
- <td>
- {% for cavepath, cavename in cavefiles.1 %}
- <a href="{% url svx cavepath %}">{{cavename}}</a>
- {% endfor %}
- </td>
-</tr>
-
-{% for primarycavefile, subcavefiles in subsurvdirs %}
-<tr>
- <td><a href="{% url svx primarycavefile.0 %}">{{primarycavefile.1}}</a></td>
- <td>
- {% for cavepath, cavename in subcavefiles %}
- <a href="{% url svx cavepath %}">{{cavename}}</a>
- {% endfor %}
- </td>
-</tr>
-{% endfor %}
-</table>
-
-{% endfor %}
-
-
-<h2 id="cmult">Caves of multiple files</h2>
-<table>
-<tr><th>Dates and explorers</th><th>Survex files</th></tr>
-{% for primarycavefile, subcavefiles in multifilecaves %}
-<tr>
- <td>
- <a href="{% url survexcavessingle primarycavefile.1 %}">{{primarycavefile.1}}</a>
- </td>
- <td>
- <a href="{% url svx primarycavefile.0 %}">{{primarycavefile.1}}</a> -
- {% for cavepath, cavename in subcavefiles %}
- <a href="{% url svx cavepath %}">{{cavename}}</a>
- {% endfor %}
- </td>
-</tr>
-{% endfor %}
-</table>
-
-<h2 id="csing">Caves of one file</h2>
-<p>
-{% for cavepath, cavename in onefilecaves %}
- <a href="{% url svx cavepath %}">{{cavename}}</a>
-{% endfor %}
-</p>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}List of survex files{% endblock %} + +{% block content %} +<p><a href="#cdir">caves with subdirectories</a> | <a href="#cmult">caves with multiple files</a> | <a href="#csing">caves with single files</a></p> + +<h3><a href="/survexfile/all.svx">Link to all.svx for processing</a></h3> + +<h2 id="cdir">Caves with subdirectories</h2> + +{% for subdircave, cavefiles, subsurvdirs in subdircaves %} +<h3>{{cavefiles.0.1}} - <a href="{% url survexcavessingle cavefiles.0.1 %}">dates and explorers</a></h3> +<table> +<tr> + <td><b><a href="{% url svx cavefiles.0.0 %}">{{cavefiles.0.1}}</a></b></td> + <td> + {% for cavepath, cavename in cavefiles.1 %} + <a href="{% url svx cavepath %}">{{cavename}}</a> + {% endfor %} + </td> +</tr> + +{% for primarycavefile, subcavefiles in subsurvdirs %} +<tr> + <td><a href="{% url svx primarycavefile.0 %}">{{primarycavefile.1}}</a></td> + <td> + {% for cavepath, cavename in subcavefiles %} + <a href="{% url svx cavepath %}">{{cavename}}</a> + {% endfor %} + </td> +</tr> +{% endfor %} +</table> + +{% endfor %} + + +<h2 id="cmult">Caves of multiple files</h2> +<table> +<tr><th>Dates and explorers</th><th>Survex files</th></tr> +{% for primarycavefile, subcavefiles in multifilecaves %} +<tr> + <td> + <a href="{% url survexcavessingle primarycavefile.1 %}">{{primarycavefile.1}}</a> + </td> + <td> + <a href="{% url svx primarycavefile.0 %}">{{primarycavefile.1}}</a> - + {% for cavepath, cavename in subcavefiles %} + <a href="{% url svx cavepath %}">{{cavename}}</a> + {% endfor %} + </td> +</tr> +{% endfor %} +</table> + +<h2 id="csing">Caves of one file</h2> +<p> +{% for cavepath, cavename in onefilecaves %} + <a href="{% url svx cavepath %}">{{cavename}}</a> +{% endfor %} +</p> + +{% 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 @@ -<pre>
- using difflistonly.html
-{% for diffline in difflist %}{{diffline}}
-{% endfor %}
-</pre>
-
-{% if logmessage %}
-{% if has_3d %}
-<p><a href="{% url threed title %}">3d file</a></p>
-{% else %}
-<p><b>No 3d file</b></p>
-{% endif %}
-<pre>
-LOGMESSAGES
-{{logmessage}}
-</pre>
-{% endif %}
-
+<pre> + using difflistonly.html +{% for diffline in difflist %}{{diffline}} +{% endfor %} +</pre> + +{% if logmessage %} +{% if has_3d %} +<p><a href="{% url threed title %}">3d file</a></p> +{% else %} +<p><b>No 3d file</b></p> +{% endif %} +<pre> +LOGMESSAGES +{{logmessage}} +</pre> +{% 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 %}
-<h2>Expo member tasks</h2>
-
-<h3>Add new data</h3>
-
-<li><a href="">Upload a photo</a></li>
-<li><a href="">Record a new trip</a></li>
-
-<h3>Your unfinished business</h3>
- {% for survey in surveys_unfinished %}
- <li>{{survey|link}}</li>
- {% endfor %}
-
-<h3>General unfinished business</h3>
-add wikilinks
-
-<h3>Caving recommendations</h3>
- {% for qm in qms_recommended %}
- <li>{{qm|link}}</li>
- {% endfor %}
-
-<h3>Profile tasks</h3>
-
-<li>Dates present on expo</li>
-<li>Mugshot</li>
-<li>Blurb</li>
-
-{% endblock content %}
-
-{% block margins %}
-<img class="leftMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}eieshole.jpg">
-<img class="rightMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}goesser.jpg">
-{% endblock margins %}
+{% extends "base.html" %} +{% load wiki_markup %} +{% load link %} + +{% block title %}Cambridge Expeditions to Austria{% endblock %} + +{% block content %} +<h2>Expo member tasks</h2> + +<h3>Add new data</h3> + +<li><a href="">Upload a photo</a></li> +<li><a href="">Record a new trip</a></li> + +<h3>Your unfinished business</h3> + {% for survey in surveys_unfinished %} + <li>{{survey|link}}</li> + {% endfor %} + +<h3>General unfinished business</h3> +add wikilinks + +<h3>Caving recommendations</h3> + {% for qm in qms_recommended %} + <li>{{qm|link}}</li> + {% endfor %} + +<h3>Profile tasks</h3> + +<li>Dates present on expo</li> +<li>Mugshot</li> +<li>Blurb</li> + +{% endblock content %} + +{% block margins %} +<img class="leftMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}eieshole.jpg"> +<img class="rightMargin eyeCandy fadeIn" src="{{ settings.MEDIA_URL }}goesser.jpg"> +{% 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 %}
-
-<h2>The unfinished front page</h2>
-<ul>
- <li><b>About {{totallogbookentries}} logbook entries have been loaded</b></li>
- <li><b><a href="{% url personindex %}">List of People</a></b></li>
- <li><b><a href="{% url caveindex %}">List of Caves</a></b></li>
- <li><a href="{% url jgtfile aaaa %}">JGT list of files</a> (temporary simple file list and tunnel use)</li>
- <li><a href="{% url survey %}">Survey files</a></li>
- <li><a href="{% url survexindex all %}">Survex directory</a></li>
- <li><a href="{% url expedition 2008 %}">Expedition 2008</a></li>
- <li><a href="{% url expedition 2007 %}">Expedition 2007</a></li>
- <li><a href="{% url expedition 1993 %}">Expedition 1993</a> (earliest parsed)</li>
-</ul>
-
-<h2>Further work</h2>
-
-<p>Please see the <a href="http://code.google.com/p/troggle/issues/list">issues</a> tracker on google code. You can contribute new feature requests and bug reports.</p>
-
-<p>Julian's work:
-<p>parse 1992-1976 logbooks; (esp top 161)</p>
-<p>detect T/U on log entries; </p>
-<p>name matching and spelling in survex files; </p>
-<p>Improve logbook wikihtml text</p>
-
-<p>Other work:</p>
-<p>surf through the tunnel sketches and images</p>
-<p>bugs with all.svx block (double dot)
-<p>render bitmap view of every survex block as a thumbnail</p>
-<p>upload tunnel images and tunnel sketches</p>
-<p>where are the subcaves; </p>
-<p>cave section entrance match for logbook entries</p>
-<p>simplify the survex parsing code (if necessary); </p>
-<p>wiki survex stop linegap between comment lins</p>
-<p>links between logbooks and survex blocks to cave things; </p>
-<p>mini-tree of survexblocks; </p>
-<p>connect sketches to caves to survey blocks and render thumbnailwise; </p>
-<p>all images to start appearing in pages; and so on</p>
-
-<h3>{{message}}</h3>
-
-<form action="" method="GET">
- <input type="submit" name="reloadexpos" value="Reload Expos">
- <input type="submit" name="reloadsurvex" value="Reload Survex">
-</form>
-
-<ul id="expeditionlist">
-{% for expedition in expeditions %}
-<li>
- <a href="{% url expedition expedition.year %}">{{expedition.name}}</a>
- - <b>{{expedition.logbookentry_set.count}}</b> logbook entries
-</li>
-{% endfor %}
-</ul>
-
-{% endblock %}
+{% extends "base.html" %} +{% load wiki_markup %} + +{% block title %}Cambridge Expeditions to Austria{% endblock %} + +{% block content %} + +<h2>The unfinished front page</h2> +<ul> + <li><b>About {{totallogbookentries}} logbook entries have been loaded</b></li> + <li><b><a href="{% url personindex %}">List of People</a></b></li> + <li><b><a href="{% url caveindex %}">List of Caves</a></b></li> + <li><a href="{% url jgtfile aaaa %}">JGT list of files</a> (temporary simple file list and tunnel use)</li> + <li><a href="{% url survey %}">Survey files</a></li> + <li><a href="{% url survexindex all %}">Survex directory</a></li> + <li><a href="{% url expedition 2008 %}">Expedition 2008</a></li> + <li><a href="{% url expedition 2007 %}">Expedition 2007</a></li> + <li><a href="{% url expedition 1993 %}">Expedition 1993</a> (earliest parsed)</li> +</ul> + +<h2>Further work</h2> + +<p>Please see the <a href="http://code.google.com/p/troggle/issues/list">issues</a> tracker on google code. You can contribute new feature requests and bug reports.</p> + +<p>Julian's work: +<p>parse 1992-1976 logbooks; (esp top 161)</p> +<p>detect T/U on log entries; </p> +<p>name matching and spelling in survex files; </p> +<p>Improve logbook wikihtml text</p> + +<p>Other work:</p> +<p>surf through the tunnel sketches and images</p> +<p>bugs with all.svx block (double dot) +<p>render bitmap view of every survex block as a thumbnail</p> +<p>upload tunnel images and tunnel sketches</p> +<p>where are the subcaves; </p> +<p>cave section entrance match for logbook entries</p> +<p>simplify the survex parsing code (if necessary); </p> +<p>wiki survex stop linegap between comment lins</p> +<p>links between logbooks and survex blocks to cave things; </p> +<p>mini-tree of survexblocks; </p> +<p>connect sketches to caves to survey blocks and render thumbnailwise; </p> +<p>all images to start appearing in pages; and so on</p> + +<h3>{{message}}</h3> + +<form action="" method="GET"> + <input type="submit" name="reloadexpos" value="Reload Expos"> + <input type="submit" name="reloadsurvex" value="Reload Survex"> +</form> + +<ul id="expeditionlist"> +{% for expedition in expeditions %} +<li> + <a href="{% url expedition expedition.year %}">{{expedition.name}}</a> + - <b>{{expedition.logbookentry_set.count}}</b> logbook entries +</li> +{% endfor %} +</ul> + +{% 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 %}
-
-<h3>All Tunnel files</h3>
-<table>
-<tr><th>File</th><th>Font</th><th>SurvexBlocks</th><th>Size</th><th>Paths</th><th>Scans folder</th><th>Scan files</th><th>Frames</th></tr>
-{% for tunnelfile in tunnelfiles %}
- <tr>
- <td><a href="{% url tunnelfile tunnelfile.tunnelpath %}">{{tunnelfile.tunnelpath}}</a></td>
- <td>{{tunnelfile.bfontcolours}}</td>
- <td></td>
- <td>{{tunnelfile.filesize}}</td>
- <td>{{tunnelfile.npaths}}</td>
-
- <td>
- {% for survexscansfolder in tunnelfile.survexscansfolders.all %}
- <a href="{{survexscansfolder.get_absolute_url}}">{{survexscansfolder.walletname}}</a>
- {% endfor %}
- </td>
-
- <td>
- {% for survexscansingle in tunnelfile.survexscans.all %}
- <a href="{{survexscansingle.get_absolute_url}}">{{survexscansingle.name}}</a>
- {% endfor %}
- </td>
-
- <td>
- {% for rtunnelfile in tunnelfile.tunnelcontains.all %}
- <a href="{% url tunnelfile rtunnelfile.tunnelpath %}">{{rtunnelfile.tunnelpath}}</a>
- {% endfor %}
- </td>
-
-
- </tr>
-{% endfor %}
-</table>
-
+{% extends "base.html" %} +{% load wiki_markup %} +{% load survex_markup %} + +{% block title %}Tunnel files{% endblock %} + +{% block content %} + +<h3>All Tunnel files</h3> +<table> +<tr><th>File</th><th>Font</th><th>SurvexBlocks</th><th>Size</th><th>Paths</th><th>Scans folder</th><th>Scan files</th><th>Frames</th></tr> +{% for tunnelfile in tunnelfiles %} + <tr> + <td><a href="{% url tunnelfile tunnelfile.tunnelpath %}">{{tunnelfile.tunnelpath}}</a></td> + <td>{{tunnelfile.bfontcolours}}</td> + <td></td> + <td>{{tunnelfile.filesize}}</td> + <td>{{tunnelfile.npaths}}</td> + + <td> + {% for survexscansfolder in tunnelfile.survexscansfolders.all %} + <a href="{{survexscansfolder.get_absolute_url}}">{{survexscansfolder.walletname}}</a> + {% endfor %} + </td> + + <td> + {% for survexscansingle in tunnelfile.survexscans.all %} + <a href="{{survexscansingle.get_absolute_url}}">{{survexscansingle.name}}</a> + {% endfor %} + </td> + + <td> + {% for rtunnelfile in tunnelfile.tunnelcontains.all %} + <a href="{% url tunnelfile rtunnelfile.tunnelpath %}">{{rtunnelfile.tunnelpath}}</a> + {% endfor %} + </td> + + + </tr> +{% endfor %} +</table> + {% endblock %}
\ No newline at end of file @@ -1,149 +1,149 @@ -from django.conf.urls.defaults import *
-from django.conf import settings
-
-from core.views import * # flat import
-from core.views_other import *
-from core.views_caves import *
-from core.views_survex import *
-from core.models import *
-from django.views.generic.create_update import create_object
-from django.contrib import admin
-from django.views.generic.list_detail import object_list
-from django.contrib import admin
-admin.autodiscover()
-
-
-# type url probably means it's used.
-
-actualurlpatterns = patterns('',
-
- url(r'^troggle$', views_other.frontpage, name="frontpage"),
- url(r'^todo/$', views_other.todo, name="todo"),
-
- url(r'^caves/?$', views_caves.caveindex, name="caveindex"),
- url(r'^people/?$', views_logbooks.personindex, name="personindex"),
-
- url(r'^newqmnumber/?$', views_other.ajax_QM_number, ),
- url(r'^lbo_suggestions/?$', logbook_entry_suggestions),
- #(r'^person/(?P<person_id>\d*)/?$', views_logbooks.person),
- url(r'^person/(?P<first_name>[A-Z]*[a-z\-\']*)[^a-zA-Z]*(?P<last_name>[a-z\-\']*[^a-zA-Z]*[A-Z]*[a-z\-]*)/?', views_logbooks.person, name="person"),
- #url(r'^person/(\w+_\w+)$', views_logbooks.person, name="person"),
-
- url(r'^expedition/(\d+)$', views_logbooks.expedition, name="expedition"),
- url(r'^expeditions/?$', object_list, {'queryset':Expedition.objects.all(),'template_name':'object_list.html'},name="expeditions"),
- url(r'^personexpedition/(?P<first_name>[A-Z]*[a-z]*)[^a-zA-Z]*(?P<last_name>[A-Z]*[a-z]*)/(?P<year>\d+)/?$', views_logbooks.personexpedition, name="personexpedition"),
- url(r'^logbookentry/(?P<date>.*)/(?P<slug>.*)/?$', views_logbooks.logbookentry,name="logbookentry"),
- url(r'^newlogbookentry/(?P<expeditionyear>.*)$', views_logbooks.newLogbookEntry, name="newLogBookEntry"),
- url(r'^editlogbookentry/(?P<expeditionyear>[^/]*)/(?P<pdate>[^/]*)/(?P<pslug>[^/]*)/$', views_logbooks.newLogbookEntry, name="editLogBookEntry"),
- url(r'^deletelogbookentry/(?P<expeditionyear>[^/]*)/(?P<date>[^/]*)/(?P<slug>[^/]*)/$', views_logbooks.deleteLogbookEntry, name="deleteLogBookEntry"),
- url(r'^newfile', views_other.newFile, name="newFile"),
-
- url(r'^getEntrances/(?P<caveslug>.*)', views_caves.get_entrances, name = "get_entrances"),
- url(r'^getQMs/(?P<caveslug>.*)', views_caves.get_qms, name = "get_qms"),
- url(r'^getPeople/(?P<expeditionslug>.*)', views_logbooks.get_people, name = "get_people"),
- url(r'^getLogBookEntries/(?P<expeditionslug>.*)', views_logbooks.get_logbook_entries, name = "get_logbook_entries"),
-
- url(r'^cave/(?P<cave_id>[^/]+)/?$', views_caves.cave, name="cave"),
- url(r'^caveslug/([^/]+)/?$', views_caves.caveSlug, name="caveSlug"),
- url(r'^cave/entrance/([^/]+)/?$', views_caves.caveEntrance),
- url(r'^cave/description/([^/]+)/?$', views_caves.caveDescription),
- url(r'^cave/qms/([^/]+)/?$', views_caves.caveQMs),
- url(r'^cave/logbook/([^/]+)/?$', views_caves.caveLogbook),
- #url(r'^cavedescription/(?P<cavedescription_name>[^/]+)/?$', views_caves.cave_description, name="cavedescription"),
- #url(r'^cavedescription/?$', object_list, {'queryset':CaveDescription.objects.all(),'template_name':'object_list.html'}, name="cavedescriptions"),
- #url(r'^cavehref/(.+)$', views_caves.cave, name="cave"),url(r'cave'),
-
- url(r'^jgtfile/(.*)$', view_surveys.jgtfile, name="jgtfile"),
- url(r'^jgtuploadfile$', view_surveys.jgtuploadfile, name="jgtuploadfile"),
-
- url(r'^cave/(?P<cave_id>[^/]+)/?(?P<ent_letter>[^/])$', ent),
- #(r'^cave/(?P<cave_id>[^/]+)/edit/$', edit_cave),
- #(r'^cavesearch', caveSearch),
-
-
- url(r'^cave/(?P<cave_id>[^/]+)/(?P<year>\d\d\d\d)-(?P<qm_id>\d*)(?P<grade>[ABCDX]?)?$', views_caves.qm, name="qm"),
-
-
- url(r'^logbooksearch/(.*)/?$', views_logbooks.logbookSearch),
-
-
- url(r'^statistics/?$', views_other.stats, name="stats"),
-
- url(r'^survey/?$', surveyindex, name="survey"),
- url(r'^survey/(?P<year>\d\d\d\d)\#(?P<wallet_number>\d*)$', survey, name="survey"),
-
- url(r'^controlpanel/?$', views_other.controlPanel, name="controlpanel"),
- url(r'^CAVETAB2\.CSV/?$', views_other.downloadCavetab, name="downloadcavetab"),
- url(r'^Surveys\.csv/?$', views_other.downloadSurveys, name="downloadsurveys"),
- url(r'^logbook(?P<year>\d\d\d\d)\.(?P<extension>.*)/?$',views_other.downloadLogbook),
- url(r'^logbook/?$',views_other.downloadLogbook, name="downloadlogbook"),
- url(r'^cave/(?P<cave_id>[^/]+)/qm\.csv/?$', views_other.downloadQMs, name="downloadqms"),
- (r'^downloadqms$', views_other.downloadQMs),
-
- url(r'^eyecandy$', views_other.eyecandy),
-
- (r'^admin/doc/?', include('django.contrib.admindocs.urls')),
- url(r'^admin/(.*)', admin.site.root, name="admin"),
-
- # don't know why this needs troggle/ in here. nice to get it out
- url(r'^troggle/media-admin/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ADMIN_DIR, 'show_indexes':True}),
-
-
- (r'^accounts/', include('registration.urls')),
- (r'^profiles/', include('profiles.urls')),
-
-
-# (r'^personform/(.*)$', personForm),
-
- (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
- {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
- (r'^tinymce_media/(?P<path>.*)$', 'django.views.static.serve',
- {'document_root': settings.TINY_MCE_MEDIA_ROOT, 'show_indexes': True}),
-
-
- url(r'^survexblock/(.+)$', views_caves.survexblock, name="survexblock"),
- url(r'^survexfile/(?P<survex_file>.*?)\.svx$', views_survex.svx, name="svx"),
- url(r'^survexfile/(?P<survex_file>.*?)\.3d$', views_survex.threed, name="threed"),
- url(r'^survexfile/(?P<survex_file>.*?)\.log$', views_survex.svxraw),
- url(r'^survexfile/(?P<survex_file>.*?)\.err$', views_survex.err),
-
-
- url(r'^survexfile/caves/$', views_survex.survexcaveslist, name="survexcaveslist"),
- url(r'^survexfile/caves/(?P<survex_cave>.*)$', views_survex.survexcavesingle, name="survexcavessingle"),
- url(r'^survexfileraw/(?P<survex_file>.*?)\.svx$', views_survex.svxraw, name="svxraw"),
-
-
- (r'^survey_files/listdir/(?P<path>.*)$', view_surveys.listdir),
- (r'^survey_files/download/(?P<path>.*)$', view_surveys.download),
- #(r'^survey_files/upload/(?P<path>.*)$', view_surveys.upload),
-
-
-
- #(r'^survey_scans/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.SURVEY_SCANS, 'show_indexes':True}),
- url(r'^survey_scans/$', view_surveys.surveyscansfolders, name="surveyscansfolders"),
- url(r'^survey_scans/(?P<path>[^/]+)/$', view_surveys.surveyscansfolder, name="surveyscansfolder"),
- url(r'^survey_scans/(?P<path>[^/]+)/(?P<file>[^/]+(?:png|jpg))$',
- view_surveys.surveyscansingle, name="surveyscansingle"),
-
- url(r'^tunneldata/$', view_surveys.tunneldata, name="tunneldata"),
- url(r'^tunneldataraw/(?P<path>.+?\.xml)$', view_surveys.tunnelfile, name="tunnelfile"),
- url(r'^tunneldataraw/(?P<path>.+?\.xml)/upload$',view_surveys.tunnelfileupload, name="tunnelfileupload"),
-
- #url(r'^tunneldatainfo/(?P<path>.+?\.xml)$', view_surveys.tunnelfileinfo, name="tunnelfileinfo"),
-
- (r'^photos/(?P<path>.*)$', 'django.views.static.serve',
- {'document_root': settings.PHOTOS_ROOT, 'show_indexes':True}),
-
- # for those silly ideas
- url(r'^experimental.*$', views_logbooks.experimental, name="experimental"),
-
- #url(r'^trip_report/?$',views_other.tripreport,name="trip_report")
-
- url(r'^(.*)_edit$', 'flatpages.views.editflatpage', name="editflatpage"),
- url(r'^(.*)$', 'flatpages.views.flatpage', name="flatpage"),
-)
-
-#Allow prefix to all urls
-urlpatterns = patterns ('',
- ('^%s' % settings.DIR_ROOT, include(actualurlpatterns))
-)
+from django.conf.urls.defaults import * +from django.conf import settings + +from core.views import * # flat import +from core.views_other import * +from core.views_caves import * +from core.views_survex import * +from core.models import * +from django.views.generic.create_update import create_object +from django.contrib import admin +from django.views.generic.list_detail import object_list +from django.contrib import admin +admin.autodiscover() + + +# type url probably means it's used. + +actualurlpatterns = patterns('', + + url(r'^troggle$', views_other.frontpage, name="frontpage"), + url(r'^todo/$', views_other.todo, name="todo"), + + url(r'^caves/?$', views_caves.caveindex, name="caveindex"), + url(r'^people/?$', views_logbooks.personindex, name="personindex"), + + url(r'^newqmnumber/?$', views_other.ajax_QM_number, ), + url(r'^lbo_suggestions/?$', logbook_entry_suggestions), + #(r'^person/(?P<person_id>\d*)/?$', views_logbooks.person), + url(r'^person/(?P<first_name>[A-Z]*[a-z\-\']*)[^a-zA-Z]*(?P<last_name>[a-z\-\']*[^a-zA-Z]*[A-Z]*[a-z\-]*)/?', views_logbooks.person, name="person"), + #url(r'^person/(\w+_\w+)$', views_logbooks.person, name="person"), + + url(r'^expedition/(\d+)$', views_logbooks.expedition, name="expedition"), + url(r'^expeditions/?$', object_list, {'queryset':Expedition.objects.all(),'template_name':'object_list.html'},name="expeditions"), + url(r'^personexpedition/(?P<first_name>[A-Z]*[a-z]*)[^a-zA-Z]*(?P<last_name>[A-Z]*[a-z]*)/(?P<year>\d+)/?$', views_logbooks.personexpedition, name="personexpedition"), + url(r'^logbookentry/(?P<date>.*)/(?P<slug>.*)/?$', views_logbooks.logbookentry,name="logbookentry"), + url(r'^newlogbookentry/(?P<expeditionyear>.*)$', views_logbooks.newLogbookEntry, name="newLogBookEntry"), + url(r'^editlogbookentry/(?P<expeditionyear>[^/]*)/(?P<pdate>[^/]*)/(?P<pslug>[^/]*)/$', views_logbooks.newLogbookEntry, name="editLogBookEntry"), + url(r'^deletelogbookentry/(?P<expeditionyear>[^/]*)/(?P<date>[^/]*)/(?P<slug>[^/]*)/$', views_logbooks.deleteLogbookEntry, name="deleteLogBookEntry"), + url(r'^newfile', views_other.newFile, name="newFile"), + + url(r'^getEntrances/(?P<caveslug>.*)', views_caves.get_entrances, name = "get_entrances"), + url(r'^getQMs/(?P<caveslug>.*)', views_caves.get_qms, name = "get_qms"), + url(r'^getPeople/(?P<expeditionslug>.*)', views_logbooks.get_people, name = "get_people"), + url(r'^getLogBookEntries/(?P<expeditionslug>.*)', views_logbooks.get_logbook_entries, name = "get_logbook_entries"), + + url(r'^cave/(?P<cave_id>[^/]+)/?$', views_caves.cave, name="cave"), + url(r'^caveslug/([^/]+)/?$', views_caves.caveSlug, name="caveSlug"), + url(r'^cave/entrance/([^/]+)/?$', views_caves.caveEntrance), + url(r'^cave/description/([^/]+)/?$', views_caves.caveDescription), + url(r'^cave/qms/([^/]+)/?$', views_caves.caveQMs), + url(r'^cave/logbook/([^/]+)/?$', views_caves.caveLogbook), + #url(r'^cavedescription/(?P<cavedescription_name>[^/]+)/?$', views_caves.cave_description, name="cavedescription"), + #url(r'^cavedescription/?$', object_list, {'queryset':CaveDescription.objects.all(),'template_name':'object_list.html'}, name="cavedescriptions"), + #url(r'^cavehref/(.+)$', views_caves.cave, name="cave"),url(r'cave'), + + url(r'^jgtfile/(.*)$', view_surveys.jgtfile, name="jgtfile"), + url(r'^jgtuploadfile$', view_surveys.jgtuploadfile, name="jgtuploadfile"), + + url(r'^cave/(?P<cave_id>[^/]+)/?(?P<ent_letter>[^/])$', ent), + #(r'^cave/(?P<cave_id>[^/]+)/edit/$', edit_cave), + #(r'^cavesearch', caveSearch), + + + url(r'^cave/(?P<cave_id>[^/]+)/(?P<year>\d\d\d\d)-(?P<qm_id>\d*)(?P<grade>[ABCDX]?)?$', views_caves.qm, name="qm"), + + + url(r'^logbooksearch/(.*)/?$', views_logbooks.logbookSearch), + + + url(r'^statistics/?$', views_other.stats, name="stats"), + + url(r'^survey/?$', surveyindex, name="survey"), + url(r'^survey/(?P<year>\d\d\d\d)\#(?P<wallet_number>\d*)$', survey, name="survey"), + + url(r'^controlpanel/?$', views_other.controlPanel, name="controlpanel"), + url(r'^CAVETAB2\.CSV/?$', views_other.downloadCavetab, name="downloadcavetab"), + url(r'^Surveys\.csv/?$', views_other.downloadSurveys, name="downloadsurveys"), + url(r'^logbook(?P<year>\d\d\d\d)\.(?P<extension>.*)/?$',views_other.downloadLogbook), + url(r'^logbook/?$',views_other.downloadLogbook, name="downloadlogbook"), + url(r'^cave/(?P<cave_id>[^/]+)/qm\.csv/?$', views_other.downloadQMs, name="downloadqms"), + (r'^downloadqms$', views_other.downloadQMs), + + url(r'^eyecandy$', views_other.eyecandy), + + (r'^admin/doc/?', include('django.contrib.admindocs.urls')), + url(r'^admin/(.*)', admin.site.root, name="admin"), + + # don't know why this needs troggle/ in here. nice to get it out + url(r'^troggle/media-admin/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ADMIN_DIR, 'show_indexes':True}), + + + (r'^accounts/', include('registration.urls')), + (r'^profiles/', include('profiles.urls')), + + +# (r'^personform/(.*)$', personForm), + + (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', + {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), + (r'^tinymce_media/(?P<path>.*)$', 'django.views.static.serve', + {'document_root': settings.TINY_MCE_MEDIA_ROOT, 'show_indexes': True}), + + + url(r'^survexblock/(.+)$', views_caves.survexblock, name="survexblock"), + url(r'^survexfile/(?P<survex_file>.*?)\.svx$', views_survex.svx, name="svx"), + url(r'^survexfile/(?P<survex_file>.*?)\.3d$', views_survex.threed, name="threed"), + url(r'^survexfile/(?P<survex_file>.*?)\.log$', views_survex.svxraw), + url(r'^survexfile/(?P<survex_file>.*?)\.err$', views_survex.err), + + + url(r'^survexfile/caves/$', views_survex.survexcaveslist, name="survexcaveslist"), + url(r'^survexfile/caves/(?P<survex_cave>.*)$', views_survex.survexcavesingle, name="survexcavessingle"), + url(r'^survexfileraw/(?P<survex_file>.*?)\.svx$', views_survex.svxraw, name="svxraw"), + + + (r'^survey_files/listdir/(?P<path>.*)$', view_surveys.listdir), + (r'^survey_files/download/(?P<path>.*)$', view_surveys.download), + #(r'^survey_files/upload/(?P<path>.*)$', view_surveys.upload), + + + + #(r'^survey_scans/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.SURVEY_SCANS, 'show_indexes':True}), + url(r'^survey_scans/$', view_surveys.surveyscansfolders, name="surveyscansfolders"), + url(r'^survey_scans/(?P<path>[^/]+)/$', view_surveys.surveyscansfolder, name="surveyscansfolder"), + url(r'^survey_scans/(?P<path>[^/]+)/(?P<file>[^/]+(?:png|jpg))$', + view_surveys.surveyscansingle, name="surveyscansingle"), + + url(r'^tunneldata/$', view_surveys.tunneldata, name="tunneldata"), + url(r'^tunneldataraw/(?P<path>.+?\.xml)$', view_surveys.tunnelfile, name="tunnelfile"), + url(r'^tunneldataraw/(?P<path>.+?\.xml)/upload$',view_surveys.tunnelfileupload, name="tunnelfileupload"), + + #url(r'^tunneldatainfo/(?P<path>.+?\.xml)$', view_surveys.tunnelfileinfo, name="tunnelfileinfo"), + + (r'^photos/(?P<path>.*)$', 'django.views.static.serve', + {'document_root': settings.PHOTOS_ROOT, 'show_indexes':True}), + + # for those silly ideas + url(r'^experimental.*$', views_logbooks.experimental, name="experimental"), + + #url(r'^trip_report/?$',views_other.tripreport,name="trip_report") + + url(r'^(.*)_edit$', 'flatpages.views.editflatpage', name="editflatpage"), + url(r'^(.*)$', 'flatpages.views.flatpage', name="flatpage"), +) + +#Allow prefix to all urls +urlpatterns = patterns ('', + ('^%s' % settings.DIR_ROOT, include(actualurlpatterns)) +) @@ -1,178 +1,178 @@ -from django.conf import settings
-import random, re, logging
-from core.models import CaveDescription
-
-def weighted_choice(lst):
- n = random.uniform(0,1)
- for item, weight in lst:
- if n < weight:
- break
- n = n - weight
- return item
-
-def randomLogbookSentence():
- from troggle.core.models import LogbookEntry
- randSent={}
-
- # needs to handle empty logbooks without crashing
-
- #Choose a random logbook entry
- randSent['entry']=LogbookEntry.objects.order_by('?')[0]
-
- #Choose again if there are no sentances (this happens if it is a placeholder entry)
- while len(re.findall('[A-Z].*?\.',randSent['entry'].text))==0:
- randSent['entry']=LogbookEntry.objects.order_by('?')[0]
-
- #Choose a random sentence from that entry. Store the sentence as randSent['sentence'], and the number of that sentence in the entry as randSent['number']
- sentenceList=re.findall('[A-Z].*?\.',randSent['entry'].text)
- randSent['number']=random.randrange(0,len(sentenceList))
- randSent['sentence']=sentenceList[randSent['number']]
-
- return randSent
-
-
-def save_carefully(objectType, lookupAttribs={}, nonLookupAttribs={}):
- """Looks up instance using lookupAttribs and carries out the following:
- -if instance does not exist in DB: add instance to DB, return (new instance, True)
- -if instance exists in DB and was modified using Troggle: do nothing, return (existing instance, False)
- -if instance exists in DB and was not modified using Troggle: overwrite instance, return (instance, False)
-
- The checking is accomplished using Django's get_or_create and the new_since_parsing boolean field
- defined in core.models.TroggleModel.
-
- """
-
- instance, created=objectType.objects.get_or_create(defaults=nonLookupAttribs, **lookupAttribs)
-
- if not created and not instance.new_since_parsing:
- for k, v in nonLookupAttribs.items(): #overwrite the existing attributes from the logbook text (except date and title)
- setattr(instance, k, v)
- instance.save()
-
- if created:
- logging.info(str(instance) + ' was just added to the database for the first time. \n')
-
- if not created and instance.new_since_parsing:
- logging.info(str(instance) + " has been modified using Troggle, so the current script left it as is. \n")
-
- if not created and not instance.new_since_parsing:
- logging.info(str(instance) + " existed in the database unchanged since last parse. It was overwritten by the current script. \n")
- return (instance, created)
-
-def render_with_context(req, *args, **kwargs):
- """this is the snippet from http://www.djangosnippets.org/snippets/3/
-
- Django uses Context, not RequestContext when you call render_to_response.
- We always want to use RequestContext, so that django adds the context from
- settings.TEMPLATE_CONTEXT_PROCESSORS. This way we automatically get
- necessary settings variables passed to each template. So we use a custom
- method, render_response instead of render_to_response. Hopefully future
- Django releases will make this unnecessary."""
-
- from django.shortcuts import render_to_response
- from django.template import RequestContext
- kwargs['context_instance'] = RequestContext(req)
- return render_to_response(*args, **kwargs)
-
-re_body = re.compile(r"\<body[^>]*\>(.*)\</body\>", re.DOTALL)
-re_title = re.compile(r"\<title[^>]*\>(.*)\</title\>", re.DOTALL)
-
-def get_html_body(text):
- return get_single_match(re_body, text)
-
-def get_html_title(text):
- return get_single_match(re_title, text)
-
-def get_single_match(regex, text):
- match = regex.search(text)
-
- if match:
- return match.groups()[0]
- else:
- return None
-
-def href_to_wikilinks(matchobj):
- """
- Given an html link, checks for possible valid wikilinks.
-
- Returns the first valid wikilink. Valid means the target
- object actually exists.
- """
- res=CaveDescription.objects.filter(long_name__icontains=matchobj.groupdict()['text'])
- if res and res[0]:
- return r'[[cavedescription:'+res[0].short_name+'|'+res[0].long_name+']]'
- else:
- return matchobj.group()
- #except:
- #print 'fail'
-
-
-re_subs = [(re.compile(r"\<b[^>]*\>(.*?)\</b\>", re.DOTALL), r"'''\1'''"),
- (re.compile(r"\<i\>(.*?)\</i\>", re.DOTALL), r"''\1''"),
- (re.compile(r"\<h1[^>]*\>(.*?)\</h1\>", re.DOTALL), r"=\1="),
- (re.compile(r"\<h2[^>]*\>(.*?)\</h2\>", re.DOTALL), r"==\1=="),
- (re.compile(r"\<h3[^>]*\>(.*?)\</h3\>", re.DOTALL), r"===\1==="),
- (re.compile(r"\<h4[^>]*\>(.*?)\</h4\>", re.DOTALL), r"====\1===="),
- (re.compile(r"\<h5[^>]*\>(.*?)\</h5\>", re.DOTALL), r"=====\1====="),
- (re.compile(r"\<h6[^>]*\>(.*?)\</h6\>", re.DOTALL), r"======\1======"),
- (re.compile(r'(<a href="?(?P<target>.*)"?>)?<img class="?(?P<class>\w*)"? src="?t/?(?P<source>[\w/\.]*)"?(?P<rest>></img>|\s/>(</a>)?)', re.DOTALL),r'[[display:\g<class> photo:\g<source>]]'), #
- (re.compile(r"\<a\s+id=['\"]([^'\"]*)['\"]\s*\>(.*?)\</a\>", re.DOTALL), r"[[subcave:\1|\2]]"), #assumes that all links with id attributes are subcaves. Not great.
- #interpage link needed
- (re.compile(r"\<a\s+href=['\"]#([^'\"]*)['\"]\s*\>(.*?)\</a\>", re.DOTALL), r"[[cavedescription:\1|\2]]"), #assumes that all links with target ids are cave descriptions. Not great.
- (re.compile(r"\[\<a\s+href=['\"][^'\"]*['\"]\s+id=['\"][^'\"]*['\"]\s*\>([^\s]*).*?\</a\>\]", re.DOTALL), r"[[qm:\1]]"),
- (re.compile(r'<a\shref="?(?P<target>.*)"?>(?P<text>.*)</a>'),href_to_wikilinks),
-
- ]
-
-def html_to_wiki(text, codec = "utf-8"):
- if type(text) == str:
- text = unicode(text, codec)
- text = re.sub("</p>", r"", text)
- text = re.sub("<p>$", r"", text)
- text = re.sub("<p>", r"\n\n", text)
- out = ""
- lists = ""
- #lists
- while text:
- mstar = re.match("^(.*?)<ul[^>]*>\s*<li[^>]*>(.*?)</li>(.*)$", text, re.DOTALL)
- munstar = re.match("^(\s*)</ul>(.*)$", text, re.DOTALL)
- mhash = re.match("^(.*?)<ol[^>]*>\s*<li[^>]*>(.*?)</li>(.*)$", text, re.DOTALL)
- munhash = re.match("^(\s*)</ol>(.*)$", text, re.DOTALL)
- mitem = re.match("^(\s*)<li[^>]*>(.*?)</li>(.*)$", text, re.DOTALL)
- ms = [len(m.groups()[0]) for m in [mstar, munstar, mhash, munhash, mitem] if m]
- def min_(i, l):
- try:
- v = i.groups()[0]
- l.remove(len(v))
- return len(v) < min(l, 1000000000)
- except:
- return False
- if min_(mstar, ms):
- lists += "*"
- pre, val, post = mstar.groups()
- out += pre + "\n" + lists + " " + val
- text = post
- elif min_(mhash, ms):
- lists += "#"
- pre, val, post = mhash.groups()
- out += pre + "\n" + lists + " " + val
- text = post
- elif min_(mitem, ms):
- pre, val, post = mitem.groups()
- out += "\n" + lists + " " + val
- text = post
- elif min_(munstar, ms):
- lists = lists[:-1]
- text = munstar.groups()[1]
- elif min_(munhash, ms):
- lists.pop()
- text = munhash.groups()[1]
- else:
- out += text
- text = ""
- #substitutions
- for regex, repl in re_subs:
- out = regex.sub(repl, out)
- return out
-
-
+from django.conf import settings +import random, re, logging +from core.models import CaveDescription + +def weighted_choice(lst): + n = random.uniform(0,1) + for item, weight in lst: + if n < weight: + break + n = n - weight + return item + +def randomLogbookSentence(): + from troggle.core.models import LogbookEntry + randSent={} + + # needs to handle empty logbooks without crashing + + #Choose a random logbook entry + randSent['entry']=LogbookEntry.objects.order_by('?')[0] + + #Choose again if there are no sentances (this happens if it is a placeholder entry) + while len(re.findall('[A-Z].*?\.',randSent['entry'].text))==0: + randSent['entry']=LogbookEntry.objects.order_by('?')[0] + + #Choose a random sentence from that entry. Store the sentence as randSent['sentence'], and the number of that sentence in the entry as randSent['number'] + sentenceList=re.findall('[A-Z].*?\.',randSent['entry'].text) + randSent['number']=random.randrange(0,len(sentenceList)) + randSent['sentence']=sentenceList[randSent['number']] + + return randSent + + +def save_carefully(objectType, lookupAttribs={}, nonLookupAttribs={}): + """Looks up instance using lookupAttribs and carries out the following: + -if instance does not exist in DB: add instance to DB, return (new instance, True) + -if instance exists in DB and was modified using Troggle: do nothing, return (existing instance, False) + -if instance exists in DB and was not modified using Troggle: overwrite instance, return (instance, False) + + The checking is accomplished using Django's get_or_create and the new_since_parsing boolean field + defined in core.models.TroggleModel. + + """ + + instance, created=objectType.objects.get_or_create(defaults=nonLookupAttribs, **lookupAttribs) + + if not created and not instance.new_since_parsing: + for k, v in nonLookupAttribs.items(): #overwrite the existing attributes from the logbook text (except date and title) + setattr(instance, k, v) + instance.save() + + if created: + logging.info(str(instance) + ' was just added to the database for the first time. \n') + + if not created and instance.new_since_parsing: + logging.info(str(instance) + " has been modified using Troggle, so the current script left it as is. \n") + + if not created and not instance.new_since_parsing: + logging.info(str(instance) + " existed in the database unchanged since last parse. It was overwritten by the current script. \n") + return (instance, created) + +def render_with_context(req, *args, **kwargs): + """this is the snippet from http://www.djangosnippets.org/snippets/3/ + + Django uses Context, not RequestContext when you call render_to_response. + We always want to use RequestContext, so that django adds the context from + settings.TEMPLATE_CONTEXT_PROCESSORS. This way we automatically get + necessary settings variables passed to each template. So we use a custom + method, render_response instead of render_to_response. Hopefully future + Django releases will make this unnecessary.""" + + from django.shortcuts import render_to_response + from django.template import RequestContext + kwargs['context_instance'] = RequestContext(req) + return render_to_response(*args, **kwargs) + +re_body = re.compile(r"\<body[^>]*\>(.*)\</body\>", re.DOTALL) +re_title = re.compile(r"\<title[^>]*\>(.*)\</title\>", re.DOTALL) + +def get_html_body(text): + return get_single_match(re_body, text) + +def get_html_title(text): + return get_single_match(re_title, text) + +def get_single_match(regex, text): + match = regex.search(text) + + if match: + return match.groups()[0] + else: + return None + +def href_to_wikilinks(matchobj): + """ + Given an html link, checks for possible valid wikilinks. + + Returns the first valid wikilink. Valid means the target + object actually exists. + """ + res=CaveDescription.objects.filter(long_name__icontains=matchobj.groupdict()['text']) + if res and res[0]: + return r'[[cavedescription:'+res[0].short_name+'|'+res[0].long_name+']]' + else: + return matchobj.group() + #except: + #print 'fail' + + +re_subs = [(re.compile(r"\<b[^>]*\>(.*?)\</b\>", re.DOTALL), r"'''\1'''"), + (re.compile(r"\<i\>(.*?)\</i\>", re.DOTALL), r"''\1''"), + (re.compile(r"\<h1[^>]*\>(.*?)\</h1\>", re.DOTALL), r"=\1="), + (re.compile(r"\<h2[^>]*\>(.*?)\</h2\>", re.DOTALL), r"==\1=="), + (re.compile(r"\<h3[^>]*\>(.*?)\</h3\>", re.DOTALL), r"===\1==="), + (re.compile(r"\<h4[^>]*\>(.*?)\</h4\>", re.DOTALL), r"====\1===="), + (re.compile(r"\<h5[^>]*\>(.*?)\</h5\>", re.DOTALL), r"=====\1====="), + (re.compile(r"\<h6[^>]*\>(.*?)\</h6\>", re.DOTALL), r"======\1======"), + (re.compile(r'(<a href="?(?P<target>.*)"?>)?<img class="?(?P<class>\w*)"? src="?t/?(?P<source>[\w/\.]*)"?(?P<rest>></img>|\s/>(</a>)?)', re.DOTALL),r'[[display:\g<class> photo:\g<source>]]'), # + (re.compile(r"\<a\s+id=['\"]([^'\"]*)['\"]\s*\>(.*?)\</a\>", re.DOTALL), r"[[subcave:\1|\2]]"), #assumes that all links with id attributes are subcaves. Not great. + #interpage link needed + (re.compile(r"\<a\s+href=['\"]#([^'\"]*)['\"]\s*\>(.*?)\</a\>", re.DOTALL), r"[[cavedescription:\1|\2]]"), #assumes that all links with target ids are cave descriptions. Not great. + (re.compile(r"\[\<a\s+href=['\"][^'\"]*['\"]\s+id=['\"][^'\"]*['\"]\s*\>([^\s]*).*?\</a\>\]", re.DOTALL), r"[[qm:\1]]"), + (re.compile(r'<a\shref="?(?P<target>.*)"?>(?P<text>.*)</a>'),href_to_wikilinks), + + ] + +def html_to_wiki(text, codec = "utf-8"): + if type(text) == str: + text = unicode(text, codec) + text = re.sub("</p>", r"", text) + text = re.sub("<p>$", r"", text) + text = re.sub("<p>", r"\n\n", text) + out = "" + lists = "" + #lists + while text: + mstar = re.match("^(.*?)<ul[^>]*>\s*<li[^>]*>(.*?)</li>(.*)$", text, re.DOTALL) + munstar = re.match("^(\s*)</ul>(.*)$", text, re.DOTALL) + mhash = re.match("^(.*?)<ol[^>]*>\s*<li[^>]*>(.*?)</li>(.*)$", text, re.DOTALL) + munhash = re.match("^(\s*)</ol>(.*)$", text, re.DOTALL) + mitem = re.match("^(\s*)<li[^>]*>(.*?)</li>(.*)$", text, re.DOTALL) + ms = [len(m.groups()[0]) for m in [mstar, munstar, mhash, munhash, mitem] if m] + def min_(i, l): + try: + v = i.groups()[0] + l.remove(len(v)) + return len(v) < min(l, 1000000000) + except: + return False + if min_(mstar, ms): + lists += "*" + pre, val, post = mstar.groups() + out += pre + "\n" + lists + " " + val + text = post + elif min_(mhash, ms): + lists += "#" + pre, val, post = mhash.groups() + out += pre + "\n" + lists + " " + val + text = post + elif min_(mitem, ms): + pre, val, post = mitem.groups() + out += "\n" + lists + " " + val + text = post + elif min_(munstar, ms): + lists = lists[:-1] + text = munstar.groups()[1] + elif min_(munhash, ms): + lists.pop() + text = munhash.groups()[1] + else: + out += text + text = "" + #substitutions + for regex, repl in re_subs: + out = regex.sub(repl, out) + return out + + |