diff options
author | Philip Sargent <philip.sargent@gmail.com> | 2025-02-18 19:59:12 +0200 |
---|---|---|
committer | Philip Sargent <philip.sargent@gmail.com> | 2025-02-18 19:59:12 +0200 |
commit | cc06e2e1f4bdfbf354d79055595980a1bdef495c (patch) | |
tree | 67c5bfc0356ce571a318ddc8a8a9b60300863b26 | |
parent | 95190324fbbf9e0a5ce3e324119c1d59eee99951 (diff) | |
download | troggle-cc06e2e1f4bdfbf354d79055595980a1bdef495c.tar.gz troggle-cc06e2e1f4bdfbf354d79055595980a1bdef495c.tar.bz2 troggle-cc06e2e1f4bdfbf354d79055595980a1bdef495c.zip |
Attempt at append_slash, and backtrack.
-rw-r--r-- | core/context.py | 2 | ||||
-rw-r--r-- | core/middleware.py | 50 | ||||
-rw-r--r-- | core/views/logbook_edit.py | 1 | ||||
-rw-r--r-- | core/views/uploads.py | 1 | ||||
-rw-r--r-- | media/css/trog3.css | 2 | ||||
-rw-r--r-- | settings.py | 24 | ||||
-rw-r--r-- | templates/photouploadform.html | 2 | ||||
-rw-r--r-- | urls.py | 44 |
8 files changed, 73 insertions, 53 deletions
diff --git a/core/context.py b/core/context.py index e410fd6..4e11f35 100644 --- a/core/context.py +++ b/core/context.py @@ -1,6 +1,6 @@ from django.conf import settings -from troggle.core.models.troggle import Expedition +# from troggle.core.models.troggle import Expedition """This is the only troggle-specific 'context processor' that troggle uses in the processing of Django templates diff --git a/core/middleware.py b/core/middleware.py index 686d7d5..2b280a1 100644 --- a/core/middleware.py +++ b/core/middleware.py @@ -1,31 +1,48 @@ +import pathlib from django import http from django.conf import settings from django.urls import Resolver404, resolve +from django.utils.deprecation import MiddlewareMixin +from troggle import settings """Non-standard django middleware is loaded from this file. """ todo = """SmartAppendSlashMiddleware(object) Not Working. -It needs re-writing to be compatible with Django v2.0 and later +It needs re-writing. Can we make this work even though we have a catchall url rule ? """ -class SmartAppendSlashMiddleware(object): +class TroggleAppendSlashMiddleware(MiddlewareMixin): """ "SmartAppendSlash" middleware for taking care of URL rewriting. This middleware appends a missing slash, if: * the SMART_APPEND_SLASH setting is True - * the URL without the slash does not exist - * the URL with an appended slash does exist. + * the URL without the slash does not exist in urls.py + * the URL with an appended slash does exist in urls.py Otherwise it won't touch the URL. + + MODIFICATION + Since we have a universal catchall url pattern in urls.py, the usual way this works + won't ever trigger adding a slash. So we check for the existence of a file in expoweb, + not the existence of a pattern in urls.py... + + but site_media.. + but css etc.... + + CONCLUSION + This technique "works" but would be a maintence nightmare, so DO NOT USE IT + do NOT include + troggle.core.middleware.TroggleAppendSlashMiddleware + in settings.py """ def process_request(self, request): """Called for every url so return as quickly as possible - Append a slash if SMART_APPEND_SLASH is set, the resulting URL resolves and it doesn't without the / + Append a slash if TROGGLE_APPEND_SLASH is set, the resulting URL resolves and it doesn't without the / """ - if not settings.SMART_APPEND_SLASH: + if not settings.TROGGLE_APPEND_SLASH: return None if request.path.endswith("/"): @@ -33,16 +50,31 @@ class SmartAppendSlashMiddleware(object): if request.path.endswith("_edit"): return None + + if request.path.startswith("/"): + relative_path = request.path[1:] + else: + relative_path = request.path + + for root in [settings.MEDIA_ROOT, settings.JSLIB_ROOT, settings.EXPOFILES, settings.SCANS_ROOT, settings.PHOTOS_ROOT]: + full_path = root / relative_path + print(f"+++++ MIDDLEWARE checking {root} / {relative_path} ") + if full_path.is_file(): + print(f"+++++ MIDDLEWARE It IS a {root} file {full_path=} so use it as-is.") + return None + else: + print(f"+++++ MIDDLEWARE NOT a {root}file {full_path=}") host = http.HttpRequest.get_host(request) old_url = [host, request.path] - if _resolves(old_url[1]): - return None + # if _resolves(old_url[1]): + # return None - # So: it does not resolve according to our criteria, i.e. _edit doesn't count + # So: it does not resolve according to our criteria, i.e. _edit doesn't count, and URL resolves doesn't count because of the catch all new_url = old_url[:] new_url[1] = new_url[1] + "/" if not _resolves(new_url[1]): + print(f"+++++ MIDDLEWARE add SLASH and resolves {old_url=} => {new_url=}") return None else: if settings.DEBUG and request.method == "POST": diff --git a/core/views/logbook_edit.py b/core/views/logbook_edit.py index a5c194f..198cc38 100644 --- a/core/views/logbook_edit.py +++ b/core/views/logbook_edit.py @@ -393,7 +393,6 @@ def logbookedit(request, year=None, slug=None): text = lbe.text
rows = max(5,len(text)/50)
- print("IDENT",identified_login, who_are_you)
return render(
request,
"logbookform.html",
diff --git a/core/views/uploads.py b/core/views/uploads.py index d65a803..12a3989 100644 --- a/core/views/uploads.py +++ b/core/views/uploads.py @@ -733,7 +733,6 @@ def dwgupload(request, folder=None, gitdisable="no"): if identified_login: # disable editing the git id string as we get it from the logged-on user data - print(f"IDENTIFIED {identified_login}") form.fields["who_are_you"].widget.attrs["readonly"]="readonly" response = render( request, diff --git a/media/css/trog3.css b/media/css/trog3.css index 3ab8faa..3eec162 100644 --- a/media/css/trog3.css +++ b/media/css/trog3.css @@ -359,7 +359,7 @@ div#header { margin-left:auto;
margin-right:auto;
Dheight:50px;
- background-image: url( ../loserBanner.jpg);
+ background-image: url( /site_media/loserBanner.jpg);
border-bottom:thin solid #000;
font-family: Arial, Helvetica, sans-serif;
font-variant: normal;
diff --git a/settings.py b/settings.py index d9c836b..486d494 100644 --- a/settings.py +++ b/settings.py @@ -48,6 +48,7 @@ ALLOWED_HOSTS = ["*", "expo.survex.com", ".survex.com", "localhost", "127.0.0.1" ADMINS = ( ('Wookey', 'wookey@wookware.org'), + ('Philip', 'philip.sargent@klebos.eu'), ) MANAGERS = ADMINS @@ -78,15 +79,12 @@ FIX_PERMISSIONS = [] # SURVEX_TOPNAME = "1623-and-1626-no-schoenberg-hs" SURVEX_TOPNAME = "troggle_import_root" # same, but without all the 'essentials' gubbins -APPEND_SLASH = ( - False # never relevant because we have urls that match unknown files and produce an 'edit this page' response -) -SMART_APPEND_SLASH = True # not eorking as middleware different after Dj2.0 - -ROOT_URLCONF = "troggle.urls" +ROOT_URLCONF = "troggle.urls" # i.e. troggle/urls.py LOGOUT_REDIRECT_URL = "/statistics" # see troggle/core/views/auth.py LOGIN_REDIRECT_URL = "/controlpanel" # see troggle/core/views/auth.py + PASSWORD_RESET_TIMEOUT = 3*60*60 # password reset sends an email. The response is valid for 3 hours +#ACCOUNT_ACTIVATION_DAYS = 3 # this is only if we are using django-registration package SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_BROWSER_XSS_FILTER = True @@ -114,6 +112,8 @@ FORM_RENDERER = "django.forms.renderers.TemplatesSetting" # Required to customi # Note that this is a radically different onion architecture from earlier versions though it looks the same, # see https://docs.djangoproject.com/en/dev/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware # Seriously, read this: https://www.webforefront.com/django/middlewaredjango.html which is MUCH BETTER than the docs + +# We are NOT using the home-built SmartAppendSlashMiddleware MIDDLEWARE = [ #'django.middleware.security.SecurityMiddleware', # SECURE_SSL_REDIRECT and SECURE_SSL_HOST # we don't use this "django.middleware.gzip.GZipMiddleware", # not needed when expofiles and photos served by apache @@ -125,15 +125,14 @@ MIDDLEWARE = [ "django.contrib.messages.middleware.MessageMiddleware", # Cookie-based and session-based message support. Needed by admin system "django.middleware.clickjacking.XFrameOptionsMiddleware", # clickjacking protection via the X-Frame-Options header #'django.middleware.security.SecurityMiddleware', # SECURE_HSTS_SECONDS, SECURE_CONTENT_TYPE_NOSNIFF, SECURE_BROWSER_XSS_FILTER, SECURE_REFERRER_POLICY, and SECURE_SSL_REDIRECT - #'troggle.core.middleware.SmartAppendSlashMiddleware' # needs adapting after Dj2.0 + #"troggle.core.middleware.TroggleAppendSlashMiddleware", # modified Feb.2025 ] WSGI_APPLICATION = "troggle.wsgi.application" # change to asgi as soon as we upgrade to Django 3.0 - -ACCOUNT_ACTIVATION_DAYS = 3 - -# AUTH_PROFILE_MODULE = 'core.person' # used by removed profiles app ? - +# Append slash can't work if we have a universal catchall URL rule, and we do because all the handbook files +# do not have simple prefix. This is why we used to have an /expoweb/ prefix for everything in the website. +# APPEND_SLASH = True # using django.middleware.common.CommonMiddleware. Pointless, never happens if there is a catchall. +# TROGGLE_APPEND_SLASH = True # this is our middleware: see the code in troggle/core/middleware.py for why we do NOT use it. QM_PATTERN = r"\[\[\s*[Qq][Mm]:([ABC]?)(\d{4})-(\d*)-(\d*)\]\]" # Re-enable TinyMCE when Dj upgraded to v3. Also templates/editexpopage.html @@ -148,5 +147,4 @@ TEST_RUNNER = "django.test.runner.DiscoverRunner" print("+ finished importing troggle/settings.py, re-importing localsettings again") from localsettings import * - # localsettings needs to take precedence. Call it to override any existing vars. diff --git a/templates/photouploadform.html b/templates/photouploadform.html index 4c2b5a0..a2167fb 100644 --- a/templates/photouploadform.html +++ b/templates/photouploadform.html @@ -24,7 +24,7 @@ pattern="[A-Za-z][A-Za-z0-9_-\.]*"/> <label style="padding: 0.5em 25px; margin-left: 110px" - for="renameto">If uploading a single file, you can rename it<br></label> + for="renameto"><br />If uploading a single file, you can rename it<br></label> <br><br><br> <button class="fancybutton2" style="padding: 0.5em 25px; margin-left: 155px" type = "submit" value = "Upload" > Upload @@ -74,6 +74,8 @@ re_path( <regular expression that matches the thing in the web browser>, Django also provides the reverse function: given an an object, provide the URL which is vital to writing code for the webapp. So the URL dispatch is declarative. +But this means that two URLs should NOT go to the same python target function, +(or only if the target name is different) The API urls return TSV or JSON and are new in July 2020. """ @@ -101,16 +103,19 @@ todo = ''' if settings.EXPOFILESREMOTE: expofilesurls = [ path('<path:filepath>', expofiles_redirect, name="expofiles_redirect"), # to http://expo.survex.com/expofiles - path('', expofiles_redirect, {'filepath': ""}, name="expofiles_redirect"), + path('', expofiles_redirect, {'filepath': ""}, name="expofiles_redirect"), #should not have duplicate urls as reverse() then fails ] else: expofilesurls = [ - path('', expofilessingle, {'filepath': ""}, name="single"), - path('<path:filepath>', expofilessingle, name="single"), # local copy of EXPOFILES + path('', expofilessingle, {'filepath': ""}, name="single"), + path('<path:filepath>', expofilessingle, name="single"), # local copy of EXPOFILES, but should not have duplicate urls as reverse() then fails ] trogglepatterns = [ + # NOT intercepted by apache. Needs to come first to prevent our troggle middleware trying to "fix" it. + re_path(r'^site_media/(?P<subpath>.*)$', mediapage, {'doc_root': settings.MEDIA_ROOT}, name="mediapage"), # MEDIA_ROOT: CSS and JS + path('pubs.htm', pubspage, name="pubspage"), # ~165 hrefs to this url in expoweb files #path('', indexpage, name="indexpage"), # ~1,212 hrefs to this url in expoweb files path('index.htm', indexpage, name="indexpage"), # ~1,212 hrefs to this url in expoweb files @@ -118,7 +123,7 @@ trogglepatterns = [ path('expofiles/', include(expofilesurls)), # intercepted by Apache, if it is running. path('expofiles', include(expofilesurls)), # curious interaction with the include() here, not just a slash problem. - re_path(r'^(.*)_edit_edit$', spider, name="spider"), # web spider funny + re_path(r'^(.*)_edit_edit$', spider, name="spider"), # web spider. Intercept and manage it. re_path(r'^caves$', caveindex, name="caveindex"), re_path(r'^indxal.htm$', caveindex, name="caveindex"), # ~420 hrefs to this url in expoweb files @@ -132,13 +137,13 @@ trogglepatterns = [ path('admin/', admin.site.urls), # includes admin login & logout urls & /admin/jsi18n/ # Uploads - uploading a file - path('walletedit/', walletedit, name='walletedit'), - path('walletedit/<path:path>', walletedit, name='walletedit'), # path=2020#01 + path('walletedit/', walletedit, name='walletedit'), # not just an upload, also edit metadata + path('walletedit/<path:path>', walletedit, name='walletedit'), # path=2020#01 path('photoupload/', photoupload, name='photoupload'), # restricted to current year - path('photoupload/<path:folder>', photoupload, name='photoupload'), # restricted to current year + path('photoupload/<path:folder>', photoupload, name='photoupload'), # restricted to current year path('gpxupload/', gpxupload, name='gpxupload'), # restricted to current year - path('gpxupload/<path:folder>', gpxupload, name='gpxupload'), # restricted to current year - path('dwgupload/<path:folder>', dwgupload, name='dwgupload'), + path('gpxupload/<path:folder>', gpxupload, name='gpxupload'), # restricted to current year + path('dwgupload/<path:folder>', dwgupload, name='dwgupload'), path('dwgupload/', dwgupload, name='dwgupload'), path('dwguploadnogit/', dwgupload, {'gitdisable': 'yes'}, name='dwguploadnogit'), # used in testing path('dwguploadnogit/<path:folder>', dwgupload, {'gitdisable': 'yes'}, name='dwguploadnogit'), # used in testing @@ -195,7 +200,6 @@ trogglepatterns = [ re_path(r'^logbook$', exportlogbook, name='exportlogbook'), path('logreport/<slug:year>', logreport, name='logreport'), path('logentrydelete/<slug:year>', logentrydelete, name='logentrydelete'), - # Internal. editfile.html template uses these internally re_path(r'^getPeople/(?P<expeditionslug>.*)', get_people, name = "get_people"), @@ -210,17 +214,13 @@ trogglepatterns = [ path('fix/<slug:areacode>', fix, name="fix"), re_path(r'^newcave/$', edit_cave, name="newcave"), re_path(r'^cave/3d/(?P<cave_id>[^/]+).3d$', cave3d, name="cave3d"), - - #re_path(r'^cave/description/([^/]+)/?$', caves.caveDescription), #!!!BAD, local links fail.. - #re_path(r'^cave/(?P<cave_id>[^/]+)/?$', caves.cave, name="cave"), # used only in testing !? XXXXXXXXXXXXXXXXXXXXXXXXXX - #re_path(r'^cave/(?P<cave_id>[^/]+)/?(?P<ent_letter>[^/])$', ent), #!!!BAD, local links fail..# view_caves.ent # Edit caves and entrances re_path(r'^(?P<path>.*)/(?P<slug>[^/]+)_cave_edit/$', edit_cave, name="edit_cave"), # edit_cave needed by cave.html template for url matching re_path(r'^(?P<caveslug>[^/]+):(?P<entslug>[^:]+)_entrance_edit', edit_entrance, name = "editentrance"), #edit existing entrance re_path(r'^(?P<path>.*)/(?P<caveslug>[^/]+)_entrance_new$', edit_entrance, name = "newentrance"), # new entrance for a cave - re_path(r'^(.*)_edit$', editexpopage, name="editexpopage"), + re_path(r'^(.*)_edit$', editexpopage, name="editexpopage"), # only happens if not a cave or entrance _edit page re_path(r'^(?P<karea>162\d)(?P<subpath>.*)$', cavepage, name="cavepage"), # shorthand /1623/264 or 1623/161/top.htm or 1623/161/i/stuff.jpg # Note that urls eg '/1623/161/l/rl89a.htm' are handled by cavepage which redirects them to 'expopage' # Note that _edit$ for a cave description page in a subfolder e.g. /1623/204/204.html_edit gets caught here and breaks with 404 @@ -265,20 +265,16 @@ trogglepatterns = [ path('survexfilewild/', statistics.svxfilewild, name="svxfilewild"), path('survexfilewild/<int:year>', statistics.svxfilewild, name="svxfilewild"), - # The survey scans in the wallets. This short-cuts SCANS_URL which is not used anymore and is defunct path('survey_scans/', allscans, name="allscans"), # all the scans in all wallets path('survey_scans/<path:path>/', walletedit, name="singlewallet"), # replaced singlewallet() path('survey_scans/<path:path>/<file>', scansingle, name="scansingle"), # works, but html href goes direct to /expofiles/ too path('cave/scans/<slug:caveid>', cavewallets, name="cavewallets"), # like allscans, but for just one cave -# The data about the wallets themselves, not the scans inside tehm +# The data about the wallets themselves, not the scans inside them path('wallets/year/<int:year>', walletslistyear, name="walletslistyear"), # wallets that are for a specific year, as an integer '1985' - # re_path('wallets/person/(?P<first_name>[A-Z]*[a-z\-\'&;]*)[^a-zA-Z]*(?P<last_name>[a-z\-\']*[^a-zA-Z]*[\-]*[A-Z]*[a-zA-Z\-&;]*)/?', walletslistperson, name="walletslistperson"), path('wallets/person/<slug:slug>', walletslistperson, name="walletslistperson"), - - # The tunnel and therion drawings files pageswalletslistcave path('drawings', dwgallfiles, name="dwgallfiles"), path('drawings/', dwgallfiles, name="dwgallfiles"), @@ -308,12 +304,6 @@ trogglepatterns = [ path('javascript/<path:subpath>', mediapage, {'doc_root': settings.JSLIB_ROOT}, name="mediapage"), # JSLIB_URL -# NOT intercepted by apache - re_path(r'^site_media/(?P<subpath>.*)$', mediapage, {'doc_root': settings.MEDIA_ROOT}, name="mediapage"), # MEDIA_ROOT: CSS and JS - -# Fossil ? /loser/caves-1623/171/171.svx fails 404, /loser/docs/smklengths fails 404 - re_path(r'^/loser/(?P<subpath>.*)$', mediapage, {'doc_root': settings.SURVEX_DATA}, name="mediapage"), # Oddly not working !? - # Helpers to edit HTML re_path(r'^image_selector/(?P<path>.*)', image_selector, name = 'image_selector'), @@ -323,6 +313,8 @@ trogglepatterns = [ re_path(r'^expo.kmz', expo_kmz, name = 'expo.kmz'), # Final catchall which also serves expoweb handbook pages and imagestiny +# but a universal catchall also prevents the djang standard append_slash working, as every string resolves. +# try to fix in troggle/middleware.py re_path(r'^(.*)$', expopage, name="expopage"), # CATCHALL assumed relative to EXPOWEB ] |