2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2025-12-18 19:07:10 +00:00

refactored and extended gpxfix()

This commit is contained in:
2025-10-27 19:41:32 +02:00
parent 78699b934d
commit c08d06d81f
2 changed files with 120 additions and 101 deletions

View File

@@ -88,6 +88,7 @@ class GPXfixForm(forms.Form): # not a model-form, just a form-form
prospector = forms.CharField(strip=True)
areacode = forms.CharField(strip=True)
station = forms.CharField(strip=True)
uploadfiles = forms.FileField()
class FilesRenameForm(forms.Form): # not a model-form, just a form-form
@@ -550,122 +551,136 @@ def analyse_gpx(saved_filename, content):
@login_required_if_public
def gpxfix(request):
"""Upload a GPX file containing a single track which is actually a single static point: for averaging
<!-- re do all this to autogenerate the form using Django magic stuff -->
"""Upload one or more GPX files containing a single track which is actually a single static point: for averaging
"""
def gpxvalid(name):
if Path(name).suffix.lower() in [".gpx"]:
return True # dangerous, we should check the actual file binary signature
return False
def _setup():
year = current_expo() # read this from the GPX file in future!
ctx = {
"year": year,
"yearpath": Path("gpsfix") / year,
"folder": "",
"dirpath": Path(settings.EXPOFILES) / "gpsfix" / year,
"urlfile": None,
"urldir": None,
"formd": GPXfixForm(),
"filesaved": False,
"actual_saved": [],
"location_data": [],
"areacode": "",
"fixstring": "*fix p2025-WW-01 13.8229370 47.6874630 1871",
"entrancestring": "*entrance p2025-WW-01"
}
ctx["urlfile"] = f"/expofiles/gpsfix/{ctx['year']}"
ctx["urldir"] = f"/gpxfix/{ctx['year']}"
return ctx
def _post(ctx):
formd = GPXfixForm(request.POST)
ctx["formd"] = formd
year = current_expo() # read this from the GPX file in future!
filesaved = False
actual_saved = []
context = {"year": year, "placeholder": "AnathemaDevice"}
yearpath = Path(settings.EXPOFILES) / "gpsfix" / year
folder = "" # improve this later
dirpath = yearpath
urlfile = f"/expofiles/gpsfix/{year}"
urldir = f"/gpxfix/{year}"
print(f"gpxfix() {folder=} {dirpath=} {urlfile=} {urldir=}")
if request.method == "POST":
formd = GPXuploadForm(request.POST)
print(f"gpxfix() method=POST")
for i in request.POST:
print(" ",i)
# Check there are files to upload
multiple = request.FILES.getlist("uploadfiles")
if not multiple:
# user supplied no files — attach a form error and return to show it
print(f"gpxfix(): no files to upload {multiple}")
formd.add_error("uploadfiles", "No files uploaded.") # does not seem to be visible on form?
ctx["formd"] = formd
return ctx
# ensure base year folder exists
try:
(yearpath).mkdir(parents=True, exist_ok=True)
except:
message = f'\n !! Permissions failure ?! 0 attempting to mkdir "{(yearpath)}"'
ctx["yearpath"].mkdir(parents=True, exist_ok=True)
except Exception as e:
message = f'\n !! Permissions failure ?! 0 attempting to mkdir "{ctx["yearpath"]}": {e}'
print(message)
raise
return render(request, "errors/generic.html", {"message": message})
# if a prospector field was submitted, validate it
if "prospector" in request.POST:
print(f"gpxfix() {request.POST=}\n {request.POST['prospector']=}")
if formd.is_valid():
newprospector = sanitize_name(request.POST["prospector"])
print(f"gpxfix() {newprospector=}")
else:
print(f"gpxfix() no prospector field")
print(f"gpxfix() {request.FILES=}")
for i in request.FILES:
print(" ",i)
print(f"gpxfix() prospector named: {newprospector}")
ctx["areacode"] = request.POST["areacode"].strip()
fs = FileSystemStorage(ctx["dirpath"])
ctx["actual_saved"] = []
ctx["location_data"] = []
for f in multiple:
if gpxvalid(f.name):
try:
saved_filename = fs.save(f.name, content=f)
except Exception as e:
print(f'\n !! Permissions failure ?! on attempting to save "{f.name}" in "{ctx["dirpath"]}": {e}')
# if save partially succeeded, guard against referencing undefined vars
continue
filepath = ctx["dirpath"] / saved_filename
if filepath.is_file():
ctx["actual_saved"].append(saved_filename)
ctx["filesaved"] = True
# analyse_gpx may use the uploaded content object
try:
ctx["location_data"].append(analyse_gpx(saved_filename, f))
except Exception as e:
print(f"gpxfix(): analyse_gpx failed for {saved_filename}: {e}")
else:
print(f"gpxfix(): not a GPX file {f.name=}")
ctx["fixstring"] = f"*fix {request.POST["station"]} 13.8229370 47.6874630 1871 # {request.POST["prospector"]}: {multiple[0]}"
ctx["entrancestring"] = f"*entrance {request.POST["station"]}"
return ctx
if not formd.is_valid():
print(f"gpxfix() Form is not valid {formd=}")
else:
print(f"gpxfix() about to look at request.FILES")
#f = request.FILES["uploadfiles"]
multiple = request.FILES.getlist("uploadfiles")
fs = FileSystemStorage(dirpath)
def _get(ctx):
files = []
dirs = []
try:
for f in ctx["dirpath"].iterdir():
if f.is_dir():
dirs.append(f.name)
if f.is_file():
files.append(f.name)
except FileNotFoundError:
files.append("(no folder yet - would be created)")
except Exception as e:
print(f"gpxfix() EXCEPTION\n {e}")
ctx["files"] = sorted(files) if files else []
ctx["dirs"] = sorted(dirs) if dirs else []
return ctx
# main flow
ctx = _setup()
actual_saved = []
location_data = []
if multiple:
for f in multiple:
if gpxvalid(f.name):
try: # crashes in Django os.chmod call if on WSL, but does save file!
saved_filename = fs.save(f.name, content=f)
except:
print(
f'\n !! Permissions failure ?! on attempting to save "{f.name}" in "{dirpath}" {renameto=}'
)
if "saved_filename" in locals():
if saved_filename.is_file():
actual_saved.append(saved_filename)
filesaved = True
location_data.append(analyse_gpx(saved_filename, f))
else:
print(f"gpxfix(): not a GPX file {f.name=}")
print(f"gpxfix() drop through")
files = []
dirs = []
formd = GPXfixForm()
print(f"gpxfix() {formd=} ")
try:
for f in dirpath.iterdir():
if f.is_dir():
dirs.append(f.name)
if f.is_file():
files.append(f.name)
except FileNotFoundError:
files.append("(no folder yet - would be created)")
except Exception as e:
print(f"gpxfix() EXCEPTION\n {e}")
if len(files) > 0:
files = sorted(files)
if request.method == "POST":
ctx = _post(ctx)
# if form invalid, still show GET-like view (ctx includes form with errors)
if isinstance(ctx, dict) and "formd" in ctx and not ctx["formd"].is_valid():
ctx = _get(ctx)
else:
ctx = _get(ctx)
if dirs:
dirs = sorted(dirs)
print(f"gpxfix() about to render..")
return render(
request,
"gpxfixform.html",
{
"form": formd,
**context,
"urlfile": urlfile,
"urldir": urldir,
"folder": folder,
"files": files,
"dirs": dirs,
"filesaved": filesaved,
"actual_saved": actual_saved,
"form": ctx.get("formd", GPXfixForm()),
"year": ctx["year"],
"urlfile": ctx["urlfile"],
"urldir": ctx["urldir"],
"yearpath": ctx["yearpath"],
"folder": ctx["folder"],
"files": ctx.get("files", []),
"dirs": ctx.get("dirs", []),
"filesaved": ctx.get("filesaved", False),
"actual_saved": ctx.get("actual_saved", []),
"areacode": ctx["areacode"],
"fixstring": ctx["fixstring"],
"entrancestring": ctx["entrancestring"],
},
)

View File

@@ -11,9 +11,9 @@
<div style = "max-width:35%; margin-left:20%; text-align: left" >
<form method ='post' enctype ="multipart/form-data">
{% csrf_token %}
{% csrf_token %}
<br>
<input class="fancybutton2" type = "file" multiple="multiple"
<input class="fancybutton2" type = "file" multiple="multiple" required
name = "uploadfiles" id="uploadfiles" />
<br><br><br>
@@ -60,8 +60,8 @@
{% endfor %}
</p>
{% endif %}
<strong style="font-size: 110%;">Files already here:</strong><br>
<p>
<strong style="font-size: 110%;">Files already here:</strong> in {{yearpath}}<br>
{% for f in files %}
<a href="{{urlfile|urlencode}}/{{f|urlencode}}">{{f}}</a><br />
{% empty %}
@@ -73,9 +73,13 @@
<hr>
<p>This GPX file has x locations of which y (_%) have been averaged to produce a a location:<br>
<pre>
[1623]
*fix p2025-WW-01 13.8229370 47.6874630 1871
*entrance p2025-WW-01
{% for f in actual_saved %}
[{{ areacode }}]
{{ fixstring }}
{{ entrancestring }}
{% endfor %}
</pre>
<p>