forked from expo/troggle
edit logbooks, new logbook format, increased database normalisation
This commit is contained in:
parent
1cc7f2d92e
commit
b001df1f53
@ -50,14 +50,13 @@ class PhotoInline(admin.TabularInline):
|
|||||||
|
|
||||||
class PersonTripInline(admin.TabularInline):
|
class PersonTripInline(admin.TabularInline):
|
||||||
model = PersonTrip
|
model = PersonTrip
|
||||||
exclude = ['persontrip_next','Delete']
|
|
||||||
raw_id_fields = ('personexpedition',)
|
raw_id_fields = ('personexpedition',)
|
||||||
extra = 1
|
extra = 1
|
||||||
|
|
||||||
#class LogbookEntryAdmin(VersionAdmin):
|
#class LogbookEntryAdmin(VersionAdmin):
|
||||||
class LogbookEntryAdmin(TroggleModelAdmin):
|
class LogbookEntryAdmin(TroggleModelAdmin):
|
||||||
prepopulated_fields = {'slug':("title",)}
|
prepopulated_fields = {'slug':("title",)}
|
||||||
raw_id_fields = ('cave','author')
|
raw_id_fields = ('cave',)
|
||||||
search_fields = ('title','expedition__year')
|
search_fields = ('title','expedition__year')
|
||||||
date_heirarchy = ('date')
|
date_heirarchy = ('date')
|
||||||
inlines = (PersonTripInline, PhotoInline, QMsFoundInline)
|
inlines = (PersonTripInline, PhotoInline, QMsFoundInline)
|
||||||
@ -140,4 +139,4 @@ def export_as_xml(modeladmin, request, queryset):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
#admin.site.add_action(export_as_xml)
|
#admin.site.add_action(export_as_xml)
|
||||||
#admin.site.add_action(export_as_json)
|
#admin.site.add_action(export_as_json)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
from django.forms import ModelForm
|
from django.forms import ModelForm
|
||||||
from models import Cave, Person, LogbookEntry, QM
|
from models import Cave, Person, PersonExpedition, LogbookEntry, QM
|
||||||
import django.forms as forms
|
import django.forms as forms
|
||||||
from django.forms.formsets import formset_factory
|
from django.forms.formsets import formset_factory
|
||||||
from django.contrib.admin.widgets import AdminDateWidget
|
from django.contrib.admin.widgets import AdminDateWidget
|
||||||
import string
|
import string
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
from tinymce.widgets import TinyMCE
|
||||||
|
|
||||||
class CaveForm(ModelForm):
|
class CaveForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -45,4 +46,43 @@ class LogbookEntryForm(ModelForm):
|
|||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(LogbookEntryForm, self).__init__(*args, **kwargs)
|
super(LogbookEntryForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['text'].help_text=self.wikiLinkHints()
|
self.fields['text'].help_text=self.wikiLinkHints()
|
||||||
|
|
||||||
|
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):
|
||||||
|
def get_name(pe):
|
||||||
|
if pe.nickname:
|
||||||
|
return pe.nickname
|
||||||
|
else:
|
||||||
|
return pe.person.first_name
|
||||||
|
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
|
||||||
|
|
||||||
|
@ -232,23 +232,27 @@ class PersonExpedition(TroggleModel):
|
|||||||
# Single parsed entry from Logbook
|
# Single parsed entry from Logbook
|
||||||
#
|
#
|
||||||
class LogbookEntry(TroggleModel):
|
class LogbookEntry(TroggleModel):
|
||||||
date = models.DateField()
|
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)
|
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-
|
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.
|
#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
|
# Re: the above- so this field should be "typist" or something, not "author". - AC 15 jun 09
|
||||||
title = models.CharField(max_length=200)
|
#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)
|
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")
|
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()
|
text = models.TextField()
|
||||||
slug = models.SlugField(max_length=50)
|
slug = models.SlugField(max_length=50)
|
||||||
|
filename= models.CharField(max_length=200,null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = "Logbook Entries"
|
verbose_name_plural = "Logbook Entries"
|
||||||
# several PersonTrips point in to this object
|
# several PersonTrips point in to this object
|
||||||
class Meta:
|
|
||||||
ordering = ('-date',)
|
ordering = ('-date',)
|
||||||
|
|
||||||
|
def isLogbookEntry(self): # Function used in templates
|
||||||
|
return True
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return urlparse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug}))
|
return urlparse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug}))
|
||||||
|
|
||||||
@ -282,22 +286,36 @@ class LogbookEntry(TroggleModel):
|
|||||||
class PersonTrip(TroggleModel):
|
class PersonTrip(TroggleModel):
|
||||||
personexpedition = models.ForeignKey("PersonExpedition",null=True)
|
personexpedition = models.ForeignKey("PersonExpedition",null=True)
|
||||||
|
|
||||||
expeditionday = models.ForeignKey("ExpeditionDay")
|
#expeditionday = models.ForeignKey("ExpeditionDay")#MJG wants to KILL THIS (redundant information)
|
||||||
date = models.DateField()
|
#date = models.DateField() #MJG wants to KILL THIS (redundant information)
|
||||||
time_underground = models.FloatField(help_text="In decimal hours")
|
time_underground = models.FloatField(help_text="In decimal hours")
|
||||||
logbook_entry = models.ForeignKey(LogbookEntry)
|
logbook_entry = models.ForeignKey(LogbookEntry)
|
||||||
is_logbook_entry_author = models.BooleanField()
|
is_logbook_entry_author = models.BooleanField()
|
||||||
|
|
||||||
|
|
||||||
# sequencing by person (difficult to solve locally)
|
# sequencing by person (difficult to solve locally)
|
||||||
persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)
|
#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)
|
#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):
|
def place(self):
|
||||||
return self.logbook_entry.cave and self.logbook_entry.cave or self.logbook_entry.place
|
return self.logbook_entry.cave and self.logbook_entry.cave or self.logbook_entry.place
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return "%s (%s)" % (self.personexpedition, self.date)
|
return "%s (%s)" % (self.personexpedition, self.logbook_entry.date)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -350,7 +368,18 @@ class Cave(TroggleModel):
|
|||||||
survex_file = 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)
|
description_file = 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)
|
#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):
|
def get_absolute_url(self):
|
||||||
if self.kataster_number:
|
if self.kataster_number:
|
||||||
@ -421,6 +450,14 @@ class Cave(TroggleModel):
|
|||||||
res += "–" + prevR
|
res += "–" + prevR
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def getCaveByReference(reference):
|
||||||
|
print reference
|
||||||
|
areaname, code = reference.split("-", 1)
|
||||||
|
area = Area.objects.get(short_name = areaname)
|
||||||
|
foundCaves = list(Cave.objects.filter(area = area, kataster_number = code).all()) + list(Cave.objects.filter(area = area, unofficial_number = code).all())
|
||||||
|
assert len(foundCaves) == 1
|
||||||
|
return foundCaves[0]
|
||||||
|
|
||||||
class OtherCaveName(TroggleModel):
|
class OtherCaveName(TroggleModel):
|
||||||
name = models.CharField(max_length=160)
|
name = models.CharField(max_length=160)
|
||||||
cave = models.ForeignKey(Cave)
|
cave = models.ForeignKey(Cave)
|
||||||
|
@ -92,6 +92,9 @@ class SurvexBlock(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('id',)
|
ordering = ('id',)
|
||||||
|
|
||||||
|
def isSurvexBlock(self): # Function used in templates
|
||||||
|
return True
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name and unicode(self.name) or 'no name'
|
return self.name and unicode(self.name) or 'no name'
|
||||||
|
|
||||||
@ -188,4 +191,4 @@ class TunnelFile(models.Model):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('tunnelpath',)
|
ordering = ('tunnelpath',)
|
||||||
|
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry
|
from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, SurvexBlock
|
||||||
import troggle.core.models as models
|
import troggle.core.models as models
|
||||||
import troggle.settings as settings
|
import troggle.settings as settings
|
||||||
import django.db.models
|
import django.db.models
|
||||||
from troggle.parsers.logbooks import LoadLogbookForExpedition
|
from troggle.parsers.logbooks import LoadLogbookForExpedition
|
||||||
from troggle.parsers.people import GetPersonExpeditionNameLookup
|
from troggle.parsers.people import GetPersonExpeditionNameLookup
|
||||||
from troggle.core.forms import PersonForm
|
from troggle.core.forms import PersonForm, getTripForm
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.http import HttpResponseRedirect, HttpResponse
|
from django.http import HttpResponseRedirect, HttpResponse
|
||||||
|
from django.template import Context, loader
|
||||||
from utils import render_with_context
|
from utils import render_with_context
|
||||||
|
import os.path
|
||||||
|
import troggle.parsers.logbooks as logbookparsers
|
||||||
|
from django.template.defaultfilters import slugify
|
||||||
|
|
||||||
|
|
||||||
# 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.
|
# 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.
|
||||||
@ -47,18 +51,23 @@ def expedition(request, expeditionname):
|
|||||||
expedition = Expedition.objects.get(year=int(expeditionname))
|
expedition = Expedition.objects.get(year=int(expeditionname))
|
||||||
expeditions = Expedition.objects.all()
|
expeditions = Expedition.objects.all()
|
||||||
personexpeditiondays = [ ]
|
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():
|
for personexpedition in expedition.personexpedition_set.all():
|
||||||
prow = [ ]
|
prow = [ ]
|
||||||
for expeditionday in expedition.expeditionday_set.all():
|
for date in dates:
|
||||||
pcell = { "persontrips":expeditionday.persontrip_set.filter(personexpedition=personexpedition) }
|
pcell = { "persontrips": PersonTrip.objects.filter(personexpedition=personexpedition,
|
||||||
pcell["survexblocks"] = set([survexpersonrole.survexblock for survexpersonrole in expeditionday.survexpersonrole_set.filter(personexpedition=personexpedition)])
|
logbook_entry__date=date) }
|
||||||
|
pcell["survexblocks"] = set(SurvexBlock.objects.filter(survexpersonrole__personexpedition=personexpedition,
|
||||||
|
date = date))
|
||||||
prow.append(pcell)
|
prow.append(pcell)
|
||||||
personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
|
personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
|
||||||
|
|
||||||
message = ""
|
message = ""
|
||||||
if "reload" in request.GET:
|
if "reload" in request.GET:
|
||||||
message = LoadLogbookForExpedition(expedition)
|
message = LoadLogbookForExpedition(expedition)
|
||||||
return render_with_context(request,'expedition.html', {'expedition': expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'message':message, 'settings':settings })
|
return render_with_context(request,'expedition.html', {'expedition': expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'message':message, 'settings':settings, 'dateditems': dateditems })
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return ('expedition', (expedition.year))
|
return ('expedition', (expedition.year))
|
||||||
@ -154,3 +163,78 @@ def experimental(request):
|
|||||||
totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs])
|
totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs])
|
||||||
return render_with_context(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
|
return render_with_context(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
|
||||||
|
|
||||||
|
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__year = year)
|
||||||
|
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)
|
||||||
|
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 tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
|
||||||
|
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 slug and date:
|
||||||
|
if lbe.cave:
|
||||||
|
tripForm = TripForm(date = previousdate,
|
||||||
|
title = previouslbe.title,
|
||||||
|
cave = previouslbe.cave.reference(),
|
||||||
|
location = None,
|
||||||
|
caveOrLocation = "cave",
|
||||||
|
html = previouslbe.text)
|
||||||
|
else:
|
||||||
|
tripForm = TripForm(date = previousdate,
|
||||||
|
title = previouslbe.title,
|
||||||
|
cave = None,
|
||||||
|
location = previouslbe.location,
|
||||||
|
caveOrLocation = "location",
|
||||||
|
html = previouslbe.text)
|
||||||
|
personTripFormSet = PersonTripFormSet(initial=[{"name": py.personexpedition.name(),
|
||||||
|
"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,
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
def deleteLogbookEntry(request, expeditionyear, date = None, slug = None):
|
||||||
|
expedition = Expedition.objects.get(year=expeditionyear)
|
||||||
|
previousdate = datetime.date(*[int(x) for x in pdate.split("-")])
|
||||||
|
previouslbe = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition__year = year)
|
||||||
|
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.delete(lbe.filename)
|
||||||
|
|
||||||
|
@ -11,11 +11,17 @@ from django.http import HttpResponse
|
|||||||
|
|
||||||
|
|
||||||
def reload_db():
|
def reload_db():
|
||||||
cursor = connection.cursor()
|
if settings.DATABASE_ENGINE == 'sqlite3':
|
||||||
cursor.execute("drop database %s" % settings.DATABASE_NAME)
|
try:
|
||||||
cursor.execute("create database %s" % settings.DATABASE_NAME)
|
os.remove(settings.DATABASE_NAME)
|
||||||
cursor.execute("ALTER DATABASE %s CHARACTER SET=utf8" % settings.DATABASE_NAME)
|
except OSError:
|
||||||
cursor.execute("USE %s" % settings.DATABASE_NAME)
|
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)
|
management.call_command('syncdb', interactive=False)
|
||||||
user = User.objects.create_user('expo', 'goatchurch@gmail.com', 'gosser')
|
user = User.objects.create_user('expo', 'goatchurch@gmail.com', 'gosser')
|
||||||
user.is_staff = True
|
user.is_staff = True
|
||||||
@ -111,6 +117,59 @@ def export_cavetab():
|
|||||||
tocavetab.writeCaveTab(outfile)
|
tocavetab.writeCaveTab(outfile)
|
||||||
outfile.close()
|
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()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import core.models
|
import core.models
|
||||||
import sys
|
import sys
|
||||||
@ -118,6 +177,8 @@ if __name__ == "__main__":
|
|||||||
resetdesc()
|
resetdesc()
|
||||||
elif "scans" in sys.argv:
|
elif "scans" in sys.argv:
|
||||||
import_surveyscans()
|
import_surveyscans()
|
||||||
|
elif "QMs" in sys.argv:
|
||||||
|
import_QMs()
|
||||||
elif "tunnel" in sys.argv:
|
elif "tunnel" in sys.argv:
|
||||||
import_tunnelfiles()
|
import_tunnelfiles()
|
||||||
elif "reset" in sys.argv:
|
elif "reset" in sys.argv:
|
||||||
@ -129,6 +190,10 @@ if __name__ == "__main__":
|
|||||||
elif "logbooks" in sys.argv:
|
elif "logbooks" in sys.argv:
|
||||||
management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex
|
management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex
|
||||||
import_logbooks()
|
import_logbooks()
|
||||||
|
elif "autologbooks" in sys.argv:
|
||||||
|
import_auto_logbooks()
|
||||||
|
elif "dumplogbooks" in sys.argv:
|
||||||
|
dumplogbooks()
|
||||||
else:
|
else:
|
||||||
print "Do 'python databaseReset.py reset'"
|
print "Do 'python databaseReset.py reset'"
|
||||||
|
|
||||||
|
@ -90,12 +90,12 @@ def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_
|
|||||||
#Check for an existing copy of the current entry, and save
|
#Check for an existing copy of the current entry, and save
|
||||||
expeditionday = expedition.get_expedition_day(date)
|
expeditionday = expedition.get_expedition_day(date)
|
||||||
lookupAttribs={'date':date, 'title':title}
|
lookupAttribs={'date':date, 'title':title}
|
||||||
nonLookupAttribs={'place':place, 'text':text, 'author':author, 'expedition':expedition, 'expeditionday':expeditionday, 'cave':cave, 'slug':slugify(title)[:50]}
|
nonLookupAttribs={'place':place, 'text':text, 'expedition':expedition, 'cave':cave, 'slug':slugify(title)[:50]}
|
||||||
lbo, created=save_carefully(models.LogbookEntry, lookupAttribs, nonLookupAttribs)
|
lbo, created=save_carefully(models.LogbookEntry, lookupAttribs, nonLookupAttribs)
|
||||||
|
|
||||||
for tripperson, time_underground in trippersons:
|
for tripperson, time_underground in trippersons:
|
||||||
lookupAttribs={'personexpedition':tripperson, 'logbook_entry':lbo}
|
lookupAttribs={'personexpedition':tripperson, 'logbook_entry':lbo}
|
||||||
nonLookupAttribs={'time_underground':time_underground, 'date':date, 'expeditionday':expeditionday, 'is_logbook_entry_author':(tripperson == author)}
|
nonLookupAttribs={'time_underground':time_underground, 'is_logbook_entry_author':(tripperson == author)}
|
||||||
#print nonLookupAttribs
|
#print nonLookupAttribs
|
||||||
save_carefully(models.PersonTrip, lookupAttribs, nonLookupAttribs)
|
save_carefully(models.PersonTrip, lookupAttribs, nonLookupAttribs)
|
||||||
|
|
||||||
@ -328,4 +328,105 @@ def LoadLogbooks():
|
|||||||
parsefunc(year, expedition, txt)
|
parsefunc(year, expedition, txt)
|
||||||
SetDatesFromLogbookEntries(expedition)
|
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
|
||||||
|
25
templates/dataformat/logbookentry.html
Normal file
25
templates/dataformat/logbookentry.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{% autoescape off %}
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style type="text/css">.author {text-decoration:underline}</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<H1>{{trip.title}}</H1>
|
||||||
|
<span class="date">{{date}}</span> - <span class="expeditionyear">{{expeditionyear}}</span>
|
||||||
|
|
||||||
|
{% if trip.caveOrLocation == "cave" %}
|
||||||
|
<span class="cave">{{trip.cave}}</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="location">{{trip.location}}</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for person in persons %}
|
||||||
|
<div class="person">
|
||||||
|
<span class="name{% if person.author %} author{% endif %}">{{person.name}}</span>
|
||||||
|
TU<span class="TU">{% if person.TU %}{{person.TU}}{% else %}0{% endif %}</span>hours
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="report">{{trip.html}}</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{% endautoescape %}
|
@ -67,22 +67,20 @@ an "S" for a survey trip. The colours are the same for people on the same trip.
|
|||||||
<form action="" method="GET"><input type="submit" name="reload" value="Reload"></form>
|
<form action="" method="GET"><input type="submit" name="reload" value="Reload"></form>
|
||||||
|
|
||||||
<h3>Logbooks and survey trips per day</h3>
|
<h3>Logbooks and survey trips per day</h3>
|
||||||
|
<a href="{% url newLogBookEntry expeditionyear=expedition.year %}">New logbook entry</a>
|
||||||
<table class="expeditionlogbooks">
|
<table class="expeditionlogbooks">
|
||||||
<tr><th>Date</th><th>Logged trips</th><th>Surveys</th></tr>
|
<tr><th>Date</th><th>Logged trips</th><th>Surveys</th></tr>
|
||||||
{% for expeditionday in expedition.expeditionday_set.all %}
|
{% regroup dateditems|dictsort:"date" by date as dates %}
|
||||||
|
{% for date in dates %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{expeditionday.date}}</td>
|
<td>{{date.grouper}}</td>
|
||||||
<td>
|
<td>{% for item in date.list %}
|
||||||
{% for logbookentry in expeditionday.logbookentry_set.all %}
|
{% if item.isLogbookEntry %}<a href="{{ item.get_absolute_url }}">{{item.title|safe}}</a><br/>{% endif %}
|
||||||
<a href="{{ logbookentry.get_absolute_url }}">{{logbookentry.title|safe}}</a><br/>
|
{% endfor %}</td>
|
||||||
{% endfor %}
|
<td>{% for item in date.list %}
|
||||||
</td>
|
{% if item.isSurvexBlock %}<a href="{% url svx item.survexfile.path %}">{{item.name}}</a><br/>{% endif %}
|
||||||
<td>
|
{% endfor %}</td>
|
||||||
{% for survexblock in expeditionday.survexblock_set.all %}
|
</tr>
|
||||||
<a href="{% url svx survexblock.survexfile.path %}">{{survexblock.name}}</a>
|
|
||||||
{% endfor %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@ -45,12 +45,12 @@
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
{% if persontrip.persontrip_prev %}
|
{% if persontrip.persontrip_prev %}
|
||||||
<a href="{{ persontrip.persontrip_prev.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_prev.date}}</a>
|
<a href="{{ persontrip.persontrip_prev.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_prev.logbook_entry.date}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if persontrip.persontrip_next %}
|
{% if persontrip.persontrip_next %}
|
||||||
<a href="{{ persontrip.persontrip_next.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_next.date}}</a>
|
<a href="{{ persontrip.persontrip_next.logbook_entry.get_absolute_url }}">{{persontrip.persontrip_next.logbook_entry.date}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
@ -69,4 +69,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if logbookentry.filename %}<a href="{% url editlogbookentry year=logbookentry.year pdate=logbookentry.date pslug=logbookentry.slug %}">Edit</a> <a href="{% url deletelogbookentry year=logbookentry.year date=logbookentry.date slug=logbookentry.slug %}">Delete</a>{%endif%}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
82
templates/newlogbookentry.html
Normal file
82
templates/newlogbookentry.html
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% 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">
|
||||||
|
{{ 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 %}
|
5
urls.py
5
urls.py
@ -33,6 +33,9 @@ urlpatterns = patterns('',
|
|||||||
url(r'^expeditions/?$', object_list, {'queryset':Expedition.objects.all(),'template_name':'object_list.html'},name="expeditions"),
|
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'^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'^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'^cave/(?P<cave_id>[^/]+)/?$', views_caves.cave, name="cave"),
|
url(r'^cave/(?P<cave_id>[^/]+)/?$', views_caves.cave, name="cave"),
|
||||||
url(r'^cavedescription/(?P<cavedescription_name>[^/]+)/?$', views_caves.cave_description, name="cavedescription"),
|
url(r'^cavedescription/(?P<cavedescription_name>[^/]+)/?$', views_caves.cave_description, name="cavedescription"),
|
||||||
@ -83,6 +86,8 @@ urlpatterns = patterns('',
|
|||||||
|
|
||||||
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
|
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
|
||||||
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
|
{'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'^survexblock/(.+)$', views_caves.survexblock, name="survexblock"),
|
||||||
|
Loading…
Reference in New Issue
Block a user