[svn] full checkin. animations disabled, sorry

This commit is contained in:
goatchurch 2009-07-27 13:43:43 +01:00
parent 694fe4b4d8
commit b135ab64e7
11 changed files with 255 additions and 173 deletions

View File

@ -58,6 +58,9 @@ class TroggleImageModel(ImageModel):
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)
@ -72,41 +75,13 @@ class Expedition(TroggleModel):
get_latest_by = 'date_from'
def get_absolute_url(self):
#return settings.URL_ROOT + "/expedition/%s" % self.year
return urlparse.urljoin(settings.URL_ROOT, reverse('expedition',args=[self.year]))
# lose these two functions (inelegant, and we may create a file with the dates that we can load from)
def GuessDateFrom(self):
try:
return self.logbookentry_set.order_by('date')[0].date
except IndexError:
pass
def GuessDateTo(self): # returns the date of the last logbook entry in the expedition
try:
return self.logbookentry_set.order_by('date')[-1].date
except IndexError:
pass
def ListDays(self):
if self.date_from and self.date_to:
res=[]
date=self.date_from
while date <= self.date_to:
res.append(date)
date+=datetime.timedelta(days=1)
return res
elif self.GuessDateFrom() and self.GuessDateTo(): # if we don't have the real dates, try it with the dates taken from the earliest and latest logbook entries
date=self.GuessDateFrom()
while date <= self.GuessDateTo():
res.append(date)
date+=datetime.timedelta(days=1)
return res
return urlparse.urljoin(settings.URL_ROOT, reverse('expedition', args=[self.year]))
#
# single Person, can go on many years
#
class Person(TroggleModel):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
@ -134,12 +109,6 @@ class Person(TroggleModel):
return "%s %s" % (self.first_name, self.last_name)
return self.first_name
# Below are no longer needed. Use {{ person.personexpedition_set.all.0.expedition }} for Firstexpedition, and {{ person.personexpedition_set.latest.expedition }} for Lastexpedition
# these ought to be possible by piping through |min in the template, or getting the first of an ordered list
# def Firstexpedition(self):
# return self.personexpedition_set.order_by('expedition')[0]
# def Lastexpedition(self):
# return self.personexpedition_set.order_by('-expedition')[0]
def notability(self):
notability = Decimal(0)
@ -161,6 +130,9 @@ class Person(TroggleModel):
#self.notability = 0.0 # set temporarily
#
# Person's attenance to one Expo
#
class PersonExpedition(TroggleModel):
expedition = models.ForeignKey(Expedition)
person = models.ForeignKey(Person)
@ -191,50 +163,10 @@ class PersonExpedition(TroggleModel):
#order_with_respect_to = 'expedition'
get_latest_by = 'expedition'
def GetPersonChronology(self):
res = { }
for persontrip in self.persontrip_set.all():
a = res.setdefault(persontrip.date(), { })
a.setdefault("persontrips", [ ]).append(persontrip)
for personrole in self.personrole_set.all():
a = res.setdefault(personrole.survex_block.date, { })
b = a.setdefault("personroles", { })
survexpath = personrole.survex_block.survexpath
if b.get(survexpath):
b[survexpath] += ", " + str(personrole.role)
else:
b[survexpath] = str(personrole.role)
# needs converting dict into list
return sorted(res.items())
# possibly not useful functions anyway -JT
# if you can find a better way to make the expo calendar table, be my guest. It isn't possible to do this logic in a django template without writing custom tags.-AC
def ListDays(self):
"""
Returns a list of the days the person was on the expedition (i.e. the days that the PersonExpedition was in existance). Needed for expedition calendar.
"""
if self.date_from and self.date_to:
res=[]
date=self.date_from
while date <= self.date_to:
res.append(date)
date+=datetime.timedelta(days=1)
return res
def ListDaysTF(self):
"""
Returns a list of true / false values. Each value corresponds to one day on the expedition; True means the person was there, False means they weren't.
"""
if self.date_from and self.date_to:
res=[]
for date in self.expedition.ListDays():
res.append(date in self.ListDays())
return res
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:
@ -244,9 +176,12 @@ class PersonExpedition(TroggleModel):
return self.person.first_name
def get_absolute_url(self):
#return settings.URL_ROOT + '/personexpedition/' + str(self.person.first_name) + '_' + str(self.person.last_name) + '/' +self.expedition.year
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}))
#
# Single parsed entry from Logbook
#
class LogbookEntry(TroggleModel):
date = models.DateField()
expedition = models.ForeignKey(Expedition,blank=True,null=True) # yes this is double-
@ -288,48 +223,35 @@ class LogbookEntry(TroggleModel):
"""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())
#
# 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):
person_expedition = models.ForeignKey(PersonExpedition,null=True)
# this will be a foreign key of the place(s) the trip went through
# possibly a trip has a plurality of triplets pointing into it
#place = models.CharField(max_length=100)
#date = models.DateField()
date = models.DateField()
time_underground = models.FloatField(help_text="In decimal hours")
logbook_entry = models.ForeignKey(LogbookEntry)
is_logbook_entry_author = models.BooleanField()
def date(self):
return self.logbook_entry.date
# sequencing by person (difficult to solve locally)
persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)
persontrip_prev = models.ForeignKey('PersonTrip', related_name='pprev', blank=True,null=True)
def place(self):
if self.logbook_entry.cave:
return self.logbook_entry.cave
else:
return self.logbook_entry.place
#persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)
#persontrip_prev = models.ForeignKey('PersonTrip', related_name='pprev', blank=True,null=True)
return self.logbook_entry.cave and self.logbook_entry.cave or self.logbook_entry.place
def __unicode__(self):
return "%s %s (%s)" % (self.person_expedition, self.place(), self.date())
return "%s (%s)" % (self.person_expedition, self.date)
def get_persons_next_trip(self):
try:
return PersonTrip.objects.filter(person_expedition__person=self.person_expedition.person, person_expedition__date__gt=self.date)[0]
except:
return
def get_persons_previous_trip(self):
try:
return PersonTrip.objects.filter(person_expedition__person=self.person_expedition.person, person_expedition__date__lt=self.date)[0]
except:
return
# def get_persons_previous_trip(self):
#
##########################################
# move following classes into models_cave
#
##########################################
class Area(TroggleModel):
short_name = models.CharField(max_length=100)

View File

@ -2,6 +2,20 @@ from django.db import models
from django.conf import settings
import os
###########################################################
# These will allow browsing and editing of the survex data
###########################################################
# Needs to add:
# SurvexFile
# Equates
# reloading
#
# Single SurvexBlock
#
class SurvexBlock(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
parent = models.ForeignKey('SurvexBlock', blank=True, null=True)
@ -31,10 +45,10 @@ class SurvexBlock(models.Model):
ordering = ('date', 'survexpath')
def __unicode__(self):
if self.name:
return unicode(self.name)
else:
return 'no name'
return self.name and unicode(self.name) or 'no name'
def filewithoutsvx(self):
return self.begin_file[:-4]
def filecontents(self):
f = os.path.join(settings.SURVEX_DATA, self.begin_file)
@ -50,20 +64,40 @@ class SurvexBlock(models.Model):
res[-1]['roles'] += ", " + str(personrole.role)
else:
res.append({'person':personrole.personexpedition.person, 'expeditionyear':personrole.personexpedition.expedition.year, 'roles':str(personrole.role)})
print res
return res
class PersonRole(models.Model):
personexpedition = models.ForeignKey('PersonExpedition')
person = models.ForeignKey('Person')
survex_block = models.ForeignKey('SurvexBlock')
role = models.ForeignKey('Role')
def __unicode__(self):
return unicode(self.person) + " - " + unicode(self.survex_block) + " - " + unicode(self.role)
#
# Replace this with a choice string in PersonRole
#
class Role(models.Model):
name = models.CharField(max_length=50)
def __unicode__(self):
return unicode(self.name)
#
# member of a SurvexBlock
#
class PersonRole(models.Model):
survex_block = models.ForeignKey('SurvexBlock')
role = models.ForeignKey('Role') # to go
ROLE_CHOICES = (
('insts','Instruments'),
('dog','Other'),
('notes','Notes'),
('pics','Pictures'),
('tape','Tape measure'),
)
nrole = models.CharField(choices=ROLE_CHOICES, max_length=200, blank=True, null=True)
# increasing levels of precision
person = models.ForeignKey('Person')
personexpedition = models.ForeignKey('PersonExpedition')
persontrip = models.ForeignKey('PersonTrip', blank=True, null=True)
def __unicode__(self):
return unicode(self.person) + " - " + unicode(self.survex_block) + " - " + unicode(self.role)

View File

@ -22,6 +22,7 @@ def getNotablePersons():
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
@ -38,6 +39,7 @@ def personindex(request):
return render_response(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, })
def expedition(request, expeditionname):
year = int(expeditionname)
expedition = Expedition.objects.get(year=year)
@ -53,6 +55,7 @@ def expedition(request, expeditionname):
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)
@ -65,11 +68,45 @@ def person(request, first_name='', last_name='', ):
return render_response(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.personrole_set.all():
a = res.setdefault(personrole.survex_block.date, { })
b = a.setdefault("personroles", { })
survexpath = personrole.survex_block.survexpath
if b.get(survexpath):
b[survexpath] += ", " + str(personrole.role)
else:
b[survexpath] = str(personrole.role)
# build up the tables
rdates = res.keys()
rdates.sort()
res2 = [ ]
for rdate in rdates:
persontrips = res[rdate].get("persontrips", [])
personroles = list(res[rdate].get("personroles", {}).items())
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)
return render_response(request,'personexpedition.html', {'personexpedition': personexpedition, })
personchronology = GetPersonChronology(personexpedition)
return render_response(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})
def logbookentry(request, date, slug):
logbookentry = LogbookEntry.objects.filter(date=date, slug=slug)
@ -80,6 +117,7 @@ def logbookentry(request, date, slug):
logbookentry=logbookentry[0]
return render_response(request, 'logbookentry.html', {'logbookentry': logbookentry})
def logbookSearch(request, extra):
query_string = ''
found_entries = None
@ -96,3 +134,4 @@ def personForm(request,pk):
person=Person.objects.get(pk=pk)
form=PersonForm(instance=person)
return render_response(request,'personform.html', {'form':form,})

View File

@ -45,13 +45,23 @@ def todo(request):
totallogbookentries = LogbookEntry.objects.count()
return render_with_context(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message})
def calendar(request,year):
def calendar(request, year):
week=['S','S','M','T','W','T','F']
if year:
expedition=Expedition.objects.get(year=year)
PersonExpeditions=expedition.personexpedition_set.all()
expedition = Expedition.objects.get(year=year)
personexpeditions = expedition.personexpedition_set.all()
return render_with_context(request,'calendar.html', locals())
listdays = [ ] # the columns of the table
date = expedition.date_from
while date <= expedition.date_to:
listdays.append(date)
date += datetime.timedelta(days=1)
personexpeditiondays = [ ]
for personexpedition in personexpeditions:
pelistdays = [ (personexpedition.date_from and (personexpedition.date_from <= date < personexpedition.date_to)) for date in listdays ]
personexpeditiondays.append([personexpedition, pelistdays])
return render_with_context(request,'calendar.html', {"expedition":expedition, "listdays":listdays, "personexpeditiondays":personexpeditiondays})
def controlPanel(request):
jobs_completed=[]

View File

@ -124,7 +124,8 @@ def svx(request, survex_file):
if message:
difflist.insert(0, message)
svxincludes = re.findall('\*include\s+"?(.*?)(?:\.svx)?"?\s*?\n(?i)', form.data['code'])
print [ form.data['code'] ]
svxincludes = re.findall('\*include\s+"?(.*?)(?:\.svx)?"?\s*?\n(?i)', form.data['code'] or "")
vmap = {'settings': settings,
'has_3d': os.path.isfile(settings.SURVEX_DATA + survex_file + ".3d"),
@ -141,6 +142,16 @@ def Dsvx(request, survex_file):
svx = open(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:
@ -160,8 +171,61 @@ def err(request, survex_file):
err = open(settings.SURVEX_DATA + survex_file + ".err", "rb")
return HttpResponse(err, mimetype="text")
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 identifycavedircontents(gcavedir):
name = os.path.split(gcavedir)[1]
subdirs = [ ]
subsvx = [ ]
primesvx = None
for f in os.listdir(gcavedir):
if os.path.isdir(os.path.join(gcavedir, f)):
if f[0] != ".":
subdirs.append(f)
elif f[-4:] == ".svx":
nf = f[:-4]
if nf == name:
assert not primesvx
primesvx = nf
else:
subsvx.append(nf)
else:
assert re.match(".*?(?:.3d|.log|.err|.txt|.espec|~)$", f), (gcavedir, f)
subsvx.sort()
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 = [ ]
# first sort the file list
fnumlist = [ (int(re.match("\d*", f).group(0) or "99999"), 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:
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))
if len(survdirobj) == 1:
onefilecaves.append(survdirobj[0])
else:
multifilecaves.append((survdirobj[0], survdirobj[1:]))
return render_to_response('svxfilecavelist.html', {'settings': settings, "onefilecaves":onefilecaves, "multifilecaves":multifilecaves})

View File

@ -4,7 +4,7 @@ ul.dropdown a { text-decoration: none; }
/*
LEVEL ONE
*/
ul.dropdown li { font-weight: bold; float:left; zoom: 1; background: none; padding:0px; margin:0px;}
ul.dropdown li { font-weight: bold; float:left; zoom: 1; Dbackground: none; padding:0px; margin:0px;}
ul.dropdown a:hover { color: black; }
ul.dropdown a:active { color: black; }
ul.dropdown li a { display: block; padding: 4px 8px; border-right: 1px solid #333;

View File

@ -181,11 +181,17 @@ table#cavepage th#status { text-align: right; width: 25%; }
}
table {
border: thin solid silver;
border: thin solid black;
border-collapse: collapse;
}
td {
padding:0px;
border: thin solid black;
}
th
{
color:white;
background-color:black;
border: thin solid silver;
}
@ -258,8 +264,8 @@ div#editLinks a{
div#content {
margin-top: 50px;
margin-left: 120px;
margin-right: 120px;
Zmargin-left: 120px;
Zmargin-right: 120px;
padding-top: 10px;
padding-left: 5em;
padding-right: 5em;
@ -269,14 +275,14 @@ div#content {
.footer {
position:fixed;
Dposition:fixed;
width:100%;
bottom:0;
left:0;
}
body {
background-color:#000;
Zbackground-color:#000;
padding-bottom:100px;
}
@ -309,7 +315,7 @@ h1 {
}
#footerLinks{
position:fixed;
Dposition:fixed;
bottom:0px;
padding: 0px;
margin-left: 130px;
@ -398,7 +404,7 @@ div#related h2
div#related
{
width:200px;
Zwidth:200px;
float:right;
border: thin solid black;
background:#EEEEEE;
@ -407,7 +413,7 @@ div#related
div#related table
{
border-collapse:separate
Zborder-collapse:separate;
}
.addlink {

View File

@ -88,7 +88,8 @@ def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_
for tripperson, time_underground in trippersons:
lookupAttribs={'person_expedition':tripperson, 'logbook_entry':lbo}
nonLookupAttribs={'time_underground':time_underground,'is_logbook_entry_author':(tripperson == author)}
nonLookupAttribs={'time_underground':time_underground, 'date':date, 'is_logbook_entry_author':(tripperson == author)}
print nonLookupAttribs
save_carefully(models.PersonTrip, lookupAttribs, nonLookupAttribs)
@ -100,7 +101,7 @@ def ParseDate(tripdate, year):
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]
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:
@ -239,7 +240,7 @@ def Parseloghtml03(year, expedition, txt):
yearlinks = [
("2008", "2008/2008logbook.txt", Parselogwikitxt),
#("2007", "2007/2007logbook.txt", Parselogwikitxt),
("2007", "2007/2007logbook.txt", Parselogwikitxt),
("2006", "2006/logbook/logbook_06.txt", Parselogwikitxt),
("2005", "2005/logbook.html", Parseloghtmltxt),
("2004", "2004/logbook.html", Parseloghtmltxt),
@ -268,16 +269,16 @@ def SetDatesFromLogbookEntries(expedition):
personexpedition.date_to = max([persontrip.logbook_entry.date for persontrip in persontrips] or [None])
personexpedition.save()
# The below is all unnecessary, just use the built in get_previous_by_date and get_next_by_date
# 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()
# 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()
# from trips rather than logbook entries, which may include events outside the expedition
expedition.date_from = min([personexpedition.date_from for personexpedition in expedition.personexpedition_set.all() if personexpedition.date_from] or [None])
@ -344,7 +345,7 @@ def LoadLogbooks():
for year, lloc, parsefunc in yearlinks:
expedition = models.Expedition.objects.filter(year = year)[0]
fin = open(os.path.join(expowebbase, lloc))
txt = fin.read()
txt = fin.read().decode("latin1")
fin.close()
parsefunc(year, expedition, txt)
SetDatesFromLogbookEntries(expedition)

View File

@ -68,7 +68,10 @@ def make_model(name, parent, iter_lines, sf, c, l):
def saveEnd(survex_file, count):
if m.start_year and team:
try:
exp = models.Expedition.objects.get(year = str(m.start_year))
explist = models.Expedition.objects.filter(year = str(m.start_year))
if not explist:
return # help hack
exp = explist[0]
for file_, (role, names) in team:
if names.strip("\t").strip(" ") == "both" or names.strip("\t").strip(" ") == "Both":
names = reduce(lambda x, y: x + u" & " + y,

17
urls.py
View File

@ -30,7 +30,6 @@ urlpatterns = patterns('',
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'^survexblock/(.+)$', views_caves.survexblock, name="survexblock"),
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/?$', object_list, {'queryset':CaveDescription.objects.all(),'template_name':'object_list.html'}, name="cavedescriptions"),
@ -46,12 +45,6 @@ urlpatterns = patterns('',
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'^survex/(.*?)\.index$', views_survex.index, name="survexindex"),
url(r'^survex/(?P<survex_file>.*?)\.svx$', svx, name="svx"),
(r'^survex/(?P<survex_file>.*)\.3d$', threed),
(r'^survex/(?P<survex_file>.*)\.log$', log),
(r'^survex/(?P<survex_file>.*)\.err$', err),
url(r'^logbooksearch/(.*)/?$', views_logbooks.logbookSearch),
@ -84,10 +77,20 @@ urlpatterns = patterns('',
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.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/caves$', views_survex.survexcaveslist,name="survexcaveslist"),
(r'^survex/(?P<survex_file>.*)\.log$', log),
(r'^survex/(?P<survex_file>.*)\.err$', err),
(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}),

View File

@ -99,7 +99,7 @@ def href_to_wikilinks(matchobj):
object actually exists.
"""
res=CaveDescription.objects.filter(long_name__icontains=matchobj.groupdict()['text'])
if res[0]:
if res and res[0]:
return r'[[cavedescription:'+res[0].short_name+'|'+res[0].long_name+']]'
else:
return matchobj.group()