2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2025-12-19 10:47:07 +00:00

rearranged QM code, added red triangle for open QMs

This commit is contained in:
2025-08-26 22:52:13 +01:00
parent 0cf76e8c6b
commit afe9190c97
5 changed files with 56 additions and 44 deletions

View File

@@ -133,6 +133,13 @@ class Cave(TroggleModel):
def __str__(self, sep=": "): def __str__(self, sep=": "):
return str(self.slug()) 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): def get_open_QMs(self):
"""Searches for all QMs that reference this cave.""" """Searches for all QMs that reference this cave."""
# qms = self.qm_set.all().order_by('expoyear', 'block__date') # qms = self.qm_set.all().order_by('expoyear', 'block__date')

View File

@@ -981,7 +981,6 @@ def get_entrances(request, caveslug):
def caveQMs(request, slug, open=False): def caveQMs(request, slug, open=False):
"""Lists all the QMs on a particular cave """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' 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 if not (cave:= get_cave_from_slug(slug)): # walrus operator
return render(request, "errors/badslug.html", {"badslug": f"{slug} - from caveQMs()"}) return render(request, "errors/badslug.html", {"badslug": f"{slug} - from caveQMs()"})

View File

@@ -84,7 +84,7 @@ def datewallet(w, earliest):
REFACTOR this to do the whole date-getting task REFACTOR this to do the whole date-getting task
Currently there is only one SurvexBlock, but this is in anticipation of 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 first = earliest
blocks = SurvexBlock.objects.filter(scanswallet=w) # only ONE I think ?! 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 = "(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 += "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 += "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)" 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 #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)^"(.*)"$') rx_quotedtitle = re.compile(r'(?i)^"(.*)"$')
# QM recognizers # QM recognizers
# does not recognise non numeric suffix survey point ids rx_qm0 = re.compile(r"(?i)^\s*QM(\d+)\s+(.+)$") # correct
rx_qm0 = re.compile(r"(?i)^\s*QM(\d+)\s+(.+)$") rx_qm1 = re.compile(r"(?i)^\s*QM(\w+)\s+(.+)$") # to detect errors
rx_qm_tick = re.compile(r"(?i)^\s*QM(\d+)\s+TICK\s([\d\-]+)\s(.*)$")
# remember there is also QM_PATTERN used in views.other and set in settings.py # remember there is also QM_PATTERN used in views.other and set in settings.py
rx_qm = re.compile( rx_qm = re.compile(
@@ -1524,32 +1523,32 @@ class LoadingSurvex:
self.currentsurvexfile.save() self.currentsurvexfile.save()
self.currentsurvexfile = self.stacksvxfiles.pop() self.currentsurvexfile = self.stacksvxfiles.pop()
def TickSurvexQM(self, survexblock, qmtick): # def TickSurvexQM(self, survexblock, qmtick):
"""Interpret the specially formatted comment which is a QM TICKED statement # """Interpret the specially formatted comment which is a QM TICKED statement
This is now not used, we have abandoned this experiment.""" # 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. # # Now we need to find the correct QM object. It will be in the same block and have the same number.
try: # try:
# could try to search on blockname instead? # # could try to search on blockname instead?
# but the QMn TICK has to be in the same block anyway # # but the QMn TICK has to be in the same block anyway
qm = QM.objects.filter(block=survexblock, number=int(qmtick.group(1))) # qm = QM.objects.filter(block=survexblock, number=int(qmtick.group(1)))
except: # except:
# raise # # 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)}" ' # 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) # print(message)
stash_data_issue( # stash_data_issue(
parser="survex", message=message, url=None, sb=(survexblock.survexfile.path) # parser="survex", message=message, url=None, sb=(survexblock.survexfile.path)
) # )
if len(qm) > 1: # 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)}" ' # 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) # print(message)
stash_data_issue( # stash_data_issue(
parser="survex", message=message, url=None, sb=(survexblock.survexfile.path) # parser="survex", message=message, url=None, sb=(survexblock.survexfile.path)
) # )
qm[0].ticked = True # qm[0].ticked = True
# qm[0].ticked_date = qmtick.group(2) # not in data model yet # # qm[0].ticked_date = qmtick.group(2) # not in data model yet
qm[0].completion_description = qmtick.group(3) # qm[0].completion_description = qmtick.group(3)
qm[0].save() # qm[0].save()
def LoadSurvexQM(self, survexblock, qmline): def LoadSurvexQM(self, survexblock, qmline):
"""Interpret the specially formatted comment which is a QM definition""" """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_no = qmline.group(1) # this is NOT unique across multiple survex files
qm_grade = qmline.group(2).strip().upper() # TICK or [a-dA-DvVxX?] qm_grade = qmline.group(2).strip().upper() # TICK or [a-dA-DvVxX?]
if qm_grade == "TICK": # not used now # if qm_grade == "TICK": # not used now
self.TickSurvexQM(survexblock, qmline) # self.TickSurvexQM(survexblock, qmline)
return # return
if qm_grade not in ["A", "B", "C", "D", "X"]: # "V", "?" not allowed in survex file QMs 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}'" 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): def ProcessQM(self, survexblock, qml, comment):
"""Process the line beginning """Process the line beginning
;QM ;QM
which is a QM new declaration or a QM TICK closing declaration. which is a QM new declaration
It _should_ recognise a non-numeric survey station ID, but currently doesn't.
Valid QM types are [A-DvVxX?] A-D, V for Vertical, X for horrible and ? for unknown 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) qmline = self.rx_qm.match(comment)
if qmline: if qmline:
self.LoadSurvexQM(survexblock, 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) # ignore all comments except ;ref, ; wallet and ;QM and ;*include (for collated survex file)
# rx_ref2 = re.compile(r'(?i)\s*ref[.;]?') # rx_ref2 = re.compile(r'(?i)\s*ref[.;]?')
# This _should_ also check that the QM survey point exists in the block
depth = " " * self.depthbegin depth = " " * self.depthbegin
refline = self.rx_commref.match(comment) refline = self.rx_commref.match(comment)
@@ -1689,11 +1695,10 @@ class LoadingSurvex:
self.LoadSurvexMessteam(survexblock, comment) self.LoadSurvexMessteam(survexblock, comment)
pass pass
qmcomment= self.rx_qm1.match(comment)
# rx_qm0 = re.compile(r"(?i)^\s*QM(\d+)\s+(.+)$") # rx_qm1 (r"(?i)^\s*QM(\w+)\s+(.+)$") QM followed by a word
qml = self.rx_qm0.match(comment) if qmcomment:
if qml: self.ProcessQM(survexblock, qmcomment, comment)
self.ProcessQM(survexblock, qml, comment)
included = self.rx_comminc.match(comment) included = self.rx_comminc.match(comment)
# ;|*include means 'we have been included'; whereas *include means 'proceed to include' # ;|*include means 'we have been included'; whereas *include means 'proceed to include'

View File

@@ -3,4 +3,5 @@ Blue star <span style="color: blue">*</span> against a name indicates that no su
Blue triangle <span style="color: #43C6DB">&#x25BC;</span> against a name indicates that the cave is 'pending' creation properly.<br /> Blue triangle <span style="color: #43C6DB">&#x25BC;</span> against a name indicates that the cave is 'pending' creation properly.<br />
Orange triangle <span style="color: orange">&#x25B2;</span> against a name indicates that the cave has no Entrance (and is not 'pending').<br /> Orange triangle <span style="color: orange">&#x25B2;</span> against a name indicates that the cave has no Entrance (and is not 'pending').<br />
Black triangle <span style="color: black">&#x25B2;</span> against a name indicates that the cave has an Entrance, but no entrances have valid located survey stations.<br /> Black triangle <span style="color: black">&#x25B2;</span> against a name indicates that the cave has an Entrance, but no entrances have valid located survey stations.<br />
Red triangle <span style="color: red">&#x25BC;</span> against a name indicates that the cave has unticked QMs<br />
<span style="color:red">Cavename in red</span> means that the cave is undescended/unexplored. <span style="color:red">Cavename in red</span> means that the cave is undescended/unexplored.

View File

@@ -25,7 +25,7 @@
{% else %} {% else %}
<span title="no survex file is explicitly associated with the cave" style="color: red">*</span> <span title="no survex file is explicitly associated with the cave" style="color: red">*</span>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if cave.any_qm_open %}<span title="the cave has open QMs" style="color: red">&#x25BC;</span>{% endif %}
</span> </span>
<br /> <br />