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:
@@ -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"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user