summaryrefslogtreecommitdiffstats
path: root/core/views/uploads.py
blob: b5b51689cfb7e67b1b89d518bbe8499415fbd488 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import re, os
import subprocess
from pathlib import Path

from django import forms

from django.conf import settings
from django.urls import reverse
from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.template import Context, loader
from django.core.files.storage import FileSystemStorage, default_storage

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 databaseReset import reinit_db # don't do this. databaseRest runs code *at import time*
from troggle.core.models.troggle import Expedition, Person, PersonExpedition
from troggle.core.models.caves import LogbookEntry, QM, Cave, PersonTrip
from troggle.core.models.survex import DrawingFile
from .auth import login_required_if_public

'''File upload 'views' 
'''

todo = '''
-Move upload forms to proper file locations
'''

class FilesForm(forms.Form):  # not a model-form, just a form-form
    uploadfiles = forms.FileField() 

@login_required_if_public
def scanupload(request, wallet=None):
    '''Upload scanned image files into a wallet on /expofiles
    This does NOT use a Django model linked to a Django form. Just a simple Django form.
    '''
    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]
    if int(year) < 1977: 
        year = "1977"
    if int(year) > 2050: 
        year = "2050"
    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}'
    
    context = {'year': year, 'prev': prev, 'next': next, 'prevy': prevy, 'nexty': nexty}
    
    wallet = wallet.replace(':','#')
    dirpath = Path(settings.SURVEY_SCANS, year, wallet)
    
    form = FilesForm()
    
    if request.method == 'POST':
        form = FilesForm(request.POST,request.FILES)
        if form.is_valid():
            f = request.FILES["uploadfiles"]
            multiple = request.FILES.getlist('uploadfiles')
            fs = FileSystemStorage(os.path.join(settings.SURVEY_SCANS, year, wallet))
           
            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)')
    else:
        files = sorted(files)
        
    if dirs:
        dirs = sorted(dirs)

    return render(request, 'scanuploadform.html', 
        {'form': form, 'wallet': wallet, **context, 'files': files, 'dirs': dirs, 'filesaved': filesaved, 'actual_saved': actual_saved})

@login_required_if_public
def dwgupload(request, folder=None, gitdisable='no'):
    '''Upload DRAWING files (tunnel or therion) into the upload folder in :drawings:
    This does NOT use a Django model linked to a Django form. Just a simple Django form.
    
    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
    the actual file will be duplicated in the filesystem with different random name ammendation.
    '''
    def dwgvalid(name):
        if name in [ '.gitignore', '.hgignore', ]:
            return False
        if Path(name).suffix.lower() in ['.xml', '.th', '.th2', '', '.svg', '.jpg', '.pdf', 'jpeg']:
            return True # dangerous, we should check the actual file binary signature
        return False
        
    filesaved = False
    actual_saved = []
    refused = []
    doesnotexist = ''
    # print(f'! - FORM dwgupload - start "{folder}" - gitdisable "{gitdisable}"')
    if folder is None:
        folder = "" # improve this later
        dirpath = Path(settings.DRAWINGS_DATA)
        urlfile = '/dwgdataraw'
        urldir  = '/dwgupload'
    else:
        dirpath = Path(settings.DRAWINGS_DATA, folder)
        urlfile = Path('/dwgdataraw/') / folder
        urldir  = Path('/dwgupload/') / folder
    
    form = FilesForm()
    
    if request.method == 'POST':
        form = FilesForm(request.POST,request.FILES)
        if form.is_valid():
            f = request.FILES["uploadfiles"]
            multiple = request.FILES.getlist('uploadfiles')
            fs = FileSystemStorage(os.path.join(settings.DRAWINGS_DATA, folder))
           
            actual_saved = []
            refused = []
            if gitdisable != 'yes': # set in url 'dwguploadnogit/'
                git = settings.GIT
            else:
                git = 'echo'

            if multiple:
                for f in multiple:
                    if dwgvalid(f.name):
                        saved_filename = fs.save(f.name, content=f)
                        actual_saved.append(saved_filename)
                        if gitdisable != 'yes':
                            subprocess.call([git, "add", saved_filename], cwd=dirpath)
                        dwgfile, created = DrawingFile.objects.get_or_create(dwgpath=saved_filename, dwgname=Path(f.name).stem, filesize=f.size)  
                        dwgfile.save()
                    else:
                        refused.append(f.name)
            if actual_saved: # maybe all were refused by the suffix test in dwgvalid()
                filesaved = True
                if gitdisable != 'yes':
                    subprocess.call([git, "commit", "-m", 'dwgupload'], cwd=dirpath)


    files = []
    dirs = []
    # print(f'! - FORM dwgupload - start {folder} \n"{dirpath}" \n"{dirpath.parent}" \n"{dirpath.exists()}"')
    try:
        for f in dirpath.iterdir():
            if f.is_dir():
                if f.name not in ['.git' ]:
                    dirs.append(f.name)
                    continue
            if f.is_file():
                if dwgvalid(f.name): 
                    files.append(f.name)
                    continue
    except FileNotFoundError:
        doesnotexist = True
    if files:
        files = sorted(files)
        
    if dirs:
        dirs = sorted(dirs)

    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})