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] 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}}&nbsp;&nbsp;
+    {% 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'