mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-16 22:57:14 +00:00
Split out logbook_edit.py and ruff fix
This commit is contained in:
@@ -54,6 +54,7 @@ class SimpleTest(SimpleTestCase):
|
|||||||
from troggle.parsers.people import GetPersonExpeditionNameLookup
|
from troggle.parsers.people import GetPersonExpeditionNameLookup
|
||||||
|
|
||||||
def test_import_views_uploads(self):
|
def test_import_views_uploads(self):
|
||||||
|
from troggle.core.views.logbook_edit import logbookedit
|
||||||
from troggle.core.views.uploads import dwgupload
|
from troggle.core.views.uploads import dwgupload
|
||||||
|
|
||||||
def test_import_views_walletedit(self):
|
def test_import_views_walletedit(self):
|
||||||
|
|||||||
@@ -20,7 +20,14 @@ from troggle.core.forms import CaveForm, EntranceForm, EntranceLetterForm # Cav
|
|||||||
from troggle.core.models.caves import Cave, CaveAndEntrance, Entrance, GetCaveLookup, get_cave_leniently
|
from troggle.core.models.caves import Cave, CaveAndEntrance, Entrance, GetCaveLookup, get_cave_leniently
|
||||||
from troggle.core.models.logbooks import QM
|
from troggle.core.models.logbooks import QM
|
||||||
from troggle.core.models.wallets import Wallet
|
from troggle.core.models.wallets import Wallet
|
||||||
from troggle.core.utils import COOKIE_MAX_AGE, WriteAndCommitError, current_expo, get_cookie, git_string, write_and_commit
|
from troggle.core.utils import (
|
||||||
|
COOKIE_MAX_AGE,
|
||||||
|
WriteAndCommitError,
|
||||||
|
current_expo,
|
||||||
|
get_cookie,
|
||||||
|
git_string,
|
||||||
|
write_and_commit,
|
||||||
|
)
|
||||||
from troggle.core.views import expo
|
from troggle.core.views import expo
|
||||||
from troggle.parsers.caves import read_cave, read_entrance
|
from troggle.parsers.caves import read_cave, read_entrance
|
||||||
from troggle.settings import CAVEDESCRIPTIONS, ENTRANCEDESCRIPTIONS
|
from troggle.settings import CAVEDESCRIPTIONS, ENTRANCEDESCRIPTIONS
|
||||||
|
|||||||
@@ -14,7 +14,14 @@ from django.views.decorators.csrf import ensure_csrf_cookie
|
|||||||
import troggle.core.views.caves
|
import troggle.core.views.caves
|
||||||
import troggle.settings as settings
|
import troggle.settings as settings
|
||||||
from troggle.core.models.caves import Cave
|
from troggle.core.models.caves import Cave
|
||||||
from troggle.core.utils import COOKIE_MAX_AGE, WriteAndCommitError, current_expo, get_cookie, git_string, write_and_commit
|
from troggle.core.utils import (
|
||||||
|
COOKIE_MAX_AGE,
|
||||||
|
WriteAndCommitError,
|
||||||
|
current_expo,
|
||||||
|
get_cookie,
|
||||||
|
git_string,
|
||||||
|
write_and_commit,
|
||||||
|
)
|
||||||
from troggle.core.views.editor_helpers import HTMLarea
|
from troggle.core.views.editor_helpers import HTMLarea
|
||||||
from troggle.core.views.uploads import edittxtpage
|
from troggle.core.views.uploads import edittxtpage
|
||||||
|
|
||||||
|
|||||||
451
core/views/logbook_edit.py
Normal file
451
core/views/logbook_edit.py
Normal file
@@ -0,0 +1,451 @@
|
|||||||
|
import subprocess
|
||||||
|
from datetime import datetime, timedelta, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
from django.core.files.storage import FileSystemStorage
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import redirect, render
|
||||||
|
|
||||||
|
import settings
|
||||||
|
from troggle.core.models.caves import GetCaveLookup
|
||||||
|
from troggle.core.models.logbooks import LogbookEntry, PersonLogEntry, writelogbook
|
||||||
|
from troggle.core.models.survex import DrawingFile
|
||||||
|
from troggle.core.models.troggle import DataIssue, Expedition, PersonExpedition
|
||||||
|
from troggle.core.utils import (
|
||||||
|
COOKIE_MAX_AGE,
|
||||||
|
alphabet_suffix,
|
||||||
|
current_expo,
|
||||||
|
get_cookie,
|
||||||
|
git_string,
|
||||||
|
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*
|
||||||
|
from .auth import login_required_if_public
|
||||||
|
|
||||||
|
"""Logbook edit 'view'
|
||||||
|
Note that there are other file upload forms in views/wallet_edit.py views/uploads.py
|
||||||
|
and that core/forms.py contains Django class-based forms for caves and entrances.
|
||||||
|
"""
|
||||||
|
|
||||||
|
todo = """ - refactor git to use utils.py functions
|
||||||
|
"""
|
||||||
|
|
||||||
|
def create_new_lbe_slug(date):
|
||||||
|
onthisdate = LogbookEntry.objects.filter(date=date)
|
||||||
|
n = len(onthisdate)
|
||||||
|
print(f" Already entries on this date: {n}\n {onthisdate}")
|
||||||
|
|
||||||
|
suffix = alphabet_suffix(n+1)
|
||||||
|
|
||||||
|
tid = f"{date}{suffix}"
|
||||||
|
if len(tid) <=4 :
|
||||||
|
print(f"BAD ERROR {tid=}")
|
||||||
|
tid = f"{date}_{LogbookEntry.objects.count()}_{n}" # fudged number
|
||||||
|
print(f"{tid=}")
|
||||||
|
return tid
|
||||||
|
|
||||||
|
def store_edited_entry_into_database(date, place, title, text, others, author, tu, slug):
|
||||||
|
"""saves a single logbook entry and related personlogentry items
|
||||||
|
|
||||||
|
need to select out *guest and foreign friends from others
|
||||||
|
|
||||||
|
Rather similar to similarly named function in parsers/logbooks but circular reference prevents us using it directly,
|
||||||
|
and they need refactoring anyway.
|
||||||
|
"""
|
||||||
|
|
||||||
|
year = slug[0:4]
|
||||||
|
expedition = Expedition.objects.get(year=year)
|
||||||
|
cave = GetCaveLookup().get(place.lower())
|
||||||
|
# print(f"store_edited_entry_into_database(): {place=} {cave=}")
|
||||||
|
|
||||||
|
if LogbookEntry.objects.filter(slug=slug).exists():
|
||||||
|
# oops.
|
||||||
|
message = f" ! - DUPLICATE SLUG for logbook entry {date} - {slug}"
|
||||||
|
DataIssue.objects.create(parser="logbooks", message=message)
|
||||||
|
slug = slug + "_" + unique_slug(text,2)
|
||||||
|
|
||||||
|
otherAttribs = {
|
||||||
|
"place": place,
|
||||||
|
"text": text,
|
||||||
|
"expedition": expedition,
|
||||||
|
"time_underground": tu,
|
||||||
|
"cave": cave,
|
||||||
|
"title": f"{place} - {title}",
|
||||||
|
# "other_people": others
|
||||||
|
}
|
||||||
|
coUniqueAttribs = {"slug": slug, "date": date }
|
||||||
|
|
||||||
|
lbo = LogbookEntry.objects.create(**otherAttribs, **coUniqueAttribs)
|
||||||
|
|
||||||
|
pt_list = []
|
||||||
|
# These entities have to be PersonExpedition objects
|
||||||
|
team = others.split(",")
|
||||||
|
team.append(author)
|
||||||
|
|
||||||
|
odds = []
|
||||||
|
for name in team:
|
||||||
|
name = name.strip()
|
||||||
|
if len(name) > 0:
|
||||||
|
if name[0] == "*": # a name prefix of "*" is special, just a string.
|
||||||
|
odds.append(name)
|
||||||
|
print(f" - adding * special name '{name}'")
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
personyear = GetPersonExpeditionNameLookup(expedition).get(name.lower())
|
||||||
|
if not personyear:
|
||||||
|
odds.append(name)
|
||||||
|
print(f" - adding unrecognised expoer '{name}'")
|
||||||
|
if known_foreigner(name):
|
||||||
|
message = f" ! - Known foreigner: '{name}' in entry {slug=}"
|
||||||
|
print(message)
|
||||||
|
else:
|
||||||
|
message = f" ! - No name match for: '{name}' in entry {slug=}"
|
||||||
|
print(message)
|
||||||
|
DataIssue.objects.create(parser="logbooks", message=message)
|
||||||
|
else:
|
||||||
|
coUniqueAttribs = {"personexpedition": personyear, "nickname_used": name, "logbook_entry": lbo} # lbo is primary key
|
||||||
|
otherAttribs = {"time_underground": tu, "is_logbook_entry_author": (name==author)}
|
||||||
|
pt_list.append(PersonLogEntry(**otherAttribs, **coUniqueAttribs))
|
||||||
|
|
||||||
|
except:
|
||||||
|
# This should not happen. We do not raise exceptions in that function
|
||||||
|
message = f" ! - EXCEPTION: '{name}' in entry {slug=}"
|
||||||
|
print(message)
|
||||||
|
DataIssue.objects.create(parser="logbooks", message=message)
|
||||||
|
raise
|
||||||
|
|
||||||
|
PersonLogEntry.objects.bulk_create(pt_list)
|
||||||
|
|
||||||
|
lbo.other_people = ", ".join(odds)
|
||||||
|
print(f" - Saving other_people '{lbo.other_people}'")
|
||||||
|
lbo.save()
|
||||||
|
|
||||||
|
|
||||||
|
@login_required_if_public
|
||||||
|
def logbookedit(request, year=None, slug=None):
|
||||||
|
"""Edit a logbook entry
|
||||||
|
|
||||||
|
This 'validates' the author as being on expo in the current year, but only indicates this by
|
||||||
|
putting the text of the form prompt in red (same as for an invalid date, which is arguably more important).
|
||||||
|
No check is done on the other people on the trip as this is picked up anyway by parsing on import
|
||||||
|
and we don't really care at this point.
|
||||||
|
"""
|
||||||
|
def yesterday():
|
||||||
|
yesterday = datetime.now() - timedelta(1)
|
||||||
|
return yesterday.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
def validate_year(year):
|
||||||
|
try:
|
||||||
|
expo = Expedition.objects.get(year=year)
|
||||||
|
except:
|
||||||
|
year = current_expo() # creates new Expedition object if needed
|
||||||
|
return year
|
||||||
|
|
||||||
|
def new_entry_form():
|
||||||
|
# set the date to be "yesterday" as this will, hopefully, usually be the case
|
||||||
|
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"logbookform.html",
|
||||||
|
{
|
||||||
|
"form": form,
|
||||||
|
"year": year,
|
||||||
|
"yesterday": yesterday(),
|
||||||
|
|
||||||
|
},
|
||||||
|
)
|
||||||
|
def clean_tu(tu):
|
||||||
|
if tu =="":
|
||||||
|
return 0
|
||||||
|
try:
|
||||||
|
tu = float(tu)/1 # check numeric
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
return tu
|
||||||
|
|
||||||
|
if not year:
|
||||||
|
if not slug: # not in the URL, we have not read teh POST response yet.. wich might have a slug in it
|
||||||
|
year = current_expo()
|
||||||
|
else:
|
||||||
|
year = slug[0:4]
|
||||||
|
try:
|
||||||
|
year = str(int(year)) # but maybe slug was hand-edited to be a future year..
|
||||||
|
year = validate_year(year) # so fix that
|
||||||
|
except:
|
||||||
|
year = current_expo()
|
||||||
|
|
||||||
|
author = ""
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
prev_slug = "" # None value pending overwrite from submitted form
|
||||||
|
form = LogbookEditForm(request.POST)
|
||||||
|
if not form.is_valid():
|
||||||
|
message = f'Invalid form response for logbook entry creating "{request.POST}"'
|
||||||
|
print(message)
|
||||||
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
|
else:
|
||||||
|
# if there is no slug then this is probably a completely new lbe and we need to enter it into the db
|
||||||
|
# otherwise it is an update
|
||||||
|
# validation all to be done yet..
|
||||||
|
date = request.POST["date"].strip()
|
||||||
|
author = request.POST["author"].strip() # TODO check against personexpedition on submit
|
||||||
|
others = request.POST["others"].strip() # TODO check each against personexpedition on submit
|
||||||
|
place = request.POST["place"].strip().replace(' - ',' = ') # no hyphens !
|
||||||
|
title = request.POST["title"].strip()
|
||||||
|
entry = request.POST["text"].strip()
|
||||||
|
if "prev_slug" in request.POST:
|
||||||
|
prev_slug = request.POST["prev_slug"].strip() # if we are re-editing the same entry again
|
||||||
|
entry = entry.replace('\r','') # remove HTML-standard CR inserted from form.
|
||||||
|
entry = entry.replace('\n\n','\n<p>\n') # replace 2 \n with <p>
|
||||||
|
tu = request.POST["tu"].strip()
|
||||||
|
tu = clean_tu(tu)
|
||||||
|
|
||||||
|
try:
|
||||||
|
odate = datetime.strptime(date.replace(".", "-"), "%Y-%m-%d").date()
|
||||||
|
print(f"{odate.year=}")
|
||||||
|
if str(odate.year) == year:
|
||||||
|
dateflag = False
|
||||||
|
else:
|
||||||
|
print(f"Trying to change the year ! No!! {odate.year=}")
|
||||||
|
odate = datetime.strptime(f"{year}-01-01", "%Y-%m-%d").date()
|
||||||
|
dateflag = True
|
||||||
|
except:
|
||||||
|
odate = datetime.strptime(f"{year}-01-01", "%Y-%m-%d").date()
|
||||||
|
print(f"! Invalid date string {date}, setting to {odate}")
|
||||||
|
dateflag = True
|
||||||
|
date = odate.isoformat()
|
||||||
|
|
||||||
|
year = validate_year(year)
|
||||||
|
expo = Expedition.objects.get(year=year)
|
||||||
|
personyear = GetPersonExpeditionNameLookup(expo).get(author.lower())
|
||||||
|
if personyear:
|
||||||
|
authorflag = False
|
||||||
|
else:
|
||||||
|
authorflag = True
|
||||||
|
print(f"! Unrecognised author: {author}")
|
||||||
|
|
||||||
|
# if somehow we get a slug set to just '2024', not eg '2020-08-10b'
|
||||||
|
# because the URL of the page is /logbookedit/2022 for a new entry
|
||||||
|
# This is a hack, why can we not reproduce this bug on the dev system?
|
||||||
|
if slug not in locals():
|
||||||
|
slug = ""
|
||||||
|
if len(slug) < 11:
|
||||||
|
slug = ""
|
||||||
|
if len(prev_slug) < 11:
|
||||||
|
prev_slug = ""
|
||||||
|
|
||||||
|
if not prev_slug and not slug:
|
||||||
|
# Creating a new logbook entry with all the gubbins
|
||||||
|
slug = create_new_lbe_slug(date)
|
||||||
|
|
||||||
|
if prev_slug and not slug:
|
||||||
|
# if this was a previous post, then prev_slug will have been set on the form
|
||||||
|
# we are editing a previous thing, so we don't create a new lbe
|
||||||
|
slug = prev_slug
|
||||||
|
|
||||||
|
# OK we could patch the object in place, but if the people on the trip have changed this
|
||||||
|
# would get very messy. So we delete it, and thus all the dependent objects,
|
||||||
|
# and recreate it and all its links. It might not exist though.
|
||||||
|
print(f"- Deleting the LogBookEntry {slug}")
|
||||||
|
LogbookEntry.objects.filter(slug=slug).delete() # works even if it does not exist
|
||||||
|
|
||||||
|
print(f"- Creating the LogBookEntry {slug}")
|
||||||
|
year = slug[0:4]
|
||||||
|
try:
|
||||||
|
expedition = Expedition.objects.get(year=year)
|
||||||
|
except Expedition.DoesNotExist:
|
||||||
|
message = f'''! - This expo "{year}" not created yet
|
||||||
|
It needs to be created before you can save a logbook entry.
|
||||||
|
See /handbook/computing/newyear.html
|
||||||
|
|
||||||
|
WHAT TO DO NOW:
|
||||||
|
1. Press the Back button on your proswer to return to the screen where you typed up the entry,
|
||||||
|
2. Copy the text of what you wrote into a new text file,
|
||||||
|
3. Direct a nerd to fix this. It should take only a couple of minutes.'''
|
||||||
|
print(message)
|
||||||
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
|
store_edited_entry_into_database(date, place, title, entry, others, author, tu, slug)
|
||||||
|
|
||||||
|
|
||||||
|
print(f"- Rewriting the entire {year} logbook to disc ")
|
||||||
|
filename= "logbook.html"
|
||||||
|
try:
|
||||||
|
print(f" - Logbook for {year} to be exported and written out.")
|
||||||
|
writelogbook(year, filename) # uses a template, not the code fragment below which is just a visible hint to logged on user
|
||||||
|
except:
|
||||||
|
message = f'! - Logbook saving failed - \n!! Permissions failure ?! on attempting to save file "logbook.html"'
|
||||||
|
print(message)
|
||||||
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
|
|
||||||
|
# Code fragment illustration - not actually what gets saved to database
|
||||||
|
output = f'''
|
||||||
|
|
||||||
|
<div class="tripdate" id="{slug}">{date}</div>
|
||||||
|
<div class="trippeople"><u>{author}</u>, {others}</div>
|
||||||
|
<div class="triptitle">{place} - {title}</div>
|
||||||
|
|
||||||
|
{entry}
|
||||||
|
|
||||||
|
<div class="timeug">T/U {tu} hrs</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Successful POST
|
||||||
|
# So save to database and then write out whole new logbook.html file
|
||||||
|
|
||||||
|
# We do author validation on the form as displayed by GET, not at the moment of POST.
|
||||||
|
# If we had JS validation then we could be more timely.
|
||||||
|
git = settings.GIT
|
||||||
|
dirpath = Path(settings.EXPOWEB) / "years" / str(year)
|
||||||
|
lbe_add = subprocess.run(
|
||||||
|
[git, "add", filename], cwd=dirpath, capture_output=True, text=True
|
||||||
|
)
|
||||||
|
msgdata = (
|
||||||
|
lbe_add.stderr
|
||||||
|
+ "\n"
|
||||||
|
+ lbe_add.stdout
|
||||||
|
+ "\nreturn code: "
|
||||||
|
+ str(lbe_add.returncode)
|
||||||
|
)
|
||||||
|
message = f'! - FORM Logbook Edit {slug} - Success: git ADD on server for this file {filename}.' + msgdata
|
||||||
|
print(message)
|
||||||
|
if lbe_add.returncode != 0:
|
||||||
|
msgdata = (
|
||||||
|
"Ask a nerd to fix this.\n\n"
|
||||||
|
+ lbe_add.stderr
|
||||||
|
+ "\n\n"
|
||||||
|
+ lbe_add.stdout
|
||||||
|
+ "\n\nreturn code: "
|
||||||
|
+ str(lbe_add.returncode)
|
||||||
|
)
|
||||||
|
message = (
|
||||||
|
f"! - FORM Logbook Edit - CANNOT git ADD on server for this file {filename}. {slug} edits saved but not added to git.\n"
|
||||||
|
+ msgdata
|
||||||
|
)
|
||||||
|
print(message)
|
||||||
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
|
|
||||||
|
lbe_commit = subprocess.run(
|
||||||
|
[git, "commit", "-m", f"Logbook edited {slug}"],
|
||||||
|
cwd=dirpath,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
message = f'! - FORM Logbook Edit - {filename}. {slug} edits saved, added to git, and COMMITTED.\n' + msgdata
|
||||||
|
print(message)
|
||||||
|
#This produces return code = 1 if it commits OK
|
||||||
|
if lbe_commit.returncode != 0:
|
||||||
|
msgdata = (
|
||||||
|
"Ask a nerd to fix this.\n\n"
|
||||||
|
+ lbe_commit.stderr
|
||||||
|
+ "\n"
|
||||||
|
+ lbe_commit.stdout
|
||||||
|
+ "\nreturn code: "
|
||||||
|
+ str(lbe_commit.returncode)
|
||||||
|
)
|
||||||
|
message = (
|
||||||
|
f"! - FORM Logbook Edit - Error code '{lbe_commit.returncode}' with git on server for {filename}. {slug} edits saved, added to git, but NOT committed.\n"
|
||||||
|
+ msgdata
|
||||||
|
)
|
||||||
|
print(message)
|
||||||
|
if not (lbe_commit.returncode ==1 and settings.DEVSERVER):
|
||||||
|
# rc=1 is OK on the development server
|
||||||
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
|
|
||||||
|
# This does not change the URL in the browser, so despite a new slug being created,
|
||||||
|
# the next time this code is run it thinks a new slug needs to be created. So we should
|
||||||
|
# actually redirect to a new URL (an edit not a create) not simply return a render object.
|
||||||
|
# logbookedit/2022-08-21a
|
||||||
|
|
||||||
|
# HOWEVER by doing a redirect rather than returning a rendered page, we lose all the
|
||||||
|
# error settings e.g dateflag and authroflag so the user gets no feedback about bad data entered.
|
||||||
|
# so we need to pass the flags explicitly int he url and then extract them from the request in the GET bit. sigh.
|
||||||
|
return HttpResponseRedirect(f"/logbookedit/{slug}?dateflag={dateflag}&authorflag={authorflag}")
|
||||||
|
|
||||||
|
# return render(
|
||||||
|
# request,
|
||||||
|
# "logbookform.html",
|
||||||
|
# {
|
||||||
|
# "form": form,
|
||||||
|
# "year": year,
|
||||||
|
# "date": date, "dateflag": dateflag,
|
||||||
|
# "author": author, "authorflag": authorflag,
|
||||||
|
# "others": others,
|
||||||
|
# "place": place,
|
||||||
|
# "title": title,
|
||||||
|
# "tu": tu,
|
||||||
|
# "entry": entry,
|
||||||
|
# "output": output,
|
||||||
|
# "slug": slug,
|
||||||
|
# },
|
||||||
|
# )
|
||||||
|
# GET here
|
||||||
|
else:
|
||||||
|
form = LogbookEditForm()
|
||||||
|
year = validate_year(year)
|
||||||
|
|
||||||
|
if request.GET.get('dateflag', 'False') == "True":
|
||||||
|
dateflag = True
|
||||||
|
else:
|
||||||
|
dateflag = False
|
||||||
|
|
||||||
|
if request.GET.get('authorflag', 'False') == "True":
|
||||||
|
authorflag = True
|
||||||
|
else:
|
||||||
|
authorflag = False
|
||||||
|
|
||||||
|
if not slug: # no slug or bad slug for an lbe which does not exist
|
||||||
|
return new_entry_form()
|
||||||
|
else:
|
||||||
|
lbes = LogbookEntry.objects.filter(slug=slug)
|
||||||
|
if not lbes:
|
||||||
|
return new_entry_form()
|
||||||
|
else:
|
||||||
|
if len(lbes) > 1:
|
||||||
|
return render(request, "object_list.html", {"object_list": lbes}) # ie a bug
|
||||||
|
else:
|
||||||
|
lbe = lbes[0]
|
||||||
|
print(f"{lbe}")
|
||||||
|
tu = clean_tu(lbe.time_underground)
|
||||||
|
|
||||||
|
people = []
|
||||||
|
for p in lbe.personlogentry_set.filter(logbook_entry=lbe): # p is a PersonLogEntry object
|
||||||
|
if p.is_logbook_entry_author:
|
||||||
|
# author = p.personexpedition.person.fullname
|
||||||
|
author = p.nickname_used
|
||||||
|
else:
|
||||||
|
# people.append(p.personexpedition.person.fullname)
|
||||||
|
people.append(p.nickname_used)
|
||||||
|
others =', '.join(people)
|
||||||
|
if lbe.other_people:
|
||||||
|
others = others + ", " + lbe.other_people
|
||||||
|
lenothers = min(70,max(20, len(others)))
|
||||||
|
|
||||||
|
text = lbe.text
|
||||||
|
rows = max(5,len(text)/50)
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"logbookform.html",
|
||||||
|
{
|
||||||
|
"form": form,
|
||||||
|
"year": year,
|
||||||
|
"date": lbe.date.isoformat(), "dateflag": dateflag,
|
||||||
|
"author": author, "authorflag": authorflag,
|
||||||
|
"others": others,
|
||||||
|
"lenothers": lenothers,
|
||||||
|
"place": lbe.place,
|
||||||
|
"title": lbe.title.replace(f"{lbe.place} - ",""),
|
||||||
|
"tu": tu,
|
||||||
|
"entry": text,
|
||||||
|
"textrows": rows,
|
||||||
|
"slug": slug,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
class LogbookEditForm(forms.Form): # not a model-form, just a form-form
|
||||||
|
author = forms.CharField(strip=True, required=False)
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.views.generic.list import ListView
|
from django.views.generic.list import ListView
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
|
|
||||||
import troggle.settings as settings
|
import troggle.settings as settings
|
||||||
from troggle.core.models.logbooks import QM, LogbookEntry, PersonLogEntry, writelogbook
|
from troggle.core.models.logbooks import QM, LogbookEntry, PersonLogEntry, writelogbook
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from troggle.core.models.caves import Cave, GetCaveLookup
|
|||||||
from troggle.core.models.logbooks import LogbookEntry
|
from troggle.core.models.logbooks import LogbookEntry
|
||||||
from troggle.core.models.survex import SurvexBlock, SurvexFile #, SurvexDirectory
|
from troggle.core.models.survex import SurvexBlock, SurvexFile #, SurvexDirectory
|
||||||
from troggle.core.models.wallets import Wallet
|
from troggle.core.models.wallets import Wallet
|
||||||
from troggle.core.utils import COOKIE_MAX_AGE, current_expo, get_cookie, git_string, add_commit
|
from troggle.core.utils import COOKIE_MAX_AGE, add_commit, current_expo, get_cookie, git_string
|
||||||
from troggle.parsers.survex import parse_one_file
|
from troggle.parsers.survex import parse_one_file
|
||||||
|
|
||||||
"""Everything that views survexfiles
|
"""Everything that views survexfiles
|
||||||
|
|||||||
@@ -9,10 +9,18 @@ from django.shortcuts import redirect, render
|
|||||||
|
|
||||||
import settings
|
import settings
|
||||||
from troggle.core.models.caves import GetCaveLookup
|
from troggle.core.models.caves import GetCaveLookup
|
||||||
from troggle.core.models.logbooks import LogbookEntry, PersonLogEntry, writelogbook
|
|
||||||
from troggle.core.models.survex import DrawingFile
|
from troggle.core.models.survex import DrawingFile
|
||||||
from troggle.core.models.troggle import DataIssue, Expedition, PersonExpedition
|
from troggle.core.models.troggle import DataIssue, Expedition, PersonExpedition
|
||||||
from troggle.core.utils import COOKIE_MAX_AGE, alphabet_suffix, current_expo, get_cookie, git_string, sanitize_name, unique_slug, write_and_commit
|
from troggle.core.utils import (
|
||||||
|
COOKIE_MAX_AGE,
|
||||||
|
alphabet_suffix,
|
||||||
|
current_expo,
|
||||||
|
get_cookie,
|
||||||
|
git_string,
|
||||||
|
sanitize_name,
|
||||||
|
unique_slug,
|
||||||
|
write_and_commit,
|
||||||
|
)
|
||||||
from troggle.parsers.people import GetPersonExpeditionNameLookup, known_foreigner
|
from troggle.parsers.people import GetPersonExpeditionNameLookup, known_foreigner
|
||||||
|
|
||||||
# from databaseReset import reinit_db # don't do this. databaseRest runs code *at import time*
|
# from databaseReset import reinit_db # don't do this. databaseRest runs code *at import time*
|
||||||
@@ -20,7 +28,7 @@ from .auth import login_required_if_public
|
|||||||
|
|
||||||
"""File upload 'views'
|
"""File upload 'views'
|
||||||
Note that there are other file upload forms in views/wallet_edit.py
|
Note that there are other file upload forms in views/wallet_edit.py
|
||||||
and that core/forms.py contains Django class-based forms for caves and entrances.
|
and views/logbook_edit.py and that core/forms.py contains Django class-based forms for caves and entrances.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
todo = """
|
todo = """
|
||||||
@@ -42,95 +50,6 @@ todo = """
|
|||||||
- Make file rename utility less ugly.
|
- Make file rename utility less ugly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def create_new_lbe_slug(date):
|
|
||||||
onthisdate = LogbookEntry.objects.filter(date=date)
|
|
||||||
n = len(onthisdate)
|
|
||||||
print(f" Already entries on this date: {n}\n {onthisdate}")
|
|
||||||
|
|
||||||
suffix = alphabet_suffix(n+1)
|
|
||||||
|
|
||||||
tid = f"{date}{suffix}"
|
|
||||||
if len(tid) <=4 :
|
|
||||||
print(f"BAD ERROR {tid=}")
|
|
||||||
tid = f"{date}_{LogbookEntry.objects.count()}_{n}" # fudged number
|
|
||||||
print(f"{tid=}")
|
|
||||||
return tid
|
|
||||||
|
|
||||||
def store_edited_entry_into_database(date, place, title, text, others, author, tu, slug):
|
|
||||||
"""saves a single logbook entry and related personlogentry items
|
|
||||||
|
|
||||||
need to select out *guest and foreign friends from others
|
|
||||||
|
|
||||||
Rather similar to similarly named function in parsers/logbooks but circular reference prevents us using it directly,
|
|
||||||
and they need refactoring anyway.
|
|
||||||
"""
|
|
||||||
|
|
||||||
year = slug[0:4]
|
|
||||||
expedition = Expedition.objects.get(year=year)
|
|
||||||
cave = GetCaveLookup().get(place.lower())
|
|
||||||
# print(f"store_edited_entry_into_database(): {place=} {cave=}")
|
|
||||||
|
|
||||||
if LogbookEntry.objects.filter(slug=slug).exists():
|
|
||||||
# oops.
|
|
||||||
message = f" ! - DUPLICATE SLUG for logbook entry {date} - {slug}"
|
|
||||||
DataIssue.objects.create(parser="logbooks", message=message)
|
|
||||||
slug = slug + "_" + unique_slug(text,2)
|
|
||||||
|
|
||||||
otherAttribs = {
|
|
||||||
"place": place,
|
|
||||||
"text": text,
|
|
||||||
"expedition": expedition,
|
|
||||||
"time_underground": tu,
|
|
||||||
"cave": cave,
|
|
||||||
"title": f"{place} - {title}",
|
|
||||||
# "other_people": others
|
|
||||||
}
|
|
||||||
coUniqueAttribs = {"slug": slug, "date": date }
|
|
||||||
|
|
||||||
lbo = LogbookEntry.objects.create(**otherAttribs, **coUniqueAttribs)
|
|
||||||
|
|
||||||
pt_list = []
|
|
||||||
# These entities have to be PersonExpedition objects
|
|
||||||
team = others.split(",")
|
|
||||||
team.append(author)
|
|
||||||
|
|
||||||
odds = []
|
|
||||||
for name in team:
|
|
||||||
name = name.strip()
|
|
||||||
if len(name) > 0:
|
|
||||||
if name[0] == "*": # a name prefix of "*" is special, just a string.
|
|
||||||
odds.append(name)
|
|
||||||
print(f" - adding * special name '{name}'")
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
personyear = GetPersonExpeditionNameLookup(expedition).get(name.lower())
|
|
||||||
if not personyear:
|
|
||||||
odds.append(name)
|
|
||||||
print(f" - adding unrecognised expoer '{name}'")
|
|
||||||
if known_foreigner(name):
|
|
||||||
message = f" ! - Known foreigner: '{name}' in entry {slug=}"
|
|
||||||
print(message)
|
|
||||||
else:
|
|
||||||
message = f" ! - No name match for: '{name}' in entry {slug=}"
|
|
||||||
print(message)
|
|
||||||
DataIssue.objects.create(parser="logbooks", message=message)
|
|
||||||
else:
|
|
||||||
coUniqueAttribs = {"personexpedition": personyear, "nickname_used": name, "logbook_entry": lbo} # lbo is primary key
|
|
||||||
otherAttribs = {"time_underground": tu, "is_logbook_entry_author": (name==author)}
|
|
||||||
pt_list.append(PersonLogEntry(**otherAttribs, **coUniqueAttribs))
|
|
||||||
|
|
||||||
except:
|
|
||||||
# This should not happen. We do not raise exceptions in that function
|
|
||||||
message = f" ! - EXCEPTION: '{name}' in entry {slug=}"
|
|
||||||
print(message)
|
|
||||||
DataIssue.objects.create(parser="logbooks", message=message)
|
|
||||||
raise
|
|
||||||
|
|
||||||
PersonLogEntry.objects.bulk_create(pt_list)
|
|
||||||
|
|
||||||
lbo.other_people = ", ".join(odds)
|
|
||||||
print(f" - Saving other_people '{lbo.other_people}'")
|
|
||||||
lbo.save()
|
|
||||||
|
|
||||||
class FilesForm(forms.Form): # not a model-form, just a form-form
|
class FilesForm(forms.Form): # not a model-form, just a form-form
|
||||||
uploadfiles = forms.FileField()
|
uploadfiles = forms.FileField()
|
||||||
@@ -157,8 +76,6 @@ 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
|
@login_required_if_public
|
||||||
def edittxtpage(request, path, filepath):
|
def edittxtpage(request, path, filepath):
|
||||||
@@ -254,327 +171,6 @@ def edittxtpage(request, path, filepath):
|
|||||||
return simple_get(originaltext)
|
return simple_get(originaltext)
|
||||||
|
|
||||||
|
|
||||||
@login_required_if_public
|
|
||||||
def logbookedit(request, year=None, slug=None):
|
|
||||||
"""Edit a logbook entry
|
|
||||||
|
|
||||||
This 'validates' the author as being on expo in the current year, but only indicates this by
|
|
||||||
putting the text of the form prompt in red (same as for an invalid date, which is arguably more important).
|
|
||||||
No check is done on the other people on the trip as this is picked up anyway by parsing on import
|
|
||||||
and we don't really care at this point.
|
|
||||||
"""
|
|
||||||
def yesterday():
|
|
||||||
yesterday = datetime.now() - timedelta(1)
|
|
||||||
return yesterday.strftime('%Y-%m-%d')
|
|
||||||
|
|
||||||
def validate_year(year):
|
|
||||||
try:
|
|
||||||
expo = Expedition.objects.get(year=year)
|
|
||||||
except:
|
|
||||||
year = current_expo() # creates new Expedition object if needed
|
|
||||||
return year
|
|
||||||
|
|
||||||
def new_entry_form():
|
|
||||||
# set the date to be "yesterday" as this will, hopefully, usually be the case
|
|
||||||
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"logbookform.html",
|
|
||||||
{
|
|
||||||
"form": form,
|
|
||||||
"year": year,
|
|
||||||
"yesterday": yesterday(),
|
|
||||||
|
|
||||||
},
|
|
||||||
)
|
|
||||||
def clean_tu(tu):
|
|
||||||
if tu =="":
|
|
||||||
return 0
|
|
||||||
try:
|
|
||||||
tu = float(tu)/1 # check numeric
|
|
||||||
except:
|
|
||||||
return 0
|
|
||||||
return tu
|
|
||||||
|
|
||||||
if not year:
|
|
||||||
if not slug: # not in the URL, we have not read teh POST response yet.. wich might have a slug in it
|
|
||||||
year = current_expo()
|
|
||||||
else:
|
|
||||||
year = slug[0:4]
|
|
||||||
try:
|
|
||||||
year = str(int(year)) # but maybe slug was hand-edited to be a future year..
|
|
||||||
year = validate_year(year) # so fix that
|
|
||||||
except:
|
|
||||||
year = current_expo()
|
|
||||||
|
|
||||||
author = ""
|
|
||||||
|
|
||||||
if request.method == "POST":
|
|
||||||
prev_slug = "" # None value pending overwrite from submitted form
|
|
||||||
form = LogbookEditForm(request.POST)
|
|
||||||
if not form.is_valid():
|
|
||||||
message = f'Invalid form response for logbook entry creating "{request.POST}"'
|
|
||||||
print(message)
|
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
|
||||||
else:
|
|
||||||
# if there is no slug then this is probably a completely new lbe and we need to enter it into the db
|
|
||||||
# otherwise it is an update
|
|
||||||
# validation all to be done yet..
|
|
||||||
date = request.POST["date"].strip()
|
|
||||||
author = request.POST["author"].strip() # TODO check against personexpedition on submit
|
|
||||||
others = request.POST["others"].strip() # TODO check each against personexpedition on submit
|
|
||||||
place = request.POST["place"].strip().replace(' - ',' = ') # no hyphens !
|
|
||||||
title = request.POST["title"].strip()
|
|
||||||
entry = request.POST["text"].strip()
|
|
||||||
if "prev_slug" in request.POST:
|
|
||||||
prev_slug = request.POST["prev_slug"].strip() # if we are re-editing the same entry again
|
|
||||||
entry = entry.replace('\r','') # remove HTML-standard CR inserted from form.
|
|
||||||
entry = entry.replace('\n\n','\n<p>\n') # replace 2 \n with <p>
|
|
||||||
tu = request.POST["tu"].strip()
|
|
||||||
tu = clean_tu(tu)
|
|
||||||
|
|
||||||
try:
|
|
||||||
odate = datetime.strptime(date.replace(".", "-"), "%Y-%m-%d").date()
|
|
||||||
print(f"{odate.year=}")
|
|
||||||
if str(odate.year) == year:
|
|
||||||
dateflag = False
|
|
||||||
else:
|
|
||||||
print(f"Trying to change the year ! No!! {odate.year=}")
|
|
||||||
odate = datetime.strptime(f"{year}-01-01", "%Y-%m-%d").date()
|
|
||||||
dateflag = True
|
|
||||||
except:
|
|
||||||
odate = datetime.strptime(f"{year}-01-01", "%Y-%m-%d").date()
|
|
||||||
print(f"! Invalid date string {date}, setting to {odate}")
|
|
||||||
dateflag = True
|
|
||||||
date = odate.isoformat()
|
|
||||||
|
|
||||||
year = validate_year(year)
|
|
||||||
expo = Expedition.objects.get(year=year)
|
|
||||||
personyear = GetPersonExpeditionNameLookup(expo).get(author.lower())
|
|
||||||
if personyear:
|
|
||||||
authorflag = False
|
|
||||||
else:
|
|
||||||
authorflag = True
|
|
||||||
print(f"! Unrecognised author: {author}")
|
|
||||||
|
|
||||||
# if somehow we get a slug set to just '2024', not eg '2020-08-10b'
|
|
||||||
# because the URL of the page is /logbookedit/2022 for a new entry
|
|
||||||
# This is a hack, why can we not reproduce this bug on the dev system?
|
|
||||||
if slug not in locals():
|
|
||||||
slug = ""
|
|
||||||
if len(slug) < 11:
|
|
||||||
slug = ""
|
|
||||||
if len(prev_slug) < 11:
|
|
||||||
prev_slug = ""
|
|
||||||
|
|
||||||
if not prev_slug and not slug:
|
|
||||||
# Creating a new logbook entry with all the gubbins
|
|
||||||
slug = create_new_lbe_slug(date)
|
|
||||||
|
|
||||||
if prev_slug and not slug:
|
|
||||||
# if this was a previous post, then prev_slug will have been set on the form
|
|
||||||
# we are editing a previous thing, so we don't create a new lbe
|
|
||||||
slug = prev_slug
|
|
||||||
|
|
||||||
# OK we could patch the object in place, but if the people on the trip have changed this
|
|
||||||
# would get very messy. So we delete it, and thus all the dependent objects,
|
|
||||||
# and recreate it and all its links. It might not exist though.
|
|
||||||
print(f"- Deleting the LogBookEntry {slug}")
|
|
||||||
LogbookEntry.objects.filter(slug=slug).delete() # works even if it does not exist
|
|
||||||
|
|
||||||
print(f"- Creating the LogBookEntry {slug}")
|
|
||||||
year = slug[0:4]
|
|
||||||
try:
|
|
||||||
expedition = Expedition.objects.get(year=year)
|
|
||||||
except Expedition.DoesNotExist:
|
|
||||||
message = f'''! - This expo "{year}" not created yet
|
|
||||||
It needs to be created before you can save a logbook entry.
|
|
||||||
See /handbook/computing/newyear.html
|
|
||||||
|
|
||||||
WHAT TO DO NOW:
|
|
||||||
1. Press the Back button on your proswer to return to the screen where you typed up the entry,
|
|
||||||
2. Copy the text of what you wrote into a new text file,
|
|
||||||
3. Direct a nerd to fix this. It should take only a couple of minutes.'''
|
|
||||||
print(message)
|
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
|
||||||
store_edited_entry_into_database(date, place, title, entry, others, author, tu, slug)
|
|
||||||
|
|
||||||
|
|
||||||
print(f"- Rewriting the entire {year} logbook to disc ")
|
|
||||||
filename= "logbook.html"
|
|
||||||
try:
|
|
||||||
print(f" - Logbook for {year} to be exported and written out.")
|
|
||||||
writelogbook(year, filename) # uses a template, not the code fragment below which is just a visible hint to logged on user
|
|
||||||
except:
|
|
||||||
message = f'! - Logbook saving failed - \n!! Permissions failure ?! on attempting to save file "logbook.html"'
|
|
||||||
print(message)
|
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
|
||||||
|
|
||||||
# Code fragment illustration - not actually what gets saved to database
|
|
||||||
output = f'''
|
|
||||||
|
|
||||||
<div class="tripdate" id="{slug}">{date}</div>
|
|
||||||
<div class="trippeople"><u>{author}</u>, {others}</div>
|
|
||||||
<div class="triptitle">{place} - {title}</div>
|
|
||||||
|
|
||||||
{entry}
|
|
||||||
|
|
||||||
<div class="timeug">T/U {tu} hrs</div>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
'''
|
|
||||||
# Successful POST
|
|
||||||
# So save to database and then write out whole new logbook.html file
|
|
||||||
|
|
||||||
# We do author validation on the form as displayed by GET, not at the moment of POST.
|
|
||||||
# If we had JS validation then we could be more timely.
|
|
||||||
git = settings.GIT
|
|
||||||
dirpath = Path(settings.EXPOWEB) / "years" / str(year)
|
|
||||||
lbe_add = subprocess.run(
|
|
||||||
[git, "add", filename], cwd=dirpath, capture_output=True, text=True
|
|
||||||
)
|
|
||||||
msgdata = (
|
|
||||||
lbe_add.stderr
|
|
||||||
+ "\n"
|
|
||||||
+ lbe_add.stdout
|
|
||||||
+ "\nreturn code: "
|
|
||||||
+ str(lbe_add.returncode)
|
|
||||||
)
|
|
||||||
message = f'! - FORM Logbook Edit {slug} - Success: git ADD on server for this file {filename}.' + msgdata
|
|
||||||
print(message)
|
|
||||||
if lbe_add.returncode != 0:
|
|
||||||
msgdata = (
|
|
||||||
"Ask a nerd to fix this.\n\n"
|
|
||||||
+ lbe_add.stderr
|
|
||||||
+ "\n\n"
|
|
||||||
+ lbe_add.stdout
|
|
||||||
+ "\n\nreturn code: "
|
|
||||||
+ str(lbe_add.returncode)
|
|
||||||
)
|
|
||||||
message = (
|
|
||||||
f"! - FORM Logbook Edit - CANNOT git ADD on server for this file {filename}. {slug} edits saved but not added to git.\n"
|
|
||||||
+ msgdata
|
|
||||||
)
|
|
||||||
print(message)
|
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
|
||||||
|
|
||||||
lbe_commit = subprocess.run(
|
|
||||||
[git, "commit", "-m", f"Logbook edited {slug}"],
|
|
||||||
cwd=dirpath,
|
|
||||||
capture_output=True,
|
|
||||||
text=True,
|
|
||||||
)
|
|
||||||
message = f'! - FORM Logbook Edit - {filename}. {slug} edits saved, added to git, and COMMITTED.\n' + msgdata
|
|
||||||
print(message)
|
|
||||||
#This produces return code = 1 if it commits OK
|
|
||||||
if lbe_commit.returncode != 0:
|
|
||||||
msgdata = (
|
|
||||||
"Ask a nerd to fix this.\n\n"
|
|
||||||
+ lbe_commit.stderr
|
|
||||||
+ "\n"
|
|
||||||
+ lbe_commit.stdout
|
|
||||||
+ "\nreturn code: "
|
|
||||||
+ str(lbe_commit.returncode)
|
|
||||||
)
|
|
||||||
message = (
|
|
||||||
f"! - FORM Logbook Edit - Error code '{lbe_commit.returncode}' with git on server for {filename}. {slug} edits saved, added to git, but NOT committed.\n"
|
|
||||||
+ msgdata
|
|
||||||
)
|
|
||||||
print(message)
|
|
||||||
if not (lbe_commit.returncode ==1 and settings.DEVSERVER):
|
|
||||||
# rc=1 is OK on the development server
|
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
|
||||||
|
|
||||||
# This does not change the URL in the browser, so despite a new slug being created,
|
|
||||||
# the next time this code is run it thinks a new slug needs to be created. So we should
|
|
||||||
# actually redirect to a new URL (an edit not a create) not simply return a render object.
|
|
||||||
# logbookedit/2022-08-21a
|
|
||||||
|
|
||||||
# HOWEVER by doing a redirect rather than returning a rendered page, we lose all the
|
|
||||||
# error settings e.g dateflag and authroflag so the user gets no feedback about bad data entered.
|
|
||||||
# so we need to pass the flags explicitly int he url and then extract them from the request in the GET bit. sigh.
|
|
||||||
return HttpResponseRedirect(f"/logbookedit/{slug}?dateflag={dateflag}&authorflag={authorflag}")
|
|
||||||
|
|
||||||
# return render(
|
|
||||||
# request,
|
|
||||||
# "logbookform.html",
|
|
||||||
# {
|
|
||||||
# "form": form,
|
|
||||||
# "year": year,
|
|
||||||
# "date": date, "dateflag": dateflag,
|
|
||||||
# "author": author, "authorflag": authorflag,
|
|
||||||
# "others": others,
|
|
||||||
# "place": place,
|
|
||||||
# "title": title,
|
|
||||||
# "tu": tu,
|
|
||||||
# "entry": entry,
|
|
||||||
# "output": output,
|
|
||||||
# "slug": slug,
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
# GET here
|
|
||||||
else:
|
|
||||||
form = LogbookEditForm()
|
|
||||||
year = validate_year(year)
|
|
||||||
|
|
||||||
if request.GET.get('dateflag', 'False') == "True":
|
|
||||||
dateflag = True
|
|
||||||
else:
|
|
||||||
dateflag = False
|
|
||||||
|
|
||||||
if request.GET.get('authorflag', 'False') == "True":
|
|
||||||
authorflag = True
|
|
||||||
else:
|
|
||||||
authorflag = False
|
|
||||||
|
|
||||||
if not slug: # no slug or bad slug for an lbe which does not exist
|
|
||||||
return new_entry_form()
|
|
||||||
else:
|
|
||||||
lbes = LogbookEntry.objects.filter(slug=slug)
|
|
||||||
if not lbes:
|
|
||||||
return new_entry_form()
|
|
||||||
else:
|
|
||||||
if len(lbes) > 1:
|
|
||||||
return render(request, "object_list.html", {"object_list": lbes}) # ie a bug
|
|
||||||
else:
|
|
||||||
lbe = lbes[0]
|
|
||||||
print(f"{lbe}")
|
|
||||||
tu = clean_tu(lbe.time_underground)
|
|
||||||
|
|
||||||
people = []
|
|
||||||
for p in lbe.personlogentry_set.filter(logbook_entry=lbe): # p is a PersonLogEntry object
|
|
||||||
if p.is_logbook_entry_author:
|
|
||||||
# author = p.personexpedition.person.fullname
|
|
||||||
author = p.nickname_used
|
|
||||||
else:
|
|
||||||
# people.append(p.personexpedition.person.fullname)
|
|
||||||
people.append(p.nickname_used)
|
|
||||||
others =', '.join(people)
|
|
||||||
if lbe.other_people:
|
|
||||||
others = others + ", " + lbe.other_people
|
|
||||||
lenothers = min(70,max(20, len(others)))
|
|
||||||
|
|
||||||
text = lbe.text
|
|
||||||
rows = max(5,len(text)/50)
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"logbookform.html",
|
|
||||||
{
|
|
||||||
"form": form,
|
|
||||||
"year": year,
|
|
||||||
"date": lbe.date.isoformat(), "dateflag": dateflag,
|
|
||||||
"author": author, "authorflag": authorflag,
|
|
||||||
"others": others,
|
|
||||||
"lenothers": lenothers,
|
|
||||||
"place": lbe.place,
|
|
||||||
"title": lbe.title.replace(f"{lbe.place} - ",""),
|
|
||||||
"tu": tu,
|
|
||||||
"entry": text,
|
|
||||||
"textrows": rows,
|
|
||||||
"slug": slug,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
@login_required_if_public
|
@login_required_if_public
|
||||||
def expofilerename(request, filepath):
|
def expofilerename(request, filepath):
|
||||||
"""Rename any single file in /expofiles/ - eventually.
|
"""Rename any single file in /expofiles/ - eventually.
|
||||||
|
|||||||
@@ -19,8 +19,18 @@ from troggle.core.models.logbooks import LogbookEntry # , PersonLogEntry
|
|||||||
from troggle.core.models.survex import SurvexBlock, SurvexFile, SurvexPersonRole
|
from troggle.core.models.survex import SurvexBlock, SurvexFile, SurvexPersonRole
|
||||||
from troggle.core.models.troggle import DataIssue, Expedition
|
from troggle.core.models.troggle import DataIssue, Expedition
|
||||||
from troggle.core.models.wallets import YEAR_RANGE, Wallet, make_valid_date
|
from troggle.core.models.wallets import YEAR_RANGE, Wallet, make_valid_date
|
||||||
from troggle.core.utils import COOKIE_MAX_AGE, WriteAndCommitError, add_commit, current_expo, get_cookie, git_add, \
|
from troggle.core.utils import (
|
||||||
git_commit, git_string, sanitize_name, write_and_commit
|
COOKIE_MAX_AGE,
|
||||||
|
WriteAndCommitError,
|
||||||
|
add_commit,
|
||||||
|
current_expo,
|
||||||
|
get_cookie,
|
||||||
|
git_add,
|
||||||
|
git_commit,
|
||||||
|
git_string,
|
||||||
|
sanitize_name,
|
||||||
|
write_and_commit,
|
||||||
|
)
|
||||||
from troggle.core.views.auth import login_required_if_public
|
from troggle.core.views.auth import login_required_if_public
|
||||||
from troggle.core.views.caves import get_cave_leniently, getCave
|
from troggle.core.views.caves import get_cave_leniently, getCave
|
||||||
from troggle.core.views.scans import caveifywallet, oldwallet
|
from troggle.core.views.scans import caveifywallet, oldwallet
|
||||||
|
|||||||
3
urls.py
3
urls.py
@@ -35,6 +35,7 @@ from troggle.core.views.expo import (
|
|||||||
pubspage,
|
pubspage,
|
||||||
spider,
|
spider,
|
||||||
)
|
)
|
||||||
|
from troggle.core.views.logbook_edit import logbookedit
|
||||||
from troggle.core.views.logbooks import (
|
from troggle.core.views.logbooks import (
|
||||||
Expeditions_jsonListView,
|
Expeditions_jsonListView,
|
||||||
Expeditions_tsvListView,
|
Expeditions_tsvListView,
|
||||||
@@ -52,7 +53,7 @@ from troggle.core.views.logbooks import (
|
|||||||
from troggle.core.views.other import controlpanel, exportlogbook, frontpage, todos
|
from troggle.core.views.other import controlpanel, exportlogbook, frontpage, todos
|
||||||
from troggle.core.views.prospect import prospecting
|
from troggle.core.views.prospect import prospecting
|
||||||
from troggle.core.views.scans import allscans, cavewallets, scansingle, walletslistperson, walletslistyear
|
from troggle.core.views.scans import allscans, cavewallets, scansingle, walletslistperson, walletslistyear
|
||||||
from troggle.core.views.uploads import dwgupload, expofilerename, gpxupload, logbookedit, photoupload
|
from troggle.core.views.uploads import dwgupload, expofilerename, gpxupload, photoupload
|
||||||
from troggle.core.views.wallets_edit import walletedit
|
from troggle.core.views.wallets_edit import walletedit
|
||||||
|
|
||||||
"""This sets the actualurlpatterns[] and urlpatterns[] lists which django uses
|
"""This sets the actualurlpatterns[] and urlpatterns[] lists which django uses
|
||||||
|
|||||||
Reference in New Issue
Block a user