2020-05-24 01:57:06 +01:00
|
|
|
import os
|
|
|
|
import re
|
2021-03-24 15:46:35 +00:00
|
|
|
from pathlib import Path
|
2021-03-28 03:48:04 +01:00
|
|
|
from urllib.parse import urljoin, unquote as urlunquote
|
|
|
|
from urllib.request import urlopen
|
2011-06-02 19:16:16 +01:00
|
|
|
|
2021-03-21 01:33:59 +00:00
|
|
|
from django.shortcuts import render, redirect
|
2011-06-02 19:16:16 +01:00
|
|
|
from django.http import HttpResponse, HttpResponseRedirect, Http404
|
2020-06-18 21:50:16 +01:00
|
|
|
from django.urls import reverse, resolve
|
2011-06-02 19:16:16 +01:00
|
|
|
from django.template import Context, loader
|
2021-03-26 23:40:34 +00:00
|
|
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
|
|
|
|
2011-06-02 19:16:16 +01:00
|
|
|
import django.forms as forms
|
2020-05-24 01:57:06 +01:00
|
|
|
|
|
|
|
from troggle.helper import login_required_if_public
|
2020-05-28 04:54:53 +01:00
|
|
|
from troggle.core.models_caves import Cave
|
2011-07-11 00:13:06 +01:00
|
|
|
import troggle.core.views_caves
|
2020-05-24 01:57:06 +01:00
|
|
|
import troggle.settings as settings
|
2011-06-02 19:16:16 +01:00
|
|
|
|
2021-03-30 21:48:36 +01:00
|
|
|
'''Formerly a separate package 'flatpages' written by Martin Green 2011.
|
|
|
|
This was NOT django.contrib.flatpages which stores HTML in the database, so the name was chnaged to expopages.
|
|
|
|
Then it was incorporated into troggle directly, rather than being an unnecessary external package.
|
|
|
|
'''
|
|
|
|
|
2021-03-21 01:33:59 +00:00
|
|
|
def expofiles_redirect(request, path):
|
|
|
|
'''This is used only when running as a test system without a local copy of /expofiles/
|
|
|
|
'''
|
2021-03-28 03:48:04 +01:00
|
|
|
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))
|
2021-03-28 23:47:47 +01:00
|
|
|
# print(" - expofilessingle {}:{}:{}:".format(filepath, fn, getmimetype(fn)))
|
2021-03-28 03:48:04 +01:00
|
|
|
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
|
|
|
|
'''
|
2021-03-28 23:47:47 +01:00
|
|
|
# print(" - expofilesdir {}".format(dirpath))
|
2021-03-28 03:48:04 +01:00
|
|
|
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 })
|
2021-03-21 01:33:59 +00:00
|
|
|
|
2011-06-02 19:16:16 +01:00
|
|
|
def flatpage(request, path):
|
2021-03-28 03:48:04 +01:00
|
|
|
'''Either renders an HTML page from expoweb with all the menus,
|
2021-03-28 23:47:47 +01:00
|
|
|
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
|
|
|
|
'''
|
2021-03-30 21:05:27 +01:00
|
|
|
# print(" - EXPOPAGES delivering the file: {} as MIME type: {}".format(path,getmimetype(path)),flush=True)
|
2021-03-28 03:48:04 +01:00
|
|
|
|
|
|
|
if path.startswith("noinfo") and settings.PUBLIC_SITE and not request.user.is_authenticated():
|
2021-03-30 21:05:27 +01:00
|
|
|
# print((" - EXPOPAGES redirect to logon: flat path noinfo", path))
|
2021-03-28 03:48:04 +01:00
|
|
|
return HttpResponseRedirect(urljoin(reverse("auth_login"),'?next={}'.format(request.path)))
|
2011-07-11 00:13:06 +01:00
|
|
|
|
2021-03-24 15:46:35 +00:00
|
|
|
expowebpath = Path(settings.EXPOWEB)
|
2019-07-10 12:32:04 +01:00
|
|
|
if path.endswith("/") or path == "":
|
2021-03-30 21:05:27 +01:00
|
|
|
# print(" - EXPOPAGES the file: {} ENDSWITH ...".format(path))
|
2020-06-20 23:08:34 +01:00
|
|
|
|
2011-07-11 22:36:48 +01:00
|
|
|
try:
|
2021-03-24 15:46:35 +00:00
|
|
|
o = open(os.path.normpath(expowebpath / path / "index.html"), "rb")
|
2011-07-11 22:36:48 +01:00
|
|
|
path = path + "index.html"
|
|
|
|
except IOError:
|
|
|
|
try:
|
2021-03-24 15:46:35 +00:00
|
|
|
o = open(os.path.normpath(expowebpath / path / "index.htm"), "rb")
|
2011-08-07 17:30:18 +01:00
|
|
|
path = path + "index.htm"
|
2011-07-11 22:36:48 +01:00
|
|
|
except IOError:
|
2019-03-30 17:02:07 +00:00
|
|
|
return render(request, 'pagenotfound.html', {'path': path})
|
2020-06-20 23:08:34 +01:00
|
|
|
else:
|
2021-03-30 21:05:27 +01:00
|
|
|
# print(" - EXPOPAGES the file: '{}' ...".format(path))
|
2021-03-28 03:48:04 +01:00
|
|
|
if path.startswith('site_media'):
|
2021-03-28 23:47:47 +01:00
|
|
|
# print(" - MEDIA_ROOT: {} ...{}".format(settings.MEDIA_ROOT, path))
|
2021-03-28 03:48:04 +01:00
|
|
|
path = path.replace("site_media", settings.MEDIA_ROOT)
|
|
|
|
filetobeopened = os.path.normpath(path)
|
|
|
|
elif path.startswith("static"):
|
2021-03-28 23:47:47 +01:00
|
|
|
# print(" - STATIC_ROOT: {} ...{}".format(settings.MEDIA_ROOT, path))
|
2021-03-28 03:48:04 +01:00
|
|
|
path = path.replace("static", settings.MEDIA_ROOT)
|
|
|
|
filetobeopened = os.path.normpath(path)
|
|
|
|
else:
|
2021-03-28 23:47:47 +01:00
|
|
|
# print(" - NO _ROOT: {} ...".format(expowebpath))
|
2021-03-28 03:48:04 +01:00
|
|
|
filetobeopened = os.path.normpath(expowebpath / path)
|
|
|
|
|
2021-03-30 21:05:27 +01:00
|
|
|
# print(" - EXPOPAGES full path : {} ...".format(filetobeopened))
|
2011-07-11 22:36:48 +01:00
|
|
|
try:
|
2012-08-04 23:26:05 +01:00
|
|
|
o = open(filetobeopened, "rb")
|
2021-03-30 21:05:27 +01:00
|
|
|
#print(" - EXPOPAGES full path no error: {} ...".format(filetobeopened))
|
2011-07-11 22:36:48 +01:00
|
|
|
except IOError:
|
2021-03-30 21:05:27 +01:00
|
|
|
#print(" - EXPOPAGES ERROR: {} ...".format(filetobeopened))
|
2021-03-28 03:48:04 +01:00
|
|
|
#o.close()
|
2019-03-30 17:02:07 +00:00
|
|
|
return render(request, 'pagenotfound.html', {'path': path})
|
2021-03-28 03:48:04 +01:00
|
|
|
|
|
|
|
|
2011-06-02 19:16:16 +01:00
|
|
|
if path.endswith(".htm") or path.endswith(".html"):
|
2021-03-28 03:48:04 +01:00
|
|
|
# add the menus etc.
|
|
|
|
with open(os.path.normpath(expowebpath / path), "rb") as o:
|
|
|
|
html = o.read()
|
|
|
|
|
2020-05-24 01:57:06 +01:00
|
|
|
m = re.search(rb'(.*)<\s*head([^>]*)>(.*)<\s*/head\s*>(.*)<\s*body([^>]*)>(.*)<\s*/body\s*>(.*)', html, re.DOTALL + re.IGNORECASE)
|
2011-06-02 19:16:16 +01:00
|
|
|
if m:
|
2012-08-06 11:19:48 +01:00
|
|
|
preheader, headerattrs, head, postheader, bodyattrs, body, postbody = m.groups()
|
2011-06-02 19:16:16 +01:00
|
|
|
else:
|
2021-03-30 21:05:27 +01:00
|
|
|
return HttpResponse(html + "HTML Parsing failure: Page could not be split into header and body: failed in expopages.views.py")
|
2020-05-24 01:57:06 +01:00
|
|
|
m = re.search(rb"<title>(.*)</title>", head, re.DOTALL + re.IGNORECASE)
|
2011-08-08 09:51:47 +01:00
|
|
|
if m:
|
|
|
|
title, = m.groups()
|
|
|
|
else:
|
|
|
|
title = ""
|
2020-05-24 01:57:06 +01:00
|
|
|
m = re.search(rb"<meta([^>]*)noedit", head, re.DOTALL + re.IGNORECASE)
|
2020-04-10 13:13:23 +01:00
|
|
|
if m:
|
|
|
|
editable = False
|
|
|
|
else:
|
|
|
|
editable = True
|
|
|
|
|
2019-02-23 15:30:58 +00:00
|
|
|
has_menu = False
|
2020-05-24 01:57:06 +01:00
|
|
|
menumatch = re.match(rb'(.*)<div id="menu">', body, re.DOTALL + re.IGNORECASE)
|
2020-04-10 13:13:23 +01:00
|
|
|
if menumatch:
|
|
|
|
has_menu = True
|
2020-05-24 01:57:06 +01:00
|
|
|
menumatch = re.match(rb'(.*)<ul id="links">', body, re.DOTALL + re.IGNORECASE)
|
2019-02-23 15:30:58 +00:00
|
|
|
if menumatch:
|
|
|
|
has_menu = True
|
2020-06-18 21:50:16 +01:00
|
|
|
#body, = menumatch.groups()
|
2020-06-18 15:54:40 +01:00
|
|
|
# if re.search(rb"iso-8859-1", html):
|
|
|
|
# body = str(body, "iso-8859-1")
|
|
|
|
# body.strip
|
2020-06-18 21:50:16 +01:00
|
|
|
return render(request, 'flatpage.html', {'editable': editable, 'path': path, 'title': title,
|
|
|
|
'body': body, 'homepage': (path == "index.htm"), 'has_menu': has_menu})
|
2011-06-02 19:16:16 +01:00
|
|
|
else:
|
2021-03-30 21:05:27 +01:00
|
|
|
# print(" - EXPOPAGES delivering the file: {} as MIME type: {}".format(path,getmimetype(path)))
|
2021-03-28 03:48:04 +01:00
|
|
|
return HttpResponse(content=open(filetobeopened, "rb"), content_type=getmimetype(path))
|
|
|
|
#return HttpResponse(content=open(singlescan.ffile,"rb"), content_type=getmimetype(path))
|
2011-07-11 22:36:48 +01:00
|
|
|
|
|
|
|
def getmimetype(path):
|
2021-03-28 03:48:04 +01:00
|
|
|
path = str(path)
|
2020-06-20 23:08:34 +01:00
|
|
|
if path.lower().endswith(".css"): return "text/css"
|
2021-03-22 02:27:19 +00:00
|
|
|
if path.lower().endswith(".txt"): return "text/css"
|
2020-06-20 23:08:34 +01:00
|
|
|
if path.lower().endswith(".js"): return "application/javascript"
|
2021-03-22 02:27:19 +00:00
|
|
|
if path.lower().endswith(".json"): return "application/javascript"
|
2021-03-28 03:48:04 +01:00
|
|
|
if path.lower().endswith(".ico"): return "image/vnd.microsoft.icon"
|
2012-08-14 14:05:15 +01:00
|
|
|
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"
|
2021-03-28 03:48:04 +01:00
|
|
|
if path.lower().endswith("xml"): return "application/xml" # we use "text/xhtml" for tunnel files
|
2012-08-14 14:05:15 +01:00
|
|
|
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"
|
2021-03-28 03:48:04 +01:00
|
|
|
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"
|
2011-07-11 22:36:48 +01:00
|
|
|
return ""
|
2011-06-02 19:16:16 +01:00
|
|
|
|
|
|
|
@login_required_if_public
|
2021-03-26 23:40:34 +00:00
|
|
|
@ensure_csrf_cookie
|
2011-06-02 19:16:16 +01:00
|
|
|
def editflatpage(request, path):
|
2011-07-11 00:13:06 +01:00
|
|
|
try:
|
2011-07-11 22:36:48 +01:00
|
|
|
r = Cave.objects.get(url = path)
|
2011-07-11 00:13:06 +01:00
|
|
|
return troggle.core.views_caves.editCave(request, r.cave.slug)
|
2011-07-11 22:36:48 +01:00
|
|
|
except Cave.DoesNotExist:
|
2011-07-11 00:13:06 +01:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
2011-06-02 19:16:16 +01:00
|
|
|
try:
|
2021-03-26 23:40:34 +00:00
|
|
|
filepath = Path(settings.EXPOWEB) / path
|
2011-06-02 19:16:16 +01:00
|
|
|
o = open(filepath, "r")
|
2011-08-08 12:18:47 +01:00
|
|
|
html = o.read()
|
2012-08-06 11:56:20 +01:00
|
|
|
autogeneratedmatch = re.search(r"\<\!--\s*(.*?(Do not edit|auto-generated).*?)\s*--\>", html, re.DOTALL + re.IGNORECASE)
|
|
|
|
if autogeneratedmatch:
|
|
|
|
return HttpResponse(autogeneratedmatch.group(1))
|
2012-08-06 11:19:48 +01:00
|
|
|
m = re.search(r"(.*)<head([^>]*)>(.*)</head>(.*)<body([^>]*)>(.*)</body>(.*)", html, re.DOTALL + re.IGNORECASE)
|
2011-08-08 12:18:47 +01:00
|
|
|
if m:
|
|
|
|
filefound = True
|
2012-08-06 11:19:48 +01:00
|
|
|
preheader, headerargs, head, postheader, bodyargs, body, postbody = m.groups()
|
2019-02-25 20:13:28 +00:00
|
|
|
linksmatch = re.match(r'(.*)(<ul\s+id="links">.*)', body, re.DOTALL + re.IGNORECASE)
|
2011-08-08 13:11:57 +01:00
|
|
|
if linksmatch:
|
2012-08-06 11:19:48 +01:00
|
|
|
body, links = linksmatch.groups()
|
2020-06-18 15:54:40 +01:00
|
|
|
# if re.search(r"iso-8859-1", html):
|
|
|
|
# body = str(body, "iso-8859-1")
|
2011-08-08 12:18:47 +01:00
|
|
|
else:
|
|
|
|
return HttpResponse("Page could not be split into header and body")
|
2011-06-02 19:16:16 +01:00
|
|
|
except IOError:
|
2021-03-26 23:40:34 +00:00
|
|
|
print("### File not found ### ", filepath)
|
2011-08-08 12:18:47 +01:00
|
|
|
filefound = False
|
|
|
|
|
|
|
|
|
2011-06-02 19:16:16 +01:00
|
|
|
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
|
2021-03-26 23:40:34 +00:00
|
|
|
print("### \n", str(flatpageForm)[0:300])
|
|
|
|
print("### \n csrfmiddlewaretoken: ",request.POST['csrfmiddlewaretoken'])
|
2012-08-06 11:19:48 +01:00
|
|
|
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", "")
|
2020-05-24 01:57:06 +01:00
|
|
|
result = "%s<head%s>%s</head>%s<body%s>\n%s</body>%s" % (preheader, headerargs, head, postheader, bodyargs, body, postbody)
|
2012-08-12 18:10:23 +01:00
|
|
|
f = open(filepath, "w")
|
|
|
|
f.write(result)
|
2011-06-02 19:16:16 +01:00
|
|
|
f.close()
|
|
|
|
return HttpResponseRedirect(reverse('flatpage', args=[path])) # Redirect after POST
|
|
|
|
else:
|
2011-08-08 12:18:47 +01:00
|
|
|
if filefound:
|
2011-08-08 12:58:02 +01:00
|
|
|
m = re.search(r"<title>(.*)</title>", head, re.DOTALL + re.IGNORECASE)
|
2011-08-08 12:18:47 +01:00
|
|
|
if m:
|
|
|
|
title, = m.groups()
|
|
|
|
else:
|
|
|
|
title = ""
|
|
|
|
flatpageForm = FlatPageForm({"html": body, "title": title})
|
2011-08-08 09:51:47 +01:00
|
|
|
else:
|
2021-03-26 23:40:34 +00:00
|
|
|
body = "### File not found ###\n" + str(filepath)
|
|
|
|
flatpageForm = FlatPageForm({"html": body, "title": "Missing"})
|
2019-03-30 17:02:07 +00:00
|
|
|
return render(request, 'editflatpage.html', {'path': path, 'form': flatpageForm, })
|
2011-06-02 19:16:16 +01:00
|
|
|
|
|
|
|
class FlatPageForm(forms.Form):
|
2011-08-08 09:51:47 +01:00
|
|
|
title = forms.CharField(widget=forms.TextInput(attrs={'size':'60'}))
|
|
|
|
|
2020-06-13 23:16:19 +01:00
|
|
|
#html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 20}))
|
|
|
|
html = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":20}))
|