import datetime import os.path import re import django.db.models from django.db.models import Min, Max from django.urls import reverse from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render from django.template import Context, loader from django.template.defaultfilters import slugify from django.utils import timezone from django.views.generic.list import ListView import troggle.core.models as models import troggle.parsers.logbooks as logbookparsers from troggle.core.forms import getTripForm # , get_name, PersonForm from troggle.core.models import Expedition, Person, PersonExpedition from troggle.core.models_caves import LogbookEntry, PersonTrip from troggle.core.models_survex import SurvexBlock from troggle.helper import login_required_if_public from troggle.parsers.logbooks import LoadLogbookForExpedition from troggle.parsers.people import GetPersonExpeditionNameLookup import troggle.settings as settings # Django uses Context, not RequestContext when you call render # to_response. We always want to use RequestContext, so that # django adds the context from settings.TEMPLATE_CONTEXT_PROCESSORS. # This way we automatically get necessary settings variables passed # to each template. So we use a custom method, render_response # instead of render_to_response. Hopefully future Django releases # will make this unnecessary. # from troggle.alwaysUseRequestContext import render_response # Deprecated in 1.11.29 # @django.db.models.permalink #this allows the nice get_absolute_url syntax we are using def getNotablePersons(): notablepersons = [] for person in Person.objects.all(): if person.bisnotable(): notablepersons.append(person) return notablepersons def personindex(request): persons = Person.objects.all() # From what I can tell, "persons" seems to be the table rows, while "personss" is the table columns. - AC 16 Feb 09 personss = [ ] ncols = 4 nc = int((len(persons) + ncols - 1) / ncols) for i in range(ncols): personss.append(persons[i * nc: (i + 1) * nc]) notablepersons = [] for person in Person.objects.all(): if person.bisnotable(): notablepersons.append(person) return render(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons}) def expedition(request, expeditionname): this_expedition = Expedition.objects.get(year=int(expeditionname)) expeditions = Expedition.objects.all() personexpeditiondays = [ ] dateditems = list(this_expedition.logbookentry_set.all()) + list(this_expedition.survexblock_set.all()) dates = sorted(set([item.date for item in dateditems])) for personexpedition in this_expedition.personexpedition_set.all(): 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}) if "reload" in request.GET: LoadLogbookForExpedition(this_expedition) return render(request,'expedition.html', {'expedition': this_expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'settings':settings, 'dateditems': dateditems }) def get_absolute_url(self): return ('expedition', (expedition.year)) # replaced by statistics page # class ExpeditionListView(ListView): # django thus expects a template called "expedition_list.html" # # from the name of the object not the name of the class. # model = Expedition class Expeditions_tsvListView(ListView): """This uses the Django built-in shortcut mechanism It defaults to use a template with 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 = """ 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 def person(request, first_name='', last_name='', ): this_person = Person.objects.get(first_name = first_name, last_name = last_name) # This is for removing the reference to the user's profile, in case they set it to the wrong person if request.method == 'GET': if request.GET.get('clear_profile')=='True': this_person.user=None this_person.save() return HttpResponseRedirect(reverse('profiles_select_profile')) return render(request,'person.html', {'person': this_person, }) def GetPersonChronology(personexpedition): '''Horrible bug here whern ther eis 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. ''' res = { } for persontrip in personexpedition.persontrip_set.all(): a = res.setdefault(persontrip.logbook_entry.date, { }) 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 rdates = sorted(list(res.keys())) 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]) )) 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 = GetPersonChronology(personexpedition) return render(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology}) def logbookentry(request, date, slug): this_logbookentry = LogbookEntry.objects.filter(date=date, slug=slug) if len(this_logbookentry)>1: return render(request, 'object_list.html',{'object_list':this_logbookentry}) else: this_logbookentry=this_logbookentry[0] return render(request, 'logbookentry.html', {'logbookentry': this_logbookentry}) 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', { 'query_string': query_string, 'found_entries': found_entries, }) #context_instance=RequestContext(request)) def personForm(request,pk): person=Person.objects.get(pk=pk) form=PersonForm(instance=person) return render(request,'personform.html', {'form':form,}) # tried to delete all this, and the reference in urls.py, but got impenetrable django error message # @login_required_if_public # def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None): # expedition = Expedition.objects.get(year=expeditionyear) # PersonTripFormSet, TripForm = getTripForm(expedition) # if pslug and pdate: # previousdate = datetime.date(*[int(x) for x in pdate.split("-")]) # previouslbe = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition) # assert previouslbe.filename # if request.method == 'POST': # If the form has been submitted... # tripForm = TripForm(request.POST) # A form bound to the POST data # personTripFormSet = PersonTripFormSet(request.POST) # if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass # dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d") # directory = os.path.join(settings.EXPOWEB, # "years", # expedition.year, # "autologbook") # filename = os.path.join(directory, # dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html") # if not os.path.isdir(directory): # os.mkdir(directory) # if pslug and pdate: # delLogbookEntry(previouslbe) # f = open(filename, "w") # template = loader.get_template('dataformat/logbookentry.html') # context = Context({'trip': tripForm.cleaned_data, # 'persons': personTripFormSet.cleaned_data, # 'date': dateStr, # 'expeditionyear': expeditionyear}) # f.write(template.render(context)) # f.close() # print((logbookparsers.parseAutoLogBookEntry(filename))) # return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST # else: # if pslug and pdate: # if previouslbe.cave: # tripForm = TripForm(initial={"date": previousdate, # "title": previouslbe.title, # "cave": previouslbe.cave.reference(), # "location": None, # "caveOrLocation": "cave", # "html": previouslbe.text}) # else: # tripForm = TripForm(initial={"date": previousdate, # "title": previouslbe.title, # "cave": None, # "location": previouslbe.place, # "caveOrLocation": "location", # "html": previouslbe.text}) # personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition), # "TU": py.time_underground, # "author": py.is_logbook_entry_author} # for py in previouslbe.persontrip_set.all()]) # else: # tripForm = TripForm() # An unbound form # personTripFormSet = PersonTripFormSet() # return render(request, 'newlogbookentry.html', { # 'tripForm': tripForm, # 'personTripFormSet': personTripFormSet, # }) # @login_required_if_public # def deleteLogbookEntry(request, expeditionyear, date = None, slug = None): # expedition = Expedition.objects.get(year=expeditionyear) # previousdate = datetime.date(*[int(x) for x in date.split("-")]) # previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition) # delLogbookEntry(previouslbe) # return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST # def delLogbookEntry(lbe): # for pt in lbe.persontrip_set.all(): # pt.delete() # lbe.delete() # os.remove(lbe.filename) 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()]}) 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()]})