summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/admin.py4
-rw-r--r--core/models/caves.py44
-rw-r--r--core/views/caves.py8
-rw-r--r--core/views/prospect.py12
-rw-r--r--core/views/survex.py21
-rw-r--r--parsers/caves.py127
-rw-r--r--parsers/locations.py4
-rw-r--r--parsers/survex.py2
-rw-r--r--templates/cave.html10
-rw-r--r--templates/survexdir.html2
10 files changed, 75 insertions, 159 deletions
diff --git a/core/admin.py b/core/admin.py
index 43aa744..880d163 100644
--- a/core/admin.py
+++ b/core/admin.py
@@ -2,7 +2,7 @@ from django.contrib import admin
from django.core import serializers
from django.http import HttpResponse
-from troggle.core.models.caves import Area, Cave, CaveAndEntrance, Entrance
+from troggle.core.models.caves import Cave, CaveAndEntrance, Entrance
from troggle.core.models.logbooks import QM, LogbookEntry, PersonLogEntry, CaveSlug
from troggle.core.models.survex import (
DrawingFile,
@@ -135,7 +135,7 @@ class WalletAdmin(TroggleModelAdmin):
admin.site.register(Cave, CaveAdmin)
-admin.site.register(Area)
+#admin.site.register(Area)
admin.site.register(CaveAndEntrance)
admin.site.register(Entrance, EntranceAdmin)
admin.site.register(CaveSlug)
diff --git a/core/models/caves.py b/core/models/caves.py
index 3821387..0ede2b1 100644
--- a/core/models/caves.py
+++ b/core/models/caves.py
@@ -32,33 +32,15 @@ todo = """
- Can we rewrite things to eliminate the CaveSlug and objects? Surely
foreign keys work fine ?!
-- Why do we have CaveAndEntrance objects ? Surely entranceletter belong son the Entrance object?
+- Why do we have CaveAndEntrance objects ? Surely entranceletter belongs on the Entrance object?
- move the aliases list from the code and put into an editable file
- Restore constraint: unique_together = (("area", "kataster_number"), ("area", "unofficial_number"))
+ or replace by a unique 'slug' field, better.
"""
-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)
- super = models.ForeignKey("Area", blank=True, null=True, on_delete=models.SET_NULL)
-
- def __str__(self):
- if self.super:
- return str(self.super) + " - " + str(self.short_name)
- else:
- return str(self.short_name)
-
- def kat_area(self):
- if self.short_name in ["1623", "1626", "1624", "1627"]:
- return self.short_name
- elif self.super:
- return self.super.kat_area()
-
-
class CaveAndEntrance(models.Model):
"""This class is ONLY used to create a FormSet for editing the cave and all its
entrances in one form.
@@ -82,7 +64,8 @@ class CaveAndEntrance(models.Model):
class Cave(TroggleModel):
# too much here perhaps,
- area = models.ManyToManyField(Area, blank=False)
+ areacode = models.CharField(max_length=4, blank=True, null=True) # could use models.IntegerChoices
+ subarea = models.CharField(max_length=10, blank=True, null=True) # 9, 8c etc.
depth = models.CharField(max_length=100, blank=True, null=True)
description_file = models.CharField(max_length=200, blank=True, null=True)
entrances = models.ManyToManyField("Entrance", through="CaveAndEntrance")
@@ -97,7 +80,7 @@ class Cave(TroggleModel):
notes = models.TextField(blank=True, null=True)
official_name = models.CharField(max_length=160)
references = models.TextField(blank=True, null=True)
- survex_file = models.CharField(max_length=100, blank=True, null=True) # should be a foreign key
+ survex_file = models.CharField(max_length=100, blank=True, null=True) # should be a foreign key?
survey = models.TextField(blank=True, null=True)
underground_centre_line = models.TextField(blank=True, null=True)
underground_description = models.TextField(blank=True, null=True)
@@ -192,12 +175,7 @@ class Cave(TroggleModel):
return qms # a QuerySet
def kat_area(self):
- try:
- for a in self.area.all():
- if a.kat_area():
- return a.kat_area()
- except:
- return ""
+ return self.areacode
def entrances(self):
return CaveAndEntrance.objects.filter(cave=self)
@@ -258,15 +236,7 @@ class Cave(TroggleModel):
return (filepath, content, "utf8")
def getArea(self):
- areas = self.area.all()
- lowestareas = list(areas)
- for area in areas:
- if area.super in areas:
- try:
- lowestareas.remove(area.super)
- except:
- pass
- return lowestareas[0]
+ return self.areacode
class Entrance(TroggleModel):
MARKING_CHOICES = (
diff --git a/core/views/caves.py b/core/views/caves.py
index a002a0e..250ae0e 100644
--- a/core/views/caves.py
+++ b/core/views/caves.py
@@ -124,10 +124,10 @@ def getnotablecaves():
def caveindex(request):
- #Cave.objects.all()
- caves1623 = list(Cave.objects.filter(area__short_name="1623"))
- caves1626 = list(Cave.objects.filter(area__short_name="1626"))
- caves1627 = list(Cave.objects.filter(area__short_name="1627"))
+
+ caves1623 = list(Cave.objects.filter(areacode="1623"))
+ caves1626 = list(Cave.objects.filter(areacode="1626"))
+ caves1627 = list(Cave.objects.filter(areacode="1627"))
caves1623.sort(key=caveKey)
caves1626.sort(key=caveKey)
caves1627.sort(key=caveKey)
diff --git a/core/views/prospect.py b/core/views/prospect.py
index a538ab6..1eb82cd 100644
--- a/core/views/prospect.py
+++ b/core/views/prospect.py
@@ -4,7 +4,7 @@ from django.http import HttpResponse
from django.shortcuts import render
import troggle.settings as settings
-from troggle.core.models.caves import Area, Cave, Entrance
+from troggle.core.models.caves import Cave, Entrance
from troggle.core.views.caves import caveKey
# from pathlib import Path
@@ -68,11 +68,11 @@ def prospecting(request):
return render(request, "errors/disabled.html", {"message": message})
areas = []
- for key, name in AREANAMES:
- a = Area.objects.get(short_name=key) # assumes unique
- caves = list(a.cave_set.all())
- caves.sort(key=caveKey)
- areas.append((name, a, caves))
+ caves = Cave.objects.all()
+
+ for c in caves:
+ if c.subarea in AREANAMES:
+ areas.append((AREANAMES[c.subarea], subarea, c))
return render(request, "prospecting.html", {"areas": areas})
diff --git a/core/views/survex.py b/core/views/survex.py
index a69c5d3..b00aed0 100644
--- a/core/views/survex.py
+++ b/core/views/survex.py
@@ -574,15 +574,15 @@ def survexcaveslist(request):
subdircaves = []
fnumlist = []
- for area in ["1623", "1626", "1624", "1627"]:
- cavesdir = get_survexareapath(area)
- arealist = sorted([(area, -int(re.match(r"\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir)])
+ for areacode in ["1623", "1626", "1624", "1627"]:
+ cavesdir = get_survexareapath(areacode)
+ arealist = sorted([(areacode, -int(re.match(r"\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir)])
fnumlist += arealist
# print(fnumlist)
# go through the list and identify the contents of each cave directory
- for area, num, cavedir in fnumlist:
+ for areacode, num, cavedir in fnumlist:
# these have sub dirs /cucc/ /arge/ /old/ but that is no reason to hide them in this webpage
# so these are now treated the same as 142 and 113 which also have a /cucc/ sub dir
@@ -593,18 +593,17 @@ def survexcaveslist(request):
# which usually but not always true. e.g. caves-1623/78/allkaese.svx not caves-1623/78/78.svx
# which is why we now also pass through the cavedir
- # Still fails for loutitohoehle etc even though this is set correctly when the pending cave is created
- cavesdir = get_survexareapath(area)
+ cavesdir = get_survexareapath(areacode)
gcavedir = os.path.join(cavesdir, cavedir)
if os.path.isdir(gcavedir) and cavedir[0] != ".":
subdirs, subsvx = identifycavedircontents(gcavedir)
check_cave_registered(
- area, cavedir
+ areacode, cavedir
) # should do this only once per database load or it will be slow
survdirobj = []
for lsubsvx in subsvx:
- survdirobj.append(("caves-" + area + "/" + cavedir + "/" + lsubsvx, lsubsvx))
+ survdirobj.append(("caves-" + areacode + "/" + cavedir + "/" + lsubsvx, lsubsvx))
# caves with subdirectories
if subdirs:
@@ -614,7 +613,7 @@ def survexcaveslist(request):
# assert not dsubdirs # handle case of empty sub directory
lsurvdirobj = []
for lsubsvx in dsubsvx:
- lsurvdirobj.append(("caves-" + area + "/" + cavedir + "/" + subdir + "/" + lsubsvx, lsubsvx))
+ lsurvdirobj.append(("caves-" + areacode + "/" + cavedir + "/" + subdir + "/" + lsubsvx, lsubsvx))
if len(dsubsvx) >= 1:
subsurvdirs.append(
(subdir, lsurvdirobj[0], lsurvdirobj[0:])
@@ -683,7 +682,7 @@ def survexcavesingle(request, cave_shortname):
else:
return render(request, "errors/svxcaves404.html", {"settings": settings, "cave": cave_shortname})
-def check_cave_registered(area, survex_cave):
+def check_cave_registered(areacode, survex_cave):
"""Checks whether a cave has been properly registered when it is found in the Loser repo
This should really be called by databaseReset not here in a view
Currently Caves are only registered if they are listed in :expoweb: settings.CAVEDESCRIPTIONS
@@ -699,7 +698,7 @@ def check_cave_registered(area, survex_cave):
except MultipleObjectsReturned:
caves = Cave.objects.filter(kataster_number=survex_cave)
for c in caves:
- if str(c) == area + "-" + survex_cave:
+ if str(c) == areacode + "-" + survex_cave:
return str(c) # just get the first that matches
return None # many returned but none in correct area
diff --git a/parsers/caves.py b/parsers/caves.py
index 6850a1c..f70cdcd 100644
--- a/parsers/caves.py
+++ b/parsers/caves.py
@@ -8,7 +8,7 @@ from pathlib import Path
from django.conf import settings
from django.db import transaction
-from troggle.core.models.caves import Area, Cave, CaveAndEntrance, Entrance, GetCaveLookup
+from troggle.core.models.caves import Cave, CaveAndEntrance, Entrance, GetCaveLookup
from troggle.core.models.logbooks import CaveSlug
from troggle.core.models.troggle import DataIssue
from troggle.settings import CAVEDESCRIPTIONS, ENTRANCEDESCRIPTIONS, EXPOWEB, SURVEX_DATA
@@ -99,36 +99,6 @@ def set_dummy_entrance(id, slug, cave, msg="DUMMY"):
# DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.url}")
# print(message)
-def make_areas():
- print(" - Creating Areas 1623, 1624, 1627 and 1626")
- # This crashes on the server with MariaDB even though a null parent is explicitly allowed.
- area_1623 = Area.objects.create(short_name="1623", super=None)
- area_1623.save()
- area_1624 = Area.objects.create(short_name="1624", super=None)
- area_1624.save()
- area_1626 = Area.objects.create(short_name="1626", super=None)
- area_1626.save()
- area_1627 = Area.objects.create(short_name="1627", super=None)
- area_1627.save()
-
-def get_area(areanum):
- """Given the number as a string, return the area object
- """
- a = Area.objects.all()
- if len(a) == 0:
- make_areas()
-
- area = Area.objects.get(short_name="1623") # default
-
- if areanum == "1623":
- area = Area.objects.get(short_name="1623")
- if areanum == "1624":
- area = Area.objects.get(short_name="1624")
- if areanum == "1626":
- area = Area.objects.get(short_name="1626")
- if areanum == "1627":
- area = Area.objects.get(short_name="1627")
- return area
def create_new_cave(svxpath, msg=None):
"""This is called only when a new survex file is edited online which has a path on the
@@ -145,29 +115,29 @@ def create_new_cave(svxpath, msg=None):
print(f"parts {parts}, {a}, {caveid}")
# double check
if a[0:3] == "162":
- areanum = a[0:4]
- url = f"{areanum}/{caveid}.html" # Note we are appending the .html as we are believe in backwards compatability.
- #url = f"{areanum}/{a[5:]}.html" # This is original code, but a above is only defined as being 4 characters long, so it did not make sense and produced non unique urls
+ areacode = a[0:4]
+ url = f"{areacode}/{caveid}.html" # Note we are appending the .html as we are believe in backwards compatability.
+ #url = f"{areacode}/{a[5:]}.html" # This is original code, but a above is only defined as being 4 characters long, so it did not make sense and produced non unique urls
else:
print(f"WARNING: parsers/caves/create_new_cave called with svxpath '{svxpath}'. Surely it should start 'caves-162*'? {msg}")
- areanum = "1623"
+ areacode = "1623"
url = f"1623/{caveid}.html"
#url = f"1623/{k}.html" # This is original code, but a above is only defined as being 4 characters long, so it did not make sense and produced non unique urls
- k = f"{areanum}-{caveid}"
- area = get_area(areanum)
+ k = f"{areacode}-{caveid}"
- caves = Cave.objects.filter(unofficial_number=caveid, area =areanum)
+
+ caves = Cave.objects.filter(unofficial_number=caveid, areacode =areacode)
if caves:
- message = f" ! Already exists, caveid:{k} in area {areanum} {caves} - {msg}"
+ message = f" ! Already exists, caveid:{k} in areacode {areacode} {caves} - {msg}"
DataIssue.objects.create(parser="caves", message=message)
print(message)
return caves[0]
try:
- cave = do_pending_cave(k, caveid, url, area, msg)
+ cave = do_pending_cave(k, caveid, url, areacode, msg)
except:
- message = f" ! Error. Cannot create pending cave and entrance, pending-id:{k} in area {areanum} - {msg}"
+ message = f" ! Error. Cannot create pending cave and entrance, pending-id:{k} in area {areacode} - {msg}"
DataIssue.objects.create(parser="caves", message=message)
print(message)
raise
@@ -175,14 +145,15 @@ def create_new_cave(svxpath, msg=None):
# we know what the survex file is, we don't need to use the guess.
# But this sets the survex file on he cave from the first one we find, not necessarily the best survex file for this cave
cave.survex_file=survex_file
+ cave.areacode=areacode
cave.save()
return cave
-def do_ARGE_cave(slug, caveid, url, area, svxid):
+def do_ARGE_cave(slug, caveid, url, areacode, svxid):
"""Only called by survex parser.
Creates a new Cave object, but with abbreviated data as the survex file (from ARGE) is all we have.
We already know the survex file.
- We already know that it doesn't exist.
+ We already know that it doesn't exist... though there are bugs..
"""
default_note = "This is an ARGE cave where we only have the survex file and no other information"
@@ -203,35 +174,31 @@ def do_ARGE_cave(slug, caveid, url, area, svxid):
cave = Cave(
unofficial_number=caveid.upper(),
+ kataster_number=caveid.upper(), # should only set this if all digits
underground_description="ARGE cave.",
survex_file= f"{svxid}.svx",
url=url,
notes=default_note,
+ areacode=areacode,
)
if cave:
cave.save() # must save to have id before foreign keys work. This is also a ManyToMany key.
- # cave.area.add(area)
- # cave.save() # crashes entire transaction with foreign key error.
- # The 'caves' list page uses the area__short_name to select for the area, so these ARGE caves do not appear.
-
- # message = f" ! {slug:18} ARGE cave url: {url} "
- # DataIssue.objects.create(parser="caves", message=message, url=url)
- # print(message)
try: # Now create a cave slug ID
CaveSlug.objects.update_or_create(cave=cave, slug=slug, primary=False)
except:
- message = f" ! {slug:11s} ARGE CaveSLUG create failure {caveid=} {url=} {area=} {svxid=}"
+ message = f" ! {slug:11s} ARGE CaveSLUG create failure {caveid=} {url=} {areacode=} {svxid=}"
DataIssue.objects.create(parser="caves", message=message)
print(message)
else:
- message = f" ! {slug:11s} ARGE cave create failure {caveid=} {url=} {area=} {svxid=}"
+ message = f" ! {slug:11s} ARGE cave create failure {caveid=} {url=} {areacode=} {svxid=}"
DataIssue.objects.create(parser="caves", message=message)
print(message)
+ return None
return cave
-def do_pending_cave(slug, caveid, url, area, msg=None):
+def do_pending_cave(slug, caveid, url, areacode, msg=None):
"""
default for a PENDING cave, should be overwritten in the db later if a real cave of the same name exists
in expoweb/cave_data/1623-"k".html
@@ -250,16 +217,16 @@ def do_pending_cave(slug, caveid, url, area, msg=None):
else:
id = Path(k)
- survex_file = f"caves-{area.short_name}/{id}/{id}.svx"
+ survex_file = f"caves-{areacode}/{id}/{id}.svx"
if Path(settings.SURVEX_DATA, survex_file).is_file():
return survex_file
else:
- survex_file = f"caves-{area.short_name}/{id}.svx"
+ survex_file = f"caves-{areacode}/{id}.svx"
if Path(settings.SURVEX_DATA, survex_file).is_file():
return survex_file
survex_file = ""
- d = Path(settings.SURVEX_DATA, f"caves-{area.short_name}/{id}")
+ d = Path(settings.SURVEX_DATA, f"caves-{areacode}/{id}")
if d.is_dir():
prime_suspect = ""
dir = d.iterdir()
@@ -334,11 +301,10 @@ def do_pending_cave(slug, caveid, url, area, msg=None):
survex_file=survex_file,
url=url,
notes=default_note,
+ areacode=areacode,
)
if cave:
cave.save() # must save to have id before foreign keys work. This is also a ManyToMany key.
- cave.area.add(area)
- cave.save()
message = f" ! {slug:18} Pending cave write-up url: {url} - {msg}"
DataIssue.objects.create(parser="caves", message=message, url=url)
print(message)
@@ -555,7 +521,7 @@ def read_cave(filename, cave=None):
# print(f"! Entrance {eslug}")
if eslug.endswith('a b'):
message = f' - Entrance has weird name slug:"{eslug}" cave:"{cave}" caveslug:"{slug}" filename:"cave_data/{filename}"'
- DataIssue.objects.create(parser="xEntrances", message=message, url=f"{cave.area}/{cave.area}-{cave.url}_cave_edit/")
+ DataIssue.objects.create(parser="xEntrances", message=message, url=f"{cave.areacode}/{cave.areacode}-{cave.url}_cave_edit/")
# print(message)
letter = getXML(e, "letter", maxItems=1, context=context)[0]
@@ -566,7 +532,7 @@ def read_cave(filename, cave=None):
if letter.lower() not in list(string.ascii_lowercase):
letter = "x"
message = f"- Warning - Empty 'letter' field for '{eslug}' in multiple-entrance cave '{cave}', setting to {letter}."
- DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.area}/{cave.area}-{cave.url}_cave_edit/")
+ DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.areacode}/{cave.areacode}-{cave.url}_cave_edit/")
print(message)
if len(entrances) == 1 and not eslug: # may be empty: <entranceslug></entranceslug>
@@ -584,13 +550,13 @@ def read_cave(filename, cave=None):
entrances_xslug[eslug] = entrance
except:
message = f"! Fail entrance loading {eslug} /entrance_data/{eslug} file does not exist or loading it failed."
- DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.area}/{cave.area}-{cave.url}_cave_edit/")
+ DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.areacode}/{cave.areacode}-{cave.url}_cave_edit/")
print(message)
return
if eslug != f"{entrance}":
message = f"eslug {eslug} using different entrance {entrance} to set CaveAndEntrance"
- DataIssue.objects.create(parser="xEntrances", message=message, url=f"{cave.area}/{cave.area}-{cave.url}_cave_edit/")
+ DataIssue.objects.create(parser="xEntrances", message=message, url=f"{cave.areacode}/{cave.areacode}-{cave.url}_cave_edit/")
print(message)
try:
# this fails if there is not an unambiguous letter set.
@@ -728,27 +694,13 @@ def read_cave(filename, cave=None):
cave.description_file=description_file[0]
cave.url=url[0]
- areas = getXML(cavecontents, "area", context=context)
- cave.area.clear() # Deletes all links to areas in db
+ areas = getXML(cavecontents, "area", context=context) # can be multiple <area> tags
for area_slug in areas:
- if area_slug in areas_xslug:
- newArea = areas_xslug[area_slug]
+ if area_slug in ["1623", "1624", "1626", "1627"]: # ignore sub areas which are in another <area> tag
+ cave.areacode = area_slug
else:
- areas_new = Area.objects.filter(short_name=area_slug)
- if areas_new:
- newArea = areas_new[0] # just the first one we find, but we are going to clean up Areas anyway
- else:
- # Area not seen before. SHould not happen with manual edit
- if manual_edit:
- message = f" ! Cave edit failure due to unrecognised Area: {area_slug[0]}, skipping this field edit. "
- DataIssue.objects.create(parser="caves", message=message)
- print(message)
- # super value is highly dodgy
- newArea = Area(short_name=area_slug, super=Area.objects.get(short_name="1623"))
- newArea.save()
- areas_xslug[area_slug] = newArea
- cave.area.add(newArea)
-
+ cave.subarea = area_slug
+
entrances = getXML(cavecontents, "entrance", context=context)
do_entrances()
# print(f"- {entrances_xslug=}")
@@ -834,8 +786,6 @@ def readcaves():
#DataIssue.objects.filter(parser="xEntrances").delete()
with transaction.atomic():
- area = get_area("1623")
-
print(" - Reading Entrances from entrance descriptions xml files")
for filename in next(os.walk(ENTRANCEDESCRIPTIONS))[2]: # Should be a better way of getting a list of files
read_entrance(filename)
@@ -860,19 +810,18 @@ def readcaves():
for k in pending:
if k[0:3] == "162":
- areanum = k[0:4]
+ areacode = k[0:4]
number = k[5:]
- url = f"{areanum}/{k[5:]}.html" # Note we are appending the .htm to allow for offline websites
+ url = f"{areacode}/{k[5:]}.html" # Note we are appending the .htm to allow for offline websites
else:
- areanum = "1623"
+ areacode = "1623"
number = k
url = f"1623/{k}"
- area = get_area(areanum)
try:
- do_pending_cave(k, number, url, area)
+ do_pending_cave(k, number, url, areacode)
except:
- message = f" ! Error. Cannot create pending cave, pending-id:{k} in area {areanum}"
+ message = f" ! Error. Cannot create pending cave, pending-id:{k} in area {areacode}"
DataIssue.objects.create(parser="caves", message=message)
print(message)
raise
diff --git a/parsers/locations.py b/parsers/locations.py
index e2190c8..bf786ab 100644
--- a/parsers/locations.py
+++ b/parsers/locations.py
@@ -57,9 +57,9 @@ class MapLocations(object):
print(message)
continue # skip this entrance
try:
- areaName = k.getArea().short_name
+ areaName = k.areacode
except:
- message = f" ! Failed to get Area on cave '{k}' linked to Entrance:{ent.name} from:{ent.filename} best:{ent.best_station()}"
+ message = f" ! Failed to get areacode on cave '{k}' linked to Entrance:{ent.name} from:{ent.filename} best:{ent.best_station()}"
stash_data_issue(parser="positions", message=message)
print(message)
store_data_issues()
diff --git a/parsers/survex.py b/parsers/survex.py
index 88c1099..96b2e4a 100644
--- a/parsers/survex.py
+++ b/parsers/survex.py
@@ -2169,7 +2169,7 @@ def FindAndLoadSurvex():
# These exceptions WILL be parsed if the are *included by any file which is not excepted
unseensroot = re.sub(r"\.svx$", "", UNSEENS)
- excpts = ["surface/terrain", "kataster/kataster-boundaries", "gpx/gpx_publish/essentials", "template", "docs", "deprecated", "subsections", "1623-and-1626-no-schoenberg-hs", "1623-and-1624-and-1626-and-1627", "1623-and-1626",unseensroot]
+ excpts = ["surface/terrain", "kataster/kataster-boundaries", "gpx/gpx_publish/essentials", "template", "docs", "deprecated", "subsections", "1623-and-1626-no-schoenberg-hs", "1623-and-1624-and-1626-and-1627", "1623-and-1626", "dummy_file", unseensroot]
removals = set()
for x in unseens:
for o in excpts:
diff --git a/templates/cave.html b/templates/cave.html
index 32387f5..f018ef4 100644
--- a/templates/cave.html
+++ b/templates/cave.html
@@ -43,9 +43,7 @@
<table id="cavepage">
<tr>
<th id="kat_no"><!-- why is this not showing unofficial_number??-->
- {% if cave.area.all %}
- {{ cave.area.all.0.kat_area }} /
- {% endif %}
+ {{ cave.areacode}} /
{% if cave.kataster_number %}
{{ cave.kataster_number|safe }}
{% if cave.entrancelist %}
@@ -200,14 +198,14 @@
<a class="editlink" href="{% if local %}https://expo.survex.com{% endif %}{% url "newentrance" cave.url_parent cave.slug %}">New Entrance</a>
</div>
<h2>Survex File(s)</h2>
- All <a href="/survexfile/{{cave.kataster_number}}">survexfiles</a> for this cave <br />
+ All <a href="/survexfile/{{ cave.areacode }}-{{cave.kataster_number}}">survexfiles</a> for this cave <br />
{% if cave.survex_file %}
Primary <a href="/survexfile/{{cave.survex_file}}">survex file</a> for this cave
<br>
- Download .3d file <a href="{% url "cave3d" cave %}">caves-{{ cave.area.all.0.kat_area }}/{{cave.kataster_number}}/{{svx3d}}.3d</a>
+ Download .3d file <a href="{% url "cave3d" cave %}">caves-{{ cave.areacode }}/{{cave.kataster_number}}/{{svx3d}}.3d</a>
<br>
cave ID '{{cave.reference}}'<br>
-cave survex path '{{ cave.area.all.0.kat_area }}/{{cave.kataster_number}}'
+cave survex path '{{ cave.areacode }}/{{cave.kataster_number}}'
<div id='scene'></div>
{% endif %}
{% endblock content %}
diff --git a/templates/survexdir.html b/templates/survexdir.html
index 4b4fe11..e6854ef 100644
--- a/templates/survexdir.html
+++ b/templates/survexdir.html
@@ -12,7 +12,7 @@
<tr><th>Cave</th><th>Cave primary</th><th>f.primary</th><th>f.path</th></tr>
{% for f in survexfiles %}
<tr>
-<td><a href="/cave/{{f.cave}}">{{f.cave}}</a></td>
+<td><a href="/cave/{{f.cave}}">{{f.cave}}</a> {{f.cave.areacode}}{f.cave.subarea}}</td>
<td>{{f.cave.survex_file}}</td>
<td> {{f.primary}}.svx</td>
<td><span {% if f.pathbad %} style="color:red" {% endif %}><a href="/survexfile/{{f.path}}.svx">{{f.path}}.svx</a></span></td>