troggle-unchained/core/views/logbooks.py

205 lines
9.2 KiB
Python
Raw Normal View History

import datetime
import os.path
import re
2011-07-11 02:10:22 +01:00
import django.db.models
2020-05-31 22:35:36 +01:00
from django.db.models import Min, Max
2020-06-18 21:50:16 +01:00
from django.urls import reverse
from django.http import HttpResponse, HttpResponseRedirect
2021-03-28 03:48:24 +01:00
from django.shortcuts import render
2011-07-11 02:10:22 +01:00
from django.template import Context, loader
from django.template.defaultfilters import slugify
from django.utils import timezone
from django.views.generic.list import ListView
2011-07-11 02:10:22 +01:00
2021-04-13 00:43:57 +01:00
from troggle.core.models.troggle import Expedition, Person, PersonExpedition
2021-04-12 23:58:48 +01:00
from troggle.core.utils import TROG
2021-04-13 00:47:17 +01:00
from troggle.core.models.caves import LogbookEntry, PersonTrip
2021-04-13 00:50:12 +01:00
from troggle.core.models.survex import SurvexBlock
from .login import login_required_if_public
from troggle.parsers.logbooks import LoadLogbookForExpedition
from troggle.parsers.people import GetPersonExpeditionNameLookup
import troggle.settings as settings
2021-04-10 01:07:49 +01:00
'''These views are for logbook items when they appear in an 'expedition' page
and for persons: their individual pages and their perseonexpedition pages.
It uses the global object TROG to hold some cached pages.
'''
2011-07-11 02:10:22 +01:00
2021-04-21 19:08:42 +01:00
todo = '''Fix the get_person_chronology() display bug.
'''
2011-07-11 02:10:22 +01:00
def personindex(request):
persons = Person.objects.all()
# From what I can tell, "persons" seems to be the table rows, while "pcols" is the table columns. - AC 16 Feb 09
pcols = [ ]
2011-07-11 02:10:22 +01:00
ncols = 4
2020-05-31 22:35:36 +01:00
nc = int((len(persons) + ncols - 1) / ncols)
2011-07-11 02:10:22 +01:00
for i in range(ncols):
pcols.append(persons[i * nc: (i + 1) * nc])
2011-07-11 02:10:22 +01:00
notablepersons = []
for person in Person.objects.all():
if person.bisnotable():
notablepersons.append(person)
return render(request,'personindex.html', {'persons': persons, 'pcols':pcols, 'notablepersons':notablepersons})
2011-07-11 02:10:22 +01:00
def expedition(request, expeditionname):
2021-04-10 01:07:49 +01:00
'''Returns a rendered page for one expedition, specified by the year e.g. '2019'.
If page caching is enabled, it caches the dictionaries used to render the template page.
The cache is refreshed if '?reload' is present in the requesting URL, which also re-parses the logbook.
By specifying a '0' for the expected number of entries in the logbook cache, this forces the parser to
re-parse the original logbook HTML file.
'''
if request.user.is_authenticated:
if "reload" in request.GET:
this_expedition = Expedition.objects.get(year=int(expeditionname))
# Need to delete the exisitng entries or we get duplication
# Need to delete both in the Django ORM and in our own object-store.
entries = this_expedition.logbookentry_set.all()
print(f'! - expo {expeditionname} {len(entries)} entries')
for entry in entries:
print(f'! - delete entry: "{entry}"')
entry.delete()
entries = this_expedition.logbookentry_set.all()
print(f'! - expo {expeditionname} {len(entries)} entries')
LoadLogbookForExpedition(this_expedition, 0) # 0 means re-parse
logged_in = True
else:
logged_in = False
2021-04-10 01:07:49 +01:00
ts = TROG['pagecache']['expedition']
if settings.CACHEDPAGES:
nexpos = len( TROG['pagecache']['expedition'])
#print(f'! - expo {expeditionname} CACHEDPAGES {nexpos} expo pages in cache.')
if expeditionname in ts:
#print('! - expo {expeditionanme} using cached page')
return render(request,'expedition.html', { **ts[expeditionname], 'logged_in' : logged_in })
2021-04-10 01:07:49 +01:00
this_expedition = Expedition.objects.get(year=int(expeditionname))
2021-04-10 01:07:49 +01:00
2011-07-11 02:10:22 +01:00
expeditions = Expedition.objects.all()
personexpeditiondays = [ ]
dateditems = list(this_expedition.logbookentry_set.all()) + list(this_expedition.survexblock_set.all())
2020-05-24 01:57:06 +01:00
dates = sorted(set([item.date for item in dateditems]))
for personexpedition in this_expedition.personexpedition_set.all():
2011-07-11 02:10:22 +01:00
prow = [ ]
for date in dates:
pcell = { "persontrips": PersonTrip.objects.filter(personexpedition=personexpedition,
logbook_entry__date=date) }
pcell["survexblocks"] = set(SurvexBlock.objects.filter(survexpersonrole__personexpedition=personexpedition,
date = date))
prow.append(pcell)
personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
2021-04-10 01:07:49 +01:00
ts[expeditionname] = {'expedition': this_expedition, 'expeditions':expeditions,
'personexpeditiondays':personexpeditiondays, 'settings':settings,
'dateditems': dateditems}
2021-04-10 01:07:49 +01:00
TROG['pagecache']['expedition'][expeditionname] = ts[expeditionname]
nexpos = len( TROG['pagecache']['expedition'])
#print(f'! - expo {expeditionname} pre-render N expos:{nexpos}')
return render(request,'expedition.html', { **ts[expeditionname], 'logged_in' : logged_in } )
2011-07-11 02:10:22 +01:00
2021-03-31 22:13:51 +01:00
# def get_absolute_url(self): # seems to have come seriously adrift. This should be in a class?!
# return ('expedition', (expedition.year))
class Expeditions_tsvListView(ListView):
"""This uses the Django built-in shortcut mechanism
It defaults to use a template with name <app-label>/<model-name>_list.html.
https://www.agiliq.com/blog/2017/12/when-and-how-use-django-listview/
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views
Either a queryset variable or set_queryset() function is used, but not needed
if you want all the obejcts of a particaulr type in which case just set model = <object>
"""
template_name = 'core/expeditions_tsv_list.html' # if not present then uses core/expedition_list.html
#queryset = Expedition.objects.all()
#context_object_name = 'expedition'
model = Expedition # equivalent to .objects.all() for a queryset
class Expeditions_jsonListView(ListView):
template_name = 'core/expeditions_json_list.html'
model = Expedition
2011-07-11 02:10:22 +01:00
def person(request, first_name='', last_name='', ):
2021-04-20 22:58:41 +01:00
try:
this_person = Person.objects.get(first_name = first_name, last_name = last_name)
return render(request,'person.html', {'person': this_person, })
except:
2021-04-20 23:57:51 +01:00
message = f'Person not found \'{first_name} {last_name}\' - possibly Scottish? (We have a name parser issue with Mc, Mac etc.)'
2021-04-20 22:58:41 +01:00
return render(request, 'errors/generic.html', {'message': message})
2011-07-11 02:10:22 +01:00
def get_person_chronology(personexpedition):
2021-04-11 03:02:06 +01:00
'''Horrible bug here whern there is more than one survex block per day, it duplicates the entry but gets it wrong
Fortunately this is just the display on this page which is wroing, no bad calculations get into the database.
'''
2011-07-11 02:10:22 +01:00
res = { }
for persontrip in personexpedition.persontrip_set.all():
a = res.setdefault(persontrip.logbook_entry.date, { })
2011-07-11 02:10:22 +01:00
a.setdefault("persontrips", [ ]).append(persontrip)
for personrole in personexpedition.survexpersonrole_set.all():
a = res.setdefault(personrole.survexblock.date, { })
a.setdefault("personroles", [ ]).append(personrole.survexblock)
# build up the tables
2020-05-24 01:57:06 +01:00
rdates = sorted(list(res.keys()))
2011-07-11 02:10:22 +01:00
res2 = [ ]
for rdate in rdates:
persontrips = res[rdate].get("persontrips", [])
personroles = res[rdate].get("personroles", [])
for n in range(max(len(persontrips), len(personroles) )):
res2.append(((n == 0 and rdate or "--"), (n < len(persontrips) and persontrips[n]), (n < len(personroles) and personroles[n]) ))
2011-07-11 02:10:22 +01:00
return res2
def personexpedition(request, first_name='', last_name='', year=''):
person = Person.objects.get(first_name = first_name, last_name = last_name)
this_expedition = Expedition.objects.get(year=year)
personexpedition = person.personexpedition_set.get(expedition=this_expedition)
personchronology = get_person_chronology(personexpedition)
return render(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})
2011-07-11 02:10:22 +01:00
def logbookentry(request, date, slug):
this_logbookentry = LogbookEntry.objects.filter(date=date, slug=slug)
2011-07-11 02:10:22 +01:00
if len(this_logbookentry)>1:
return render(request, 'object_list.html',{'object_list':this_logbookentry})
2011-07-11 02:10:22 +01:00
else:
this_logbookentry=this_logbookentry[0]
return render(request, 'logbookentry.html', {'logbookentry': this_logbookentry})
2011-07-11 02:10:22 +01:00
def logbookSearch(request, extra):
query_string = ''
found_entries = None
if ('q' in request.GET) and request.GET['q'].strip():
query_string = request.GET['q']
entry_query = search.get_query(query_string, ['text','title',])
found_entries = LogbookEntry.objects.filter(entry_query)
return render(request,'logbooksearch.html',
2011-07-11 02:10:22 +01:00
{ 'query_string': query_string, 'found_entries': found_entries, })
def get_people(request, expeditionslug):
exp = Expedition.objects.get(year = expeditionslug)
return render(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]})
2011-07-11 02:10:22 +01:00
def get_logbook_entries(request, expeditionslug):
exp = Expedition.objects.get(year = expeditionslug)
return render(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]})