2020-05-28 01:16:45 +01:00
import os
import string
import re
import settings
import urllib . parse
2021-04-02 23:21:23 +01:00
import subprocess
from pathlib import Path
2012-01-07 19:05:25 +00:00
from django import forms
2020-05-28 01:16:45 +01:00
from django . conf import settings
2020-06-18 21:50:16 +01:00
from django . urls import reverse
2021-04-03 20:52:35 +01:00
from django . http import HttpResponse , HttpResponseRedirect , HttpResponseNotFound
2019-03-30 17:02:07 +00:00
from django . shortcuts import get_object_or_404 , render
2021-03-28 23:47:47 +01:00
from django . core . exceptions import ObjectDoesNotExist , MultipleObjectsReturned
2022-06-23 17:01:57 +01:00
from django . urls import NoReverseMatch
2013-08-01 16:00:01 +01:00
2020-05-28 01:16:45 +01:00
import troggle . settings as settings
2021-04-01 21:44:03 +01:00
from troggle . core . views import expo
2021-04-13 00:43:57 +01:00
from troggle . core . models . troggle import Expedition , DataIssue
2021-04-13 00:47:17 +01:00
from troggle . core . models . caves import CaveSlug , Cave , CaveAndEntrance , QM , EntranceSlug , Entrance , Area , SurvexStation , GetCaveLookup
2022-06-28 00:24:57 +01:00
from troggle . core . forms import CaveForm , CaveAndEntranceFormSet , EntranceForm , EntranceLetterForm
2021-05-03 20:35:35 +01:00
from . auth import login_required_if_public
2019-02-26 00:43:05 +00:00
2021-04-13 01:37:42 +01:00
''' Manages the complex procedures to assemble a cave description out of the compnoents
Manages the use of cavern to parse survex files to produce 3 d and pos files
'''
2022-02-26 23:20:59 +00:00
todo = ''' - Fix rendercave() so that CaveView works
- in getCaves ( ) search GCavelookup first , which should raise a MultpleObjectsReturned exception if no duplicates
2021-11-06 22:36:44 +00:00
'''
2021-04-02 23:21:23 +01:00
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 [ ]
2011-07-11 02:10:22 +01:00
def getCave ( cave_id ) :
2021-03-28 23:47:47 +01:00
''' Returns a cave object when given a cave name or number. It is used by views including cavehref, ent, and qm.
TO DO : search GCavelookup first , which should raise a MultpleObjectsReturned exception if there
are duplicates '''
2011-07-11 02:10:22 +01:00
try :
cave = Cave . objects . get ( kataster_number = cave_id )
2021-03-31 20:18:46 +01:00
return cave
2021-03-28 23:47:47 +01:00
except Cave . MultipleObjectsReturned as ex :
raise MultipleObjectsReturned ( " Duplicate kataster number " ) from ex # propagate this up
2021-03-31 20:18:46 +01:00
except Cave . DoesNotExist as ex :
2021-03-28 23:47:47 +01:00
Gcavelookup = GetCaveLookup ( ) # dictionary makes strings to Cave objects
if cave_id in Gcavelookup :
return Gcavelookup [ cave_id ]
2021-03-31 20:18:46 +01:00
else :
raise ObjectDoesNotExist ( " No cave found with this identifier in any id field " ) from ex # propagate this up
2021-03-28 23:47:47 +01:00
except :
raise ObjectDoesNotExist ( " No cave found with this identifier in any id field " )
2011-07-11 02:10:22 +01:00
2012-08-05 18:26:24 +01:00
def pad5 ( x ) :
return " 0 " * ( 5 - len ( x . group ( 0 ) ) ) + x . group ( 0 )
def padnumber ( x ) :
return re . sub ( " \ d+ " , pad5 , x )
def numericalcmp ( x , y ) :
return cmp ( padnumber ( x ) , padnumber ( y ) )
2021-04-16 16:01:35 +01:00
def caveKey ( c ) :
""" This function goes into a lexicogrpahic sort function, and the values are strings,
but we want to sort numberically on kataster number before sorting on unofficial number .
2020-05-25 01:46:52 +01:00
"""
2021-04-16 16:01:35 +01:00
if not c . kataster_number :
return " 9999. " + c . unofficial_number
else :
if int ( c . kataster_number ) > = 100 :
return " 99. " + c . kataster_number
if int ( c . kataster_number ) > = 10 :
return " 9. " + c . kataster_number
return c . kataster_number
2012-06-10 14:59:21 +01:00
2020-06-07 16:13:59 +01:00
def getnotablecaves ( ) :
notablecaves = [ ]
for kataster_number in settings . NOTABLECAVESHREFS :
try :
cave = Cave . objects . get ( kataster_number = kataster_number )
notablecaves . append ( cave )
except :
2021-04-03 20:52:35 +01:00
#print(" ! FAILED to get only one cave per kataster_number OR invalid number for: "+kataster_number)
2020-06-07 16:13:59 +01:00
caves = Cave . objects . all ( ) . filter ( kataster_number = kataster_number )
for c in caves :
2021-04-03 20:52:35 +01:00
#print(c.kataster_number, c.slug())
2020-06-07 16:13:59 +01:00
if c . slug ( ) != None :
notablecaves . append ( c )
return notablecaves
2011-07-11 02:10:22 +01:00
def caveindex ( request ) :
2019-06-26 20:57:24 +01:00
caves = Cave . objects . all ( )
2012-06-10 14:59:21 +01:00
caves1623 = list ( Cave . objects . filter ( area__short_name = " 1623 " ) )
caves1626 = list ( Cave . objects . filter ( area__short_name = " 1626 " ) )
2020-05-25 01:46:52 +01:00
caves1623 . sort ( key = caveKey )
caves1626 . sort ( key = caveKey )
2020-06-07 16:13:59 +01:00
return render ( request , ' caveindex.html ' , { ' caves1623 ' : caves1623 , ' caves1626 ' : caves1626 , ' notablecaves ' : getnotablecaves ( ) , ' cavepage ' : True } )
2011-07-11 02:10:22 +01:00
2018-04-20 20:55:12 +01:00
def cave3d ( request , cave_id = ' ' ) :
2021-04-02 23:21:23 +01:00
''' 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
2021-04-03 20:52:35 +01:00
But the template file cave . html has its own ideas about the name of the file and thus the href . Ouch .
/ cave / 3 d / < cave_id >
2021-04-02 23:21:23 +01:00
'''
2021-03-28 23:47:47 +01:00
try :
2021-04-02 23:21:23 +01:00
cave = getCave ( cave_id )
except ObjectDoesNotExist :
2021-04-14 16:28:30 +01:00
return HttpResponseNotFound
2021-04-02 23:21:23 +01:00
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.
2021-04-03 20:52:35 +01:00
survex_file should be in valid path format ' caves-1623/264/264.svx ' but it might be mis - entered as simply ' 2012-ns-10.svx '
Also the cave . survex_file may well not match the cave description path :
e . g . it might be to the whole system ' smk-system.svx ' instead of just for the specific cave .
2021-03-28 23:47:47 +01:00
2021-04-03 20:52:35 +01:00
- If the expected .3 d file corresponding to cave . survex_file is present , return it .
- If the cave . survex_file exists , generate the 3 d file , cache it and return it
- Use the cave_id to guess what the 3 d file might be and , if in the cache , return it
- Use the cave_id to guess what the . svx file might be and generate the .3 d file and return it
- ( Use the incomplete cave . survex_file and a guess at the missing directories to guess the real . svx file location ? )
2021-04-02 23:21:23 +01:00
'''
2021-04-03 20:52:35 +01:00
def runcavern ( survexpath ) :
#print(" - Regenerating cavern .log and .3d for '{}'".format(survexpath))
if not survexpath . is_file ( ) :
#print(" - - Regeneration ABORT\n - - from '{}'".format(survexpath))
2021-04-03 20:54:33 +01:00
pass
2021-04-02 23:21:23 +01:00
try :
2021-04-03 20:52:35 +01:00
completed_process = subprocess . run ( [ settings . CAVERN , " --log " , " --output= {} " . format ( settings . THREEDCACHEDIR ) , " {} " . format ( survexpath ) ] )
2021-04-02 23:21:23 +01:00
except OSError as ex :
2021-04-03 20:52:35 +01:00
# propagate this to caller.
raise OSError ( completed_process . stdout ) from ex
op3d = ( Path ( settings . THREEDCACHEDIR ) / Path ( survexpath ) . name ) . with_suffix ( ' .3d ' )
op3dlog = Path ( op3d . with_suffix ( ' .log ' ) )
if not op3d . is_file ( ) :
print ( " - - Regeneration FAILED \n - - from ' {} ' \n - - to ' {} ' " . format ( survexpath , op3d ) )
print ( " - - Regeneration stdout: " , completed_process . stdout )
print ( " - - Regeneration cavern log output: " , op3dlog . read_text ( ) )
def return3d ( threedpath ) :
if threedpath . is_file ( ) :
response = HttpResponse ( content = open ( threedpath , ' rb ' ) , content_type = ' application/3d ' )
response [ ' Content-Disposition ' ] = ' attachment; filename= {} ' . format ( threedpath . name )
return response
else :
message = ' <h1>Path provided does not correspond to any actual 3d file.</h1><p>path: " {} " ' . format ( threedpath )
#print(message)
return HttpResponseNotFound ( message )
2021-04-02 23:21:23 +01:00
2021-04-03 20:52:35 +01:00
survexname = Path ( cave . survex_file ) . name # removes directories
survexpath = Path ( settings . SURVEX_DATA , cave . survex_file )
threedname = Path ( survexname ) . with_suffix ( ' .3d ' ) # removes .svx, replaces with .3d
threedpath = Path ( settings . THREEDCACHEDIR , threedname )
threedcachedir = Path ( settings . THREEDCACHEDIR )
# These if statements need refactoring more cleanly
if cave . survex_file :
#print(" - cave.survex_file '{}'".format(cave.survex_file))
if threedpath . is_file ( ) :
#print(" - threedpath '{}'".format(threedpath))
# possible error here as several .svx files of same names in different directories will overwrite in /3d/
if survexpath . is_file ( ) :
if os . path . getmtime ( survexpath ) > os . path . getmtime ( threedpath ) :
runcavern ( survexpath )
return return3d ( threedpath )
else :
#print(" - - survexpath '{}'".format(survexpath))
if survexpath . is_file ( ) :
#print(" - - - survexpath '{}'".format(survexpath))
runcavern ( survexpath )
return return3d ( threedpath )
# Get here if cave.survex_file was set but did not correspond to a valid svx file
if survexpath . is_file ( ) :
# a file, but invalid format
message = ' <h1>File is not valid .svx format.</h1><p>Could not generate 3d file from " {} " ' . format ( survexpath )
2021-04-02 23:21:23 +01:00
else :
2021-04-03 20:52:35 +01:00
# we could try to guess that 'caves-1623/' is missing,... nah.
message = ' <h1>Path provided does not correspond to any actual file.</h1><p>path: " {} " ' . format ( survexpath )
return HttpResponseNotFound ( message )
def rendercave ( request , cave , slug , cave_id = ' ' ) :
''' Gets the data and files ready and then triggers Django to render the template.
The resulting html contains urls which are dispatched independently , e . g . the ' download ' link
'''
2022-03-18 20:00:15 +00:00
# print(" ! rendercave:'{}' START slug:'{}' cave_id:'{}'".format(cave, slug, cave_id))
2021-04-03 20:52:35 +01:00
2021-04-07 21:53:17 +01:00
if cave . non_public and settings . PUBLIC_SITE and not request . user . is_authenticated :
2021-04-03 20:52:35 +01:00
return render ( request , ' nonpublic.html ' , { ' instance ' : cave , ' cavepage ' : True , ' cave_id ' : cave_id } )
else :
2022-03-18 20:00:15 +00:00
# print(f" ! rendercave: slug:'{slug}' survex file:'{cave.survex_file}'")
try :
svx3d = Path ( cave . survex_file ) . stem
svxstem = Path ( settings . SURVEX_DATA ) / Path ( cave . survex_file )
# print(f" ! rendercave: slug:'{slug}' '' ++ '{svxstem}'")
except :
print ( f " ! rendercave: slug: ' { slug } ' FAIL TO MANAGE survex file: ' { cave . survex_file } ' " )
2021-04-03 20:52:35 +01:00
# NOTE the template itself loads the 3d file using javascript before it loads anything else.
# Django cannot see what this javascript is doing, so we need to ensure that the 3d file exists first.
2022-03-18 20:00:15 +00:00
# So only do this render if a valid .3d file exists. TO BE DONE -Not yet as CaveView is currently disabled
2021-11-06 20:59:10 +00:00
# see design docum in troggle/templates/cave.html
# see rendercave() in troggle/core/views/caves.py
2021-04-28 00:50:26 +01:00
templatefile = ' cave.html '
2022-07-11 21:12:53 +01:00
2021-04-25 04:04:53 +01:00
if not cave_id :
cave_id = slug # cave.unofficial_number
2022-07-11 21:12:53 +01:00
context = { ' cave_editable ' : True , ' settings ' : settings , ' cave ' : cave , ' cavepage ' : True ,
2022-03-18 20:00:15 +00:00
' cave_id ' : cave_id , ' svxstem ' : str ( svxstem ) , ' svx3d ' : svx3d }
2022-06-23 17:01:57 +01:00
try :
r = render ( request , templatefile , context ) # crashes here with NoReverseMatch if url not set up for 'edit_cave' in urls.py
2021-04-17 23:59:11 +01:00
return r
2022-06-23 17:01:57 +01:00
except NoReverseMatch :
raise
2021-04-17 23:59:11 +01:00
except :
2022-03-18 20:00:15 +00:00
message = f ' Failed to render cave: { slug } '
return render ( request , ' errors/generic.html ' , { ' message ' : message } )
2018-04-17 21:57:02 +01:00
2021-04-01 20:08:57 +01:00
def cavepage ( request , karea , subpath ) :
2021-04-01 21:44:03 +01:00
''' Displays a cave description page
2021-04-03 20:52:35 +01:00
accessed by kataster area number specifically
2022-03-18 20:00:15 +00:00
OR
accessed by cave . url specifically set in data , e . g .
" 1623/000/000.html " < = cave - data / 1623 - 000. html
" 1623/41/115.htm " < = cave - data / 1623 - 115. html
so we have to query the database to fine the URL as we cannot rely on the url actually telling us the cave by inspection .
2021-04-01 21:44:03 +01:00
There are A LOT OF URLS to e . g . / 1623 / 161 / l / rl89a . htm which are IMAGES and html files
in cave descriptions . These need to be handled HERE
'''
2022-03-18 20:00:15 +00:00
kpath = karea + subpath
# print(f" ! cavepage:'{kpath}' kataster area:'{karea}' rest of path:'{subpath}'")
2021-04-01 20:08:57 +01:00
try :
2022-06-23 17:18:21 +01:00
cave = Cave . objects . get ( url = kpath ) # ideally this will be unique
2021-04-01 20:08:57 +01:00
except Cave . DoesNotExist :
2021-04-01 21:44:03 +01:00
# probably a link to text or an image e.g. 1623/161/l/rl89a.htm i.e. an expoweb page
2022-03-22 02:22:15 +00:00
# cannot assume that this is a simple cave page, for a cave we don't know.
2022-06-23 17:18:21 +01:00
# print(f" ! cavepage: url={kpath} A cave of this name does not exist")
2022-06-18 22:41:00 +01:00
return expo . expopage ( request , kpath )
2021-04-01 20:08:57 +01:00
except Cave . MultipleObjectsReturned :
2022-03-18 20:00:15 +00:00
caves = Cave . objects . filter ( url = kpath )
2022-06-23 17:18:21 +01:00
# print(f" ! cavepage: url={kpath} multiple caves exist")
2021-04-17 23:59:11 +01:00
# we should have a -several variant for the cave pages, not just the svxcaves:
2021-04-01 20:08:57 +01:00
return render ( request , ' svxcaveseveral.html ' , { ' settings ' : settings , " caves " : caves } )
2022-06-23 17:18:21 +01:00
try :
r = rendercave ( request , cave , cave . slug ( ) )
return r
2022-06-23 17:01:57 +01:00
except NoReverseMatch :
raise
2021-04-01 20:08:57 +01:00
except :
2022-06-23 17:01:57 +01:00
message = f ' Failed to render cave: { kpath } (it does exist and is unique) because of a Django URL resolution error. Check urls.py. '
2021-05-13 19:46:29 +01:00
return render ( request , ' errors/generic.html ' , { ' message ' : message } )
2021-04-17 23:59:11 +01:00
2022-06-23 17:18:21 +01:00
# return rendercave(request, cave, cave.slug(), cave_id=cave_id)
2011-07-11 02:10:22 +01:00
def caveEntrance ( request , slug ) :
2021-12-05 21:23:06 +00:00
try :
cave = Cave . objects . get ( caveslug__slug = slug )
except :
return render ( request , ' errors/badslug.html ' , { ' badslug ' : slug } )
2021-04-07 21:53:17 +01:00
if cave . non_public and settings . PUBLIC_SITE and not request . user . is_authenticated :
2019-03-30 17:02:07 +00:00
return render ( request , ' nonpublic.html ' , { ' instance ' : cave } )
2011-07-11 02:10:22 +01:00
else :
2019-03-30 17:02:07 +00:00
return render ( request , ' cave_entrances.html ' , { ' cave ' : cave } )
2012-05-23 09:23:40 +01:00
2011-07-11 02:10:22 +01:00
@login_required_if_public
2012-01-07 19:05:25 +00:00
def edit_cave ( request , slug = None ) :
2021-04-02 23:21:23 +01:00
''' 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
2021-04-14 16:28:30 +01:00
It does save the data into into the database directly , not by parsing the file .
2022-03-22 02:22:15 +00:00
It does NOT yet commit to the git repo
2021-04-02 23:21:23 +01:00
'''
2021-04-14 16:28:30 +01:00
message = " "
2012-08-12 18:10:23 +01:00
if slug is not None :
2021-12-05 21:45:06 +00:00
try :
cave = Cave . objects . get ( caveslug__slug = slug )
except :
return render ( request , ' errors/badslug.html ' , { ' badslug ' : slug } )
2012-08-12 18:10:23 +01:00
else :
cave = Cave ( )
2012-05-23 09:23:40 +01:00
if request . POST :
form = CaveForm ( request . POST , instance = cave )
ceFormSet = CaveAndEntranceFormSet ( request . POST )
2021-04-26 02:10:45 +01:00
#versionControlForm = VersionControlCommentForm(request.POST)
2021-04-14 16:28:30 +01:00
if form . is_valid ( ) and ceFormSet . is_valid ( ) :
#print(f'! POST is valid. {cave}')
2012-08-12 18:10:23 +01:00
cave = form . save ( commit = False )
2012-08-14 21:51:15 +01:00
if slug is None :
for a in form . cleaned_data [ " area " ] :
if a . kat_area ( ) :
myArea = a . kat_area ( )
if form . cleaned_data [ " kataster_number " ] :
myslug = " %s - %s " % ( myArea , form . cleaned_data [ " kataster_number " ] )
else :
myslug = " %s - %s " % ( myArea , form . cleaned_data [ " unofficial_number " ] )
else :
myslug = slug
2021-04-25 04:04:53 +01:00
# Converting a PENDING cave to a real cave by saving this form
myslug = myslug . replace ( ' -PENDING- ' , ' - ' )
2012-08-14 21:51:15 +01:00
cave . filename = myslug + " .html "
2012-08-12 18:10:23 +01:00
cave . save ( )
form . save_m2m ( )
if slug is None :
2012-08-14 21:51:15 +01:00
cs = CaveSlug ( cave = cave , slug = myslug , primary = True )
2012-08-12 18:10:23 +01:00
cs . save ( )
2012-06-10 14:59:21 +01:00
ceinsts = ceFormSet . save ( commit = False )
for ceinst in ceinsts :
ceinst . cave = cave
2021-12-30 19:28:33 +00:00
ceinst . save ( )
2021-12-30 21:13:34 +00:00
try :
cave . writeDataFile ( )
# leave other exceptions unhandled so that they bubble up to user interface
except PermissionError :
message = f ' CANNOT save this file. \n PERMISSIONS incorrectly set on server for this file { cave . filename } . Ask a nerd to fix this. '
return render ( request , ' errors/generic.html ' , { ' message ' : message } )
except SubprocessError :
message = f ' CANNOT git on server for this file { cave . filename } . Edits may not be committed. \n Ask a nerd to fix this. '
return render ( request , ' errors/generic.html ' , { ' message ' : message } )
2021-12-30 19:28:33 +00:00
2021-04-14 16:28:30 +01:00
return HttpResponseRedirect ( " / " + cave . url )
else :
message = f ' ! POST data is INVALID { cave } '
print ( message )
2012-05-23 09:23:40 +01:00
else :
form = CaveForm ( instance = cave )
2012-06-10 14:59:21 +01:00
ceFormSet = CaveAndEntranceFormSet ( queryset = cave . caveandentrance_set . all ( ) )
2021-04-14 16:28:30 +01:00
#versionControlForm = VersionControlCommentForm()
2012-06-10 14:59:21 +01:00
2019-03-30 17:02:07 +00:00
return render ( request ,
2021-04-30 21:32:53 +01:00
' editcave.html ' ,
2021-04-14 16:28:30 +01:00
{ ' form ' : form , ' cave ' : cave , ' message ' : message ,
2012-06-10 14:59:21 +01:00
' caveAndEntranceFormSet ' : ceFormSet ,
2021-04-14 16:28:30 +01:00
#'versionControlForm': versionControlForm
2012-06-10 14:59:21 +01:00
} )
@login_required_if_public
2021-04-17 01:41:06 +01:00
def edit_entrance ( request , caveslug = None , slug = None ) :
2021-04-14 16:28:30 +01:00
''' This is the form that edits the entrance data for a single entrance and writes out
an XML file in the : expoweb : repo folder
The format for the file being saved is in templates / dataformat / entrance . xml
It does save the data into into the database directly , not by parsing the file .
'''
message = " "
2021-04-17 01:41:06 +01:00
if caveslug is not None :
2021-12-05 21:45:06 +00:00
try :
cave = Cave . objects . get ( caveslug__slug = caveslug )
except :
return render ( request , ' errors/badslug.html ' , { ' badslug ' : caveslug } )
2021-04-17 01:41:06 +01:00
else :
cave = Cave ( )
2012-08-12 18:10:23 +01:00
if slug is not None :
entrance = Entrance . objects . get ( entranceslug__slug = slug )
else :
entrance = Entrance ( )
2012-06-10 14:59:21 +01:00
if request . POST :
form = EntranceForm ( request . POST , instance = entrance )
2021-04-14 16:28:30 +01:00
#versionControlForm = VersionControlCommentForm(request.POST)
2012-08-14 21:51:15 +01:00
if slug is None :
entletter = EntranceLetterForm ( request . POST )
else :
entletter = None
2021-04-14 16:28:30 +01:00
if form . is_valid ( ) and ( slug is not None or entletter . is_valid ( ) ) :
2012-08-12 18:10:23 +01:00
entrance = form . save ( commit = False )
if slug is None :
2021-04-25 04:04:53 +01:00
if entletter . cleaned_data [ " entrance_letter " ] :
slugname = cave . slug ( ) + entletter . cleaned_data [ " entrance_letter " ]
else :
slugname = cave . slug ( )
2012-08-14 21:51:15 +01:00
entrance . cached_primary_slug = slugname
entrance . filename = slugname + " .html "
2012-08-12 18:10:23 +01:00
entrance . save ( )
if slug is None :
2012-08-14 21:51:15 +01:00
es = EntranceSlug ( entrance = entrance , slug = slugname , primary = True )
es . save ( )
el = entletter . save ( commit = False )
el . cave = cave
el . entrance = entrance
el . save ( )
2021-12-30 19:28:33 +00:00
try :
entrance . writeDataFile ( )
2021-12-30 21:13:34 +00:00
# leave other exceptions unhandled so that they bubble up to user interface
2021-12-30 19:28:33 +00:00
except PermissionError :
message = f ' CANNOT save this file. \n PERMISSIONS incorrectly set on server for this file { entrance . filename } . Ask a nerd to fix this. '
return render ( request , ' errors/generic.html ' , { ' message ' : message } )
2021-12-30 21:13:34 +00:00
except SubprocessError :
message = f ' CANNOT git on server for this file { entrance . filename } . Edits may not be committed. \n Ask a nerd to fix this. '
2021-12-30 19:28:33 +00:00
return render ( request , ' errors/generic.html ' , { ' message ' : message } )
2012-08-14 21:51:15 +01:00
return HttpResponseRedirect ( " / " + cave . url )
2021-04-14 16:28:30 +01:00
else :
message = f ' ! POST data is INVALID { cave } '
print ( message )
2012-06-10 14:59:21 +01:00
else :
form = EntranceForm ( instance = entrance )
2021-04-14 16:28:30 +01:00
#versionControlForm = VersionControlCommentForm()
2012-08-14 21:51:15 +01:00
if slug is None :
entletter = EntranceLetterForm ( request . POST )
else :
entletter = None
2019-03-30 17:02:07 +00:00
return render ( request ,
2012-06-10 14:59:21 +01:00
' editentrance.html ' ,
2021-04-14 16:28:30 +01:00
{ ' form ' : form , ' cave ' : cave , ' message ' : message ,
#'versionControlForm': versionControlForm,
2012-08-14 21:51:15 +01:00
' entletter ' : entletter
2012-01-07 19:05:25 +00:00
} )
2011-07-11 02:10:22 +01:00
def ent ( request , cave_id , ent_letter ) :
cave = Cave . objects . filter ( kataster_number = cave_id ) [ 0 ]
cave_and_ent = CaveAndEntrance . objects . filter ( cave = cave ) . filter ( entrance_letter = ent_letter ) [ 0 ]
2019-03-30 17:02:07 +00:00
return render ( request , ' entrance.html ' , { ' cave ' : cave ,
2011-07-11 02:10:22 +01:00
' entrance ' : cave_and_ent . entrance ,
' letter ' : cave_and_ent . entrance_letter , } )
def entranceSlug ( request , slug ) :
2012-06-10 14:59:21 +01:00
entrance = Entrance . objects . get ( entranceslug__slug = slug )
2021-04-07 21:53:17 +01:00
if entrance . non_public and not request . user . is_authenticated :
2019-03-30 17:02:07 +00:00
return render ( request , ' nonpublic.html ' , { ' instance ' : entrance } )
2011-07-11 02:10:22 +01:00
else :
2019-03-30 17:02:07 +00:00
return render ( request , ' entranceslug.html ' , { ' entrance ' : entrance } )
2011-07-11 02:10:22 +01:00
def surveyindex ( request ) :
surveys = Survey . objects . all ( )
expeditions = Expedition . objects . order_by ( " -year " )
2019-03-30 17:02:07 +00:00
return render ( request , ' survey.html ' , locals ( ) )
2011-07-11 02:10:22 +01:00
def get_entrances ( request , caveslug ) :
2021-12-05 21:45:06 +00:00
try :
cave = Cave . objects . get ( caveslug__slug = caveslug )
except :
return render ( request , ' errors/badslug.html ' , { ' badslug ' : caveslug } )
2019-03-30 17:02:07 +00:00
return render ( request , ' options.html ' , { " items " : [ ( e . entrance . slug ( ) , e . entrance . slug ( ) ) for e in cave . entrances ( ) ] } )
2011-07-11 02:10:22 +01:00
2022-03-18 20:00:15 +00:00
def caveQMs ( request , slug ) :
2022-07-05 18:24:51 +01:00
''' Lists all the QMs on a particular cave
2022-07-05 13:38:23 +01:00
relies on the template to find all the QMs for the cave specified in the slug , e . g . ' 1623-161 '
Now working in July 2022
'''
2022-03-18 20:00:15 +00:00
try :
cave = Cave . objects . get ( caveslug__slug = slug )
except :
return render ( request , ' errors/badslug.html ' , { ' badslug ' : slug } )
if cave . non_public and settings . PUBLIC_SITE and not request . user . is_authenticated :
return render ( request , ' nonpublic.html ' , { ' instance ' : cave } )
else :
return render ( request , ' cave_qms.html ' , { ' cave ' : cave } )
2022-07-06 13:38:53 +01:00
def qm ( request , cave_id , qm_id , year , grade = None , blockname = None ) :
2022-07-05 18:24:51 +01:00
''' Reports on one specific QM
2022-07-06 13:38:53 +01:00
Fixed and working July 2022 , for both CSV imported QMs
2022-07-05 20:40:58 +01:00
needs refactoring though .
2022-07-06 15:35:08 +01:00
290 has several QMS with the same number , grade , year ( 2108 ) and first 8 chars of the survexblock . This crashes things .
2022-07-05 13:38:23 +01:00
'''
2022-03-18 20:00:15 +00:00
year = int ( year )
2022-07-06 13:38:53 +01:00
2022-07-06 15:35:08 +01:00
if blockname == ' ' :
2022-07-06 13:38:53 +01:00
# CSV import QMs, use old technique
try :
c = getCave ( cave_id )
manyqms = c . get_QMs ( )
2022-07-06 15:35:08 +01:00
qm = manyqms . get ( number = qm_id , expoyear = year )
2022-07-05 20:40:58 +01:00
return render ( request , ' qm.html ' , { ' qm ' : qm } )
2022-07-06 13:38:53 +01:00
except QM . DoesNotExist :
2022-07-06 15:35:08 +01:00
raise
2022-07-05 20:40:58 +01:00
return render ( request , ' errors/badslug.html ' , { ' badslug ' : f ' { cave_id =} { year =} { qm_id =} { blockname =} ' } )
2022-07-06 13:38:53 +01:00
else :
try :
qmslug = f ' { cave_id } - { year } - { blockname =} { qm_id } { grade } '
c = getCave ( cave_id )
manyqms = c . get_QMs ( )
2022-07-06 15:35:08 +01:00
qmqs = manyqms . filter ( expoyear = year , blockname = blockname , number = qm_id , grade = grade )
if len ( qmqs ) > 1 :
for q in qmqs :
print ( qmqs )
message = f ' Multiple QMs with the same cave, year, number, grade AND first 8 chars of the survexblock name. Fix this in the survex file(s). { cave_id =} { year =} { qm_id =} { blockname =} '
return render ( request , ' errors/generic.html ' , { ' message ' : message } )
2022-07-06 13:38:53 +01:00
else :
2022-07-06 15:35:08 +01:00
qm = qmqs . get ( expoyear = year , blockname = blockname , number = qm_id , grade = grade )
if qm :
print ( qm , f ' { qmslug =} : { cave_id =} { year =} { qm_id =} { blockname =} { qm . expoyear =} ' )
return render ( request , ' qm.html ' , { ' qm ' : qm } )
else :
raise
return render ( request , ' errors/badslug.html ' , { ' badslug ' : f ' { cave_id =} { year =} { qm_id =} { blockname =} ' } )
2022-07-06 13:38:53 +01:00
except MultipleObjectsReturned :
2022-07-06 15:35:08 +01:00
raise
2022-07-06 13:38:53 +01:00
except QM . DoesNotExist :
2022-07-06 15:35:08 +01:00
raise
return render ( request , ' errors/badslug.html ' , { ' badslug ' : f ' { cave_id =} { year =} { qm_id =} { blockname =} ' } )
2022-07-06 13:38:53 +01:00
2022-07-05 20:40:58 +01:00
2022-07-08 20:20:29 +01:00
# def get_qms(request, caveslug):
# '''Does not crash, but just returns a text list of the entrances for a cave.
# Used internally by the JSON export code? Archeology required..
# cf get_entrances() above
# '''
# try:
# cave = Cave.objects.get(caveslug__slug = caveslug)
# except:
# return render(request,'errors/badslug.html', {'badslug': caveslug})
# return render(request,'options.html', {"items": [(q.slug(), q.slug()) for q in cave.QMs()]})