forked from expo/troggle
Much QM re-engineering
This commit is contained in:
parent
de54576d11
commit
7345e3a328
@ -47,11 +47,11 @@ class SurvexBlockAdmin(TroggleModelAdmin):
|
|||||||
inlines = (RoleInline,)
|
inlines = (RoleInline,)
|
||||||
|
|
||||||
|
|
||||||
class QMsFoundInline(admin.TabularInline):
|
# class QMsFoundInline(admin.TabularInline):
|
||||||
model = QM
|
# model = QM
|
||||||
fk_name = "found_by"
|
# fk_name = "found_by"
|
||||||
fields = ("number", "grade", "location_description", "comment") # need to add foreignkey to cave part
|
# fields = ("number", "grade", "location_description", "comment") # need to add foreignkey to cave part
|
||||||
extra = 1
|
# extra = 1
|
||||||
|
|
||||||
|
|
||||||
class PersonLogEntryInline(admin.TabularInline):
|
class PersonLogEntryInline(admin.TabularInline):
|
||||||
@ -64,7 +64,7 @@ class LogbookEntryAdmin(TroggleModelAdmin):
|
|||||||
prepopulated_fields = {"slug": ("title",)}
|
prepopulated_fields = {"slug": ("title",)}
|
||||||
search_fields = ("title", "expedition__year")
|
search_fields = ("title", "expedition__year")
|
||||||
date_heirarchy = "date"
|
date_heirarchy = "date"
|
||||||
inlines = (PersonLogEntryInline, QMsFoundInline)
|
# inlines = (PersonLogEntryInline, QMsFoundInline)
|
||||||
|
|
||||||
class Media:
|
class Media:
|
||||||
css = {"all": ("css/troggleadmin.css",)} # this does not exist
|
css = {"all": ("css/troggleadmin.css",)} # this does not exist
|
||||||
@ -91,12 +91,12 @@ class PersonAdmin(TroggleModelAdmin):
|
|||||||
|
|
||||||
|
|
||||||
class QMAdmin(TroggleModelAdmin):
|
class QMAdmin(TroggleModelAdmin):
|
||||||
search_fields = ("found_by__cave__kataster_number", "number", "found_by__date")
|
search_fields = ("number", "expoyear")
|
||||||
list_display = ("__str__", "grade", "found_by", "ticked_off_by")
|
list_display = ("__str__", "grade")
|
||||||
list_display_links = ("__str__",)
|
list_display_links = ("__str__",)
|
||||||
list_editable = ("found_by", "ticked_off_by", "grade")
|
# list_editable = ("comment", "page_ref", "grade")
|
||||||
list_per_page = 20
|
# list_per_page = 20
|
||||||
raw_id_fields = ("found_by", "ticked_off_by")
|
# raw_id_fields = ("found_by", "ticked_off_by")
|
||||||
|
|
||||||
|
|
||||||
class PersonExpeditionAdmin(TroggleModelAdmin):
|
class PersonExpeditionAdmin(TroggleModelAdmin):
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
@ -161,14 +162,27 @@ class Cave(TroggleModel):
|
|||||||
def __str__(self, sep=": "):
|
def __str__(self, sep=": "):
|
||||||
return str(self.slug())
|
return str(self.slug())
|
||||||
|
|
||||||
def get_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')
|
||||||
qms = QM.objects.filter(cave=self).order_by(
|
qms = QM.objects.filter(cave=self).order_by(
|
||||||
"expoyear", "block__date"
|
"expoyear", "block__date"
|
||||||
) # a QuerySet, see https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by
|
) # a QuerySet, see https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by
|
||||||
return qms # a QuerySet
|
qmsopen = qms.filter(ticked=False)
|
||||||
|
return qmsopen # a QuerySet
|
||||||
|
|
||||||
|
def get_ticked_QMs(self):
|
||||||
|
"""Searches for all QMs that reference this cave."""
|
||||||
|
qms = QM.objects.filter(cave=self).order_by(
|
||||||
|
"expoyear", "block__date"
|
||||||
|
)
|
||||||
|
qmticked = qms.filter(ticked=True)
|
||||||
|
return qmticked # a QuerySet
|
||||||
|
|
||||||
|
def get_QMs(self):
|
||||||
|
qms = self.get_open_QMs() | self.get_ticked_QMs() # set union operation
|
||||||
|
return qms # a QuerySet
|
||||||
|
|
||||||
def kat_area(self):
|
def kat_area(self):
|
||||||
for a in self.area.all():
|
for a in self.area.all():
|
||||||
if a.kat_area():
|
if a.kat_area():
|
||||||
|
@ -144,38 +144,19 @@ class QM(TroggleModel):
|
|||||||
number = models.IntegerField(
|
number = models.IntegerField(
|
||||||
help_text="this is the sequential number in the year, only unique for CSV imports",
|
help_text="this is the sequential number in the year, only unique for CSV imports",
|
||||||
)
|
)
|
||||||
|
grade = models.CharField(max_length=1, blank=True, null=True, help_text="A/B/C/D/X")
|
||||||
cave = models.ForeignKey("Cave", related_name="QMs", blank=True, null=True, on_delete=models.SET_NULL)
|
cave = models.ForeignKey("Cave", related_name="QMs", blank=True, null=True, on_delete=models.SET_NULL)
|
||||||
block = models.ForeignKey("SurvexBlock", null=True, on_delete=models.SET_NULL) # only for QMs from survex files
|
block = models.ForeignKey("SurvexBlock", null=True, on_delete=models.SET_NULL) # only for QMs from survex files
|
||||||
blockname = models.TextField(blank=True, null=True) # NB truncated copy of survexblock name with last char added
|
blockname = models.TextField(blank=True, null=True) # NB truncated copy of survexblock name with last char added
|
||||||
expoyear = models.CharField(
|
expoyear = models.CharField(max_length=4, blank=True, null=True)
|
||||||
max_length=4, blank=True, null=True
|
ticked = models.BooleanField(default=False)
|
||||||
) # could change to datetime if logbooks similarly chnaged
|
|
||||||
found_by = models.ForeignKey(
|
|
||||||
LogbookEntry, related_name="QMs_found", blank=True, null=True, on_delete=models.SET_NULL
|
|
||||||
)
|
|
||||||
ticked = models.BooleanField(
|
|
||||||
default=False
|
|
||||||
) # for ticked QMs not attached to a logbook entry, should imply completion_description has text
|
|
||||||
ticked_off_by = models.ForeignKey(
|
|
||||||
LogbookEntry, related_name="QMs_ticked_off", blank=True, null=True, on_delete=models.SET_NULL
|
|
||||||
) # unused, ever?!
|
|
||||||
|
|
||||||
GRADE_CHOICES = (
|
|
||||||
("A", "A: Large obvious lead"),
|
|
||||||
("B", "B: Average lead"),
|
|
||||||
("C", "C: Tight unpromising lead"),
|
|
||||||
("D", "D: Dig"),
|
|
||||||
("X", "X: Unclimbable or horrid"),
|
|
||||||
("V", "V: Vertical"),
|
|
||||||
) # also seen "?" in imported data - see urls.py
|
|
||||||
grade = models.CharField(max_length=1, choices=GRADE_CHOICES)
|
|
||||||
location_description = models.TextField(blank=True)
|
location_description = models.TextField(blank=True)
|
||||||
nearest_station_description = models.CharField(max_length=400, blank=True, null=True)
|
completion_description = models.TextField(blank=True)
|
||||||
|
completion_date = models.DateField(blank=True, null=True)
|
||||||
nearest_station_name = models.CharField(max_length=200, blank=True, null=True)
|
nearest_station_name = models.CharField(max_length=200, blank=True, null=True)
|
||||||
resolution_station_name = models.CharField(max_length=200, blank=True, null=True)
|
resolution_station_name = models.CharField(max_length=200, blank=True, null=True)
|
||||||
nearest_station = models.ForeignKey("SurvexStation", blank=True, null=True, on_delete=models.SET_NULL)
|
|
||||||
area = models.CharField(max_length=100, blank=True, null=True)
|
area = models.CharField(max_length=100, blank=True, null=True)
|
||||||
completion_description = models.TextField(blank=True, null=True)
|
page_ref = models.TextField(blank=True, null=True)
|
||||||
comment = models.TextField(blank=True, null=True)
|
comment = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -228,8 +209,8 @@ class QM(TroggleModel):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_next_by_id(self):
|
def get_next_by_id(self): # called in template
|
||||||
return QM.objects.get(id=self.id + 1)
|
return QM.objects.get(id=self.id + 1)
|
||||||
|
|
||||||
def get_previous_by_id(self):
|
def get_previous_by_id(self): # called in template
|
||||||
return QM.objects.get(id=self.id - 1)
|
return QM.objects.get(id=self.id - 1)
|
||||||
|
@ -536,9 +536,11 @@ def caveQMs(request, slug):
|
|||||||
def qm(request, cave_id, qm_id, year, grade=None, blockname=None):
|
def qm(request, cave_id, qm_id, year, grade=None, blockname=None):
|
||||||
"""Reports on one specific QM
|
"""Reports on one specific QM
|
||||||
Fixed and working July 2022, for both CSV imported QMs
|
Fixed and working July 2022, for both CSV imported QMs
|
||||||
needs refactoring though.
|
|
||||||
|
Needs refactoring though! Uses extremely baroque way of getting the QMs instead of querying for QM objects
|
||||||
|
directly, presumably as a result of a baroque history.
|
||||||
|
|
||||||
290 has several QMS with the same number, grade, year (2108) and first 8 chars of the survexblock. This crashes things.
|
Many caves have several QMS with the same number, grade, year (2018) and first 8 chars of the survexblock. This crashes things, so the terminal char of the survexblock name was added
|
||||||
"""
|
"""
|
||||||
|
|
||||||
year = int(year)
|
year = int(year)
|
||||||
@ -547,7 +549,7 @@ def qm(request, cave_id, qm_id, year, grade=None, blockname=None):
|
|||||||
# CSV import QMs, use old technique
|
# CSV import QMs, use old technique
|
||||||
try:
|
try:
|
||||||
c = getCave(cave_id)
|
c = getCave(cave_id)
|
||||||
manyqms = c.get_QMs()
|
manyqms = c.get_open_QMs() | c.get_ticked_QMs() # set union operation
|
||||||
qm = manyqms.get(number=qm_id, expoyear=year)
|
qm = manyqms.get(number=qm_id, expoyear=year)
|
||||||
return render(request, "qm.html", {"qm": qm})
|
return render(request, "qm.html", {"qm": qm})
|
||||||
except QM.DoesNotExist:
|
except QM.DoesNotExist:
|
||||||
@ -565,12 +567,12 @@ def qm(request, cave_id, qm_id, year, grade=None, blockname=None):
|
|||||||
qmslug = f"{cave_id}-{year}-{blockname=}{qm_id}{grade}"
|
qmslug = f"{cave_id}-{year}-{blockname=}{qm_id}{grade}"
|
||||||
print(f"{qmslug=}")
|
print(f"{qmslug=}")
|
||||||
c = getCave(cave_id)
|
c = getCave(cave_id)
|
||||||
manyqms = c.get_QMs()
|
manyqms = c.get_open_QMs() | c.get_ticked_QMs() # set union operation
|
||||||
qmqs = manyqms.filter(expoyear=year, blockname=blockname, number=qm_id, grade=grade)
|
qmqs = manyqms.filter(expoyear=year, blockname=blockname, number=qm_id, grade=grade)
|
||||||
if len(qmqs) > 1:
|
if len(qmqs) > 1:
|
||||||
for q in qmqs:
|
for q in qmqs:
|
||||||
print(qmqs)
|
print(qmqs)
|
||||||
message = f"Multiple QMs with the same cave, year, number, grade AND first 8 chars of the survexblock name. (Could be caused by incomplete databasereset). Fix this in the survex file(s). {cave_id=} {year=} {qm_id=} {blockname=}"
|
message = f"Multiple QMs with the same cave, year, number, grade AND first-several+terminal chars of the survexblock name. (Could be caused by incomplete databasereset). Fix this in the survex file(s). {cave_id=} {year=} {qm_id=} {blockname=}"
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
else:
|
else:
|
||||||
qm = qmqs.get(expoyear=year, blockname=blockname, number=qm_id, grade=grade)
|
qm = qmqs.get(expoyear=year, blockname=blockname, number=qm_id, grade=grade)
|
||||||
@ -588,7 +590,7 @@ def qm(request, cave_id, qm_id, year, grade=None, blockname=None):
|
|||||||
{"badslug": f"Failed get {cave_id=} {year=} {qm_id=} {grade=} {blockname=}"},
|
{"badslug": f"Failed get {cave_id=} {year=} {qm_id=} {grade=} {blockname=}"},
|
||||||
)
|
)
|
||||||
except MultipleObjectsReturned:
|
except MultipleObjectsReturned:
|
||||||
message = f"Multiple QMs with the same cave, year, number, grade AND first 8 chars of the survexblock name. (Could be caused by incomplete databasereset). Fix this in the survex file(s). {cave_id=} {year=} {qm_id=} {blockname=}"
|
message = f"Multiple QMs with the same cave, year, number, grade AND first-several+terminal chars of the survexblock name. (Could be caused by incomplete databasereset). Fix this in the survex file(s). {cave_id=} {year=} {qm_id=} {blockname=}"
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
except QM.DoesNotExist:
|
except QM.DoesNotExist:
|
||||||
# raise
|
# raise
|
||||||
|
79
md5bash.sh
Normal file
79
md5bash.sh
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# read in the input string from command line arguments
|
||||||
|
input=$1
|
||||||
|
|
||||||
|
# pad the input string with a single "1" bit
|
||||||
|
padded_input="$input"$(echo -ne '\x80')
|
||||||
|
|
||||||
|
# pad the input string to a multiple of 512 bits (64 bytes)
|
||||||
|
while (( $(echo -n "$padded_input" | wc -c) % 64 != 56 ))
|
||||||
|
do
|
||||||
|
padded_input="$padded_input"$(echo -ne '\x00')
|
||||||
|
done
|
||||||
|
|
||||||
|
# append the length of the input string (in bits) as a 64-bit little-endian integer
|
||||||
|
length=$(echo -n "$input" | wc -c)
|
||||||
|
length=$(echo "obase=16; $length * 8" | bc | xxd -p -c 16 | tac | tr -d '\n')
|
||||||
|
while (( $(echo -n "$length" | wc -c) < 16 ))
|
||||||
|
do
|
||||||
|
length="$length"0
|
||||||
|
done
|
||||||
|
padded_input="$padded_input"$(echo -ne "$length" | xxd -r -p)
|
||||||
|
|
||||||
|
# initialize the buffer (A, B, C, D)
|
||||||
|
A="67452301"
|
||||||
|
B="efcdab89"
|
||||||
|
C="98badcfe"
|
||||||
|
D="10325476"
|
||||||
|
|
||||||
|
# process the input in 512-bit (64-byte) chunks
|
||||||
|
for (( i=0; i<$(echo -n "$padded_input" | wc -c)/64; i++ ))
|
||||||
|
do
|
||||||
|
chunk=$(echo -n "$padded_input" | dd bs=64 skip=$i count=1 2>/dev/null | xxd -p -c 64)
|
||||||
|
|
||||||
|
# initialize the message schedule (M)
|
||||||
|
M=()
|
||||||
|
for (( j=0; j<16; j++ ))
|
||||||
|
do
|
||||||
|
word=$(echo -ne "${chunk:$j*8:8}" | xxd -r -p | od -An -tu4 -v)
|
||||||
|
M+=($word)
|
||||||
|
done
|
||||||
|
for (( j=16; j<64; j++ ))
|
||||||
|
do
|
||||||
|
word1=${M[j-15]}
|
||||||
|
s0=$(( (word1>>7 | word1<<25) ^ (word1>>18 | word1<<14) ^ (word1>>3) ))
|
||||||
|
|
||||||
|
word2=${M[j-2]}
|
||||||
|
s1=$(( (word2>>17 | word2<<15) ^ (word2>>19 | word2<<13) ^ (word2>>10) ))
|
||||||
|
|
||||||
|
M+=($((M[j-16] + s0 + M[j-7] + s1)))
|
||||||
|
done
|
||||||
|
|
||||||
|
# initialize the working variables
|
||||||
|
AA=$A
|
||||||
|
BB=$B
|
||||||
|
CC=$C
|
||||||
|
DD=$D
|
||||||
|
|
||||||
|
# round 1
|
||||||
|
for (( j=0; j<16; j++ ))
|
||||||
|
do
|
||||||
|
F=$(( (B & C) | (~B & D) ))
|
||||||
|
g=$j
|
||||||
|
dTemp=$((D))
|
||||||
|
D=$((C))
|
||||||
|
C=$((B))
|
||||||
|
B=$((B + ((A + F + M[g] + 0xd76aa478) & 0xffffffff)))
|
||||||
|
A=$((dTemp))
|
||||||
|
done
|
||||||
|
|
||||||
|
# round 2
|
||||||
|
for (( j=16; j<32; j++ ))
|
||||||
|
do
|
||||||
|
F=$(( (D & B) | (~D & C) ))
|
||||||
|
g=$(( (5*j + 1) % 16 ))
|
||||||
|
dTemp=$((D))
|
||||||
|
D=$((C))
|
||||||
|
C=$((B))
|
||||||
|
|
@ -65,7 +65,6 @@ def parseCaveQMs(cave, inputFile, ticked=False):
|
|||||||
nqms = parse_KH_QMs(kh, inputFile=inputFile, ticked=ticked)
|
nqms = parse_KH_QMs(kh, inputFile=inputFile, ticked=ticked)
|
||||||
return nqms
|
return nqms
|
||||||
|
|
||||||
# qmPath = settings.EXPOWEB+inputFile
|
|
||||||
qmPath = Path(settings.EXPOWEB, inputFile)
|
qmPath = Path(settings.EXPOWEB, inputFile)
|
||||||
|
|
||||||
with open(qmPath, "r") as qmCSVContents:
|
with open(qmPath, "r") as qmCSVContents:
|
||||||
@ -76,15 +75,17 @@ def parseCaveQMs(cave, inputFile, ticked=False):
|
|||||||
n = 0
|
n = 0
|
||||||
nqms = 0
|
nqms = 0
|
||||||
for line in qmReader:
|
for line in qmReader:
|
||||||
|
#"Number","Grade","Area","Description","Page reference","Nearest survey station","Completion description","Comment"
|
||||||
try:
|
try:
|
||||||
n += 1
|
n += 1
|
||||||
year = int(line[0][1:5])
|
year = int(line[0][1:5])
|
||||||
f"PH_{int(year)}_{int(n):02d}"
|
f"PH_{int(year)}_{int(n):02d}"
|
||||||
QMnum = re.match(r".*?-\d*?-X?(?P<numb>\d*)", line[0]).group("numb")
|
QMnum = re.match(r".*?-\d*?-X?(?P<numb>\d*)", line[0]).group("numb")
|
||||||
newQM = QM()
|
newQM = QM() # creates python object, does not touch db yet
|
||||||
# newQM.found_by=placeholder
|
# newQM.found_by=placeholder
|
||||||
newQM.number = QMnum
|
newQM.number = QMnum
|
||||||
newQM.cave = caveid
|
newQM.cave = caveid
|
||||||
|
newQM.expoyear = year
|
||||||
newQM.blockname = ""
|
newQM.blockname = ""
|
||||||
if line[1] == "Dig":
|
if line[1] == "Dig":
|
||||||
newQM.grade = "D"
|
newQM.grade = "D"
|
||||||
@ -92,32 +93,28 @@ def parseCaveQMs(cave, inputFile, ticked=False):
|
|||||||
newQM.grade = line[1]
|
newQM.grade = line[1]
|
||||||
newQM.area = line[2]
|
newQM.area = line[2]
|
||||||
newQM.location_description = line[3]
|
newQM.location_description = line[3]
|
||||||
|
newQM.page_ref = line[4]
|
||||||
# In the table, completion is indicated by the presence of a completion discription.
|
# In the table, completion is indicated by the presence of a completion discription.
|
||||||
newQM.completion_description = line[4]
|
newQM.nearest_station_name = line[5]
|
||||||
newQM.nearest_station_description = line[5]
|
newQM.completion_description = line[6]
|
||||||
if newQM.completion_description:
|
if newQM.completion_description:
|
||||||
newQM.ticked = True
|
newQM.ticked = True
|
||||||
else:
|
else:
|
||||||
newQM.ticked = False
|
newQM.ticked = False
|
||||||
|
|
||||||
newQM.comment = line[6]
|
newQM.comment = line[7]
|
||||||
try:
|
try:
|
||||||
# year and number are unique for a cave in CSV imports
|
# year and number are unique for a cave in CSV imports
|
||||||
preexistingQM = QM.objects.get(
|
preexistingQM = QM.objects.get(
|
||||||
number=QMnum, found_by__date__year=year
|
number=QMnum, expoyear=year, cave=caveid,
|
||||||
) # if we don't have this one in the DB, save it
|
)
|
||||||
if (
|
if preexistingQM:
|
||||||
preexistingQM.new_since_parsing is False
|
message = f" ! - {qmPath} PRE-EXISTING QM - should not exist ! {str(line)} "
|
||||||
): # if the pre-existing QM has not been modified, overwrite it - VERY OLD THING
|
print(message)
|
||||||
|
DataIssue.objects.create(parser="QMs", message=message)
|
||||||
preexistingQM.delete()
|
preexistingQM.delete()
|
||||||
newQM.expoyear = year
|
newQM.save()
|
||||||
newQM.save()
|
|
||||||
else: # otherwise, print that it was ignored
|
|
||||||
print((" - preserving " + str(preexistingQM) + ", which was edited in admin \r"))
|
|
||||||
|
|
||||||
except QM.DoesNotExist: # if there is no pre-existing QM, save the new one
|
except QM.DoesNotExist: # if there is no pre-existing QM, save the new one
|
||||||
newQM.expoyear = year
|
|
||||||
newQM.save()
|
newQM.save()
|
||||||
nqms += 1
|
nqms += 1
|
||||||
except KeyError: # check on this one
|
except KeyError: # check on this one
|
||||||
@ -130,6 +127,12 @@ def parseCaveQMs(cave, inputFile, ticked=False):
|
|||||||
print(message)
|
print(message)
|
||||||
DataIssue.objects.create(parser="QMs", message=message)
|
DataIssue.objects.create(parser="QMs", message=message)
|
||||||
continue
|
continue
|
||||||
|
except:
|
||||||
|
message = f" ! - {qmPath} UNKNOWN error {str(line)} "
|
||||||
|
print(message)
|
||||||
|
DataIssue.objects.create(parser="QMs", message=message)
|
||||||
|
raise
|
||||||
|
continue
|
||||||
return nqms
|
return nqms
|
||||||
|
|
||||||
|
|
||||||
@ -139,8 +142,9 @@ def parse_KH_QMs(kh, inputFile, ticked):
|
|||||||
khQMs = khQMfile.readlines()
|
khQMs = khQMfile.readlines()
|
||||||
nqms = 0
|
nqms = 0
|
||||||
for line in khQMs:
|
for line in khQMs:
|
||||||
|
# <dt><a href="sibria.htm#qC1997-161-27" name="C1997-161-27">C1997-161-27</a> A<dd>Sib: pitch at end of Fuzzy Logic [Paradox Rift - continues] [sep.fuzzy.13]
|
||||||
res = re.search(
|
res = re.search(
|
||||||
r"name=\"[CB](?P<year>\d*)-(?P<cave>\d*)-(?P<number>\d*).*</a> (?P<grade>[ABDCV])<dd>(?P<description>.*)\[(?P<nearest_station>.*)\]",
|
r"name=\"[CB](?P<year>\d*)-(?P<cave>\d*)-(?P<number>\d*).*</a> (?P<grade>[ABCDX])<dd>(?P<location_description>.*)\[(?P<nearest_station_name>.*)\]",
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
if res:
|
if res:
|
||||||
@ -157,8 +161,10 @@ def parse_KH_QMs(kh, inputFile, ticked):
|
|||||||
}
|
}
|
||||||
nonLookupAttribs = {
|
nonLookupAttribs = {
|
||||||
"ticked": ticked,
|
"ticked": ticked,
|
||||||
"nearest_station_name": res["nearest_station"],
|
"page_ref": "",
|
||||||
"location_description": res["description"],
|
"completion_description": "",
|
||||||
|
"nearest_station_name": res["nearest_station_name"],
|
||||||
|
"location_description": res["location_description"],
|
||||||
}
|
}
|
||||||
# Create new. We know it doesn't exist as we deleted evrything when we started.
|
# Create new. We know it doesn't exist as we deleted evrything when we started.
|
||||||
instance = QM.objects.create(**nonLookupAttribs, **lookupAttribs)
|
instance = QM.objects.create(**nonLookupAttribs, **lookupAttribs)
|
||||||
@ -169,8 +175,11 @@ def parse_KH_QMs(kh, inputFile, ticked):
|
|||||||
|
|
||||||
def Load_QMs():
|
def Load_QMs():
|
||||||
deleteQMs()
|
deleteQMs()
|
||||||
n204 = parseCaveQMs(cave="204-steinBH", inputFile=r"1623/204/qm.csv")
|
#Number Grade Area Description Page reference Nearest station Completion description Comment
|
||||||
n234 = parseCaveQMs(cave="234-Hauch", inputFile=r"1623/234/qm.csv")
|
n204 = parseCaveQMs(cave="204-steinBH", inputFile=r"1623/204/qm-204.csv") # TAB separated values
|
||||||
|
|
||||||
|
#"Number","Grade","Area","Description","Page reference","Nearest survey station","Completion description","Comment"
|
||||||
|
n234 = parseCaveQMs(cave="234-Hauch", inputFile=r"1623/234/qm-234.csv") # COMMA separated values, with quotes.
|
||||||
n161 = parseCaveQMs(cave="161-KH", inputFile="1623/161/qmtodo.htm", ticked=False)
|
n161 = parseCaveQMs(cave="161-KH", inputFile="1623/161/qmtodo.htm", ticked=False)
|
||||||
t161 = parseCaveQMs(cave="161-KH", inputFile="1623/161/qmdone.htm", ticked=True)
|
t161 = parseCaveQMs(cave="161-KH", inputFile="1623/161/qmdone.htm", ticked=True)
|
||||||
# parseCaveQMs(cave='balkonhoehle',inputFile=r"1623/264/qm.csv")
|
# parseCaveQMs(cave='balkonhoehle',inputFile=r"1623/264/qm.csv")
|
||||||
|
@ -1309,7 +1309,10 @@ class LoadingSurvex:
|
|||||||
|
|
||||||
insp = self.insp
|
insp = self.insp
|
||||||
# create a short, hopefully-unique name for this block to be used in the QM id
|
# create a short, hopefully-unique name for this block to be used in the QM id
|
||||||
blockname = survexblock.name[:6] + survexblock.name[-1:]
|
if len(survexblock.name) < 7:
|
||||||
|
blockname = survexblock.name
|
||||||
|
else:
|
||||||
|
blockname = survexblock.name[:6] + survexblock.name[-1:]
|
||||||
# logslug = f'D{int(qmyear)}_{blockname}_{int(qm_no):03d}'
|
# logslug = f'D{int(qmyear)}_{blockname}_{int(qm_no):03d}'
|
||||||
qm_ticked = False # default
|
qm_ticked = False # default
|
||||||
|
|
||||||
@ -1319,7 +1322,7 @@ class LoadingSurvex:
|
|||||||
self.TickSurvexQM(survexblock, qmline)
|
self.TickSurvexQM(survexblock, qmline)
|
||||||
return
|
return
|
||||||
|
|
||||||
if qm_grade not in ["A", "B", "C", "D", "X", "V", "?"]:
|
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}'"
|
||||||
print(insp + message)
|
print(insp + message)
|
||||||
stash_data_issue(
|
stash_data_issue(
|
||||||
@ -1336,7 +1339,7 @@ class LoadingSurvex:
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
qm_ticked = True
|
qm_ticked = True
|
||||||
print(f"{survexblock.survexfile.cave} {survexblock}:{qm_no}{qm_grade} {qmline.group(4)}", file=sys.stderr)
|
# print(f"{survexblock.survexfile.cave} {survexblock}:{qm_no}{qm_grade} {qmline.group(4)}", file=sys.stderr)
|
||||||
if resolution_station_name:
|
if resolution_station_name:
|
||||||
qm_ticked = True
|
qm_ticked = True
|
||||||
# if qmline.group(6) and qmline.group(6) != "-":
|
# if qmline.group(6) and qmline.group(6) != "-":
|
||||||
|
@ -20,39 +20,42 @@
|
|||||||
<li><a href="{% url 'caveQMs' '1626-359' %}">1626-359 QMs</a> Homecoming
|
<li><a href="{% url 'caveQMs' '1626-359' %}">1626-359 QMs</a> Homecoming
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<p>For how to set up your own QMs, see <a href="/handbook/survey/qmentry.html">Adding QMs </a>.
|
||||||
<p>For full explanation of the current status of the QM system(s), see <a href="/handbook/troggle/scriptsqms.html">scriptsqms page</a>.
|
<p>For full explanation of the current status of the QM system(s), see <a href="/handbook/troggle/scriptsqms.html">scriptsqms page</a>.
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h3>Extant</h3>
|
<h3>Open leads</h3>
|
||||||
<p>{% if cave.get_QMs %}
|
<ul>{% for QM in cave.get_open_QMs %}
|
||||||
<ul>
|
|
||||||
{% for QM in cave.get_QMs %}
|
|
||||||
{% if QM.ticked %}
|
|
||||||
{% else %}
|
|
||||||
<li><a href="{{QM.get_absolute_url}}">{{QM}}</a>
|
<li><a href="{{QM.get_absolute_url}}">{{QM}}</a>
|
||||||
{% if QM.nearest_station_description %}⋮<em>{{QM.nearest_station_description}}</em>⋮{% endif %} {{QM.location_description}} <b>{{QM.grade}}</b>
|
{% if QM.nearest_station_name %}§<em>{{QM.nearest_station_name}}</em>§{% endif %}
|
||||||
|
{{QM.location_description}} <b>{{QM.grade}}</b>
|
||||||
{% if QM.block %} <a href="/survexfile/{{QM.block.survexfile.path}}.svx">{{QM.block}}.svx</a> {{QM.block.date}} {% endif %}</li>
|
{% if QM.block %} <a href="/survexfile/{{QM.block.survexfile.path}}.svx">{{QM.block}}.svx</a> {{QM.block.date}} {% endif %}</li>
|
||||||
{% endif %}
|
{% empty %}
|
||||||
|
<li>No open leads.
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
§ QM.nearest_station_name<br />
|
||||||
|
☆ QM.resolution_station_name<br />
|
||||||
<h3>Ticked off</h3>
|
<h3>Ticked off</h3>
|
||||||
<ul>
|
<ul>{% for QM in cave.get_ticked_QMs %}
|
||||||
{% for QM in cave.get_QMs %}
|
|
||||||
{% if QM.ticked %}
|
|
||||||
<li><a href="{{QM.get_absolute_url}}">{{QM}}</a>
|
<li><a href="{{QM.get_absolute_url}}">{{QM}}</a>
|
||||||
{% if QM.nearest_station %}⋮<em>{{QM.nearest_station}}</em>⋮{% endif %}
|
{% if QM.nearest_station_name %}§<em>{{QM.nearest_station_name}}</em>§{% endif %}
|
||||||
{% if QM.nearest_station_name %}⋮<em>{{QM.nearest_station_name}}</em>⋮{% endif %}
|
{% if QM.resolution_station_name %}☆<em>{{QM.resolution_station_name}}</em>☆{% endif %}
|
||||||
{% if QM.nearest_station_description %}⋮<em>{{QM.nearest_station_description}}</em>⋮{% endif %} {{QM.location_description}} <b>{{QM.grade}}</b>
|
{{QM.location_description}} <b>{{QM.grade}}</b>
|
||||||
{% if QM.block %} <a href="/survexfile/{{QM.block.survexfile.path}}.svx">{{QM.block}}.svx</a> {{QM.block.date}} {% endif %}
|
{% if QM.block %} <a href="/survexfile/{{QM.block.survexfile.path}}.svx">{{QM.block}}.svx</a> {{QM.block.date}} {% endif %}
|
||||||
|
|
||||||
{% if QM.completion_description %}
|
{% if QM.completion_description %}
|
||||||
Completion page: <a href="/{{QM.get_completion_url}}">{{QM.completion_description}}</a>
|
Completion page: <a href="/{{QM.get_completion_url}}">{{QM.completion_description}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% if QM.comment %}
|
||||||
|
Comment: <a href="/{{QM.get_completion_url}}">{{QM.comment}}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
<li>No ticked leads.
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}</p>
|
</p>
|
||||||
|
§ QM.nearest_station_name<br />
|
||||||
|
☆ QM.resolution_station_name<br />
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -18,16 +18,4 @@ Hacked up list of caves with grade "?"
|
|||||||
{% endfor %} }
|
{% endfor %} }
|
||||||
<br /><br />
|
<br /><br />
|
||||||
------------------------------------------------------<br />
|
------------------------------------------------------<br />
|
||||||
Hacked up list of caves with grade "V"
|
|
||||||
<br /><br />
|
|
||||||
|
|
||||||
{% for qm in object_list %}
|
|
||||||
{% if qm.grade == "V" %}<br />
|
|
||||||
"{{qm.id}}": ["{{qm.expoyear}}","{{qm.cave}}",{% if qm.ticked %}"TICKed",{% else %}"OPEN",{% endif %}
|
|
||||||
"{{qm.blockname}}","QM{{qm.number}}","{{qm.grade}}","{{qm.nearest_station_name}}","{{qm.resolution_station_name}}",
|
|
||||||
<a href="{{qm.get_absolute_url}}">"{{qm.get_absolute_url}}"</a>
|
|
||||||
]{% if not forloop.last %},{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %} }
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
@ -2,6 +2,75 @@
|
|||||||
{% load link %}
|
{% load link %}
|
||||||
{% block title %} QM: {{qm|safe}} {% endblock %}
|
{% block title %} QM: {{qm|safe}} {% endblock %}
|
||||||
{% block contentheader %}
|
{% block contentheader %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block related %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<table id="cavepage">
|
||||||
|
<tr>
|
||||||
|
<th id="kat_no"><a class="whitetext" href="{{qm.get_previous_by_id.get_absolute_url}}">Previous QM</a></th>
|
||||||
|
<th id="name">QM {{qm|safe}}</th>
|
||||||
|
<th id="status"><a class="whitetext" href="{{qm.get_next_by_id.get_absolute_url}}">Next QM</a></th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% if qm.ticked %}
|
||||||
|
<h3>This QM is TICKED</h3>
|
||||||
|
|
||||||
|
|
||||||
|
{% if qm.resolution_station_name %}
|
||||||
|
The survey station which record the continuation of the cave past this QM is <b>{{qm.resolution_station_name}}</b>.<br />
|
||||||
|
{%endif %}
|
||||||
|
Tick off comment: '{{qm.comment}}'</a> <br />
|
||||||
|
Tick off completion description: '{{qm.completion_description}}' </a> <br />
|
||||||
|
Tick off url: <a href="/{{qm.get_completion_url}}">{{qm.get_completion_url}}</a> WRONG <br />
|
||||||
|
Tick off date: '{{qm.completion_date}}' [For survex file ticks. not implemented yet]</a> <br />
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if qm.cave %}
|
||||||
|
<h3>Cave: {{qm.cave|safe }}</h3>
|
||||||
|
<a href="{% url 'caveQMs' qm.cave|safe %}">All QMs on this cave </a>{{ qm.cave|safe }} <br>
|
||||||
|
<a href="/{{ qm.cave.url }}"> Cave description </a> {{ qm.cave|safe }}
|
||||||
|
{% else %}
|
||||||
|
<h3>This QM is OPEN</h3>
|
||||||
|
Comment: '{{qm.comment}}'</a> <br />
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
QM page_ref: '{{qm.page_ref}}'<br>
|
||||||
|
|
||||||
|
<h3>QM Number: {{qm.number}} Grade: {{qm.grade}} </h3>
|
||||||
|
|
||||||
|
<p>Explanation of Grade letters: <a href="/handbook/survey/qm.html">Handbook - QM grades</a>
|
||||||
|
|
||||||
|
{% if qm.block %}
|
||||||
|
<h3>Survexfile</h3>
|
||||||
|
{{qm.block.date}} <a href="/survexfile/{{qm.block.survexfile.path}}.svx">{{qm.block}}.svx</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3>QM original closest survey station</h3>
|
||||||
|
{% if qm.block %}
|
||||||
|
Survex block: {{qm.blockname}}
|
||||||
|
<br>
|
||||||
|
{% endif %}
|
||||||
|
Nearest station: '{{qm.nearest_station_name}}' {{nearest_station_description}}
|
||||||
|
<h3>QM original description</h3>
|
||||||
|
{{qm.location_description}}
|
||||||
|
|
||||||
|
{% if qm.found_by %}
|
||||||
|
<h3>Creation</h3>
|
||||||
|
Found by <a href="{{qm.found_by.get_absolute_url}}">{{qm.found_by}}</a> on {{qm.found_by.date}}.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<hr />
|
||||||
<h3>QMs available for these caves from CSV import</h3>
|
<h3>QMs available for these caves from CSV import</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{% url 'caveQMs' '1623-161' %}">1623-161 QMs</a> Maybe OUT OF DATE. See <a href="/1623/161/qmdone.htm">the curated list <b>instead</b></a>
|
<li><a href="{% url 'caveQMs' '1623-161' %}">1623-161 QMs</a> Maybe OUT OF DATE. See <a href="/1623/161/qmdone.htm">the curated list <b>instead</b></a>
|
||||||
@ -18,79 +87,5 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>For full explanation of the current status of the QM system(s), see <a href="/handbook/troggle/scriptsqms.html">scriptsqms page</a>.
|
<p>For full explanation of the current status of the QM system(s), see <a href="/handbook/troggle/scriptsqms.html">scriptsqms page</a>.
|
||||||
|
<hr />
|
||||||
<table id="cavepage">
|
|
||||||
<tr>
|
|
||||||
<th id="kat_no"><a class="whitetext" href="{{qm.get_previous_by_id.get_absolute_url}}">Previous QM</a></th>
|
|
||||||
<th id="name">QM {{qm|safe}}</th>
|
|
||||||
<th id="status"><a class="whitetext" href="{{qm.get_next_by_id.get_absolute_url}}">Next QM</a></th>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block related %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h3>Cave</h3>
|
|
||||||
{% if qm.cave %}
|
|
||||||
<a href="{% url 'caveQMs' qm.cave|safe %}">{{ qm.cave|safe }} QMs</a> <br>
|
|
||||||
{% else %}
|
|
||||||
{% if qm.cave %}
|
|
||||||
<a href="{% url 'caveQMs' qm.cave|safe %}">{{ qm.cave|safe }} QMs</a> <br>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
<a href="/{{ qm.cave.url }}">{{ qm.cave|safe }} cave description</a>
|
|
||||||
|
|
||||||
<h3>QM Number</h3>
|
|
||||||
{{qm.number}}
|
|
||||||
|
|
||||||
<h3>Grade</h3>
|
|
||||||
{{qm.grade}}
|
|
||||||
<p>Explanation of Grade letters: <a href="/handbook/survey/qm.html">Handbook - QM grades</a>
|
|
||||||
|
|
||||||
{% if qm.block %}
|
|
||||||
<h3>Survexfile</h3>
|
|
||||||
{{qm.block.date}} <a href="/survexfile/{{qm.block.survexfile.path}}.svx">{{qm.block}}.svx</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if qm.ticked %}
|
|
||||||
<h3>Ticked</h3>
|
|
||||||
This QM is TICKED
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if qm.resolution_station_name %}
|
|
||||||
<h3>resolution_station_name</h3>
|
|
||||||
{{qm.resolution_station_name}}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h3>Location</h3>
|
|
||||||
{% if qm.block %}
|
|
||||||
Survex block: {{qm.blockname}}
|
|
||||||
<br>
|
|
||||||
{% endif %}
|
|
||||||
Nearest station: '{{qm.nearest_station_name}}' {{nearest_station_description}}
|
|
||||||
<h3>QM Description</h3>
|
|
||||||
{{qm.location_description}}
|
|
||||||
|
|
||||||
{% if qm.found_by %}
|
|
||||||
<h3>Creation</h3>
|
|
||||||
Found by <a href="{{qm.found_by.get_absolute_url}}">{{qm.found_by}}</a> on {{qm.found_by.date}}.
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h3>Completion</h3>
|
|
||||||
{% if qm.ticked %}
|
|
||||||
Ticked off log entry: <a href="{{qm.ticked_off_by.get_absolute_url}}">{{qm.ticked_off_by}}</a><br />
|
|
||||||
Ticked off date: <a href="/{{qm.get_completion_url}}">{{qm.get_completion_url}}</a> WRONG <br />
|
|
||||||
Tick off date: [For survex file ticks. not implemented yet, needs model change]</a> <br />
|
|
||||||
Tick off completion description: {{qm.completion_description}}</a>
|
|
||||||
{% else %}
|
|
||||||
No completion description yet- STILL EXTANT.
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h3>Comment</h3>
|
|
||||||
{{qm.comment}}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user