From cc3203a31fdb53433b5873f810c6fd96dc12af58 Mon Sep 17 00:00:00 2001 From: Philip Sargent Date: Fri, 29 Aug 2025 19:18:47 +0300 Subject: [PATCH] initial GPX track averager --- core/views/uploads.py | 152 ++++++++++++++++++++++++++++++++++++++ templates/gpxfixform.html | 61 +++++++++++++++ urls.py | 3 +- 3 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 templates/gpxfixform.html diff --git a/core/views/uploads.py b/core/views/uploads.py index b956480..c66b8bc 100644 --- a/core/views/uploads.py +++ b/core/views/uploads.py @@ -79,6 +79,9 @@ class PhotographerForm(forms.Form): # not a model-form, just a form-form class GPXuploadForm(forms.Form): # not a model-form, just a form-form prospector = forms.CharField(strip=True) + +class gpxfixForm(forms.Form): # not a model-form, just a form-form + prospector = forms.CharField(strip=True) class FilesRenameForm(forms.Form): # not a model-form, just a form-form """Used only for renaming photos in /expofiles/photos/ @@ -563,6 +566,155 @@ def gpxupload(request, folder=None): }, ) +@login_required_if_public +def gpxfix(request): + """Upload a GPX file containing a single track which is actually a single static point: for averaging + """ + def gpxvalid(name): + if Path(name).suffix.lower() in [".xml", ".gpx"]: + return True # dangerous, we should check the actual file binary signature + return False + + year = current_expo() # read thsi from the GPX file + 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=}") + form = FilesRenameForm() + formd = gpxfixForm() + print(f"gpxfix() {form=} {formd=} ") + + + if request.method == "POST": + print(f"gpxfix() method=POST") + for i in request.POST: + print(" ",i) + + try: + (yearpath).mkdir(parents=True, exist_ok=True) + except: + message = f'\n !! Permissions failure ?! 0 attempting to mkdir "{(yearpath)}"' + print(message) + raise + return render(request, "errors/generic.html", {"message": message}) + + if "prospector" in request.POST: + print(f"gpxfix() {request.POST=}\n {request.POST['prospector']=}") + formd = gpxfixForm(request.POST) + 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) + + form = FilesRenameForm(request.POST, request.FILES) + print(f"gpxfix() is the FilesRenameForm valid? {form=}") + for i in form: + print(" ",i) + + if not form.is_valid(): + print(f"gpxfix() Form is not valid {form=}") + else: + print(f"gpxfix() about to look at request.FILES") + f = request.FILES["uploadfiles"] + multiple = request.FILES.getlist("uploadfiles") + # NO CHECK that the files being uploaded are image files + fs = FileSystemStorage(dirpath) + + renameto = sanitize_name(request.POST["renameto"]) + + actual_saved = [] + if multiple: + if len(multiple) == 1: + if renameto != "": + try: # crashes in Django os.chmod call if on WSL, but does save file! + saved_filename = fs.save(renameto, content=f) + except: + print( + f'\n !! Permissions failure ?! 1 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 + else: # multiple is the uploaded content + 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 ?! 2 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 + else: # multiple is a list of content + 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 ?! 3 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 + else: + print(f"gpxfix(): not a GPX file {f.name=}") + + print(f"gpxfix() drop through") + files = [] + dirs = [] + 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( + request, + "gpxfixform.html", + { + "form": form, + **context, + "urlfile": urlfile, + "urldir": urldir, + "folder": folder, + "files": files, + "dirs": dirs, + "filesaved": filesaved, + "actual_saved": actual_saved, + }, + ) + + @login_required_if_public def dwgupload(request, folder=None, gitdisable="no"): """Upload DRAWING files (tunnel or therion) into the upload folder in :drawings diff --git a/templates/gpxfixform.html b/templates/gpxfixform.html new file mode 100644 index 0000000..b4a456f --- /dev/null +++ b/templates/gpxfixform.html @@ -0,0 +1,61 @@ +{% extends "base.html" %} + +{% block title %}Upload GPX file for a *fix{% endblock %} + +{% block content %} + + + +

Upload GPX file for a *fix

+ +
+
+ {% csrf_token %} +
+ +


+ +
+ +


+ +
+
+
+ {% if filesaved %} +

+ File(s) saved as
+ {% for f in actual_saved %} + {{f}}
+ {% endfor %} +

+ {% endif %} + + Files:
+ {% for f in files %} + {{f}}
+ {% empty %} +

<No files here> + {% endfor %} +

+

You can upload your GPX track which will be averaged into a single *fix +

Note that only GPX files are accepted: all other types of files are refused. +


+ + + + + +

+ +


+ + +{% endblock %} \ No newline at end of file diff --git a/urls.py b/urls.py index 2371901..ba19397 100644 --- a/urls.py +++ b/urls.py @@ -64,7 +64,7 @@ from troggle.core.views.prospect import prospecting from troggle.core.views.user_registration import register, newregister, reset_done, ExpoPasswordResetForm from troggle.core.views.scans import allscans, cavewallets, scansingle, walletslistperson, walletslistyear from troggle.core.views.signup import signup, signupok -from troggle.core.views.uploads import dwgupload, expofilerename, gpxupload, photoupload +from troggle.core.views.uploads import dwgupload, expofilerename, gpxupload, photoupload, gpxfix from troggle.core.views.wallets_edit import walletedit # crashes when run from wsgi on new server OS: @@ -180,6 +180,7 @@ trogglepatterns = [ path('walletedit/', walletedit, name='walletedit'), # path=2020#01 path('photoupload', photoupload, name='photoupload'), # restricted to current year path('photoupload/', photoupload, name='photoupload'), # restricted to current year + path('gpxfix', gpxfix, name='gpxfix'), # upload GPX 'track' for a single fix path('gpxupload', gpxupload, name='gpxupload'), # restricted to current year path('gpxupload/', gpxupload, name='gpxupload'), # restricted to current year path('dwgupload/', dwgupload, name='dwgupload'),