From 2c673514240d93c5a4431c98f87aafecb94bc081 Mon Sep 17 00:00:00 2001 From: Philip Sargent Date: Sun, 5 Nov 2023 15:20:45 +0200 Subject: [PATCH] bugfix and making more robust --- core/forms.py | 4 +- core/views/caves.py | 2 +- parsers/locations.py | 100 ++++++++++++++++++++----------------------- 3 files changed, 50 insertions(+), 56 deletions(-) diff --git a/core/forms.py b/core/forms.py index 24beee4..5cbbe95 100644 --- a/core/forms.py +++ b/core/forms.py @@ -208,7 +208,9 @@ class EntranceLetterForm(ModelForm): Nb. The relationship between caves and entrances has historically been a many to many relationship. With entrances gaining new caves and letters when caves are joined. """ - entranceletter = forms.CharField(required=False, widget=forms.TextInput(attrs={"size": "2"})) + + # This only needs to be required=True for the second and subsequent entrances, not the first. Tricky. + entranceletter = forms.CharField(required=True, widget=forms.TextInput(attrs={"size": "2"})) class Meta: model = CaveAndEntrance diff --git a/core/views/caves.py b/core/views/caves.py index c845f01..adb3398 100644 --- a/core/views/caves.py +++ b/core/views/caves.py @@ -519,7 +519,7 @@ def edit_entrance(request, path="", caveslug=None, entslug=None): entranceletter = entletterform.cleaned_data["entranceletter"] else: print(f"- POST INVALID {caveslug=} {entslug=} {path=} entletterform invalid.") - return render(request, "errors/badslug.html", {"entletter problem in edit_entrances()"}) + return render(request, "errors/badslug.html", {"badslug": "entletter problem in edit_entrances()"}) # if entform.is_valid() and entletterform.is_valid(): if entform.is_valid(): entrance = entform.save(commit=False) diff --git a/parsers/locations.py b/parsers/locations.py index 92df13e..d3d65ab 100644 --- a/parsers/locations.py +++ b/parsers/locations.py @@ -292,7 +292,7 @@ def LoadPositions(): print(message) topdata = os.fspath(Path(settings.SURVEX_DATA) / settings.SURVEX_TOPNAME) - print(f" - Generating a list of Pos from {topdata}.svx and then loading...") + print(f" - Generating a list of Pos from {topdata}.3d and then loading...") found = 0 print("\n") # extra line because cavern overwrites the text buffer somehow @@ -316,7 +316,7 @@ def LoadPositions(): runcavern3d() if not os.path.isfile(d3dpath): runcavern3d() - elif d3d_t - svx_t > 0: # stale, 3d older than svx file + elif d3d_t - svx_t > 0: # stale, 3d older than svx file runcavern3d() elif now - d3d_t > 24 * 60 * 60: # >1 days old, re-run anyway runcavern3d() @@ -341,62 +341,54 @@ def LoadPositions(): stash_data_issue(parser="positions", message=message, url=f"/entrance_data/{pospath}_edit") print(message) return + with open(pospath) as posfile: + posfile.readline() # Drop header + + sbdict = {} + dups = 0 + lineno = 1 # we dropped the header + for line in posfile.readlines(): + lineno += 1 + r = poslineregex.match(line) + if r: + x, y, z, sbid = r.groups() # renamed id to sbid so as to not confuse with Django internal .id + if sbid in sbdict: + dups += 1 + message = f" ! DUPLICATE SurvexBlock identifier in .pos file '{sbid}'\n{sbs[sbid]}\n{lineno} / {line}" + print(message) + stash_data_issue(parser="positions", message=message) + else: + sbdict[sbid] = lineno + - posfile = open(pospath) - posfile.readline() # Drop header - - sbdict = {} - dups = 0 - lineno = 1 # we dropped the header - for line in posfile.readlines(): - lineno += 1 - r = poslineregex.match(line) - if r: - x, y, z, sbid = r.groups() # renamed id to sbid so as to not confuse with Django internal .id - if sbid in sbdict: - dups += 1 - message = f" ! DUPLICATE SurvexBlock identifier in .pos file '{sbid}'\n{sbs[sbid]}\n{lineno} / {line}" - print(message) - stash_data_issue(parser="positions", message=message) - else: - sbdict[sbid] = lineno - - - for sid in mappoints: - if not sid: # catch None entry - continue - if sbid.endswith(sid) or sbid.endswith(sid.lower()): - blockpath = "." + sbid[: -len(sid)].strip(".") # only the most recent one that is mappoints - if sid in found_points: - found_points[sid] += 1 - else: - found_points[sid] = 1 - - try: - ss = SurvexStation(name=sbid) - ss.x = float(x) - ss.y = float(y) - ss.z = float(z) - ss.entrance = mappoints[sid] - ss.save() - found += 1 - except: - message = f" ! {lineno} FAIL to create SurvexStation Entrance point {blockpath} {sid}" - print(message) - stash_data_issue(parser="positions", message=message) - store_data_issues() - raise + for sid in mappoints: + if not sid: # catch None entry + continue + if sbid.endswith(sid) or sbid.endswith(sid.lower()): + blockpath = "." + sbid[: -len(sid)].strip(".") # only the most recent one that is mappoints + if sid in found_points: + found_points[sid] += 1 + else: + found_points[sid] = 1 + + try: + ss = SurvexStation(name=sbid) + ss.x = float(x) + ss.y = float(y) + ss.z = float(z) + ss.entrance = mappoints[sid] + ss.save() + found += 1 + except: + message = f" ! {lineno} FAIL to create SurvexStation Entrance point {blockpath} {sid}" + print(message) + stash_data_issue(parser="positions", message=message) + store_data_issues() + raise validate_entrance_stations() # do not need to use db here really positions_filename = Path(pospath).name print(f" - {found} distinct SurvexStation entrance stations identified in {lineno:,} lines in {positions_filename}.") if dups > 0: print(f" - {dups} Duplicated SurvexStation entrances found") - - # for p in mappoints: - # if p not in found_points: - # print(f"Valid point {p} NOT found in {positions_filename}") - # print(f" - {len(mappoints)} mappoints, {len(found_points)} found_points") - # for sid in found_points: - # if found_points[sid] > 1: - # print(f" - {sid} - {found_points[sid]}") + store_data_issues()