django 1.8.19

This commit is contained in:
Philip Sargent 2020-06-16 22:16:48 +01:00
parent adc43324f3
commit b153fafa9f
7 changed files with 602 additions and 33 deletions

View File

@ -123,6 +123,9 @@ copy this over the installed version of django on your machine:
$ cd troggle
$ sudo cp django-patch/html_parser.py /usr/local/lib/python3.8/dist-packages/django/utils/
or, if you have django installed by person arthe rthan by system:
$ sudo cp django-patch/html_parser.py /home/philip/.local/lib/python3.8/site-packages/django/utils/
or
$ cp django-patch/html_parser.py ~/.local/lib/python3.8/site-packages/django/utils/
if you didn't use sudo when installing everything using pip.

View File

@ -126,10 +126,10 @@ class SurvexBlock(models.Model):
survexscansfolder = models.ForeignKey("SurvexScansFolder", null=True)
#refscandir = models.CharField(max_length=100)
legsall = models.IntegerField(null=True) # summary data for this block
legssplay = models.IntegerField(null=True) # summary data for this block
legssurfc = models.IntegerField(null=True) # summary data for this block
totalleglength = models.FloatField(null=True)
legsall = models.IntegerField() # summary data for this block
legssplay = models.IntegerField() # summary data for this block
legssurfc = models.IntegerField() # summary data for this block
totalleglength = models.FloatField()
class Meta:
ordering = ('id',)

226
models.py Normal file
View File

@ -0,0 +1,226 @@
import string
import os
import datetime
import logging
import re
from subprocess import call
from urllib.parse import urljoin
from decimal import Decimal, getcontext
getcontext().prec=2 #use 2 significant figures for decimal calculations
import settings
from django.db import models
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
from django.core.urlresolvers import reverse
from django.template import Context, loader
import troggle.core.models_survex
def get_related_by_wikilinks(wiki_text):
found=re.findall(settings.QM_PATTERN,wiki_text)
res=[]
for wikilink in found:
qmdict={'urlroot':settings.URL_ROOT,'cave':wikilink[2],'year':wikilink[1],'number':wikilink[3]}
try:
cave_slugs = models_caves.CaveSlug.objects.filter(cave__kataster_number = qmdict['cave'])
qm=QM.objects.get(found_by__cave_slug__in = cave_slugs,
found_by__date__year = qmdict['year'],
number = qmdict['number'])
res.append(qm)
except QM.DoesNotExist:
print(('fail on '+str(wikilink)))
return res
try:
logging.basicConfig(level=logging.DEBUG,
filename=settings.LOGFILE,
filemode='w')
except:
# Opening of file for writing is going to fail currently, so decide it doesn't matter for now
pass
#This class is for adding fields and methods which all of our models will have.
class TroggleModel(models.Model):
new_since_parsing = models.BooleanField(default=False, editable=False)
non_public = models.BooleanField(default=False)
def object_name(self):
return self._meta.object_name
def get_admin_url(self):
return urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk))
class Meta:
abstract = True
class DataIssue(TroggleModel):
date = models.DateTimeField(auto_now_add=True, blank=True)
parser = models.CharField(max_length=50, blank=True, null=True)
message = models.CharField(max_length=400, blank=True, null=True)
class Meta:
ordering = ['date']
def __str__(self):
return "%s - %s" % (self.parser, self.message)
#
# single Expedition, usually seen by year
#
class Expedition(TroggleModel):
year = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=100)
def __str__(self):
return self.year
class Meta:
ordering = ('-year',)
get_latest_by = 'year'
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:
assert len(expeditiondays) == 1
return expeditiondays[0]
res = ExpeditionDay(expedition=self, date=date)
res.save()
return res
def day_min(self):
res = self.expeditionday_set.all()
return res and res[0] or None
def day_max(self):
res = self.expeditionday_set.all()
return res and res[len(res) - 1] or None
class ExpeditionDay(TroggleModel):
expedition = models.ForeignKey("Expedition")
date = models.DateField()
class Meta:
ordering = ('date',)
def GetPersonTrip(self, personexpedition):
personexpeditions = self.persontrip_set.filter(expeditionday=self)
return personexpeditions and personexpeditions[0] or None
class Person(TroggleModel):
"""single Person, can go on many years
"""
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
fullname = models.CharField(max_length=200)
is_vfho = models.BooleanField(help_text="VFHO is the Vereines für Höhlenkunde in Obersteier, a nearby Austrian caving club.", default=False)
mug_shot = models.CharField(max_length=100, blank=True,null=True)
blurb = models.TextField(blank=True,null=True)
#href = models.CharField(max_length=200)
orderref = models.CharField(max_length=200) # for alphabetic
user = models.OneToOneField(User, null=True, blank=True)
def get_absolute_url(self):
return urljoin(settings.URL_ROOT,reverse('person',kwargs={'first_name':self.first_name,'last_name':self.last_name}))
class Meta:
verbose_name_plural = "People"
ordering = ('orderref',) # "Wookey" makes too complex for: ('last_name', 'first_name')
def __str__(self):
if self.last_name:
return "%s %s" % (self.first_name, self.last_name)
return self.first_name
def notability(self):
notability = Decimal(0)
max_expo_val = 0
max_expo_year = Expedition.objects.all().aggregate(models.Max('year'))
max_expo_val = int(max_expo_year['year__max']) + 1
for personexpedition in self.personexpedition_set.all():
if not personexpedition.is_guest:
print((personexpedition.expedition.year))
notability += Decimal(1) / (max_expo_val - int(personexpedition.expedition.year))
return notability
def bisnotable(self):
return self.notability() > Decimal(1)/Decimal(3)
def surveyedleglength(self):
return sum([personexpedition.surveyedleglength() for personexpedition in self.personexpedition_set.all()])
def first(self):
return self.personexpedition_set.order_by('-expedition')[0]
def last(self):
return self.personexpedition_set.order_by('expedition')[0]
class PersonExpedition(TroggleModel):
"""Person's attendance to one Expo
"""
expedition = models.ForeignKey(Expedition)
person = models.ForeignKey(Person)
slugfield = models.SlugField(max_length=50,blank=True,null=True)
is_guest = models.BooleanField(default=False)
COMMITTEE_CHOICES = (
('leader','Expo leader'),
('medical','Expo medical officer'),
('treasurer','Expo treasurer'),
('sponsorship','Expo sponsorship coordinator'),
('research','Expo research coordinator'),
)
expo_committee_position = models.CharField(blank=True,null=True,choices=COMMITTEE_CHOICES,max_length=200)
nickname = models.CharField(max_length=100,blank=True,null=True)
def GetPersonroles(self):
res = [ ]
for personrole in self.personrole_set.order_by('survexblock'):
if res and res[-1]['survexpath'] == personrole.survexblock.survexpath:
res[-1]['roles'] += ", " + str(personrole.role)
else:
res.append({'date':personrole.survexblock.date, 'survexpath':personrole.survexblock.survexpath, 'roles':str(personrole.role)})
return res
class Meta:
ordering = ('-expedition',)
#order_with_respect_to = 'expedition'
def __str__(self):
return "%s: (%s)" % (self.person, self.expedition)
#why is the below a function in personexpedition, rather than in person? - AC 14 Feb 09
def name(self):
if self.nickname:
return "%s (%s) %s" % (self.person.first_name, self.nickname, self.person.last_name)
if self.person.last_name:
return "%s %s" % (self.person.first_name, self.person.last_name)
return self.person.first_name
def get_absolute_url(self):
return urljoin(settings.URL_ROOT, reverse('personexpedition',kwargs={'first_name':self.person.first_name,'last_name':self.person.last_name,'year':self.expedition.year}))
def surveyedleglength(self):
survexblocks = [personrole.survexblock for personrole in self.personrole_set.all() ]
return sum([survexblock.totalleglength 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"]

239
models_survex.py Normal file
View File

@ -0,0 +1,239 @@
import os
from urllib.parse import urljoin
import re
from django.db import models
from django.conf import settings
from django.core.urlresolvers import reverse
###########################################################
# These will allow browsing and editing of the survex data
###########################################################
# Needs to add:
# Equates
# reloading
class SurvexDirectory(models.Model):
path = models.CharField(max_length=200)
cave = models.ForeignKey('Cave', blank=True, null=True)
primarysurvexfile = models.ForeignKey('SurvexFile', related_name='primarysurvexfile', blank=True, null=True)
# could also include files in directory but not referenced
class Meta:
ordering = ('id',)
class SurvexFile(models.Model):
path = models.CharField(max_length=200)
survexdirectory = models.ForeignKey("SurvexDirectory", blank=True, null=True)
cave = models.ForeignKey('Cave', blank=True, null=True)
class Meta:
ordering = ('id',)
def exists(self):
fname = os.path.join(settings.SURVEX_DATA, self.path + ".svx")
return os.path.isfile(fname)
def OpenFile(self):
fname = os.path.join(settings.SURVEX_DATA, self.path + ".svx")
return open(fname)
def SetDirectory(self):
dirpath = os.path.split(self.path)[0]
survexdirectorylist = SurvexDirectory.objects.filter(cave=self.cave, path=dirpath)
if survexdirectorylist:
self.survexdirectory = survexdirectorylist[0]
else:
survexdirectory = SurvexDirectory(path=dirpath, cave=self.cave, primarysurvexfile=self)
survexdirectory.save()
self.survexdirectory = survexdirectory
self.save()
class SurvexEquate(models.Model):
cave = models.ForeignKey('Cave', blank=True, null=True)
class SurvexStationLookUpManager(models.Manager):
def lookup(self, name):
blocknames, sep, stationname = name.rpartition(".")
return self.get(block = SurvexBlock.objects.lookup(blocknames),
name__iexact = stationname)
class SurvexStation(models.Model):
name = models.CharField(max_length=100)
block = models.ForeignKey('SurvexBlock')
equate = models.ForeignKey('SurvexEquate', blank=True, null=True)
objects = SurvexStationLookUpManager()
x = models.FloatField(blank=True, null=True)
y = models.FloatField(blank=True, null=True)
z = models.FloatField(blank=True, null=True)
def path(self):
r = self.name
b = self.block
while True:
if b.name:
r = b.name + "." + r
if b.parent:
b = b.parent
else:
return r
# class SurvexLeg(models.Model):
# block = models.ForeignKey('SurvexBlock')
# #title = models.ForeignKey('SurvexTitle')
# stationfrom = models.ForeignKey('SurvexStation', related_name='stationfrom')
# stationto = models.ForeignKey('SurvexStation', related_name='stationto')
# tape = models.FloatField()
# compass = models.FloatField()
# clino = models.FloatField()
class SurvexLeg():
tape = 0.0
compass = 0.0
clino = 0.0
#
# Single SurvexBlock
#
class SurvexBlockLookUpManager(models.Manager):
def lookup(self, name):
if name == "":
blocknames = []
else:
blocknames = name.split(".")
block = SurvexBlock.objects.get(parent=None, survexfile__path=settings.SURVEX_TOPNAME)
for blockname in blocknames:
block = SurvexBlock.objects.get(parent=block, name__iexact=blockname)
return block
class SurvexBlock(models.Model):
objects = SurvexBlockLookUpManager()
name = models.CharField(max_length=100)
parent = models.ForeignKey('SurvexBlock', blank=True, null=True)
# text = models.TextField()
cave = models.ForeignKey('Cave', blank=True, null=True)
date = models.DateField(blank=True, null=True)
expeditionday = models.ForeignKey("ExpeditionDay", null=True)
expedition = models.ForeignKey('Expedition', blank=True, null=True)
survexfile = models.ForeignKey("SurvexFile", blank=True, null=True)
# begin_char = models.IntegerField() # code for where in the survex data files this block sits
survexpath = models.CharField(max_length=200) # the path for the survex stations
survexscansfolder = models.ForeignKey("SurvexScansFolder", null=True)
#refscandir = models.CharField(max_length=100)
legsall = models.IntegerField(null=True) # summary data for this block
legssplay = models.IntegerField(null=True) # summary data for this block
legssurfc = models.IntegerField(null=True) # summary data for this block
totalleglength = models.FloatField(null=True)
class Meta:
ordering = ('id',)
def isSurvexBlock(self): # Function used in templates
return True
def __str__(self):
return self.name and str(self.name) or 'no name'
def GetPersonroles(self):
res = [ ]
for personrole in self.personrole_set.order_by('personexpedition'):
if res and res[-1]['person'] == personrole.personexpedition.person:
res[-1]['roles'] += ", " + str(personrole.role)
else:
res.append({'person':personrole.personexpedition.person, 'expeditionyear':personrole.personexpedition.expedition.year, 'roles':str(personrole.role)})
return res
def MakeSurvexStation(self, name):
ssl = self.survexstation_set.filter(name=name)
if ssl:
assert len(ssl) == 1
return ssl[0]
#print name
ss = SurvexStation(name=name, block=self)
#ss.save()
return ss
def DayIndex(self):
return list(self.expeditionday.survexblock_set.all()).index(self)
class SurvexTitle(models.Model):
survexblock = models.ForeignKey('SurvexBlock')
title = models.CharField(max_length=200)
cave = models.ForeignKey('Cave', blank=True, null=True)
#
# member of a SurvexBlock
#
ROLE_CHOICES = (
('insts','Instruments'),
('dog','Other'),
('notes','Notes'),
('pics','Pictures'),
('tape','Tape measure'),
('useless','Useless'),
('helper','Helper'),
('disto','Disto'),
('consultant','Consultant'),
)
class SurvexPersonRole(models.Model):
survexblock = models.ForeignKey('SurvexBlock')
nrole = models.CharField(choices=ROLE_CHOICES, max_length=200, blank=True, null=True)
# increasing levels of precision
personname = models.CharField(max_length=100)
person = models.ForeignKey('Person', blank=True, null=True)
personexpedition = models.ForeignKey('PersonExpedition', blank=True, null=True)
persontrip = models.ForeignKey('PersonTrip', blank=True, null=True)
expeditionday = models.ForeignKey("ExpeditionDay", null=True)
def __str__(self):
return str(self.person) + " - " + str(self.survexblock) + " - " + str(self.nrole)
class SurvexScansFolder(models.Model):
fpath = models.CharField(max_length=200)
walletname = models.CharField(max_length=200)
class Meta:
ordering = ('walletname',)
def get_absolute_url(self):
return urljoin(settings.URL_ROOT, reverse('surveyscansfolder', kwargs={"path":re.sub("#", "%23", self.walletname)}))
def __str__(self):
return str(self.walletname) + " (Survey Scans Folder)"
class SurvexScanSingle(models.Model):
ffile = models.CharField(max_length=200)
name = models.CharField(max_length=200)
survexscansfolder = models.ForeignKey("SurvexScansFolder", null=True)
class Meta:
ordering = ('name',)
def get_absolute_url(self):
return urljoin(settings.URL_ROOT, reverse('surveyscansingle', kwargs={"path":re.sub("#", "%23", self.survexscansfolder.walletname), "file":self.name}))
def __str__(self):
return "Survey Scan Image: " + str(self.name) + " in " + str(self.survexscansfolder)
class TunnelFile(models.Model):
tunnelpath = models.CharField(max_length=200)
tunnelname = models.CharField(max_length=200)
bfontcolours = models.BooleanField(default=False)
survexscansfolders = models.ManyToManyField("SurvexScansFolder")
survexscans = models.ManyToManyField("SurvexScanSingle")
survexblocks = models.ManyToManyField("SurvexBlock")
tunnelcontains = models.ManyToManyField("TunnelFile") # case when its a frame type
filesize = models.IntegerField(default=0)
npaths = models.IntegerField(default=0)
survextitles = models.ManyToManyField("SurvexTitle")
class Meta:
ordering = ('tunnelpath',)

109
requirements-works1.7.4.txt Normal file
View File

@ -0,0 +1,109 @@
appdirs==1.4.3
apturl==0.5.2
astroid==2.4.1
attrs==19.3.0
Automat==0.8.0
blinker==1.4
catfish==1.4.13
certifi==2019.11.28
chardet==3.0.4
Click==7.0
cloud-init==20.1
colorama==0.4.3
command-not-found==0.3
configobj==5.0.6
constantly==15.1.0
coverage==5.1
cryptography==2.8
cupshelpers==1.0
dbus-python==1.2.16
defer==1.0.6
distlib==0.3.0
distro==1.4.0
distro-info===0.23ubuntu1
Django==1.7
django-extensions==2.2.9
django-registration==2.0
django-tinymce==2.0.1
docutils==0.16
entrypoints==0.3
filelock==3.0.12
httplib2==0.14.0
hyperlink==19.0.0
idna==2.8
importlib-metadata==1.5.0
incremental==16.10.1
isort==4.3.21
Jinja2==2.10.1
jsonpatch==1.22
jsonpointer==2.0
jsonschema==3.2.0
keyring==18.0.1
language-selector==0.1
launchpadlib==1.10.13
lazr.restfulclient==0.14.2
lazr.uri==1.0.3
lazy-object-proxy==1.4.3
lightdm-gtk-greeter-settings==1.2.2
macaroonbakery==1.3.1
MarkupSafe==1.1.0
mccabe==0.6.1
menulibre==2.2.1
more-itertools==4.2.0
mugshot==0.4.2
netifaces==0.10.4
oauthlib==3.1.0
olefile==0.46
onboard==1.4.1
pexpect==4.6.0
Pillow==7.1.2
protobuf==3.6.1
psutil==5.5.1
pyasn1==0.4.2
pyasn1-modules==0.2.1
pycairo==1.16.2
pycups==1.9.73
Pygments==2.3.1
PyGObject==3.36.0
PyHamcrest==1.9.0
PyJWT==1.7.1
pylint==2.5.2
pymacaroons==0.13.0
PyNaCl==1.3.0
pyOpenSSL==19.0.0
pyRFC3339==1.1
pyrsistent==0.15.5
pyserial==3.4
python-apt==2.0.0
python-dateutil==2.7.3
python-debian===0.1.36ubuntu1
pytz==2019.3
pyxdg==0.26
PyYAML==5.3.1
reportlab==3.5.34
requests==2.22.0
requests-unixsocket==0.2.0
roman==2.0.0
rope==0.17.0
SecretStorage==2.3.1
service-identity==18.1.0
sgt-launcher==0.2.5
simplejson==3.16.0
six==1.14.0
ssh-import-id==5.10
systemd-python==234
toml==0.10.1
Twisted==18.9.0
ubuntu-advantage-tools==20.3
ubuntu-drivers-common==0.0.0
ufw==0.36
unattended-upgrades==0.1
Unidecode==1.1.1
urllib3==1.25.8
virtualenv==20.0.17
wadllib==1.3.3
wrapt==1.12.1
xcffib==0.8.1
xkit==0.0.0
zipp==1.0.0
zope.interface==4.7.1

View File

@ -0,0 +1,7 @@
Django==1.8.19
django-extensions==2.2.9
django-registration==2.0
Pillow==7.1.0
six==1.15.0
sqlparse==0.3.1
Unidecode==1.1.0

View File

@ -45,6 +45,20 @@
<a href="{% url "expedition" 2020 %}">Expo2020</a> |
<a href="/admin/">Django admin</a>
<br>
<a id="cuccLink" href="https://camcaving.uk">cucc server</a> |
<a id="expoWebsiteLink" href="http://expo.survex.com">expo server</a> |
<a href="{% url "frontpage" %}">tasks to do </a> |
<a id="cavesLink" href="{% url "caveindex" %}">caves</a> |
<a id="caversLink" href="{% url "personindex" %}">cavers</a> |
<a id="expeditionsLink" href="{% url "expeditions" %}">all expeditions</a> |
<a href="{% url "stats" %}">statistics</a> |
<a id="cuccLink" href="{% url "controlpanel" %}">import/export data</a>
</div>
<div id="nav">
@ -77,36 +91,7 @@
</div>
<div class="footer">
<ul class="dropdown" id="footerLinks">
<li><a href="#">External links</a>
<ul class="sub_menu">
<li><a id="cuccLink" href="https://camcaving.uk">CUCC website</a></li>
<li><a id="expoWebsiteLink" href="http://expo.survex.com">Expedition website</a></li>
</ul>
</li>
<li><a href="{% url "frontpage" %}">Troggle front page</a></li>
<li><a id="cavesLink" href="{% url "caveindex" %}">caves</a></li>
<li><a id="caversLink" href="{% url "personindex" %}">cavers</a></li>
<li><a href="#">expeditions</a>
<ul class="sub_menu">
<li><a id="expeditionsLink" href="{{ expedition.objects.latest.get_absolute_url }}">newest</a></li>
<li><a id="expeditionsLink" href="{% url "expeditions" %}">list all</a></li>
</ul>
</li>
<li><a href="#">diversions</a>
<ul class="sub_menu">
<li><a href="{% url "stats" %}">statistics</a></li>
</ul>
</li>
<li><a href="#">admin</a>
<ul class="sub_menu">
<li><a id="cuccLink" href="{% url "controlpanel" %}">Import / export data</a></li>
<li><a id="expoWebsiteLink" href="{{ settings.URL_ROOT }}admin">Troggle administration pages</a></li>
</ul>
<li class="toggleMenu"><a href="#">hide menu</a></li>
</ul>
</div>
</body>
</html>