forked from expo/troggle
[svn] latest hacking for various statistics
This commit is contained in:
parent
60dcb82ef6
commit
e4496e4cd8
@ -13,6 +13,7 @@ getcontext().prec=2 #use 2 significant figures for decimal calculations
|
|||||||
|
|
||||||
from models_survex import *
|
from models_survex import *
|
||||||
|
|
||||||
|
|
||||||
def get_related_by_wikilinks(wiki_text):
|
def get_related_by_wikilinks(wiki_text):
|
||||||
found=re.findall(settings.QM_PATTERN,wiki_text)
|
found=re.findall(settings.QM_PATTERN,wiki_text)
|
||||||
res=[]
|
res=[]
|
||||||
@ -120,6 +121,14 @@ class Person(TroggleModel):
|
|||||||
def bisnotable(self):
|
def bisnotable(self):
|
||||||
return self.notability() > Decimal(1)/Decimal(3)
|
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]
|
||||||
|
|
||||||
#def Sethref(self):
|
#def Sethref(self):
|
||||||
#if self.last_name:
|
#if self.last_name:
|
||||||
#self.href = self.first_name.lower() + "_" + self.last_name.lower()
|
#self.href = self.first_name.lower() + "_" + self.last_name.lower()
|
||||||
@ -151,11 +160,11 @@ class PersonExpedition(TroggleModel):
|
|||||||
|
|
||||||
def GetPersonroles(self):
|
def GetPersonroles(self):
|
||||||
res = [ ]
|
res = [ ]
|
||||||
for personrole in self.personrole_set.order_by('survex_block'):
|
for personrole in self.personrole_set.order_by('survexblock'):
|
||||||
if res and res[-1]['survexpath'] == personrole.survex_block.survexpath:
|
if res and res[-1]['survexpath'] == personrole.survexblock.survexpath:
|
||||||
res[-1]['roles'] += ", " + str(personrole.role)
|
res[-1]['roles'] += ", " + str(personrole.role)
|
||||||
else:
|
else:
|
||||||
res.append({'date':personrole.survex_block.date, 'survexpath':personrole.survex_block.survexpath, 'roles':str(personrole.role)})
|
res.append({'date':personrole.survexblock.date, 'survexpath':personrole.survexblock.survexpath, 'roles':str(personrole.role)})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -178,6 +187,9 @@ class PersonExpedition(TroggleModel):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return urlparse.urljoin(settings.URL_ROOT, reverse('personexpedition',kwargs={'first_name':self.person.first_name,'last_name':self.person.last_name,'year':self.expedition.year}))
|
return urlparse.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)])
|
||||||
|
|
||||||
#
|
#
|
||||||
# Single parsed entry from Logbook
|
# Single parsed entry from Logbook
|
||||||
|
@ -46,6 +46,22 @@ class SurvexFile(models.Model):
|
|||||||
self.survexdirectory = survexdirectory
|
self.survexdirectory = survexdirectory
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
class SurvexEquate(models.Model):
|
||||||
|
cave = models.ForeignKey('Cave', blank=True, null=True)
|
||||||
|
|
||||||
|
class SurvexStation(models.Model):
|
||||||
|
name = models.CharField(max_length=20)
|
||||||
|
block = models.ForeignKey('SurvexBlock')
|
||||||
|
equate = models.ForeignKey('SurvexEquate', blank=True, null=True)
|
||||||
|
|
||||||
|
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()
|
||||||
#
|
#
|
||||||
# Single SurvexBlock
|
# Single SurvexBlock
|
||||||
#
|
#
|
||||||
@ -62,6 +78,7 @@ class SurvexBlock(models.Model):
|
|||||||
begin_char = models.IntegerField() # code for where in the survex data files this block sits
|
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
|
survexpath = models.CharField(max_length=200) # the path for the survex stations
|
||||||
refscandir = models.CharField(max_length=100)
|
refscandir = models.CharField(max_length=100)
|
||||||
|
totalleglength = models.FloatField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('id',)
|
ordering = ('id',)
|
||||||
@ -78,6 +95,17 @@ class SurvexBlock(models.Model):
|
|||||||
res.append({'person':personrole.personexpedition.person, 'expeditionyear':personrole.personexpedition.expedition.year, 'roles':str(personrole.role)})
|
res.append({'person':personrole.personexpedition.person, 'expeditionyear':personrole.personexpedition.expedition.year, 'roles':str(personrole.role)})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def MakeSurvexStation(self, name):
|
||||||
|
ssl = self.survexstation_set.filter(name=name)
|
||||||
|
if ssl:
|
||||||
|
assert len(ssl) == 1
|
||||||
|
return ssl[0]
|
||||||
|
ss = SurvexStation(name=name, block=self)
|
||||||
|
ss.save()
|
||||||
|
return ss
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SurvexTitle(models.Model):
|
class SurvexTitle(models.Model):
|
||||||
survexblock = models.ForeignKey('SurvexBlock')
|
survexblock = models.ForeignKey('SurvexBlock')
|
||||||
title = models.CharField(max_length=200)
|
title = models.CharField(max_length=200)
|
||||||
@ -87,7 +115,7 @@ class SurvexTitle(models.Model):
|
|||||||
# member of a SurvexBlock
|
# member of a SurvexBlock
|
||||||
#
|
#
|
||||||
class PersonRole(models.Model):
|
class PersonRole(models.Model):
|
||||||
survex_block = models.ForeignKey('SurvexBlock')
|
survexblock = models.ForeignKey('SurvexBlock')
|
||||||
|
|
||||||
ROLE_CHOICES = (
|
ROLE_CHOICES = (
|
||||||
('insts','Instruments'),
|
('insts','Instruments'),
|
||||||
@ -109,6 +137,6 @@ class PersonRole(models.Model):
|
|||||||
persontrip = models.ForeignKey('PersonTrip', blank=True, null=True)
|
persontrip = models.ForeignKey('PersonTrip', blank=True, null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.person) + " - " + unicode(self.survex_block) + " - " + unicode(self.nrole)
|
return unicode(self.person) + " - " + unicode(self.survexblock) + " - " + unicode(self.nrole)
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,9 +7,6 @@ from core.models import QM, Photo, LogbookEntry, Cave
|
|||||||
import re, urlparse
|
import re, urlparse
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
url_root=settings.URL_ROOT
|
|
||||||
if settings.URL_ROOT.endswith('/'):
|
|
||||||
url_root=settings.URL_ROOT[:-1]
|
|
||||||
|
|
||||||
|
|
||||||
@register.filter()
|
@register.filter()
|
||||||
@ -93,7 +90,7 @@ def wiki_to_html_short(value, autoescape=None):
|
|||||||
[[QM:C204-1999-24]]
|
[[QM:C204-1999-24]]
|
||||||
If the QM does not exist, the function will return a link for creating it.
|
If the QM does not exist, the function will return a link for creating it.
|
||||||
"""
|
"""
|
||||||
qmdict={'urlroot':url_root,'cave':matchobj.groups()[2],'year':matchobj.groups()[1],'number':matchobj.groups()[3]}
|
qmdict={'urlroot':settings.URL_ROOT,'cave':matchobj.groups()[2],'year':matchobj.groups()[1],'number':matchobj.groups()[3]}
|
||||||
try:
|
try:
|
||||||
qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
|
qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
|
||||||
found_by__date__year = qmdict['year'],
|
found_by__date__year = qmdict['year'],
|
||||||
@ -146,13 +143,13 @@ def wiki_to_html_short(value, autoescape=None):
|
|||||||
value = re.sub(photoSrcPattern,photoSrcRepl, value, re.DOTALL)
|
value = re.sub(photoSrcPattern,photoSrcRepl, value, re.DOTALL)
|
||||||
|
|
||||||
#make cave links
|
#make cave links
|
||||||
value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%s/cave/\1/">\1</a>' % url_root, value, re.DOTALL)
|
value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%scave/\1/">\1</a>' % settings.URL_ROOT, value, re.DOTALL)
|
||||||
#make people links
|
#make people links
|
||||||
value = re.sub("\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%s/person/\1/">\2</a>' % url_root, value, re.DOTALL)
|
value = re.sub("\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%sperson/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
|
||||||
#make subcave links
|
#make subcave links
|
||||||
value = re.sub("\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%s/subcave/\1/">\2</a>' % url_root, value, re.DOTALL)
|
value = re.sub("\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%ssubcave/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
|
||||||
#make cavedescription links
|
#make cavedescription links
|
||||||
value = re.sub("\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%s/cavedescription/\1/">\2</a>' % url_root, value, re.DOTALL)
|
value = re.sub("\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%scavedescription/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry
|
from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry
|
||||||
|
import troggle.core.models as models
|
||||||
import troggle.settings as settings
|
import troggle.settings as settings
|
||||||
from django.db import models
|
import django.db.models
|
||||||
from troggle.parsers.logbooks import LoadLogbookForExpedition
|
from troggle.parsers.logbooks import LoadLogbookForExpedition
|
||||||
from troggle.parsers.people import GetPersonExpeditionNameLookup
|
from troggle.parsers.people import GetPersonExpeditionNameLookup
|
||||||
from troggle.core.forms import PersonForm
|
from troggle.core.forms import PersonForm
|
||||||
@ -13,7 +14,7 @@ from troggle.alwaysUseRequestContext import render_response
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@models.permalink #this allows the nice get_absolute_url syntax we are using
|
@django.db.models.permalink #this allows the nice get_absolute_url syntax we are using
|
||||||
|
|
||||||
def getNotablePersons():
|
def getNotablePersons():
|
||||||
notablepersons = []
|
notablepersons = []
|
||||||
@ -27,7 +28,7 @@ def personindex(request):
|
|||||||
persons = Person.objects.all()
|
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
|
# From what I can tell, "persons" seems to be the table rows, while "personss" is the table columns. - AC 16 Feb 09
|
||||||
personss = [ ]
|
personss = [ ]
|
||||||
ncols = 5
|
ncols = 4
|
||||||
nc = (len(persons) + ncols - 1) / ncols
|
nc = (len(persons) + ncols - 1) / ncols
|
||||||
for i in range(ncols):
|
for i in range(ncols):
|
||||||
personss.append(persons[i * nc: (i + 1) * nc])
|
personss.append(persons[i * nc: (i + 1) * nc])
|
||||||
@ -76,9 +77,9 @@ def GetPersonChronology(personexpedition):
|
|||||||
a.setdefault("persontrips", [ ]).append(persontrip)
|
a.setdefault("persontrips", [ ]).append(persontrip)
|
||||||
|
|
||||||
for personrole in personexpedition.personrole_set.all():
|
for personrole in personexpedition.personrole_set.all():
|
||||||
a = res.setdefault(personrole.survex_block.date, { })
|
a = res.setdefault(personrole.survexblock.date, { })
|
||||||
b = a.setdefault("personroles", { })
|
b = a.setdefault("personroles", { })
|
||||||
survexpath = personrole.survex_block.survexpath
|
survexpath = personrole.survexblock.survexpath
|
||||||
|
|
||||||
if b.get(survexpath):
|
if b.get(survexpath):
|
||||||
b[survexpath] += ", " + str(personrole.nrole)
|
b[survexpath] += ", " + str(personrole.nrole)
|
||||||
@ -135,3 +136,20 @@ def personForm(request,pk):
|
|||||||
form=PersonForm(instance=person)
|
form=PersonForm(instance=person)
|
||||||
return render_response(request,'personform.html', {'form':form,})
|
return render_response(request,'personform.html', {'form':form,})
|
||||||
|
|
||||||
|
|
||||||
|
def experimental(request):
|
||||||
|
legsbyexpo = [ ]
|
||||||
|
for expedition in Expedition.objects.all():
|
||||||
|
survexblocks = expedition.survexblock_set.all()
|
||||||
|
survexlegs = [ ]
|
||||||
|
survexleglength = 0.0
|
||||||
|
for survexblock in survexblocks:
|
||||||
|
survexlegs.extend(survexblock.survexleg_set.all())
|
||||||
|
survexleglength += survexblock.totalleglength
|
||||||
|
legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength}))
|
||||||
|
legsbyexpo.reverse()
|
||||||
|
|
||||||
|
survexlegs = models.SurvexLeg.objects.all()
|
||||||
|
totalsurvexlength = sum([survexleg.tape for survexleg in survexlegs])
|
||||||
|
return render_response(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
|
||||||
|
|
||||||
|
@ -113,8 +113,7 @@ class SvxForm(forms.Form):
|
|||||||
def svx(request, survex_file):
|
def svx(request, survex_file):
|
||||||
# get the basic data from the file given in the URL
|
# get the basic data from the file given in the URL
|
||||||
dirname = os.path.split(survex_file)[0]
|
dirname = os.path.split(survex_file)[0]
|
||||||
if dirname:
|
dirname += "/"
|
||||||
dirname += "/"
|
|
||||||
nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
outputtype = "normal"
|
outputtype = "normal"
|
||||||
form = SvxForm({'filename':survex_file, 'dirname':dirname, 'datetime':nowtime, 'outputtype':outputtype})
|
form = SvxForm({'filename':survex_file, 'dirname':dirname, 'datetime':nowtime, 'outputtype':outputtype})
|
||||||
|
@ -106,7 +106,10 @@ if __name__ == "__main__":
|
|||||||
reset()
|
reset()
|
||||||
elif "survex" in sys.argv:
|
elif "survex" in sys.argv:
|
||||||
management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex
|
management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex
|
||||||
# import_survex()
|
import_survex()
|
||||||
|
|
||||||
|
elif "logbooks" in sys.argv:
|
||||||
|
management.call_command('syncdb', interactive=False) # this sets the path so that import settings works in import_survex
|
||||||
import_logbooks()
|
import_logbooks()
|
||||||
else:
|
else:
|
||||||
print "Do 'python databaseReset.py reset'"
|
print "Do 'python databaseReset.py reset'"
|
||||||
|
@ -278,7 +278,10 @@ div#content {
|
|||||||
|
|
||||||
.toolbarlinks
|
.toolbarlinks
|
||||||
{
|
{
|
||||||
padding:0;
|
padding:5px;
|
||||||
|
background-color:#ff9;
|
||||||
|
text-align:center;
|
||||||
|
font-weight:bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
|
@ -40,6 +40,8 @@ def GetTripPersons(trippeople, expedition, logtime_underground):
|
|||||||
if mul:
|
if mul:
|
||||||
author = personyear
|
author = personyear
|
||||||
if not author:
|
if not author:
|
||||||
|
if not res:
|
||||||
|
return None, None
|
||||||
author = res[-1][0]
|
author = res[-1][0]
|
||||||
return res, author
|
return res, author
|
||||||
|
|
||||||
@ -75,6 +77,10 @@ noncaveplaces = [ "Journey", "Loser Plateau" ]
|
|||||||
def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_underground):
|
def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_underground):
|
||||||
""" saves a logbook entry and related persontrips """
|
""" saves a logbook entry and related persontrips """
|
||||||
trippersons, author = GetTripPersons(trippeople, expedition, logtime_underground)
|
trippersons, author = GetTripPersons(trippeople, expedition, logtime_underground)
|
||||||
|
if not author:
|
||||||
|
print "skipping logentry", title
|
||||||
|
return
|
||||||
|
|
||||||
# tripCave = GetTripCave(place)
|
# tripCave = GetTripCave(place)
|
||||||
#
|
#
|
||||||
lplace = place.lower()
|
lplace = place.lower()
|
||||||
@ -135,15 +141,20 @@ def Parselogwikitxt(year, expedition, txt):
|
|||||||
def Parseloghtmltxt(year, expedition, txt):
|
def Parseloghtmltxt(year, expedition, txt):
|
||||||
tripparas = re.findall("<hr\s*/>([\s\S]*?)(?=<hr)", txt)
|
tripparas = re.findall("<hr\s*/>([\s\S]*?)(?=<hr)", txt)
|
||||||
for trippara in tripparas:
|
for trippara in tripparas:
|
||||||
s = re.match('''(?x)\s*(?:<a\s+id="(.*?)"\s*/>)?
|
|
||||||
\s*<div\s+class="tripdate"\s*(?:id="(.*?)")?>(.*?)</div>
|
s = re.match('''(?x)(?:\s*<div\sclass="tripdate"\sid=".*?">.*?</div>\s*<p>)? # second date
|
||||||
|
\s*(?:<a\s+id="(.*?)"\s*/>)?
|
||||||
|
\s*<div\s+class="tripdate"\s*(?:id="(.*?)")?>(.*?)</div>(?:<p>)?
|
||||||
\s*<div\s+class="trippeople">\s*(.*?)</div>
|
\s*<div\s+class="trippeople">\s*(.*?)</div>
|
||||||
\s*<div\s+class="triptitle">\s*(.*?)</div>
|
\s*<div\s+class="triptitle">\s*(.*?)</div>
|
||||||
([\s\S]*?)
|
([\s\S]*?)
|
||||||
\s*(?:<div\s+class="timeug">\s*(.*?)</div>)?
|
\s*(?:<div\s+class="timeug">\s*(.*?)</div>)?
|
||||||
\s*$
|
\s*$
|
||||||
''', trippara)
|
''', trippara)
|
||||||
assert s, trippara
|
if not s:
|
||||||
|
print "can't parse: ", trippara # this is 2007 which needs editing
|
||||||
|
#assert s, trippara
|
||||||
|
continue
|
||||||
|
|
||||||
tripid, tripid1, tripdate, trippeople, triptitle, triptext, tu = s.groups()
|
tripid, tripid1, tripdate, trippeople, triptitle, triptext, tu = s.groups()
|
||||||
ldate = ParseDate(tripdate.strip(), year)
|
ldate = ParseDate(tripdate.strip(), year)
|
||||||
@ -240,7 +251,7 @@ def Parseloghtml03(year, expedition, txt):
|
|||||||
|
|
||||||
yearlinks = [
|
yearlinks = [
|
||||||
("2008", "2008/2008logbook.txt", Parselogwikitxt),
|
("2008", "2008/2008logbook.txt", Parselogwikitxt),
|
||||||
("2007", "2007/2007logbook.txt", Parselogwikitxt),
|
("2007", "2007/logbook.html", Parseloghtmltxt),
|
||||||
("2006", "2006/logbook/logbook_06.txt", Parselogwikitxt),
|
("2006", "2006/logbook/logbook_06.txt", Parselogwikitxt),
|
||||||
("2005", "2005/logbook.html", Parseloghtmltxt),
|
("2005", "2005/logbook.html", Parseloghtmltxt),
|
||||||
("2004", "2004/logbook.html", Parseloghtmltxt),
|
("2004", "2004/logbook.html", Parseloghtmltxt),
|
||||||
@ -326,6 +337,7 @@ def LoadLogbookForExpedition(expedition):
|
|||||||
if lyear == year:
|
if lyear == year:
|
||||||
break
|
break
|
||||||
fin = open(os.path.join(expowebbase, lloc))
|
fin = open(os.path.join(expowebbase, lloc))
|
||||||
|
print "opennning", lloc
|
||||||
txt = fin.read().decode("latin1")
|
txt = fin.read().decode("latin1")
|
||||||
fin.close()
|
fin.close()
|
||||||
parsefunc(year, expedition, txt)
|
parsefunc(year, expedition, txt)
|
||||||
|
@ -6,77 +6,156 @@ import re
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def LoadSurvexLineLeg(survexblock, stardata, sline, comment):
|
||||||
|
ls = sline.lower().split()
|
||||||
|
ssfrom = survexblock.MakeSurvexStation(ls[stardata["from"]])
|
||||||
|
ssto = survexblock.MakeSurvexStation(ls[stardata["to"]])
|
||||||
|
|
||||||
|
survexleg = models.SurvexLeg(block=survexblock, stationfrom=ssfrom, stationto=ssto)
|
||||||
|
if stardata["type"] == "normal":
|
||||||
|
survexleg.tape = float(ls[stardata["tape"]])
|
||||||
|
lclino = ls[stardata["clino"]]
|
||||||
|
lcompass = ls[stardata["compass"]]
|
||||||
|
if lclino == "up":
|
||||||
|
survexleg.compass = 0.0
|
||||||
|
survexleg.clino = 90.0
|
||||||
|
elif lclino == "down":
|
||||||
|
survexleg.compass = 0.0
|
||||||
|
survexleg.clino = -90.0
|
||||||
|
elif lclino == "-" or lclino == "level":
|
||||||
|
survexleg.compass = float(lcompass)
|
||||||
|
survexleg.clino = -90.0
|
||||||
|
else:
|
||||||
|
assert re.match("[\d\-+.]+$", lcompass), ls
|
||||||
|
assert re.match("[\d\-+.]+$", lclino) and lclino != "-", ls
|
||||||
|
survexleg.compass = float(lcompass)
|
||||||
|
survexleg.clino = float(lclino)
|
||||||
|
|
||||||
|
# only save proper legs
|
||||||
|
survexleg.save()
|
||||||
|
|
||||||
|
itape = stardata.get("tape")
|
||||||
|
if itape:
|
||||||
|
survexblock.totalleglength += float(ls[itape])
|
||||||
|
survexblock.save()
|
||||||
|
|
||||||
|
def LoadSurvexEquate(survexblock, sline):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def LoadSurvexLinePassage(survexblock, stardata, sline, comment):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
stardatadefault = { "type":"normal", "t":"leg", "from":0, "to":1, "tape":2, "compass":3, "clino":4 }
|
||||||
|
stardataparamconvert = { "length":"tape", "bearing":"compass", "gradient":"clino" }
|
||||||
|
|
||||||
def RecursiveLoad(survexblock, survexfile, fin, textlines):
|
def RecursiveLoad(survexblock, survexfile, fin, textlines):
|
||||||
iblankbegins = 0
|
iblankbegins = 0
|
||||||
text = [ ]
|
text = [ ]
|
||||||
|
stardata = stardatadefault
|
||||||
teammembers = [ ]
|
teammembers = [ ]
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
svxline = fin.readline().decode("latin1")
|
svxline = fin.readline().decode("latin1")
|
||||||
if not svxline:
|
if not svxline:
|
||||||
return
|
return
|
||||||
textlines.append(svxline)
|
textlines.append(svxline)
|
||||||
mstar = re.match('\s*\*(\w+)\s+(.*?)\s*(?:;.*)?$', svxline)
|
|
||||||
|
|
||||||
#;ref.: 2008#18
|
# break the line at the comment
|
||||||
mref = re.match('.*?ref.*?(\d+#\d+)', svxline)
|
sline, comment = re.match("([^;]*?)\s*(?:;\s*(.*))?\n?$", svxline.strip()).groups()
|
||||||
|
|
||||||
|
# detect ref line pointing to the scans directory
|
||||||
|
mref = comment and re.match('.*?ref.*?(\d+)\s*#\s*(\d+)', comment)
|
||||||
if mref:
|
if mref:
|
||||||
survexblock.refscandir = mref.group(1)
|
survexblock.refscandir = "%s/%s%%23%s" % (mref.group(1), mref.group(1), mref.group(2))
|
||||||
survexblock.save()
|
survexblock.save()
|
||||||
|
continue
|
||||||
if mstar:
|
|
||||||
cmd, line = mstar.groups()
|
if not sline:
|
||||||
|
continue
|
||||||
if re.match("include$(?i)", cmd):
|
|
||||||
includepath = os.path.join(os.path.split(survexfile.path)[0], re.sub("\.svx$", "", line))
|
# detect the star command
|
||||||
includesurvexfile = models.SurvexFile(path=includepath, cave=survexfile.cave)
|
mstar = re.match('\s*\*(\w+)\s*(.*?)\s*(?:;.*)?$', sline)
|
||||||
includesurvexfile.save()
|
if not mstar:
|
||||||
includesurvexfile.SetDirectory()
|
if "from" in stardata:
|
||||||
if includesurvexfile.exists():
|
LoadSurvexLineLeg(survexblock, stardata, sline, comment)
|
||||||
fininclude = includesurvexfile.OpenFile()
|
elif stardata["type"] == "passage":
|
||||||
RecursiveLoad(survexblock, includesurvexfile, fininclude, textlines)
|
LoadSurvexLinePassage(survexblock, stardata, sline, comment)
|
||||||
|
continue
|
||||||
elif re.match("begin$(?i)", cmd):
|
|
||||||
if line:
|
# detect the star command
|
||||||
name = line.lower()
|
cmd, line = mstar.groups()
|
||||||
survexblockdown = models.SurvexBlock(name=name, begin_char=fin.tell(), parent=survexblock, survexpath=survexblock.survexpath+"."+name, cave=survexblock.cave, survexfile=survexfile)
|
if re.match("include$(?i)", cmd):
|
||||||
survexblockdown.save()
|
includepath = os.path.join(os.path.split(survexfile.path)[0], re.sub("\.svx$", "", line))
|
||||||
textlinesdown = [ ]
|
includesurvexfile = models.SurvexFile(path=includepath, cave=survexfile.cave)
|
||||||
RecursiveLoad(survexblockdown, survexfile, fin, textlinesdown)
|
includesurvexfile.save()
|
||||||
else:
|
includesurvexfile.SetDirectory()
|
||||||
iblankbegins += 1
|
if includesurvexfile.exists():
|
||||||
|
fininclude = includesurvexfile.OpenFile()
|
||||||
elif re.match("end$(?i)", cmd):
|
RecursiveLoad(survexblock, includesurvexfile, fininclude, textlines)
|
||||||
if iblankbegins:
|
|
||||||
iblankbegins -= 1
|
elif re.match("begin$(?i)", cmd):
|
||||||
else:
|
if line:
|
||||||
survexblock.text = "".join(textlines)
|
name = line.lower()
|
||||||
survexblock.save()
|
survexblockdown = models.SurvexBlock(name=name, begin_char=fin.tell(), parent=survexblock, survexpath=survexblock.survexpath+"."+name, cave=survexblock.cave, survexfile=survexfile, totalleglength=0.0)
|
||||||
return
|
survexblockdown.save()
|
||||||
|
textlinesdown = [ ]
|
||||||
elif re.match("date$(?i)", cmd):
|
RecursiveLoad(survexblockdown, survexfile, fin, textlinesdown)
|
||||||
if len(line) == 10:
|
|
||||||
survexblock.date = re.sub("\.", "-", line)
|
|
||||||
expeditions = models.Expedition.objects.filter(year=line[:4])
|
|
||||||
if expeditions:
|
|
||||||
survexblock.expedition = expeditions[0]
|
|
||||||
|
|
||||||
elif re.match("team$(?i)", cmd):
|
|
||||||
mteammember = re.match("(Insts|Notes|Tape|Dog|Useless|Pics|Helper|Disto|Consultant)\s+(.*)$(?i)", line)
|
|
||||||
if mteammember:
|
|
||||||
for tm in re.split(" and | / |, | & | \+ |^both$|^none$(?i)", mteammember.group(2)):
|
|
||||||
if tm:
|
|
||||||
personexpedition = survexblock.expedition and GetPersonExpeditionNameLookup(survexblock.expedition).get(tm.lower())
|
|
||||||
if (personexpedition, tm) not in teammembers:
|
|
||||||
teammembers.append((personexpedition, tm))
|
|
||||||
personrole = models.PersonRole(survex_block=survexblock, nrole=mteammember.group(1).lower(), personexpedition=personexpedition, personname=tm)
|
|
||||||
personrole.save()
|
|
||||||
|
|
||||||
elif cmd == "title":
|
|
||||||
survextitle = models.SurvexTitle(survexblock=survexblock, title=line.strip('"'), cave=survexblock.cave)
|
|
||||||
survextitle.save()
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
assert cmd.lower() in [ "sd", "equate", "include", "units", "entrance", "fix", "data", "flags", "title", "export", "instrument", "calibrate", ], (cmd, line, survexblock)
|
iblankbegins += 1
|
||||||
|
|
||||||
|
elif re.match("end$(?i)", cmd):
|
||||||
|
if iblankbegins:
|
||||||
|
iblankbegins -= 1
|
||||||
|
else:
|
||||||
|
survexblock.text = "".join(textlines)
|
||||||
|
survexblock.save()
|
||||||
|
return
|
||||||
|
|
||||||
|
elif re.match("date$(?i)", cmd):
|
||||||
|
if len(line) == 10:
|
||||||
|
survexblock.date = re.sub("\.", "-", line)
|
||||||
|
expeditions = models.Expedition.objects.filter(year=line[:4])
|
||||||
|
if expeditions:
|
||||||
|
survexblock.expedition = expeditions[0]
|
||||||
|
|
||||||
|
elif re.match("team$(?i)", cmd):
|
||||||
|
mteammember = re.match("(Insts|Notes|Tape|Dog|Useless|Pics|Helper|Disto|Consultant)\s+(.*)$(?i)", line)
|
||||||
|
if mteammember:
|
||||||
|
for tm in re.split(" and | / |, | & | \+ |^both$|^none$(?i)", mteammember.group(2)):
|
||||||
|
if tm:
|
||||||
|
personexpedition = survexblock.expedition and GetPersonExpeditionNameLookup(survexblock.expedition).get(tm.lower())
|
||||||
|
if (personexpedition, tm) not in teammembers:
|
||||||
|
teammembers.append((personexpedition, tm))
|
||||||
|
personrole = models.PersonRole(survexblock=survexblock, nrole=mteammember.group(1).lower(), personexpedition=personexpedition, personname=tm)
|
||||||
|
if personexpedition:
|
||||||
|
personrole.person=personexpedition.person
|
||||||
|
personrole.save()
|
||||||
|
|
||||||
|
elif cmd == "title":
|
||||||
|
survextitle = models.SurvexTitle(survexblock=survexblock, title=line.strip('"'), cave=survexblock.cave)
|
||||||
|
survextitle.save()
|
||||||
|
|
||||||
|
elif cmd == "data":
|
||||||
|
ls = line.lower().split()
|
||||||
|
stardata = { "type":ls[0] }
|
||||||
|
for i in range(0, len(ls)):
|
||||||
|
stardata[stardataparamconvert.get(ls[i], ls[i])] = i - 1
|
||||||
|
if ls[0] in ["normal", "cartesian", "nosurvey"]:
|
||||||
|
assert "from" in stardata, line
|
||||||
|
assert "to" in stardata, line
|
||||||
|
elif ls[0] == "default":
|
||||||
|
stardata = stardatadefault
|
||||||
|
else:
|
||||||
|
assert ls[0] == "passage", line
|
||||||
|
|
||||||
|
elif cmd == "equate":
|
||||||
|
LoadSurvexEquate(survexblock, sline)
|
||||||
|
|
||||||
|
else:
|
||||||
|
assert cmd.lower() in [ "sd", "equate", "include", "units", "entrance", "fix", "data", "flags", "title", "export", "instrument", "calibrate", ], (cmd, line, survexblock)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def ReloadSurvexCave(survex_cave):
|
def ReloadSurvexCave(survex_cave):
|
||||||
@ -89,7 +168,7 @@ def ReloadSurvexCave(survex_cave):
|
|||||||
survexfile.save()
|
survexfile.save()
|
||||||
survexfile.SetDirectory()
|
survexfile.SetDirectory()
|
||||||
|
|
||||||
survexblockroot = models.SurvexBlock(name="root", survexpath="caves", begin_char=0, cave=cave, survexfile=survexfile)
|
survexblockroot = models.SurvexBlock(name="root", survexpath="caves", begin_char=0, cave=cave, survexfile=survexfile, totalleglength=0.0)
|
||||||
survexblockroot.save()
|
survexblockroot.save()
|
||||||
fin = survexfile.OpenFile()
|
fin = survexfile.OpenFile()
|
||||||
textlines = [ ]
|
textlines = [ ]
|
||||||
@ -97,6 +176,7 @@ def ReloadSurvexCave(survex_cave):
|
|||||||
survexblockroot.text = "".join(textlines)
|
survexblockroot.text = "".join(textlines)
|
||||||
survexblockroot.save()
|
survexblockroot.save()
|
||||||
|
|
||||||
|
|
||||||
def LoadAllSurvexBlocks():
|
def LoadAllSurvexBlocks():
|
||||||
caves = models.Cave.objects.all()
|
caves = models.Cave.objects.all()
|
||||||
for cave in caves:
|
for cave in caves:
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="toolbarlinks">
|
<div class="toolbarlinks">
|
||||||
<a href="{% url survexcaveslist %}">Cave Survex</a> |
|
<a href="{% url survexcaveslist %}">All Cave Survex</a> |
|
||||||
<a href="{% url survexcavessingle 161 %}">161</a> |
|
<a href="{% url survexcavessingle 161 %}">161</a> |
|
||||||
<a href="{% url survexcavessingle 204 %}">204</a> |
|
<a href="{% url survexcavessingle 204 %}">204</a> |
|
||||||
<a href="{% url survexcavessingle 258 %}">258</a> |
|
<a href="{% url survexcavessingle 258 %}">258</a> |
|
||||||
|
@ -52,4 +52,18 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3 id="surveysdone">Surveys done</h3>
|
||||||
|
<table class="survextrip">
|
||||||
|
<tr><th>Date</th><th>Name</th><th>Length</th></tr>
|
||||||
|
{% for survexblock in expedition.survexblock_set.all %}
|
||||||
|
<tr>
|
||||||
|
<td>{{survexblock.date}}</td>
|
||||||
|
<td><a href="{% url svx survexblock.survexfile.path %}">{{survexblock.name}}</a></td>
|
||||||
|
<td>{{survexblock.totalleglength}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
26
templates/experimental.html
Normal file
26
templates/experimental.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load wiki_markup %}
|
||||||
|
{% load link %}
|
||||||
|
|
||||||
|
{% block title %}Experimental{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h1>Expo Experimental</h1>
|
||||||
|
|
||||||
|
<p>Number of survey legs: {{nsurvexlegs}}, total length: {{totalsurvexlength}}</p>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th>Year</th><th>Surveys</th><th>Survey Legs</th><th>Total length</th></tr>
|
||||||
|
{% for legs in legsbyexpo %}
|
||||||
|
<tr>
|
||||||
|
<td>{{legs.0.year}}</td>
|
||||||
|
<td>{{legs.0.survexblock_set.all|length}}</td>
|
||||||
|
<td>{{legs.1.nsurvexlegs}}</td>
|
||||||
|
<td>{{legs.1.survexleglength}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -11,8 +11,8 @@
|
|||||||
{% for person in notablepersons %}
|
{% for person in notablepersons %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td>
|
<td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td>
|
||||||
<td><a href="{{ person.personexpedition_set.all.0.get_absolute_url }}">{{ person.personexpedition_set.all.0.expedition.year }}</a></td>
|
<td><a href="{{ person.first.get_absolute_url }}">{{ person.first.expedition.year }}</a></td>
|
||||||
<td><a href="{{ person.personexpedition_set.latest.get_absolute_url }}">{{ person.personexpedition_set.latest.expedition.year }}</a></td>
|
<td><a href="{{ person.last.get_absolute_url }}">{{ person.last.expedition.year }}</a></td>
|
||||||
<td>{{person.notability}}</td>
|
<td>{{person.notability}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -26,12 +26,13 @@
|
|||||||
<td>
|
<td>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Person</th><th>First</th><th>Last</th></tr>
|
<tr><th>Person</th><th>First</th><th>Last</th><th>Surveyed length</th></tr>
|
||||||
{% for person in persons %}
|
{% for person in persons %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td>
|
<td><a href="{{ person.get_absolute_url }}">{{person|wiki_to_html_short}}</a></td>
|
||||||
<td><a href="{{ person.personexpedition_set.all.0.get_absolute_url }}">{{person.personexpedition_set.all.0.expedition.year}}</a></td>
|
<td><a href="{{ person.first.get_absolute_url }}">{{person.first.expedition.year}}</a></td>
|
||||||
<td><a href="{{ person.personexpedition_set.latest.get_absolute_url }}">{{person.personexpedition_set.latest.expedition.year}}</a></td>
|
<td><a href="{{ person.last.get_absolute_url }}">{{person.last.expedition.year}}</a></td>
|
||||||
|
<td>{{ person.surveyedleglength }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<h3 id="T_{{survexdirectory.primarysurvexfile.path}}">{{survexdirectory.path}}</h3>
|
<h3 id="T_{{survexdirectory.primarysurvexfile.path}}">{{survexdirectory.path}}</h3>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Survex file</th><th>Block</th><th>Date</th><th>Explorers</th><th>Titles</th><th>Scans</th></tr>
|
<tr><th>Survex file</th><th>Block</th><th>Date</th><th>Explorers</th><th>length</th><th>Titles</th><th>Scans</th></tr>
|
||||||
|
|
||||||
{% for survexfile in survexdirectory.survexfile_set.all %}
|
{% for survexfile in survexdirectory.survexfile_set.all %}
|
||||||
<tr>
|
<tr>
|
||||||
@ -57,6 +57,8 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
<td>{{survexblock.totalleglength}}</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
{% for survextitle in survexblock.survextitle_set.all %}
|
{% for survextitle in survexblock.survextitle_set.all %}
|
||||||
{{survextitle.title}}
|
{{survextitle.title}}
|
||||||
@ -65,7 +67,7 @@
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
{% if survexblock.refscandir %}
|
{% if survexblock.refscandir %}
|
||||||
<b>{{survexblock.refscandir}}</b>
|
<b><a href="/survey_scans/{{survexblock.refscandir}}/">scans</a></b>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<p><a href="#cdir">caves with subdirectories</a> | <a href="#cmult">caves with multiple files</a> | <a href="#csing">caves with single files</a></p>
|
<p><a href="#cdir">caves with subdirectories</a> | <a href="#cmult">caves with multiple files</a> | <a href="#csing">caves with single files</a></p>
|
||||||
|
|
||||||
|
<h3><a href="/survexfile/all.svx">Link to all.svx for processing</a></h3>
|
||||||
|
|
||||||
<h2 id="cdir">Caves with subdirectories</h2>
|
<h2 id="cdir">Caves with subdirectories</h2>
|
||||||
|
|
||||||
{% for subdircave, cavefiles, subsurvdirs in subdircaves %}
|
{% for subdircave, cavefiles, subsurvdirs in subdircaves %}
|
||||||
|
18
urls.py
18
urls.py
@ -72,21 +72,24 @@ urlpatterns = patterns('',
|
|||||||
(r'^accounts/', include('registration.urls')),
|
(r'^accounts/', include('registration.urls')),
|
||||||
(r'^profiles/', include('profiles.urls')),
|
(r'^profiles/', include('profiles.urls')),
|
||||||
|
|
||||||
|
|
||||||
# (r'^personform/(.*)$', personForm),
|
# (r'^personform/(.*)$', personForm),
|
||||||
|
|
||||||
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
|
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
|
||||||
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
|
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
|
||||||
|
|
||||||
|
|
||||||
url(r'^survexblock/(.+)$', views_caves.survexblock, name="survexblock"),
|
url(r'^survexblock/(.+)$', views_caves.survexblock, name="survexblock"),
|
||||||
url(r'^survexfile/(?P<survex_file>.*?)\.svx$', views_survex.svx, name="svx"),
|
url(r'^survexfile/(?P<survex_file>.*?)\.svx$', views_survex.svx, name="svx"),
|
||||||
url(r'^survexfile/(?P<survex_file>.*)\.3d$', views_survex.threed, name="threed"),
|
url(r'^survexfile/(?P<survex_file>.*?)\.3d$', views_survex.threed, name="threed"),
|
||||||
url(r'^survexfile/caves$', views_survex.survexcaveslist, name="survexcaveslist"),
|
url(r'^survexfile/(?P<survex_file>.*?)\.log$', views_survex.svxraw),
|
||||||
|
url(r'^survexfile/(?P<survex_file>.*?)\.err$', views_survex.err),
|
||||||
|
|
||||||
|
|
||||||
|
url(r'^survexfile/caves/$', views_survex.survexcaveslist, name="survexcaveslist"),
|
||||||
url(r'^survexfile/caves/(?P<survex_cave>.*)$', views_survex.survexcavesingle, name="survexcavessingle"),
|
url(r'^survexfile/caves/(?P<survex_cave>.*)$', views_survex.survexcavesingle, name="survexcavessingle"),
|
||||||
url(r'^survexfileraw/(?P<survex_file>.*?)\.svx$', views_survex.svxraw, name="svxraw"),
|
url(r'^survexfileraw/(?P<survex_file>.*?)\.svx$', views_survex.svxraw, name="svxraw"),
|
||||||
|
|
||||||
(r'^survex/(?P<survex_file>.*)\.log$', log),
|
|
||||||
(r'^survex/(?P<survex_file>.*)\.err$', err),
|
|
||||||
|
|
||||||
(r'^survey_files/listdir/(?P<path>.*)$', view_surveys.listdir),
|
(r'^survey_files/listdir/(?P<path>.*)$', view_surveys.listdir),
|
||||||
(r'^survey_files/download/(?P<path>.*)$', view_surveys.download),
|
(r'^survey_files/download/(?P<path>.*)$', view_surveys.download),
|
||||||
@ -100,5 +103,8 @@ urlpatterns = patterns('',
|
|||||||
(r'^photos/(?P<path>.*)$', 'django.views.static.serve',
|
(r'^photos/(?P<path>.*)$', 'django.views.static.serve',
|
||||||
{'document_root': settings.PHOTOS_ROOT, 'show_indexes':True}),
|
{'document_root': settings.PHOTOS_ROOT, 'show_indexes':True}),
|
||||||
|
|
||||||
#url(r'^trip_report/?$',views_other.tripreport,name="trip_report")
|
# for those silly ideas
|
||||||
|
url(r'^experimental.*$', views_logbooks.experimental, name="experimental"),
|
||||||
|
|
||||||
|
#url(r'^trip_report/?$',views_other.tripreport,name="trip_report")
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user