mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-16 10:37:12 +00:00
246 lines
12 KiB
Python
246 lines
12 KiB
Python
import re
|
|
from pathlib import Path
|
|
|
|
import django.forms as forms
|
|
from django.http import HttpResponseRedirect
|
|
|
|
from django.shortcuts import redirect, render
|
|
|
|
import troggle.settings as settings
|
|
#from troggle.core.models.caves import Entrance, Cave
|
|
from troggle.core.utils import (
|
|
COOKIE_MAX_AGE,
|
|
WriteAndCommitError,
|
|
current_expo,
|
|
get_cookie,
|
|
git_string,
|
|
write_and_commit,
|
|
)
|
|
from troggle.core.views.caves import get_cave_from_slug
|
|
|
|
"""Forms to handle renaming files and editing contents when a cave
|
|
is 'katastered', ie.e moves from an informal number, such as
|
|
1623-2024-BL-10 to 1623-999
|
|
"""
|
|
|
|
def get_loser_dir(cave):
|
|
""" Copes with capitalisation mismatch between declared loser diretory and actual
|
|
"""
|
|
loser_name = f"{str(cave.unofficial_number)}"
|
|
parent = settings.SURVEX_DATA / f"caves-{str(cave.areacode)}"
|
|
|
|
for dn in [loser_name, loser_name.lower(), loser_name.upper()]:
|
|
if ( parent / dn).is_dir():
|
|
return parent / dn, Path(f"caves-{str(cave.areacode)}") / dn
|
|
return None, None
|
|
|
|
def get_cd(path):
|
|
return f"$BASE_DIR/{path.relative_to(settings.REPOS_ROOT_PATH)}"
|
|
|
|
def entrances_list(cave):
|
|
entrances = []
|
|
for e in cave.entrances(): # horrid CaveAndEntrance indirection we need to refactor out in due course
|
|
if e.entrance.best_station():
|
|
entrances.append(e.entrance)
|
|
return entrances
|
|
|
|
def entrances_stations(cave):
|
|
entrance_stations = []
|
|
for e in cave.entrances(): # horrid CaveAndEntrance indirection we need to refactor out in due course
|
|
if e.entrance.tag_station:
|
|
entrance_stations.append((e.entrance, e.entrance.tag_station[4:]))
|
|
if e.entrance.other_station:
|
|
entrance_stations.append((e.entrance, e.entrance.other_station[4:]))
|
|
return entrance_stations
|
|
|
|
def kataster(request, slug):
|
|
"""Create the page which analyses how to rename a cave and all the files from the unofficial_number
|
|
identifier, e.g. 1623-2023-mg-03 to the kataster number e.g. 1623-999
|
|
"""
|
|
|
|
def do_file_finding(knum):
|
|
|
|
global cavefilename, cave_data, entrance_data, loser_name, loser_data
|
|
|
|
mvscript = f"BASE_DIR={settings.REPOS_ROOT_PATH}\n\n"
|
|
|
|
ent_dir = settings.ENTRANCEDESCRIPTIONS # settings.EXPOWEB / "entrance_data"
|
|
mvscript += f"cd {get_cd(settings.ENTRANCEDESCRIPTIONS)}\n"
|
|
|
|
if cave.areacode == "1623":
|
|
pt_target = "$BASE_DIR/loser/fixedpts/gps/gps*.svx"
|
|
elif cave.areacode == "1626":
|
|
pt_target = "$BASE_DIR/loser/fixedpts/*.svx"
|
|
for ent, station in entrances_stations(cave):
|
|
new = station.replace(cave.unofficial_number,str(knum))
|
|
sed_cmd = f"s/{station}/{new}/g".replace(".","\.")
|
|
mvscript += f'sed -i {sed_cmd} {ent}.html\n'
|
|
mvscript += f'sed -i {sed_cmd} {pt_target}\n'
|
|
|
|
entrance_data = []
|
|
for ent in ent_dir.iterdir():
|
|
if str(ent.name).startswith(str(cave)):
|
|
print(ent.name)
|
|
entrance_data.append("entrance_data/"+ent.name)
|
|
# entrance_ids.append(ent.name.replace(".html",""))
|
|
mvscript += f"mv {ent.name} {ent.name.replace(str(cave.unofficial_number),str(knum))}\n"
|
|
|
|
mvscript += f"\ncd {get_cd(settings.CAVEDESCRIPTIONS)}\n"
|
|
cavefilename = str(cave) + ".html"
|
|
target= f"{cave.areacode}-{str(knum)}"
|
|
|
|
cave_data = Path( "cave_data", cavefilename )
|
|
if not (settings.CAVEDESCRIPTIONS / cavefilename).is_file: # settings.EXPOWEB / cave_data
|
|
cave_data = "does not exist"
|
|
|
|
mvscript += f'sed -i "/<kataster_number>/s/<kataster_number>/<kataster_number>{knum}/" {cavefilename}\n'
|
|
mvscript += f'sed -i "/<survex_file>/s/<survex_file>[^<]*/<survex_file>caves-{cave.areacode}\/{knum}\/{knum}.svx/" {cavefilename}\n'
|
|
mvscript += f'sed -i "/<entranceslug>/s/<entranceslug>{str(cave)}/<entranceslug>{cave.areacode}-{knum}/" {cavefilename}\n'
|
|
mvscript += f'sed -i "/href=\|src=/s/\/{cave.areacode}\/{cave.unofficial_number}\//\/{cave.areacode}\/{knum}\//g" {cavefilename}\n'
|
|
|
|
mvscript += f"mv {cavefilename} {target}.html\n\n"
|
|
|
|
mvscript += f"cd {get_cd(settings.EXPOWEB / cave.areacode / cave.unofficial_number)}\n"
|
|
|
|
|
|
loser_data = []
|
|
loser_dir, loser_name = get_loser_dir(cave)
|
|
if (loser_dir).is_dir():
|
|
print(loser_dir)
|
|
for svx in loser_dir.iterdir():
|
|
print(svx)
|
|
loser_data.append(Path(loser_dir , svx).name)
|
|
return mvscript
|
|
|
|
def script_loser(knum):
|
|
global cavefilename, cave_data, entrance_data, loser_name, loser_data
|
|
|
|
loser_dir, loser_name = get_loser_dir(cave) #/home/philip/expo/loser/caves-1623/2024-jc-01 , caves-1623/2024-jc-01
|
|
target = loser_name.parent / str(knum)
|
|
survex_name = str(loser_name.name)
|
|
l_script = f"\ncd {get_cd(settings.SURVEX_DATA)}\n"
|
|
l_script += f'sed -i "/^*include/s/{survex_name}/{knum}/g" {loser_name.parent}/caves.svx\n'
|
|
|
|
l_script += f'sed -i "/^*equate/s/{survex_name}/{knum}/g" {loser_name}/{survex_name}.svx\n'
|
|
l_script += f'sed -i "/^*entrance/s/{survex_name}/{knum}/g" {loser_name}/{survex_name}.svx\n'
|
|
l_script += f'sed -i "/^*begin/s/{survex_name}/{knum}/" {loser_name}/{survex_name}.svx\n'
|
|
l_script += f'sed -i "/^*end/s/{survex_name}/{knum}/" {loser_name}/{survex_name}.svx\n'
|
|
l_script +=f"# These 'sed' edits will not do everything in all cases, but they do the basics\n\n"
|
|
|
|
l_script +=f"mv {loser_name} {target}\n"
|
|
l_script +=f"cd {target}\n"
|
|
for filename in loser_data:
|
|
l_script +=f"mv {filename} {filename.replace(survex_name,str(knum))}\n"
|
|
l_script +=f"# But note that git ignores .log and .3d files\n\n"
|
|
|
|
|
|
|
|
# 1623 : fixedpts/gps/gps23.svx:26:*fix p2023-mg-03 reference 13.81514 47.69169 1767
|
|
# 1626: fixedpts/1626-no-schoenberg-hs-not-tied-to-caves.svx
|
|
return l_script
|
|
|
|
knum = 9999
|
|
|
|
|
|
if cave := get_cave_from_slug(slug.lower()):
|
|
pass
|
|
elif cave := get_cave_from_slug(slug.upper()):
|
|
pass
|
|
else:
|
|
return HttpResponseRedirect("/caves")
|
|
|
|
entrances = entrances_list(cave)
|
|
# for e in cave.entrances(): # horrid CaveAndEntrance indirection we need to refactor out in due course
|
|
# if e.entrance.best_station():
|
|
# entrances.append(e.entrance)
|
|
_ = do_file_finding(knum)
|
|
|
|
try:
|
|
# this is a python generator idiom.
|
|
# see https://realpython.com/introduction-to-python-generators/
|
|
|
|
# THIS IS VERY SILLY. We have this in the databse fom when this file was parsed. Don't read it again !
|
|
# However we will need to parse the href= and src= strings in the cave description text, notes etc.
|
|
with open(settings.CAVEDESCRIPTIONS / cavefilename, 'r') as f:
|
|
for line in f:
|
|
if match := re.search(r'<entranceslug>(.*?)</entranceslug>', line):
|
|
entrance = match.group(1)
|
|
print(entrance)
|
|
|
|
except PermissionError as e:
|
|
msg=f"CANNOT save this file.\nPERMISSIONS incorrectly set on server for this file {filepath}. Ask a nerd to fix this: {e}"
|
|
print(msg)
|
|
raise
|
|
except Exception as e:
|
|
msg=f"CANNOT write this file {filepath}. Ask a nerd to fix this: {e}"
|
|
print(msg)
|
|
|
|
# Restart script with POST data
|
|
script = "# Conversion script - VERY INCOMPLETE AS YET\n# When doing it by hand, it is less error-prone to do the file re-namings last,\n"
|
|
script += "# after the edits, but in a script it does not matter so much\n"
|
|
script += "# so long as everything is consistent and tested.\n"
|
|
script += "# Except that reversing changes using git does not always restore directories exactly\n# (because of .gitignore).\n\n"
|
|
script += "# Be careful with the BASE_DIR directory: usually NOT be the same on your PC as on the server\n\n"
|
|
|
|
warning =""
|
|
|
|
if request.method == "POST": # If the form has been submitted...
|
|
form = KatasterForm(request.POST) # A form bound to the POST data
|
|
if form.is_valid():
|
|
clean = form.cleaned_data
|
|
knum = clean['kataster_number']
|
|
print(f" # kataster_number {clean['kataster_number']}")
|
|
if test := get_cave_from_slug(f"{cave.areacode}-{knum}"):
|
|
warning = "<br /><br />DANGER DANGER You will overwrite an existing katastered cave !!!<br />"
|
|
warning += "resetting proposed new kataster number to 666.<br /><br />"
|
|
knum = 666
|
|
else: # GET and fall-through if POST is not valid
|
|
form = KatasterForm()
|
|
|
|
script += do_file_finding(knum)
|
|
script += script_loser(knum)
|
|
|
|
alias = f'(\\"{cave.slug()}\\", \\"{cave.areacode}-{knum}\\"),'
|
|
aliasfile = settings.CAVEDESCRIPTIONS / "cavealiases.txt"
|
|
script += f'\necho "{alias}" >> {get_cd(aliasfile)}\n\n'
|
|
|
|
script += f"# grep to see what we have missed, though should still be records of the old name in expoweb.\n"
|
|
script += f"# (and gps_essentials will need refreshing)\n"
|
|
script += f'grep -nirI --exclude-dir=.git --exclude-dir=gpx --exclude="*.gpx" --exclude="*.log" --exclude="*.kml" --exclude="*.pos" "{cave.unofficial_number}" $BASE_DIR/loser\n'
|
|
script += f'grep -nirI --exclude-dir=.git --exclude="*.gpx" "{cave.unofficial_number}" $BASE_DIR/expoweb\n'
|
|
|
|
script_rows = str(max(35,3+script.count('\n')))
|
|
return render(
|
|
request,
|
|
"cave_kataster.html",
|
|
{
|
|
"form": form, "warning": warning,
|
|
"cave": cave, "entrances": entrances,
|
|
"cave_data": cave_data, "entrance_data": entrance_data,
|
|
"loser_name": loser_name, "loser_data": loser_data,
|
|
"knum": knum, "script": script, "rows": script_rows,
|
|
}, )
|
|
|
|
class KatasterForm(forms.Form):
|
|
# areacode = forms.CharField(label='Full name', max_length=4, widget=forms.TextInput(attrs={'tabindex': 1, 'placeholder': '1623'}))
|
|
# official_name = forms.CharField(label='CUCC name', max_length=160,widget=forms.TextInput(attrs={'tabindex': 2, 'placeholder': '2012-ns-07'}))
|
|
kataster_number= forms.IntegerField(label="New kataster no.", widget=forms.TextInput(attrs={'tabindex': 1, 'size':1, 'placeholder': '9999'}))
|
|
|
|
"""
|
|
areacode = models.CharField(max_length=4, blank=True, null=True) # could use models.IntegerChoices
|
|
entrances = models.ManyToManyField("Entrance", through="CaveAndEntrance")
|
|
filename = models.CharField(max_length=200) # if a cave is 'pending' this is not set. Otherwise it is.
|
|
kataster_code = models.CharField(max_length=20, blank=True, null=True)
|
|
kataster_number = models.CharField(max_length=10, blank=True, null=True)
|
|
kataster_status = models.TextField(blank=True, null=True)
|
|
official_name = models.CharField(max_length=160)
|
|
survex_file = models.CharField(max_length=100, blank=True, null=True) # should be a foreign key?
|
|
unofficial_number = models.CharField(max_length=60, blank=True, null=True)
|
|
url = models.CharField(max_length=300, blank=True, null=True, unique = True)
|
|
|
|
SURVEX_DATA = REPOS_ROOT_PATH / "loser"
|
|
EXPOWEB = REPOS_ROOT_PATH / "expoweb"
|
|
CAVEDESCRIPTIONS = EXPOWEB / "cave_data"
|
|
ENTRANCEDESCRIPTIONS = EXPOWEB / "entrance_data"
|
|
|
|
""" |