survex_file field inconsistency detection & edit

This commit is contained in:
Philip Sargent
2021-04-02 23:21:23 +01:00
parent bd8d59b343
commit 52c1dabd0e
7 changed files with 120 additions and 47 deletions

View File

@@ -1,11 +1,12 @@
import os
import string
import subprocess
import re
import settings
import urllib.parse
import subprocess
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
from django import forms
from django.conf import settings
from django.urls import reverse
@@ -59,6 +60,23 @@ class MapLocations(object):
def __str__(self):
return "{} map locations".format(len(self.p))
def getCaves(cave_id):
'''Only gets called if a call to getCave() raises a MultipleObjects exception
TO DO: search GCavelookup first, which should raise a MultpleObjectsReturned exception if there
are duplicates'''
try:
caves = Cave.objects.filter(kataster_number=cave_id)
caveset = set(caves)
Gcavelookup = GetCaveLookup() # dictionary makes strings to Cave objects
if cave_id in Gcavelookup:
caveset.add(Gcavelookup[cave_id])
return list(caveset)
except:
return []
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.
@@ -110,7 +128,6 @@ def getnotablecaves():
notablecaves.append(c)
return notablecaves
def caveindex(request):
caves = Cave.objects.all()
caves1623 = list(Cave.objects.filter(area__short_name = "1623"))
@@ -120,23 +137,51 @@ def caveindex(request):
return render(request,'caveindex.html', {'caves1623': caves1623, 'caves1626': caves1626, 'notablecaves':getnotablecaves(), 'cavepage': True})
def cave3d(request, cave_id=''):
'''This is used to create a download url in templates/cave.html if anyone wants to download the .3d file
The caller template tries kataster first, then unofficial_number if that kataster number does not exist
but only if Cave.survex_file is non-empty
'''
try:
cave = getCave(cave_id)
except Cave.MultipleObjectsReturned: # entirely the wrong action, REPLACE with the right display
caves = Cave.objects.filter(kataster_number=cave_id)
return render(request, 'svxcaveseveral.html', {'settings': settings, "caves":caves })
cave = getCave(cave_id)
except ObjectDoesNotExist:
return None
except Cave.MultipleObjectsReturned:
# But only one might have survex data? So scan and return the first that works.
caves = getCaves(cave_id)
for c in caves:
if c.survex_file:
# exists, but may not be a valid file path to a valid .svx file in the Loser repo
return file3d(request, c, c.slug)
else:
return file3d(request, cave, cave_id)
def file3d(request, cave, cave_id):
'''Produces a .3d file directly for download.
survex_file should be in format 'caves-1623/264/264.svx' but it might be mis-entered as simply '2012-ns-10.svx'
Here we only use the stem of the last part anyway.
survexfilename = settings.SURVEX_DATA + cave.survex_file
threedfilename = settings.THREEDCACHEDIR + '%s.3d' % cave_id
if True or os.path.getmtime(survexfilename) > os.path.getmtime(threedfilename):
subprocess.call(["cavern", "--output=%s" % threedfilename, survexfilename])
test_file = open(threedfilename, 'rb')
response = HttpResponse(content=test_file, content_type='application/3d')#mimetype is replaced by content_type for django 1.7
response['Content-Disposition'] = 'attachment; filename=%s.3d' % cave_id
# response['X-Sendfile'] = "%s.3d" % cave_id
# It's usually a good idea to set the 'Content-Length' header too.
# You can also set any other required headers: Cache-Control, etc.
return response
TO DO properly decide whether we want to use the stem of the .svx file or the cave slug . This assumes they are the same...
'''
survexfilename = Path(settings.SURVEX_DATA, cave.survex_file)
threedfilename = Path(settings.THREEDCACHEDIR, cave_id +'.3d') # assumes cave_id is stem of survex_file. oops.
threedcachedir = Path(settings.THREEDCACHEDIR)
if not threedfilename.is_file() or os.path.getmtime(survexfilename) > os.path.getmtime(threedfilename):
try:
op = subprocess.check_output([settings.CAVERN, "--log", "--output={}".format(threedcachedir), "{}".format(survexfilename)])
except OSError as ex:
# propagate this to caller
raise OSError(op) from ex
if threedfilename.is_file():
response = HttpResponse(content=open(threedfilename, 'rb'), content_type='application/3d')
response['Content-Disposition'] = 'attachment; filename={}.3d'.format(cave_id)
# response['X-Sendfile'] = "%s.3d" % cave_id
# It's usually a good idea to set the 'Content-Length' header too.
# You can also set any other required headers: Cache-Control, etc.
return response
else:
return None
def cavepage(request, karea, subpath):
'''Displays a cave description page
@@ -217,6 +262,9 @@ def caveLogbook(request, slug):
@login_required_if_public
def edit_cave(request, slug=None):
'''This is the form that edits all the cave data and writes out an XML file in the :expoweb: repo folder
The format for the file being saved is in templates/dataformat/cave.xml
'''
if slug is not None:
cave = Cave.objects.get(caveslug__slug = slug)
else:
@@ -339,10 +387,6 @@ def surveyindex(request):
expeditions=Expedition.objects.order_by("-year")
return render(request,'survey.html',locals())
# def cave_description(request, cavedescription_name):
# cave_description = get_object_or_404(CaveDescription, short_name = cavedescription_name)
# return render(request,'cave_description.html', locals())
def get_entrances(request, caveslug):
cave = Cave.objects.get(caveslug__slug = caveslug)
return render(request,'options.html', {"items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]})