From 5738da8566cefc54df0cfba83a6bcdc89520c92a Mon Sep 17 00:00:00 2001 From: Philip Sargent Date: Tue, 28 Mar 2023 19:08:05 +0100 Subject: [PATCH] cached_slug str now a .slug field & pending fixed --- core/models/caves.py | 25 ++++++------ parsers/caves.py | 86 ++++++++++++++++++++++----------------- templates/cave_debug.html | 2 +- 3 files changed, 62 insertions(+), 51 deletions(-) diff --git a/core/models/caves.py b/core/models/caves.py index fc3e80f..4737c82 100644 --- a/core/models/caves.py +++ b/core/models/caves.py @@ -284,7 +284,6 @@ class Entrance(TroggleModel): alt = models.TextField(blank=True, null=True) approach = models.TextField(blank=True, null=True) bearings = models.TextField(blank=True, null=True) - cached_slug = models.CharField(max_length=200, blank=True, null=True) easting = models.TextField(blank=True, null=True) entrance_description = models.TextField(blank=True, null=True) exact_station = models.TextField(blank=True, null=True) @@ -304,6 +303,7 @@ class Entrance(TroggleModel): other_description = models.TextField(blank=True, null=True) other_station = models.TextField(blank=True, null=True) photo = models.TextField(blank=True, null=True) + slug = models.SlugField(max_length=50, unique=True, default="default_slug_id") tag_station = models.TextField(blank=True, null=True) underground_description = models.TextField(blank=True, null=True) url = models.CharField(max_length=200, blank=True, null=True) @@ -312,7 +312,7 @@ class Entrance(TroggleModel): ordering = ["caveandentrance__entrance_letter"] def __str__(self): - return str(self.slug()) + return str(self.slug) def exact_location(self): return SurvexStation.objects.lookup(self.exact_station) @@ -394,16 +394,17 @@ class Entrance(TroggleModel): res = "/".join((self.get_root().cave.get_absolute_url(), self.title)) return res - def slug(self): - """Returns the first slug with primary=True that it can find, - if there are none with primary=True, then it returns the first slug it finds - """ - if not self.cached_slug: - slugs = self.entranceslug_set.filter() - if slugs: - self.cached_slug = slugs[0].slug - self.save() - return self.cached_slug + #REPLACE this with a slug filed on the Entrance itself + # def slug(self): + # """Returns the first slug with primary=True that it can find, + # if there are none with primary=True, then it returns the first slug it finds + # """ + # if not self.cached_slug: + # slugs = self.entranceslug_set.filter() + # if slugs: + # self.cached_slug = slugs[0].slug + # self.save() + # return self.cached_slug def cavelist(self): rs = [] diff --git a/parsers/caves.py b/parsers/caves.py index 3f88c45..4e1f171 100644 --- a/parsers/caves.py +++ b/parsers/caves.py @@ -39,47 +39,55 @@ def dummy_entrance(k, slug, msg="DUMMY"): """Returns an empty entrance object for either a PENDING cave or a DUMMY entrance if user forgot to provide one when creating the cave """ - ent = Entrance( - name=k, + ent = Entrance.objects.create( # creates object and saves into db + name=k, slug=k, filename = k + ".html", entrance_description="Dummy entrance: auto-created when registering a new cave " + "and you forgot to create an entrance for it. Click on 'Edit' to enter the correct data, then 'Submit'.", marking="?", ) if ent: - ent.save() # must save to have id before foreign keys work. - try: # Now create a entrance slug ID + try: # Now create a entranceslug object EntranceSlug(entrance=ent, slug=slug) except: message = f" ! {k:11s} {msg}-{slug} entrance create failure" - DataIssue.objects.create(parser="caves", message=message, url=f"{slug}") + DataIssue.objects.create(parser="entrances", message=message, url=f"{slug}") print(message) - ent.cached_slug = slug - ent.filename = slug + ".html" - ent.save() + # ent.cached_slug = slug + # ent.filename = slug + ".html" + # ent.save() return ent else: message = f" ! {k:11s} {msg} cave SLUG '{slug}' create failure" - DataIssue.objects.create(parser="caves", message=message, url=f"{slug}") + DataIssue.objects.create(parser="entrances", message=message, url=f"{slug}") print(message) raise + def set_dummy_entrance(id, slug, cave, msg="DUMMY"): - """Entrance field either missing or holds a null string instead of a filename in a cave_data file.""" + """Called only when reading the cave and entrance html files + Entrance field either missing or holds a null string instead of a filename in a cave_data file.""" global entrances_xslug try: entrance = dummy_entrance(id, slug, msg="DUMMY") entrances_xslug[slug] = entrance CaveAndEntrance.objects.update_or_create(cave=cave, entrance_letter="", entrance=entrance) - message = f" ! Warning: Dummy Entrance successfully set for entrance {id} on cave {cave}" - - DataIssue.objects.create(parser="caves", message=message, url=f"{cave.url}") - print(message) + message = f" - Note: Dummy Entrance successfully set for entrance {id} on cave {cave}" + DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.url}") + # print(message) except: # raise message = f' ! Entrance Dummy setting failure, slug:"{slug}" cave id :"{id}" ' - DataIssue.objects.create(parser="caves", message=message, url=f"{cave.url}") + DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.url}") + print(message) + + try: + EntranceSlug.objects.update_or_create(entrance=entrance, slug=slug) + except: + # raise + message = f' ! EntranceSlug setting failure for Dummy cave, slug:"{slug}" cave id :"{id}" ' + DataIssue.objects.create(parser="entrances", message=message, url=f"{cave.url}") print(message) def make_areas(): @@ -274,21 +282,23 @@ def do_pending_cave(k, url, area): print(message) try: - ent = dummy_entrance(k, slug, msg="PENDING") - ceinsts = CaveAndEntrance.objects.update_or_create(cave=cave, entrance_letter="", entrance=ent) - for ceinst in ceinsts: - if str(ceinst) == str(cave): # magic runes... why is the next value a Bool? - ceinst.cave = cave - ceinst.save() - break + set_dummy_entrance(k, slug, cave, msg="PENDING") + # ent = dummy_entrance(k, slug, msg="PENDING") + # ceinsts = CaveAndEntrance.objects.update_or_create(cave=cave, entrance_letter="", entrance=ent) + # for ceinst in ceinsts: + # if str(ceinst) == str(cave): # magic runes... why is the next value a Bool? + # ceinst.cave = cave + # ceinst.save() + # break except: - message = f" ! {k:11s} PENDING entrance + cave UNION create failure '{cave}' [{ent}]" + message = f" ! {k:11s} PENDING entrance + cave UNION create failure '{cave}' [{slug}] {k}" + # message = f" ! {k:11s} PENDING entrance + cave UNION create failure '{cave}' [{ent}]" DataIssue.objects.create(parser="caves", message=message) print(message) return cave def readentrance(filename): - """Reads an enrance description from the .html file + """Reads an entrance description from the .html file Convoluted. Sorry.This is as I inherited it and I haven't fiddled with it. Needs rewriting """ global entrances_xslug @@ -303,7 +313,7 @@ def readentrance(filename): entrancecontentslist = getXML(contents, "entrance", maxItems=1, context=context) if len(entrancecontentslist) != 1: message = f'! BAD ENTRANCE at "{filename}"' - DataIssue.objects.create(parser="caves", message=message) + DataIssue.objects.create(parser="entrances", message=message) print(message) else: entrancecontents = entrancecontentslist[0] @@ -362,8 +372,13 @@ def readentrance(filename): bearings=bearings[0], url=url[0], filename=filename, - cached_slug=slugs[0], + slug=slugs[0], ) + if len(slugs) >1: + # Only ever one of these in the expo dataset + message = f" ! - More than one slug for an entrance: {entrance}, slugs: {slugs}. Aborting." + DataIssue.objects.create(parser="entrances", message=message, url=f"/cave/{slug}/edit/") + print(message) for slug in slugs: # print("entrance slug:{} filename:{}".format(slug, filename)) try: @@ -371,22 +386,17 @@ def readentrance(filename): except: # need to cope with duplicates message = f" ! FAILED to get precisely one ENTRANCE when updating using: cave_entrance/{filename}" - DataIssue.objects.create(parser="caves", message=message, url=f"/cave/{slug}/edit/") + DataIssue.objects.create(parser="entrances", message=message, url=f"/cave/{slug}/edit/") # kents = EntranceSlug.objects.all().filter(entrance=e, slug=slug, primary=primary) kents = EntranceSlug.objects.all().filter(entrance=e, slug=slug) for k in kents: message = " ! - DUPLICATE in db. entrance:" + str(k.entrance) + ", slug:" + str(k.slug()) - DataIssue.objects.create(parser="caves", message=message, url=f"/cave/{slug}/edit/") + DataIssue.objects.create(parser="entrances", message=message, url=f"/cave/{slug}/edit/") print(message) for k in kents: if k.slug() is not None: print(" ! - OVERWRITING this one: slug:" + str(k.slug())) k.notes = "DUPLICATE entrance found on import. Please fix\n" + k.notes - # else: # more than one item in long list. But this is not an error, and the max and min have been checked by getXML - # slug = Path(filename).stem - # message = f' ! ABORT loading this entrance. in "{filename}"' - # DataIssue.objects.create(parser='caves', message=message, url=f'/cave/{slug}/edit/') - # print(message) def readcave(filename): @@ -526,13 +536,13 @@ def readcave(filename): if not entrances or len(entrances) < 1: # missing entrance link in cave_data/1623-* .html file - set_dummy_entrance(slug[5:], slug, c, msg="DUMMY") + set_dummy_entrance(slug[5:], slug, c, msg="DUMMY: no entrances") else: for entrance in entrances: eslug = getXML(entrance, "entranceslug", maxItems=1, context=context)[0] letter = getXML(entrance, "letter", maxItems=1, context=context)[0] if len(entrances) == 1 and not eslug: # may be empty: - set_dummy_entrance(slug[5:], slug, c, msg="DUMMY") + set_dummy_entrance(slug[5:], slug, c, msg="DUMMY: no entrance slug read from file") else: try: if eslug in entrances_xslug: @@ -545,7 +555,7 @@ def readcave(filename): ) except: message = f' ! Entrance setting failure, slug:"{slug}" #entrances:{len(entrances)} {entrance} letter:"{letter}" cave:"{c}" filename:"cave_data/{filename}"' - DataIssue.objects.create(parser="caves", message=message, url=f"{c.url}_edit/") + DataIssue.objects.create(parser="entrances", message=message, url=f"{c.url}_edit/") print(message) if survex_file[0]: @@ -601,8 +611,8 @@ def getXML(text, itemname, minItems=1, maxItems=None, printwarnings=True, contex def readcaves(): """Reads the xml-format HTML files in the EXPOWEB repo, not from the loser repo.""" - # For those caves which do not have cave_data/1623-xxx.html XML files even though they exist and have surveys - # should put this in a simple list + # Pending is for those caves which do not have cave_data/1623-xxx.html XML files even though + # they exist and have surveys. pending = set() fpending = Path(CAVEDESCRIPTIONS, "pendingcaves.txt") if fpending.is_file(): diff --git a/templates/cave_debug.html b/templates/cave_debug.html index 7de0ce0..6ff51c0 100644 --- a/templates/cave_debug.html +++ b/templates/cave_debug.html @@ -18,7 +18,7 @@ #{{ent.id}} {{ent}} - {{ent.cached_slug}} + {{ent.slug}} {{ent.entranceslug_set.all|length }}