diff --git a/core/TESTS/tests.py b/core/TESTS/tests.py index 77cd998..7a12637 100644 --- a/core/TESTS/tests.py +++ b/core/TESTS/tests.py @@ -25,6 +25,7 @@ todo = '''ADD TESTS when we are redirecting /expofiles/ to a remote file-deliver import unittest import re +from http import HTTPStatus from django.test import TestCase, SimpleTestCase, Client @@ -170,8 +171,6 @@ class PageTests(TestCase): ph = r'All Survey scans folders ' content = response.content.decode() phmatch = re.search(ph, content) - # with open('ss-op.html', 'w') as f: - # f.write(content) self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'") diff --git a/core/TESTS/tests_logins.py b/core/TESTS/tests_logins.py index 45bd33e..66e69c6 100644 --- a/core/TESTS/tests_logins.py +++ b/core/TESTS/tests_logins.py @@ -7,6 +7,8 @@ Modified for Expo April 2021. import unittest import re +from http import HTTPStatus + from django.test import TestCase, SimpleTestCase, TransactionTestCase, Client @@ -61,6 +63,41 @@ class FixturePageTests(TestCase): t = re.search(r'Troggle administration', content) self.assertIsNone(t, 'Logged in as \'' + u.username + '\' (not staff) but still managed to get the Admin page' ) +class PostTests(TestCase): + ''' + ''' + fixtures = ['auth_users'] + + @classmethod + def setUpTestData(cls): + pass + + def setUp(self): + from django.contrib.auth.models import User + self.user = User.objects.get(username='expotest') + self.client = Client() + + def test_scan_upload(self): + '''Test file upload. Need to login first. + ''' + c = self.client + from django.contrib.auth.models import User + u = User.objects.get(username='expotest') + + self.assertTrue(u.is_active, 'User \'' + u.username + '\' is INACTIVE') + logged_in = c.login(username=u.username, password='secretword') + + with open('README.txt','r') as testf: + response = self.client.post('/scanupload/2021:02', data={'title': '2021#00', 'name': 'README.txt', 'scanfiles': testf }) + content = response.content.decode() + self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, HTTPStatus.OK) + with open('test_up.html', 'w') as f: + f.write(content) + t = re.search(r'README.txt', content) + self.assertIsNone(t, 'Logged in as \'' + u.username + '\' (not staff) but failed to upload file' ) + + class ComplexLoginTests(TestCase): '''These test the login and capabilities of logged-in users, they do not use fixtures''' diff --git a/core/forms.py b/core/forms.py index a7b44db..2781c67 100644 --- a/core/forms.py +++ b/core/forms.py @@ -8,7 +8,7 @@ from django.contrib.admin.widgets import AdminDateWidget #from tinymce.widgets import TinyMCE -from troggle.core.models.troggle import Person, PersonExpedition, Expedition, SimpleFileModel +from troggle.core.models.troggle import Person, PersonExpedition, Expedition from troggle.core.models.caves import Cave, LogbookEntry, QM, Entrance, CaveAndEntrance '''These are all the Forms used by troggle @@ -107,55 +107,5 @@ class EntranceLetterForm(ModelForm): model = CaveAndEntrance exclude = ('cave', 'entrance') -def get_name(pe): - if pe.nickname: - return pe.nickname - else: - return pe.person.first_name - -class UploadFileForm(forms.Form): - """Only called by views.others.newFile() which seems to be only about logbook files. - """ - title = forms.CharField(max_length=50) - file = forms.FileField() - #html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30})) - html = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":20})) - lon_utm = forms.FloatField(required=False) - lat_utm = forms.FloatField(required=False) - slug = forms.CharField(max_length=50) - date = forms.DateField(required=False) - survey_point = forms.CharField() - - # Because this has EXECUTABLE statements in its signature (the fields) they get - # executed when this module is LOADED. Which barfs horribly. - # so all put in an __init__ method instead pending deletion or rewriting - def __init__(self): - #This next line is the one that causes django.setup() to BARF LOUDLY - caves = [cave.slug for cave in Cave.objects.all()] - #caves.sort() # sort needs rewriting for python3 - caves = ["-----"] + caves - cave = forms.ChoiceField([(c, c) for c in caves], required=False) - - entrance = forms.ChoiceField([("-----", "Please select a cave"), ], required=False) - - expeditions = [e.year for e in Expedition.objects.all()] - expeditions.sort() - expeditions = ["-----"] + expeditions - expedition = forms.ChoiceField([(e, e) for e in expeditions], required=False) - - qm = forms.ChoiceField([("-----", "Please select a cave"), ], required=False) - logbookentry = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False) - person = forms.ChoiceField([("-----", "Please select an expedition"), ], required=False) - - - -class SimpleUploadFileForm(forms.ModelForm): - """New in April 2021 - """ - class Meta: - model = SimpleFileModel - fields = ('title', 'simplefile',) - - diff --git a/core/models/troggle.py b/core/models/troggle.py index f9558ff..32a5064 100644 --- a/core/models/troggle.py +++ b/core/models/troggle.py @@ -229,12 +229,3 @@ class PersonExpedition(TroggleModel): def day_max(self): res = self.persontrip_set.all().aggregate(day_max=models.Max("expeditionday__date")) return res["day_max"] - -class SimpleFileModel(models.Model): - simplefile = models.FileField(upload_to='fileuploads/') # in MEDIA_FILES - title = models.CharField(max_length = 80) - class Meta: - ordering = ['title'] - - def __str__(self): - return f"{self.title}" diff --git a/core/views/other.py b/core/views/other.py index d9eba3f..c721a61 100644 --- a/core/views/other.py +++ b/core/views/other.py @@ -2,6 +2,7 @@ import re, os from pathlib import Path from django import forms + from django.conf import settings from django.urls import reverse from django.db.models import Q @@ -16,7 +17,6 @@ from troggle.parsers.imports import import_logbooks, import_QMs, import_drawings from troggle.core.models.troggle import Expedition, Person, PersonExpedition from troggle.core.models.caves import LogbookEntry, QM, Cave, PersonTrip from .login import login_required_if_public -from troggle.core.forms import UploadFileForm, SimpleUploadFileForm '''Utility functions and code to serve the control panel and individual user's progress and task list (deprecated as we do not have individual user login). @@ -203,6 +203,11 @@ def ajax_test(request): content_type="application/json") + +class MyForm(forms.Form): # not a model-form + title = forms.CharField(max_length=20) + scanfiles = forms.FileField() # in MEDIA_FILES + @login_required_if_public def scanupload(request, wallet=None): '''Upload one scanned image file into a wallet on /expofiles @@ -228,13 +233,15 @@ def scanupload(request, wallet=None): wallet = wallet.replace(':','#') dirpath = Path(settings.SURVEY_SCANS, year, wallet) + form = MyForm() + if request.method == 'POST': - form = SimpleUploadFileForm(request.POST,request.FILES) + form = MyForm(request.POST,request.FILES) if form.is_valid(): #form.save() # comment out so nothing saved in MEDIA_ROOT/fileuploads - f = request.FILES["simplefile"] + f = request.FILES["scanfiles"] w = request.POST["title"] - multiple = request.FILES.getlist('simplefile') + multiple = request.FILES.getlist('scanfiles') fs = FileSystemStorage(os.path.join(settings.SURVEY_SCANS, year, w)) actual_saved = [] @@ -260,7 +267,70 @@ def scanupload(request, wallet=None): files.append('(no image files in wallet)') - form = SimpleUploadFileForm() return render(request, 'scanuploadform.html', {'form': form, 'wallet': wallet, 'year': year, 'prev': prev, 'next': next, 'prevy': prevy, 'nexty': nexty, 'files': files, 'dirs': dirs, 'filesaved': filesaved, 'actual_saved': actual_saved}) + +# @login_required_if_public +# def verysimplescanupload(request, wallet=None): + # '''Upload one scanned image file into a wallet on /expofiles + # ''' + # print(f'VERY SIMPLE') + # filesaved = False + # actual_saved = [] + # print(f'! - FORM scanupload - start {wallet}') + # if wallet is None: + # wallet = "2021#01" # improve this later + # if not re.match('(19|20)\d\d:\d\d', wallet): + # wallet = "2021:01" # improve this later + + # year = wallet[:4] + # nexty = f'{int(year)+1}' + # prevy = f'{int(year)-1}' + # wnumber = wallet[5:] + # next = f'{int(wnumber)+1:02d}' + # prev = f'{int(wnumber)-1:02d}' + + # if int(wnumber) == 0: + # prev = f'{int(wnumber):02d}' + + # wallet = wallet.replace(':','#') + # dirpath = Path(settings.SURVEY_SCANS, year, wallet) + + # form = MyForm() + + # if request.method == 'POST': + # form = MyForm(request.POST,request.FILES) + # if form.is_valid(): + # #form.save() # comment out so nothing saved in MEDIA_ROOT/fileuploads + # f = request.FILES["simplefile"] + # w = request.POST["title"] + # multiple = request.FILES.getlist('simplefile') + # fs = FileSystemStorage(os.path.join(settings.SURVEY_SCANS, year, w)) + + # 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 + + # files = [] + # dirs = [] + # #print(f'! - FORM scanupload - start {wallet} {dirpath}') + # try: + # for f in dirpath.iterdir(): + # if f.is_dir(): + # dirs.append(f.name) + # if f.is_file(): + # if f.name != 'contents.json' and f.name != 'walletindex.html': + # files.append(f.name) + # except FileNotFoundError: + # files.append('(no wallet yet - would be created)') + # if len(files) ==0 : + # files.append('(no image files in wallet)') + + + # return render(request, 'scanuploadform.html', + # {'form': form, 'wallet': wallet, 'year': year, 'prev': prev, 'next': next, 'prevy': prevy, 'nexty': nexty, 'files': files, 'dirs': dirs, 'filesaved': filesaved, 'actual_saved': actual_saved}) + diff --git a/templates/_fileupload.html b/templates/_fileupload.html deleted file mode 100644 index f71760d..0000000 --- a/templates/_fileupload.html +++ /dev/null @@ -1,18 +0,0 @@ -

Fileupload

- - -

MESSAGE: {{message}} -

- -{% if not filesuploaded %} -
-

file to upload

-

-

-
-{% endif %} diff --git a/templates/scanuploadform.html b/templates/scanuploadform.html index ed16301..4beae89 100644 --- a/templates/scanuploadform.html +++ b/templates/scanuploadform.html @@ -16,25 +16,12 @@

-
- - {% if filesaved %} -

- File(s) saved as - {% for f in actual_saved %} - '{{f}}' - {% endfor %} -

Upload more?
-

-
- {% endif %} - - +
{% csrf_token %}
+ placeholder = "Scanfiles" name = "scanfiles" id="scanfiles">

@@ -46,7 +33,17 @@
-
+ {% if filesaved %} +

+ File(s) saved as + {% for f in actual_saved %} + '{{f}}' + {% endfor %} +

Upload more?
+

+
+ {% endif %} +

{% for f in files %} diff --git a/urls.py b/urls.py index 4b4ccf8..85a9759 100644 --- a/urls.py +++ b/urls.py @@ -10,7 +10,7 @@ from django.urls import reverse, resolve from troggle.core.views import caves, statistics, survex from troggle.core.views.surveys import scansingle, singlewallet, allwallets, dwgdata, dwgfilesingle, dwgfileupload -from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage, scanupload +from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage, scanupload from troggle.core.views.other import exportlogbook from troggle.core.views.caves import ent, cavepage from troggle.core.views.logbooks import get_logbook_entries, logbookentry, logbookSearch