mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2024-11-22 07:11:52 +00:00
Upload form for Photos
This commit is contained in:
parent
f99ebf84e9
commit
b65639df05
@ -153,7 +153,7 @@ class PageTests(TestCase):
|
|||||||
|
|
||||||
def test_expoweb_via_areaid(self):
|
def test_expoweb_via_areaid(self):
|
||||||
# the dispatcher takes a detour via the cave renering procedure for this
|
# the dispatcher takes a detour via the cave renering procedure for this
|
||||||
response = self.client.get('/1623/others/t/via201.jpg')
|
response = self.client.get('/guidebook/t/via201.jpg')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(len(response.content), 6057)
|
self.assertEqual(len(response.content), 6057)
|
||||||
|
|
||||||
@ -175,7 +175,6 @@ class PageTests(TestCase):
|
|||||||
phmatch = re.search(ph, content)
|
phmatch = re.search(ph, content)
|
||||||
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
|
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
|
||||||
|
|
||||||
|
|
||||||
def test_page_admin(self):
|
def test_page_admin(self):
|
||||||
# see the login page
|
# see the login page
|
||||||
response = self.client.get('/admin/login/')
|
response = self.client.get('/admin/login/')
|
||||||
|
@ -12,6 +12,7 @@ from django.shortcuts import render
|
|||||||
from django.template import Context, loader
|
from django.template import Context, loader
|
||||||
from django.core.files.storage import FileSystemStorage, default_storage
|
from django.core.files.storage import FileSystemStorage, default_storage
|
||||||
|
|
||||||
|
#from troggle import settings
|
||||||
from troggle.parsers.imports import import_caves, import_people, import_surveyscans
|
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.imports import import_logbooks, import_QMs, import_drawingsfiles, import_survex
|
||||||
# from databaseReset import reinit_db # don't do this. databaseRest runs code *at import time*
|
# from databaseReset import reinit_db # don't do this. databaseRest runs code *at import time*
|
||||||
@ -19,6 +20,7 @@ from troggle.core.models.troggle import Expedition, Person, PersonExpedition
|
|||||||
from troggle.core.models.caves import LogbookEntry, QM, Cave, PersonTrip
|
from troggle.core.models.caves import LogbookEntry, QM, Cave, PersonTrip
|
||||||
from troggle.core.models.survex import DrawingFile
|
from troggle.core.models.survex import DrawingFile
|
||||||
from .auth import login_required_if_public
|
from .auth import login_required_if_public
|
||||||
|
#from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt
|
||||||
|
|
||||||
'''File upload 'views'
|
'''File upload 'views'
|
||||||
'''
|
'''
|
||||||
@ -42,6 +44,9 @@ todo = '''
|
|||||||
class FilesForm(forms.Form): # not a model-form, just a form-form
|
class FilesForm(forms.Form): # not a model-form, just a form-form
|
||||||
uploadfiles = forms.FileField()
|
uploadfiles = forms.FileField()
|
||||||
|
|
||||||
|
class TextForm(forms.Form): # not a model-form, just a form-form
|
||||||
|
photographer = forms.CharField(strip=True)
|
||||||
|
|
||||||
@login_required_if_public
|
@login_required_if_public
|
||||||
def scanupload(request, wallet=None):
|
def scanupload(request, wallet=None):
|
||||||
'''Upload scanned image files into a wallet on /expofiles
|
'''Upload scanned image files into a wallet on /expofiles
|
||||||
@ -77,9 +82,11 @@ def scanupload(request, wallet=None):
|
|||||||
dirpath = Path(settings.SURVEY_SCANS, year, wallet)
|
dirpath = Path(settings.SURVEY_SCANS, year, wallet)
|
||||||
|
|
||||||
form = FilesForm()
|
form = FilesForm()
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = FilesForm(request.POST,request.FILES)
|
form = FilesForm(request.POST,request.FILES)
|
||||||
|
print(f'! - FilesForm POSTED')
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
f = request.FILES["uploadfiles"]
|
f = request.FILES["uploadfiles"]
|
||||||
multiple = request.FILES.getlist('uploadfiles')
|
multiple = request.FILES.getlist('uploadfiles')
|
||||||
@ -115,6 +122,80 @@ def scanupload(request, wallet=None):
|
|||||||
return render(request, 'scanuploadform.html',
|
return render(request, 'scanuploadform.html',
|
||||||
{'form': form, 'wallet': wallet, **context, 'files': files, 'dirs': dirs, 'filesaved': filesaved, 'actual_saved': actual_saved})
|
{'form': form, 'wallet': wallet, **context, 'files': files, 'dirs': dirs, 'filesaved': filesaved, 'actual_saved': actual_saved})
|
||||||
|
|
||||||
|
@login_required_if_public
|
||||||
|
def photoupload(request, folder=None):
|
||||||
|
'''Upload photo image files into /expofiles/photos/<year>/<photographer>/
|
||||||
|
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.
|
||||||
|
'''
|
||||||
|
year = settings.PHOTOS_YEAR
|
||||||
|
filesaved = False
|
||||||
|
actual_saved = []
|
||||||
|
|
||||||
|
context = {'year': year, 'placeholder': "AnathemaDevice"}
|
||||||
|
|
||||||
|
yearpath = Path(settings.PHOTOS_ROOT, year)
|
||||||
|
|
||||||
|
if folder == str(year) or folder == str(year) +"/":
|
||||||
|
folder = None
|
||||||
|
|
||||||
|
if folder is None:
|
||||||
|
folder = "" # improve this later
|
||||||
|
dirpath = Path(settings.PHOTOS_ROOT, year)
|
||||||
|
urlfile = f'/expofiles/photos/{year}'
|
||||||
|
urldir = f'/photoupload/{year}'
|
||||||
|
else: # it will contain the year as well as the photographer
|
||||||
|
dirpath = Path(settings.PHOTOS_ROOT, folder)
|
||||||
|
if dirpath.is_dir():
|
||||||
|
urlfile = f'/expofiles/photos/{folder}'
|
||||||
|
urldir = Path('/photoupload') / folder
|
||||||
|
else:
|
||||||
|
folder = "" # improve this later
|
||||||
|
dirpath = Path(settings.PHOTOS_ROOT, year)
|
||||||
|
urlfile = f'/expofiles/photos/{year}'
|
||||||
|
urldir = f'/photoupload/{year}'
|
||||||
|
|
||||||
|
|
||||||
|
form = FilesForm()
|
||||||
|
formd = TextForm()
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
if "photographer" in request.POST:
|
||||||
|
formd = TextForm(request.POST)
|
||||||
|
if formd.is_valid():
|
||||||
|
newphotographer = request.POST["photographer"]
|
||||||
|
(yearpath / newphotographer).mkdir(exist_ok=True)
|
||||||
|
else:
|
||||||
|
form = FilesForm(request.POST,request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
f = request.FILES["uploadfiles"]
|
||||||
|
multiple = request.FILES.getlist('uploadfiles')
|
||||||
|
fs = FileSystemStorage(dirpath)
|
||||||
|
|
||||||
|
actual_saved = []
|
||||||
|
if multiple:
|
||||||
|
for f in multiple:
|
||||||
|
actual_saved.append( fs.save(f.name, content=f) )
|
||||||
|
filesaved = True
|
||||||
|
files = []
|
||||||
|
dirs = []
|
||||||
|
try:
|
||||||
|
for f in dirpath.iterdir():
|
||||||
|
if f.is_dir():
|
||||||
|
dirs.append(f.name)
|
||||||
|
if f.is_file():
|
||||||
|
files.append(f.name)
|
||||||
|
except FileNotFoundError:
|
||||||
|
files.append('(no folder yet - would be created)')
|
||||||
|
if len(files) >0 :
|
||||||
|
files = sorted(files)
|
||||||
|
|
||||||
|
if dirs:
|
||||||
|
dirs = sorted(dirs)
|
||||||
|
|
||||||
|
return render(request, 'photouploadform.html',
|
||||||
|
{'form': form, **context, 'urlfile': urlfile, 'urldir': urldir,'folder': folder, 'files': files, 'dirs': dirs, 'filesaved': filesaved, 'actual_saved': actual_saved})
|
||||||
|
|
||||||
@login_required_if_public
|
@login_required_if_public
|
||||||
def dwgupload(request, folder=None, gitdisable='no'):
|
def dwgupload(request, folder=None, gitdisable='no'):
|
||||||
'''Upload DRAWING files (tunnel or therion) into the upload folder in :drawings
|
'''Upload DRAWING files (tunnel or therion) into the upload folder in :drawings
|
||||||
|
@ -427,7 +427,7 @@ div#difflistajax
|
|||||||
background-color: #dfffdf;
|
background-color: #dfffdf;
|
||||||
border: thin green solid;
|
border: thin green solid;
|
||||||
}
|
}
|
||||||
|
/* Using in DrawingsUpload and ScanUpload*/
|
||||||
.fancybutton {
|
.fancybutton {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font: 18px Georgia, "Times New Roman", Times, serif;
|
font: 18px Georgia, "Times New Roman", Times, serif;
|
||||||
@ -479,6 +479,58 @@ div#difflistajax
|
|||||||
background: linear-gradient(bottom, #39b2e5, #6083BF);
|
background: linear-gradient(bottom, #39b2e5, #6083BF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used in PhotoUpload and GPSlog upload */
|
||||||
|
.fancybutton2 {
|
||||||
|
color: #ffffff;
|
||||||
|
font: 18px Georgia, "Times New Roman", Times, serif;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
|
||||||
|
text-shadow: 0 1px 1px #000000;
|
||||||
|
|
||||||
|
#display: block;
|
||||||
|
/* margin: auto; */
|
||||||
|
font-size: 1.2em;
|
||||||
|
line-height: 1.25em;
|
||||||
|
|
||||||
|
padding: 7px 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: static;
|
||||||
|
background: #9ff;
|
||||||
|
border: 1px solid #60AABF;
|
||||||
|
/* -moz-border-radius: 20px;
|
||||||
|
-webkit-border-radius: 20px;
|
||||||
|
-khtml-border-radius: 20px;*/
|
||||||
|
border-radius: 20px;
|
||||||
|
/*
|
||||||
|
-webkit-box-shadow: rgba(0, 0, 0, .25) 0 1px 1px;
|
||||||
|
-moz-box-shadow: rgba(0, 0, 0, .25) 0 1px 1px;
|
||||||
|
-o-box-shadow: rgba(0, 0, 0, .25) 0 1px 1px;*/
|
||||||
|
box-shadow: rgba(0, 0, 0, .25) 0 1px 1px;
|
||||||
|
background: #9ff;
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, from(#9ff), to(#6083fF));
|
||||||
|
background: -moz-linear-gradient(top, #9ff, #6083fF);
|
||||||
|
background: -o-linear-gradient(top, #9ff, #6083fF);
|
||||||
|
background: linear-gradient(top, #9ff, #6083fF);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fancybutton2:hover,
|
||||||
|
.fancybutton2:focus {
|
||||||
|
cursor: pointer;
|
||||||
|
border-color: blue;
|
||||||
|
/* -webkit-box-shadow: aqua 0 0 8px;
|
||||||
|
-moz-box-shadow: aqua 0 0 8px;
|
||||||
|
-o-box-shadow: aqua 0 0 8px; */
|
||||||
|
box-shadow: aqua 0 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fancybutton2:active {
|
||||||
|
background: #39e5b2;
|
||||||
|
/* background: -webkit-gradient(linear, left bottom, left top, from(#39e5b2), to(#6083BF));
|
||||||
|
background: -moz-linear-gradient(bottom, #39e5b2, #6083BF);
|
||||||
|
background: -o-linear-gradient(bottom, #39e5b2, #6083BF); */
|
||||||
|
background: linear-gradient(bottom, #9ff, #6083BF);
|
||||||
|
}
|
||||||
|
|
||||||
/* For the Scan upload form - to be used with a phone */
|
/* For the Scan upload form - to be used with a phone */
|
||||||
::-webkit-file-upload-button {
|
::-webkit-file-upload-button {
|
||||||
padding: 0.3em;
|
padding: 0.3em;
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
<a href="{% url "scanupload" '2021:01' %}">Upload Scans</a> |
|
<a href="{% url "scanupload" '2021:01' %}">Upload Scans</a> |
|
||||||
<a href="{% url "dwgallfiles" %}">Drawings</a> |
|
<a href="{% url "dwgallfiles" %}">Drawings</a> |
|
||||||
<a href="{% url "dwgupload" %}">Upload 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="/1623/290/290.html">290 (FGH)</a> |
|
||||||
<a href="/1626/359/359.html">359 (Homecoming)</a> |
|
<a href="/1626/359/359.html">359 (Homecoming)</a> |
|
||||||
<br>
|
<br>
|
||||||
|
93
templates/photouploadform.html
Normal file
93
templates/photouploadform.html
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Simple Fileupload (Photos){% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if folder %}
|
||||||
|
<h2>Upload photos into /photos/{{folder}}/</h2>
|
||||||
|
{% else %}
|
||||||
|
<h2>Upload photos into /photos/{{year}}/</h2>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
<div style = "max-width:35%; margin-left:20%; text-align: center; " >
|
||||||
|
<form method ='post' enctype ="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
<br>
|
||||||
|
<input class="fancybutton2" type = "file" multiple="multiple"
|
||||||
|
name = "uploadfiles" id="uploadfiles" />
|
||||||
|
<br><br><br>
|
||||||
|
<button class="fancybutton2" style="padding: 0.5em 25px; margin-left: 155px" type = "submit" value = "Upload" >
|
||||||
|
Upload
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div style = "max-width:29%; margin-left:20%; text-align: left" >
|
||||||
|
{% if filesaved %}
|
||||||
|
<p>
|
||||||
|
<b>File(s) saved as <br>
|
||||||
|
{% for f in actual_saved %}
|
||||||
|
<em>{{f}}</em> <br>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<strong style="font-size: 110%;">Files:</strong><br>
|
||||||
|
{% for f in files %}
|
||||||
|
<a href="{{urlfile|urlencode}}/{{f|urlencode}}">{{f}}</a><br />
|
||||||
|
{% empty %}
|
||||||
|
<p><No files here>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
<p><strong style="font-size: 110%;">Photographer Directories:</strong><br>
|
||||||
|
{% if folder %}
|
||||||
|
<a href="{{urldir}}/..">[up]</a><br />
|
||||||
|
{% endif %}
|
||||||
|
{% for f in dirs %}
|
||||||
|
<a href="{{urldir}}/{{f}}">/{{f}}/</a><br />
|
||||||
|
{% empty %}
|
||||||
|
<p><No subdirectories>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% if folder %}
|
||||||
|
<p>You can upload your photographs here.
|
||||||
|
<p>You cannot create sub-folders here.
|
||||||
|
<p>Note that only photo image files are accepted: all other types of files are refused.
|
||||||
|
{% else %}
|
||||||
|
<p>You can upload your photographs to any of these folders, and you can create a new folder in your name for your photos.
|
||||||
|
<p>Note that only photo image files are accepted: all other types of files are refused.
|
||||||
|
<hr>
|
||||||
|
<h2>Create new Photographer folder in /photos/{{year}}/</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div style = "max-width:35%; margin-left:20%; text-align: center; " >
|
||||||
|
<form method ='post'>
|
||||||
|
{% csrf_token %}
|
||||||
|
<br>
|
||||||
|
<input class="fancybutton2" style="padding: 0.5em 25px; margin-left: 125px"
|
||||||
|
label = "Photographer" name = "photographer" id="photographer"
|
||||||
|
pattern="[A-Za-z]+"
|
||||||
|
placeholder="{{placeholder}}" required />
|
||||||
|
<label
|
||||||
|
style="padding: 0.5em 25px; margin-left: 110px"
|
||||||
|
for="photographer">Photographer's name<br></label>
|
||||||
|
<label
|
||||||
|
style="padding: 0.5em 25px; margin-left: 110px"
|
||||||
|
for="photographer">(no spaces, only letters)</label>
|
||||||
|
<br><br><br>
|
||||||
|
<button class="fancybutton2" style="padding: 0.5em 25px; margin-left: 155px" type = "submit" value = "Create" >
|
||||||
|
Create folder
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
10
urls.py
10
urls.py
@ -10,7 +10,7 @@ from django.urls import path, reverse, resolve
|
|||||||
from troggle.core.views import caves, statistics, survex
|
from troggle.core.views import caves, statistics, survex
|
||||||
from troggle.core.views.scans import scansingle, singlewallet, allwallets
|
from troggle.core.views.scans import scansingle, singlewallet, allwallets
|
||||||
from troggle.core.views.drawings import dwgallfiles, dwgfilesingle
|
from troggle.core.views.drawings import dwgallfiles, dwgfilesingle
|
||||||
from troggle.core.views.uploads import dwgupload, scanupload
|
from troggle.core.views.uploads import dwgupload, scanupload, photoupload
|
||||||
from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage
|
from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage
|
||||||
from troggle.core.views.other import exportlogbook
|
from troggle.core.views.other import exportlogbook
|
||||||
from troggle.core.views.caves import ent, cavepage
|
from troggle.core.views.caves import ent, cavepage
|
||||||
@ -86,9 +86,11 @@ trogglepatterns = [
|
|||||||
re_path(r'^admin/', admin.site.urls), # includes admin login & logout urls
|
re_path(r'^admin/', admin.site.urls), # includes admin login & logout urls
|
||||||
|
|
||||||
# Uploads - uploading a file
|
# Uploads - uploading a file
|
||||||
path('scanupload/<wallet>', scanupload, name='scanupload'), # wallet=2020#01, not a path
|
path('scanupload/<wallet>', scanupload, name='scanupload'), # wallet=2020#01, not a path
|
||||||
path('dwgupload/<path:folder>', dwgupload, name='dwgupload'),
|
path('photoupload/', photoupload, name='photoupload'), # restricted to current year
|
||||||
path('dwgupload/', dwgupload, name='dwgupload'),
|
path('photoupload/<path:folder>', photoupload, name='photoupload'), # restricted to current year
|
||||||
|
path('dwgupload/<path:folder>', dwgupload, name='dwgupload'),
|
||||||
|
path('dwgupload/', dwgupload, name='dwgupload'),
|
||||||
path('dwguploadnogit/', dwgupload, {'gitdisable': 'yes'}, name='dwguploadnogit'), # used in testing
|
path('dwguploadnogit/', dwgupload, {'gitdisable': 'yes'}, name='dwguploadnogit'), # used in testing
|
||||||
path('dwguploadnogit/<path:folder>', dwgupload, {'gitdisable': 'yes'}, name='dwguploadnogit'), # used in testing
|
path('dwguploadnogit/<path:folder>', dwgupload, {'gitdisable': 'yes'}, name='dwguploadnogit'), # used in testing
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user