diff --git a/core/models/caves.py b/core/models/caves.py
index 8714305..473cd6b 100644
--- a/core/models/caves.py
+++ b/core/models/caves.py
@@ -133,6 +133,13 @@ class Cave(TroggleModel):
def __str__(self, sep=": "):
return str(self.slug())
+ def any_qm_open(self):
+ qm_count = QM.objects.filter(cave=self, ticked=False).count()
+ if qm_count >= 1:
+ return True
+ else:
+ return False
+
def get_open_QMs(self):
"""Searches for all QMs that reference this cave."""
# qms = self.qm_set.all().order_by('expoyear', 'block__date')
diff --git a/core/views/caves.py b/core/views/caves.py
index 2dca8b7..4ba1ac8 100644
--- a/core/views/caves.py
+++ b/core/views/caves.py
@@ -981,7 +981,6 @@ def get_entrances(request, caveslug):
def caveQMs(request, slug, open=False):
"""Lists all the QMs on a particular cave
relies on the template to find all the QMs for the cave specified in the slug, e.g. '1623-161'
- Now working in July 2022
"""
if not (cave:= get_cave_from_slug(slug)): # walrus operator
return render(request, "errors/badslug.html", {"badslug": f"{slug} - from caveQMs()"})
diff --git a/parsers/survex.py b/parsers/survex.py
index a50ab39..7bafffb 100644
--- a/parsers/survex.py
+++ b/parsers/survex.py
@@ -84,7 +84,7 @@ def datewallet(w, earliest):
REFACTOR this to do the whole date-getting task
Currently there is only one SurvexBlock, but this is in anticipation of
- chnaging the schema to allow many.
+ changing the schema to allow many.
"""
first = earliest
blocks = SurvexBlock.objects.filter(scanswallet=w) # only ONE I think ?!
@@ -274,7 +274,7 @@ class LoadingSurvex:
roles = "(assistant|bitch|bodger|bolt|bolter|bolting|book|clino|comp|compass|consultant|disto|distox|distox2|"
roles += "dog|dogsbody|drawing|drill|gps|helper|inst|instr|instrument|length|monkey|nagging|nail|"
roles += "nail_polish|nail_polish_bitch|nail_polish_monkey|nail_varnish|nail_varnish_bitch|note|notebook|"
- roles += "paint|photo|pic|pictures|point|polish|powerdrill|rig|rigger|rigging|shoot|sketch|slacker|explorer|"
+ roles += "paint|photo|pic|pictures|point|polish|powerdrill|rig|rigger|rigging|SAP|shoot|sketch|slacker|explorer|"
roles += "something|station|surface|tape|topodroid|unknown|useless|varnish|waiting_patiently)"
#rx_teammem = re.compile(r"(?i)" + roles + r"?(?:es|s)?\s+(.*)$") no longer legal survex ordering
@@ -303,9 +303,8 @@ class LoadingSurvex:
rx_quotedtitle = re.compile(r'(?i)^"(.*)"$')
# QM recognizers
- # does not recognise non numeric suffix survey point ids
- rx_qm0 = re.compile(r"(?i)^\s*QM(\d+)\s+(.+)$")
- rx_qm_tick = re.compile(r"(?i)^\s*QM(\d+)\s+TICK\s([\d\-]+)\s(.*)$")
+ rx_qm0 = re.compile(r"(?i)^\s*QM(\d+)\s+(.+)$") # correct
+ rx_qm1 = re.compile(r"(?i)^\s*QM(\w+)\s+(.+)$") # to detect errors
# remember there is also QM_PATTERN used in views.other and set in settings.py
rx_qm = re.compile(
@@ -1524,32 +1523,32 @@ class LoadingSurvex:
self.currentsurvexfile.save()
self.currentsurvexfile = self.stacksvxfiles.pop()
- def TickSurvexQM(self, survexblock, qmtick):
- """Interpret the specially formatted comment which is a QM TICKED statement
- This is now not used, we have abandoned this experiment."""
- # Now we need to find the correct QM object. It will be in the same block and have the same number.
+ # def TickSurvexQM(self, survexblock, qmtick):
+ # """Interpret the specially formatted comment which is a QM TICKED statement
+ # This is now not used, we have abandoned this experiment."""
+ # # Now we need to find the correct QM object. It will be in the same block and have the same number.
- try:
- # could try to search on blockname instead?
- # but the QMn TICK has to be in the same block anyway
- qm = QM.objects.filter(block=survexblock, number=int(qmtick.group(1)))
- except:
- # raise
- message = f' ! QM TICK find FAIL QM{qmtick.group(1)} date:"{qmtick.group(2)}" qmlist:"{qm}" in "{survexblock.survexfile.path}" + completion_description:"{qmtick.group(3)}" '
- print(message)
- stash_data_issue(
- parser="survex", message=message, url=None, sb=(survexblock.survexfile.path)
- )
- if len(qm) > 1:
- message = f' ! QM TICK MULTIPLE found FAIL QM{qmtick.group(1)} date:"{qmtick.group(2)}" in "{survexblock.survexfile.path}" + completion_description:"{qmtick.group(3)}" '
- print(message)
- stash_data_issue(
- parser="survex", message=message, url=None, sb=(survexblock.survexfile.path)
- )
- qm[0].ticked = True
- # qm[0].ticked_date = qmtick.group(2) # not in data model yet
- qm[0].completion_description = qmtick.group(3)
- qm[0].save()
+ # try:
+ # # could try to search on blockname instead?
+ # # but the QMn TICK has to be in the same block anyway
+ # qm = QM.objects.filter(block=survexblock, number=int(qmtick.group(1)))
+ # except:
+ # # raise
+ # message = f' ! QM TICK find FAIL QM{qmtick.group(1)} date:"{qmtick.group(2)}" qmlist:"{qm}" in "{survexblock.survexfile.path}" + completion_description:"{qmtick.group(3)}" '
+ # print(message)
+ # stash_data_issue(
+ # parser="survex", message=message, url=None, sb=(survexblock.survexfile.path)
+ # )
+ # if len(qm) > 1:
+ # message = f' ! QM TICK MULTIPLE found FAIL QM{qmtick.group(1)} date:"{qmtick.group(2)}" in "{survexblock.survexfile.path}" + completion_description:"{qmtick.group(3)}" '
+ # print(message)
+ # stash_data_issue(
+ # parser="survex", message=message, url=None, sb=(survexblock.survexfile.path)
+ # )
+ # qm[0].ticked = True
+ # # qm[0].ticked_date = qmtick.group(2) # not in data model yet
+ # qm[0].completion_description = qmtick.group(3)
+ # qm[0].save()
def LoadSurvexQM(self, survexblock, qmline):
"""Interpret the specially formatted comment which is a QM definition"""
@@ -1565,9 +1564,9 @@ class LoadingSurvex:
qm_no = qmline.group(1) # this is NOT unique across multiple survex files
qm_grade = qmline.group(2).strip().upper() # TICK or [a-dA-DvVxX?]
- if qm_grade == "TICK": # not used now
- self.TickSurvexQM(survexblock, qmline)
- return
+ # if qm_grade == "TICK": # not used now
+ # self.TickSurvexQM(survexblock, qmline)
+ # return
if qm_grade not in ["A", "B", "C", "D", "X"]: # "V", "?" not allowed in survex file QMs
message = f" ! QM{qm_no} INVALID code '{qm_grade}' [{blockname}] '{survexblock.survexfile.path}'"
@@ -1650,11 +1649,19 @@ class LoadingSurvex:
def ProcessQM(self, survexblock, qml, comment):
"""Process the line beginning
;QM
- which is a QM new declaration or a QM TICK closing declaration.
-
- It _should_ recognise a non-numeric survey station ID, but currently doesn't.
+ which is a QM new declaration
Valid QM types are [A-DvVxX?] A-D, V for Vertical, X for horrible and ? for unknown
+
+ This _should_ also check that the first QM survey point exists in the block in this survex file.
"""
+ qml = self.rx_qm0.match(comment) # checks for valid QM digit(s)
+ if not qml:
+ message = f' ! QM Unrecognised QM number in "{survexblock.survexfile.path}" line:{comment}'
+ print(message)
+ stash_data_issue(
+ parser="survex", message=message, url=None, sb=(survexblock.survexfile.path)
+ )
+ return False
qmline = self.rx_qm.match(comment)
if qmline:
self.LoadSurvexQM(survexblock, qmline)
@@ -1669,7 +1676,6 @@ class LoadingSurvex:
# ignore all comments except ;ref, ; wallet and ;QM and ;*include (for collated survex file)
# rx_ref2 = re.compile(r'(?i)\s*ref[.;]?')
- # This _should_ also check that the QM survey point exists in the block
depth = " " * self.depthbegin
refline = self.rx_commref.match(comment)
@@ -1689,11 +1695,10 @@ class LoadingSurvex:
self.LoadSurvexMessteam(survexblock, comment)
pass
-
- # rx_qm0 = re.compile(r"(?i)^\s*QM(\d+)\s+(.+)$")
- qml = self.rx_qm0.match(comment)
- if qml:
- self.ProcessQM(survexblock, qml, comment)
+ qmcomment= self.rx_qm1.match(comment)
+ # rx_qm1 (r"(?i)^\s*QM(\w+)\s+(.+)$") QM followed by a word
+ if qmcomment:
+ self.ProcessQM(survexblock, qmcomment, comment)
included = self.rx_comminc.match(comment)
# ;|*include means 'we have been included'; whereas *include means 'proceed to include'
diff --git a/templates/cave_red_star.html b/templates/cave_red_star.html
index 2632869..5a28596 100644
--- a/templates/cave_red_star.html
+++ b/templates/cave_red_star.html
@@ -3,4 +3,5 @@ Blue star * against a name indicates that no su
Blue triangle ▼ against a name indicates that the cave is 'pending' creation properly.
Orange triangle ▲ against a name indicates that the cave has no Entrance (and is not 'pending').
Black triangle ▲ against a name indicates that the cave has an Entrance, but no entrances have valid located survey stations.
+Red triangle ▼ against a name indicates that the cave has unticked QMs
Cavename in red means that the cave is undescended/unexplored.
\ No newline at end of file
diff --git a/templates/cavelist_columns.html b/templates/cavelist_columns.html
index 407a5a5..ffe7378 100644
--- a/templates/cavelist_columns.html
+++ b/templates/cavelist_columns.html
@@ -25,7 +25,7 @@
{% else %}
*
{% endif %}
-
{% endif %}
+ {% if cave.any_qm_open %}▼{% endif %}