diff options
Diffstat (limited to 'expopages/views.py')
-rw-r--r-- | expopages/views.py | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/expopages/views.py b/expopages/views.py new file mode 100644 index 0000000..0567229 --- /dev/null +++ b/expopages/views.py @@ -0,0 +1,245 @@ +import os +import re +from pathlib import Path +from urllib.parse import urljoin, unquote as urlunquote +from urllib.request import urlopen + +from django.shortcuts import render, redirect +from django.http import HttpResponse, HttpResponseRedirect, Http404 +from django.urls import reverse, resolve +from django.template import Context, loader +from django.views.decorators.csrf import ensure_csrf_cookie + +import django.forms as forms + +from troggle.helper import login_required_if_public +from troggle.core.models_caves import Cave +import troggle.core.views_caves +import troggle.settings as settings + +def expofiles_redirect(request, path): + '''This is used only when running as a test system without a local copy of /expofiles/ + ''' + return redirect(urljoin('http://expo.survex.com/expofiles/', path)) + +def expofilessingle(request, filepath): + '''sends a single binary file to the user, + ''' + fn=urlunquote(filepath) + fn = Path(settings.EXPOFILES,filepath) + if fn.is_dir(): + return expofilesdir(request, Path(fn), Path(filepath)) + # print(" - expofilessingle {}:{}:{}:".format(filepath, fn, getmimetype(fn))) + return HttpResponse(content=open(fn, "rb"),content_type=getmimetype(filepath)) # any file + +def expofilesdir(request, dirpath, filepath): + '''does a directory display. If there is an index.html file we should display that. + - dirpath is a Path() and it does not have /expofiles/ in it + ''' + # print(" - expofilesdir {}".format(dirpath)) + urlpath = 'expofiles' / Path(filepath) + fileitems = [] + diritems = [] + for f in dirpath.iterdir(): + if f.is_dir(): + diritems.append((urlpath / f.parts[-1], str(f.parts[-1]))) + else: + # if f.parts[-1].lower() == 'index.htm' or f.parts[-1].lower() == 'index.html': # css cwd problem + # return HttpResponse(content=open(f, "rb"),content_type=getmimetype(filepath)) # any file + # return expofilessingle(request, str(Path(filepath / f.parts[-1]))) + fileitems.append((Path(urlpath) / f.parts[-1], str(f.parts[-1]), getmimetype(f))) + return render(request, 'dirdisplay.html', { 'filepath': urlpath, 'fileitems':fileitems, 'diritems': diritems,'settings': settings }) + +def flatpage(request, path): + '''Either renders an HTML page from expoweb with all the menus, + or serves an unadorned binary file with mime type + + This is a horrible mess and some code is redundant and unreachable because of urls.py setup + ''' + # print(" - EXPOPAGES delivering the file: {} as MIME type: {}".format(path,getmimetype(path)),flush=True) + + if path.startswith("noinfo") and settings.PUBLIC_SITE and not request.user.is_authenticated(): + # print((" - EXPOPAGES redirect to logon: flat path noinfo", path)) + return HttpResponseRedirect(urljoin(reverse("auth_login"),'?next={}'.format(request.path))) + + expowebpath = Path(settings.EXPOWEB) + if path.endswith("/") or path == "": + # print(" - EXPOPAGES the file: {} ENDSWITH ...".format(path)) + + try: + o = open(os.path.normpath(expowebpath / path / "index.html"), "rb") + path = path + "index.html" + except IOError: + try: + o = open(os.path.normpath(expowebpath / path / "index.htm"), "rb") + path = path + "index.htm" + except IOError: + return render(request, 'pagenotfound.html', {'path': path}) + else: + # print(" - EXPOPAGES the file: '{}' ...".format(path)) + if path.startswith('site_media'): + # print(" - MEDIA_ROOT: {} ...{}".format(settings.MEDIA_ROOT, path)) + path = path.replace("site_media", settings.MEDIA_ROOT) + filetobeopened = os.path.normpath(path) + elif path.startswith("static"): + # print(" - STATIC_ROOT: {} ...{}".format(settings.MEDIA_ROOT, path)) + path = path.replace("static", settings.MEDIA_ROOT) + filetobeopened = os.path.normpath(path) + else: + # print(" - NO _ROOT: {} ...".format(expowebpath)) + filetobeopened = os.path.normpath(expowebpath / path) + + # print(" - EXPOPAGES full path : {} ...".format(filetobeopened)) + try: + o = open(filetobeopened, "rb") + #print(" - EXPOPAGES full path no error: {} ...".format(filetobeopened)) + except IOError: + #print(" - EXPOPAGES ERROR: {} ...".format(filetobeopened)) + #o.close() + return render(request, 'pagenotfound.html', {'path': path}) + + + if path.endswith(".htm") or path.endswith(".html"): + # add the menus etc. + with open(os.path.normpath(expowebpath / path), "rb") as o: + html = o.read() + + m = re.search(rb'(.*)<\s*head([^>]*)>(.*)<\s*/head\s*>(.*)<\s*body([^>]*)>(.*)<\s*/body\s*>(.*)', html, re.DOTALL + re.IGNORECASE) + if m: + preheader, headerattrs, head, postheader, bodyattrs, body, postbody = m.groups() + else: + return HttpResponse(html + "HTML Parsing failure: Page could not be split into header and body: failed in expopages.views.py") + m = re.search(rb"<title>(.*)</title>", head, re.DOTALL + re.IGNORECASE) + if m: + title, = m.groups() + else: + title = "" + m = re.search(rb"<meta([^>]*)noedit", head, re.DOTALL + re.IGNORECASE) + if m: + editable = False + else: + editable = True + + has_menu = False + menumatch = re.match(rb'(.*)<div id="menu">', body, re.DOTALL + re.IGNORECASE) + if menumatch: + has_menu = True + menumatch = re.match(rb'(.*)<ul id="links">', body, re.DOTALL + re.IGNORECASE) + if menumatch: + has_menu = True + #body, = menumatch.groups() +# if re.search(rb"iso-8859-1", html): +# body = str(body, "iso-8859-1") +# body.strip + return render(request, 'flatpage.html', {'editable': editable, 'path': path, 'title': title, + 'body': body, 'homepage': (path == "index.htm"), 'has_menu': has_menu}) + else: + # print(" - EXPOPAGES delivering the file: {} as MIME type: {}".format(path,getmimetype(path))) + return HttpResponse(content=open(filetobeopened, "rb"), content_type=getmimetype(path)) + #return HttpResponse(content=open(singlescan.ffile,"rb"), content_type=getmimetype(path)) + +def getmimetype(path): + path = str(path) + if path.lower().endswith(".css"): return "text/css" + if path.lower().endswith(".txt"): return "text/css" + if path.lower().endswith(".js"): return "application/javascript" + if path.lower().endswith(".json"): return "application/javascript" + if path.lower().endswith(".ico"): return "image/vnd.microsoft.icon" + if path.lower().endswith(".png"): return "image/png" + if path.lower().endswith(".tif"): return "image/tif" + if path.lower().endswith(".gif"): return "image/gif" + if path.lower().endswith(".jpeg"): return "image/jpeg" + if path.lower().endswith(".jpg"): return "image/jpeg" + if path.lower().endswith("svg"): return "image/svg+xml" + if path.lower().endswith("xml"): return "application/xml" # we use "text/xhtml" for tunnel files + if path.lower().endswith(".pdf"): return "application/pdf" + if path.lower().endswith(".ps"): return "application/postscript" + if path.lower().endswith(".svx"): return "application/x-survex-svx" + if path.lower().endswith(".3d"): return "application/x-survex-3d" + if path.lower().endswith(".pos"): return "application/x-survex-pos" + if path.lower().endswith(".err"): return "application/x-survex-err" + if path.lower().endswith(".odt"): return "application/vnd.oasis.opendocument.text" + if path.lower().endswith(".ods"): return "application/vnd.oasis.opendocument.spreadsheet" + if path.lower().endswith(".docx"): return "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + if path.lower().endswith(".xslx"): return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + if path.lower().endswith(".gz"): return "application/x-7z-compressed" + if path.lower().endswith(".7z"): return "application/x-7z-compressed" + if path.lower().endswith(".zip"): return "application/zip" + return "" + +@login_required_if_public +@ensure_csrf_cookie +def editflatpage(request, path): + try: + r = Cave.objects.get(url = path) + return troggle.core.views_caves.editCave(request, r.cave.slug) + except Cave.DoesNotExist: + pass + + + try: + filepath = Path(settings.EXPOWEB) / path + o = open(filepath, "r") + html = o.read() + autogeneratedmatch = re.search(r"\<\!--\s*(.*?(Do not edit|auto-generated).*?)\s*--\>", html, re.DOTALL + re.IGNORECASE) + if autogeneratedmatch: + return HttpResponse(autogeneratedmatch.group(1)) + m = re.search(r"(.*)<head([^>]*)>(.*)</head>(.*)<body([^>]*)>(.*)</body>(.*)", html, re.DOTALL + re.IGNORECASE) + if m: + filefound = True + preheader, headerargs, head, postheader, bodyargs, body, postbody = m.groups() + linksmatch = re.match(r'(.*)(<ul\s+id="links">.*)', body, re.DOTALL + re.IGNORECASE) + if linksmatch: + body, links = linksmatch.groups() +# if re.search(r"iso-8859-1", html): +# body = str(body, "iso-8859-1") + else: + return HttpResponse("Page could not be split into header and body") + except IOError: + print("### File not found ### ", filepath) + filefound = False + + + if request.method == 'POST': # If the form has been submitted... + flatpageForm = FlatPageForm(request.POST) # A form bound to the POST data + if flatpageForm.is_valid():# Form valid therefore write file + print("### \n", str(flatpageForm)[0:300]) + print("### \n csrfmiddlewaretoken: ",request.POST['csrfmiddlewaretoken']) + if filefound: + headmatch = re.match(r"(.*)<title>.*</title>(.*)", head, re.DOTALL + re.IGNORECASE) + if headmatch: + head = headmatch.group(1) + "<title>" + flatpageForm.cleaned_data["title"] + "</title>" + headmatch.group(2) + else: + head = "<title>" + flatpageForm.cleaned_data["title"] + "</title>" + else: + head = "<title>" + flatpageForm.cleaned_data["title"] + "</title>" + preheader = "<html>" + headerargs = "" + postheader = "" + bodyargs = "" + postbody = "</html>" + body = flatpageForm.cleaned_data["html"] + body = body.replace("\r", "") + result = "%s<head%s>%s</head>%s<body%s>\n%s</body>%s" % (preheader, headerargs, head, postheader, bodyargs, body, postbody) + f = open(filepath, "w") + f.write(result) + f.close() + return HttpResponseRedirect(reverse('flatpage', args=[path])) # Redirect after POST + else: + if filefound: + m = re.search(r"<title>(.*)</title>", head, re.DOTALL + re.IGNORECASE) + if m: + title, = m.groups() + else: + title = "" + flatpageForm = FlatPageForm({"html": body, "title": title}) + else: + body = "### File not found ###\n" + str(filepath) + flatpageForm = FlatPageForm({"html": body, "title": "Missing"}) + return render(request, 'editflatpage.html', {'path': path, 'form': flatpageForm, }) + +class FlatPageForm(forms.Form): + title = forms.CharField(widget=forms.TextInput(attrs={'size':'60'})) + + #html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 20})) + html = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":20})) |