259 lines
12 KiB
Python
Raw Normal View History

2020-05-24 01:57:06 +01:00
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
2020-06-18 21:50:16 +01:00
from django.urls import reverse, resolve
from django.template import Context, loader
2021-03-26 23:40:34 +00:00
from django.views.decorators.csrf import ensure_csrf_cookie
import django.forms as forms
2020-05-24 01:57:06 +01:00
from troggle.helper import login_required_if_public
#from troggle.flatpages.models import Redirect, EntranceRedirect
from troggle.core.models_caves import Cave
import troggle.core.views_caves
2020-05-24 01:57:06 +01:00
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'''
print(" - FLATPAGES 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((" - FLATPAGES redirect to logon: flat path noinfo", path))
return HttpResponseRedirect(urljoin(reverse("auth_login"),'?next={}'.format(request.path)))
try:
r = Cave.objects.get(url = path)
return troggle.core.views_caves.caveSlug(request, r.slug())
except Cave.DoesNotExist:
pass
except:
#print(" ! FAILED to get only one cave per slug for: "+path)
# we should do this proper;ly, not this hack that returns the first cave that matches
caves = Cave.objects.all().filter(url = path)
for c in caves:
print(path, c.slug())
if c.slug() != None:
return troggle.core.views_caves.caveSlug(request, c.slug())
pass
expowebpath = Path(settings.EXPOWEB)
if path.endswith("/") or path == "":
print(" - FLATPAGES 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")
2011-08-07 17:30:18 +01:00
path = path + "index.htm"
except IOError:
return render(request, 'pagenotfound.html', {'path': path})
else:
print(" - FLATPAGES 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(" - FLATPAGES full path : {} ...".format(filetobeopened))
try:
o = open(filetobeopened, "rb")
print(" - FLATPAGES full path no error: {} ...".format(filetobeopened))
except IOError:
print(" - FLATPAGES 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()
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)
if m:
preheader, headerattrs, head, postheader, bodyattrs, body, postbody = m.groups()
else:
2020-08-02 23:53:35 +01:00
return HttpResponse(html + "HTML Parsing failure: Page could not be split into header and body: failed in flatpages.views.py")
2020-05-24 01:57:06 +01:00
m = re.search(rb"<title>(.*)</title>", head, re.DOTALL + re.IGNORECASE)
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)
if m:
editable = False
else:
editable = True
has_menu = False
2020-05-24 01:57:06 +01:00
menumatch = re.match(rb'(.*)<div id="menu">', body, re.DOTALL + re.IGNORECASE)
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)
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})
else:
print(" - FLATPAGES 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"
2021-03-22 02:27:19 +00:00
if path.lower().endswith(".txt"): return "text/css"
if path.lower().endswith(".js"): return "application/javascript"
2021-03-22 02:27:19 +00:00
if path.lower().endswith(".json"): return "application/javascript"
if path.lower().endswith(".ico"): return "image/vnd.microsoft.icon"
2012-08-14 15:05:15 +02: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"
if path.lower().endswith("xml"): return "application/xml" # we use "text/xhtml" for tunnel files
2012-08-14 15:05:15 +02: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"
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
2021-03-26 23:40:34 +00:00
@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:
2021-03-26 23:40:34 +00:00
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)
2011-08-08 13:11:57 +01:00
if linksmatch:
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")
else:
return HttpResponse("Page could not be split into header and body")
except IOError:
2021-03-26 23:40:34 +00:00
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
2021-03-26 23:40:34 +00:00
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", "")
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)
f = open(filepath, "w")
f.write(result)
f.close()
return HttpResponseRedirect(reverse('flatpage', args=[path])) # Redirect after POST
else:
if filefound:
2011-08-08 12:58:02 +01:00
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:
2021-03-26 23:40:34 +00:00
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'}))
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}))