2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2025-12-19 11:07:28 +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,94 +551,96 @@ 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! year = current_expo() # read this from the GPX file in future!
filesaved = False ctx = {
actual_saved = [] "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
context = {"year": year, "placeholder": "AnathemaDevice"} def _post(ctx):
formd = GPXfixForm(request.POST)
ctx["formd"] = formd
yearpath = Path(settings.EXPOFILES) / "gpsfix" / year # Check there are files to upload
multiple = request.FILES.getlist("uploadfiles")
if not multiple:
folder = "" # improve this later # user supplied no files — attach a form error and return to show it
dirpath = yearpath print(f"gpxfix(): no files to upload {multiple}")
urlfile = f"/expofiles/gpsfix/{year}" formd.add_error("uploadfiles", "No files uploaded.") # does not seem to be visible on form?
urldir = f"/gpxfix/{year}" ctx["formd"] = formd
return ctx
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")
print(f"gpxfix() {request.FILES=}")
for i in request.FILES:
print(" ",i)
ctx["areacode"] = request.POST["areacode"].strip()
if not formd.is_valid(): fs = FileSystemStorage(ctx["dirpath"])
print(f"gpxfix() Form is not valid {formd=}") ctx["actual_saved"] = []
else: ctx["location_data"] = []
print(f"gpxfix() about to look at request.FILES")
#f = request.FILES["uploadfiles"]
multiple = request.FILES.getlist("uploadfiles")
fs = FileSystemStorage(dirpath)
actual_saved = []
location_data = []
if multiple:
for f in multiple: for f in multiple:
if gpxvalid(f.name): if gpxvalid(f.name):
try: # crashes in Django os.chmod call if on WSL, but does save file! try:
saved_filename = fs.save(f.name, content=f) saved_filename = fs.save(f.name, content=f)
except: except Exception as e:
print( print(f'\n !! Permissions failure ?! on attempting to save "{f.name}" in "{ctx["dirpath"]}": {e}')
f'\n !! Permissions failure ?! on attempting to save "{f.name}" in "{dirpath}" {renameto=}' # if save partially succeeded, guard against referencing undefined vars
) continue
if "saved_filename" in locals(): filepath = ctx["dirpath"] / saved_filename
if saved_filename.is_file(): if filepath.is_file():
actual_saved.append(saved_filename) ctx["actual_saved"].append(saved_filename)
filesaved = True ctx["filesaved"] = True
location_data.append(analyse_gpx(saved_filename, f)) # 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: else:
print(f"gpxfix(): not a GPX file {f.name=}") print(f"gpxfix(): not a GPX file {f.name=}")
print(f"gpxfix() drop through") 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):
files = [] files = []
dirs = [] dirs = []
formd = GPXfixForm()
print(f"gpxfix() {formd=} ")
try: try:
for f in dirpath.iterdir(): for f in ctx["dirpath"].iterdir():
if f.is_dir(): if f.is_dir():
dirs.append(f.name) dirs.append(f.name)
if f.is_file(): if f.is_file():
@@ -646,26 +649,38 @@ def gpxfix(request):
files.append("(no folder yet - would be created)") files.append("(no folder yet - would be created)")
except Exception as e: except Exception as e:
print(f"gpxfix() EXCEPTION\n {e}") print(f"gpxfix() EXCEPTION\n {e}")
if len(files) > 0: ctx["files"] = sorted(files) if files else []
files = sorted(files) ctx["dirs"] = sorted(dirs) if dirs else []
return ctx
if dirs: # main flow
dirs = sorted(dirs) ctx = _setup()
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)
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

@@ -13,7 +13,7 @@
<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>