From 5d4ad93c5113a7895e98556f741714e2652f05b9 Mon Sep 17 00:00:00 2001 From: Philip Sargent <philip.sargent@klebos.com> Date: Sat, 10 Apr 2021 15:30:29 +0100 Subject: [PATCH] Better FileNotFound in expofiles --- core/views/expo.py | 60 +++++++++++++++------- templates/{flatpage.html => expopage.html} | 0 urls.py | 1 + 3 files changed, 42 insertions(+), 19 deletions(-) rename templates/{flatpage.html => expopage.html} (100%) diff --git a/core/views/expo.py b/core/views/expo.py index d74120f..0a95011 100644 --- a/core/views/expo.py +++ b/core/views/expo.py @@ -50,27 +50,40 @@ default_head = '''<head> def expofiles_redirect(request, path): '''This is used only when running as a test system without a local copy of /expofiles/ + when settings.EXPOFILESREMOTE is True ''' return redirect(urljoin('http://expo.survex.com/expofiles/', path)) def expofilessingle(request, filepath): - '''sends a single binary file to the user, + '''sends a single binary file to the user, if not found, show the parent directory + If the path actually is a directory, then show that. ''' 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 + if fn.is_file(): + return HttpResponse(content=open(fn, "rb"),content_type=getmimetype(filepath)) # any file + else: + # not a file, so show parent directory + return expofilesdir(request, Path(fn).parent, Path(filepath).parent) 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 + - dirpath is a full Path() resolved including lcoal machine /expofiles/ + - filepath is a Path() and it does not have /expofiles/ in it ''' - # print(" - expofilesdir {}".format(dirpath)) + # print(f' - expofilesdir {dirpath}') urlpath = 'expofiles' / Path(filepath) + try: + for f in dirpath.iterdir(): + pass + except FileNotFoundError: + print(f' - expofilesdir {dirpath}') + return expofilesdir(request, dirpath.parent, filepath.parent) + fileitems = [] - diritems = [] + diritems = [] for f in dirpath.iterdir(): if f.is_dir(): diritems.append((urlpath / f.parts[-1], str(f.parts[-1]))) @@ -113,7 +126,7 @@ def expowebpage(request, expowebpath, path): menumatch = re.match(r'(.*)<ul id="links">', body, re.DOTALL + re.IGNORECASE) if menumatch: has_menu = True - return render(request, 'flatpage.html', {'editable': editable, 'path': path, 'title': title, + return render(request, 'expopage.html', {'editable': editable, 'path': path, 'title': title, 'body': body, 'homepage': (path == "index.htm"), 'has_menu': has_menu}) def mediapage(request, subpath=None, doc_root=None): @@ -179,6 +192,10 @@ def expopage(request, path): def getmimetype(path): + '''Our own version rather than relying on what is provided by the python library. Note that when + Apache or nginx is used to deliver /expofiles/ it will use it's own idea of mimetypes and + not these. + ''' path = str(path) if path.lower().endswith(".css"): return "text/css" if path.lower().endswith(".txt"): return "text/css" @@ -210,13 +227,16 @@ def getmimetype(path): @login_required_if_public @ensure_csrf_cookie def editexpopage(request, path): + '''Manages the 'Edit this Page' capability for expo handbook and other html pages. + Relies on javascript to provide the in-browser editing environment. + ''' try: + # if a cave not a webpage at all. 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") @@ -242,24 +262,24 @@ def editexpopage(request, path): 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]) + pageform = ExpoPageForm(request.POST) # A form bound to the POST data + if pageform.is_valid():# Form valid therefore write file + print("### \n", str(pageform)[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) + head = headmatch.group(1) + "<title>" + pageform.cleaned_data["title"] + "</title>" + headmatch.group(2) else: - head = "<title>" + flatpageForm.cleaned_data["title"] + "</title>" + head = "<title>" + pageform.cleaned_data["title"] + "</title>" else: - head = "<title>" + flatpageForm.cleaned_data["title"] + "</title>" + head = "<title>" + pageform.cleaned_data["title"] + "</title>" preheader = "<html>" headerargs = "" postheader = "" bodyargs = "" postbody = "</html>" - body = flatpageForm.cleaned_data["html"] + body = pageform.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") @@ -273,13 +293,15 @@ def editexpopage(request, path): title, = m.groups() else: title = "" - flatpageForm = FlatPageForm({"html": body, "title": title}) + pageform = ExpoPageForm({"html": body, "title": title}) else: body = "### File not found ###\n" + str(filepath) - flatpageForm = FlatPageForm({"html": body, "title": "Missing"}) - return render(request, 'editexpopage.html', {'path': path, 'form': flatpageForm, }) + pageform = ExpoPageForm({"html": body, "title": "Missing"}) + return render(request, 'editexpopage.html', {'path': path, 'form': pageform, }) -class FlatPageForm(forms.Form): +class ExpoPageForm(forms.Form): + '''The form used by the editexpopage function + ''' title = forms.CharField(widget=forms.TextInput(attrs={'size':'60'})) #html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 20})) diff --git a/templates/flatpage.html b/templates/expopage.html similarity index 100% rename from templates/flatpage.html rename to templates/expopage.html diff --git a/urls.py b/urls.py index 7bd6585..7184823 100644 --- a/urls.py +++ b/urls.py @@ -172,6 +172,7 @@ urlpatterns = [ ] # When apache is running these prempt Django so Django never sees them. +# NB apache has its own ideas about mimetypes, so behaviour may not be identical for .xml files by troggle # NEW apache configurations suggested as of 2 April 2021: # Alias /site-media/ /home/expo/troggle/media/