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) prospector = forms.CharField(strip=True)
areacode = forms.CharField(strip=True) areacode = forms.CharField(strip=True)
station = forms.CharField(strip=True) station = forms.CharField(strip=True)
uploadfiles = forms.FileField()
class FilesRenameForm(forms.Form): # not a model-form, just a form-form 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 @login_required_if_public
def gpxfix(request): def gpxfix(request):
"""Upload a GPX file containing a single track which is actually a single static point: for averaging """Upload one or more GPX files 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 -->
""" """
def gpxvalid(name): def gpxvalid(name):
if Path(name).suffix.lower() in [".gpx"]: if Path(name).suffix.lower() in [".gpx"]:
return True # dangerous, we should check the actual file binary signature return True # dangerous, we should check the actual file binary signature
return False 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! # Check there are files to upload
filesaved = False multiple = request.FILES.getlist("uploadfiles")
actual_saved = [] if not multiple:
# user supplied no files — attach a form error and return to show it
context = {"year": year, "placeholder": "AnathemaDevice"} print(f"gpxfix(): no files to upload {multiple}")
formd.add_error("uploadfiles", "No files uploaded.") # does not seem to be visible on form?
yearpath = Path(settings.EXPOFILES) / "gpsfix" / year ctx["formd"] = formd
return ctx
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)
# ensure base year folder exists
try: try:
(yearpath).mkdir(parents=True, exist_ok=True) ctx["yearpath"].mkdir(parents=True, exist_ok=True)
except: except Exception as e:
message = f'\n !! Permissions failure ?! 0 attempting to mkdir "{(yearpath)}"' message = f'\n !! Permissions failure ?! 0 attempting to mkdir "{ctx["yearpath"]}": {e}'
print(message) print(message)
raise
return render(request, "errors/generic.html", {"message": message}) return render(request, "errors/generic.html", {"message": message})
# if a prospector field was submitted, validate it
if "prospector" in request.POST: if "prospector" in request.POST:
print(f"gpxfix() {request.POST=}\n {request.POST['prospector']=}")
if formd.is_valid(): if formd.is_valid():
newprospector = sanitize_name(request.POST["prospector"]) newprospector = sanitize_name(request.POST["prospector"])
print(f"gpxfix() {newprospector=}") print(f"gpxfix() prospector named: {newprospector}")
else:
print(f"gpxfix() no prospector field") ctx["areacode"] = request.POST["areacode"].strip()
print(f"gpxfix() {request.FILES=}")
for i in request.FILES: fs = FileSystemStorage(ctx["dirpath"])
print(" ",i) 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
def _get(ctx):
if not formd.is_valid(): files = []
print(f"gpxfix() Form is not valid {formd=}") dirs = []
else: try:
print(f"gpxfix() about to look at request.FILES") for f in ctx["dirpath"].iterdir():
#f = request.FILES["uploadfiles"] if f.is_dir():
multiple = request.FILES.getlist("uploadfiles") dirs.append(f.name)
fs = FileSystemStorage(dirpath) 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 = [] if request.method == "POST":
location_data = [] ctx = _post(ctx)
if multiple: # if form invalid, still show GET-like view (ctx includes form with errors)
for f in multiple: if isinstance(ctx, dict) and "formd" in ctx and not ctx["formd"].is_valid():
if gpxvalid(f.name): ctx = _get(ctx)
try: # crashes in Django os.chmod call if on WSL, but does save file! else:
saved_filename = fs.save(f.name, content=f) ctx = _get(ctx)
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 dirs:
dirs = sorted(dirs)
print(f"gpxfix() about to render..")
return render( return render(
request, request,
"gpxfixform.html", "gpxfixform.html",
{ {
"form": formd, "form": ctx.get("formd", GPXfixForm()),
**context, "year": ctx["year"],
"urlfile": urlfile, "urlfile": ctx["urlfile"],
"urldir": urldir, "urldir": ctx["urldir"],
"folder": folder, "yearpath": ctx["yearpath"],
"files": files, "folder": ctx["folder"],
"dirs": dirs, "files": ctx.get("files", []),
"filesaved": filesaved, "dirs": ctx.get("dirs", []),
"actual_saved": actual_saved, "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" > <div style = "max-width:35%; margin-left:20%; text-align: left" >
<form method ='post' enctype ="multipart/form-data"> <form method ='post' enctype ="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<br> <br>
<input class="fancybutton2" type = "file" multiple="multiple" <input class="fancybutton2" type = "file" multiple="multiple" required
name = "uploadfiles" id="uploadfiles" /> name = "uploadfiles" id="uploadfiles" />
<br><br><br> <br><br><br>
@@ -60,8 +60,8 @@
{% endfor %} {% endfor %}
</p> </p>
{% endif %} {% endif %}
<p>
<strong style="font-size: 110%;">Files already here:</strong><br> <strong style="font-size: 110%;">Files already here:</strong> in {{yearpath}}<br>
{% for f in files %} {% for f in files %}
<a href="{{urlfile|urlencode}}/{{f|urlencode}}">{{f}}</a><br /> <a href="{{urlfile|urlencode}}/{{f|urlencode}}">{{f}}</a><br />
{% empty %} {% empty %}
@@ -73,9 +73,13 @@
<hr> <hr>
<p>This GPX file has x locations of which y (_%) have been averaged to produce a a location:<br> <p>This GPX file has x locations of which y (_%) have been averaged to produce a a location:<br>
<pre> <pre>
[1623] {% for f in actual_saved %}
*fix p2025-WW-01 13.8229370 47.6874630 1871
*entrance p2025-WW-01 [{{ areacode }}]
{{ fixstring }}
{{ entrancestring }}
{% endfor %}
</pre> </pre>
<p> <p>