diff --git a/core/models/caves.py b/core/models/caves.py index db86e66..5a09229 100644 --- a/core/models/caves.py +++ b/core/models/caves.py @@ -505,7 +505,7 @@ class QM(TroggleModel): return f'{self.code()}' def code(self): - return f'{str(self.found_by.cave_slug)[5:]}-{self.expoyear}-{self.blockname}{self.number}{self.grade}' + return f'{str(self.cave.slug())[5:]}-{self.expoyear}-{self.blockname}{self.number}{self.grade}' def newslug(self): qmslug = f'{str(self.cave)}-{self.expoyear}-{self.blockname}{self.number}{self.grade}' diff --git a/core/views/caves.py b/core/views/caves.py index 616e69f..2a2e5b8 100644 --- a/core/views/caves.py +++ b/core/views/caves.py @@ -485,43 +485,46 @@ def qm(request,cave_id,qm_id,year,grade=None, blockname=None): '''Reports on one specific QM Fixed and working July 2022, for both CSV imported QMs needs refactoring though. - For survex-imported QMs we are not getting unique objects returned, so the query needs fixing. + + 290 has several QMS with the same number, grade, year (2108) and first 8 chars of the survexblock. This crashes things. ''' year=int(year) - if blockname == 'None': + if blockname == '': # CSV import QMs, use old technique try: c=getCave(cave_id) manyqms=c.get_QMs() - qm=manyqms.get(number=qm_id,found_by__date__year=year, found_by__cave_slug=c.slug()) + qm=manyqms.get(number=qm_id,expoyear=year) return render(request,'qm.html', {'qm': qm}) except QM.DoesNotExist: + raise return render(request,'errors/badslug.html', {'badslug': f'{cave_id=} {year=} {qm_id=} {blockname=}'}) else: - # survex import QMs, need to disambiguate with blockname - # slug = f'{str(self.cave)}-{self.found_by.date.year}-{self.blockname}{self.number}{self.grade}' - try: qmslug = f'{cave_id}-{year}-{blockname=}{qm_id}{grade}' c=getCave(cave_id) manyqms=c.get_QMs() - qm=manyqms.get(found_by__date__year=year, blockname=blockname, number=qm_id, grade=grade) - if qm: - print(qm, f'{qmslug=}:{cave_id=} {year=} {qm_id=} {blockname=} {qm.expoyear=}') - return render(request,'qm.html', {'qm': qm}) + qmqs=manyqms.filter(expoyear=year, blockname=blockname, number=qm_id, grade=grade) + if len(qmqs) > 1: + for q in qmqs: + print(qmqs) + message = f'Multiple QMs with the same cave, year, number, grade AND first 8 chars of the survexblock name. Fix this in the survex file(s). {cave_id=} {year=} {qm_id=} {blockname=}' + return render(request,'errors/generic.html', {'message': message}) else: - return render(request,'errors/badslug.html', {'badslug': f'{cave_id=} {year=} {qm_id=} {blockname=}'}) + qm=qmqs.get(expoyear=year, blockname=blockname, number=qm_id, grade=grade) + if qm: + print(qm, f'{qmslug=}:{cave_id=} {year=} {qm_id=} {blockname=} {qm.expoyear=}') + return render(request,'qm.html', {'qm': qm}) + else: + raise + return render(request,'errors/badslug.html', {'badslug': f'{cave_id=} {year=} {qm_id=} {blockname=}'}) except MultipleObjectsReturned: - if len(qm) > 1: - for q in qm: - print(qm) - return render(request,'qm.html', {'qm': qm[0]}) - else: - return render(request,'qm.html', {'qm': qm}) + raise except QM.DoesNotExist: - return render(request,'errors/badslug.html', {'badslug': f'{cave_id=} {year=} {qm_id=} {blockname=}'}) + raise + return render(request,'errors/badslug.html', {'badslug': f'{cave_id=} {year=} {qm_id=} {blockname=}'}) def get_qms(request, caveslug): diff --git a/parsers/QMs.py b/parsers/QMs.py index ab9ec0f..2aa9bbf 100644 --- a/parsers/QMs.py +++ b/parsers/QMs.py @@ -27,7 +27,11 @@ def parseCaveQMs(cave,inputFile): have the passage name, e.g. in 204/qm.csv C2000-204-39 B Tree Pitch in Cave Tree treeumphant.28 Gosser Streamway The CSV file does not have the exact date for the QM, only the year, so links to - survex files might be ambiguous. But potentially useful?""" + survex files might be ambiguous. But potentially useful? + + Much of this code assumes that QMs are edited using troggle. This is not done so this code can be deleted. + All QMs are created afresh and this is all only run once on import on a fresh database. + """ if cave=='204-steinBH': try: @@ -59,7 +63,7 @@ def parseCaveQMs(cave,inputFile): return nqms #qmPath = settings.EXPOWEB+inputFile - qmPath = os.path.join(settings.EXPOWEB, inputFile) + qmPath = os.path.join(settings.EXPOWEB, inputFile) # why not use the pathlib stuff ? qmCSVContents = open(qmPath,'rU') dialect=csv.Sniffer().sniff(qmCSVContents.read()) @@ -73,20 +77,22 @@ def parseCaveQMs(cave,inputFile): n += 1 year=int(line[0][1:5]) logslug = f'PH_{int(year)}_{int(n):02d}' + # logbook placeholder code was previously here. No longer needed. #check if placeholder exists for given year, create it if not - message = " ! - "+ str(year) + " logbook: placeholder entry for '" + cave + "' created. DUMMY EXPEDITION ID. Should be re-attached to the actual trip." - if cave=='204-steinBH': - placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, place="204", title="placeholder for QMs in 204", text=message, entry_type="DUMMY", expedition_id=1, defaults={"date": date(year, 1, 1),"cave_slug":str(steinBr), "slug": logslug}) - elif cave=='234-Hauch': - placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, place="234", title="placeholder for QMs in 234", text=message, entry_type="DUMMY", expedition_id=1, defaults={"date": date(year, 1, 1),"cave_slug":str(hauchHl)}) - # if hadToCreate: - # print(message) - # DataIssue.objects.create(parser='QMs', message=message) + # message = " ! - "+ str(year) + " logbook: placeholder entry for '" + cave + "' created. DUMMY EXPEDITION ID. Should be re-attached to the actual trip." + # if cave=='204-steinBH': + # placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, place="204", title="placeholder for QMs in 204", text=message, entry_type="DUMMY", expedition_id=1, defaults={"date": date(year, 1, 1),"cave_slug":str(steinBr), "slug": logslug}) + # elif cave=='234-Hauch': + # placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, place="234", title="placeholder for QMs in 234", text=message, entry_type="DUMMY", expedition_id=1, defaults={"date": date(year, 1, 1),"cave_slug":str(hauchHl)}) + # # if hadToCreate: + # # print(message) + # # DataIssue.objects.create(parser='QMs', message=message) QMnum=re.match(r".*?-\d*?-X?(?P<numb>\d*)",line[0]).group("numb") newQM = QM() - newQM.found_by=placeholder + # newQM.found_by=placeholder newQM.number=QMnum newQM.cave = caveid + newQM.blockname = "" if line[1]=="Dig": newQM.grade="D" else: @@ -94,12 +100,12 @@ def parseCaveQMs(cave,inputFile): newQM.area=line[2] newQM.location_description=line[3] - # Troggle checks if QMs are completed by checking if they have a ticked_off_by trip. + # Troggle will in future (?! - written in 2006) check if QMs are completed by checking if they have a ticked_off_by trip. # In the table, completion is indicated by the presence of a completion discription. newQM.completion_description=line[4] newQM.nearest_station_description=line[5] - if newQM.completion_description: - newQM.ticked_off_by=placeholder + # if newQM.completion_description: + # newQM.ticked_off_by=placeholder newQM.comment=line[6] try: @@ -139,15 +145,16 @@ def parse_KH_QMs(kh, inputFile): if res: res=res.groupdict() year=int(res['year']) + # logbook placeholder code was previously here. No longer needed. #check if placeholder exists for given year, create it if not - message = " ! - "+ str(year) + " logbook: placeholder entry for '161 KH' created. DUMMY EXPEDITION ID. Should be re-attached to the actual trip." - placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, place="161", title="placeholder for QMs in 161", text=message, entry_type="DUMMY", expedition_id=1, defaults={"date": date((year), 1, 1),"cave_slug":str(kh)}) - # if hadToCreate: + # message = " ! - "+ str(year) + " logbook: placeholder entry for '161 KH' created. DUMMY EXPEDITION ID. Should be re-attached to the actual trip." + # placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, place="161", title="placeholder for QMs in 161", text=message, entry_type="DUMMY", expedition_id=1, defaults={"date": date((year), 1, 1),"cave_slug":str(kh)}) + # # if hadToCreate: # print(message) # DataIssue.objects.create(parser='QMs', message=message) lookupArgs={ - # inadequate now that the sequence numbers are not unique for survex-parsed QMs - 'found_by':placeholder, + #'found_by':placeholder, + 'blockname': "", 'expoyear':year, 'number':res['number'], 'cave': kh, @@ -158,10 +165,10 @@ def parse_KH_QMs(kh, inputFile): 'location_description':res['description'] } instance, created = save_carefully(QM,lookupArgs,nonLookupArgs) - if created: - message = " ! - "+ instance.code() + " QM entry for '161 KH' created. " - print(message) - DataIssue.objects.create(parser='QMs', message=message) + # if created: + # message = " ! - "+ instance.code() + " QM entry for '161 KH' created. " + # print(message) + # DataIssue.objects.create(parser='QMs', message=message) nqms += 1 return nqms diff --git a/parsers/survex.py b/parsers/survex.py index fa92924..e4ec8b3 100644 --- a/parsers/survex.py +++ b/parsers/survex.py @@ -532,11 +532,7 @@ class LoadingSurvex(): # we would have to create one. But that is not obligatory and no QMs loaded from CSVs have one # Older troggle/CSV assumes a logbook entry 'found_by' for each QM, with a date. - # We have a date from the survexfile. This is needed for the absolute_url resolution.. - - # We don't know if the survexfile has an associated logbook entry as there is no direct link - # so we create a dummy one anyway. We should make logbook entry links optional in QMs in future and - # remove this hack. + # We don't need this anymore so we don't need to create a placeholder logbook entry. qmyear = str(survexblock.date)[:4] blockname = survexblock.name[:7] logslug = f'D{int(qmyear)}_{blockname}_{int(qm_no):03d}' @@ -548,27 +544,27 @@ class LoadingSurvex(): place = "oops" - message = f' ! - logbook dummy "{logslug}" {str(survexblock.date)[:11]} for cave "{caveslug}" created.' + # message = f' ! - logbook dummy "{logslug}" {str(survexblock.date)[:11]} for cave "{caveslug}" created.' - placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=qmyear, - place=place, - title="placeholder for survex QM", - text=message, - entry_type="DUMMY", - expedition_id=1, - defaults={"date": survexblock.date,"cave_slug":caveslug, "slug": logslug}) + # placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=qmyear, + # place=place, + # title="placeholder for survex QM", + # text=message, + # entry_type="DUMMY", + # expedition_id=1, + # defaults={"date": survexblock.date,"cave_slug":caveslug, "slug": logslug}) # print(insp+message) # DataIssue.objects.create(parser='survex', message=message) try: qm = QM.objects.create(number=qm_no, - # nearest_station=a_survex_station_object, # can be null + # nearest_station=a_survex_station_object, # can be null nearest_station_description=qm_resolve_station, nearest_station_name=qm_nearest, grade=qm_grade.upper(), location_description=qm_notes, blockname = blockname, # only set for survex-imported QMs - found_by = placeholder, + # found_by = placeholder, expoyear = str(survexblock.date.year), cave = survexblock.survexfile.cave) qm.save diff --git a/templates/qm.html b/templates/qm.html index 4bcc25d..a63b903 100644 --- a/templates/qm.html +++ b/templates/qm.html @@ -34,8 +34,8 @@ {% if qm.cave %} <a href="{% url 'caveQMs' qm.cave|safe %}">{{ qm.cave|safe }} QMs</a> <br> {% else %} - {% if qm.found_by.cave %} - <a href="{% url 'caveQMs' qm.found_by.cave|safe %}">{{ qm.found_by.cave|safe }} QMs</a> <br> + {% 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> @@ -49,8 +49,10 @@ <h3>Grade</h3> {{qm.grade}} +{% 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 ticked_off_by %}