diff --git a/core/forms.py b/core/forms.py
index a2727f8..08f7e6c 100644
--- a/core/forms.py
+++ b/core/forms.py
@@ -53,12 +53,6 @@ class CaveForm(ModelForm):
self._errors["url"] = self.error_class(["This field cannot start with a /."])
return self.cleaned_data
-# class VersionControlCommentForm(forms.Form):
- # '''Was appended to all forms. Not used currently
- # '''
- # description_of_change = forms.CharField(required = True, widget=forms.Textarea(attrs={'rows':2}))
-
-
class EntranceForm(ModelForm):
'''Only those fields for which we want to override defaults are listed here
the other fields are present on the form, but use the default presentaiton style
@@ -95,9 +89,10 @@ class EntranceForm(ModelForm):
# This next line is called from the templates/edit_cave2.html template.
-# This is sufficeint to create an entire entry for for the cave fields automatically
+# This is sufficient to create an entire entry for for the cave fields automatically
# http://localhost:8000/cave/new/
-# using django built-in Deep magic. https://docs.djangoproject.com/en/2.2/topics/forms/modelforms/
+# using django built-in Deep Magic. https://docs.djangoproject.com/en/3.2/topics/forms/modelforms/
+# for forms which map directly onto a Django Model
CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=('cave',))
class EntranceLetterForm(ModelForm):
diff --git a/core/views/caves.py b/core/views/caves.py
index 1e9c3c4..4956004 100644
--- a/core/views/caves.py
+++ b/core/views/caves.py
@@ -18,7 +18,6 @@ from troggle.core.views import expo
from troggle.core.models.troggle import Expedition, DataIssue
from troggle.core.models.caves import CaveSlug, Cave, CaveAndEntrance, QM, EntranceSlug, Entrance, Area, SurvexStation, GetCaveLookup
from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, EntranceForm, EntranceLetterForm
-#from troggle.core.forms import VersionControlCommentForm
from .auth import login_required_if_public
'''Manages the complex procedures to assemble a cave description out of the compnoents
diff --git a/core/views/uploads.py b/core/views/uploads.py
index 0acd326..dfaa29d 100644
--- a/core/views/uploads.py
+++ b/core/views/uploads.py
@@ -31,15 +31,15 @@ from .auth import login_required_if_public
'''
todo = '''
-- Write equivalent photo upload form system, similar to scanupload() but in expofiles/photos/
- Need to validate it as being a valid image file, not a dubious script or hack
+- Need to validate uploaded file as being a valid image file, not a dubious script or hack
- Write equivalent GPX upload form system, similar to scanupload() but in expofiles/gpslogs/
Need to validate it as being a valid GPX file using an XML parser, not a dubious script or hack
- Validate Tunnel & Therion files using an XML parser in dwgupload()
-- Validate image files using a magic recogniser in scanupload()
+- Validate image files using a magic recogniser in scanupload() https://pypi.org/project/reportlab/ or
+ https://stackoverflow.com/questions/889333/how-to-check-if-a-file-is-a-valid-image-file
- Enable folder creation in dwguploads or as a separate form
@@ -52,14 +52,55 @@ class FilesForm(forms.Form): # not a model-form, just a form-form
class TextForm(forms.Form): # not a model-form, just a form-form
photographer = forms.CharField(strip=True)
+class WalletForm(forms.Form): # not a model-form, just a form-form
+ descriptionw = forms.CharField(strip=True, required=False)
+ people = forms.CharField(strip=True, required=False)
+ survexnr = forms.CharField(strip=True, required=False)
+ qmsw = forms.CharField(strip=True, required=False)
+ date = forms.CharField(strip=True, required=True) # the only required field
+ websiteupt = forms.CharField(strip=True, required=False)
+ elevnr = forms.CharField(strip=True, required=False)
+ cave = forms.CharField(strip=True, required=False)
+ psg = forms.CharField(strip=True, required=False)
+ plannr = forms.CharField(strip=True, required=False)
+ electronic = forms.CharField(strip=True, required=False)
+ pland = forms.CharField(strip=True, required=False)
+ elevd = forms.CharField(strip=True, required=False)
+ url = forms.CharField(strip=True, required=False)
+ survex = forms.CharField(strip=True, required=False)
+
+xlate = {"url": "description url",
+ "descriptionw": "description written",
+ "people": "people",
+ "date": "date",
+ "cave": "cave",
+ "people": "people",
+ "plannr": "plan not required",
+ "survexnr": "survex not required",
+ "qmsw": "qms written",
+ "elevnr": "elev not required",
+ "websiteupt": "website updated",
+ "electronic": "electronic survey",
+ "pland": "plan drawn",
+ "elevd": "elev drawn",
+ "psg": "name",
+ "survex": "survex file",
+ }
+
@login_required_if_public
def scanupload(request, wallet=None):
'''Upload scanned image files into a wallet on /expofiles
+ Also display and edit the contents.json data in the wallet.
+
This does NOT use a Django model linked to a Django form. Just a simple Django form.
You will find the Django documentation on forms very confusing, This is simpler.
'''
filesaved = False
actual_saved = []
+
+ checkboxes = ["description written", "survex not required", "qms written", "website updated",
+ "plan not required", "plan drawn", "elev not required", "elev drawn", "electronic survey" ]
+
# print(f'! - FORM scanupload - start {wallet}')
if wallet is None:
wallet = "2021#01" # improve this later
@@ -90,33 +131,70 @@ def scanupload(request, wallet=None):
form = FilesForm()
if request.method == 'POST':
- form = FilesForm(request.POST,request.FILES)
- #print(f'! - FilesForm POSTED')
-
- if form.is_valid():
- f = request.FILES["uploadfiles"]
- multiple = request.FILES.getlist('uploadfiles')
- fs = FileSystemStorage(os.path.join(dirpath)) # creates wallet folder if necessary
-
- actual_saved = []
- if multiple:
- for f in multiple:
- actual_saved.append( fs.save(f.name, content=f) )
- # print(f'! - FORM scanupload multiple {actual_saved}')
- filesaved = True
-
- # Wallet folder created, but index and contents.json need to be created.
+ if "psg" in request.POST:
+ formj = WalletForm(request.POST)
+ # Beware. All fields returned as strings. Must re-type them as lists etc. before using or re-saving
+ # Also lots of hassle with lists of strings interpreted as a single string
+ # Unset checkboxes do not return any value, checked ones return "True". So need initialising to False
+ if formj.is_valid():
+ #print(f'--- JSON Update form is VALID, saving to {contents_path}')
+ posted = request.POST.copy()
+ posted.pop("csrfmiddlewaretoken") # discard this
+ wd = wallet_blank_json
+ for f in checkboxes:
+ wd[f] = False
+ #print(f'--- wd ${f}$ - {wd[f]}')
+ for f in posted:
+ wd[xlate[f]] = posted[f].replace("\'", "\"")
- if not contents_path.is_file(): # double-check
- with open(contents_path, "w") as json_file:
- json.dump(wallet_blank_json, json_file, sort_keys=True, indent = 1)
- index_path = dirpath / indexhtml
- if not index_path.is_file(): # double-check
- thishtml = wallet_blank_html.replace("YEAR", str(year))
- thishtml = thishtml.replace("WALLET", str(wallet))
- with open(index_path, "w") as html_file:
- html_file.write(thishtml )
-
+ if posted[f] =="True":
+ wd[xlate[f]] = True
+
+ wd["people"] = wd["people"][1:-1].replace("\"", "").split(",")
+ for i, elem in enumerate(wd["people"]):
+ wd["people"][i] = elem.strip()
+
+ #print(f'--- ${wd["survex file"]}$ - {type(wd["survex file"])}')
+ if wd["survex file"][0] == '[':
+ wd["survex file"] = wd["survex file"][1:-1]
+ wd["survex file"] = wd["survex file"].replace("\"", "").split(",")
+ for i, elem in enumerate(wd["survex file"]):
+ wd["survex file"][i] = elem.strip()
+ #print(f'--- {wd["survex file"]} - {type(wd["survex file"])}')
+
+ with open(contents_path, "w") as jfile:
+ json.dump(wd, jfile, indent = 1)
+ # print(f'--- FINISHED saving to JSON\n')
+ else:
+ print(f'--- INVALID JSON Update form submitted')
+ print(formj.errors)
+ return render(request,'errors/generic.html', {'message': formj.errors})
+
+ else:
+ form = FilesForm(request.POST,request.FILES)
+
+ if form.is_valid():
+ f = request.FILES["uploadfiles"]
+ multiple = request.FILES.getlist('uploadfiles')
+ fs = FileSystemStorage(os.path.join(dirpath)) # creates wallet folder if necessary
+
+ actual_saved = []
+ if multiple:
+ for f in multiple:
+ actual_saved.append( fs.save(f.name, content=f) )
+ # print(f'! - FORM scanupload multiple {actual_saved}')
+ filesaved = True
+
+ if not contents_path.is_file(): # double-check
+ with open(contents_path, "w") as json_file:
+ json.dump(wallet_blank_json, json_file, sort_keys=True, indent = 1)
+ index_path = dirpath / indexhtml
+ if not index_path.is_file(): # double-check
+ thishtml = wallet_blank_html.replace("YEAR", str(year))
+ thishtml = thishtml.replace("WALLET", str(wallet))
+ with open(index_path, "w") as html_file:
+ html_file.write(thishtml )
+
files = []
dirs = []
# print(f'! - FORM scanupload - start {wallet} {dirpath}')
@@ -150,35 +228,71 @@ def scanupload(request, wallet=None):
print(message)
DataIssue.objects.create(parser='scans', message=message, url=wurl) # set URL to this wallet folder
raise
-
cave =""
psg = ""
-
+ chkplannr = ""
+ chkpland = ""
+ svxfiles = []
+ checked = {}
if waldata:
if not waldata["people"]:
waldata["people"]=["NOBODY"]
-
+ if not type(waldata["people"])==list:
+ if waldata["people"][0] == '"':
+ waldata["people"] = waldata["people"][1:-1]
+ waldata["people"] = list(waldata["people"])
+
+ if not waldata["description url"]:
+ waldata["description url"]=""
if waldata["cave"]:
cave = waldata["cave"]
if waldata["name"]:
psg = waldata["name"]
+
if waldata["survex file"]:
- if not isinstance(waldata["survex file"], list):
+ #print(f'+++ ${waldata["survex file"]}$ {type(waldata["survex file"])}')
+ if not type(waldata["survex file"])==list: # a string also is a sequence type, so do it this way
+ #print(f'+++ NOT A LIST: {waldata["survex file"]} {type(waldata["survex file"])}')
waldata["survex file"] = [waldata["survex file"]]
for svx in waldata["survex file"]:
- print(f'{svx}')
+ svxfiles.append(svx)
if not (Path(settings.SURVEX_DATA) / svx).is_file():
message = f"! {wallet} Incorrect survex file in wallet data: {svx} not found in LOSER repo"
print(message)
DataIssue.objects.create(parser='scans', message=message, url=wurl) # set URL to this wallet folder
- context = {'year': year, 'prev': prev, 'next': next, 'prevy': prevy, 'nexty': nexty,
- 'files': files, 'dirs': dirs, 'waldata': waldata, 'create': create,
+ for f in checkboxes:
+ if waldata[f]:
+ checked[f] = "checked"
+
+ context = {'year': year, 'prev': prev, 'next': next, 'prevy': prevy, 'nexty': nexty,
+ 'files': files, 'dirs': dirs, 'waldata': waldata, 'svxfiles': svxfiles,
+ 'checked': checked,
+ 'create': create,
+ 'people': waldata["people"], 'peoplesize': str(len(str(waldata["people"]))),
'filesaved': filesaved, 'actual_saved': actual_saved }
- return render(request, 'scanuploadform.html',
- {'form': form, 'wallet': wallet, **context, 'cave': cave, 'psg': psg})
+ return render(request, 'scanuploadform.html',
+ {'form': form, 'wallet': wallet, **context,
+ 'date': waldata["date"],
+ 'url': waldata["description url"], 'urlsize': str(len(str(waldata["description url"]))),
+ 'survex': waldata["survex file"], 'survexsize': str(len(str(waldata["survex file"]))),
+ 'cave': cave, 'psg': psg, 'psgsize': str(max(12,len(str(psg))))})
+ else: # no wallet here
+ context = {'year': year, 'prev': prev, 'next': next, 'prevy': prevy, 'nexty': nexty,
+ 'files': files, 'dirs': dirs, 'waldata': waldata, 'svxfiles': svxfiles,
+ 'checked': checked,
+ 'create': create,
+ 'people': "", 'peoplesize': 12,
+ 'filesaved': filesaved, 'actual_saved': actual_saved }
+
+ return render(request, 'scanuploadform.html',
+ {'form': form, 'wallet': wallet, **context,
+ 'date': "",
+ 'url': "", 'urlsize': 12,
+ 'survex': "", 'survexsize': 12,
+ 'cave': cave, 'psg': psg, 'psgsize': 12})
@login_required_if_public
def photoupload(request, folder=None):
diff --git a/media/css/trog3.css b/media/css/trog3.css
index 3da931a..54e6e84 100644
--- a/media/css/trog3.css
+++ b/media/css/trog3.css
@@ -427,6 +427,10 @@ div#difflistajax
background-color: #dfffdf;
border: thin green solid;
}
+/* FORMS */
+input:invalid {
+ border-color: red;
+}
/* Using in DrawingsUpload and ScanUpload*/
.fancybutton {
color: #ffffff;
diff --git a/templates/scanuploadform.html b/templates/scanuploadform.html
index 095fad9..8f4e26e 100644
--- a/templates/scanuploadform.html
+++ b/templates/scanuploadform.html
@@ -60,26 +60,104 @@
{% if cave %}Cave ID: {{cave}}
{% endif %}
-{% if psg %}Survey area: {{psg}}
{% endif %}
+{% if psg %}Survey area: {{psg}}
{% endif %}
+{% if svxfiles %}Survey files:
+ {% for svx in svxfiles%}
+ {{svx}}
+ {% endfor %}
+
+
+{% endif %}
+
+
+