2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2024-11-22 07:11:52 +00:00

fixing Sunday display on calendar

This commit is contained in:
Philip Sargent 2023-01-30 15:28:11 +00:00
parent 7d98980121
commit 3742e0f367
7 changed files with 97 additions and 88 deletions

View File

@ -33,6 +33,7 @@ todo='''
'''
class CaveSlug(models.Model):
"""Moved here to avoid nasty cyclic import error"""
cave = models.ForeignKey('Cave',on_delete=models.CASCADE)
slug = models.SlugField(max_length=50, unique = True)
primary = models.BooleanField(default=False)
@ -41,7 +42,6 @@ class LogbookEntry(TroggleModel):
"""Single parsed entry from 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,on_delete=models.SET_NULL)#MJG wants to KILL THIS (redundant information)
expedition = models.ForeignKey(Expedition,blank=True, null=True,on_delete=models.SET_NULL) # yes this is double-
title = models.CharField(max_length=200)
cave_slug = models.SlugField(max_length=50, blank=True, null=True)
@ -77,9 +77,16 @@ class LogbookEntry(TroggleModel):
def DayIndex(self):
"""This is used to set different colours for the different trips on
the calendar view of the expedition"""
index = list(LogbookEntry.objects.filter(date=self.date)).index(self)
if index not in range(0,10):
print(f"Unexpected LogbookEntry DayIndex '{index}' {self}")
mx = 10
todays = list(LogbookEntry.objects.filter(date=self.date))
if self in todays:
index = todays.index(self)
else:
print(f"DayIndex: Synchronization error. Restart server. {self}")
index = 0
if index not in range(0, mx):
print(f"DayIndex: More than {mx-1} LogbookEntry items on one day '{index}' {self}")
index = 0
return index

View File

@ -148,10 +148,11 @@ class SurvexBlock(models.Model):
def DayIndex(self):
"""This is used to set different colours for the different trips on
the calendar view of the expedition"""
mx = 10
index = list(SurvexBlock.objects.filter(date=self.date)).index(self)
if index not in range(0,10):
print(f"Unexpected SurvexBlock DayIndex '{index}' {self}")
index = 10
if index not in range(0, mx):
print(f"DayIndex: More than {mx-1} SurvexBlock items on one day '{index}' {self}")
index = 0
#return list(self.survexblock_set.all()).index(self)
return index

View File

@ -51,6 +51,8 @@ class DataIssue(TroggleModel):
We have replaced all assertions in the code with messages and local fix-ups or skips:
https://martinfowler.com/articles/replaceThrowWithNotification.html
See also the use of stash_data_issue() & store_data_issues() in parsers/survex.py which defer writing to the database until the end of the import.
"""
date = models.DateTimeField(auto_now_add=True, blank=True)
parser = models.CharField(max_length=50, blank=True, null=True)
@ -81,34 +83,9 @@ class Expedition(TroggleModel):
def get_absolute_url(self):
return urljoin(settings.URL_ROOT, reverse('expedition', args=[self.year]))
# construction function. should be moved out
# def get_expedition_day(self, date):
# expeditiondays = self.expeditionday_set.filter(date=date)
# if expeditiondays:
# if len(expeditiondays) == 1:
# return expeditiondays[0]
# else:
# message =f'! - More than one expeditionday for the same date: {date} .\n - This should never happen. \n - Restart mysql and run reset to clean database.'
# DataIssue.objects.create(parser='expedition', message=message)
# return expeditiondays[0]
# res = ExpeditionDay(expedition=self, date=date)
# res.save()
# return res
# def day_min(self):
# """First day of expedition
# """
# res = self.expeditionday_set.all()
# return res and res[0] or None
# def day_max(self):
# """last day of expedition
# """
# res = self.expeditionday_set.all()
# return res and res[len(res) - 1] or None
class ExpeditionDay(TroggleModel):
"""Exists only on Expedition now. Removed from logbookentry, persontrip, survex stuff etc.
"""Exists only on Expedition now. Removed links from logbookentry, persontrip, survex stuff etc.
"""
expedition = models.ForeignKey("Expedition",on_delete=models.CASCADE)
date = models.DateField()
@ -116,11 +93,11 @@ class ExpeditionDay(TroggleModel):
class Meta:
ordering = ('date',)
def GetPersonTrip(self, personexpedition):
"""returns all logbook trips for this expeditonday
"""
personexpeditions = self.persontrip_set.filter(expeditionday=self)
return personexpeditions and personexpeditions[0] or None
# def GetPersonTrip(self, personexpedition):
# """returns all logbook trips for this expeditonday
# """
# personexpeditions = self.persontrip_set.filter(expeditionday=self)
# return personexpeditions and personexpeditions[0] or None
class Person(TroggleModel):
"""single Person, can go on many years
@ -182,7 +159,7 @@ class PersonExpedition(TroggleModel):
slugfield = models.SlugField(max_length=50,blank=True, null=True) # 2022 to be used in future
is_guest = models.BooleanField(default=False)
nickname = models.CharField(max_length=100,blank=True, null=True)
nickname = models.CharField(max_length=100,blank=True, null=True) # removbe this
class Meta:
ordering = ('-expedition',)
@ -208,11 +185,4 @@ class PersonExpedition(TroggleModel):
survexblocks = [personrole.survexblock for personrole in self.survexpersonrole_set.all() ]
return sum([survexblock.legslength for survexblock in set(survexblocks)])
# would prefer to return actual person trips so we could link to first and last ones
# def day_min(self):
# res = self.persontrip_set.aggregate(day_min=Min("expeditionday__date"))
# return res["day_min"]
# def day_max(self):
# res = self.persontrip_set.all().aggregate(day_max=models.Max("expeditionday__date"))
# return res["day_max"]

View File

@ -58,23 +58,33 @@ def notablepersons(request):
def expedition(request, expeditionname):
'''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.
This is not as difficult to understand as it looks. Yes there are many levels of indirection, with multiple trees being traversed at the same time. And the Django special syntax
makes this hard for normal Python programmers.
Remember that 'personexpedition__expedition' is interpreted by Django to mean the
'expedition' object which is connected by a foreign key to the 'personexpedition'
object, which is a field of the PersonTrip object:
PersonTrip.objects.filter(personexpedition__expedition=expo)
Queries are not evaluated to hit the database until a result is actually used. Django
does lazy evaluation.
'''
try:
expo = Expedition.objects.get(year=int(expeditionname))
except:
message = f'Expedition not found - database apparently empty, you probably need to do a full re-import of all data.'
return render(request, 'errors/generic.html', {'message': message})
if request.user.is_authenticated:
if "reload" in request.GET:
this_expedition = Expedition.objects.get(year=int(expeditionname))
# Need to delete the existing 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()
for entry in entries:
#print(f'! - delete entry: "{entry}"')
entry.delete()
entries = this_expedition.logbookentry_set.all()
import_logbook(year=this_expedition.year)
logged_in = True
if "reload" in request.GET:
expo.logbookentry_set.all().delete()
import_logbook(year=expo.year)
else:
logged_in = False
ts = TROG['pagecache']['expedition'] # not much use unless single user!
if settings.CACHEDPAGES:
nexpos = len( TROG['pagecache']['expedition'])
@ -83,33 +93,41 @@ def expedition(request, expeditionname):
#print('! - expo {expeditionanme} using cached page')
return render(request,'expedition.html', { **ts[expeditionname], 'logged_in' : logged_in })
try:
this_expedition = Expedition.objects.get(year=int(expeditionname))
except:
message = f'Expedition not found - database apparently empty, you probably need to do a full re-import of all data.'
return render(request, 'errors/generic.html', {'message': message})
expeditions = Expedition.objects.all() # top menu only, evaluated only when template renders
expeditions = Expedition.objects.all()
personexpeditiondays = [ ]
dateditems = list(this_expedition.logbookentry_set.all()) + list(this_expedition.survexblock_set.all())
entries = expo.logbookentry_set.all()
blocks = expo.survexblock_set.all()
dateditems = list(entries) + list(blocks) # evaluates the Django query and hits db
dates = sorted(set([item.date for item in dateditems]))
for personexpedition in this_expedition.personexpedition_set.all():
allpersontrips = PersonTrip.objects.filter(personexpedition__expedition=expo)
personexpeditiondays = [ ]
for personexpedition in expo.personexpedition_set.all():
expotrips = allpersontrips.filter(personexpedition=personexpedition) # lazy
expoblocks = blocks.filter(survexpersonrole__personexpedition=personexpedition)
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))
personentries = expotrips.filter(logbook_entry__date=date) # lazy
personblocks = set(expoblocks.filter(date = date)) # not lazy
pcell = {}
pcell["personentries"] = personentries
pcell["survexblocks"] = personblocks
if issunday := (date.weekday() == 6): # WALRUS
pcell["sunday"] = issunday
prow.append(pcell)
personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
ts[expeditionname] = {'expedition': this_expedition, 'expeditions':expeditions,
ts[expeditionname] = {'expedition': expo,
'expeditions':expeditions,
'personexpeditiondays':personexpeditiondays, 'settings':settings,
'dateditems': dateditems, 'dates':dates}
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 } )
class Expeditions_tsvListView(ListView):

View File

@ -55,12 +55,19 @@ table.expeditionpersonlist td.persondayactivity
width:4em;
font-size:70%;
padding:0 0 0 0;
background-color:#ddd;
}
table.expeditionpersonlist td.persondayactivity-nothing
{
background-color:#bbb;
}
table.expeditionpersonlist td.persondayactivity-sunday
{
background-color:#aad;
}
table.expeditionpersonlist a
{
text-decoration:none;

View File

@ -60,7 +60,9 @@ def stash_data_issue(parser=None, message=None, url=None, sb=None):
dataissues.append((parser, message, url, sb))
def store_data_issues():
"""Take the stash and store it permanently in the database instead"""
"""Take the stash and store it permanently in the database instead
use BULK creation here !"""
global dataissues
print(f" - Storing {len(dataissues)} Data Issues into database")

View File

@ -27,10 +27,10 @@
{% endif %}
<p><b>At a single glance:</b> The table shows all expo cavers and their recorded trips.
The columns are the date in the month (July or August), with a
The columns are the date in the month (July, August or September), Sundays in blue, with a
"<b>T</b>" for a logbook entry, and
an "<b>S</b>" for a survey trip. The colours are the same for people on the same trip. </p>
<!-- Colours are set in trog3.css and there can be 3 trips a day of each type-->
an "<b>S</b>" for a survey trip. The colours of the "<b>T</b>" and "<b>S</b>" are the same for people on the same trip. </p>
<!-- Colours are set in trog3.css and there can be 10 trips a day of each type-->
<table class="expeditionpersonlist">
<tr>
@ -44,20 +44,24 @@ an "<b>S</b>" for a survey trip. The colours are the same for people on the sam
{% for personexpeditionday in personexpeditiondays %}
<tr>
<td><a href="{{ personexpeditionday.personexpedition.get_absolute_url }}">{{personexpeditionday.personexpedition.person|safe}}</a></td>
{% for persondayactivities in personexpeditionday.personrow %}
{% for activities in personexpeditionday.personrow %}
{% if persondayactivities.persontrips or persondayactivities.survexblocks %}
{% if activities.personentries or activities.survexblocks %}
<td class="persondayactivity">
{% for persontrip in persondayactivities.persontrips %}
<a href="{{persontrip.logbook_entry.get_absolute_url}}" class="dayindexlog-{{persontrip.logbook_entry.DayIndex}}">T</a>
{% for personentry in activities.personentries %}
<a href="{{personentry.logbook_entry.get_absolute_url}}" class="dayindexlog-{{personentry.logbook_entry.DayIndex}}">T</a>
{% endfor %}
<br/>
{% for survexblock in persondayactivities.survexblocks %}
{% for survexblock in activities.survexblocks %}
<a href="{% url "svx" survexblock.survexfile.path %}" class="dayindexsurvex-{{survexblock.DayIndex}}">S</a>
{% endfor %}
</td>
{% else %}
{% if activities.sunday %}
<td class="persondayactivity-sunday">
{% else %}
<td class="persondayactivity-nothing">
{% endif %}
</td>
{% endif %}