From c39fb3070789c19b870603434560e523166abad4 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Wed, 27 Jul 2022 23:22:46 +0300 Subject: [PATCH 01/17] new urls and dummy functions and rename --- core/views/scans.py | 23 +++++++++++++++++++++-- templates/base.html | 2 +- urls.py | 19 ++++++++++++------- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/core/views/scans.py b/core/views/scans.py index 770b925..61d988e 100644 --- a/core/views/scans.py +++ b/core/views/scans.py @@ -20,7 +20,26 @@ by looking inside the file before being served. need to check if inavlid query string is invalid, or produces multiple replies and render a user-friendly error page. ''' - + + +def walletslistyear(request, year): + '''Page which displays a list of all the wallets in a specific year + ''' + if year < 1976 or year > 2050: + return render(request, 'errors/generic.html', {'message': 'Year out of range. Must be between 1976 and 2050'}) + else: + year = str(year) + return render(request, 'errors/generic.html', {'message': 'not implemented yet'}) + +def walletslistcave(request, caveid): + '''Page which displays a list of all the wallets attached to a specific cave, e.g. '1623-204' + ''' + g = GetCaveLookup() + if caveid not in g: + return render(request, 'errors/generic.html', {'message': f'Cave identifier not recognised:"{caveid}"'}) + + return render(request, 'errors/generic.html', {'message': 'not implemented yet'}) + def oldwallet(request, path): '''Now called only for non-standard wallet structures for pre-2000 wallets ''' @@ -59,7 +78,7 @@ def scansingle(request, path, file): return render(request, 'errors/generic.html', {'message': message}) -def allwallets(request): +def allscans(request): '''Returns all the wallets in the system, we would like to use the Django queryset SQL optimisation https://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-related to get the related singlescan and survexblock objects but that requires rewriting this to do the query on those, not on diff --git a/templates/base.html b/templates/base.html index 2661123..8f3f562 100644 --- a/templates/base.html +++ b/templates/base.html @@ -31,7 +31,7 @@ <a href="{% url "survexcavessingle" "359" %}">359</a> | <a href="/survexfile/">Survex</a> | <a href="{% url "survexcaveslist" %}">All Survex</a> | - <a href="{% url "allwallets" %}">Scans</a> | + <a href="{% url "allscans" %}">Scans</a> | <a href="{% url "scanupload" '2022:01' %}">Upload Scans</a> | <a href="{% url "dwgallfiles" %}">Drawings</a> | <a href="{% url "dwgupload" %}">Upload Drawings</a> | diff --git a/urls.py b/urls.py index e02c4f0..7dba6f6 100644 --- a/urls.py +++ b/urls.py @@ -8,7 +8,7 @@ from django.contrib import auth from django.urls import path, reverse, resolve from troggle.core.views import statistics, survex -from troggle.core.views.scans import scansingle, allwallets, cavewallets +from troggle.core.views.scans import scansingle, allscans, cavewallets, walletslistyear, walletslistcave from troggle.core.views.drawings import dwgallfiles, dwgfilesingle from troggle.core.views.uploads import dwgupload, scanupload, photoupload from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage @@ -164,13 +164,18 @@ trogglepatterns = [ path('survexfile/<path:survex_cave>', survex.survexcavesingle, name="survexcavessingle"), -# The survey scans in the wallets. This short-cuts SCANS_URL which is not actually used anywhere! - path('survey_scans/', allwallets, name="allwallets"), - path('survey_scans/<path:path>/', scanupload, name="singlewallet"), # replaced singlewallet() - path('survey_scans/<path:path>/<file>', scansingle, name="scansingle"), # works, but html href goes direct to /expofiles/ too - re_path(r'^cave/scans/(?P<cave_id>[^/]+)$', cavewallets, name="cavewallets"), # like allwallets, but for just one cave +# The survey scans in the wallets. This short-cuts SCANS_URL which is not used anymore and is defunct + path('survey_scans/', allscans, name="allscans"), # all the scans in all wallets + path('survey_scans/<path:path>/', scanupload, name="singlewallet"), # replaced singlewallet() + path('survey_scans/<path:path>/<file>', scansingle, name="scansingle"), # works, but html href goes direct to /expofiles/ too + path('cave/scans/<slug:caveid>', cavewallets, name="cavewallets"), # like allscans, but for just one cave + +# The data about the wallets themselves, not the scans inside tehm + path('wallets/cave/<slug:caveid>', walletslistcave, name="walletslistcave"), # wallets that are for a specific cave, an identifier + path('wallets/year/<int:year>', walletslistyear, name="walletslistyear"), # wallets that are for a specific year, as an integer '1985' -# The tunnel and therion drawings files pages + +# The tunnel and therion drawings files pageswalletslistcave path('dwgfiles', dwgallfiles, name="dwgallfiles"), path('dwgfiles/', dwgallfiles, name="dwgallfiles"), path('dwgdataraw/<path:path>', dwgfilesingle, name="dwgfilesingle"), From 1468c49723347b972f5e5a021e08801772ff354a Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Wed, 27 Jul 2022 23:23:43 +0300 Subject: [PATCH 02/17] remove unused SCANS_URL --- _deploy/wsl/localsettingsWSL.py | 2 +- core/views/statistics.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_deploy/wsl/localsettingsWSL.py b/_deploy/wsl/localsettingsWSL.py index c57a35b..2584732 100644 --- a/_deploy/wsl/localsettingsWSL.py +++ b/_deploy/wsl/localsettingsWSL.py @@ -178,7 +178,7 @@ EXPOWEB = REPOS_ROOT_PATH / "expoweb" CAVEDESCRIPTIONS = EXPOWEB / "cave_data" ENTRANCEDESCRIPTIONS = EXPOWEB / "entrance_data" EXPOWEB_URL = '' -SCANS_URL = '/survey_scans/' +# SCANS_URL = '/survey_scans/' # defunct, removed. # Sanitise these to be strings as all other code is expecting strings # and we have not made the change to pathlib Path type in the other localsettings-* variants yet. diff --git a/core/views/statistics.py b/core/views/statistics.py index 9e7ff81..15858d3 100644 --- a/core/views/statistics.py +++ b/core/views/statistics.py @@ -51,7 +51,7 @@ def pathsreport(request): "SURVEX_DATA" : str( settings.SURVEX_DATA), "SCANS_ROOT" : str( settings.SCANS_ROOT), # "SURVEYS" : str( settings.SURVEYS), - "SCANS_URL" : str( settings.SCANS_URL), +# "SCANS_URL" : str( settings.SCANS_URL), "SURVEXPORT" : str( settings.SURVEXPORT), "DRAWINGS_DATA" : str( settings.DRAWINGS_DATA), "URL_ROOT" : str( settings.URL_ROOT) @@ -88,7 +88,7 @@ def pathsreport(request): "SURVEX_DATA" : type(settings.SURVEX_DATA), "SCANS_ROOT" : type(settings.SCANS_ROOT), # "SURVEYS" : type(settings.SURVEYS), - "SCANS_URL" : type(settings.SCANS_URL), +# "SCANS_URL" : type(settings.SCANS_URL), "SURVEXPORT" : type(settings.SURVEXPORT), "DRAWINGS_DATA" : type(settings.DRAWINGS_DATA), "URL_ROOT" : type(settings.URL_ROOT) From 3d7cb78e4733cb2adcab16fe83c93cbe00665d79 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Wed, 27 Jul 2022 23:24:19 +0300 Subject: [PATCH 03/17] copies all wallet data to drawings repo as backup --- parsers/scans.py | 54 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/parsers/scans.py b/parsers/scans.py index fdded82..c75b7f2 100644 --- a/parsers/scans.py +++ b/parsers/scans.py @@ -1,12 +1,15 @@ import sys import os +import subprocess import types import stat import csv import re import datetime +import shutil, filecmp from functools import reduce +from pathlib import Path import settings from troggle.core.models.survex import SingleScan, Wallet, DrawingFile @@ -18,7 +21,9 @@ from troggle.core.utils import save_carefully, GetListDir contentsjson = "contents.json" indexhtml = "walletindex.html" +git = settings.GIT +# to do: create a 'low priority' field, so that any such wallet does not appear in summary reports wallet_blank_json = { "cave": "", "date": "", @@ -73,7 +78,43 @@ def LoadListScansFile(wallet): if c>=10: print(".", end='') c = 0 +def CopyWalletData(wallet): + '''Copies all the contents.json to a parallel set of folders in the drawings repo + ''' + year = wallet.walletname[0:4] + destfolder = Path(settings.DRAWINGS_DATA,'walletjson', year, wallet.walletname) + destjson = destfolder / contentsjson + sourcejson = Path(wallet.fpath, contentsjson) + if not os.path.exists(Path(destfolder)): + try: + os.makedirs(destfolder) + print(f' - created folder {destfolder}..') + except PermissionError: + print(f"CANNOT save this JSON file.\nPERMISSIONS incorrectly set on server for this folder {destfolder}. Ask a nerd to fix this.") + if os.path.isfile(sourcejson): + try: + if not os.path.isfile(destjson) or not filecmp.cmp(sourcejson, destjson): + shutil.copy(sourcejson, destjson) + print(f' - Copied {sourcejson} to {destjson}') + dr_add = subprocess.run([git, "add", contentsjson], cwd=destfolder, capture_output=True, text=True) + if dr_add.returncode != 0: + msgdata = 'Ask a nerd to fix this.\n\n' + dr_add.stderr + '\n\n' + dr_add.stdout + '\n\nreturn code: ' + str(dr_add.returncode) + message = f'CANNOT git on server for this file {contentsjson}. Edits saved but not added to git.\n\n' + msgdata + print(message) + else: + # ideally we would commit many chnages to many wallets just once. But most of the time only a couple of files will change. + dr_commit = subprocess.run([git, "commit", "-m", f'Update of {contentsjson} in wallet'], cwd=destfolder, capture_output=True, text=True) + # This produces return code = 1 if it commits OK + if dr_commit.returncode != 0: + msgdata = 'Ask a nerd to fix this.\n\n' + dr_commit.stderr + '\n\n' + dr_commit.stdout + '\n\nreturn code: ' + str(dr_commit.returncode) + message = f'Error code with git on server for this {contentsjson}. File is copied, added to git, but NOT committed.\n\n' + msgdata + print(message) + except PermissionError: + print(f"CANNOT copy this JSON file.\nPERMISSIONS incorrectly set on server for this file {destjson}. Ask a nerd to fix this.") + + + # this iterates through the scans directories (either here or on the remote server) # and builds up the models we can access later @@ -109,17 +150,18 @@ def load_all_scans(): if fisdir: wallet = Wallet(fpath=fpath, walletname=walletname) # this is where we should load the contents.json for people so we can report on them later - # this is where we shoudl record the year explicitly + # this is where we should record the year explicitly # line 347 of view/uploads.py and needs refactoring for loading contentsjson wallet.save() LoadListScansFile(wallet) + CopyWalletData(wallet) # what is this? - elif walletname != "thumbs": - print(f'\n - Wallet {walletname} - {fpath}') - wallet = Wallet(fpath=fpath, walletname=walletname) - wallet.save() - LoadListScansFile(wallet) + # elif walletname != "thumbs": + # print(f'\n - Wallet {walletname} - {fpath}') + # wallet = Wallet(fpath=fpath, walletname=walletname) + # wallet.save() + # LoadListScansFile(wallet) else: print(f'\n - IGNORE {walletname} - {fpath}') From dd0fcc28ddc4768fb8fa3edcec32ee205d77101b Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Wed, 27 Jul 2022 23:24:40 +0300 Subject: [PATCH 04/17] update todo strings --- core/forms.py | 2 +- parsers/caves.py | 13 +++---------- parsers/survex.py | 1 - 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/core/forms.py b/core/forms.py index f3df10a..9dd01db 100644 --- a/core/forms.py +++ b/core/forms.py @@ -18,7 +18,7 @@ There are other, simpler, upload forms in view/uploads.py Some are not used and need renovating or destroying. ''' -todo = '''Re-enable TinyMCE +todo = ''' ''' class CaveForm(ModelForm): diff --git a/parsers/caves.py b/parsers/caves.py index 3549c75..bc2bfbc 100644 --- a/parsers/caves.py +++ b/parsers/caves.py @@ -13,23 +13,16 @@ from troggle.core.models.caves import Area, Cave, Entrance, CaveSlug, EntranceSl '''Reads all the cave description data by parsing the xml files (stored as e.g. :EXPOWEB:/cave_data/1623-161.html ) and creating the various Cave, Entrance and necessary Area objects. -This is the first import that happens after the dabase is reinitialised. +This is the first import that happens after the database is reinitialised. So is the first thing that creates tables. -BUT in Django 2.0 and later we cannot do any queries on data we have just entered -because this is all happening inside one transaction. Bummer. - -django.db.transaction.TransactionManagementError: -An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block. ''' -todo='''- db Update does not work when a cave id is in the pending list but a proper cave description file exists - and is being imported. It should work. But currently Django aborts and he file is not read in. - +todo=''' - Cannot use Edit This Page for pendingcaves.txt_edit as Edit This Page is expecting an html file. So we will need a separate file-editing capability just for this configuration file ?! -- crashes on MariaDB on server when deleting Caves and complains Area needs a non null parent, But this is not true. +- crashes on MariaDB in databasereset.py on server when deleting Caves and complains Area needs a non null parent, But this is not true. The only solution we have found is to let it crash, then stop and restart MariaDB (requires a logon able to sudo) and then restart the databasereset.py again. (status as of July 2022) ''' diff --git a/parsers/survex.py b/parsers/survex.py index 7b94005..615019d 100644 --- a/parsers/survex.py +++ b/parsers/survex.py @@ -37,7 +37,6 @@ todo = '''Also walk the entire tree in the :loser: repo looking for unconnected - LoadSurvexFile() Creates a new current survexfile and valid .survexdirectory The survexblock passed-in is not necessarily the parent. FIX THIS. -- rx_qm recognises only simple survey point ids. EXTEND to cover more naming formats and test fully for 2023 ''' survexblockroot = None ROOTBLOCK = "rootblock" From fea69c03717d700192d7a5a5afc4c27a654a923f Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Thu, 28 Jul 2022 01:48:22 +0300 Subject: [PATCH 05/17] Extend wallets by cave report --- core/models/caves.py | 10 ++++++++-- core/models/survex.py | 34 ++++++++++++++++++++++++++++++-- core/utils.py | 4 ++++ core/views/scans.py | 40 +++++++++++++++----------------------- core/views/uploads.py | 2 +- parsers/drawings.py | 2 +- templates/cavewallets.html | 31 ++++++++++++++++++----------- templates/dwgfiles.html | 2 +- urls.py | 3 +-- 9 files changed, 84 insertions(+), 44 deletions(-) diff --git a/core/models/caves.py b/core/models/caves.py index 8cd658c..f5ae320 100644 --- a/core/models/caves.py +++ b/core/models/caves.py @@ -26,6 +26,14 @@ from django.shortcuts import render from troggle.core.models.troggle import TroggleModel, Person, Expedition, DataIssue from troggle.core.models.survex import SurvexStation from troggle.core.utils import writetrogglefile +from troggle.core.utils import TROG + +# Us ethe TROG global object to cache teh cave lookup list +Gcavelookup = TROG['caves']['gcavelookup'] +Gcave_count = TROG['caves']['gcavecount'] + +Gcavelookup = None +Gcave_count = None '''The model declarations for Areas, Caves and Entrances. Also LogBookENtry, QM, PersonTrip ''' @@ -564,8 +572,6 @@ class PersonTrip(TroggleModel): return f'{self.personexpedition} ({self.logbook_entry.date})' -Gcavelookup = None -Gcave_count = None def GetCaveLookup(): """A very relaxed way of finding probably the right cave given almost any string which might serve to identify it diff --git a/core/models/survex.py b/core/models/survex.py index 1273a8b..9746afb 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -1,6 +1,8 @@ import os -from urllib.parse import urljoin import re +import json +from urllib.parse import urljoin +from pathlib import Path from django.db import models from django.conf import settings @@ -160,6 +162,9 @@ class SurvexPersonRole(models.Model): return str(self.person) + " - " + str(self.survexblock) class Wallet(models.Model): + '''We do not keep the JSON values in the database, we query them afresh each time, + but we will change this when we need to do a Django query on e.g. personame + ''' fpath = models.CharField(max_length=200) walletname = models.CharField(max_length=200) @@ -169,6 +174,31 @@ class Wallet(models.Model): def get_absolute_url(self): return urljoin(settings.URL_ROOT, reverse('singlewallet', kwargs={"path":re.sub("#", "%23", self.walletname)})) + def get_json(self): + jsonfile = Path(self.fpath, 'contents.json') + if not Path(jsonfile).is_file(): + print(f'{jsonfile} is not a file') + return None + else: + with open(jsonfile) as json_f: + try: + waldata = json.load(json_f) + except: + wurl = f"/scanupload/{self.walletname}" # .replace('#', ':') + message = f"! {str(self.walletname)} Failed to load {jsonfile} JSON file" + print(message) + raise + + return waldata + + def date(self): + jsondata = self.get_json() + return jsondata["date"] + + def name(self): + jsondata = self.get_json() + return jsondata["name"] + def __str__(self): return str(self.walletname) + " (Wallet)" @@ -189,7 +219,7 @@ class SingleScan(models.Model): class DrawingFile(models.Model): dwgpath = models.CharField(max_length=200) dwgname = models.CharField(max_length=200) - manywallets = models.ManyToManyField("Wallet") # implicitly links via folders to scans to SVX files + dwgwallets = models.ManyToManyField("Wallet") # implicitly links via folders to scans to SVX files scans = models.ManyToManyField("SingleScan") # implicitly links via scans to SVX files dwgcontains = models.ManyToManyField("DrawingFile") # case when its a frame type filesize = models.IntegerField(default=0) diff --git a/core/utils.py b/core/utils.py index 9aa4679..5b696dd 100644 --- a/core/utils.py +++ b/core/utils.py @@ -42,6 +42,10 @@ TROG = { }, 'issues' : { 'logdataissues' : {} + }, + 'caves' : { + 'gcavelookup' : {}, + 'gcavecount' : {} } } diff --git a/core/views/scans.py b/core/views/scans.py index 61d988e..7d933c7 100644 --- a/core/views/scans.py +++ b/core/views/scans.py @@ -29,16 +29,23 @@ def walletslistyear(request, year): return render(request, 'errors/generic.html', {'message': 'Year out of range. Must be between 1976 and 2050'}) else: year = str(year) - return render(request, 'errors/generic.html', {'message': 'not implemented yet'}) + return render(request, 'errors/generic.html', {'message': 'This page logic not implemented yet'}) -def walletslistcave(request, caveid): - '''Page which displays a list of all the wallets attached to a specific cave, e.g. '1623-204' + +def cavewallets(request, caveid): + '''Returns all the wallets for just one cave ''' - g = GetCaveLookup() - if caveid not in g: - return render(request, 'errors/generic.html', {'message': f'Cave identifier not recognised:"{caveid}"'}) - - return render(request, 'errors/generic.html', {'message': 'not implemented yet'}) + Gcavelookup = GetCaveLookup() + if caveid in Gcavelookup: + cave = Gcavelookup[caveid] + else: + return render(request,'errors/badslug.html', {'badslug': caveid}) + + # remove duplication. SOrting is done in the template + wallets = set(Wallet.objects.filter(survexblock__survexfile__cave=cave)) # NB a filtered set + manywallets = list(wallets) + + return render(request, 'cavewallets.html', { 'manywallets':manywallets, 'settings': settings, 'cave': cave}) def oldwallet(request, path): '''Now called only for non-standard wallet structures for pre-2000 wallets @@ -84,22 +91,7 @@ def allscans(request): to get the related singlescan and survexblock objects but that requires rewriting this to do the query on those, not on the wallets ''' - manywallets = Wallet.objects.all() + manywallets = Wallet.objects.all() # NB all of them # manywallets = Wallet.objects.all().prefetch_related('singlescan') fails as the link is defined on 'singlescan' not on 'wallet' return render(request, 'manywallets.html', { 'manywallets':manywallets, 'settings': settings }) -def cavewallets(request, cave_id): - '''Returns all the wallets for just one cave, - ''' - - Gcavelookup = GetCaveLookup() - if cave_id in Gcavelookup: - cave = Gcavelookup[cave_id] - else: - return render(request,'errors/badslug.html', {'badslug': cave_id}) - - # remove duplication. SOrting is done in the template - wallets = set(Wallet.objects.filter(survexblock__survexfile__cave=cave)) - manywallets = list(wallets) - - return render(request, 'cavewallets.html', { 'manywallets':manywallets, 'settings': settings, 'cave': cave}) diff --git a/core/views/uploads.py b/core/views/uploads.py index b275d2a..62ed56e 100644 --- a/core/views/uploads.py +++ b/core/views/uploads.py @@ -93,7 +93,7 @@ xlate = {"url": "description url", "electronic": "electronic survey", "pland": "plan drawn", "elevd": "elev drawn", - "psg": "name", + "psg": "name", # not real ? "survex": "survex file", } diff --git a/parsers/drawings.py b/parsers/drawings.py index 88a6ca3..4b3e44d 100644 --- a/parsers/drawings.py +++ b/parsers/drawings.py @@ -50,7 +50,7 @@ def find_dwg_file(dwgfile, path): scansfile = scansfilel[0] if wallet: - dwgfile.manywallets.add(wallet) + dwgfile.dwgwallets.add(wallet) if scansfile: dwgfile.scans.add(scansfile) diff --git a/templates/cavewallets.html b/templates/cavewallets.html index 2cbce29..509ca9f 100644 --- a/templates/cavewallets.html +++ b/templates/cavewallets.html @@ -4,29 +4,38 @@ {% block content %} -<h3>Survey scans folders (wallets) for <a href="/{{cave.url}}">{{cave}}</a></h3> +<h3>Wallets for <a href="/{{cave.url}}">{{cave}}</a> {{cave.official_name|safe}}</h3> <p>Each wallet contains the scanned original in-cave survey notes and sketches of plans and elevations. It also contains scans of centre-line survex output on which hand-drawn passage sections are drawn. These hand-drawn passages will eventually be traced to produce Tunnel or Therion drawings and eventually the final complete cave survey. +<p>This lists all the files in a wallet, some of which may not be for this specific cave. <table width=95%> -<tr><th>Scans folder</th><th>Files</th><th>Survex blocks</th><th>Cave</th></tr> -{% for scanswallet in manywallets|dictsort:"walletname" %} +<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>Scans</th><th>Survex blocks</th><th>Survex dates</th><th>Drawings using these scans</th></tr> +{% for wallet in manywallets|dictsort:"walletname" %} <tr> - <td style="padding:2px"><a href="{{scanswallet.get_absolute_url}}">{{scanswallet.walletname}}</a></td> - <td align="right" style="padding:2px">{{scanswallet.singlescan_set.all|length}}</td> + <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> + + <td style="padding:2px">{{wallet.date}}</td> + <td style="padding:2px">{{wallet.name}}</td> + + <td align="right" style="padding:2px">{{wallet.singlescan_set.all|length}}</td> <td style="padding:2px"> - {% for survexblock in scanswallet.survexblock_set.all %} + {% for survexblock in wallet.survexblock_set.all %} <a href="{% url "svx" survexblock.survexfile.path %}">{{survexblock}}</a> {% endfor %} </td> <td style="padding:2px"> - {% for survexblock in scanswallet.survexblock_set.all %} - {% ifchanged survexblock.survexfile.cave %} - <a href="/{{survexblock.survexfile.cave.url}}">/{{survexblock.survexfile.cave.slug}}</a> - {% endifchanged %} - + {% for survexblock in wallet.survexblock_set.all %} + {{survexblock.date}} + {% endfor %} + </td> + <td style="padding:2px"> + {% for drawing in wallet.drawingfile_set.all %} + <a href="{% url "dwgfilesingle" drawing.dwgpath %}">{{drawing.dwgpath}}</a><br> + {% empty %} + (no Tunnel drawings found: but there might be Therion drawings) {% endfor %} </td> </tr> diff --git a/templates/dwgfiles.html b/templates/dwgfiles.html index 6367ad2..48f236d 100644 --- a/templates/dwgfiles.html +++ b/templates/dwgfiles.html @@ -13,7 +13,7 @@ <td align="right" style="padding:2px">{{dwgfile.npaths}}</td> <td style="padding:2px"> - {% for scanswallet in dwgfile.manywallets.all %} + {% for scanswallet in dwgfile.dwgwallets.all %} <a href="{{scanswallet.get_absolute_url}}">{{scanswallet.walletname}}</a> {% endfor %} </td> diff --git a/urls.py b/urls.py index 7dba6f6..d43ac7e 100644 --- a/urls.py +++ b/urls.py @@ -8,7 +8,7 @@ from django.contrib import auth from django.urls import path, reverse, resolve from troggle.core.views import statistics, survex -from troggle.core.views.scans import scansingle, allscans, cavewallets, walletslistyear, walletslistcave +from troggle.core.views.scans import scansingle, allscans, cavewallets, walletslistyear from troggle.core.views.drawings import dwgallfiles, dwgfilesingle from troggle.core.views.uploads import dwgupload, scanupload, photoupload from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage @@ -171,7 +171,6 @@ trogglepatterns = [ path('cave/scans/<slug:caveid>', cavewallets, name="cavewallets"), # like allscans, but for just one cave # The data about the wallets themselves, not the scans inside tehm - path('wallets/cave/<slug:caveid>', walletslistcave, name="walletslistcave"), # wallets that are for a specific cave, an identifier path('wallets/year/<int:year>', walletslistyear, name="walletslistyear"), # wallets that are for a specific year, as an integer '1985' From 9a461c31a882b544b3707e308f6c65ad29784625 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Thu, 28 Jul 2022 02:37:44 +0300 Subject: [PATCH 06/17] adding people --- core/models/survex.py | 4 ++++ templates/cavewallets.html | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/models/survex.py b/core/models/survex.py index 9746afb..29241f9 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -195,6 +195,10 @@ class Wallet(models.Model): jsondata = self.get_json() return jsondata["date"] + def people(self): + jsondata = self.get_json() + return jsondata["people"] + def name(self): jsondata = self.get_json() return jsondata["name"] diff --git a/templates/cavewallets.html b/templates/cavewallets.html index 509ca9f..49a36e3 100644 --- a/templates/cavewallets.html +++ b/templates/cavewallets.html @@ -12,13 +12,14 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <p>This lists all the files in a wallet, some of which may not be for this specific cave. <table width=95%> -<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>Scans</th><th>Survex blocks</th><th>Survex dates</th><th>Drawings using these scans</th></tr> +<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Scans</th><th>Survex blocks</th><th>Survex dates</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} <tr> <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> <td style="padding:2px">{{wallet.date}}</td> <td style="padding:2px">{{wallet.name}}</td> + <td style="padding:2px">{{wallet.people}}</td> <td align="right" style="padding:2px">{{wallet.singlescan_set.all|length}}</td> <td style="padding:2px"> From 93622b111f4a7136033ccf844a7e03a4093cb336 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Thu, 28 Jul 2022 15:15:11 +0300 Subject: [PATCH 07/17] obscure bug fixed for lines ;*include --- core/models/survex.py | 2 +- parsers/survex.py | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/core/models/survex.py b/core/models/survex.py index 29241f9..d8a5fb5 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -20,7 +20,7 @@ class SurvexDirectory(models.Model): verbose_name_plural = "Survex directories" def __str__(self): - return "[SurvexDirectory:"+str(self.path) + "-" + str(self.primarysurvexfile.path) + "-" + str(self.cave)+"]" + return "[SurvexDirectory:"+str(self.path) + " | Primary svx:" + str(self.primarysurvexfile.path) +".svx ]" class SurvexFile(models.Model): diff --git a/parsers/survex.py b/parsers/survex.py index 615019d..5eee625 100644 --- a/parsers/survex.py +++ b/parsers/survex.py @@ -130,8 +130,8 @@ class LoadingSurvex(): rx_cave = re.compile(r'(?i)caves-(\d\d\d\d)/([-\d\w]+|\d\d\d\d-?\w+-\d+)') rx_comment = re.compile(r'([^;]*?)\s*(?:;\s*(.*))?\n?$') - rx_comminc = re.compile(r'(?i)^\*include[\s]*([-\w/]*).*$') # inserted by linear collate ;*include - rx_commcni = re.compile(r'(?i)^\*edulcni[\s]*([-\w/]*).*$') # inserted by linear collate ;*edulcni + rx_comminc = re.compile(r'(?i)^\|\*include[\s]*([-\w/]*).*$') # inserted by linear collate ;*include + rx_commcni = re.compile(r'(?i)^\|\*edulcni[\s]*([-\w/]*).*$') # inserted by linear collate ;*edulcni rx_include = re.compile(r'(?i)^\s*(\*include[\s].*)$') rx_commref = re.compile(r'(?i)^\s*ref(?:erence)?[\s.:]*(\d+)\s*#\s*(X)?\s*(\d+)') rx_wallet = re.compile(r'(?i)^\s*wallet[\s.:]*(\d+)\s*#\s*(X)?\s*(\d+)') @@ -177,7 +177,7 @@ class LoadingSurvex(): callcount = 0 caverncount = 0 ignoreprefix = ["surface", "kataster", "fixedpts", "gpx"] - ignorenoncave = ["caves-1623", "caves-1623/2007-neu"] + ignorenoncave = ["caves-1623", "caves-1626", "caves-1623/2007-neu"] includedfilename ="" currentsurvexblock = None currentsurvexfile = None @@ -689,9 +689,7 @@ class LoadingSurvex(): def IdentifyCave(self, cavepath): if cavepath.lower() in self.caveslist: return self.caveslist[cavepath.lower()] - # TO DO - some of this is already done in generating self.caveslist so simplify this - # esp. as it is in a loop. - # TO DO recognise cave if different name, e.g. gruenstein == 281 + # TO DO - this predates the big revision to Gcavelookup so look at this again carefully path_match = self.rx_cave.search(cavepath) if path_match: sluggy = '{}-{}'.format(path_match.group(1), path_match.group(2)) @@ -724,17 +722,17 @@ class LoadingSurvex(): """Ignore surface, kataser and gpx *include survex files """ if headpath in self.ignorenoncave: - #message = f" - {headpath} is <ignorenoncave> (while creating '{includelabel}' sfile & sdirectory)" + message = f" - {headpath} is <ignorenoncave> (while creating '{includelabel}' sfile & sdirectory)" #print("\n"+message) #print("\n"+message,file=sys.stderr) return for i in self.ignoreprefix: if headpath.startswith(i): message = f" - {headpath} starts with <ignoreprefix> (while creating '{includelabel}' sfile & sdirectory)" - #print("\n"+message) - #print("\n"+message,file=sys.stderr) + # print("\n"+message) + # print("\n"+message,file=sys.stderr) return - message = f" ! Error: FAILURE '{headpath}' while creating '{includelabel}' at depth:[{depth}]. Not a cave or in the ignore list:'{self.ignoreprefix}'" + message = f" ! Error: not a cave nor ignorable. headpath:'{headpath}' while creating '{includelabel=}' at depth:[{len(depth)}]. ignore prefix list:'{self.ignoreprefix}'" # getting this triggered for gpx/2018 (cavern error) but not for gpx/2017 (no content). print("\n"+message) print("\n"+message,file=sys.stderr) @@ -779,7 +777,7 @@ class LoadingSurvex(): if cave: newdirectory.cave = cave newfile.cave = cave - # print(f"\n - New directory {newdirectory} for cave {newdirectory.cave}",file=sys.stderr) + # print(f"\n - New directory '{newdirectory}' for cave '{cave}'",file=sys.stderr) else: # probably a surface survey, or a cave in a new area e.g. 1624 not previously managed, and not in the pending list self.ReportNonCaveIncludes(headpath, svxid, depth) @@ -861,6 +859,7 @@ class LoadingSurvex(): included = self.rx_comminc.match(comment) # ;*include means 'we have been included'; whereas *include means 'proceed to include' + # bug, If the original survex file contians the line ;*include then we pick it up ! So fix our special code to be ;|*include if included: self.ProcessIncludeLine(included) @@ -1210,7 +1209,7 @@ class LoadingSurvex(): #-------------------------------------------------------- self.depthinclude += 1 fininclude = open(fullpath,'r') - fcollate.write(";*include {}\n".format(includepath)) + fcollate.write(";|*include {}\n".format(includepath)) flinear.write("{:2} {} *include {}\n".format(self.depthinclude, indent, includepath)) push = includepath.lower() self.includestack.append(push) @@ -1225,7 +1224,7 @@ class LoadingSurvex(): print(message,file=sys.stderr) DataIssue.objects.create(parser='survex', message=message, url=get_offending_filename(path)) flinear.write("{:2} {} *edulcni {}\n".format(self.depthinclude, indent, pop)) - fcollate.write(";*edulcni {}\n".format(pop)) + fcollate.write(";|*edulcni {}\n".format(pop)) fininclude.close() self.depthinclude -= 1 #-------------------------------------------------------- From c29e240c2b6f3ced17bdd42de107215431c7d19d Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Thu, 28 Jul 2022 18:36:40 +0300 Subject: [PATCH 08/17] creating new wallet now copies nd commits --- core/views/uploads.py | 36 ++++++++++++++++++++++++++---------- parsers/scans.py | 2 ++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/core/views/uploads.py b/core/views/uploads.py index 62ed56e..500e4bd 100644 --- a/core/views/uploads.py +++ b/core/views/uploads.py @@ -23,12 +23,12 @@ from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned #from troggle import settings from troggle.parsers.imports import import_caves, import_people, import_surveyscans from troggle.parsers.imports import import_logbooks, import_QMs, import_drawingsfiles, import_survex -from troggle.parsers.scans import wallet_blank_json, wallet_blank_html, contentsjson, indexhtml +from troggle.parsers.scans import wallet_blank_json, wallet_blank_html, contentsjson, indexhtml, CopyWalletData # from databaseReset import reinit_db # don't do this. databaseRest runs code *at import time* from troggle.core.models.troggle import DataIssue from troggle.core.models.troggle import Expedition, Person, PersonExpedition from troggle.core.models.caves import LogbookEntry, QM, Cave, PersonTrip -from troggle.core.models.survex import DrawingFile +from troggle.core.models.survex import DrawingFile, Wallet from troggle.core.views.scans import oldwallet, walletindex from troggle.core.views.caves import getCave @@ -93,7 +93,7 @@ xlate = {"url": "description url", "electronic": "electronic survey", "pland": "plan drawn", "elevd": "elev drawn", - "psg": "name", # not real ? + "psg": "name", # a name for this wallet "survex": "survex file", } @@ -115,13 +115,14 @@ def get_complaints(complaints, waldata, svxfiles, files, wallet, wurl): if not type(waldata["survex file"])==list: # a string also is a sequence type, so do it this way waldata["survex file"] = [waldata["survex file"]] for svx in waldata["survex file"]: - svxfiles.append(svx) - if not (Path(settings.SURVEX_DATA) / svx).is_file(): - file_complaint = f"{wallet} Incorrect survex file name in wallet data: {svx} not found in LOSER repo" - complaints.append(file_complaint) - message = f"! {file_complaint}" - print(message) - DataIssue.objects.create(parser='scans', message=message, url=wurl) # set URL to this wallet folder + if svx !="": + svxfiles.append(svx) + if not (Path(settings.SURVEX_DATA) / svx).is_file(): + file_complaint = f"{wallet} Incorrect survex file name in wallet data: {svx} not found in LOSER repo" + complaints.append(file_complaint) + message = f"! {file_complaint}" + print(message) + DataIssue.objects.create(parser='scans', message=message, url=wurl) # set URL to this wallet folder if waldata["survex not required"] and waldata["survex file"] != "": survex_complaint = "Survex is stated as not required and yet there is a survex file!" @@ -290,6 +291,21 @@ def scanupload(request, path=None): with open(contents_path, "w") as jfile: json.dump(wd, jfile, indent = 1) # print(f'--- FINISHED saving to JSON\n') + + # This copies the new data to the drawings repo and commit it + # needs the troggle object wallet, not a string + + try: + w, created = Wallet.objects.get_or_create(walletname=wallet) + print(f'wallet string {wallet}, wallet object {w} created new?: {created}') + if created: + w.fpath = Path(settings.SCANS_ROOT, wallet[0:4], wallet) + w.save() + CopyWalletData(w) + except: + print(f'wallet string {wallet}, FAIL TO GET WALLET OBJECT, maybe we need to create it ?') + raise + else: print(f'--- INVALID JSON Update form submitted') print(formj.errors) diff --git a/parsers/scans.py b/parsers/scans.py index c75b7f2..8b8f92f 100644 --- a/parsers/scans.py +++ b/parsers/scans.py @@ -80,6 +80,8 @@ def LoadListScansFile(wallet): c = 0 def CopyWalletData(wallet): '''Copies all the contents.json to a parallel set of folders in the drawings repo + refreshes everything during a ful import, but it shoudl all be up to date as every time + wallet data gets saved it should also be copied across and committed. ''' year = wallet.walletname[0:4] destfolder = Path(settings.DRAWINGS_DATA,'walletjson', year, wallet.walletname) From 7872e98cb2a8f8b087afab4c7a93d5ba71624fd2 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Thu, 28 Jul 2022 18:36:57 +0300 Subject: [PATCH 09/17] fixing pending caves system to be cleaner --- parsers/caves.py | 55 ++++++++++++++++++++++++++++------------------- parsers/survex.py | 22 ++++++++++++++++--- 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/parsers/caves.py b/parsers/caves.py index bc2bfbc..9d95f32 100644 --- a/parsers/caves.py +++ b/parsers/caves.py @@ -84,6 +84,15 @@ def do_pending_cave(k, url, area): in expoweb/cave_data/1623-"k".html ''' slug = k + + g = GetCaveLookup() + if slug in g: + message = f" ! {k} cave listed in pendingcaves.txt already exists." + DataIssue.objects.create(parser='caves', message=message, url=url) + print(message) + return + + default_note = f"_Survex file found in loser repo but no description in expoweb <br><br><br>\n" default_note += f"INSTRUCTIONS: First open 'This survex file' (link above the CaveView panel) to find the date and info. Then " @@ -111,7 +120,7 @@ def do_pending_cave(k, url, area): cave = Cave( unofficial_number = k, underground_description = "Pending cave write-up - creating as empty object. No XML file available yet.", - survex_file = f"caves-{area.short_name}/{k}/{k}.svx", + survex_file = f"caves-{area.short_name}/{k[5:]}/{k[5:]}.svx", url = url, notes = default_note) if cave: @@ -458,27 +467,6 @@ def readcaves(): print(" - Saving Area 1626") area_1626.save() - print (" - Setting pending caves") - # Do this first, so that these empty entries are overwritten as they get properly created. - - for k in pending: - - area = area_1623 - areanum = k[0:4] - url = areanum + "/" + k[5:] # Note we are not appending the .htm as we are modern folks now. - if areanum == "1623": - area = area_1623 - if areanum == "1624": - area = area_1624 - if areanum == "1626": - area = area_1626 - try: - do_pending_cave(k[5:], url, area) - except: - message = f" ! Error. Cannot create pending cave and entrance, pending-id:{k} in area {areanum}" - DataIssue.objects.create(parser='caves', message=message) - print(message) - raise with transaction.atomic(): print(" - settings.CAVEDESCRIPTIONS: ", CAVEDESCRIPTIONS) @@ -498,4 +486,27 @@ def readcaves(): print (" - Setting up all the variously useful alias names") mycavelookup = GetCaveLookup() + + print (" - Setting pending caves") + # Do this last, so we can detect if they are created and no longer 'pending' + + for k in pending: + + area = area_1623 + areanum = k[0:4] + url = areanum + "/" + k[5:] # Note we are not appending the .htm as we are modern folks now. + if areanum == "1623": + area = area_1623 + if areanum == "1624": + area = area_1624 + if areanum == "1626": + area = area_1626 + try: + do_pending_cave(k, url, area) + except: + message = f" ! Error. Cannot create pending cave and entrance, pending-id:{k} in area {areanum}" + DataIssue.objects.create(parser='caves', message=message) + print(message) + raise + diff --git a/parsers/survex.py b/parsers/survex.py index 5eee625..39d42dc 100644 --- a/parsers/survex.py +++ b/parsers/survex.py @@ -184,6 +184,7 @@ class LoadingSurvex(): currentcave = None caverndate = None currentpersonexped = [] + pending = [] def __init__(self): self.caveslist = GetCaveLookup() @@ -721,6 +722,15 @@ class LoadingSurvex(): def ReportNonCaveIncludes(self, headpath, includelabel, depth): """Ignore surface, kataser and gpx *include survex files """ + if not self.pending: + self.pending = set() + fpending = Path(settings.CAVEDESCRIPTIONS, "pendingcaves.txt") + if fpending.is_file(): + with open(fpending, "r") as fo: + cids = fo.readlines() + for cid in cids: + self.pending.add(cid.rstrip('\n').upper()) + if headpath in self.ignorenoncave: message = f" - {headpath} is <ignorenoncave> (while creating '{includelabel}' sfile & sdirectory)" #print("\n"+message) @@ -732,20 +742,26 @@ class LoadingSurvex(): # print("\n"+message) # print("\n"+message,file=sys.stderr) return - message = f" ! Error: not a cave nor ignorable. headpath:'{headpath}' while creating '{includelabel=}' at depth:[{len(depth)}]. ignore prefix list:'{self.ignoreprefix}'" - # getting this triggered for gpx/2018 (cavern error) but not for gpx/2017 (no content). + caveid = f'{headpath[6:10]}-{headpath[11:]}'.upper() + if caveid in self.pending: + # Yes we didn't find this cave, but we know it is a pending one. So not an error. + # print(f'! ALREADY PENDING {caveid}',file=sys.stderr) + return + + message = f" ! Error: not a cave nor ignorable. headpath:'{headpath}' while parsing '{includelabel=}.svx' at depth:[{len(depth)}]. ignore prefix list:'{self.ignoreprefix}'" print("\n"+message) print("\n"+message,file=sys.stderr) DataIssue.objects.create(parser='survex', message=message, url=get_offending_filename(headpath)) print(f' # datastack in LoadSurvexFile:{includelabel} type:', end="",file=sys.stderr) for dict in self.datastack: - print(f'{dict["type"].upper()} ', end="",file=sys.stderr) + print(f'<{dict["type"].upper()} >', end="",file=sys.stderr) def LoadSurvexFile(self, svxid): """Creates SurvexFile in the database, and SurvexDirectory if needed with links to 'cave' Creates a new current survexfile and valid .survexdirectory + Inspects the parent folder of the survexfile and uses that to decide if this is a cave we know The survexblock passed-in is not necessarily the parent. FIX THIS. """ if debugprint: From bc3da1182bf82ce59b0195ea0496ca123c544438 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Fri, 29 Jul 2022 17:49:07 +0300 Subject: [PATCH 10/17] starting jsn population when we know the data --- parsers/scans.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/parsers/scans.py b/parsers/scans.py index 8b8f92f..b78f76f 100644 --- a/parsers/scans.py +++ b/parsers/scans.py @@ -59,6 +59,22 @@ wallet_blank_html = '''<html><body><H1>Wallet WALLET</H1> </UL> </body></html> ''' + +def CheckEmptyDate(wallet): + '''If date is not set, get it from a linked survex file. If several, pick the earliest. + + Maybe also look at filedates for the scans in expofiles/surveyscans/ , but these can be re-set by copying. + ''' + return + +def CheckEmptyPeople(wallet): + '''If people list is empty, copy them from the survex files: all of them + + To be a Troggle model change; a many:many relationship between wallets and people, + as well as being a list in the JSON file (which is the permanent repository). We want the many:many + relationship so that we can filter wallets based on a person. + ''' + return def LoadListScansFile(wallet): gld = [ ] @@ -156,6 +172,8 @@ def load_all_scans(): # line 347 of view/uploads.py and needs refactoring for loading contentsjson wallet.save() LoadListScansFile(wallet) + CheckEmptyDate(wallet) + CheckEmptyPeople(wallet) CopyWalletData(wallet) # what is this? From 724234949f1770645b0f8c34221ae16b0615daf3 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Fri, 29 Jul 2022 20:55:19 +0300 Subject: [PATCH 11/17] Populate blank wallet fields with survex data --- core/models/survex.py | 7 ++++- core/views/scans.py | 63 ++++++++++++++++++++++++++++++++++++-- templates/cavewallets.html | 9 ++---- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/core/models/survex.py b/core/models/survex.py index d8a5fb5..79a645e 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -191,6 +191,7 @@ class Wallet(models.Model): return waldata + # Yes this is horribly, horribly inefficient, esp. for a page that have date, people and cave in it def date(self): jsondata = self.get_json() return jsondata["date"] @@ -199,12 +200,16 @@ class Wallet(models.Model): jsondata = self.get_json() return jsondata["people"] + def cave(self): + jsondata = self.get_json() + return jsondata["cave"] + def name(self): jsondata = self.get_json() return jsondata["name"] def __str__(self): - return str(self.walletname) + " (Wallet)" + return "[" + str(self.walletname) + " (Wallet)]" class SingleScan(models.Model): ffile = models.CharField(max_length=200) diff --git a/core/views/scans.py b/core/views/scans.py index 7d933c7..fda3d6d 100644 --- a/core/views/scans.py +++ b/core/views/scans.py @@ -1,5 +1,6 @@ import os, stat import re +import datetime from pathlib import Path from urllib.parse import urljoin, unquote as urlunquote from urllib.request import urlopen @@ -8,7 +9,7 @@ from django.conf import settings from django.shortcuts import render from django.http import HttpResponse -from troggle.core.models.survex import Wallet, SingleScan +from troggle.core.models.survex import Wallet, SingleScan, SurvexBlock from troggle.core.models.caves import GetCaveLookup from troggle.core.views.expo import getmimetype #import parsers.surveys @@ -21,9 +22,43 @@ need to check if inavlid query string is invalid, or produces multiple replies and render a user-friendly error page. ''' +def populatewallet(w): + '''Copy survex data here just for display, not permanently + ''' + # {% for personrole in wallet.survexblock.survexpersonrole_set.all %} + # {% if personrole.personexpedition %} + # <a href="{{personrole.personexpedition.get_absolute_url}}">{{personrole.personname}}</a> + # {% else %} + # {{personrole.personname}} + # {% endif %} + # {% endfor %} + + survexpeople = [] + blocks = SurvexBlock.objects.filter(scanswallet = w) + for b in blocks: + for personrole in b.survexpersonrole_set.all(): + survexpeople.append(personrole.personname) + w.people = list(set(survexpeople)) # remove duplicates + +def datewallet(w, earliest): + blocks = SurvexBlock.objects.filter(scanswallet = w) + for b in blocks: + if b.date < earliest: + earliest = b.date + w.date = earliest + +def caveifywallet(w): + print('*') + blocks = SurvexBlock.objects.filter(scanswallet = w) + for b in blocks: + # NB b.cave is not populated by parser. Use b.survexfile.cave instead, or we could parse b.survexpath + if b.survexfile.cave: + w.cave = b.survexfile.cave # just gets the last one, randomly + print(w.cave) + def walletslistyear(request, year): - '''Page which displays a list of all the wallets in a specific year + '''Page which displays a list of all the wallets in a specific year - TO BE WRITTEN ''' if year < 1976 or year > 2050: return render(request, 'errors/generic.html', {'message': 'Year out of range. Must be between 1976 and 2050'}) @@ -35,16 +70,38 @@ def walletslistyear(request, year): def cavewallets(request, caveid): '''Returns all the wallets for just one cave ''' + Gcavelookup = GetCaveLookup() if caveid in Gcavelookup: cave = Gcavelookup[caveid] else: return render(request,'errors/badslug.html', {'badslug': caveid}) + earliest = datetime.datetime.now().date() + # remove duplication. SOrting is done in the template wallets = set(Wallet.objects.filter(survexblock__survexfile__cave=cave)) # NB a filtered set manywallets = list(wallets) - + + + for w in manywallets: + wp = w.people() + if not wp: # an -empty list + populatewallet(w) + else: + if len(wp) == 1: + nobody = wp[0].lower() + if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': + populatewallet(w) + + if not w.date(): + datewallet(w, earliest) + + c = w.cave() + + if not c: + caveifywallet(w) + return render(request, 'cavewallets.html', { 'manywallets':manywallets, 'settings': settings, 'cave': cave}) def oldwallet(request, path): diff --git a/templates/cavewallets.html b/templates/cavewallets.html index 49a36e3..51e5d76 100644 --- a/templates/cavewallets.html +++ b/templates/cavewallets.html @@ -12,7 +12,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <p>This lists all the files in a wallet, some of which may not be for this specific cave. <table width=95%> -<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Scans</th><th>Survex blocks</th><th>Survex dates</th><th>Drawings using these scans</th></tr> +<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} <tr> <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> @@ -20,6 +20,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <td style="padding:2px">{{wallet.date}}</td> <td style="padding:2px">{{wallet.name}}</td> <td style="padding:2px">{{wallet.people}}</td> + <td style="padding:2px">{{wallet.cave}}</td> <td align="right" style="padding:2px">{{wallet.singlescan_set.all|length}}</td> <td style="padding:2px"> @@ -27,11 +28,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <a href="{% url "svx" survexblock.survexfile.path %}">{{survexblock}}</a> {% endfor %} </td> - <td style="padding:2px"> - {% for survexblock in wallet.survexblock_set.all %} - {{survexblock.date}} - {% endfor %} - </td> + <td style="padding:2px"> {% for drawing in wallet.drawingfile_set.all %} <a href="{% url "dwgfilesingle" drawing.dwgpath %}">{{drawing.dwgpath}}</a><br> From c1ba6a39a5f556d832da22e1f8e8ab33494f755b Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Sun, 31 Jul 2022 01:02:02 +0300 Subject: [PATCH 12/17] Wallets by year and by cave --- core/models/survex.py | 10 ++++++++ core/views/scans.py | 45 +++++++++++++++++++++++++++++++----- templates/base.html | 8 +++---- templates/cavewallets.html | 9 +++++--- templates/manywallets.html | 5 ++++ templates/svxcavesingle.html | 1 + templates/yearwallets.html | 45 ++++++++++++++++++++++++++++++++++++ 7 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 templates/yearwallets.html diff --git a/core/models/survex.py b/core/models/survex.py index 79a645e..a84a37e 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -190,6 +190,16 @@ class Wallet(models.Model): raise return waldata + + def year(self): + if self.walletname[4] != "#": + return None + year = int(self.walletname[0:4]) + if year < 1976 or year > 2050: + return None + else: + return str(year) + # Yes this is horribly, horribly inefficient, esp. for a page that have date, people and cave in it def date(self): diff --git a/core/views/scans.py b/core/views/scans.py index fda3d6d..6ecae2b 100644 --- a/core/views/scans.py +++ b/core/views/scans.py @@ -20,6 +20,9 @@ by looking inside the file before being served. need to check if inavlid query string is invalid, or produces multiple replies and render a user-friendly error page. + +Note that datewallet(), caveifywallet() etc do NOT save the object to the db. They are ephemeral, just for the page rendering of the +manywallets dict. ''' def populatewallet(w): @@ -42,13 +45,13 @@ def populatewallet(w): def datewallet(w, earliest): blocks = SurvexBlock.objects.filter(scanswallet = w) - for b in blocks: - if b.date < earliest: - earliest = b.date + for b in blocks: + if b.date: + if b.date < earliest: + earliest = b.date w.date = earliest def caveifywallet(w): - print('*') blocks = SurvexBlock.objects.filter(scanswallet = w) for b in blocks: # NB b.cave is not populated by parser. Use b.survexfile.cave instead, or we could parse b.survexpath @@ -64,7 +67,38 @@ def walletslistyear(request, year): return render(request, 'errors/generic.html', {'message': 'Year out of range. Must be between 1976 and 2050'}) else: year = str(year) - return render(request, 'errors/generic.html', {'message': 'This page logic not implemented yet'}) + #return render(request, 'errors/generic.html', {'message': 'This page logic not implemented yet'}) + earliest = datetime.datetime.now().date() + + manywallets = [] + wallets = Wallet.objects.all() + for w in wallets: + + if year == w.year(): + print(w.year(), w) + manywallets.append(w) + else: + print("NOT WANTED",year, w.year()) + continue + + wp = w.people() + if not wp: # an -empty list + populatewallet(w) + else: + if len(wp) == 1: + nobody = wp[0].lower() + if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': + populatewallet(w) + + if not w.date(): + datewallet(w, earliest) + + c = w.cave() + if not c: + caveifywallet(w) + + return render(request, 'yearwallets.html', { 'manywallets':manywallets, 'settings': settings, 'year': year}) + def cavewallets(request, caveid): @@ -98,7 +132,6 @@ def cavewallets(request, caveid): datewallet(w, earliest) c = w.cave() - if not c: caveifywallet(w) diff --git a/templates/base.html b/templates/base.html index 8f3f562..6d43e63 100644 --- a/templates/base.html +++ b/templates/base.html @@ -36,8 +36,8 @@ <a href="{% url "dwgallfiles" %}">Drawings</a> | <a href="{% url "dwgupload" %}">Upload Drawings</a> | <a href="{% url "photoupload" %}">Upload Photos</a> | - <a href="/1623/290/290.html">290 (FGH)</a> | - <a href="/1626/359/359.html">359 (Homecoming)</a> | + <a href="/1623/290/290">290 (FGH)</a> | + <a href="/1626/359/359">359 (Homecoming)</a> | <br> <a href="{% url "dataissues" %}">Data Issues</a> | @@ -48,8 +48,8 @@ <a id="folklink" href="/folk">expoers</a> | <a id="caversLink" href="{% url "notablepersons" %}">survey lengths</a> | <a href="{% url "stats" %}">statistics</a> | - <a href="{% url "expedition" 2018 %}">Expo2018</a> | - <a href="{% url "expedition" 2019 %}">Expo2019</a> | + <a href="/wallets/year/2019">Wallets(2019)</a> | + <a href="{% url "expedition" 2019 %}">Expo(2019)</a> | <a href="{% url "controlpanel" %}">import/export</a> | <a href="/admin/">Django admin</a> </div> diff --git a/templates/cavewallets.html b/templates/cavewallets.html index 51e5d76..3208927 100644 --- a/templates/cavewallets.html +++ b/templates/cavewallets.html @@ -10,9 +10,13 @@ plans and elevations. It also contains scans of centre-line survex output on whi hand-drawn passage sections are drawn. These hand-drawn passages will eventually be traced to produce Tunnel or Therion drawings and eventually the final complete cave survey. <p>This lists all the files in a wallet, some of which may not be for this specific cave. +<p>See also wallets +<ul> +<li>per year, e.g. <a href="/wallets/year/2019">2019</a> +</ul> <table width=95%> -<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> +<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} <tr> <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> @@ -20,9 +24,8 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <td style="padding:2px">{{wallet.date}}</td> <td style="padding:2px">{{wallet.name}}</td> <td style="padding:2px">{{wallet.people}}</td> - <td style="padding:2px">{{wallet.cave}}</td> - <td align="right" style="padding:2px">{{wallet.singlescan_set.all|length}}</td> + <td align="center" style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.singlescan_set.all|length}}</a></td> <td style="padding:2px"> {% for survexblock in wallet.survexblock_set.all %} <a href="{% url "svx" survexblock.survexfile.path %}">{{survexblock}}</a> diff --git a/templates/manywallets.html b/templates/manywallets.html index 7fc04cb..44d097f 100644 --- a/templates/manywallets.html +++ b/templates/manywallets.html @@ -9,6 +9,11 @@ plans and elevations. It also contains scans of centre-line survex output on which hand-drawn passage sections are drawn. These hand-drawn passages will eventually be traced to produce Tunnel or Therion drawings and eventually the final complete cave survey. +<p>See also wallets +<ul> +<li>per year, e.g. <a href="/wallets/year/2019">2019</a> +<li>per cave, e.g. <a href="/cave/scans/1623-204">1623/204</a> +</ul> <!-- This should all be restructured to use .prefetch_related() and .select_related() see https://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-related diff --git a/templates/svxcavesingle.html b/templates/svxcavesingle.html index ad8af8c..6b90b22 100644 --- a/templates/svxcavesingle.html +++ b/templates/svxcavesingle.html @@ -10,6 +10,7 @@ All the processing to extract the survex subdriectories and survex files is done in this template --> <p>Cave description: <a href="/{{cave.url}}">{{cave.url}}</a> +<p>Wallets: <a href="/cave/scans/{{cave|safe}}">{{cave|safe}}</a> </p> <p> {% for survexdirectory in cave.survexdirectory_set.all %} diff --git a/templates/yearwallets.html b/templates/yearwallets.html new file mode 100644 index 0000000..87843d2 --- /dev/null +++ b/templates/yearwallets.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} + +{% block title %}One Year Survey scans folders (wallets){% endblock %} + +{% block content %} +<h3>Wallets for {{year}} </h3> +<p>Each wallet contains the scanned original in-cave survey notes and sketches of +plans and elevations. It also contains scans of centre-line survex output on which +hand-drawn passage sections are drawn. These hand-drawn passages will eventually be +traced to produce Tunnel or Therion drawings and eventually the final complete cave survey. +<p>This lists all the files in a wallet, some of which may not be for this specific cave. +<p>See also wallets +<ul> +<li>per cave, e.g. <a href="/cave/scans/1623-204">1623/204</a> +</ul> +<table width=95%> +<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> +{% for wallet in manywallets|dictsort:"walletname" %} + <tr> + <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> + + <td style="padding:2px">{{wallet.date}}</td> + <td style="padding:2px">{{wallet.name}}</td> + <td style="padding:2px">{{wallet.people}}</td> + <td style="padding:2px">{{wallet.cave}}</td> + + <td align="center" style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.singlescan_set.all|length}}</a></td> + <td style="padding:2px"> + {% for survexblock in wallet.survexblock_set.all %} + <a href="{% url "svx" survexblock.survexfile.path %}">{{survexblock}}</a> + {% endfor %} + </td> + + <td style="padding:2px"> + {% for drawing in wallet.drawingfile_set.all %} + <a href="{% url "dwgfilesingle" drawing.dwgpath %}">{{drawing.dwgpath}}</a><br> + {% empty %} + (no Tunnel drawings found: but there might be Therion drawings) + {% endfor %} + </td> + </tr> +{% endfor %} +</table> + +{% endblock %} \ No newline at end of file From a2a5e9200ec5a588729a19684bba9c045dad8ef6 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Sun, 31 Jul 2022 18:58:46 +0300 Subject: [PATCH 13/17] wallets per person - slow implementation --- core/models/survex.py | 8 +++++ core/models/troggle.py | 4 +-- core/views/scans.py | 69 ++++++++++++++++++++++++++++++++---- templates/cavewallets.html | 5 +-- templates/dataissues.html | 2 +- templates/manywallets.html | 1 + templates/personwallets.html | 46 ++++++++++++++++++++++++ templates/yearwallets.html | 9 ++--- urls.py | 3 +- 9 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 templates/personwallets.html diff --git a/core/models/survex.py b/core/models/survex.py index a84a37e..a562a44 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -203,18 +203,26 @@ class Wallet(models.Model): # Yes this is horribly, horribly inefficient, esp. for a page that have date, people and cave in it def date(self): + if not self.get_json(): + return None jsondata = self.get_json() return jsondata["date"] def people(self): + if not self.get_json(): + return None jsondata = self.get_json() return jsondata["people"] def cave(self): + if not self.get_json(): + return None jsondata = self.get_json() return jsondata["cave"] def name(self): + if not self.get_json(): + return None jsondata = self.get_json() return jsondata["name"] diff --git a/core/models/troggle.py b/core/models/troggle.py index 593bd1d..84f1bc3 100644 --- a/core/models/troggle.py +++ b/core/models/troggle.py @@ -124,11 +124,11 @@ class Person(TroggleModel): fullname = models.CharField(max_length=200) is_vfho = models.BooleanField(help_text="VFHO is the Vereines für Höhlenkunde in Obersteier, a nearby Austrian caving club.", default=False) mug_shot = models.CharField(max_length=100, blank=True,null=True) - blurb = models.TextField(blank=True,null=True) + blurb = models.TextField(blank=True,null=True) #href = models.CharField(max_length=200) orderref = models.CharField(max_length=200) # for alphabetic - user = models.OneToOneField(User, null=True, blank=True,on_delete=models.CASCADE) + user = models.OneToOneField(User, null=True, blank=True,on_delete=models.CASCADE) # not used now def get_absolute_url(self): return urljoin(settings.URL_ROOT,reverse('person',kwargs={'first_name':self.first_name,'last_name':self.last_name})) diff --git a/core/views/scans.py b/core/views/scans.py index 6ecae2b..d7c48e2 100644 --- a/core/views/scans.py +++ b/core/views/scans.py @@ -10,8 +10,11 @@ from django.shortcuts import render from django.http import HttpResponse from troggle.core.models.survex import Wallet, SingleScan, SurvexBlock +from troggle.core.models.troggle import Person from troggle.core.models.caves import GetCaveLookup from troggle.core.views.expo import getmimetype +#from troggle.parsers.people import GetPersonExpeditionNameLookup + #import parsers.surveys '''one of these views serves files as binary blobs, and simply set the mime type based on the file extension, @@ -41,15 +44,20 @@ def populatewallet(w): for b in blocks: for personrole in b.survexpersonrole_set.all(): survexpeople.append(personrole.personname) - w.people = list(set(survexpeople)) # remove duplicates + w.persons = list(set(survexpeople)) def datewallet(w, earliest): + first = earliest blocks = SurvexBlock.objects.filter(scanswallet = w) for b in blocks: if b.date: - if b.date < earliest: - earliest = b.date - w.date = earliest + if b.date < first: + first = b.date + if first == earliest: + # no date found + w.date = None + else: + w.date = first def caveifywallet(w): blocks = SurvexBlock.objects.filter(scanswallet = w) @@ -57,11 +65,59 @@ def caveifywallet(w): # NB b.cave is not populated by parser. Use b.survexfile.cave instead, or we could parse b.survexpath if b.survexfile.cave: w.cave = b.survexfile.cave # just gets the last one, randomly - print(w.cave) +def walletslistperson(request, first_name, last_name): + '''Page which displays a list of all the wallets for a specific person + HORRIBLE linear search through everything. Index and do SQL query properly + ''' + # This is where we face having to re-do everything to do with names properly, rather than the horrible series of hacks over 20 years.. + #GetPersonExpeditionNameLookup + + try: + if last_name: + p = Person.objects.get(fullname= f'{first_name} {last_name}') + else: + # speciall Wookey-hack + p = Person.objects.get(first_name= f'{first_name}') + except: + #raise + return render(request, 'errors/generic.html', {'message': f'Unrecognised name of a expo person: "{first_name} {last_name}"'}) + + #personyear = GetPersonExpeditionNameLookup(expedition).get(tripperson.lower()) + earliest = datetime.datetime.now().date() + + manywallets = [] + wallets = Wallet.objects.all() + for w in wallets: + w.persons = w.people() # ephemeral attribute for web page + # check if there is a json + if not w.get_json(): + populatewallet(w) + else: + wp = w.people() + if not wp: # an -empty list + populatewallet(w) + else: + if len(wp) == 1: + nobody = wp[0].lower() + if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': + populatewallet(w) + + if p.fullname in w.persons: + #found person + manywallets.append(w) + + if not w.date(): + datewallet(w, earliest) + + c = w.cave() + if not c: + caveifywallet(w) + + return render(request, 'personwallets.html', { 'manywallets':manywallets, 'settings': settings, 'person': p}) def walletslistyear(request, year): - '''Page which displays a list of all the wallets in a specific year - TO BE WRITTEN + '''Page which displays a list of all the wallets in a specific year ''' if year < 1976 or year > 2050: return render(request, 'errors/generic.html', {'message': 'Year out of range. Must be between 1976 and 2050'}) @@ -78,7 +134,6 @@ def walletslistyear(request, year): print(w.year(), w) manywallets.append(w) else: - print("NOT WANTED",year, w.year()) continue wp = w.people() diff --git a/templates/cavewallets.html b/templates/cavewallets.html index 3208927..8fd5d83 100644 --- a/templates/cavewallets.html +++ b/templates/cavewallets.html @@ -13,17 +13,18 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <p>See also wallets <ul> <li>per year, e.g. <a href="/wallets/year/2019">2019</a> +<li>per person, e.g. <a href="/wallets/person/MichaelSargent">Michael Sargent</a> </ul> <table width=95%> -<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> +<tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} <tr> <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> <td style="padding:2px">{{wallet.date}}</td> <td style="padding:2px">{{wallet.name}}</td> - <td style="padding:2px">{{wallet.people}}</td> + <td style="padding:2px">{{wallet.persons}}</td> <td align="center" style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.singlescan_set.all|length}}</a></td> <td style="padding:2px"> diff --git a/templates/dataissues.html b/templates/dataissues.html index 2127a0e..97c415e 100644 --- a/templates/dataissues.html +++ b/templates/dataissues.html @@ -6,7 +6,7 @@ <h1>Loading data from files: Issues arising that need attention</h1> <p> -This is work in progress (June 2022).The URL links to the offending objects are enabled on only some types of fault as yet. +This is work in progress.The URL links to the offending objects are enabled on only some types of fault as yet. <p> See the <a href="/handbook/computing/todo-data.html">Data Management To Do list</a> as well as these import/parsing issues. diff --git a/templates/manywallets.html b/templates/manywallets.html index 44d097f..7295ac5 100644 --- a/templates/manywallets.html +++ b/templates/manywallets.html @@ -13,6 +13,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <ul> <li>per year, e.g. <a href="/wallets/year/2019">2019</a> <li>per cave, e.g. <a href="/cave/scans/1623-204">1623/204</a> +<li>per person, e.g. <a href="/wallets/person/MichaelSargent">Michael Sargent</a> </ul> <!-- This should all be restructured to use .prefetch_related() and .select_related() diff --git a/templates/personwallets.html b/templates/personwallets.html new file mode 100644 index 0000000..27c6db8 --- /dev/null +++ b/templates/personwallets.html @@ -0,0 +1,46 @@ +{% extends "base.html" %} + +{% block title %}One Person Survey scans folders (wallets){% endblock %} + +{% block content %} +<h3>Wallets for <a href="{{person.get_absolute_url}}">{{person}}</a> </h3> +<p>Each wallet contains the scanned original in-cave survey notes and sketches of +plans and elevations. It also contains scans of centre-line survex output on which +hand-drawn passage sections are drawn. These hand-drawn passages will eventually be +traced to produce Tunnel or Therion drawings and eventually the final complete cave survey. + +<p>See also wallets +<ul> +<li>per year, e.g. <a href="/wallets/year/2019">2019</a> +<li>per cave, e.g. <a href="/cave/scans/1623-161">1623/161</a> +</ul> +<table width=95%> +<tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Wallet Name</th><th width=15%>Other People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> +{% for wallet in manywallets|dictsort:"walletname" %} + <tr> + <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> + + <td style="padding:2px" >{{wallet.date}}</td> + <td style="padding:2px">{{wallet.name}}</td> + <td style="padding:2px">{{wallet.persons}}</td> + <td style="padding:2px">{{wallet.cave}}</td> + + <td align="center" style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.singlescan_set.all|length}}</a></td> + <td style="padding:2px"> + {% for survexblock in wallet.survexblock_set.all %} + <a href="{% url "svx" survexblock.survexfile.path %}">{{survexblock}}</a> + {% endfor %} + </td> + + <td style="padding:2px"> + {% for drawing in wallet.drawingfile_set.all %} + <a href="{% url "dwgfilesingle" drawing.dwgpath %}">{{drawing.dwgpath}}</a><br> + {% empty %} + (no Tunnel drawings found: but there might be Therion drawings) + {% endfor %} + </td> + </tr> +{% endfor %} +</table> + +{% endblock %} \ No newline at end of file diff --git a/templates/yearwallets.html b/templates/yearwallets.html index 87843d2..ce061c0 100644 --- a/templates/yearwallets.html +++ b/templates/yearwallets.html @@ -8,20 +8,21 @@ plans and elevations. It also contains scans of centre-line survex output on which hand-drawn passage sections are drawn. These hand-drawn passages will eventually be traced to produce Tunnel or Therion drawings and eventually the final complete cave survey. -<p>This lists all the files in a wallet, some of which may not be for this specific cave. + <p>See also wallets <ul> -<li>per cave, e.g. <a href="/cave/scans/1623-204">1623/204</a> +<li>per cave, e.g. <a href="/cave/scans/1623-161">1623/161</a> +<li>per person, e.g. <a href="/wallets/person/MichaelSargent">Michael Sargent</a> </ul> <table width=95%> -<tr><th>Wallet</th><th>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> +<tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} <tr> <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> <td style="padding:2px">{{wallet.date}}</td> <td style="padding:2px">{{wallet.name}}</td> - <td style="padding:2px">{{wallet.people}}</td> + <td style="padding:2px">{{wallet.persons}}</td> <td style="padding:2px">{{wallet.cave}}</td> <td align="center" style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.singlescan_set.all|length}}</a></td> diff --git a/urls.py b/urls.py index d43ac7e..09e151a 100644 --- a/urls.py +++ b/urls.py @@ -8,7 +8,7 @@ from django.contrib import auth from django.urls import path, reverse, resolve from troggle.core.views import statistics, survex -from troggle.core.views.scans import scansingle, allscans, cavewallets, walletslistyear +from troggle.core.views.scans import scansingle, allscans, cavewallets, walletslistyear, walletslistperson from troggle.core.views.drawings import dwgallfiles, dwgfilesingle from troggle.core.views.uploads import dwgupload, scanupload, photoupload from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage @@ -172,6 +172,7 @@ trogglepatterns = [ # The data about the wallets themselves, not the scans inside tehm path('wallets/year/<int:year>', walletslistyear, name="walletslistyear"), # wallets that are for a specific year, as an integer '1985' + re_path('wallets/person/(?P<first_name>[A-Z]*[a-z\-\'&;]*)[^a-zA-Z]*(?P<last_name>[a-z\-\']*[^a-zA-Z]*[\-]*[A-Z]*[a-zA-Z\-&;]*)/?', walletslistperson, name="walletslistperson"), # The tunnel and therion drawings files pageswalletslistcave From 5da1fce41fcace616f15001b3d53834267c70081 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Sun, 31 Jul 2022 19:33:14 +0300 Subject: [PATCH 14/17] tidy links --- templates/person.html | 3 +++ templates/walletform.html | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/templates/person.html b/templates/person.html index 8128760..d390b80 100644 --- a/templates/person.html +++ b/templates/person.html @@ -27,6 +27,9 @@ </ul> </p> +<h3>Surveys done</h3> +Wallets and surveys mentioning <a href="/wallets/person/{{person}}">{{person}}</a> + {% if person.blurb %} {{person.blurb|safe}} {% else %} diff --git a/templates/walletform.html b/templates/walletform.html index f120791..0bde7be 100644 --- a/templates/walletform.html +++ b/templates/walletform.html @@ -129,7 +129,7 @@ title="Date of the trip in ISO format: 2020-08-17" placeholder="{{date}}" value="{{date}}" required /> <br> - <label for="cave">Cave ID</label> + <label for="cave">Cave ID (only needed if no survex file yet)</label> <input label = "Cave" name = "cave" size="12" title="Cave id e.g. 2017-DM-01 or 1623/256" @@ -174,7 +174,7 @@ title="List of people on the survey trip" placeholder="{{people}}" value="{{people}}" /> <br> - <label for="url">URL of cave description</label> + <label for="url">URL of survey area (only needed if not a cave)</label> <input label = "URL" name = "url" size ="{{urlsize}}" title="URL of cave description, e.g. /1623/264/264.html" From 129ea3cc5bd9a77db9138277e2dc23b294c19608 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Mon, 1 Aug 2022 02:50:19 +0300 Subject: [PATCH 15/17] debugging ticklist --- core/models/survex.py | 117 ++++++++++++++++++++++++++++++++++- core/views/scans.py | 22 ++++--- core/views/uploads.py | 10 ++- templates/personwallets.html | 43 +++++++++++++ templates/walletform.html | 4 +- 5 files changed, 180 insertions(+), 16 deletions(-) diff --git a/core/models/survex.py b/core/models/survex.py index a562a44..11ef4f4 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -1,8 +1,10 @@ import os import re import json +import operator from urllib.parse import urljoin from pathlib import Path +from functools import reduce from django.db import models from django.conf import settings @@ -177,7 +179,7 @@ class Wallet(models.Model): def get_json(self): jsonfile = Path(self.fpath, 'contents.json') if not Path(jsonfile).is_file(): - print(f'{jsonfile} is not a file') + #print(f'{jsonfile} is not a file') return None else: with open(jsonfile) as json_f: @@ -186,7 +188,7 @@ class Wallet(models.Model): except: wurl = f"/scanupload/{self.walletname}" # .replace('#', ':') message = f"! {str(self.walletname)} Failed to load {jsonfile} JSON file" - print(message) + #print(message) raise return waldata @@ -225,7 +227,118 @@ class Wallet(models.Model): return None jsondata = self.get_json() return jsondata["name"] + + def get_fnames(self): + '''Filenames without the suffix, i.e. without the ".jpg" + ''' + dirpath = Path(settings.SCANS_ROOT, self.fpath) + files = [] + if dirpath.is_dir(): + try: + for f in dirpath.iterdir(): + if f.is_file(): + if f.name != 'contents.json' and f.name != 'walletindex.html': + files.append(Path(f.name).stem) + except FileNotFoundError: + pass + return files + + + def get_ticks(self): + waldata = self.get_json() + if not waldata: + return {} + ticks = {} + # Initially, are there any required survex files present ? + survexok = "red" + ticks["S"] = "red" + if waldata["survex not required"]: + survexok = "green" + ticks["S"] = "green" + else: + if waldata["survex file"]: + if not type(waldata["survex file"])==list: # a string also is a sequence type, so do it this way + waldata["survex file"] = [waldata["survex file"]] + ngood = 0 + nbad = 0 + ticks["S"] = "lightblue" + for svx in waldata["survex file"]: + if svx !="": + if (Path(settings.SURVEX_DATA) / svx).is_file(): + ngood += 1 + else: + nbad += 1 + if nbad == 0 and ngood >= 1: + ticks["S"] = "green" + if nbad >= 1 and ngood >= 1: + ticks["S"] = "orange" + if nbad >= 1 and ngood == 0: + ticks["S"] = "red" + + # Cave Description + if waldata["description written"]: + ticks["C"] = "green" + else: + ticks["C"] = survexok + # QMs + if waldata["qms written"]: + ticks["Q"] = "green" + else: + ticks["Q"] = survexok + + # Notes, Plan, Elevation; Tunnel + if waldata["electronic survey"]: + ticks["N"] = "green" + ticks["P"] = "green" + ticks["E"] = "green" + ticks["T"] = "green" + else: + + files = self.get_fnames() + print(self.walletname,files) + # Notes required + notes_scanned = reduce(operator.or_, [f.startswith("note") for f in files], False) + notes_scanned = reduce(operator.or_, [f.endswith("notes") for f in files], notes_scanned) + if notes_scanned: + ticks["N"] = "green" + else: + ticks["N"] = "red" + + # Plan drawing required + plan_scanned = reduce(operator.or_, [f.startswith("plan") for f in files], False) + plan_scanned = reduce(operator.or_, [f.endswith("plan") for f in files], plan_scanned) + plan_drawing_required = not (plan_scanned or waldata["plan drawn"] or waldata["plan not required"]) + if plan_drawing_required: + ticks["P"] = "red" + else: + ticks["P"] = "green" + + # Elev drawing required + elev_scanned = reduce(operator.or_, [f.startswith("elev") for f in files], False) + elev_scanned = reduce(operator.or_, [f.endswith("elev") for f in files], elev_scanned) + elev_scanned = reduce(operator.or_, [f.endswith("elevation") for f in files], elev_scanned) + elev_drawing_required = not (elev_scanned or waldata["elev drawn"] or waldata["elev not required"]) + if elev_drawing_required: + ticks["E"] = "red" + else: + ticks["E"] = "green" + + # Tunnel / Therion + if elev_drawing_required or plan_drawing_required: + ticks["T"] = "red" + else: + ticks["T"] = "green" + + + # Website + if waldata["website updated"]: + ticks["W"] = "green" + else: + ticks["W"] = "red" + + return ticks + def __str__(self): return "[" + str(self.walletname) + " (Wallet)]" diff --git a/core/views/scans.py b/core/views/scans.py index d7c48e2..94fb560 100644 --- a/core/views/scans.py +++ b/core/views/scans.py @@ -85,11 +85,13 @@ def walletslistperson(request, first_name, last_name): #personyear = GetPersonExpeditionNameLookup(expedition).get(tripperson.lower()) earliest = datetime.datetime.now().date() + manywallets = [] - wallets = Wallet.objects.all() + wallets = Wallet.objects.all() for w in wallets: w.persons = w.people() # ephemeral attribute for web page + w.ticks = {} # ephemeral tick boxes display # check if there is a json if not w.get_json(): populatewallet(w) @@ -102,18 +104,20 @@ def walletslistperson(request, first_name, last_name): nobody = wp[0].lower() if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': populatewallet(w) - + if w.persons: if p.fullname in w.persons: #found person manywallets.append(w) - if not w.date(): - datewallet(w, earliest) - - c = w.cave() - if not c: - caveifywallet(w) - + if not w.date(): + datewallet(w, earliest) + + c = w.cave() + if not c: + caveifywallet(w) + + w.ticks = w.get_ticks() # the complaints in colour form + return render(request, 'personwallets.html', { 'manywallets':manywallets, 'settings': settings, 'person': p}) def walletslistyear(request, year): diff --git a/core/views/uploads.py b/core/views/uploads.py index 500e4bd..685f7bf 100644 --- a/core/views/uploads.py +++ b/core/views/uploads.py @@ -100,6 +100,9 @@ xlate = {"url": "description url", def get_complaints(complaints, waldata, svxfiles, files, wallet, wurl): '''Taken from old script wallets.py and edited to make more comprehensible Loads the survex files names and processes all complaints + + All needs to be restructred to use the get_ticks() function on the Wallets class in core/models/survex.py + which does the same thing ''' # Date if not waldata["date"]: @@ -134,20 +137,21 @@ def get_complaints(complaints, waldata, svxfiles, files, wallet, wurl): # Notes required if not waldata["electronic survey"]: notes_scanned = reduce(operator.or_, [f.startswith("note") for f in files], False) - notes_scanned = reduce(operator.or_, [f.endswith("note") for f in files], notes_scanned) + notes_scanned = reduce(operator.or_, [Path(f).stem.endswith("notes") for f in files], notes_scanned) if not notes_scanned: complaints.append("The notes needs scanning (or renaming): no noteNN.jpg or XXnote.jpg file found; and this is not an electronic survey.") # Plan drawing required plan_scanned = reduce(operator.or_, [f.startswith("plan") for f in files], False) - plan_scanned = reduce(operator.or_, [f.endswith("plan") for f in files], plan_scanned) + plan_scanned = reduce(operator.or_, [Path(f).stem.endswith("plan") for f in files], plan_scanned) plan_drawing_required = not (plan_scanned or waldata["plan drawn"] or waldata["plan not required"]) if plan_drawing_required: complaints.append("The plan needs drawing (or renaming, or tick 'Plan drawn' checkbox or 'Plan not required' checkbox): no planNN.jpg or XXplan.jpg file found.") # Elev drawing required elev_scanned = reduce(operator.or_, [f.startswith("elev") for f in files], False) - elev_scanned = reduce(operator.or_, [f.endswith("elev") for f in files], elev_scanned) + elev_scanned = reduce(operator.or_, [Path(f).stem.endswith("elev") for f in files], elev_scanned) + elev_scanned = reduce(operator.or_, [Path(f).stem.endswith("elevation") for f in files], elev_scanned) elev_drawing_required = not (elev_scanned or waldata["elev drawn"] or waldata["elev not required"]) if elev_drawing_required: complaints.append("The elevation needs drawing (or renaming, or tick 'Elev drawn' checkbox or 'Elev not required' checkbox): no elevNN.jpg or XXelev.jpg file found.") diff --git a/templates/personwallets.html b/templates/personwallets.html index 27c6db8..5586485 100644 --- a/templates/personwallets.html +++ b/templates/personwallets.html @@ -14,6 +14,48 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <li>per year, e.g. <a href="/wallets/year/2019">2019</a> <li>per cave, e.g. <a href="/cave/scans/1623-161">1623/161</a> </ul> + + +<table width=95%> +<tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Cave</th><th>Wallet Name</th> + +<!-- survex file--> +<th style="font-family: monospace; font-size: 150%;" title="Survex data">S</th> +<th style="font-family: monospace; font-size: 150%;" title="Survex Cave Description">C</th> +<th style="font-family: monospace; font-size: 150%;" title="Survex QMs">Q</th> + + +<!-- scanned--> +<th style="font-family: monospace; font-size: 150%;" title="Notes">N</th> +<th style="font-family: monospace; font-size: 150%;" title="Plan">P</th> +<th style="font-family: monospace; font-size: 150%;" title="Elevation">E</th> + +<th style="font-family: monospace; font-size: 150%;" title="Tunnel or Therion">T</th> +<th style="font-family: monospace; font-size: 150%;" title="Website updated">W</th> + +</tr> +{% for wallet in manywallets|dictsort:"walletname" %} + <tr> + <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> + + <td style="padding:2px" >{{wallet.date}}</td> + <td style="padding:2px">{{wallet.cave}}</td> + <td style="padding:2px">{{wallet.name}}</td> + + <td style="padding:1px; background-color:{{wallet.ticks.S}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.C}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.Q}}"> </td> + + <td style="padding:1px; background-color:{{wallet.ticks.N}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.P}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.E}}"> </td> + + <td style="padding:1px; background-color:{{wallet.ticks.T}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.W}}"> </td> + </tr> +{% endfor %} +</table> +<br /> <table width=95%> <tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Wallet Name</th><th width=15%>Other People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} @@ -43,4 +85,5 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c {% endfor %} </table> + {% endblock %} \ No newline at end of file diff --git a/templates/walletform.html b/templates/walletform.html index 0bde7be..37b1c11 100644 --- a/templates/walletform.html +++ b/templates/walletform.html @@ -156,10 +156,10 @@ <label for="elevd">Elevation drawn ?</label> <input type="checkbox" name="elevd" id="elevd" value="True" {% if "elev drawn" in checked %}checked{% endif %}> <br> - <label for="descriptionw">Cave description written ?</label> + <label for="descriptionw">Cave description written (or nothing recorded) ?</label> <input type="checkbox" name="descriptionw" id="descriptionw" value="True" {% if "description written" in checked %}checked{% endif %}> <br> - <label for="qmsw">QMs written ?</label> + <label for="qmsw">QMs written (or none seen) ?</label> <input type="checkbox" name="qmsw" id="qmsw" value="True" {% if "qms written" in checked %}checked{% endif %}> <br> <label for="websiteupt">Website updated ?</label> From df42b1ccb3766beb5eaadb742bf905a593143c75 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Mon, 1 Aug 2022 03:10:07 +0300 Subject: [PATCH 16/17] remove debugging print --- core/models/survex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/models/survex.py b/core/models/survex.py index 11ef4f4..05588f9 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -296,7 +296,7 @@ class Wallet(models.Model): else: files = self.get_fnames() - print(self.walletname,files) + # Notes required notes_scanned = reduce(operator.or_, [f.startswith("note") for f in files], False) notes_scanned = reduce(operator.or_, [f.endswith("notes") for f in files], notes_scanned) From eed35d01a86a365d464a6b1584d12b9cb40652f6 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Mon, 1 Aug 2022 15:55:20 +0300 Subject: [PATCH 17/17] tick lists now on 3 wallets reports --- core/views/scans.py | 147 ++++++++++++++--------------------- templates/base.html | 17 ++-- templates/cavewallets.html | 5 +- templates/personwallets.html | 43 +--------- templates/wallet_table.html | 40 ++++++++++ templates/yearwallets.html | 5 +- 6 files changed, 115 insertions(+), 142 deletions(-) create mode 100644 templates/wallet_table.html diff --git a/core/views/scans.py b/core/views/scans.py index 94fb560..0ffdb22 100644 --- a/core/views/scans.py +++ b/core/views/scans.py @@ -31,14 +31,6 @@ manywallets dict. def populatewallet(w): '''Copy survex data here just for display, not permanently ''' - # {% for personrole in wallet.survexblock.survexpersonrole_set.all %} - # {% if personrole.personexpedition %} - # <a href="{{personrole.personexpedition.get_absolute_url}}">{{personrole.personname}}</a> - # {% else %} - # {{personrole.personname}} - # {% endif %} - # {% endfor %} - survexpeople = [] blocks = SurvexBlock.objects.filter(scanswallet = w) for b in blocks: @@ -60,11 +52,34 @@ def datewallet(w, earliest): w.date = first def caveifywallet(w): + '''Gets the cave from the list of survex files, + only selects one of them though. Only used for display. + ''' blocks = SurvexBlock.objects.filter(scanswallet = w) for b in blocks: # NB b.cave is not populated by parser. Use b.survexfile.cave instead, or we could parse b.survexpath if b.survexfile.cave: - w.cave = b.survexfile.cave # just gets the last one, randomly + w.cave = b.survexfile.cave # just gets the last one, randomly. SHould make this a list or many:many ideally + +def fillblankpeople(w): + wp = w.people() + if not wp: # an -empty list + populatewallet(w) + else: + if len(wp) == 1: + nobody = wp[0].lower() + if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': + populatewallet(w) + +def fillblankothers(w): + earliest = datetime.datetime.now().date() + if not w.date(): + datewallet(w, earliest) + + c = w.cave() + if not c: + caveifywallet(w) + def walletslistperson(request, first_name, last_name): '''Page which displays a list of all the wallets for a specific person @@ -72,6 +87,18 @@ def walletslistperson(request, first_name, last_name): ''' # This is where we face having to re-do everything to do with names properly, rather than the horrible series of hacks over 20 years.. #GetPersonExpeditionNameLookup + def tickspersonwallet(p): + manywallets = [] + wallets = Wallet.objects.all() + for w in wallets: + w.persons = w.people() # ephemeral attribute for web page + fillblankpeople(w) + if w.persons: + if p.fullname in w.persons: + manywallets.append(w) + fillblankothers(w) + w.ticks = w.get_ticks() # the complaints in colour form + return manywallets try: if last_name: @@ -82,79 +109,37 @@ def walletslistperson(request, first_name, last_name): except: #raise return render(request, 'errors/generic.html', {'message': f'Unrecognised name of a expo person: "{first_name} {last_name}"'}) - - #personyear = GetPersonExpeditionNameLookup(expedition).get(tripperson.lower()) - earliest = datetime.datetime.now().date() - - manywallets = [] - wallets = Wallet.objects.all() - for w in wallets: - w.persons = w.people() # ephemeral attribute for web page - w.ticks = {} # ephemeral tick boxes display - # check if there is a json - if not w.get_json(): - populatewallet(w) - else: - wp = w.people() - if not wp: # an -empty list - populatewallet(w) - else: - if len(wp) == 1: - nobody = wp[0].lower() - if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': - populatewallet(w) - if w.persons: - if p.fullname in w.persons: - #found person - manywallets.append(w) - - if not w.date(): - datewallet(w, earliest) - - c = w.cave() - if not c: - caveifywallet(w) - - w.ticks = w.get_ticks() # the complaints in colour form + manywallets = tickspersonwallet(p) return render(request, 'personwallets.html', { 'manywallets':manywallets, 'settings': settings, 'person': p}) + def walletslistyear(request, year): '''Page which displays a list of all the wallets in a specific year ''' + def ticksyearwallet(year): + manywallets = [] + wallets = Wallet.objects.all() + for w in wallets: + + if year == w.year(): + manywallets.append(w) + fillblankpeople(w) + fillblankothers(w) + w.ticks = w.get_ticks() # the complaints in colour form + else: + continue + + return manywallets + if year < 1976 or year > 2050: return render(request, 'errors/generic.html', {'message': 'Year out of range. Must be between 1976 and 2050'}) else: year = str(year) #return render(request, 'errors/generic.html', {'message': 'This page logic not implemented yet'}) - earliest = datetime.datetime.now().date() - manywallets = [] - wallets = Wallet.objects.all() - for w in wallets: - - if year == w.year(): - print(w.year(), w) - manywallets.append(w) - else: - continue - - wp = w.people() - if not wp: # an -empty list - populatewallet(w) - else: - if len(wp) == 1: - nobody = wp[0].lower() - if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': - populatewallet(w) - - if not w.date(): - datewallet(w, earliest) - - c = w.cave() - if not c: - caveifywallet(w) + manywallets = ticksyearwallet(year) return render(request, 'yearwallets.html', { 'manywallets':manywallets, 'settings': settings, 'year': year}) @@ -163,39 +148,23 @@ def walletslistyear(request, year): def cavewallets(request, caveid): '''Returns all the wallets for just one cave ''' - Gcavelookup = GetCaveLookup() if caveid in Gcavelookup: cave = Gcavelookup[caveid] else: return render(request,'errors/badslug.html', {'badslug': caveid}) - earliest = datetime.datetime.now().date() - # remove duplication. SOrting is done in the template wallets = set(Wallet.objects.filter(survexblock__survexfile__cave=cave)) # NB a filtered set manywallets = list(wallets) - for w in manywallets: - wp = w.people() - if not wp: # an -empty list - populatewallet(w) - else: - if len(wp) == 1: - nobody = wp[0].lower() - if nobody == 'unknown' or nobody == 'nobody' or nobody == ' ': - populatewallet(w) - - if not w.date(): - datewallet(w, earliest) - - c = w.cave() - if not c: - caveifywallet(w) - + fillblankpeople(w) + fillblankothers(w) + w.ticks = w.get_ticks() # the complaints in colour form return render(request, 'cavewallets.html', { 'manywallets':manywallets, 'settings': settings, 'cave': cave}) + def oldwallet(request, path): '''Now called only for non-standard wallet structures for pre-2000 wallets ''' diff --git a/templates/base.html b/templates/base.html index 6d43e63..a25e13c 100644 --- a/templates/base.html +++ b/templates/base.html @@ -56,7 +56,7 @@ <div id="nav"> {% block nav %} - <!-- Use id="nav" for the left side menu --> + <!-- Not used any more? --> {% endblock %} </div> @@ -65,16 +65,15 @@ {% block contentheader %} {% endblock %} -<div id="related"> -{% block related %} - -{% endblock %} -</div> + <div id="related"> + {% block related %} + {% endblock %} + </div> {% block content %} REPLACE : The content {% endblock %} - </div> - <div class="footer"> - </div> +</div> +<div class="footer"> +</div> </body> </html> diff --git a/templates/cavewallets.html b/templates/cavewallets.html index 8fd5d83..8ce1da1 100644 --- a/templates/cavewallets.html +++ b/templates/cavewallets.html @@ -14,8 +14,9 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <ul> <li>per year, e.g. <a href="/wallets/year/2019">2019</a> <li>per person, e.g. <a href="/wallets/person/MichaelSargent">Michael Sargent</a> - </ul> +{% include 'wallet_table.html' %} +<br /> <table width=95%> <tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} @@ -33,7 +34,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c {% endfor %} </td> - <td style="padding:2px"> + <td style="padding:2px; font-size: 70%;"> {% for drawing in wallet.drawingfile_set.all %} <a href="{% url "dwgfilesingle" drawing.dwgpath %}">{{drawing.dwgpath}}</a><br> {% empty %} diff --git a/templates/personwallets.html b/templates/personwallets.html index 5586485..f513e20 100644 --- a/templates/personwallets.html +++ b/templates/personwallets.html @@ -15,46 +15,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <li>per cave, e.g. <a href="/cave/scans/1623-161">1623/161</a> </ul> - -<table width=95%> -<tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Cave</th><th>Wallet Name</th> - -<!-- survex file--> -<th style="font-family: monospace; font-size: 150%;" title="Survex data">S</th> -<th style="font-family: monospace; font-size: 150%;" title="Survex Cave Description">C</th> -<th style="font-family: monospace; font-size: 150%;" title="Survex QMs">Q</th> - - -<!-- scanned--> -<th style="font-family: monospace; font-size: 150%;" title="Notes">N</th> -<th style="font-family: monospace; font-size: 150%;" title="Plan">P</th> -<th style="font-family: monospace; font-size: 150%;" title="Elevation">E</th> - -<th style="font-family: monospace; font-size: 150%;" title="Tunnel or Therion">T</th> -<th style="font-family: monospace; font-size: 150%;" title="Website updated">W</th> - -</tr> -{% for wallet in manywallets|dictsort:"walletname" %} - <tr> - <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> - - <td style="padding:2px" >{{wallet.date}}</td> - <td style="padding:2px">{{wallet.cave}}</td> - <td style="padding:2px">{{wallet.name}}</td> - - <td style="padding:1px; background-color:{{wallet.ticks.S}}"> </td> - <td style="padding:1px; background-color:{{wallet.ticks.C}}"> </td> - <td style="padding:1px; background-color:{{wallet.ticks.Q}}"> </td> - - <td style="padding:1px; background-color:{{wallet.ticks.N}}"> </td> - <td style="padding:1px; background-color:{{wallet.ticks.P}}"> </td> - <td style="padding:1px; background-color:{{wallet.ticks.E}}"> </td> - - <td style="padding:1px; background-color:{{wallet.ticks.T}}"> </td> - <td style="padding:1px; background-color:{{wallet.ticks.W}}"> </td> - </tr> -{% endfor %} -</table> +{% include 'wallet_table.html' %} <br /> <table width=95%> <tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Wallet Name</th><th width=15%>Other People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> @@ -74,7 +35,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c {% endfor %} </td> - <td style="padding:2px"> + <td style="padding:2px; font-size: 70%;"> {% for drawing in wallet.drawingfile_set.all %} <a href="{% url "dwgfilesingle" drawing.dwgpath %}">{{drawing.dwgpath}}</a><br> {% empty %} diff --git a/templates/wallet_table.html b/templates/wallet_table.html new file mode 100644 index 0000000..b239e91 --- /dev/null +++ b/templates/wallet_table.html @@ -0,0 +1,40 @@ + +<table width=95%> +<tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Cave</th><th>Wallet Name</th> + +<!-- survex file--> +<th style="font-family: monospace; font-size: 150%;" title="Survex data">S</th> +<th style="font-family: monospace; font-size: 150%;" title="Survex Cave Description">C</th> +<th style="font-family: monospace; font-size: 150%;" title="Survex QMs">Q</th> + + +<!-- scanned--> +<th style="font-family: monospace; font-size: 150%;" title="Notes">N</th> +<th style="font-family: monospace; font-size: 150%;" title="Plan">P</th> +<th style="font-family: monospace; font-size: 150%;" title="Elevation">E</th> + +<th style="font-family: monospace; font-size: 150%;" title="Tunnel or Therion">T</th> +<th style="font-family: monospace; font-size: 150%;" title="Website updated">W</th> + +</tr> +{% for wallet in manywallets|dictsort:"walletname" %} + <tr> + <td style="padding:2px"><a href="{{wallet.get_absolute_url}}">{{wallet.walletname}}</a></td> + + <td style="padding:2px" >{{wallet.date}}</td> + <td style="padding:2px">{{wallet.cave}}</td> + <td style="padding:2px">{{wallet.name}}</td> + + <td style="padding:1px; background-color:{{wallet.ticks.S}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.C}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.Q}}"> </td> + + <td style="padding:1px; background-color:{{wallet.ticks.N}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.P}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.E}}"> </td> + + <td style="padding:1px; background-color:{{wallet.ticks.T}}"> </td> + <td style="padding:1px; background-color:{{wallet.ticks.W}}"> </td> + </tr> +{% endfor %} +</table> diff --git a/templates/yearwallets.html b/templates/yearwallets.html index ce061c0..33b86ef 100644 --- a/templates/yearwallets.html +++ b/templates/yearwallets.html @@ -14,6 +14,9 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c <li>per cave, e.g. <a href="/cave/scans/1623-161">1623/161</a> <li>per person, e.g. <a href="/wallets/person/MichaelSargent">Michael Sargent</a> </ul> + +{% include 'wallet_table.html' %} +<br /> <table width=95%> <tr><th>Wallet</th><th width=8%>Wallet Date</th><th>Wallet Name</th><th>People</th><th>Cave</th><th>Scans</th><th>Survex blocks</th><th>Drawings using these scans</th></tr> {% for wallet in manywallets|dictsort:"walletname" %} @@ -32,7 +35,7 @@ traced to produce Tunnel or Therion drawings and eventually the final complete c {% endfor %} </td> - <td style="padding:2px"> + <td style="padding:2px; font-size: 70%;"> {% for drawing in wallet.drawingfile_set.all %} <a href="{% url "dwgfilesingle" drawing.dwgpath %}">{{drawing.dwgpath}}</a><br> {% empty %}