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

refactored gpxupload() into new standard form

This commit is contained in:
2025-10-27 20:06:44 +02:00
parent c08d06d81f
commit f5c1c6a90e

View File

@@ -81,6 +81,7 @@ class PhotographerForm(forms.Form): # not a model-form, just a form-form
class GPXuploadForm(forms.Form): # not a model-form, just a form-form
"""not a git repo so we do not need an "editor" to assign blame to"""
uploadfiles = forms.FileField()
prospector = forms.CharField(strip=True)
class GPXfixForm(forms.Form): # not a model-form, just a form-form
@@ -548,7 +549,169 @@ def analyse_gpx(saved_filename, content):
"""For an uploaded GPX file, analyse it to get a *fix number
"""
print(f"analyse_gpx(): {saved_filename} -- {content.name} length: {len(content)} bytes")
@login_required_if_public
def gpxupload(request, folder=None):
"""Copy of photo upload folder is the "path"
"""
def gpxvalid(name):
# dangerous, we should check the actual file binary signature
return Path(name).suffix.lower() in [".xml", ".gpx"]
print(f"gpxupload() {folder=}")
def _setup(folder_arg):
year = current_expo()
# put year/placeholder directly on ctx (no nested 'context' dict)
ctx = {
"year": year,
"placeholder": "AnathemaDevice",
"filesaved": False,
"actual_saved": [],
"yearpath": Path(settings.EXPOFILES) / "gpslogs" / year,
"formd": GPXuploadForm(),
}
# normalize folder -> dirpath, urlfile, urldir
if folder_arg == str(year) or folder_arg == str(year) + "/":
folder_arg = None
if folder_arg is None:
folder_arg = ""
dirpath = ctx["yearpath"]
urlfile = f"/expofiles/gpslogs/{year}"
urldir = f"/gpxupload/{year}"
else:
dirpath = Path(settings.EXPOFILES) / "gpslogs" / folder_arg
if dirpath.is_dir():
urlfile = f"/expofiles/gpslogs/{folder_arg}"
urldir = Path("/gpxupload") / folder_arg
else:
folder_arg = ""
dirpath = ctx["yearpath"]
urlfile = f"/expofiles/gpslogs/{year}"
urldir = f"/gpxupload/{year}"
ctx.update({"folder": folder_arg, "dirpath": dirpath, "urlfile": urlfile, "urldir": urldir})
print(f"gpxupload() {_setup.__name__} -> {folder_arg=} {dirpath=} {urlfile=} {urldir=}")
return ctx
def _post(ctx):
print(f"gpxupload() method=POST")
for i in request.POST:
print(" ", i)
formd = GPXuploadForm(request.POST)
ctx["formd"] = formd
# prospector creation branch (preserve original behavior and prints)
if "prospector" in request.POST:
print(f"gpxupload() {request.POST=}\n {request.POST.get('prospector')=}")
if formd.is_valid():
newprospector = sanitize_name(request.POST["prospector"])
print(f"gpxupload() {newprospector=}")
try:
(ctx["yearpath"] / newprospector).mkdir(parents=True, exist_ok=True)
except Exception as e:
message = f'\n !! Permissions failure ?! 0 attempting to mkdir "{(ctx["yearpath"] / newprospector)}": {e}'
print(message)
raise
return render(request, "errors/generic.html", {"message": message})
return ctx
# file upload branch
print(f"gpxupload() no prospector field")
print(f"gpxupload() {request.FILES=}")
for i in request.FILES:
print(" ", i)
print(f"gpxupload() about to look at request.FILES")
multiple = request.FILES.getlist("uploadfiles")
if not multiple:
# user supplied no files — attach a form error and return to show it
print(f"gpxupload(): 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
# NO CHECK that the files being uploaded are image files
fs = FileSystemStorage(ctx["dirpath"])
ctx["actual_saved"] = []
ctx["filesaved"] = False
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 Exception:
print(
f'\n !! Permissions failure ?! 3 attempting to save "{f.name}" in "{ctx["dirpath"]}"'
)
if "saved_filename" in locals():
if (ctx["dirpath"] / saved_filename).is_file():
ctx["actual_saved"].append(saved_filename)
ctx["filesaved"] = True
continue
if (ctx["dirpath"] / saved_filename).is_file():
ctx["actual_saved"].append(saved_filename)
ctx["filesaved"] = True
else:
print(f"gpxupload(): not a GPX file {f.name=}")
return ctx
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"gpxupload() EXCEPTION\n {e}")
ctx["files"] = sorted(files) if files else []
ctx["dirs"] = sorted(dirs) if dirs else []
return ctx
# main flow
ctx = _setup(folder)
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"gpxupload() drop through")
files = ctx.get("files", [])
dirs = ctx.get("dirs", [])
print(f"gpxupload() about to render..")
return render(
request,
"gpxuploadform.html",
{
"form": ctx.get("formd", GPXuploadForm()),
"year": ctx["year"],
"placeholder": ctx["placeholder"],
"urlfile": ctx["urlfile"],
"urldir": ctx["urldir"],
"folder": ctx["folder"],
"files": files,
"dirs": dirs,
"filesaved": ctx.get("filesaved", False),
"actual_saved": ctx.get("actual_saved", []),
},
)
@login_required_if_public
def gpxfix(request):
"""Upload one or more GPX files containing a single track which is actually a single static point: for averaging