summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/models/caves.py15
-rw-r--r--core/utils.py49
-rw-r--r--core/views/uploads.py59
-rw-r--r--templates/textfileform.html2
4 files changed, 104 insertions, 21 deletions
diff --git a/core/models/caves.py b/core/models/caves.py
index c9405ee..4cf0512 100644
--- a/core/models/caves.py
+++ b/core/models/caves.py
@@ -12,7 +12,7 @@ import settings
from troggle.core.models.logbooks import QM
from troggle.core.models.survex import SurvexStation, utmToLatLng
from troggle.core.models.troggle import DataIssue, TroggleModel
-from troggle.core.utils import TROG, writetrogglefile
+from troggle.core.utils import TROG, writetrogglefile, parse_aliases
# Use the TROG global object to cache the cave lookup list. No good for multi-user.., or even multi-page. Pointless in fact.
Gcavelookup = TROG["caves"]["gcavelookup"]
@@ -532,10 +532,19 @@ def GetCaveLookup():
print(cave, cave.slug())
# These might alse create more duplicate entries
- # Yes, this should be set in, and imported from, an easily editable file
+ aliases = []
+ # read the two files in /cave_data/
+ for ca in ["cavealiasesold.txt", "cavealiases.txt"]:
+ pairs, report = parse_aliases(ca)
+ aliases += pairs
+
+ # print(f"Loaded aliases, {len(aliases)} found\n{report}\n {aliases}")
+
# On reset, these aliases only work if the cave already properly exists with an entry in :expoweb:/cave_data/
# but as the aliases are recomputed repeatedly, eventually they work on PENDING caves too
- aliases = [
+
+ # oldaliases are NOT USED. We are reading from the files instead now. Pending deletion..
+ oldaliases = [
("1987-02", "1623-267"),
("1990-01", "1623-171"),
("1990-02", "1623-172"),
diff --git a/core/utils.py b/core/utils.py
index 6670a65..40483e3 100644
--- a/core/utils.py
+++ b/core/utils.py
@@ -2,6 +2,7 @@ import hashlib
import logging
import math
import os
+import re
import random
import resource
import string
@@ -43,6 +44,8 @@ sha = hashlib.new('sha256')
throw = 35.0
+
+
# This is module-level executable. This is a Bad Thing. Especially when it touches the file system.
try:
logging.basicConfig(level=logging.DEBUG, filename=settings.LOGFILE, filemode="w")
@@ -131,6 +134,52 @@ def current_expo():
else:
return settings.EPOCH.year # this is 1970
+def parse_aliases(aliasfile):
+ """Reads a long text string containing pairs of strings:
+ (alias, target)
+ where the alias is an old name for a cave and the target is the current, valid name for the cave, e.g.
+ ("2015-mf-06", "1623-288"),
+ returns a list of tuple pairs
+
+ May fail if there is more than one space after the comma separating strings
+ """
+
+ report = [] # Messages about failed lines
+ aliases = []
+
+ filepath = Path(settings.EXPOWEB) / "cave_data" / aliasfile
+ if not filepath.is_file():
+ message = f' ** {filepath} is not a file.'
+ print(message)
+ return [(None, None)]
+ try:
+ with open(filepath, "r") as aliasfile:
+ for line in aliasfile:
+ l, sep, tail = line.partition('#')
+ l, sep, tail = l.partition(';')
+ l = l.strip().strip(',') # remove terminal comma if present
+ l = l.strip().strip('()')
+ l = l.replace("\"","")
+ l = l.replace("\'","")
+ l = l.replace(" ","") # removes all spaces
+ l = " ".join(l.split(',')) # subtle, splits on comma, joins with one space
+ if len(l) == 0:
+ # print(f"no parseable content: {line}")
+ continue
+ key, sep, target = l.partition(' ')
+ if len(key) == 0 or len(target) == 0:
+ message = f' ** Parsing failure for {line}'
+ print(message)
+ continue
+
+ print(f"{key} => {target}")
+ aliases.append((key,target))
+ except:
+ message = f' ** Cannot open {filepath} for text file reading even though it is a file.'
+ print(message)
+ return [(None, None)], "Fail on file reading"
+ return aliases, report
+
def only_commit(fname, message):
"""Only used to commit a survex file edited and saved in view/survex.py"""
git = settings.GIT
diff --git a/core/views/uploads.py b/core/views/uploads.py
index 6ebec8c..3d4e987 100644
--- a/core/views/uploads.py
+++ b/core/views/uploads.py
@@ -12,7 +12,7 @@ from troggle.core.models.caves import GetCaveLookup
from troggle.core.models.logbooks import LogbookEntry, writelogbook, PersonLogEntry
from troggle.core.models.survex import DrawingFile
from troggle.core.models.troggle import DataIssue, Expedition, PersonExpedition
-from troggle.core.utils import alphabet_suffix, current_expo, sanitize_name, unique_slug
+from troggle.core.utils import alphabet_suffix, current_expo, sanitize_name, unique_slug, write_and_commit
from troggle.parsers.people import GetPersonExpeditionNameLookup, known_foreigner
# from databaseReset import reinit_db # don't do this. databaseRest runs code *at import time*
@@ -152,11 +152,11 @@ class ExpotextfileForm(forms.Form): # not a model-form, just a form-form
class LogbookEditForm(forms.Form): # not a model-form, just a form-form
author = forms.CharField(strip=True, required=False)
+@login_required_if_public
def edittxtpage(request, path, filepath):
"""Editing a .txt file on expoweb/
"""
- message=""
- def simple_get():
+ def simple_get(viewtext):
form = ExpotextfileForm()
return render(
request,
@@ -166,23 +166,26 @@ def edittxtpage(request, path, filepath):
"path": path,
"message": message,
"filepath": filepath,
- "text": text,
+ "text": viewtext,
},
)
+ message=""
+
if not filepath.is_file():
print(f"Not a file: {filepath}")
errpage = f"<html>" + default_head + f"<h3>File not found '{filepath}'<br><br>failure detected in expowebpage() in views.expo.py</h3> </body>"
return HttpResponse(errpage)
try:
- with open(filepath) as f:
- text = f.read()
+ with open(filepath, "r") as f:
+ originaltext = f.read()
except IOError:
- print("### File reading failue, but it exists.. ### ", filepath)
- filefound = False
+ message = f'Cannot open {filepath} for text file reading even though it is a file.'
+ print(message)
+ return render(request, "errors/generic.html", {"message": message})
if request.method == "GET":
- return simple_get()
+ return simple_get(originaltext)
elif request.method == "POST":
form = ExpotextfileForm(request.POST)
@@ -191,22 +194,44 @@ def edittxtpage(request, path, filepath):
print(message)
return render(request, "errors/generic.html", {"message": message})
else:
- for i in request.POST:
- print(":: ",i, " => ", request.POST[i])
+ # for i in request.POST:
+ # print(":: ",i, " => ", request.POST[i])
+ newtext = request.POST["text"]
print("POST")
if "Cancel" in request.POST:
print("cancel")
- return simple_get()
+ return simple_get(originaltext)
if "Save" in request.POST:
print("submitted for saving..")
- message="submitted for saving.. not implemented yet.."
- # INSERT FILE SAVING AND git committing on server
- return simple_get()
- # mistake, abort
+ if newtext != originaltext: # Check if content has changed at all
+ print("text changed.. saving and committing")
+ try:
+ write_and_commit([(filepath, newtext, "utf-8")], f"Online edit of {path}")
+ except WriteAndCommitError as e:
+ return render(request, "errors/generic.html", {"message": e.message})
+
+ print("re-reading from file..")
+ try:
+ with open(filepath) as f:
+ rereadtext = f.read()
+ except:
+ print("### File reading failure, but it exists.. ### ", filepath)
+ return render(request, "errors/generic.html", {"message": e.message})
+ savepath = "/" + path
+ print(f"redirect {savepath}")
+ return redirect(savepath) # Redirect after POST
+
+ else:
+ # no changes
+ pass
+ return simple_get(originaltext)
+ else:
+ # mistake not POST or GET
message="Something went wrong"
- return simple_get()
+ print(message)
+ return simple_get(originaltext)
@login_required_if_public
diff --git a/templates/textfileform.html b/templates/textfileform.html
index 2110598..0fbd753 100644
--- a/templates/textfileform.html
+++ b/templates/textfileform.html
@@ -23,7 +23,7 @@ Full path on server: {{filepath}}
<textarea {% if not user.username %} disabled{% endif %}
rows="{% if textrows%}{{textrows}}{% else %}20{% endif %}" cols="100"
label = "" name = "text"
- required />{% if text %}{{text}}{% else %}We had a lot of fun...{% endif %}
+ required />{% if text %}{{text}}{% else %}Placeholder text{% endif %}
</textarea>
<br>
[Edit the text by just typing in the box.]