summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore16
-rw-r--r--_deploy/debian-server/credentials.py22
-rw-r--r--_deploy/debian-server/localsettings-expo-live.py162
-rw-r--r--_deploy/debian-server/localsettings.py164
-rw-r--r--[-rwxr-xr-x]_deploy/wsl/gitpull.sh0
-rw-r--r--_deploy/wsl/localsettingsWSL.py.bak181
-rw-r--r--[-rwxr-xr-x]_deploy/wsl/os-trog24.04.sh0
-rw-r--r--[-rwxr-xr-x]_deploy/wsl/using-pip/requirements-keep.txt0
-rw-r--r--[-rwxr-xr-x]_deploy/wsl/using-pip/requirements-p9d4.txt0
-rw-r--r--localsettings.py187
-rw-r--r--[-rwxr-xr-x]pre-push.sh0
-rw-r--r--[-rwxr-xr-x]pre-run.sh0
12 files changed, 717 insertions, 15 deletions
diff --git a/.gitignore b/.gitignore
index 15e1963..28cf73a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,22 +49,8 @@ troggle.sqlite-journal
troggle_log.txt
tunnel-import.log
-credentials.py
-localsettings.py
-localsettings-expo-live.py
-localsettings-oldMuscogee.py
+secret_credentials.py
-_deploy/old/localsettings-expo-live.py
-_deploy/old/localsettings.py
-_deploy/debian/localsettings.py
-_deploy/debian/credentials.py
-_deploy/debian/localsettings-jan.py
-_deploy/debian/localsettings-nw.py
-_deploy/debian/localsettingsserver2023-01-secret.py
-_deploy/debian/localsettings2023-04-05-secret.py
-_deploy/wsl/localsettings.py
-_deploy/wsl/credentials.py
-_deploy/wsl/localsettingsWSL.py.bak
media/jslib/*
!media/jslib/readme.txt
diff --git a/_deploy/debian-server/credentials.py b/_deploy/debian-server/credentials.py
new file mode 100644
index 0000000..2f856ed
--- /dev/null
+++ b/_deploy/debian-server/credentials.py
@@ -0,0 +1,22 @@
+
+EXPOUSER = 'expo'
+EXPOADMINUSER = 'expoadmin'
+EXPOUSER_EMAIL = 'wookey@wookware.org'
+EXPOADMINUSER_EMAIL = 'wookey@wookware.org'
+import secret_credentials.py
+
+EXPOFILESREMOTE = False # if True, then re-routes urls in expofiles to remote sever
+#SECURE_SSL_REDIRECT = True # breaks 7 tests in test suite 301 not 200 (or 302) and runserver fails completely
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.mysql', # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ "OPTIONS": {
+ "charset": "utf8mb4", # To permit emojis in logbook entries and elsewhere
+ }, 'NAME' : 'troggle', # Or path to database file if using sqlite3.
+ 'USER' : 'expo', # Not used with sqlite3.
+ 'PASSWORD' : MARIADB_SERVER_PASSWORD, # Not used with sqlite3.
+ 'HOST' : '', # Set to empty string for localhost. Not used with sqlite3.
+ 'PORT' : '', # Set to empty string for default. Not used with sqlite3.
+ }
+}
diff --git a/_deploy/debian-server/localsettings-expo-live.py b/_deploy/debian-server/localsettings-expo-live.py
new file mode 100644
index 0000000..d1dd8a1
--- /dev/null
+++ b/_deploy/debian-server/localsettings-expo-live.py
@@ -0,0 +1,162 @@
+import os
+import sys
+import urllib.parse
+from pathlib import Path
+
+"""Settings for a troggle installation which may vary among different
+installations: for development or deployment, in a docker image or
+python virtual environment (venv), on ubuntu, debian or in Windows
+System for Linux (WSL), on the main server or in the potato hut,
+using SQLite or mariaDB.
+
+It sets the directory locations for the major parts of the system so
+that e.g. expofiles can be on a different filesystem.
+
+This file is included at the end of the main troggle/settings.py file so that
+it overwrites defaults in that file.
+
+NOTE this file is out of sync with troggle/_deploy/wsl/localsettings.py
+which is the most recent version used in active maintenance. There should be
+essential differences, but there and many, many non-essential differences which
+should be eliminated for clarity and to use modern idioms.
+Edited 31/12/2024
+"""
+
+print(" * importing troggle/localsettings.py")
+
+# DO NOT check this file into the git repo - it contains real passwords.
+
+EXPOFILESREMOTE = False # if True, then re-routes urls in expofiles to remote sever
+#SECURE_SSL_REDIRECT = True # breaks 7 tests in test suite 301 not 200 (or 302) and runserver fails completely
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.mysql', # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ "OPTIONS": {
+ "charset": "utf8mb4", # To permit emojis in logbook entries and elsewhere
+ }, 'NAME' : 'troggle', # Or path to database file if using sqlite3.
+ 'USER' : 'expo', # Not used with sqlite3.
+ 'PASSWORD' : 'uFqP56B4XleeyIW', # Not used with sqlite3.
+ 'HOST' : '', # Set to empty string for localhost. Not used with sqlite3.
+ 'PORT' : '', # Set to empty string for default. Not used with sqlite3.
+ }
+}
+
+
+EXPOUSER = 'expo'
+EXPOADMINUSER = 'expoadmin'
+EXPOUSER_EMAIL = 'wookey@wookware.org'
+EXPOADMINUSER_EMAIL = 'wookey@wookware.org'
+import secret_credentials.py
+
+REPOS_ROOT_PATH = '/home/expo/'
+sys.path.append(REPOS_ROOT_PATH)
+sys.path.append(REPOS_ROOT_PATH + 'troggle')
+# Define the path to the django app (troggle in this case)
+PYTHON_PATH = REPOS_ROOT_PATH + 'troggle/'
+
+
+PHOTOS_YEAR = "2024"
+# add in 358 when they don't make it crash horribly
+NOTABLECAVESHREFS = [ "290", "291", "359", "264", "258", "204", "76", "107"]
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [
+ PYTHON_PATH + "templates"
+ ],
+ 'OPTIONS': {
+ 'debug': 'DEBUG',
+ 'context_processors': [
+ # django.template.context_processors.csrf, # is always enabled and cannot be removed, sets csrf_token
+ 'django.contrib.auth.context_processors.auth', # knowledge of logged-on user & permissions
+ 'core.context.troggle_context', # in core/troggle.py
+ 'django.template.context_processors.debug',
+ #'django.template.context_processors.request', # copy of current request, added in trying to make csrf work
+ 'django.template.context_processors.i18n',
+ 'django.template.context_processors.media', # includes a variable MEDIA_URL
+ 'django.template.context_processors.static', # includes a variable STATIC_URL
+ 'django.template.context_processors.tz',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ 'loaders': [
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader', #For each app, inc admin, in INSTALLED_APPS, loader looks for /templates
+ # insert your own TEMPLATE_LOADERS here
+ ]
+ },
+ },
+]
+
+PUBLIC_SITE = True
+
+# This should be False for normal running
+DEBUG = True
+CACHEDPAGES = True # experimental page cache for a handful of page types
+
+
+# executables:
+CAVERN = 'cavern' # for parsing .svx files and producing .2d files
+SURVEXPORT = 'survexport' # for parsing .3d files and producing .pos files
+
+PV = "python" + str(sys.version_info.major) + "." + str(sys.version_info.minor)
+LIBDIR = Path(REPOS_ROOT_PATH) / 'lib' / PV
+
+EXPOWEB = Path(REPOS_ROOT_PATH + 'expoweb/')
+SURVEYS = REPOS_ROOT_PATH
+SURVEY_SCANS = REPOS_ROOT_PATH + 'expofiles/surveyscans/'
+FILES = REPOS_ROOT_PATH + 'expofiles'
+PHOTOS_ROOT = REPOS_ROOT_PATH + 'expofiles/photos/'
+
+TROGGLE_PATH = Path(__file__).parent
+TEMPLATE_PATH = TROGGLE_PATH / 'templates'
+MEDIA_ROOT = TROGGLE_PATH / 'media'
+JSLIB_ROOT = TROGGLE_PATH / 'media' / 'jslib' # used for CaveViewer JS utility
+
+
+CAVEDESCRIPTIONS = EXPOWEB / "cave_data"
+ENTRANCEDESCRIPTIONS = EXPOWEB / "entrance_data"
+
+
+PYTHON_PATH = REPOS_ROOT_PATH + 'troggle/'
+
+
+#URL_ROOT = 'http://expo.survex.com/'
+URL_ROOT = '/'
+DIR_ROOT = Path("") #this should end in / if a value is given
+EXPOWEB_URL = '/'
+SURVEYS_URL = '/survey_scans/'
+
+REPOS_ROOT_PATH = Path(REPOS_ROOT_PATH)
+
+SURVEX_DATA = REPOS_ROOT_PATH / "loser"
+DRAWINGS_DATA = REPOS_ROOT_PATH / "drawings"
+
+
+EXPOFILES = REPOS_ROOT_PATH / "expofiles"
+SCANS_ROOT = EXPOFILES / "surveyscans"
+PHOTOS_ROOT = EXPOFILES / "photos"
+
+#EXPOFILES = urllib.parse.urljoin(REPOS_ROOT_PATH, 'expofiles/')
+PHOTOS_URL = urllib.parse.urljoin(URL_ROOT, '/photos/')
+
+# MEDIA_URL is used by urls.py in a regex. See urls.py & core/views_surveys.py
+MEDIA_URL = '/site_media/'
+
+
+STATIC_URL = urllib.parse.urljoin(URL_ROOT , '/static/') # used by Django admin pages. Do not delete.
+JSLIB_URL = urllib.parse.urljoin(URL_ROOT , '/javascript/') # always fails, try to revive it ?
+# STATIC_ROOT removed after merging content into MEDIA_ROOT. See urls.py & core/views/surveys.py
+
+#TINY_MCE_MEDIA_ROOT = STATIC_ROOT + '/tiny_mce/' # not needed while TinyMCE not installed
+#TINY_MCE_MEDIA_URL = STATIC_URL + '/tiny_mce/' # not needed while TinyMCE not installed
+
+LOGFILE = '/var/log/troggle/troggle.log'
+IMPORTLOGFILE = '/var/log/troggle/import.log'
+
+# Sanitise these to be strings as Django seems to be particularly sensitive to crashing if they aren't
+#STATIC_URL = str(STATIC_URL) + "/"
+#MEDIA_URL = str(MEDIA_URL) + "/"
+
+print(" + finished importing troggle/localsettings.py")
diff --git a/_deploy/debian-server/localsettings.py b/_deploy/debian-server/localsettings.py
new file mode 100644
index 0000000..0e2fe6f
--- /dev/null
+++ b/_deploy/debian-server/localsettings.py
@@ -0,0 +1,164 @@
+import os
+import sys
+import urllib.parse
+from pathlib import Path
+
+"""Settings for a troggle installation which may vary among different
+installations: for development or deployment, in a docker image or
+python virtual environment (venv), on ubuntu, debian or in Windows
+System for Linux (WSL), on the main server or in the potato hut,
+using SQLite or mariaDB.
+
+It sets the directory locations for the major parts of the system so
+that e.g. expofiles can be on a different filesystem.
+
+This file is included at the end of the main troggle/settings.py file so that
+it overwrites defaults in that file.
+
+NOTE this file is out of sync with troggle/_deploy/wsl/localsettings.py
+which is the most recent version used in active maintenance. There should be
+essential differences, but there and many, many non-essential differences which
+should be eliminated for clarity and to use modern idioms.
+Edited 31/12/2024
+"""
+
+print(" * importing troggle/localsettings.py")
+
+# DO NOT check this file into the git repo - it contains real passwords.
+
+EXPOFILESREMOTE = False # if True, then re-routes urls in expofiles to remote sever
+#SECURE_SSL_REDIRECT = True # breaks 7 tests in test suite 301 not 200 (or 302) and runserver fails completely
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.mysql', # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ "OPTIONS": {
+ "charset": "utf8mb4", # To permit emojis in logbook entries and elsewhere
+ },
+ 'NAME' : 'troggle', # Or path to database file if using sqlite3.
+ 'USER' : 'expo', # Not used with sqlite3.
+ 'PASSWORD' : 'not-the-real-password', # Not used with sqlite3.
+ 'HOST' : '', # Set to empty string for localhost. Not used with sqlite3.
+ 'PORT' : '', # Set to empty string for default. Not used with sqlite3.
+ }
+}
+
+
+EXPOUSER = 'expo'
+EXPOUSERPASS = 'not-the-real-password'
+EXPOADMINUSER = 'expoadmin'
+EXPOADMINUSERPASS = 'not-the-real-password'
+EXPOUSER_EMAIL = 'wookey@wookware.org'
+EXPOADMINUSER_EMAIL = 'wookey@wookware.org'
+
+REPOS_ROOT_PATH = '/home/expo/'
+sys.path.append(REPOS_ROOT_PATH)
+sys.path.append(REPOS_ROOT_PATH + 'troggle')
+# Define the path to the django app (troggle in this case)
+PYTHON_PATH = REPOS_ROOT_PATH + 'troggle/'
+
+
+PHOTOS_YEAR = "2024"
+# add in 358 when they don't make it crash horribly
+NOTABLECAVESHREFS = [ "290", "291", "359", "264", "258", "204", "76", "107"]
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [
+ PYTHON_PATH + "templates"
+ ],
+ 'OPTIONS': {
+ 'debug': 'DEBUG',
+ 'context_processors': [
+ # django.template.context_processors.csrf, # is always enabled and cannot be removed, sets csrf_token
+ 'django.contrib.auth.context_processors.auth', # knowledge of logged-on user & permissions
+ 'core.context.troggle_context', # in core/troggle.py
+ 'django.template.context_processors.debug',
+ #'django.template.context_processors.request', # copy of current request, added in trying to make csrf work
+ 'django.template.context_processors.i18n',
+ 'django.template.context_processors.media', # includes a variable MEDIA_URL
+ 'django.template.context_processors.static', # includes a variable STATIC_URL
+ 'django.template.context_processors.tz',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ 'loaders': [
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader', #For each app, inc admin, in INSTALLED_APPS, loader looks for /templates
+ # insert your own TEMPLATE_LOADERS here
+ ]
+ },
+ },
+]
+
+PUBLIC_SITE = True
+
+# This should be False for normal running
+DEBUG = True
+CACHEDPAGES = True # experimental page cache for a handful of page types
+
+
+# executables:
+CAVERN = 'cavern' # for parsing .svx files and producing .2d files
+SURVEXPORT = 'survexport' # for parsing .3d files and producing .pos files
+
+PV = "python" + str(sys.version_info.major) + "." + str(sys.version_info.minor)
+LIBDIR = Path(REPOS_ROOT_PATH) / 'lib' / PV
+
+EXPOWEB = Path(REPOS_ROOT_PATH + 'expoweb/')
+SURVEYS = REPOS_ROOT_PATH
+SURVEY_SCANS = REPOS_ROOT_PATH + 'expofiles/surveyscans/'
+FILES = REPOS_ROOT_PATH + 'expofiles'
+PHOTOS_ROOT = REPOS_ROOT_PATH + 'expofiles/photos/'
+
+TROGGLE_PATH = Path(__file__).parent
+TEMPLATE_PATH = TROGGLE_PATH / 'templates'
+MEDIA_ROOT = TROGGLE_PATH / 'media'
+JSLIB_ROOT = TROGGLE_PATH / 'media' / 'jslib' # used for CaveViewer JS utility
+
+
+CAVEDESCRIPTIONS = EXPOWEB / "cave_data"
+ENTRANCEDESCRIPTIONS = EXPOWEB / "entrance_data"
+
+
+PYTHON_PATH = REPOS_ROOT_PATH + 'troggle/'
+
+
+#URL_ROOT = 'http://expo.survex.com/'
+URL_ROOT = '/'
+DIR_ROOT = Path("") #this should end in / if a value is given
+EXPOWEB_URL = '/'
+SURVEYS_URL = '/survey_scans/'
+
+REPOS_ROOT_PATH = Path(REPOS_ROOT_PATH)
+
+SURVEX_DATA = REPOS_ROOT_PATH / "loser"
+DRAWINGS_DATA = REPOS_ROOT_PATH / "drawings"
+
+
+EXPOFILES = REPOS_ROOT_PATH / "expofiles"
+SCANS_ROOT = EXPOFILES / "surveyscans"
+PHOTOS_ROOT = EXPOFILES / "photos"
+
+#EXPOFILES = urllib.parse.urljoin(REPOS_ROOT_PATH, 'expofiles/')
+PHOTOS_URL = urllib.parse.urljoin(URL_ROOT, '/photos/')
+
+# MEDIA_URL is used by urls.py in a regex. See urls.py & core/views_surveys.py
+MEDIA_URL = '/site_media/'
+
+
+STATIC_URL = urllib.parse.urljoin(URL_ROOT , '/static/') # used by Django admin pages. Do not delete.
+JSLIB_URL = urllib.parse.urljoin(URL_ROOT , '/javascript/') # always fails, try to revive it ?
+# STATIC_ROOT removed after merging content into MEDIA_ROOT. See urls.py & core/views/surveys.py
+
+#TINY_MCE_MEDIA_ROOT = STATIC_ROOT + '/tiny_mce/' # not needed while TinyMCE not installed
+#TINY_MCE_MEDIA_URL = STATIC_URL + '/tiny_mce/' # not needed while TinyMCE not installed
+
+LOGFILE = '/var/log/troggle/troggle.log'
+IMPORTLOGFILE = '/var/log/troggle/import.log'
+
+# Sanitise these to be strings as Django seems to be particularly sensitive to crashing if they aren't
+#STATIC_URL = str(STATIC_URL) + "/"
+#MEDIA_URL = str(MEDIA_URL) + "/"
+
+print(" + finished importing troggle/localsettings.py")
diff --git a/_deploy/wsl/gitpull.sh b/_deploy/wsl/gitpull.sh
index ad7a45f..ad7a45f 100755..100644
--- a/_deploy/wsl/gitpull.sh
+++ b/_deploy/wsl/gitpull.sh
diff --git a/_deploy/wsl/localsettingsWSL.py.bak b/_deploy/wsl/localsettingsWSL.py.bak
new file mode 100644
index 0000000..3f43c11
--- /dev/null
+++ b/_deploy/wsl/localsettingsWSL.py.bak
@@ -0,0 +1,181 @@
+import sys
+from pathlib import Path
+
+"""Settings for a troggle installation which may vary among different
+installations: for development or deployment, in a docker image or
+python virtual environment (venv), on ubuntu, debian or in Windows
+System for Linux (WSL), on the main server or in the potato hut,
+using SQLite or mariaDB.
+
+It sets the directory locations for the major parts of the system so
+that e.g. expofiles can be on a different filesystem, or /javascript/ can be in
+a system-wide location rather than just a local directory.
+
+This file is included at the end of the main troggle/settings.py file so that
+it overwrites defaults in that file.
+
+Read https://realpython.com/python-pathlib/
+Read https://adamj.eu/tech/2020/03/16/use-pathlib-in-your-django-project/
+"""
+
+print(" * importing troggle/localsettings.py")
+
+# -----------------------------------------------------------------
+# THINK before you push this to a repo
+# - have you checked that credentials.py is in .gitignore ?
+# - we don't want to have to change the expo system password !
+# -----------------------------------------------------------------
+# default values, real secrets imported from credentials.py
+
+SECRET_KEY = "real-SECRET_KEY--imported-from-localsettings.py"
+EXPOUSERPASS = "nnn:gggggg - real-expo-password---imported-from-localsettings.py"
+EXPOADMINUSERPASS = "gggggg:nnn - real-expo-password---imported-from-localsettings.py"
+EMAIL_HOST_PASSWORD = "real-email-password---imported-from-localsettings.py"
+
+EXPOFILESREMOTE = False # if True, then re-routes urls in expofiles to remote sever. Tests are then less accurate.
+# SECURE_SSL_REDIRECT = True # breaks 7 tests in test suite 301 not 200 (or 302) and runserver fails completely
+
+SERVERPORT = "8000" # not needed
+
+PV = "python" + str(sys.version_info.major) + "." + str(sys.version_info.minor)
+
+# Troggle does a lot of file-handling. This is very error-prone when using primitive methods,
+# so we use pathlib which has been standard since python 3.4
+# If pathlib is new to you, you will need to read https://realpython.com/python-pathlib/
+
+# --------------------- MEDIA redirections BEGIN ---------------------
+REPOS_ROOT_PATH = Path(__file__).parent.parent
+LIBDIR = REPOS_ROOT_PATH / "lib" / PV
+
+TROGGLE_PATH = Path(__file__).parent
+TEMPLATE_PATH = TROGGLE_PATH / "templates"
+MEDIA_ROOT = TROGGLE_PATH / "media"
+JSLIB_ROOT = TROGGLE_PATH / "media" / "jslib" # used for CaveViewer JS utility
+
+# FILES = Path('/mnt/d/expofiles/')
+EXPOFILES = REPOS_ROOT_PATH / "expofiles"
+
+SCANS_ROOT = EXPOFILES / "surveyscans"
+PHOTOS_ROOT = EXPOFILES / "photos"
+PHOTOS_YEAR = "2023"
+NOTABLECAVESHREFS = ["290", "291", "264", "258", "204", "359", "76", "107"]
+
+
+PYTHON_PATH = REPOS_ROOT_PATH / "troggle"
+LOGFILE = PYTHON_PATH / "troggle.log"
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+MEDIA_URL = "/site-media/"
+
+DIR_ROOT = Path("") # this should end in / if a value is given
+URL_ROOT = "/"
+# URL_ROOT = 'http://localhost:'+ SERVERPORT +'/'
+
+# Note that these constants are not actually used in urls.py, they should be..
+# and they all need to end with / so using 'Path' doesn't work..
+MEDIA_URL = Path(URL_ROOT, "/site_media/")
+PHOTOS_URL = Path(URL_ROOT, "/photos/")
+
+
+STATIC_URL = Path(URL_ROOT, "/static/") # used by Django admin pages. Do not delete.
+JSLIB_URL = Path(URL_ROOT, "/javascript/") # used for CaveViewer JS utility
+
+# STATIC_ROOT removed after merging content into MEDIA_ROOT. See urls.py & core/views/surveys.py
+# --------------------- MEDIA redirections END ---------------------
+
+PUBLIC_SITE = True
+DEBUG = True # Always keep this True, even when on public server. Otherwise NO USEFUL ERROR MESSAGES !
+CACHEDPAGES = True # experimental page cache for a handful of page types
+
+# executables:
+CAVERN = "cavern" # for parsing .svx files and producing .3d files
+SURVEXPORT = "survexport" # for parsing .3d files and producing .pos files
+
+DBSQLITE = {
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3", # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ "NAME": "/home/philip/expo/troggle.sqlite",
+ # 'NAME' : ':memory:',
+ "USER": "expo", # Not used with sqlite3.
+ "PASSWORD": "sekrit", # Not used with sqlite3.
+ "HOST": "", # Set to empty string for localhost. Not used with sqlite3.
+ "PORT": "", # Set to empty string for default. Not used with sqlite3.
+ }
+}
+DBMARIADB = {
+ "default": {
+ "ENGINE": "django.db.backends.mysql", # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ "NAME": "troggle", # Or path to database file if using sqlite3.
+ "USER": "expo",
+ "PASSWORD": "my-secret-password-schwatzmooskogel",
+ "HOST": "", # Set to empty string for localhost. Not used with sqlite3.
+ "PORT": "", # Set to empty string for default. Not used with sqlite3.
+ }
+}
+
+# default database for me is squlite
+DBSWITCH = "sqlite"
+
+if DBSWITCH == "sqlite":
+ DATABASES = DBSQLITE
+if DBSWITCH == "mariadb":
+ DATABASES = DBMARIADB
+
+
+
+TEMPLATES = [
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [TEMPLATE_PATH],
+ "OPTIONS": {
+ "debug": "DEBUG",
+ "context_processors": [
+ # django.template.context_processors.csrf, # is always enabled and cannot be removed, sets csrf_token
+ "django.contrib.auth.context_processors.auth", # knowledge of logged-on user & permissions
+ "core.context.troggle_context", # in core/context.py - only used in expedition.html
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.media", # includes a variable MEDIA_URL
+ "django.template.context_processors.static", # includes a variable STATIC_URL used by admin pages
+ "django.template.context_processors.tz",
+ "django.template.context_processors.request", # must be enabled in DjangoTemplates (TEMPLATES) in order to use the admin navigation sidebar.
+ "django.contrib.messages.context_processors.messages",
+ ],
+ "loaders": [
+ "django.template.loaders.filesystem.Loader", # default lcation is troggle/templates/
+ "django.template.loaders.app_directories.Loader", # needed for admin 'app'
+ ],
+ },
+ },
+]
+
+EXPOUSER = "expo"
+EXPOUSER_EMAIL = "philip.sargent@gmail.com"
+EXPOADMINUSER = "expoadmin"
+EXPOADMINUSER_EMAIL = "philip.sargent@gmail.com"
+
+EMAIL_HOST = "smtp-auth.mythic-beasts.com"
+EMAIL_HOST_USER = "django-test@klebos.net" # Philip Sargent really
+EMAIL_PORT = 587
+EMAIL_USE_TLS = True
+DEFAULT_FROM_EMAIL = "django-test@klebos.net"
+
+SURVEX_DATA = REPOS_ROOT_PATH / "loser"
+DRAWINGS_DATA = REPOS_ROOT_PATH / "drawings"
+EXPOWEB = REPOS_ROOT_PATH / "expoweb"
+CAVEDESCRIPTIONS = EXPOWEB / "cave_data"
+ENTRANCEDESCRIPTIONS = EXPOWEB / "entrance_data"
+
+# EXPOWEB_URL = "" # defunct, removed.
+# SCANS_URL = '/survey_scans/' # defunct, removed.
+
+sys.path.append(str(REPOS_ROOT_PATH))
+sys.path.append(str(PYTHON_PATH))
+#TINY_MCE_MEDIA_ROOT = STATIC_ROOT + '/tiny_mce/' # not needed while TinyMCE not installed
+#TINY_MCE_MEDIA_URL = STATIC_URL + '/tiny_mce/' # not needed while TinyMCE not installed
+
+# Sanitise these to be strings as Django seems to be particularly sensitive to crashing if they aren't
+STATIC_URL = str(STATIC_URL) + "/"
+MEDIA_URL = str(MEDIA_URL) + "/"
+
diff --git a/_deploy/wsl/os-trog24.04.sh b/_deploy/wsl/os-trog24.04.sh
index f3d1185..f3d1185 100755..100644
--- a/_deploy/wsl/os-trog24.04.sh
+++ b/_deploy/wsl/os-trog24.04.sh
diff --git a/_deploy/wsl/using-pip/requirements-keep.txt b/_deploy/wsl/using-pip/requirements-keep.txt
index a497cf9..a497cf9 100755..100644
--- a/_deploy/wsl/using-pip/requirements-keep.txt
+++ b/_deploy/wsl/using-pip/requirements-keep.txt
diff --git a/_deploy/wsl/using-pip/requirements-p9d4.txt b/_deploy/wsl/using-pip/requirements-p9d4.txt
index 5e290b5..5e290b5 100755..100644
--- a/_deploy/wsl/using-pip/requirements-p9d4.txt
+++ b/_deploy/wsl/using-pip/requirements-p9d4.txt
diff --git a/localsettings.py b/localsettings.py
new file mode 100644
index 0000000..d997789
--- /dev/null
+++ b/localsettings.py
@@ -0,0 +1,187 @@
+import sys
+from pathlib import Path
+
+"""Settings for a troggle installation which may vary among different
+installations: for development or deployment, in a docker image or
+python virtual environment (venv), on ubuntu, debian or in Windows
+System for Linux (WSL), on the main server or in the potato hut,
+using SQLite or mariaDB.
+
+It sets the directory locations for the major parts of the system so
+that e.g. expofiles can be on a different filesystem, or /javascript/ can be in
+a system-wide location rather than just a local directory.
+
+This file is included at the end of the main troggle/settings.py file so that
+it overwrites defaults in that file.
+
+Read https://realpython.com/python-pathlib/
+Read https://adamj.eu/tech/2020/03/16/use-pathlib-in-your-django-project/
+"""
+
+print(" * importing troggle/localsettings.py")
+
+# -----------------------------------------------------------------
+# THINK before you push this to a repo
+# - have you checked that credentials.py is in .gitignore ?
+# - we don't want to have to change the expo system password !
+# -----------------------------------------------------------------
+# default values, real secrets will be imported from credentials.py in future
+
+
+
+SQLITEFILE = "/home/philip/expo/troggle.sqlite" # can be ':memory:'
+
+PHOTOSREMOTE = False # if True, then re-routes urls in expofiles/photos to remote server. Not implemented yet
+EXPOFILESREMOTE = False # if True, then re-routes urls in expofiles to remote server. Tests are then less accurate.
+# SECURE_SSL_REDIRECT = True # breaks 7 tests in test suite 301 not 200 (or 302) and runserver fails completely
+SERVERPORT = "8000" # not needed as it is the default
+
+ADMINS = (
+ ('Philip', 'philip.sargent@klebos.eu'),
+)
+
+PV = "python" + str(sys.version_info.major) + "." + str(sys.version_info.minor)
+
+# Troggle does a lot of file-handling. This is very error-prone when using primitive methods,
+# so we use pathlib which has been standard since python 3.4
+# If pathlib is new to you, you will need to read https://realpython.com/python-pathlib/
+
+# --------------------- MEDIA redirections BEGIN ---------------------
+REPOS_ROOT_PATH = Path(__file__).parent.parent
+LIBDIR = REPOS_ROOT_PATH / "lib" / PV
+
+TROGGLE_PATH = Path(__file__).parent
+TEMPLATE_PATH = TROGGLE_PATH / "templates"
+MEDIA_ROOT = TROGGLE_PATH / "media"
+JSLIB_ROOT = TROGGLE_PATH / "media" / "jslib" # used for CaveViewer JS utility
+
+# FILES = Path('/mnt/d/expofiles/')
+EXPOFILES = REPOS_ROOT_PATH / "expofiles"
+
+SCANS_ROOT = EXPOFILES / "surveyscans"
+PHOTOS_ROOT = EXPOFILES / "photos"
+PHOTOS_YEAR = "2023"
+NOTABLECAVESHREFS = ["290", "291", "264", "258", "204", "359", "76", "107"]
+
+
+PYTHON_PATH = REPOS_ROOT_PATH / "troggle"
+LOGFILE = PYTHON_PATH / "troggle.log"
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+MEDIA_URL = "/site-media/"
+
+DIR_ROOT = Path("") # this should end in / if a value is given
+URL_ROOT = "/"
+# URL_ROOT = 'http://localhost:'+ SERVERPORT +'/'
+
+# Note that these constants are not actually used in urls.py, they should be..
+# and they all need to end with / so using 'Path' doesn't work..
+MEDIA_URL = Path(URL_ROOT, "/site_media/")
+PHOTOS_URL = Path(URL_ROOT, "/photos/")
+
+
+STATIC_URL = Path(URL_ROOT, "/static/") # used by Django admin pages. Do not delete.
+JSLIB_URL = Path(URL_ROOT, "/javascript/") # used for CaveViewer JS utility
+
+# STATIC_ROOT removed after merging content into MEDIA_ROOT. See urls.py & core/views/surveys.py
+# --------------------- MEDIA redirections END ---------------------
+
+PUBLIC_SITE = True
+DEBUG = True # Always keep this True, even when on public server. Otherwise NO USEFUL ERROR MESSAGES !
+CACHEDPAGES = True # experimental page cache for a handful of page types
+
+# executables:
+CAVERN = "cavern" # for parsing .svx files and producing .3d files
+SURVEXPORT = "survexport" # for parsing .3d files and producing .pos files
+
+DBSQLITE = {
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3", # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ "NAME": SQLITEFILE,
+ # 'NAME' : ':memory:',
+ "USER": "expo", # Not used with sqlite3.
+ "PASSWORD": "sekrit", # Not used with sqlite3.
+ "HOST": "", # Set to empty string for localhost. Not used with sqlite3.
+ "PORT": "", # Set to empty string for default. Not used with sqlite3.
+ }
+}
+DBMARIADB = {
+ "default": {
+ "ENGINE": "django.db.backends.mysql", # 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ "OPTIONS": {
+ "charset": "utf8mb4",
+ },
+ "NAME": "troggle", # Or path to database file if using sqlite3.
+ "USER": "expo",
+ "PASSWORD": "my-secret-password-schwatzmooskogel",
+ "HOST": "", # Set to empty string for localhost. Not used with sqlite3.
+ "PORT": "", # Set to empty string for default. Not used with sqlite3.
+ }
+}
+
+# default database for me is squlite
+DBSWITCH = "sqlite"
+
+if DBSWITCH == "sqlite":
+ DATABASES = DBSQLITE
+if DBSWITCH == "mariadb":
+ DATABASES = DBMARIADB
+
+
+
+TEMPLATES = [
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [TEMPLATE_PATH],
+ "OPTIONS": {
+ "debug": "DEBUG",
+ "context_processors": [
+ # django.template.context_processors.csrf, # is always enabled and cannot be removed, sets csrf_token
+ "django.contrib.auth.context_processors.auth", # knowledge of logged-on user & permissions
+ "core.context.troggle_context", # in core/context.py - only used in expedition.html
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.media", # includes a variable MEDIA_URL
+ "django.template.context_processors.static", # includes a variable STATIC_URL used by admin pages
+ "django.template.context_processors.tz",
+ "django.template.context_processors.request", # must be enabled in DjangoTemplates (TEMPLATES) in order to use the admin navigation sidebar.
+ "django.contrib.messages.context_processors.messages",
+ ],
+ "loaders": [
+ "django.template.loaders.filesystem.Loader", # default lcation is troggle/templates/
+ "django.template.loaders.app_directories.Loader", # needed for admin 'app'
+ ],
+ },
+ },
+]
+
+EXPOUSER = "expo"
+EXPOUSER_EMAIL = "philip.sargent@gmail.com"
+EXPOADMINUSER = "expoadmin"
+EXPOADMINUSER_EMAIL = "philip.sargent@gmail.com"
+
+EMAIL_HOST = "smtp-auth.mythic-beasts.com"
+EMAIL_HOST_USER = "django-test@klebos.net" # Philip Sargent really
+EMAIL_PORT = 587
+EMAIL_USE_TLS = True
+DEFAULT_FROM_EMAIL = "django-test@klebos.net"
+
+SURVEX_DATA = REPOS_ROOT_PATH / "loser"
+DRAWINGS_DATA = REPOS_ROOT_PATH / "drawings"
+EXPOWEB = REPOS_ROOT_PATH / "expoweb"
+CAVEDESCRIPTIONS = EXPOWEB / "cave_data"
+ENTRANCEDESCRIPTIONS = EXPOWEB / "entrance_data"
+
+# EXPOWEB_URL = "" # defunct, removed.
+# SCANS_URL = '/survey_scans/' # defunct, removed.
+
+sys.path.append(str(REPOS_ROOT_PATH))
+sys.path.append(str(PYTHON_PATH))
+#TINY_MCE_MEDIA_ROOT = STATIC_ROOT + '/tiny_mce/' # not needed while TinyMCE not installed
+#TINY_MCE_MEDIA_URL = STATIC_URL + '/tiny_mce/' # not needed while TinyMCE not installed
+
+# Sanitise these to be strings as Django seems to be particularly sensitive to crashing if they aren't
+STATIC_URL = str(STATIC_URL) + "/"
+MEDIA_URL = str(MEDIA_URL) + "/"
+
diff --git a/pre-push.sh b/pre-push.sh
index fe6fb0b..fe6fb0b 100755..100644
--- a/pre-push.sh
+++ b/pre-push.sh
diff --git a/pre-run.sh b/pre-run.sh
index ab13800..ab13800 100755..100644
--- a/pre-run.sh
+++ b/pre-run.sh