2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2024-11-25 08:41:51 +00:00

Import rejigging to fix circular refs

This commit is contained in:
Philip Sargent 2020-05-30 01:11:02 +01:00
parent 6568cb8900
commit 0776978c9c
8 changed files with 131 additions and 132 deletions

View File

@ -8,8 +8,8 @@ from django.contrib.admin.widgets import AdminDateWidget
from tinymce.widgets import TinyMCE from tinymce.widgets import TinyMCE
from troggle.core.models import Person, PersonExpedition, LogbookEntry, Expedition from troggle.core.models import Person, PersonExpedition, Expedition
from troggle.core.models_caves import Cave, QM, Entrance, CaveAndEntrance from troggle.core.models_caves import Cave, LogbookEntry, QM, Entrance, CaveAndEntrance
class CaveForm(ModelForm): class CaveForm(ModelForm):
underground_description = forms.CharField(required = False, widget=forms.Textarea()) underground_description = forms.CharField(required = False, widget=forms.Textarea())

View File

@ -5,7 +5,7 @@ import logging
import re import re
from subprocess import call from subprocess import call
from urllib.parse import urljoin import urllib.parse
from decimal import Decimal, getcontext from decimal import Decimal, getcontext
getcontext().prec=2 #use 2 significant figures for decimal calculations getcontext().prec=2 #use 2 significant figures for decimal calculations
@ -15,7 +15,6 @@ from django.db import models
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
#from django.db.models import Min, Max
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.template import Context, loader from django.template import Context, loader
@ -237,119 +236,3 @@ class PersonExpedition(TroggleModel):
return res["day_max"] return res["day_max"]
class LogbookEntry(TroggleModel):
"""Single parsed entry from Logbook
"""
LOGBOOK_ENTRY_TYPES = (
("wiki", "Wiki style logbook"),
("html", "Html style logbook")
)
date = models.DateField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.ld()
expeditionday = models.ForeignKey("ExpeditionDay", null=True)#MJG wants to KILL THIS (redundant information)
expedition = models.ForeignKey(Expedition,blank=True,null=True) # yes this is double-
title = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
cave_slug = models.SlugField(max_length=50)
place = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
text = models.TextField()
slug = models.SlugField(max_length=50)
filename = models.CharField(max_length=200,null=True)
entry_type = models.CharField(default="wiki",null=True,choices=LOGBOOK_ENTRY_TYPES,max_length=50)
class Meta:
verbose_name_plural = "Logbook Entries"
# several PersonTrips point in to this object
ordering = ('-date',)
def __getattribute__(self, item):
if item == "cave":
#Allow a logbookentries cave to be directly accessed despite not having a proper foreignkey
return models_caves.CaveSlug.objects.get(slug = self.cave_slug).cave
# parse error in python3.8
# https://stackoverflow.com/questions/41343263/provide-classcell-example-for-python-3-6-metaclass
#https://github.com/django/django/pull/7653
#return TroggleModel.__getattribute__(item)
#return super(LogbookEntry, self).__getattribute__(item) # works in py3.5, fails in 3.8
return TroggleModel.__getattribute__(self,item) # works in py 3.5 AND in 3.8
def __init__(self, *args, **kwargs):
if "cave" in list(kwargs.keys()):
if kwargs["cave"] is not None:
kwargs["cave_slug"] = models_caves.CaveSlug.objects.get(cave=kwargs["cave"], primary=True).slug
kwargs.pop("cave")
# parse error in python3.8
return TroggleModel.__init__(self, *args, **kwargs) # seems OK in 3.5 & 3.8! failure later elsewhere with 3.8
#return TroggleModel().__init__(self, *args, **kwargs) # parses OK, fails at runtime in 3.8
#return super().__init__(self, *args, **kwargs) # fails in 3.8
#return super().__init__(*args, **kwargs) # works in py3.5 fails in 3.8
#return super(LogbookEntry, self).__init__(*args, **kwargs) # works in py3.5
#return TroggleModel.__init__(*args, **kwargs) # fails in py3.5, runtime fail in 3.8
def isLogbookEntry(self): # Function used in templates
return True
def get_absolute_url(self):
return urllib.parse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug}))
def __str__(self):
return "%s: (%s)" % (self.date, self.title)
def get_next_by_id(self):
LogbookEntry.objects.get(id=self.id+1)
def get_previous_by_id(self):
LogbookEntry.objects.get(id=self.id-1)
def new_QM_number(self):
"""Returns """
if self.cave:
nextQMnumber=self.cave.new_QM_number(self.date.year)
else:
return None
return nextQMnumber
def new_QM_found_link(self):
"""Produces a link to a new QM with the next number filled in and this LogbookEntry set as 'found by' """
return settings.URL_ROOT + r'/admin/core/qm/add/?' + r'found_by=' + str(self.pk) +'&number=' + str(self.new_QM_number())
def DayIndex(self):
return list(self.expeditionday.logbookentry_set.all()).index(self)
#
# Single Person going on a trip, which may or may not be written up (accounts for different T/U for people in same logbook entry)
#
class PersonTrip(TroggleModel):
personexpedition = models.ForeignKey("PersonExpedition",null=True)
#expeditionday = models.ForeignKey("ExpeditionDay")#MJG wants to KILL THIS (redundant information)
#date = models.DateField() #MJG wants to KILL THIS (redundant information)
time_underground = models.FloatField(help_text="In decimal hours")
logbook_entry = models.ForeignKey(LogbookEntry)
is_logbook_entry_author = models.BooleanField(default=False)
# sequencing by person (difficult to solve locally)
#persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)#MJG wants to KILL THIS (and use funstion persontrip_next_auto)
#persontrip_prev = models.ForeignKey('PersonTrip', related_name='pprev', blank=True,null=True)#MJG wants to KILL THIS(and use funstion persontrip_prev_auto)
def persontrip_next(self):
futurePTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__gt = self.logbook_entry.date).order_by('logbook_entry__date').all()
if len(futurePTs) > 0:
return futurePTs[0]
else:
return None
def persontrip_prev(self):
pastPTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__lt = self.logbook_entry.date).order_by('-logbook_entry__date').all()
if len(pastPTs) > 0:
return pastPTs[0]
else:
return None
def place(self):
return self.logbook_entry.cave and self.logbook_entry.cave or self.logbook_entry.place
def __str__(self):
return "%s (%s)" % (self.personexpedition, self.logbook_entry.date)

View File

@ -18,7 +18,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.template import Context, loader from django.template import Context, loader
from troggle.core.models import * from troggle.core.models import TroggleModel, TroggleImageModel, Person, Expedition
from troggle.core.models_survex import * from troggle.core.models_survex import *
class Area(TroggleModel): class Area(TroggleModel):
@ -406,6 +406,85 @@ class NewSubCave(TroggleModel):
def __str__(self): def __str__(self):
return str(self.name) return str(self.name)
class LogbookEntry(TroggleModel):
"""Single parsed entry from Logbook
"""
LOGBOOK_ENTRY_TYPES = (
("wiki", "Wiki style logbook"),
("html", "Html style logbook")
)
date = models.DateField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.ld()
expeditionday = models.ForeignKey("ExpeditionDay", null=True)#MJG wants to KILL THIS (redundant information)
expedition = models.ForeignKey(Expedition,blank=True,null=True) # yes this is double-
title = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
cave_slug = models.SlugField(max_length=50)
place = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
text = models.TextField()
slug = models.SlugField(max_length=50)
filename = models.CharField(max_length=200,null=True)
entry_type = models.CharField(default="wiki",null=True,choices=LOGBOOK_ENTRY_TYPES,max_length=50)
class Meta:
verbose_name_plural = "Logbook Entries"
# several PersonTrips point in to this object
ordering = ('-date',)
def __getattribute__(self, item):
if item == "cave":
#Allow a logbookentries cave to be directly accessed despite not having a proper foreignkey
return CaveSlug.objects.get(slug = self.cave_slug).cave
# parse error in python3.8
# https://stackoverflow.com/questions/41343263/provide-classcell-example-for-python-3-6-metaclass
#https://github.com/django/django/pull/7653
#return TroggleModel.__getattribute__(item)
#return super(LogbookEntry, self).__getattribute__(item) # works in py3.5, fails in 3.8
return TroggleModel.__getattribute__(self,item) # works in py 3.5 AND in 3.8
def __init__(self, *args, **kwargs):
if "cave" in list(kwargs.keys()):
if kwargs["cave"] is not None:
kwargs["cave_slug"] = models_caves.CaveSlug.objects.get(cave=kwargs["cave"], primary=True).slug
kwargs.pop("cave")
# parse error in python3.8
return TroggleModel.__init__(self, *args, **kwargs) # seems OK in 3.5 & 3.8! failure later elsewhere with 3.8
#return TroggleModel().__init__(self, *args, **kwargs) # parses OK, fails at runtime in 3.8
#return super().__init__(self, *args, **kwargs) # fails in 3.8
#return super().__init__(*args, **kwargs) # works in py3.5 fails in 3.8
#return super(LogbookEntry, self).__init__(*args, **kwargs) # works in py3.5
#return TroggleModel.__init__(*args, **kwargs) # fails in py3.5, runtime fail in 3.8
def isLogbookEntry(self): # Function used in templates
return True
def get_absolute_url(self):
return urllib.parse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug}))
def __str__(self):
return "%s: (%s)" % (self.date, self.title)
def get_next_by_id(self):
LogbookEntry.objects.get(id=self.id+1)
def get_previous_by_id(self):
LogbookEntry.objects.get(id=self.id-1)
def new_QM_number(self):
"""Returns """
if self.cave:
nextQMnumber=self.cave.new_QM_number(self.date.year)
else:
return None
return nextQMnumber
def new_QM_found_link(self):
"""Produces a link to a new QM with the next number filled in and this LogbookEntry set as 'found by' """
return settings.URL_ROOT + r'/admin/core/qm/add/?' + r'found_by=' + str(self.pk) +'&number=' + str(self.new_QM_number())
def DayIndex(self):
return list(self.expeditionday.logbookentry_set.all()).index(self)
class QM(TroggleModel): class QM(TroggleModel):
#based on qm.csv in trunk/expoweb/1623/204 which has the fields: #based on qm.csv in trunk/expoweb/1623/204 which has the fields:
#"Number","Grade","Area","Description","Page reference","Nearest station","Completion description","Comment" #"Number","Grade","Area","Description","Page reference","Nearest station","Completion description","Comment"
@ -510,4 +589,39 @@ class Survey(TroggleModel):
def elevations(self): def elevations(self):
return self.scannedimage_set.filter(contents='elevation') return self.scannedimage_set.filter(contents='elevation')
#
# Single Person going on a trip, which may or may not be written up (accounts for different T/U for people in same logbook entry)
#
class PersonTrip(TroggleModel):
personexpedition = models.ForeignKey("PersonExpedition",null=True)
#expeditionday = models.ForeignKey("ExpeditionDay")#MJG wants to KILL THIS (redundant information)
#date = models.DateField() #MJG wants to KILL THIS (redundant information)
time_underground = models.FloatField(help_text="In decimal hours")
logbook_entry = models.ForeignKey(LogbookEntry)
is_logbook_entry_author = models.BooleanField(default=False)
# sequencing by person (difficult to solve locally)
#persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)#MJG wants to KILL THIS (and use funstion persontrip_next_auto)
#persontrip_prev = models.ForeignKey('PersonTrip', related_name='pprev', blank=True,null=True)#MJG wants to KILL THIS(and use funstion persontrip_prev_auto)
def persontrip_next(self):
futurePTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__gt = self.logbook_entry.date).order_by('logbook_entry__date').all()
if len(futurePTs) > 0:
return futurePTs[0]
else:
return None
def persontrip_prev(self):
pastPTs = PersonTrip.objects.filter(personexpedition = self.personexpedition, logbook_entry__date__lt = self.logbook_entry.date).order_by('-logbook_entry__date').all()
if len(pastPTs) > 0:
return pastPTs[0]
else:
return None
def place(self):
return self.logbook_entry.cave and self.logbook_entry.cave or self.logbook_entry.place
def __str__(self):
return "%s (%s)" % (self.personexpedition, self.logbook_entry.date)

View File

@ -3,7 +3,7 @@ from django.utils.html import conditional_escape
from django.template.defaultfilters import stringfilter from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.conf import settings from django.conf import settings
from troggle.core.models import QM, LogbookEntry, Cave from troggle.core.models_caves import LogbookEntry, QM, Cave
import re, urllib.parse import re, urllib.parse
register = template.Library() register = template.Library()

View File

@ -21,7 +21,8 @@ from django.shortcuts import get_object_or_404, render
import troggle.settings as settings import troggle.settings as settings
import troggle.core.models as models import troggle.core.models as models
from troggle.core.models_caves import CaveSlug, Cave, CaveAndEntrance, Survey, Expedition, QM, CaveDescription, EntranceSlug, Entrance, Area, SurvexStation from troggle.core.models import Expedition
from troggle.core.models_caves import CaveSlug, Cave, CaveAndEntrance, Survey, QM, CaveDescription, EntranceSlug, Entrance, Area, SurvexStation
from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, VersionControlCommentForm, EntranceForm, EntranceLetterForm from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, VersionControlCommentForm, EntranceForm, EntranceLetterForm
from troggle.helper import login_required_if_public from troggle.helper import login_required_if_public

View File

@ -14,8 +14,9 @@ from django.views.generic.list import ListView
import troggle.core.models as models import troggle.core.models as models
import troggle.parsers.logbooks as logbookparsers import troggle.parsers.logbooks as logbookparsers
from troggle.core.forms import getTripForm # , get_name, PersonForm from troggle.core.forms import getTripForm # , get_name, PersonForm
from troggle.core.models import Expedition, LogbookEntry, Person, PersonExpedition, PersonTrip from troggle.core.models import Expedition, Person, PersonExpedition
from troggle.core.models_survex import SurvexBlock from troggle.core.models_caves import LogbookEntry, PersonTrip
from troggle.core.models_survex import SurvexBlock, SurvexLeg
from troggle.helper import login_required_if_public from troggle.helper import login_required_if_public
from troggle.parsers.logbooks import LoadLogbookForExpedition from troggle.parsers.logbooks import LoadLogbookForExpedition
from troggle.parsers.people import GetPersonExpeditionNameLookup from troggle.parsers.people import GetPersonExpeditionNameLookup
@ -226,12 +227,12 @@ def experimental(request):
for survexblock in survexblocks: for survexblock in survexblocks:
survexlegs.extend(survexblock.survexleg_set.all()) survexlegs.extend(survexblock.survexleg_set.all())
survexleglength += survexblock.totalleglength survexleglength += survexblock.totalleglength
legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength})) legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength/1000}))
legsbyexpo.reverse() legsbyexpo.reverse()
survexlegs = models.SurvexLeg.objects.all() survexlegs = SurvexLeg.objects.all()
totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs]) totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs])
return render(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo }) return render(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength/1000, "legsbyexpo":legsbyexpo })
@login_required_if_public @login_required_if_public
def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None): def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None):

View File

@ -9,8 +9,8 @@ from django.shortcuts import render
from django.template import Context, loader from django.template import Context, loader
import databaseReset import databaseReset
from troggle.core.models import Expedition, LogbookEntry, Person, PersonExpedition, PersonTrip from troggle.core.models import Expedition, Person, PersonExpedition
from troggle.core.models_caves import QM, Cave from troggle.core.models_caves import LogbookEntry, QM, Cave, PersonTrip
from troggle.helper import login_required_if_public from troggle.helper import login_required_if_public

View File

@ -11,9 +11,9 @@ from django.http import HttpResponse, Http404
import troggle.settings as settings import troggle.settings as settings
import parsers.survex import parsers.survex
from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry from troggle.core.models import Expedition, Person, PersonExpedition
from troggle.core.models_survex import SurvexBlock, SurvexPersonRole, SurvexFile, SurvexDirectory, SurvexTitle from troggle.core.models_survex import SurvexBlock, SurvexPersonRole, SurvexFile, SurvexDirectory, SurvexTitle
from troggle.core.models_caves import Cave from troggle.core.models_caves import Cave, PersonTrip, LogbookEntry
from troggle.parsers.people import GetPersonExpeditionNameLookup from troggle.parsers.people import GetPersonExpeditionNameLookup