2023-01-19 18:35:56 +00:00
import datetime
2022-03-15 17:04:43 +00:00
import json
2022-07-17 13:01:53 +01:00
import operator
2023-01-19 18:35:56 +00:00
import os
import re
import socket
import subprocess
import urllib
2022-07-17 13:01:53 +01:00
from functools import reduce
2023-01-19 18:35:56 +00:00
from pathlib import Path
2022-09-23 19:07:51 +01:00
from urllib . parse import unquote
2021-05-05 00:35:10 +01:00
from django import forms
from django . conf import settings
2023-01-19 18:35:56 +00:00
from django . core . exceptions import MultipleObjectsReturned , ObjectDoesNotExist
from django . core . files . storage import FileSystemStorage , default_storage
2021-05-05 00:35:10 +01:00
from django . db . models import Q
from django . http import HttpResponse , HttpResponseRedirect
from django . shortcuts import render
from django . template import Context , loader
2023-01-19 18:35:56 +00:00
from django . urls import reverse
2022-03-18 11:28:35 +00:00
2023-01-19 18:35:56 +00:00
import settings
2023-01-29 16:47:46 +00:00
from troggle . core . models . caves import Cave
2023-01-30 19:04:36 +00:00
from troggle . core . models . logbooks import QM , LogbookEntry # , PersonLogEntry
from troggle . core . models . survex import DrawingFile , SurvexBlock , SurvexFile , SurvexPersonRole , Wallet
2021-05-05 00:35:10 +01:00
# from databaseReset import reinit_db # don't do this. databaseRest runs code *at import time*
2023-01-30 19:04:36 +00:00
from troggle . core . models . troggle import DataIssue , Expedition , Person , PersonExpedition
2022-07-17 13:01:53 +01:00
from troggle . core . views . caves import getCave
2023-01-19 18:35:56 +00:00
from troggle . core . views . scans import caveifywallet , oldwallet
2023-01-30 19:04:36 +00:00
# from troggle import settings
from troggle . parsers . imports import (
import_caves ,
import_drawingsfiles ,
import_logbooks ,
import_people ,
import_QMs ,
import_survex ,
import_surveyscans ,
)
2023-01-19 18:35:56 +00:00
from troggle . parsers . scans import contentsjson
2022-09-13 22:31:37 +01:00
2021-05-05 00:35:10 +01:00
from . auth import login_required_if_public
2023-01-19 18:35:56 +00:00
2023-01-30 19:04:36 +00:00
# from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt
2021-05-05 00:35:10 +01:00
2023-01-30 19:04:36 +00:00
""" File upload ' views '
"""
2021-05-05 00:35:10 +01:00
2023-01-30 19:04:36 +00:00
todo = """
2022-07-17 13:01:53 +01:00
- Register uploaded filenames in the Django db without needing to wait for a reset & bulk file import
- Refactor scanupload ( ) as it contains all the wallets ' complaints ' code from the old script wallets . py
2022-03-17 00:41:29 +00:00
- Need to validate uploaded file as being a valid image file , not a dubious script or hack
2022-03-08 22:59:04 +00:00
- 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
2022-04-20 21:18:05 +01:00
- Validate Tunnel & Therion files using an XML parser in dwgupload ( ) . Though Julian says tunnel is only mostly correct XML
2022-03-08 22:59:04 +00:00
2022-03-17 00:41:29 +00:00
- 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
2022-03-08 22:59:04 +00:00
- Enable folder creation in dwguploads or as a separate form
2022-04-20 21:18:05 +01:00
2023-01-30 19:04:36 +00:00
"""
2022-08-24 14:22:15 +01:00
WALLET_BLANK_JSON = {
2023-01-30 19:04:36 +00:00
" cave " : " " ,
" date " : " " ,
" free text " : " " ,
# "description url": "1623/NNN",
" description written " : False ,
" electronic survey " : False ,
" elev drawn " : False ,
" elev not required " : False ,
" name " : " " ,
" people " : [ " Unknown " ] ,
" plan drawn " : False ,
" plan not required " : False ,
" qms written " : False ,
" survex file " : [ ] ,
" survex not required " : False ,
" website updated " : False ,
}
2021-05-05 00:35:10 +01:00
class FilesForm ( forms . Form ) : # not a model-form, just a form-form
2023-01-30 19:04:36 +00:00
uploadfiles = forms . FileField ( )
2022-08-11 19:19:52 +01:00
class FilesRenameForm ( forms . Form ) : # not a model-form, just a form-form
2023-01-30 19:04:36 +00:00
uploadfiles = forms . FileField ( )
2022-08-11 21:35:53 +01:00
renameto = forms . CharField ( strip = True , required = False )
2022-08-14 20:52:14 +01:00
2023-01-30 19:04:36 +00:00
2022-08-14 20:52:14 +01:00
class WalletGotoForm ( forms . Form ) : # not a model-form, just a form-form
2023-01-30 19:04:36 +00:00
walletgoto = forms . CharField ( strip = True , required = False )
2022-03-13 01:01:00 +00:00
class TextForm ( forms . Form ) : # not a model-form, just a form-form
2023-01-30 19:04:36 +00:00
photographer = forms . CharField ( strip = True )
2022-03-13 01:01:00 +00:00
2022-03-17 00:41:29 +00:00
class WalletForm ( forms . Form ) : # not a model-form, just a form-form
2023-01-30 19:04:36 +00:00
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 )
freetext = 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 )
2022-03-17 00:41:29 +00:00
2022-09-19 18:55:34 +01:00
xlate = {
2023-01-30 19:04:36 +00:00
# "url": "description url",
" descriptionw " : " description written " ,
" people " : " people " ,
" date " : " date " ,
" cave " : " cave " ,
" 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 " , # a name for this wallet
" freetext " : " free text " ,
" survex " : " survex file " ,
}
2022-03-17 00:41:29 +00:00
2022-07-21 07:40:35 +01:00
def get_complaints ( complaints , waldata , svxfiles , files , wallet , wurl ) :
2023-01-30 19:04:36 +00:00
""" Taken from old script wallets.py and edited to make more comprehensible
2022-07-17 13:01:53 +01:00
Loads the survex files names and processes all complaints
2023-01-30 19:04:36 +00:00
"""
2022-08-31 07:27:14 +01:00
# If skipping through the wallets on the upload form, the wallet may not yet exist
2022-08-07 20:52:29 +01:00
try :
w = Wallet . objects . get ( walletname = wallet )
except ObjectDoesNotExist :
return None , None
2023-01-30 19:04:36 +00:00
2022-07-17 13:41:05 +01:00
# Date
if not waldata [ " date " ] :
2023-01-30 19:04:36 +00:00
complaints . append (
" A date is mandatory. No data can be updated or edited unless you specify a date. Look in the survex file if there is one. "
)
2022-07-17 13:41:05 +01:00
# People
2023-01-30 19:04:36 +00:00
if (
not waldata [ " people " ]
or waldata [ " people " ] == [ " NOBODY " ]
or waldata [ " people " ] == [ " Unknown " ]
or waldata [ " people " ] == [ " " ]
) :
complaints . append (
" Someody must have done this. Look in the survex file, or in the logbook entries for this date, for the people who created this data. "
)
2022-08-01 15:32:35 +01:00
# survex, but get_ticks has already done much of this ??
2022-07-17 13:01:53 +01:00
survex_complaint = " "
if waldata [ " survex file " ] :
2023-01-30 19:04:36 +00:00
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 " ] ]
2022-08-25 15:29:43 +01:00
for sx in waldata [ " survex file " ] :
2023-01-30 19:04:36 +00:00
# this logic appears in several places, inc get_ticks(). Refactor.
if sx != " " :
2022-08-25 15:29:43 +01:00
if Path ( sx ) . suffix . lower ( ) != " .svx " :
sx = sx + " .svx "
2023-01-30 19:04:36 +00:00
svxfiles . append ( sx )
2022-08-25 15:29:43 +01:00
if not ( Path ( settings . SURVEX_DATA ) / sx ) . is_file ( ) :
2022-09-21 22:23:47 +01:00
file_complaint = f " { wallet } Incorrect survex file name. File { sx } was not found in LOSER repo "
2022-07-28 16:36:40 +01:00
complaints . append ( file_complaint )
message = f " ! { file_complaint } "
print ( message )
2023-01-30 19:04:36 +00:00
DataIssue . objects . update_or_create (
parser = " scans " , message = message , url = wurl
) # set URL to this wallet folder
2022-09-20 00:36:40 +01:00
else :
try :
2023-01-30 19:04:36 +00:00
sxpath = str ( Path ( sx ) . with_suffix ( " " ) )
2022-09-21 22:23:47 +01:00
svxfile = SurvexFile . objects . get ( path = sxpath )
2022-10-06 19:55:31 +01:00
except MultipleObjectsReturned :
# can happen if connecting a wallet to a survex file.. i think..
2022-10-15 15:26:09 +01:00
QSsvxfiles = SurvexFile . objects . filter ( path = sxpath )
for s in QSsvxfiles :
2022-10-06 19:55:31 +01:00
print ( s . path , s . cave , s . survexdirectory )
2023-01-30 19:04:36 +00:00
svxfile = QSsvxfiles [ 0 ] # dont' know how this happened, fix later..
2022-09-20 00:36:40 +01:00
except :
2023-01-30 19:04:36 +00:00
file_complaint = (
f " { wallet } Survex file { sx } exists, but is not registered in the database { sxpath } . How?.. "
)
2022-09-20 00:36:40 +01:00
complaints . append ( file_complaint )
message = f " ! { file_complaint } "
print ( message )
2023-01-30 19:04:36 +00:00
DataIssue . objects . update_or_create (
parser = " scans " , message = message , url = wurl
) # set URL to this wallet folder
2022-07-17 13:01:53 +01:00
2022-09-20 20:05:35 +01:00
if waldata [ " survex not required " ] and waldata [ " survex file " ] != [ " " ] :
2023-01-30 19:04:36 +00:00
survex_complaint = (
f ' Survex is stated as not required and yet there is a survex file! ( { waldata [ " survex file " ] } ) '
)
2022-09-20 20:05:35 +01:00
if not waldata [ " survex not required " ] and waldata [ " survex file " ] == [ " " ] :
2023-01-30 19:04:36 +00:00
survex_complaint = " A survex file is required, but has not been specified! "
2022-07-17 13:01:53 +01:00
if survex_complaint :
complaints . append ( survex_complaint )
2022-08-01 15:32:35 +01:00
2022-08-31 07:27:14 +01:00
ticks = w . get_ticks ( )
2022-07-17 13:01:53 +01:00
# Notes required
2023-01-30 19:04:36 +00:00
if ticks [ " N " ] != " green " :
complaints . append (
" The notes needs scanning (or renaming): no noteNN.jpg or XXnote.jpg file found; and this is not an electronic survey. "
)
2022-07-17 13:01:53 +01:00
# Plan drawing required
2023-01-30 19:04:36 +00:00
if ticks [ " P " ] != " green " :
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. "
)
2022-07-17 13:01:53 +01:00
# Elev drawing required
2023-01-30 19:04:36 +00:00
if ticks [ " E " ] != " green " :
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. "
)
2022-07-17 13:01:53 +01:00
2022-08-01 15:32:35 +01:00
# ETherion
2023-01-30 19:04:36 +00:00
if ticks [ " T " ] != " green " :
complaints . append (
" Tunnel or Therion drawing files need drawing. Or if this an electronic survey, please tick the ' Electronic survey ' checkbox. "
)
2022-07-17 13:01:53 +01:00
# Description
2023-01-30 19:04:36 +00:00
if not waldata [ " description written " ] :
complaints . append (
" The guidebook description needs writing into the survex file. Tick the ' Cave description written ' checkbox when this is done. "
)
2022-07-17 13:01:53 +01:00
# QMs
2022-09-23 21:43:34 +01:00
if not waldata [ " qms written " ] and w . year ( ) and int ( w . year ( ) ) > = 2015 :
2023-01-30 19:04:36 +00:00
complaints . append (
" The QMs needs writing into the survex file. Tick the ' QMs written ' checkbox when this is done. "
)
2022-07-17 13:01:53 +01:00
# Website
if not waldata [ " website updated " ] :
2023-01-30 19:04:36 +00:00
complaints . append (
" The cave description website is marked as needing updating using the guidebook description from the survex file. Tick the ' Website updated ' checkbox when this is done. "
)
2022-07-17 13:01:53 +01:00
2022-09-19 18:55:34 +01:00
# Find the cave, if it exists
2022-07-17 13:22:26 +01:00
if waldata [ " cave " ] :
try :
2022-07-17 13:28:20 +01:00
caveid = waldata [ " cave " ]
2022-09-19 23:02:06 +01:00
if type ( caveid ) is list :
for i in caveid :
2023-01-30 19:04:36 +00:00
i = i . replace ( " / " , " - " )
caveobject = getCave ( i ) # only the last one gets recorded.. ouch.
2022-09-19 23:02:06 +01:00
else :
caveid = caveid
2023-01-30 19:04:36 +00:00
caveobject = getCave ( caveid )
2022-07-17 13:22:26 +01:00
print ( f ' getCave for id " { waldata [ " cave " ] } " { caveobject } ' )
2022-09-19 18:55:34 +01:00
# if not caveobject.url == waldata["description url"]:
2023-01-30 19:04:36 +00:00
# complaints.append(f'The URL of cave description \"{waldata["description url"]}\" does not match the one on record for this cave which is: "{caveobject.url}". If the wallet is not for a cave, put a useful URL here.')
except Cave . MultipleObjectsReturned :
2022-07-17 13:22:26 +01:00
complaints . append ( f ' The cave ID \' { waldata [ " cave " ] } \' is AMBIGUOUS. Please fix it. ' )
caveobject = None
except ObjectDoesNotExist :
complaints . append ( f ' The cave ID \' { waldata [ " cave " ] } \' is not recognised. Please fix it. ' )
caveobject = None
else :
2023-01-30 19:04:36 +00:00
complaints . append (
f ' No cave ID is given. If there is no survex file, please give something, even if it is just " 1623-000 " , " surface survey " or " scraps found in hut " '
)
2022-07-17 13:01:53 +01:00
caveobject = None
return complaints , caveobject
2023-01-30 19:04:36 +00:00
2022-03-24 20:45:15 +00:00
# @login_required_if_public
2022-03-18 11:28:35 +00:00
def scanupload ( request , path = None ) :
2023-01-30 19:04:36 +00:00
""" Upload scanned image files into a wallet on /expofiles
2022-08-13 21:56:56 +01:00
Also display AND EDIT the contents . json data in the wallet .
2023-01-30 19:04:36 +00:00
2022-09-13 22:31:37 +01:00
This is the main wallet display and edit page .
2023-01-30 19:04:36 +00:00
2022-08-14 21:40:56 +01:00
The Wallet object and the contents . json file are created when the user
2023-01-30 19:04:36 +00:00
first uploads files .
2021-05-05 00:35:10 +01:00
This does NOT use a Django model linked to a Django form . Just a simple Django form .
2022-08-14 21:40:56 +01:00
You will find the Django documentation on forms very confusing ,
as it covers many very differnet things we do not need . This is simpler .
2023-01-30 19:04:36 +00:00
2022-07-17 13:01:53 +01:00
This subsumes much of the code which was in the old wallets . py script and so this function is very long
indeed and needs refactoring .
2023-01-30 19:04:36 +00:00
REWRITE bits using the ticklist , dateify , caveify , populate etc utility functions in core . view . scans . py
"""
2022-08-13 21:56:56 +01:00
git = settings . GIT
2021-05-05 00:35:10 +01:00
filesaved = False
actual_saved = [ ]
2023-01-30 19:04:36 +00:00
2022-08-24 15:01:20 +01:00
def read_json ( ) :
2023-01-30 19:04:36 +00:00
""" Read JSON from the wallet metadata file in the repo
2022-09-19 23:02:06 +01:00
or fills with blank data if that files can ' t be read
2023-01-30 19:04:36 +00:00
Should sanitise to ensure no spurious backslashes e . g . in windows style paths """
2022-08-31 07:27:14 +01:00
waldata = { }
2023-01-30 19:04:36 +00:00
if contents_path . is_file ( ) :
create = False # yes wallet exists because JSON exists, even if no files in the surveyscans folder, or even if that folder does not exist
2022-08-24 15:01:20 +01:00
with open ( contents_path ) as json_file :
try :
waldata = json . load ( json_file )
except :
message = f " ! { wallet } Failed to load { contents_path } JSON file "
print ( message )
2023-01-30 19:04:36 +00:00
DataIssue . objects . create ( parser = " scans " , message = message , url = wurl ) # set URL to this wallet folder
2022-08-24 15:01:20 +01:00
raise
2023-01-30 19:04:36 +00:00
else : # no JSON file exists
print ( f " --- No JSON exists, so creating blank copy " )
2022-08-24 15:01:20 +01:00
waldata = WALLET_BLANK_JSON . copy ( )
2022-08-24 17:08:08 +01:00
if not waldata [ " survex file " ] :
2022-08-31 07:27:14 +01:00
try :
w = Wallet . objects . get ( walletname = wallet )
b = SurvexBlock . objects . filter ( scanswallet = w )
waldata [ " survex file " ] = [ ]
for bsf in b :
waldata [ " survex file " ] . append ( bsf . survexfile . path )
except :
2023-01-30 19:04:36 +00:00
print ( f " --- No wallet { wallet } exists in database " )
2022-08-24 15:01:20 +01:00
return waldata
2023-01-30 19:04:36 +00:00
2022-08-14 21:40:56 +01:00
def save_json ( jsondict ) :
newfolder = contents_path . parent
2023-01-30 19:04:36 +00:00
# print(f'--- Wallet directory in :drawings: repo {newfolder=} {jsondict}')
2022-08-14 21:40:56 +01:00
if not os . path . exists ( contents_path . parent ) :
2023-01-30 19:04:36 +00:00
print ( f " --- No wallet directory in :drawings: repo, so creating it " )
2022-08-14 21:40:56 +01:00
os . makedirs ( contents_path . parent )
2023-01-30 19:04:36 +00:00
2022-08-14 21:40:56 +01:00
with open ( contents_path , " w " ) as jfile :
2023-01-30 19:04:36 +00:00
json . dump ( jsondict , jfile , indent = 1 )
2022-08-24 15:01:20 +01:00
# print(f'--- FINISHED saving to JSON at {contents_path}')
2023-01-30 19:04:36 +00:00
2022-08-14 21:40:56 +01:00
def make_wallet ( walletname ) :
2023-01-30 19:04:36 +00:00
""" We need a wallet Object so that the django template stuff can find the files """
2022-08-14 21:40:56 +01:00
try :
w , created = Wallet . objects . get_or_create ( walletname = walletname )
2023-01-30 19:04:36 +00:00
print ( f " --- Wallet string { walletname } , wallet object { w } created new?: { created } " )
2022-08-14 21:40:56 +01:00
if created :
w . fpath = Path ( settings . SCANS_ROOT , walletname [ 0 : 4 ] , walletname )
w . save ( )
except :
2023-01-30 19:04:36 +00:00
print ( f " !-- Wallet string { walletname } , FAIL TO GET or create WALLET OBJECT " )
raise
2022-12-23 22:14:00 +00:00
return w
2022-08-14 21:40:56 +01:00
2022-08-16 19:58:13 +01:00
def commit_json ( waldata ) :
2022-08-14 21:40:56 +01:00
destfolder = contents_path . parent
dr_add = subprocess . run ( [ git , " add " , contentsjson ] , cwd = destfolder , capture_output = True , text = True )
if dr_add . returncode != 0 :
2023-01-30 19:04:36 +00:00
msgdata = (
" Ask a nerd to fix this. \n -- "
+ dr_add . stderr
+ " \n -- "
+ dr_add . stdout
+ " \n --return 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
)
2022-08-14 21:40:56 +01:00
print ( message )
2023-01-30 19:04:36 +00:00
return render ( request , " errors/generic.html " , { " message " : message } )
2022-08-14 21:40:56 +01:00
else :
2022-08-16 18:02:28 +01:00
if socket . gethostname ( ) != " expo " :
2023-01-30 19:04:36 +00:00
comment = f " on dev machine ' { socket . gethostname ( ) } ' "
2022-08-16 18:57:34 +01:00
else :
comment = " "
2022-08-20 07:45:28 +01:00
if " cave " in waldata :
2022-08-16 19:58:13 +01:00
label = waldata [ " cave " ]
else :
2022-08-20 07:45:28 +01:00
if " name " in waldata :
2022-08-16 19:58:13 +01:00
label = waldata [ " name " ]
else :
label = " "
2023-01-30 19:04:36 +00:00
dr_commit = subprocess . run (
[ git , " commit " , " -m " , f " JSON update wallet { wallet } { label } { comment } " ] ,
cwd = destfolder ,
capture_output = True ,
text = True ,
)
2022-08-14 21:40:56 +01:00
# This produces return code = 1 if it commits OK
if dr_commit . returncode != 0 :
2023-01-30 19:04:36 +00:00
msgdata = (
" Ask a nerd to fix this. \n \n "
+ dr_commit . stderr
+ " \n \n "
+ dr_commit . stdout
+ " \n \n return code: "
+ str ( dr_commit . returncode )
)
message = (
f " Error code with git on server for this { contentsjson } . File is added to git, but NOT committed. \n "
+ msgdata
)
2022-08-14 21:40:56 +01:00
print ( message )
2023-01-30 19:04:36 +00:00
return render ( request , " errors/generic.html " , { " message " : message } )
2022-08-14 21:40:56 +01:00
2022-09-13 22:31:37 +01:00
def get_logbook_trips ( ) :
return None
2023-01-30 19:04:36 +00:00
checkboxes = [
" description written " ,
" survex not required " ,
" qms written " ,
" website updated " ,
" plan not required " ,
" plan drawn " ,
" elev not required " ,
" elev drawn " ,
" electronic survey " ,
]
2022-03-18 11:28:35 +00:00
if path :
wallet = urllib . parse . unquote ( path )
else :
2023-01-30 19:04:36 +00:00
wallet = " 2022#00 " # improve this later
2022-03-17 00:41:29 +00:00
2021-05-05 00:35:10 +01:00
year = wallet [ : 4 ]
2022-07-23 18:05:58 +01:00
try :
2023-01-30 19:04:36 +00:00
if wallet [ 4 ] != " # " and wallet [ 4 ] != " : " :
2022-09-23 19:07:51 +01:00
# print(f'! - FORM scanupload - {wallet[4]} unurlencoded {unquote(wallet)[4]}')
# print(f'! - FORM scanupload - start {wallet} REDIRECT TO OLDWALLET')
2023-01-30 19:04:36 +00:00
return oldwallet ( request , path )
2022-07-23 18:05:58 +01:00
except :
# if nonumeric wallet name for example
2023-01-30 19:04:36 +00:00
return oldwallet ( request , path )
if str ( wallet ) . lower ( ) . endswith ( " indexpages " ) :
2022-03-18 20:00:15 +00:00
# print(f'! - FORM scanupload - start {wallet} REDIRECT TO OLDWALLET')
2023-01-30 19:04:36 +00:00
return walletindex ( request , path )
2022-03-18 11:28:35 +00:00
2023-01-30 19:04:36 +00:00
if not re . match ( " (19|20) \ d \ d[:#] \ d \ d " , wallet ) :
wallet = " 2022:00 " # improve this later
2022-03-18 20:00:15 +00:00
# print(f'! - FORM scanupload - start {wallet}')
2023-01-30 19:04:36 +00:00
2022-03-18 11:28:35 +00:00
if path :
2022-03-18 20:00:15 +00:00
pass
# print(f'! - FORM scanupload - start wallet:{wallet}: path:{path}:')
2023-01-30 19:04:36 +00:00
if int ( year ) < 1977 :
2021-05-05 00:35:10 +01:00
year = " 1977 "
2023-01-30 19:04:36 +00:00
if int ( year ) > 2050 :
2021-05-05 00:35:10 +01:00
year = " 2050 "
2023-01-30 19:04:36 +00:00
nexty = f " { int ( year ) + 1 } "
prevy = f " { int ( year ) - 1 } "
2022-03-18 11:28:35 +00:00
2021-05-05 00:35:10 +01:00
wnumber = wallet [ 5 : ]
2023-01-30 19:04:36 +00:00
next = f " { int ( wnumber ) + 1 : 02d } "
prev = f " { int ( wnumber ) - 1 : 02d } "
2021-05-05 00:35:10 +01:00
if int ( wnumber ) == 0 :
2023-01-30 19:04:36 +00:00
prev = f " { int ( wnumber ) : 02d } "
2022-03-15 20:53:55 +00:00
2023-01-30 19:04:36 +00:00
wurl = f " /scanupload/ { wallet } " . replace ( " # " , " : " )
wallet = wallet . replace ( " : " , " # " )
2022-04-18 20:48:49 +01:00
dirpath = Path ( settings . SCANS_ROOT , year , wallet )
2022-08-06 20:23:39 +01:00
contents_path = Path ( settings . DRAWINGS_DATA , " walletjson " ) / year / wallet / contentsjson
2023-01-30 19:04:36 +00:00
2021-05-05 00:35:10 +01:00
form = FilesForm ( )
2023-01-30 19:04:36 +00:00
if request . method == " POST " :
if " psg " in request . POST : # handle metadata form
2022-03-17 00:41:29 +00:00
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 ( ) :
posted = request . POST . copy ( )
2023-01-30 19:04:36 +00:00
posted . pop ( " csrfmiddlewaretoken " ) # discard this
2022-08-24 14:22:15 +01:00
wd = WALLET_BLANK_JSON . copy ( )
2022-03-17 00:41:29 +00:00
for f in checkboxes :
wd [ f ] = False
2023-01-30 19:04:36 +00:00
# print(f'--- wd ${f}$ - {wd[f]}')
2022-03-17 00:41:29 +00:00
for f in posted :
2023-01-30 19:04:36 +00:00
wd [ xlate [ f ] ] = posted [ f ] . replace ( " ' " , ' " ' )
2022-03-17 00:41:29 +00:00
2023-01-30 19:04:36 +00:00
if posted [ f ] == " True " :
2022-03-17 00:41:29 +00:00
wd [ xlate [ f ] ] = True
2023-01-30 19:04:36 +00:00
wd [ " people " ] = wd [ " people " ] [ 1 : - 1 ] . replace ( ' " ' , " " ) . split ( " , " )
2022-03-17 00:41:29 +00:00
for i , elem in enumerate ( wd [ " people " ] ) :
wd [ " people " ] [ i ] = elem . strip ( )
2023-01-30 19:04:36 +00:00
# print(f'--- ${wd["survex file"]}$ - {type(wd["survex file"])}')
if wd [ " survex file " ] : # allow for no survex file at all
if wd [ " survex file " ] [ 0 ] == " [ " :
2022-03-18 12:55:08 +00:00
wd [ " survex file " ] = wd [ " survex file " ] [ 1 : - 1 ]
2023-01-30 19:04:36 +00:00
wd [ " survex file " ] = wd [ " survex file " ] . replace ( ' " ' , " " ) . split ( " , " )
2022-03-18 12:55:08 +00:00
for i , elem in enumerate ( wd [ " survex file " ] ) :
2023-01-30 19:04:36 +00:00
wd [ " survex file " ] [ i ] = elem . strip ( )
# print(f'--- {wd["survex file"]} - {type(wd["survex file"])}')
2022-03-17 00:41:29 +00:00
2022-08-14 21:40:56 +01:00
save_json ( wd )
2022-12-23 22:14:00 +00:00
walletobject = make_wallet ( wallet )
2022-08-16 19:58:13 +01:00
commit_json ( wd )
2023-01-30 19:04:36 +00:00
2022-03-17 00:41:29 +00:00
else :
2023-01-30 19:04:36 +00:00
print ( f " --- INVALID JSON Update form submitted " )
2022-03-17 00:41:29 +00:00
print ( formj . errors )
2023-01-30 19:04:36 +00:00
return render ( request , " errors/generic.html " , { " message " : formj . errors } )
2022-03-17 00:41:29 +00:00
2023-01-30 19:04:36 +00:00
elif (
" walletgoto " in request . POST
) : # not editing wallet data or uploading a file.. going direct to a named wallet
formg = WalletGotoForm ( request . POST , request . FILES )
2022-08-14 20:52:14 +01:00
if formg . is_valid ( ) :
walletgoto = request . POST [ " walletgoto " ]
2023-01-30 19:04:36 +00:00
2022-08-14 20:52:14 +01:00
return HttpResponseRedirect ( f ' /scanupload/ { walletgoto . replace ( " # " , " : " ) } ' )
2023-01-30 19:04:36 +00:00
else : # not editing wallet data, uploading a file. But should not overwrite metadata at all.
form = FilesForm ( request . POST , request . FILES )
2022-03-17 00:41:29 +00:00
if form . is_valid ( ) :
2023-01-30 19:04:36 +00:00
# print(f'--- FORM scanupload multiple BUT EMPTY METADATA supposedly {WALLET_BLANK_JSON["date"]=}')
multiple = request . FILES . getlist ( " uploadfiles " )
fs = FileSystemStorage ( os . path . join ( dirpath ) ) # creates wallet folder if necessary
2022-08-24 15:01:20 +01:00
waldata = read_json ( )
2022-03-17 00:41:29 +00:00
actual_saved = [ ]
if multiple :
for f in multiple :
2023-01-30 19:04:36 +00:00
try : # crashes in Django os.chmod call if on WSL, but does save file!
saved_filename = fs . save ( f . name , content = f )
2022-04-06 18:43:26 +01:00
except :
2023-01-30 19:04:36 +00:00
print ( f " \n !! Permissions failure ?! on attempting to save scanfile { f . name } " )
if " saved_filename " in locals ( ) :
2022-04-06 18:43:26 +01:00
if saved_filename . is_file ( ) :
actual_saved . append ( saved_filename )
# print(f'! - FORM scanupload multiple {actual_saved}')
filesaved = True
2023-01-30 19:04:36 +00:00
# print(f'--- FORM scanupload multiple BUT EMPTY METADATA supposedly {WALLET_BLANK_JSON["date"]=}')
2022-08-24 15:01:20 +01:00
save_json ( waldata )
2022-12-23 22:14:00 +00:00
walletobject = make_wallet ( wallet )
2022-08-16 19:58:13 +01:00
commit_json ( waldata )
2022-09-13 22:31:37 +01:00
#
2022-08-24 14:22:15 +01:00
# Not a POST, so a GET starts here. And also control gets here after a POST is processed.
2022-09-13 22:31:37 +01:00
#
2021-05-05 00:35:10 +01:00
files = [ ]
dirs = [ ]
# print(f'! - FORM scanupload - start {wallet} {dirpath}')
2022-03-15 17:04:43 +00:00
if dirpath . is_dir ( ) :
2023-01-30 19:04:36 +00:00
create = False # wallet exists because folder exists, even if nothing in it
2022-03-15 17:04:43 +00:00
try :
for f in dirpath . iterdir ( ) :
if f . is_dir ( ) :
2022-09-23 22:34:39 +01:00
for d in f . iterdir ( ) :
2023-01-30 19:04:36 +00:00
dirs . append ( f " { f . name } / { d . name } " )
2022-03-15 17:04:43 +00:00
if f . is_file ( ) :
2022-08-14 20:52:14 +01:00
files . append ( f . name )
2022-03-15 17:04:43 +00:00
except FileNotFoundError :
2023-01-30 19:04:36 +00:00
files . append (
" (No wallet yet. It would be created if you upload a scan and then save the form with a date.) "
)
2021-05-05 00:35:10 +01:00
else :
2023-01-30 19:04:36 +00:00
create = True
if len ( files ) > 0 :
2021-05-05 00:35:10 +01:00
files = sorted ( files )
2023-01-30 19:04:36 +00:00
2021-05-05 00:35:10 +01:00
if dirs :
dirs = sorted ( dirs )
2022-09-19 23:02:06 +01:00
try :
waldata = read_json ( )
except :
2023-01-30 19:04:36 +00:00
message = f " Nasty failure in parsing wallets metadata in { contents_path } . Probably backslash not forward slash in filename path "
return render ( request , " errors/generic.html " , { " message " : message } )
2022-09-19 23:02:06 +01:00
2022-08-31 10:09:07 +01:00
jsonfile = Path ( settings . DRAWINGS_DATA , " walletjson " ) / wallet [ 0 : 4 ] / wallet / " contents.json "
2022-09-19 19:54:51 +01:00
# print(f'! - FORM scanupload - jsonfile {jsonfile}')
2022-08-31 10:09:07 +01:00
if not Path ( jsonfile ) . is_file ( ) :
metadataurl = " "
else :
2023-01-30 19:04:36 +00:00
metadataurl = Path ( " /dwgdataraw " , " walletjson " ) / wallet [ 0 : 4 ] / wallet . replace ( " # " , " : " ) / " contents.json "
2022-03-15 20:53:55 +00:00
psg = " "
2022-09-20 20:05:35 +01:00
freetext = " "
2022-03-17 00:41:29 +00:00
chkplannr = " "
chkpland = " "
svxfiles = [ ]
2023-01-30 19:04:36 +00:00
trips = [ ]
2022-03-17 00:41:29 +00:00
checked = { }
2022-08-16 18:02:28 +01:00
context = { }
2023-01-30 19:04:36 +00:00
if waldata : # should always be true as populated by blank data if json file doesn't exist
2022-03-17 00:41:29 +00:00
2023-01-30 19:04:36 +00:00
# if not type(waldata["people"])==list:
# if waldata["people"][0] == '"':
# waldata["people"] = waldata["people"][1:-1]
# waldata["people"] = list(waldata["people"])
2022-03-17 00:41:29 +00:00
2023-01-30 19:04:36 +00:00
if (
not waldata [ " date " ]
or not waldata [ " people " ]
or waldata [ " people " ] == [ " Unknown " ]
or waldata [ " people " ] == [ " " ]
or waldata [ " cave " ] == " "
) : # json file does not exist, blank data, or people not typed into JSON file
2022-09-19 23:02:06 +01:00
# refactor into separate functions for no date set or no people set or no cave set
2022-08-31 07:27:14 +01:00
# print(f'No date set')
2023-01-30 19:04:36 +00:00
print ( f " \n - Incomplete, empty or default wallet data { wallet } { waldata =} " )
refs = [ ]
2022-08-30 18:46:17 +01:00
dates = [ ]
2022-08-31 07:27:14 +01:00
team = [ ]
caverefs = [ ]
2023-01-30 19:04:36 +00:00
caves = [ ]
names = [ ]
svxf = " "
2022-08-31 07:27:14 +01:00
if waldata [ " survex file " ] :
2023-01-30 19:04:36 +00:00
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 " ] ]
2022-08-30 18:46:17 +01:00
for svxf in waldata [ " survex file " ] :
2023-01-30 19:04:36 +00:00
print ( f " - { svxf =} " )
2022-08-31 07:27:14 +01:00
if svxf :
svx = Path ( svxf )
if svx . suffix . lower ( ) != " .svx " :
svx = svx . with_suffix ( " .svx " )
f = Path ( settings . SURVEX_DATA ) / svx
if f . is_file ( ) :
path = svx . parent / svx . stem
2023-01-30 19:04:36 +00:00
# print(f' - {path=}')
2022-09-12 18:50:57 +01:00
try :
svxfile = SurvexFile . objects . get ( path = path )
2023-01-30 19:04:36 +00:00
print ( f " - { svxfile =} " )
2022-09-20 00:36:40 +01:00
if svxfile . cave :
caves . append ( svxfile . cave )
caverefs . append ( svxfile . cave . reference ( ) )
2023-01-30 19:04:36 +00:00
blocks = SurvexBlock . objects . filter ( survexfile = svxfile )
2022-09-20 00:36:40 +01:00
for b in blocks :
2023-01-30 19:04:36 +00:00
print ( f " - - { b =} { b . scanswallet =} { b . date =} " )
2022-09-20 00:36:40 +01:00
if b . scanswallet :
refs . append ( b . scanswallet )
if b . scanswallet . walletname == wallet :
if b . date :
dates . append ( b . date )
if b . name != b . title :
names . append ( str ( b . name ) + " | " + str ( b . title ) )
else :
names . append ( str ( b . name ) )
# we can use the people, across all blocks that have this *ref
QSpeople = SurvexPersonRole . objects . filter ( survexblock = b )
2023-01-30 19:04:36 +00:00
print ( f " - - { QSpeople =} " )
2022-09-20 00:36:40 +01:00
for p in QSpeople :
2023-01-30 19:04:36 +00:00
print ( f " - - { p . personname } " )
2022-09-20 00:36:40 +01:00
team . append ( p . personname )
# else:
2023-01-30 19:04:36 +00:00
# print(f' - Wallet not matching *ref {b.scanswallet=} {wallet}')
2022-09-20 00:36:40 +01:00
except :
2023-01-30 19:04:36 +00:00
message = f " Specified survex file not found - database may be empty, or this survex file is not *included anywhere. "
2022-09-20 00:36:40 +01:00
# return render(request, 'errors/generic.html', {'message': message})
pass
2023-01-30 19:04:36 +00:00
2022-08-31 07:27:14 +01:00
if dates :
waldata [ " date " ] = min ( dates ) . isoformat ( )
2023-01-30 19:04:36 +00:00
print ( f " - - { team =} " )
2022-08-31 07:27:14 +01:00
team = list ( set ( team ) )
waldata [ " people " ] = team
2023-01-30 19:04:36 +00:00
2022-08-31 07:27:14 +01:00
caverefs = list ( set ( caverefs ) )
caves = list ( set ( caves ) )
if len ( caverefs ) == 1 :
waldata [ " cave " ] = caverefs [ 0 ]
2023-01-30 19:04:36 +00:00
print ( f " - Setting wallet cave to { caverefs [ 0 ] } " )
2022-09-19 18:55:34 +01:00
# waldata["description url"] = caves[0]
2022-08-31 07:27:14 +01:00
elif len ( caverefs ) == 0 :
waldata [ " cave " ] = " "
2022-09-19 18:55:34 +01:00
# waldata["description url"] = ""
2023-01-30 19:04:36 +00:00
print ( f " - No caves in this wallet { wallet } . " )
2022-08-31 07:27:14 +01:00
else :
waldata [ " cave " ] = " several caves "
2022-09-19 18:55:34 +01:00
# waldata["description url"] = "several.."
2023-01-30 19:04:36 +00:00
print (
f " - More than one Cave { caves } in this wallet { wallet } . Not managed in this troggle release. "
)
2022-08-31 07:27:14 +01:00
if len ( names ) == 1 :
2023-01-30 19:04:36 +00:00
if waldata [ " name " ] == " " :
2022-08-31 07:27:14 +01:00
waldata [ " name " ] = names [ 0 ]
2023-01-30 19:04:36 +00:00
print ( f " - Setting wallet name to { names [ 0 ] } " )
2022-08-31 07:27:14 +01:00
elif len ( names ) == 0 :
2023-01-30 19:04:36 +00:00
waldata [ " name " ] = " "
print ( f " - Setting wallet name blank " )
2022-08-31 07:27:14 +01:00
else :
waldata [ " name " ] = f " several, please edit: { names } "
2023-01-30 19:04:36 +00:00
print (
f " - More than one block name is relevant { names } in this wallet { wallet } . Not managed in this troggle release. "
)
2022-08-31 07:27:14 +01:00
2022-08-31 10:09:07 +01:00
if " cave " in waldata :
2023-01-30 19:04:36 +00:00
cave = waldata [ " cave " ] # text string
2022-08-31 10:09:07 +01:00
else :
cave = " "
2022-08-31 07:27:14 +01:00
if waldata [ " name " ] :
2023-01-30 19:04:36 +00:00
psg = waldata [ " name " ]
2022-09-20 20:05:35 +01:00
if " free text " in waldata :
2023-01-30 19:04:36 +00:00
freetext = waldata [ " free text " ]
2022-09-13 22:31:37 +01:00
# find trips and survex files of the same date
2022-09-16 19:26:03 +01:00
if waldata [ " date " ] :
2023-01-30 19:04:36 +00:00
datestr = waldata [ " date " ] . replace ( " . " , " - " )
2022-09-16 19:26:03 +01:00
try :
samedate = datetime . date . fromisoformat ( datestr )
except ValueError :
# probably a single digit day number. HACKUS MAXIMUS.
# clearly we need to fix this when we first import date strings..
2023-01-30 19:04:36 +00:00
datestr = datestr [ : - 1 ] + " 0 " + datestr [ - 1 ]
print ( f " - { datestr =} " )
2022-09-20 20:52:31 +01:00
try :
samedate = datetime . date . fromisoformat ( datestr )
except :
try :
samedate = datetime . date . fromisoformat ( datestr [ : 10 ] )
except :
samedate = None
2023-01-30 19:04:36 +00:00
2022-09-16 19:26:03 +01:00
thisexpo = Expedition . objects . get ( year = int ( year ) )
2022-09-20 20:52:31 +01:00
if samedate :
2023-01-29 21:45:51 +00:00
svxothers = SurvexBlock . objects . filter ( date = samedate )
2022-09-20 20:52:31 +01:00
trips = LogbookEntry . objects . filter ( date = samedate )
else :
svxothers = None
trips = None
2023-01-30 19:04:36 +00:00
2022-09-16 19:26:03 +01:00
else :
svxothers = None
trips = None
2023-01-30 19:04:36 +00:00
# Survex and survex complaints, comes from json file on disc, not as pre-populated as above
2022-07-21 07:40:35 +01:00
complaints , caveobject = get_complaints ( [ ] , waldata , svxfiles , files , wallet , wurl )
2022-08-31 07:27:14 +01:00
# print(f' - {caveobject=}')
2022-03-15 23:00:23 +00:00
2022-03-17 00:41:29 +00:00
for f in checkboxes :
2023-01-30 19:04:36 +00:00
if waldata [ f ] :
checked [ f ] = " checked "
survexsize = str ( min ( len ( str ( waldata [ " survex file " ] ) ) , 46 ) )
2022-12-29 13:56:09 +00:00
try :
thiswallet = Wallet . objects . get ( walletname = wallet )
caveifywallet ( thiswallet )
2023-01-30 19:04:36 +00:00
thiswallet . ticks = thiswallet . get_ticks ( ) # the complaints in colour form
# fixsurvextick(thiswallet, thiswallet.ticks)
2022-12-29 13:56:09 +00:00
print ( thiswallet )
except :
thiswallet = None
2023-01-30 19:04:36 +00:00
context = {
" year " : year ,
" prev " : prev ,
" next " : next ,
" prevy " : prevy ,
" nexty " : nexty ,
" files " : files ,
" dirs " : dirs ,
" waldata " : waldata ,
" svxfiles " : svxfiles ,
" checked " : checked ,
" trips " : trips ,
" manywallets " : [ thiswallet ] ,
" svxothers " : svxothers ,
" create " : create ,
" metadataurl " : metadataurl ,
" complaints " : complaints ,
" caveobject " : caveobject ,
" people " : waldata [ " people " ] ,
" peoplesize " : str ( len ( str ( waldata [ " people " ] ) ) ) ,
" filesaved " : filesaved ,
" actual_saved " : actual_saved ,
}
return render (
request ,
" walletform.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 " : survexsize ,
" cave " : cave ,
" psg " : psg ,
" freetext " : freetext ,
" psgsize " : str ( max ( 12 , len ( str ( psg ) ) ) ) ,
" freetextsize " : str ( max ( 60 , len ( str ( freetext ) ) ) ) ,
} ,
)
else : # no wallet data: should never happen as there should be default data in all cases
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 ,
" walletform.html " ,
{
" form " : form ,
" wallet " : wallet ,
* * context ,
" date " : " " ,
#'url': "", 'urlsize': 12,
" survex " : " " ,
" survexsize " : 46 ,
" cave " : cave ,
" psg " : psg ,
" freetext " : freetext ,
" psgsize " : 12 ,
" freetextsize " : 20 ,
} ,
)
2021-05-05 00:35:10 +01:00
2022-03-13 01:01:00 +00:00
@login_required_if_public
def photoupload ( request , folder = None ) :
2023-01-30 19:04:36 +00:00
""" Upload photo image files into /expofiles/photos/<year>/<photographer>/
2022-03-13 01:01:00 +00:00
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 .
2023-01-30 19:04:36 +00:00
When uploading from a phone , it is useful to be able to rename the file to something
2022-08-11 19:19:52 +01:00
meaningful as this is difficult to do on a phone . Previously we had assumed files would
be renamed to something useful before starting the upload .
Unfortunately this only works when uploading one file at at time ,
inevitable once you think about it .
2023-01-30 19:04:36 +00:00
"""
2022-03-13 01:01:00 +00:00
year = settings . PHOTOS_YEAR
filesaved = False
actual_saved = [ ]
2023-01-30 19:04:36 +00:00
context = { " year " : year , " placeholder " : " AnathemaDevice " }
2022-03-13 01:01:00 +00:00
yearpath = Path ( settings . PHOTOS_ROOT , year )
2023-01-30 19:04:36 +00:00
if folder == str ( year ) or folder == str ( year ) + " / " :
2022-03-13 01:01:00 +00:00
folder = None
2023-01-30 19:04:36 +00:00
2022-03-13 01:01:00 +00:00
if folder is None :
2023-01-30 19:04:36 +00:00
folder = " " # improve this later
2022-03-13 01:01:00 +00:00
dirpath = Path ( settings . PHOTOS_ROOT , year )
2023-01-30 19:04:36 +00:00
urlfile = f " /expofiles/photos/ { year } "
urldir = f " /photoupload/ { year } "
else : # it will contain the year as well as the photographer
2022-03-13 01:01:00 +00:00
dirpath = Path ( settings . PHOTOS_ROOT , folder )
if dirpath . is_dir ( ) :
2023-01-30 19:04:36 +00:00
urlfile = f " /expofiles/photos/ { folder } "
urldir = Path ( " /photoupload " ) / folder
2022-03-13 01:01:00 +00:00
else :
2023-01-30 19:04:36 +00:00
folder = " " # improve this later
2022-03-13 01:01:00 +00:00
dirpath = Path ( settings . PHOTOS_ROOT , year )
2023-01-30 19:04:36 +00:00
urlfile = f " /expofiles/photos/ { year } "
urldir = f " /photoupload/ { year } "
2022-08-11 19:19:52 +01:00
form = FilesRenameForm ( )
2023-01-30 19:04:36 +00:00
formd = TextForm ( )
if request . method == " POST " :
if " photographer " in request . POST :
2022-03-13 01:01:00 +00:00
formd = TextForm ( request . POST )
if formd . is_valid ( ) :
newphotographer = request . POST [ " photographer " ]
2022-11-23 21:59:42 +00:00
try :
( yearpath / newphotographer ) . mkdir ( exist_ok = True )
except :
2023-01-30 19:04:36 +00:00
message = f ' \n !! Permissions failure ?! 0 attempting to mkdir " { ( yearpath / newphotographer ) } " '
2022-11-23 21:59:42 +00:00
print ( message )
2023-01-30 19:04:36 +00:00
return render ( request , " errors/generic.html " , { " message " : message } )
2022-11-23 21:59:42 +00:00
2022-03-13 01:01:00 +00:00
else :
2023-01-30 19:04:36 +00:00
form = FilesRenameForm ( request . POST , request . FILES )
2022-03-13 01:01:00 +00:00
if form . is_valid ( ) :
f = request . FILES [ " uploadfiles " ]
2023-01-30 19:04:36 +00:00
multiple = request . FILES . getlist ( " uploadfiles " )
2022-03-15 23:00:23 +00:00
# NO CHECK that the files being uploaded are image files
2022-03-13 01:01:00 +00:00
fs = FileSystemStorage ( dirpath )
2023-01-30 19:04:36 +00:00
2022-08-11 19:19:52 +01:00
renameto = request . POST [ " renameto " ]
2023-01-30 19:04:36 +00:00
2022-03-13 01:01:00 +00:00
actual_saved = [ ]
2023-01-30 19:04:36 +00:00
if multiple :
2022-08-11 19:19:52 +01:00
if len ( multiple ) == 1 :
2022-08-11 21:35:53 +01:00
if renameto != " " :
2023-01-30 19:04:36 +00:00
try : # crashes in Django os.chmod call if on WSL, but does save file!
saved_filename = fs . save ( renameto , content = f )
2022-08-11 21:35:53 +01:00
except :
2023-01-30 19:04:36 +00:00
print (
f ' \n !! Permissions failure ?! 1 attempting to save " { f . name } " in " { dirpath } " { renameto =} '
)
if " saved_filename " in locals ( ) :
2022-08-11 21:35:53 +01:00
if saved_filename . is_file ( ) :
actual_saved . append ( saved_filename )
2023-01-30 19:04:36 +00:00
filesaved = True
else : # multiple is the uploaded content
try : # crashes in Django os.chmod call if on WSL, but does save file!
saved_filename = fs . save ( f . name , content = f )
2022-08-11 21:35:53 +01:00
except :
2023-01-30 19:04:36 +00:00
print (
f ' \n !! Permissions failure ?! 2 attempting to save " { f . name } " in " { dirpath } " { renameto =} '
)
if " saved_filename " in locals ( ) :
2022-08-11 21:35:53 +01:00
if saved_filename . is_file ( ) :
actual_saved . append ( saved_filename )
2023-01-30 19:04:36 +00:00
filesaved = True
else : # multiple is a list of content
2022-08-11 19:19:52 +01:00
for f in multiple :
2023-01-30 19:04:36 +00:00
try : # crashes in Django os.chmod call if on WSL, but does save file!
saved_filename = fs . save ( f . name , content = f )
2022-08-11 19:19:52 +01:00
except :
2023-01-30 19:04:36 +00:00
print (
f ' \n !! Permissions failure ?! 3 attempting to save " { f . name } " in " { dirpath } " { renameto =} '
)
if " saved_filename " in locals ( ) :
2022-08-11 19:19:52 +01:00
if saved_filename . is_file ( ) :
actual_saved . append ( saved_filename )
2023-01-30 19:04:36 +00:00
filesaved = True
2022-03-13 01:01:00 +00:00
files = [ ]
dirs = [ ]
try :
for f in dirpath . iterdir ( ) :
if f . is_dir ( ) :
dirs . append ( f . name )
if f . is_file ( ) :
2023-01-30 19:04:36 +00:00
files . append ( f . name )
2022-03-13 01:01:00 +00:00
except FileNotFoundError :
2023-01-30 19:04:36 +00:00
files . append ( " (no folder yet - would be created) " )
if len ( files ) > 0 :
2022-03-13 01:01:00 +00:00
files = sorted ( files )
2023-01-30 19:04:36 +00:00
2022-03-13 01:01:00 +00:00
if dirs :
dirs = sorted ( dirs )
2023-01-30 19:04:36 +00:00
return render (
request ,
" photouploadform.html " ,
{
" form " : form ,
* * context ,
" urlfile " : urlfile ,
" urldir " : urldir ,
" folder " : folder ,
" files " : files ,
" dirs " : dirs ,
" filesaved " : filesaved ,
" actual_saved " : actual_saved ,
} ,
)
2022-03-13 01:01:00 +00:00
2021-05-05 00:35:10 +01:00
@login_required_if_public
2023-01-30 19:04:36 +00:00
def dwgupload ( request , folder = None , gitdisable = " no " ) :
""" Upload DRAWING files (tunnel or therion) into the upload folder in :drawings
2022-03-08 22:59:04 +00:00
AND registers it into the : drawings : git repo .
2023-01-30 19:04:36 +00:00
2021-05-05 00:35:10 +01:00
This does NOT use a Django model linked to a Django form . Just a simple Django form .
2022-03-08 22:59:04 +00:00
You will find the Django documentation on forms very confusing , This is simpler .
2023-01-30 19:04:36 +00:00
2022-08-11 19:19:52 +01:00
We could validate the uploaded files as being a valid files using an XML parser , not a dubious script or hack
2022-03-08 22:59:04 +00:00
2023-01-30 19:04:36 +00:00
2021-05-05 00:35:10 +01:00
We use get_or_create instead of simply creating a new object in case someone uploads the same file
several times in one session , and expects them to be overwritten in the database . Although
2022-03-05 20:29:01 +00:00
the actual file will be duplicated in the filesystem with different random name ending .
2023-01-30 19:04:36 +00:00
"""
2021-05-05 00:35:10 +01:00
def dwgvalid ( name ) :
2023-01-30 19:04:36 +00:00
if name in [
" .gitignore " ,
] :
2021-05-05 00:35:10 +01:00
return False
2023-01-30 19:04:36 +00:00
if Path ( name ) . suffix . lower ( ) in [ " .xml " , " .th " , " .th2 " , " " , " .svg " , " .txt " ] :
return True # dangerous, we should check the actual file binary signature
2021-05-05 00:35:10 +01:00
return False
2022-03-05 22:16:03 +00:00
def dwgvaliddisp ( name ) :
2023-01-30 19:04:36 +00:00
""" OK to display, even if we are not going to allow a new one to be uploaded """
if name in [
" .gitignore " ,
] :
2022-03-05 22:16:03 +00:00
return False
2023-01-30 19:04:36 +00:00
if Path ( name ) . suffix . lower ( ) in [
" .xml " ,
" .th " ,
" .th2 " ,
" " ,
" .svg " ,
" .txt " ,
" .jpg " ,
" .jpeg " ,
" .png " ,
" .pdf " ,
" .top " ,
" .topo " ,
] :
return True # dangerous, we should check the actual file binary signature
2022-03-05 22:16:03 +00:00
return False
2021-05-05 00:35:10 +01:00
filesaved = False
actual_saved = [ ]
refused = [ ]
2023-01-30 19:04:36 +00:00
doesnotexist = " "
2021-10-31 17:25:45 +00:00
# print(f'! - FORM dwgupload - start "{folder}" - gitdisable "{gitdisable}"')
2021-05-05 00:35:10 +01:00
if folder is None :
2023-01-30 19:04:36 +00:00
folder = " " # improve this later
2021-05-05 00:35:10 +01:00
dirpath = Path ( settings . DRAWINGS_DATA )
2023-01-30 19:04:36 +00:00
urlfile = " /dwgdataraw "
urldir = " /dwgupload "
2021-05-05 00:35:10 +01:00
else :
dirpath = Path ( settings . DRAWINGS_DATA , folder )
2023-01-30 19:04:36 +00:00
urlfile = Path ( " /dwgdataraw/ " ) / folder
urldir = Path ( " /dwgupload/ " ) / folder
2021-05-05 00:35:10 +01:00
form = FilesForm ( )
2023-01-30 19:04:36 +00:00
if request . method == " POST " :
form = FilesForm ( request . POST , request . FILES )
2021-05-05 00:35:10 +01:00
if form . is_valid ( ) :
2022-08-13 19:14:57 +01:00
# print(f'! - FORM dwgupload - POST valid: "{request.FILES["uploadfiles"]}" ')
2021-05-05 00:35:10 +01:00
f = request . FILES [ " uploadfiles " ]
2023-01-30 19:04:36 +00:00
multiple = request . FILES . getlist ( " uploadfiles " )
2022-11-23 21:59:42 +00:00
savepath = Path ( settings . DRAWINGS_DATA , folder )
fs = FileSystemStorage ( savepath )
2023-01-30 19:04:36 +00:00
2021-05-05 00:35:10 +01:00
actual_saved = [ ]
refused = [ ]
2023-01-30 19:04:36 +00:00
2022-03-05 17:05:15 +00:00
# GIT see also core/views/expo.py editexpopage()
# GIT see also core/models/cave.py writetrogglefile()
2023-01-30 19:04:36 +00:00
if gitdisable != " yes " : # set in url 'dwguploadnogit/'
2021-10-31 17:25:45 +00:00
git = settings . GIT
else :
2023-01-30 19:04:36 +00:00
git = " echo "
2022-08-13 19:14:57 +01:00
# print(f'git DISABLED {f.name}')
2021-10-31 17:25:45 +00:00
2021-05-05 00:35:10 +01:00
if multiple :
for f in multiple :
2022-08-13 19:14:57 +01:00
# print(f'! - FORM dwgupload - file {f} in {multiple=}')
2021-05-05 00:35:10 +01:00
if dwgvalid ( f . name ) :
2023-01-30 19:04:36 +00:00
try : # crashes in Django os.chmod call if on WSL without metadata drvfs, but does save file!
saved_filename = fs . save ( f . name , content = f )
2022-04-06 18:43:26 +01:00
except :
2023-01-30 19:04:36 +00:00
print (
f ' ! - FORM dwgupload - \n !! Permissions failure ?! on attempting to save file " { f . name } " in " { savepath } " . Attempting to continue.. '
)
if " saved_filename " in locals ( ) :
2022-08-13 19:14:57 +01:00
if Path ( dirpath , saved_filename ) . is_file ( ) :
actual_saved . append ( saved_filename )
2023-01-30 19:04:36 +00:00
if gitdisable != " yes " :
dr_add = subprocess . run (
[ git , " add " , saved_filename ] , cwd = dirpath , capture_output = True , text = True
)
msgdata = (
dr_add . stderr
+ " \n "
+ dr_add . stdout
+ " \n return code: "
+ str ( dr_add . returncode )
)
2022-08-13 19:14:57 +01:00
# message = f'! - FORM dwgupload - Success: git ADD on server for this file {saved_filename}.' + msgdata
# print(message)
2022-04-06 18:43:26 +01:00
if dr_add . returncode != 0 :
2023-01-30 19:04:36 +00:00
msgdata = (
" Ask a nerd to fix this. \n \n "
+ dr_add . stderr
+ " \n \n "
+ dr_add . stdout
+ " \n \n return code: "
+ str ( dr_add . returncode )
)
message = (
f " ! - FORM dwgupload - CANNOT git ADD on server for this file { saved_filename } . Edits saved but not added to git. \n "
+ msgdata
)
2022-08-13 19:14:57 +01:00
print ( message )
2023-01-30 19:04:36 +00:00
return render ( request , " errors/generic.html " , { " message " : message } )
dwgfile , created = DrawingFile . objects . get_or_create (
dwgpath = saved_filename , dwgname = Path ( f . name ) . stem , filesize = f . size
)
2022-08-13 19:14:57 +01:00
dwgfile . save ( )
else :
2023-01-30 19:04:36 +00:00
message = f " ! - FORM dwgupload - NOT A FILE { Path ( dirpath , saved_filename ) =} . "
2022-08-13 19:14:57 +01:00
print ( message )
else :
2023-01-30 19:04:36 +00:00
message = f " ! - FORM dwgupload - Save failure for { f . name } . Changes NOT saved. "
2022-08-13 19:14:57 +01:00
print ( message )
2023-01-30 19:04:36 +00:00
return render ( request , " errors/generic.html " , { " message " : message } )
2022-08-13 19:14:57 +01:00
if saved_filename != f . name :
# message = f'! - FORM dwgupload - Save RENAME {f.name} renamed as {saved_filename}. This is OK.'
# print(message)
pass
2023-01-30 19:04:36 +00:00
2021-05-05 00:35:10 +01:00
else :
refused . append ( f . name )
2022-08-13 19:14:57 +01:00
# print(f'REFUSED {f.name}')
2023-01-30 19:04:36 +00:00
if actual_saved :
2021-10-31 17:25:45 +00:00
filesaved = True
2022-03-05 22:16:03 +00:00
if len ( actual_saved ) > 1 :
dots = " ... "
else :
dots = " "
2023-01-30 19:04:36 +00:00
if gitdisable != " yes " :
dr_commit = subprocess . run (
[ git , " commit " , " -m " , f " Drawings upload - { actual_saved [ 0 ] } { dots } " ] ,
cwd = dirpath ,
capture_output = True ,
text = True ,
)
2022-08-13 19:14:57 +01:00
# message = f'! - FORM dwgupload - For uploading {actual_saved[0]}{dots}. Edits saved, added to git, and COMMITTED.\n' + msgdata
# print(message)
2022-03-05 22:16:03 +00:00
# This produces return code = 1 if it commits OK
if dr_commit . returncode != 0 :
2023-01-30 19:04:36 +00:00
msgdata = (
" Ask a nerd to fix this. \n \n "
+ dr_commit . stderr
+ " \n "
+ dr_commit . stdout
+ " \n return code: "
+ str ( dr_commit . returncode )
)
message = (
f " ! - FORM dwgupload -Error code with git on server for this { actual_saved [ 0 ] } { dots } . Edits saved, added to git, but NOT committed. \n "
+ msgdata
)
2022-08-13 19:14:57 +01:00
print ( message )
2023-01-30 19:04:36 +00:00
return render ( request , " errors/generic.html " , { " message " : message } )
2022-08-13 19:14:57 +01:00
else :
print ( f ' git disabled " { git =} " ' )
2023-01-30 19:04:36 +00:00
else : # maybe all were refused by the suffix test in dwgvalid()
message = f " ! - FORM dwgupload - Nothing actually saved. All were refused. { actual_saved =} "
2022-08-13 19:14:57 +01:00
print ( message )
2021-10-31 17:25:45 +00:00
2021-05-05 00:35:10 +01:00
files = [ ]
dirs = [ ]
2022-08-13 19:14:57 +01:00
# print(f'! - FORM dwgupload - start {folder=} \n"{dirpath=}" \n"{dirpath.parent=}" \n"{dirpath.exists()=}"')
2021-05-05 00:35:10 +01:00
try :
for f in dirpath . iterdir ( ) :
if f . is_dir ( ) :
2023-01-30 19:04:36 +00:00
if f . name not in [ " .git " ] :
2021-05-05 00:35:10 +01:00
dirs . append ( f . name )
continue
if f . is_file ( ) :
2023-01-30 19:04:36 +00:00
if dwgvaliddisp ( f . name ) :
2021-05-05 00:35:10 +01:00
files . append ( f . name )
continue
except FileNotFoundError :
doesnotexist = True
if files :
files = sorted ( files )
2023-01-30 19:04:36 +00:00
2021-05-05 00:35:10 +01:00
if dirs :
dirs = sorted ( dirs )
2023-01-30 19:04:36 +00:00
return render (
request ,
" dwguploadform.html " ,
{
" form " : form ,
" doesnotexist " : doesnotexist ,
" urlfile " : urlfile ,
" urldir " : urldir ,
" folder " : folder ,
" files " : files ,
" dirs " : dirs ,
" filesaved " : filesaved ,
" actual_saved " : actual_saved ,
" refused " : refused ,
} ,
)