diff --git a/troggle/__init__.py b/troggle/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/troggle/alwaysUseRequestContext.py b/troggle/alwaysUseRequestContext.py
deleted file mode 100644
index b587b5283..000000000
--- a/troggle/alwaysUseRequestContext.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# this is the snippet from http://www.djangosnippets.org/snippets/3/
-
-from django.shortcuts import render_to_response
-from django.template import RequestContext
-
-def render_response(req, *args, **kwargs):
- kwargs['context_instance'] = RequestContext(req)
- return render_to_response(*args, **kwargs)
\ No newline at end of file
diff --git a/troggle/databaseReset.py b/troggle/databaseReset.py
deleted file mode 100644
index f2c3b51b6..000000000
--- a/troggle/databaseReset.py
+++ /dev/null
@@ -1,58 +0,0 @@
-import os
-import time
-import settings
-os.environ['PYTHONPATH'] = settings.PYTHON_PATH
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-from django.core import management
-from django.db import connection
-from django.contrib.auth.models import User
-
-def reload_db():
- cursor = connection.cursor()
- cursor.execute("drop database %s" % settings.DATABASE_NAME)
- cursor.execute("create database %s" % settings.DATABASE_NAME)
- cursor.execute("ALTER DATABASE %s CHARACTER SET=utf8" % settings.DATABASE_NAME)
- cursor.execute("USE %s" % settings.DATABASE_NAME)
- management.call_command('syncdb')
- user = User.objects.create_user('m', 'm@m.com', 'm')
- user.is_staff = True
- user.is_superuser = True
- user.save()
-
-def make_dirs():
- """Make directories that troggle requires"""
- if not os.path.isdir(settings.PHOTOS_ROOT):
- os.mkdir(settings.PHOTOS_ROOT)
-
-def import_cavetab():
- import parsers.cavetab
- parsers.cavetab.LoadCaveTab(logfile=settings.LOGFILE)
-
-def import_people():
- import parsers.people
- parsers.people.LoadPersonsExpos()
-
-def import_logbooks():
- settings.LOGFILE.write('\nBegun importing logbooks at ' + time.asctime() +'\n'+'-'*60)
- import parsers.logbooks
- parsers.logbooks.LoadLogbooks()
-
-def import_survex():
- import parsers.survex
- parsers.survex.LoadAllSurvexBlocks()
-
-def import_QMs():
- import parsers.QMs
-
-def import_surveys():
- import parsers.surveys
-
-def reset():
- reload_db()
- make_dirs()
- import_cavetab()
- import_people()
- import_logbooks()
- import_survex()
- import_QMs()
- import_surveys()
\ No newline at end of file
diff --git a/troggle/expo/__init__.py b/troggle/expo/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/troggle/expo/admin.py b/troggle/expo/admin.py
deleted file mode 100644
index f2717d920..000000000
--- a/troggle/expo/admin.py
+++ /dev/null
@@ -1,93 +0,0 @@
-from troggle.expo.models import *
-from django.contrib import admin
-from django.forms import ModelForm
-import django.forms as forms
-from expo.forms import LogbookEntryForm
-#from troggle.reversion.admin import VersionAdmin #django-reversion version control
-
-#overriding admin save so we have the new since parsing field
-class TroggleModelAdmin(admin.ModelAdmin):
- def save_model(self, request, obj, form, change):
- obj.new_since_parsing=True
- obj.save()
-
-class RoleInline(admin.TabularInline):
- model = PersonRole
- extra = 4
-
-class SurvexBlockAdmin(TroggleModelAdmin):
- inlines = (RoleInline,)
-
-class ScannedImageInline(admin.TabularInline):
- model = ScannedImage
- extra = 4
-
-class SurveyAdmin(TroggleModelAdmin):
- inlines = (ScannedImageInline,)
- search_fields = ('expedition__year','wallet_number')
-
-class QMInline(admin.TabularInline):
- model=QM
- extra = 4
-
-class PhotoInline(admin.TabularInline):
- model = Photo
- exclude = ['is_mugshot', ]
- extra = 1
-
-class PersonTripInline(admin.TabularInline):
- model = PersonTrip
- exclude = ['persontrip_next','Delete']
- extra = 1
-
-#class LogbookEntryAdmin(VersionAdmin):
-class LogbookEntryAdmin(TroggleModelAdmin):
- prepopulated_fields = {'slug':("title",)}
- search_fields = ('title','expedition__year')
- inlines = (PersonTripInline, PhotoInline)
- form = LogbookEntryForm
- #inlines = (QMInline,) #doesn't work because QM has two foreignkeys to Logbookentry- need workaround
-
-class PersonExpeditionInline(admin.TabularInline):
- model = PersonExpedition
- extra = 1
-
-
-
-class PersonAdmin(TroggleModelAdmin):
- search_fields = ('first_name','last_name')
- inlines = (PersonExpeditionInline,)
-
-class QMAdmin(TroggleModelAdmin):
- search_fields = ('found_by__cave__kataster_number','number')
-
-class PersonExpeditionAdmin(TroggleModelAdmin):
- search_fields = ('person__first_name','expedition__year')
-
-class CaveAdmin(TroggleModelAdmin):
- search_fields = ('official_name','kataster_number','unofficial_number')
- #inlines = (QMInline,)
- extra = 4
-
-
-
-admin.site.register(Photo)
-admin.site.register(Subcave)
-admin.site.register(Cave, CaveAdmin)
-admin.site.register(Area)
-admin.site.register(OtherCaveName)
-admin.site.register(CaveAndEntrance)
-admin.site.register(SurveyStation)
-admin.site.register(Entrance)
-admin.site.register(SurvexBlock, SurvexBlockAdmin)
-admin.site.register(Expedition)
-admin.site.register(Person,PersonAdmin)
-admin.site.register(PersonRole)
-admin.site.register(PersonExpedition,PersonExpeditionAdmin)
-admin.site.register(Role)
-admin.site.register(LogbookEntry, LogbookEntryAdmin)
-admin.site.register(PersonTrip)
-admin.site.register(QM, QMAdmin)
-admin.site.register(Survey, SurveyAdmin)
-admin.site.register(ScannedImage)
-
diff --git a/troggle/expo/context.py b/troggle/expo/context.py
deleted file mode 100644
index 06215cea0..000000000
--- a/troggle/expo/context.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from django.conf import settings
-
-def settings_context(request):
- return { 'settings':settings }
\ No newline at end of file
diff --git a/troggle/expo/fileAbstraction.py b/troggle/expo/fileAbstraction.py
deleted file mode 100644
index 94b8b0c4b..000000000
--- a/troggle/expo/fileAbstraction.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import troggle.settings as settings
-import os
-import urllib
-
-def urljoin(x, y): return x + "/" + y
-
-def listdir(*path):
- try:
- strippedpath = [p for p in path if p]
- root = os.path.join(settings.FILES, *strippedpath )
- l = ""
- #l = root + "\n"
- isdir = os.path.isdir(root) #This seems to be required for os.path.isdir to work...
- #l += str(isdir) + "\n"
- for p in os.listdir(root):
- if os.path.isdir(os.path.join(root, p)):
- l += p + "/\n"
-
- elif os.path.isfile(os.path.join(root, p)):
- l += p + "\n"
- #Ignore non-files and non-directories
- return l
- except:
- if strippedpath:
- c = reduce(urljoin, strippedpath)
- else:
- c = ""
- c = c.replace("#", "%23")
- print "FILE: ", settings.FILES + "listdir/" + c
- return urllib.urlopen(settings.FILES + "listdir/" + c).read()
-
-def dirsAsList(*path):
- return [d for d in listdir(*path).split("\n") if len(d) > 0 and d[-1] == "/"]
-
-def filesAsList(*path):
- return [d for d in listdir(*path).split("\n") if len(d) > 0 and d[-1] != "/"]
-
-def readFile(*path):
- try:
- f = open(os.path.join(settings.FILES, *path))
- except:
- f = urllib.urlopen(settings.FILES + "download/" + reduce(urljoin, path))
- return f.read()
\ No newline at end of file
diff --git a/troggle/expo/forms.py b/troggle/expo/forms.py
deleted file mode 100644
index 2225b0c83..000000000
--- a/troggle/expo/forms.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from django.forms import ModelForm
-from models import Cave, Person, LogbookEntry
-import django.forms as forms
-from django.forms.formsets import formset_factory
-from django.contrib.admin.widgets import AdminDateWidget
-import string
-
-class CaveForm(ModelForm):
- class Meta:
- model = Cave
-
-class PersonForm(ModelForm):
- class Meta:
- model = Person
-
-class LogbookEntryForm(ModelForm):
- class Meta:
- model = LogbookEntry
-
- def wikiLinkHints(LogbookEntry=None):
- res = ["Please use the following wikilinks, which are related to this logbook entry:"]
-
- res.append(r'
QMs found:')
- for QM in LogbookEntry.instance.QMs_found.all():
- res.append(QM.wiki_link())
-
- res.append(r'
QMs ticked off:')
- for QM in LogbookEntry.instance.QMs_ticked_off.all():
- res.append(QM.wiki_link())
-
-# res.append(r'
People')
-# for persontrip in LogbookEntry.instance.persontrip_set.all():
-# res.append(persontrip.wiki_link())
-# res.append(r'
')
-
- return string.join(res, r'
')
-
- def __init__(self, *args, **kwargs):
- super(LogbookEntryForm, self).__init__(*args, **kwargs)
- self.fields['text'].help_text=self.wikiLinkHints()
\ No newline at end of file
diff --git a/troggle/expo/imagekit_specs.py b/troggle/expo/imagekit_specs.py
deleted file mode 100644
index 243cb9f76..000000000
--- a/troggle/expo/imagekit_specs.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from imagekit.specs import ImageSpec
-from imagekit import processors
-
-class ResizeThumb(processors.Resize):
- width = 100
- height = 75
- crop = True
-
-class ResizeDisplay(processors.Resize):
- width = 600
-
-class EnhanceThumb(processors.Adjustment):
- contrast = 1.2
- sharpness = 1.1
-
-class Thumbnail(ImageSpec):
- access_as = 'thumbnail_image'
- pre_cache = True
- processors = [ResizeThumb, EnhanceThumb]
-
-class Display(ImageSpec):
- increment_count = True
- processors = [ResizeDisplay]
diff --git a/troggle/expo/models.py b/troggle/expo/models.py
deleted file mode 100644
index 3472a01b9..000000000
--- a/troggle/expo/models.py
+++ /dev/null
@@ -1,615 +0,0 @@
-import urllib, urlparse, string, os, datetime
-from django.forms import ModelForm
-from django.db import models
-from django.contrib import admin
-from django.core.files.storage import FileSystemStorage
-from django.contrib.auth.models import User
-from django.contrib.contenttypes.models import ContentType
-from django.conf import settings
-from decimal import Decimal, getcontext
-from django.core.urlresolvers import reverse
-from imagekit.models import ImageModel
-getcontext().prec=2 #use 2 significant figures for decimal calculations
-
-from models_survex import *
-
-#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)
-
- def get_admin_url(self):
- return settings.URL_ROOT + "/admin/expo/" + self._meta.object_name.lower() + "/" + str(self.pk)
-
- class Meta:
- abstract = True
-
-class TroggleImageModel(ImageModel):
- new_since_parsing = models.BooleanField(default=False, editable=False)
-
- def get_admin_url(self):
- return settings.URL_ROOT + "/admin/expo/" + self._meta.object_name.lower() + "/" + str(self.pk)
-
- class Meta:
- abstract = True
-
-class Expedition(TroggleModel):
- year = models.CharField(max_length=20, unique=True)
- name = models.CharField(max_length=100)
- date_from = models.DateField(blank=True,null=True)
- date_to = models.DateField(blank=True,null=True)
-
- def __unicode__(self):
- return self.year
-
- class Meta:
- ordering = ('year',)
- get_latest_by = 'date_from'
-
- def get_absolute_url(self):
- #return settings.URL_ROOT + "/expedition/%s" % self.year
- return settings.URL_ROOT + reverse('expedition',args=[self.year])
-
-
- # lose these two functions (inelegant, and we may create a file with the dates that we can load from)
- def GuessDateFrom(self):
- try:
- return self.logbookentry_set.order_by('date')[0].date
- except IndexError:
- pass
-
- def GuessDateTo(self): # returns the date of the last logbook entry in the expedition
- try:
- return self.logbookentry_set.order_by('date')[-1].date
- except IndexError:
- pass
-
- def ListDays(self):
- if self.date_from and self.date_to:
- res=[]
- date=self.date_from
- while date <= self.date_to:
- res.append(date)
- date+=datetime.timedelta(days=1)
- return res
- elif self.GuessDateFrom() and self.GuessDateTo(): # if we don't have the real dates, try it with the dates taken from the earliest and latest logbook entries
- date=self.GuessDateFrom()
- while date <= self.GuessDateTo():
- res.append(date)
- date+=datetime.timedelta(days=1)
- return res
-
-
-
-
-class Person(TroggleModel):
- first_name = models.CharField(max_length=100)
- last_name = models.CharField(max_length=100)
- is_vfho = models.BooleanField(help_text="VFHO is the Vereines für Höhlenkunde in Obersteier, a nearby Austrian caving club.")
- 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
-
- #the below have been removed and made methods. I'm not sure what the b in bisnotable stands for. - AC 16 Feb
- #notability = models.FloatField() # for listing the top 20 people
- #bisnotable = models.BooleanField()
- user = models.OneToOneField(User, null=True, blank=True)
- def get_absolute_url(self):
- return settings.URL_ROOT + reverse('person',kwargs={'first_name':self.first_name,'last_name':self.last_name})
-
- class Meta:
- verbose_name_plural = "People"
- class Meta:
- ordering = ('orderref',) # "Wookey" makes too complex for: ('last_name', 'first_name')
-
- def __unicode__(self):
- if self.last_name:
- return "%s %s" % (self.first_name, self.last_name)
- return self.first_name
-
-# Below are no longer needed. Use {{ person.personexpedition_set.all.0.expedition }} for Firstexpedition, and {{ person.personexpedition_set.latest.expedition }} for Lastexpedition
- # these ought to be possible by piping through |min in the template, or getting the first of an ordered list
-# def Firstexpedition(self):
-# return self.personexpedition_set.order_by('expedition')[0]
-# def Lastexpedition(self):
-# return self.personexpedition_set.order_by('-expedition')[0]
-
- def notability(self):
- notability = Decimal(0)
- for personexpedition in self.personexpedition_set.all():
- if not personexpedition.is_guest:
- notability += Decimal(1) / (2012 - int(personexpedition.expedition.year))
- return notability
-
- def bisnotable(self):
- return self.notability() > Decimal(1)/Decimal(3)
-
- #def Sethref(self):
- #if self.last_name:
- #self.href = self.first_name.lower() + "_" + self.last_name.lower()
- #self.orderref = self.last_name + " " + self.first_name
- #else:
- # self.href = self.first_name.lower()
- #self.orderref = self.first_name
- #self.notability = 0.0 # set temporarily
-
-
-class PersonExpedition(TroggleModel):
- expedition = models.ForeignKey(Expedition)
- person = models.ForeignKey(Person)
- date_from = models.DateField(blank=True,null=True)
- date_to = models.DateField(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('survex_block'):
- if res and res[-1]['survexpath'] == personrole.survex_block.survexpath:
- res[-1]['roles'] += ", " + str(personrole.role)
- else:
- res.append({'date':personrole.survex_block.date, 'survexpath':personrole.survex_block.survexpath, 'roles':str(personrole.role)})
- return res
-
- class Meta:
- ordering = ('expedition',)
- get_latest_by = 'date_from'
-
- def GetPersonChronology(self):
- res = { }
- for persontrip in self.persontrip_set.all():
- a = res.setdefault(persontrip.date, { })
- a.setdefault("persontrips", [ ]).append(persontrip)
- for personrole in self.personrole_set.all():
- a = res.setdefault(personrole.survex_block.date, { })
- b = a.setdefault("personroles", { })
- survexpath = personrole.survex_block.survexpath
-
- if b.get(survexpath):
- b[survexpath] += ", " + str(personrole.role)
- else:
- b[survexpath] = str(personrole.role)
-# needs converting dict into list
- return sorted(res.items())
-
- # possibly not useful functions anyway -JT
- # if you can find a better way to make the expo calendar table, be my guest. It isn't possible to do this logic in a django template without writing custom tags.
- def ListDays(self):
- if self.date_from and self.date_to:
- res=[]
- date=self.date_from
- while date <= self.date_to:
- res.append(date)
- date+=datetime.timedelta(days=1)
- return res
-
- def ListDaysTF(self):
- if self.date_from and self.date_to:
- res=[]
- for date in self.expedition.ListDays():
- res.append(date in self.ListDays())
- return res
-
- def __unicode__(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 settings.URL_ROOT + '/personexpedition/' + str(self.person.first_name) + '_' + str(self.person.last_name) + '/' +self.expedition.year
- return settings.URL_ROOT + reverse('personexpedition',kwargs={'first_name':self.person.first_name,'last_name':self.person.last_name,'year':self.expedition.year})
-
-class LogbookEntry(TroggleModel):
- date = models.DateField()
- expedition = models.ForeignKey(Expedition,blank=True,null=True) # yes this is double-
- author = models.ForeignKey(PersonExpedition,blank=True,null=True) # the person who writes it up doesn't have to have been on the trip
- title = models.CharField(max_length=200)
- cave = models.ForeignKey('Cave',blank=True,null=True)
- place = models.CharField(max_length=100,blank=True,null=True)
- text = models.TextField()
- slug = models.SlugField(max_length=50)
- #href = models.CharField(max_length=100)
-
-
- #logbookentry_next = models.ForeignKey('LogbookEntry', related_name='pnext', blank=True,null=True)
- #logbookentry_prev = models.ForeignKey('LogbookEntry', related_name='pprev', blank=True,null=True)
-
- class Meta:
- verbose_name_plural = "Logbook Entries"
- # several PersonTrips point in to this object
- class Meta:
- ordering = ('-date',)
-
- def get_absolute_url(self):
- return settings.URL_ROOT + reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug})
-
- def __unicode__(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)
-
-class PersonTrip(TroggleModel):
- person_expedition = models.ForeignKey(PersonExpedition,null=True)
-
- # this will be a foreign key of the place(s) the trip went through
- # possibly a trip has a plurality of triplets pointing into it
- place = models.CharField(max_length=100)
- # should add cave thing here (copied from logbook maybe)
- date = models.DateField()
- time_underground = models.FloatField()
- logbook_entry = models.ForeignKey(LogbookEntry)
- is_logbook_entry_author = models.BooleanField()
-
- #persontrip_next = models.ForeignKey('PersonTrip', related_name='pnext', blank=True,null=True)
- #persontrip_prev = models.ForeignKey('PersonTrip', related_name='pprev', blank=True,null=True)
-
- def __unicode__(self):
- return "%s %s (%s)" % (self.person_expedition, self.place, self.date)
-
- def get_persons_next_trip(self):
- try:
- return PersonTrip.objects.filter(person_expedition__person=self.person_expedition.person, date__gt=self.date)[0]
- except:
- return
-
- def get_persons_previous_trip(self):
- try:
- return PersonTrip.objects.filter(person_expedition__person=self.person_expedition.person, date__lt=self.date)[0]
- except:
- return
-
-# def get_persons_previous_trip(self):
-#
-# move following classes into models_cave
-#
-
-class Area(TroggleModel):
- short_name = models.CharField(max_length=100)
- name = models.CharField(max_length=200, blank=True, null=True)
- description = models.TextField(blank=True,null=True)
- parent = models.ForeignKey('Area', blank=True, null=True)
- def __unicode__(self):
- if self.parent:
- return unicode(self.parent) + u" - " + unicode(self.short_name)
- else:
- return unicode(self.short_name)
- def kat_area(self):
- if self.short_name in ["1623", "1626"]:
- return self.short_name
- elif self.parent:
- return self.parent.kat_area()
-
-class CaveAndEntrance(TroggleModel):
- cave = models.ForeignKey('Cave')
- entrance = models.ForeignKey('Entrance')
- entrance_letter = models.CharField(max_length=20,blank=True,null=True)
- def __unicode__(self):
- return unicode(self.cave) + unicode(self.entrance_letter)
-
-class Cave(TroggleModel):
- # too much here perhaps
- official_name = models.CharField(max_length=160)
- area = models.ManyToManyField(Area, blank=True, null=True)
- kataster_code = models.CharField(max_length=20,blank=True,null=True)
- kataster_number = models.CharField(max_length=10,blank=True, null=True)
- unofficial_number = models.CharField(max_length=60,blank=True, null=True)
- entrances = models.ManyToManyField('Entrance', through='CaveAndEntrance')
- explorers = models.TextField(blank=True,null=True)
- underground_description = models.TextField(blank=True,null=True)
- equipment = models.TextField(blank=True,null=True)
- references = models.TextField(blank=True,null=True)
- survey = models.TextField(blank=True,null=True)
- kataster_status = models.TextField(blank=True,null=True)
- underground_centre_line = models.TextField(blank=True,null=True)
- notes = models.TextField(blank=True,null=True)
- length = models.CharField(max_length=100,blank=True,null=True)
- depth = models.CharField(max_length=100,blank=True,null=True)
- extent = models.CharField(max_length=100,blank=True,null=True)
- survex_file = models.CharField(max_length=100,blank=True,null=True) #should be filefield, need to fix parser first
-
- #href = models.CharField(max_length=100)
-
- def get_absolute_url(self):
- if self.kataster_number:
- href = self.kataster_number
- elif self.unofficial_number:
- href = self.unofficial_number
- else:
- href = official_name.lower()
- #return settings.URL_ROOT + '/cave/' + href + '/'
- return settings.URL_ROOT + reverse('cave',kwargs={'cave_id':href,})
-
-
-
- def __unicode__(self):
- if self.kataster_number:
- if self.kat_area():
- return self.kat_area() + u": " + self.kataster_number
- else:
- return unicode("l") + u": " + self.kataster_number
- else:
- if self.kat_area():
- return self.kat_area() + u": " + self.unofficial_number
- else:
- return self.unofficial_number
-
- def get_QMs(self):
- return QM.objects.filter(found_by__cave=self)
-
- def kat_area(self):
- for a in self.area.all():
- if a.kat_area():
- return a.kat_area()
- def entrances(self):
- return CaveAndEntrance.objects.filter(cave=self)
- def entrancelist(self):
- rs = []
- res = ""
- for e in CaveAndEntrance.objects.filter(cave=self):
- rs.append(e.entrance_letter)
- rs.sort()
- prevR = None
- n = 0
- for r in rs:
- if prevR:
- if chr(ord(prevR) + 1 ) == r:
- prevR = r
- n += 1
- else:
- if n == 0:
- res += ", " + prevR
- else:
- res += "–" + prevR
- else:
- prevR = r
- n = 0
- res += r
- if n == 0:
- res += ", " + prevR
- else:
- res += "–" + prevR
- return res
-
-
-
-class OtherCaveName(TroggleModel):
- name = models.CharField(max_length=160)
- cave = models.ForeignKey(Cave)
- def __unicode__(self):
- return unicode(self.name)
-
-class SurveyStation(TroggleModel):
- name = models.CharField(max_length=200)
- def __unicode__(self):
- return unicode(self.name)
-
-class Entrance(TroggleModel):
- name = models.CharField(max_length=100, blank=True,null=True)
- entrance_description = models.TextField(blank=True,null=True)
- explorers = models.TextField(blank=True,null=True)
- map_description = models.TextField(blank=True,null=True)
- location_description = models.TextField(blank=True,null=True)
- approach = models.TextField(blank=True,null=True)
- underground_description = models.TextField(blank=True,null=True)
- photo = models.TextField(blank=True,null=True)
- MARKING_CHOICES = (
- ('P', 'Paint'),
- ('P?', 'Paint (?)'),
- ('T', 'Tag'),
- ('T?', 'Tag (?)'),
- ('R', 'Retagged'),
- ('S', 'Spit'),
- ('S?', 'Spit (?)'),
- ('U', 'Unmarked'),
- ('?', 'Unknown'))
- marking = models.CharField(max_length=2, choices=MARKING_CHOICES)
- marking_comment = models.TextField(blank=True,null=True)
- FINDABLE_CHOICES = (
- ('?', 'To be confirmed ...'),
- ('S', 'Surveyed'),
- ('L', 'Lost'),
- ('R', 'Refindable'))
- findability = models.CharField(max_length=1, choices=FINDABLE_CHOICES, blank=True, null=True)
- findability_description = models.TextField(blank=True,null=True)
- alt = models.TextField(blank=True, null=True)
- northing = models.TextField(blank=True, null=True)
- easting = models.TextField(blank=True, null=True)
- tag_station = models.ForeignKey(SurveyStation, blank=True,null=True, related_name="tag_station")
- exact_station = models.ForeignKey(SurveyStation, blank=True,null=True, related_name="exact_station")
- other_station = models.ForeignKey(SurveyStation, blank=True,null=True, related_name="other_station")
- other_description = models.TextField(blank=True,null=True)
- bearings = models.TextField(blank=True,null=True)
- def __unicode__(self):
- a = CaveAndEntrance.objects.filter(entrance = self)
- name = u''
- if self.name:
- name = unicode(self.name) + u' '
- if len(a) == 1:
- return name + unicode(a[0])
- return name + unicode(a)
- def marking_val(self):
- for m in self.MARKING_CHOICES:
- if m[0] == self.marking:
- return m[1]
- def findability_val(self):
- for f in self.FINDABLE_CHOICES:
- if f[0] == self.findability:
- return f[1]
-
-class Subcave(TroggleModel):
- description = models.TextField()
- name = models.CharField(max_length=200, )
- cave = models.ForeignKey('Cave', blank=True, null=True, help_text="Only the top-level subcave should be linked to a cave")
- parent= models.ForeignKey('Subcave', blank=True, null=True, related_name='children')
- adjoining = models.ManyToManyField('Subcave',blank=True, null=True,)
- survex_file = models.CharField(max_length=200, blank=True, null=True,)
-
- def __unicode__(self):
- return self.name
-
- def get_absolute_url(self):
- urlString=self.name
- if self.parent:
- parent=self.parent
- while parent: #recursively walk up the tree, adding parents to the left of the URL
- urlString=parent.name+'/'+urlString
- if parent.cave:
- cave=parent.cave
- parent=parent.parent
- urlString='cave/'+unicode(cave.kataster_number)+'/'+urlString
- else:
- urlString='cave/'+unicode(self.cave.kataster_number)+'/'+urlString
-
-
- return urlparse.urljoin(settings.URL_ROOT, urlString)
-
-class QM(TroggleModel):
- #based on qm.csv in trunk/expoweb/smkridge/204 which has the fields:
- #"Number","Grade","Area","Description","Page reference","Nearest station","Completion description","Comment"
- found_by = models.ForeignKey(LogbookEntry, related_name='QMs_found',blank=True, null=True )
- ticked_off_by = models.ForeignKey(LogbookEntry, related_name='QMs_ticked_off',null=True,blank=True)
- number = models.IntegerField()
- GRADE_CHOICES=(
- ('A', 'A: Large obvious lead'),
- ('B', 'B: Average lead'),
- ('C', 'C: Tight unpromising lead'),
- ('D', 'D: Dig'),
- ('X', 'X: Unclimbable aven')
- )
- grade = models.CharField(max_length=1, choices=GRADE_CHOICES)
- location_description = models.TextField(blank=True)
- #should be a foreignkey to surveystation
- nearest_station_description = models.CharField(max_length=400,null=True,blank=True)
- nearest_station = models.CharField(max_length=200,blank=True,null=True)
- area = models.CharField(max_length=100,blank=True,null=True)
- completion_description = models.TextField(blank=True,null=True)
- comment=models.TextField(blank=True,null=True)
- #the below are unneeded- instead use the date fields of the QM's trips
- #dateFound = models.DateField(blank=True)
- #dateKilled = models.DateField(blank=True)
- def __str__(self):
- QMnumber=str(self.found_by.cave)+'-'+str(self.found_by.date.year)+"-"+str(self.number)+self.grade
- return str(QMnumber)
-
- def get_absolute_url(self):
- #return settings.URL_ROOT + '/cave/' + self.found_by.cave.kataster_number + '/' + str(self.found_by.date.year) + '-' + '%02d' %self.number
- return settings.URL_ROOT + reverse('qm',kwargs={'cave_id':self.cave.kataster_number,'year':self.found_by.date.year,'qm_id':self.number,'grade':self.grade})
-
- def get_next_by_id(self):
- return QM.objects.get(id=self.id+1)
-
- def get_previous_by_id(self):
- return QM.objects.get(id=self.id-1)
-
- def wiki_link(self):
- res = '[[cave:' + str(self.found_by.cave.kataster_number) + ' '
- res += 'QM:' + str(self.found_by.date.year) + '-'
- res += str(self.number) + self.grade + ']]'
- return res
-
-photoFileStorage = FileSystemStorage(location=settings.PHOTOS_ROOT, base_url=settings.PHOTOS_URL)
-class Photo(TroggleImageModel):
- caption = models.CharField(max_length=1000,blank=True,null=True)
- contains_logbookentry = models.ForeignKey(LogbookEntry,blank=True,null=True)
- contains_person = models.ManyToManyField(Person,blank=True,null=True)
- file = models.ImageField(storage=photoFileStorage, upload_to='.',)
- is_mugshot = models.BooleanField(default=False)
- contains_cave = models.ForeignKey(Cave,blank=True,null=True)
- contains_entrance = models.ForeignKey(Entrance, related_name="photo_file",blank=True,null=True)
- nearest_survey_point = models.ForeignKey(SurveyStation,blank=True,null=True)
- nearest_QM = models.ForeignKey(QM,blank=True,null=True)
- lon_utm = models.FloatField(blank=True,null=True)
- lat_utm = models.FloatField(blank=True,null=True)
-
- class IKOptions:
- spec_module = 'expo.imagekit_specs'
- cache_dir = 'thumbs'
- image_field = 'file'
-
- #content_type = models.ForeignKey(ContentType)
- #object_id = models.PositiveIntegerField()
- #location = generic.GenericForeignKey('content_type', 'object_id')
-
- def __str__(self):
- return self.caption
-
-scansFileStorage = FileSystemStorage(location=settings.SURVEY_SCANS, base_url=settings.SURVEYS_URL)
-def get_scan_path(instance, filename):
- year=instance.survey.expedition.year
- print "WN: ", type(instance.survey.wallet_number), instance.survey.wallet_number
- number="%02d" % instance.survey.wallet_number + str(instance.survey.wallet_letter) #using %02d string formatting because convention was 2009#01
- return os.path.join('./',year,year+r'#'+number,instance.contents+str(instance.number_in_wallet)+r'.jpg')
-
-class ScannedImage(TroggleImageModel):
- file = models.ImageField(storage=scansFileStorage, upload_to=get_scan_path)
- scanned_by = models.ForeignKey(Person,blank=True, null=True)
- scanned_on = models.DateField(null=True)
- survey = models.ForeignKey('Survey')
- contents = models.CharField(max_length=20,choices=(('notes','notes'),('plan','plan_sketch'),('elevation','elevation_sketch')))
- number_in_wallet = models.IntegerField(null=True)
- lon_utm = models.FloatField(blank=True,null=True)
- lat_utm = models.FloatField(blank=True,null=True)
-
- class IKOptions:
- spec_module = 'expo.imagekit_specs'
- cache_dir = 'thumbs'
- image_field = 'file'
- #content_type = models.ForeignKey(ContentType)
- #object_id = models.PositiveIntegerField()
- #location = generic.GenericForeignKey('content_type', 'object_id')
-
- #This is an ugly hack to deal with the #s in our survey scan paths. The correct thing is to write a custom file storage backend which calls urlencode on the name for making file.url but not file.path.
- def correctURL(self):
- return string.replace(self.file.url,r'#',r'%23')
-
- def __str__(self):
- return get_scan_path(self,'')
-
-class Survey(TroggleModel):
- expedition = models.ForeignKey('Expedition')
- wallet_number = models.IntegerField(blank=True,null=True)
- wallet_letter = models.CharField(max_length=1,blank=True,null=True)
- comments = models.TextField(blank=True,null=True)
- location = models.CharField(max_length=400,blank=True,null=True)
- #notes_scan = models.ForeignKey('ScannedImage',related_name='notes_scan',blank=True, null=True) #Replaced by contents field of ScannedImage model
- survex_block = models.ForeignKey('SurvexBlock',blank=True, null=True)
- centreline_printed_on = models.DateField(blank=True, null=True)
- centreline_printed_by = models.ForeignKey('Person',related_name='centreline_printed_by',blank=True,null=True)
- #sketch_scan = models.ForeignKey(ScannedImage,blank=True, null=True) #Replaced by contents field of ScannedImage model
- tunnel_file = models.FileField(upload_to='surveyXMLfiles',blank=True, null=True)
- tunnel_main_sketch = models.ForeignKey('Survey',blank=True,null=True)
- integrated_into_main_sketch_on = models.DateField(blank=True,null=True)
- integrated_into_main_sketch_by = models.ForeignKey('Person' ,related_name='integrated_into_main_sketch_by', blank=True,null=True)
- rendered_image = models.ImageField(upload_to='renderedSurveys',blank=True,null=True)
- def __str__(self):
- return self.expedition.year+"#"+"%02d" % self.wallet_number
-
- def notes(self):
- return self.scannedimage_set.filter(contents='notes')
-
- def plans(self):
- return self.scannedimage_set.filter(contents='plan')
-
- def elevations(self):
- return self.scannedimage_set.filter(contents='elevation')
-
-
diff --git a/troggle/expo/models_survex.py b/troggle/expo/models_survex.py
deleted file mode 100644
index cf339f9fe..000000000
--- a/troggle/expo/models_survex.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from django.db import models
-from django.conf import settings
-import os
-
-class SurvexBlock(models.Model):
- name = models.CharField(max_length=100, blank=True, null=True)
- parent = models.ForeignKey('SurvexBlock', blank=True, null=True)
- text = models.TextField()
-
- # non-useful representation of incomplete data
- start_year = models.IntegerField(blank=True, null=True)
- start_month = models.IntegerField(blank=True, null=True)
- start_day = models.IntegerField(blank=True, null=True)
- end_year = models.IntegerField(blank=True, null=True)
- end_month = models.IntegerField(blank=True, null=True)
- end_day = models.IntegerField(blank=True, null=True)
-
- date = models.DateField(blank=True, null=True)
- survexpath = models.CharField(max_length=100)
-
- # superfluous
- person = models.ManyToManyField('Person', through='PersonRole', blank=True, null=True)
-
- # code for where in the survex data files this block sits
- begin_file = models.CharField(max_length=200)
- begin_char = models.IntegerField()
- end_file = models.CharField(max_length=200, blank=True, null=True)
- end_char = models.IntegerField(blank=True, null=True)
-
- class Meta:
- ordering = ('date', 'survexpath')
-
- def __unicode__(self):
- return unicode(self.name)
-
- def filecontents(self):
- f = os.path.join(settings.SURVEX_DATA, self.begin_file)
- fin = open(f, "rb")
- res = fin.read().decode("latin1")
- fin.close()
- return res
-
- 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)})
- print res
- return res
-
-
-class PersonRole(models.Model):
- personexpedition = models.ForeignKey('PersonExpedition')
- person = models.ForeignKey('Person')
- survex_block = models.ForeignKey('SurvexBlock')
- role = models.ForeignKey('Role')
- def __unicode__(self):
- return unicode(self.person) + " - " + unicode(self.survex_block) + " - " + unicode(self.role)
-
-class Role(models.Model):
- name = models.CharField(max_length=50)
- def __unicode__(self):
- return unicode(self.name)
-
diff --git a/troggle/expo/randSent.py b/troggle/expo/randSent.py
deleted file mode 100644
index a99b97466..000000000
--- a/troggle/expo/randSent.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import troggle.settings as settings
-from django import forms
-from troggle.expo.models import LogbookEntry
-import random
-import re
-
-def weighted_choice(lst):
- n = random.uniform(0,1)
- for item, weight in lst:
- if n < weight:
- break
- n = n - weight
- return item
-
-def randomLogbookSentence():
- randSent={}
-
- # needs to handle empty logbooks without crashing
-
- #Choose a random logbook entry
- randSent['entry']=LogbookEntry.objects.order_by('?')[0]
-
- #Choose again if there are no sentances (this happens if it is a placeholder entry)
- while len(re.findall('[A-Z].*?\.',randSent['entry'].text))==0:
- randSent['entry']=LogbookEntry.objects.order_by('?')[0]
-
- #Choose a random sentence from that entry. Store the sentence as randSent['sentence'], and the number of that sentence in the entry as randSent['number']
- sentenceList=re.findall('[A-Z].*?\.',randSent['entry'].text)
- randSent['number']=random.randrange(0,len(sentenceList))
- randSent['sentence']=sentenceList[randSent['number']]
-
- return randSent
diff --git a/troggle/expo/search.py b/troggle/expo/search.py
deleted file mode 100644
index 5ec2ce2f1..000000000
--- a/troggle/expo/search.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import re
-
-from django.db.models import Q
-
-# search script from http://www.julienphalip.com/blog/2008/08/16/adding-search-django-site-snap/
-
-def normalize_query(query_string,
- findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
- normspace=re.compile(r'\s{2,}').sub):
- ''' Splits the query string in invidual keywords, getting rid of unecessary spaces
- and grouping quoted words together.
- Example:
-
- >>> normalize_query(' some random words "with quotes " and spaces')
- ['some', 'random', 'words', 'with quotes', 'and', 'spaces']
-
- '''
- return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)]
-
-def get_query(query_string, search_fields):
- ''' Returns a query, that is a combination of Q objects. That combination
- aims to search keywords within a model by testing the given search fields.
-
- '''
- query = None # Query to search for every search term
- terms = normalize_query(query_string)
- for term in terms:
- or_query = None # Query to search for a given term in each field
- for field_name in search_fields:
- q = Q(**{"%s__icontains" % field_name: term})
- if or_query is None:
- or_query = q
- else:
- or_query = or_query | q
- if query is None:
- query = or_query
- else:
- query = query & or_query
- return query
\ No newline at end of file
diff --git a/troggle/expo/templatetags/__init__.py b/troggle/expo/templatetags/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/troggle/expo/templatetags/survex_markup.py b/troggle/expo/templatetags/survex_markup.py
deleted file mode 100644
index 464a04bc6..000000000
--- a/troggle/expo/templatetags/survex_markup.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from django import template
-from django.utils.html import conditional_escape
-from django.template.defaultfilters import stringfilter
-from django.utils.safestring import mark_safe
-import re
-
-register = template.Library()
-
-# seems to add extra lines between the commented lines, which isn't so great.
-regexes = []
-regexes.append((re.compile(r"(;.*)$", re.IGNORECASE|re.MULTILINE),
- r'\n'))
-regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)(.svx)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4\5'))
-regexes.append((re.compile(r"^(\s*)(\*include)(\s+)([^\s]*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*team\s+(?:notes|tape|insts|pics))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*(?:begin|end|copyright|date|entrance|equate|export|fix|prefix|require|SOLVE|title|truncate))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*calibrate\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|X|Y|Z)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*data\s+(?:DEFAULT|NORMAL|DIVING|CARTESIAN|TOPOFIL|CYLPOLAR|NOSURVEY|passage)(?:\s+station|\s+from|\s+to|\s+FROMDEPTH|\s+TODEPTH|\s+DEPTHCHANGE|\s+newline|\s+direction|\s+tape|\s+compass|\s+clino|\s+northing|\s+easting|\s+altitude|\s+length|\s+bearing|\s+gradient|\s+ignoreall|\sleft|\sright|\sup|\sdown)*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2'))
-regexes.append((re.compile(r"^(\s*)(\*default\s+(?:CALIBRATE|DATA|UNITS)+)(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*flags\s+(?:DUPLICATE|SPLAY|SURFACE|not DUPLICATE|not SPLAY|not SURFACE))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*infer\s+(?:plumbs|equates|exports))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*instrument\s+(?:compass|clino|tape))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*sd\s+(?:TAPE|COMPASS|CLINO|COUNTER|DEPTH|DECLINATION|DX|DY|DZ))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*set\s+(?:BLANK|COMMENT|DECIMAL|EOL|KEYWORD|MINUS|NAMES|OMIT|PLUS|ROOT|SEPARATOR))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(\s*)(\*units\s+(?:TAPE|LENGTH|COMPASS|BEARING|CLINO|GRADIENT|COUNTER|DEPTH|DECLINATION|X|Y|Z))(\s+)(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1\2\3\4'))
-regexes.append((re.compile(r"^(.*)$", re.IGNORECASE|re.MULTILINE),
- r'\1
\n'))
-
-@register.filter()
-@stringfilter
-def survex_to_html(value, autoescape=None):
- if autoescape:
- value = conditional_escape(value)
- for regex, sub in regexes:
- print sub
- value = regex.sub(sub, value)
- return mark_safe(value)
\ No newline at end of file
diff --git a/troggle/expo/templatetags/wiki_markup.py b/troggle/expo/templatetags/wiki_markup.py
deleted file mode 100644
index 30c9a087f..000000000
--- a/troggle/expo/templatetags/wiki_markup.py
+++ /dev/null
@@ -1,101 +0,0 @@
-from django import template
-from django.utils.html import conditional_escape
-from django.template.defaultfilters import stringfilter
-from django.utils.safestring import mark_safe
-from django.conf import settings
-from expo.models import QM
-import re
-
-register = template.Library()
-
-def wiki_list(line, listdepth):
- l = ""
- for d in listdepth:
- l += d
- mstar = re.match(l + "\*(.*)", line)
- if mstar:
- listdepth.append("\*")
- return ("\n" + " " * len(listdepth) + "- %s
\n" % mstar.groups()[0], listdepth)
- mhash = re.match(l + "#(.*)", line)
- if mhash:
- listdepth.append("#")
- return ("\n" + " " * len(listdepth) + "- %s
\n" % mhash.groups()[0], listdepth)
- mflat = re.match(l + "(.*)", line)
- if mflat and listdepth:
- return (" " * len(listdepth) + "- %s
\n" % mflat.groups()[0], listdepth)
- if listdepth:
- prev = listdepth.pop()
- if prev == "\*":
- t, l = wiki_list(line, listdepth)
- return ("
\n" + t, l)
- if prev == "#":
- t, l = wiki_list(line, listdepth)
- return ("\n" + t, l)
- return (line, listdepth)
-
-@register.filter()
-@stringfilter
-def wiki_to_html(value, autoescape=None):
- #find paragraphs
- outValue = ""
- for paragraph in re.split("\n\s*?\n", value, re.DOTALL):
- outValue += ""
- outValue += wiki_to_html_short(paragraph, autoescape)
- outValue += "
\n"
- return mark_safe(outValue)
-
-@register.filter()
-@stringfilter
-def wiki_to_html_short(value, autoescape=None):
- if autoescape:
- value = conditional_escape(value)
- #deescape doubly escaped characters
- value = re.sub("&(.*?);", r"&\1;", value, re.DOTALL)
- #italics and bold
- value = re.sub("''''([^']+)''''", r"\1", value, re.DOTALL)
- value = re.sub("'''([^']+)'''", r"\1", value, re.DOTALL)
- value = re.sub("''([^']+)''", r"\1", value, re.DOTALL)
- #make cave links
- value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'\1' % settings.URL_ROOT, value, re.DOTALL)
-
-
- #function for replacing wikicode qm links with html qm links
- def qmrepl(matchobj):
- if len(matchobj.groups())==4:
- grade=matchobj.groups()[3]
- else:
- grade=''
- qmdict={'urlroot':settings.URL_ROOT,'cave':matchobj.groups()[0],'year':matchobj.groups()[1],'number':matchobj.groups()[2],'grade':grade}
- try:
- qm=QM.objects.get(found_by__cave__kataster_number=qmdict['cave'],found_by__date__year=qmdict['year'], number=qmdict['number'])
- url=r'' + str(qm) + ''
- except QM.DoesNotExist:
- url = r'%(cave)s:%(year)s-%(number)s%(grade)s' % qmdict
- return url
-
- #make qm links
- value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\QM:(\d*)-(\d*)([ABCDX]?)\]\]",qmrepl, value, re.DOTALL)
-
- #qms=qmfinder.search(value)
- #for qm in qms:
- #if QM.objects.filter(cave__kataster_number=qm[0], found_by__year=qm[1], number=qm[2]).count >= 1: # If there is at lesat one QM matching this query
- #replace qm with link in red
- #else
- #replace qm with link in blue
-
- #turn qm links red if nonexistant
-
- #Make lists from lines starting with lists of [stars and hashes]
- outValue = ""
- listdepth = []
- for line in value.split("\n"):
- t, listdepth = wiki_list(line, listdepth)
- outValue += t
- for item in listdepth:
- if item == "\*":
- outValue += "\n"
- elif item == "#":
- outValue += "\n"
- return mark_safe(outValue)
-
-wiki_to_html.needs_autoescape = True
diff --git a/troggle/expo/view_surveys.py b/troggle/expo/view_surveys.py
deleted file mode 100644
index 846b245fb..000000000
--- a/troggle/expo/view_surveys.py
+++ /dev/null
@@ -1,161 +0,0 @@
-from django.conf import settings
-import fileAbstraction
-from django.shortcuts import render_to_response
-from django.http import HttpResponse, Http404
-import os
-import re
-
-# inline fileabstraction into here if it's not going to be useful anywhere else
-# keep things simple and ignore exceptions everywhere for now
-
-def getMimeType(extension):
- try:
- return {"txt": "text/plain",
- "html": "text/html",
- }[extension]
- except:
- print "unknown file type"
- return "text/plain"
-
-
-def listdir(request, path):
- #try:
- return HttpResponse(fileAbstraction.listdir(path), mimetype = "text/plain")
- #except:
- # raise Http404
-
-def upload(request, path):
- pass
-
-def download(request, path):
- #try:
-
- return HttpResponse(fileAbstraction.readFile(path), mimetype=getMimeType(path.split(".")[-1]))
- #except:
- # raise Http404
-
-
-#
-# julian's quick hack for something that works
-# could signal directories by ending with /, and forward cases where it's missing
-#
-extmimetypes = {".txt": "text/plain",
- ".html": "text/html",
- ".png": "image/png",
- ".jpg": "image/jpeg",
- }
-
-def jgtfile(request, f):
- fp = os.path.join(settings.SURVEYS, f)
- # could also surf through SURVEX_DATA
-
- # directory listing
- if os.path.isdir(fp):
- listdirfiles = [ ]
- listdirdirs = [ ]
-
- for lf in sorted(os.listdir(fp)):
- hpath = os.path.join(f, lf) # not absolute path
- if lf[0] == "." or lf[-1] == "~":
- continue
-
- hpath = hpath.replace("\\", "/") # for windows users
- href = hpath.replace("#", "%23") # '#' in file name annoyance
-
- flf = os.path.join(fp, lf)
- if os.path.isdir(flf):
- nfiles = len([sf for sf in os.listdir(flf) if sf[0] != "."])
- listdirdirs.append((href, hpath + "/", nfiles))
- else:
- listdirfiles.append((href, hpath, os.path.getsize(flf)))
-
- upperdirs = [ ]
- lf = f
- while lf:
- hpath = lf.replace("\\", "/") # for windows users
- if hpath[-1] != "/":
- hpath += "/"
- href = hpath.replace("#", "%23")
- lf = os.path.split(lf)[0]
- upperdirs.append((href, hpath))
- upperdirs.append(("", "/"))
-
- return render_to_response('listdir.html', {'file':f, 'listdirfiles':listdirfiles, 'listdirdirs':listdirdirs, 'upperdirs':upperdirs, 'settings': settings})
-
- # flat output of file when loaded
- if os.path.isfile(fp):
- ext = os.path.splitext(fp)[1].lower()
- mimetype = extmimetypes.get(ext, "text/plain")
- fin = open(fp)
- ftext = fin.read()
- fin.close()
- return HttpResponse(ftext, mimetype=mimetype)
-
- return HttpResponse("unknown file::%s::" % f, mimetype = "text/plain")
-
-
-def UniqueFile(fname):
- while True:
- if not os.path.exists(fname):
- break
- mname = re.match("(.*?)(?:-(\d+))?\.(png|jpg|jpeg)$(?i)", fname)
- if mname:
- fname = "%s-%d.%s" % (mname.group(1), int(mname.group(2) or "0") + 1, mname.group(3))
- return fname
-
-
-# join it all up and then split them off for the directories that don't exist
-# anyway, this mkdir doesn't work
-def SaveImageInDir(name, imgdir, project, fdata, bbinary):
- print ("hihihihi", fdata, settings.SURVEYS)
- fimgdir = os.path.join(settings.SURVEYS, imgdir)
- if not os.path.isdir(fimgdir):
- print "*** Making directory", fimgdir
- os.path.mkdir(fimgdir)
- fprojdir = os.path.join(fimgdir, project)
- if not os.path.isdir(fprojdir):
- print "*** Making directory", fprojdir
- os.path.mkdir(fprojdir)
- print "hhh"
-
- fname = os.path.join(fprojdir, name)
- print fname, "fff"
- fname = UniqueFile(fname)
-
- p2, p1 = os.path.split(fname)
- p3, p2 = os.path.split(p2)
- p4, p3 = os.path.split(p3)
- res = os.path.join(p3, p2, p1)
-
- print "saving file", fname
- fout = open(fname, (bbinary and "wb" or "w"))
- fout.write(fdata.read())
- fout.close()
- res = os.path.join(imgdir, name)
- return res.replace("\\", "/")
-
-
-# do we want to consider saving project/field rather than field/project
-def jgtuploadfile(request):
- filesuploaded = [ ]
- project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"]
- print (project, user, tunnelversion)
- for uploadedfile in request.FILES.values():
- if uploadedfile.field_name in ["tileimage", "backgroundimage"] and \
- uploadedfile.content_type in ["image/png", "image/jpeg"]:
- fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
- print fname
- fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, True)
- filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
- if uploadedfile.field_name in ["sketch"] and \
- uploadedfile.content_type in ["text/plain"]:
- fname = user + "_" + re.sub("[\\\\/]", "-", uploadedfile.name) # very escaped \
- print fname
- fileuploaded = SaveImageInDir(fname, uploadedfile.field_name, project, uploadedfile, False)
- filesuploaded.append(settings.URL_ROOT + "/jgtfile/" + fileuploaded)
- #print "FF", request.FILES
- #print ("FFF", request.FILES.values())
- message = ""
- print "gothere"
- return render_to_response('fileupload.html', {'message':message, 'filesuploaded':filesuploaded, 'settings': settings})
-
diff --git a/troggle/expo/views.py b/troggle/expo/views.py
deleted file mode 100644
index 337989a92..000000000
--- a/troggle/expo/views.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# primary namespace
-
-import view_surveys
-import views_caves
-import views_survex
-import views_logbooks
-import views_other
-
diff --git a/troggle/expo/views_caves.py b/troggle/expo/views_caves.py
deleted file mode 100644
index 691cdcb68..000000000
--- a/troggle/expo/views_caves.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from troggle.expo.models import Cave, CaveAndEntrance, Survey, Expedition, QM
-import troggle.expo.models as models
-import troggle.settings as settings
-from django.forms.models import formset_factory
-import search
-from django.core.urlresolvers import reverse
-from troggle.alwaysUseRequestContext import render_response # see views_logbooks for explanation on this.
-from django.http import HttpResponseRedirect
-from django.conf import settings
-import re
-
-def getCave(cave_id):
- """Returns a cave object when given a cave name or number. It is used by views including cavehref, ent, and qm."""
- try:
- cave = Cave.objects.get(kataster_number=cave_id)
- except Cave.DoesNotExist:
- cave = Cave.objects.get(unofficial_number=cave_id)
- return cave
-
-def caveindex(request):
- caves = Cave.objects.all()
- notablecavehrefs = [ "161", "204", "258", "76" ] # could detect notability by trips and notability of people who have been down them
- notablecaves = [Cave.objects.get(kataster_number=kataster_number) for kataster_number in notablecavehrefs ]
- return render_response(request,'caveindex.html', {'caves': caves, 'notablecaves':notablecaves})
-
-def cave(request, cave_id='', offical_name=''):
- return render_response(request,'cave.html', {'cave': getCave(cave_id),})
-
-def qm(request,cave_id,qm_id,year,grade=None):
- year=int(year)
- try:
- qm=getCave(cave_id).get_QMs().get(number=qm_id,found_by__date__year=year)
- return render_response(request,'qm.html',locals())
-
- except QM.DoesNotExist:
- url= settings.URL_ROOT + r'/admin/expo/qm/add/?'+ r'number=' + qm_id
- if grade:
- url += r'&grade=' + grade
- return HttpResponseRedirect(url)
-
-
-def ent(request, cave_id, ent_letter):
- cave = Cave.objects.filter(kataster_number = cave_id)[0]
- cave_and_ent = CaveAndEntrance.objects.filter(cave = cave).filter(entrance_letter = ent_letter)[0]
- return render_response(request,'entrance.html', {'cave': cave,
- 'entrance': cave_and_ent.entrance,
- 'letter': cave_and_ent.entrance_letter,})
-
-def survexblock(request, survexpath):
- survexblock = models.SurvexBlock.objects.get(survexpath=survexpath)
- #ftext = survexblock.filecontents()
- ftext = survexblock.text
- return render_response(request,'survexblock.html', {'survexblock':survexblock, 'ftext':ftext, })
-
-def subcave(request, cave_id, subcave):
- print subcave
- subcaveSeq=re.findall('(?:/)([^/]*)',subcave)
- print subcaveSeq
- cave=models.Cave.objects.get(kataster_number = cave_id)
- subcave=models.Subcave.objects.get(name=subcaveSeq[0], cave=cave)
- if len(subcaveSeq)>1:
- for subcaveUrlSegment in subcaveSeq[1:]:
- if subcaveUrlSegment:
- subcave=subcave.children.get(name=subcaveUrlSegment)
- print subcave
- return render_response(request,'subcave.html', {'subcave': subcave,'cave':cave})
-
-def caveSearch(request):
- 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, ['underground_description','official_name',])
- found_entries = Cave.objects.filter(entry_query)
-
- return render_response(request,'cavesearch.html',
- { 'query_string': query_string, 'found_entries': found_entries,})
-
-def surveyindex(request):
- surveys=Survey.objects.all()
- expeditions=Expedition.objects.order_by("-year")
- return render_response(request,'survey.html',locals())
-
-def survey(request,year,wallet_number):
- surveys=Survey.objects.all()
- expeditions=Expedition.objects.order_by("-year")
- current_expedition=Expedition.objects.filter(year=year)[0]
-
- if wallet_number!='':
- current_survey=Survey.objects.filter(expedition=current_expedition,wallet_number=wallet_number)[0]
- notes=current_survey.scannedimage_set.filter(contents='notes')
- planSketches=current_survey.scannedimage_set.filter(contents='plan')
- elevationSketches=current_survey.scannedimage_set.filter(contents='elevation')
-
- return render_response(request,'survey.html', locals())
-
diff --git a/troggle/expo/views_logbooks.py b/troggle/expo/views_logbooks.py
deleted file mode 100644
index cfebd35e6..000000000
--- a/troggle/expo/views_logbooks.py
+++ /dev/null
@@ -1,120 +0,0 @@
-from django.shortcuts import render_to_response
-from troggle.expo.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry
-import troggle.settings as settings
-from django.db import models
-from troggle.parsers.logbooks import LoadLogbookForExpedition
-from troggle.parsers.people import GetPersonExpeditionNameLookup
-from troggle.expo.forms import PersonForm
-from django.core.urlresolvers import reverse
-from django.http import HttpResponseRedirect
-
-# 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
-
-import search
-import re
-
-@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 = 5
- nc = (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_response(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, })
-
-def expedition(request, expeditionname):
- year = int(expeditionname)
- expedition = Expedition.objects.get(year=year)
- expedition_next = Expedition.objects.filter(year=year+1) and Expedition.objects.get(year=year+1) or None
- expedition_prev = Expedition.objects.filter(year=year-1) and Expedition.objects.get(year=year-1) or None
- message = "No message"
- if "reload" in request.GET:
- message = LoadLogbookForExpedition(expedition)
- #message = str(GetPersonExpeditionNameLookup(expedition).keys())
- logbookentries = expedition.logbookentry_set.order_by('date')
- return render_response(request,'expedition.html', {'expedition': expedition, 'expedition_next':expedition_next, 'expedition_prev':expedition_prev, 'logbookentries':logbookentries, 'message':message, })
-
- def get_absolute_url(self):
- return ('expedition', (expedition.year))
-
-def person(request, first_name='', last_name='', ):
- 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':
- person.user=None
- person.save()
- return HttpResponseRedirect(reverse('profiles_select_profile'))
-
- return render_response(request,'person.html', {'person': person, })
-
- def get_absolute_url(self):
- return settings.URL_ROOT + self.first_name + '_' + self.last_name
-
-#def person(request, name):
-# person = Person.objects.get(href=name)
-#
-
-def personexpedition(request, first_name='', last_name='', year=''):
- person = Person.objects.get(first_name = first_name, last_name = last_name)
- expedition = Expedition.objects.get(year=year)
- personexpedition = person.personexpedition_set.get(expedition=expedition)
- return render_response(request,'personexpedition.html', {'personexpedition': personexpedition, })
-
-def newQMlink(logbookentry):
- biggestQMnumber=0
- if logbookentry.cave:
- for log in logbookentry.cave.logbookentry_set.all():
- try:
- biggestQMnumberInLog = logbookentry.QMs_found.order_by('-number')[0].number
- except IndexError:
- biggestQMnumberInLog = 0
- if biggestQMnumberInLog > biggestQMnumber:
- biggestQMnumber = biggestQMnumberInLog
- else:
- return None
-
-
-
- nextQMnumber=biggestQMnumber+1
- return settings.URL_ROOT + r'/admin/expo/qm/add/?' + r'found_by=' + str(logbookentry.pk) +'&number=' + str(nextQMnumber)
-
-def logbookentry(request, date, slug):
- logbookentry = LogbookEntry.objects.get(date=date, slug=slug)
-
- return render_response(request, 'logbookentry.html', {'logbookentry': logbookentry, 'newQMlink':newQMlink(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_response(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_response(request,'personform.html', {'form':form,})
\ No newline at end of file
diff --git a/troggle/expo/views_other.py b/troggle/expo/views_other.py
deleted file mode 100644
index 0f8cb7935..000000000
--- a/troggle/expo/views_other.py
+++ /dev/null
@@ -1,70 +0,0 @@
-from troggle.expo.models import Cave, Expedition, Person, LogbookEntry, PersonExpedition, PersonTrip, Photo
-import troggle.settings as settings
-from django import forms
-from django.db.models import Q
-import databaseReset
-import re
-import randSent
-from django.http import HttpResponse
-
-from django.core.urlresolvers import reverse
-from troggle.alwaysUseRequestContext import render_response # see views_logbooks for explanation on this.
-
-def showrequest(request):
- return HttpResponse(request.GET)
-
-def stats(request):
- statsDict={}
- statsDict['expoCount'] = int(Expedition.objects.count())
- statsDict['caveCount'] = int(Cave.objects.count())
- statsDict['personCount'] = int(Person.objects.count())
- statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count())
- return render_response(request,'statistics.html', statsDict)
-
-def frontpage(request):
- message = "no test message" #reverse('personn', kwargs={"name":"hkjhjh"})
- if "reloadexpos" in request.GET:
- message = LoadPersonsExpos()
- message = "Reloaded personexpos"
- if "reloadsurvex" in request.POST:
- message = LoadAllSurvexBlocks()
- message = "Reloaded survexblocks"
-
- #'randSent':randSent.randomLogbookSentence(),
- expeditions = Expedition.objects.order_by("-year")
- logbookentry = LogbookEntry
- cave = Cave
- photo = Photo
- return render_response(request,'frontpage.html', locals())
-
-def todo(request):
- message = "no test message" #reverse('personn', kwargs={"name":"hkjhjh"})
- if "reloadexpos" in request.GET:
- message = LoadPersonsExpos()
- message = "Reloaded personexpos"
- if "reloadsurvex" in request.POST:
- message = LoadAllSurvexBlocks()
- message = "Reloaded survexblocks"
-
- #'randSent':randSent.randomLogbookSentence(),
- expeditions = Expedition.objects.order_by("-year")
- totallogbookentries = LogbookEntry.objects.count()
- return render_response(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message})
-
-def calendar(request,year):
- week=['S','S','M','T','W','T','F']
- if year:
- expedition=Expedition.objects.get(year=year)
- PersonExpeditions=expedition.personexpedition_set.all()
-
- return render_response(request,'calendar.html', locals())
-
-def controlPanel(request):
- message = "no test message" #reverse('personn', kwargs={"name":"hkjhjh"})
- if request.method=='POST':
- for item in request.POST:
- if request.user.is_superuser and item!='item':
- print "running"+ " databaseReset."+item+"()"
- exec "databaseReset."+item+"()"
-
- return render_response(request,'controlPanel.html', )
\ No newline at end of file
diff --git a/troggle/expo/views_survex.py b/troggle/expo/views_survex.py
deleted file mode 100644
index 067d4e34c..000000000
--- a/troggle/expo/views_survex.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from django.shortcuts import render_to_response
-from django.http import HttpResponse, Http404
-import re
-import os
-
-import troggle.settings as settings
-
-def index(request, survex_file):
- process(survex_file)
- f = open(settings.SURVEX_DATA + survex_file + ".svx", "rb")
- a = f.read()
- return render_to_response('svxfile.html', {'settings': settings,
- 'has_3d': os.path.isfile(settings.SURVEX_DATA + survex_file + ".3d"),
- 'title': survex_file,
- 'text': unicode(a, "latin1")})
-
-def svx(request, survex_file):
- svx = open(settings.SURVEX_DATA + survex_file + ".svx", "rb")
- return HttpResponse(svx, mimetype="text")
-
-def threed(request, survex_file):
- process(survex_file)
- try:
- threed = open(settings.SURVEX_DATA + survex_file + ".3d", "rb")
- return HttpResponse(threed, mimetype="model/3d")
- except:
- log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
- return HttpResponse(log, mimetype="text")
-
-def log(request, survex_file):
- process(survex_file)
- log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
- return HttpResponse(log, mimetype="text")
-
-def err(request, survex_file):
- process(survex_file)
- err = open(settings.SURVEX_DATA + survex_file + ".err", "rb")
- return HttpResponse(err, mimetype="text")
-
-def process(survex_file):
- cwd = os.getcwd()
- os.chdir(os.path.split(settings.SURVEX_DATA + survex_file)[0])
- os.system(settings.CAVERN + " --log " +settings.SURVEX_DATA + survex_file + ".svx")
- os.chdir(cwd)
diff --git a/troggle/export/__init__.py b/troggle/export/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/troggle/export/tocavetab.py b/troggle/export/tocavetab.py
deleted file mode 100644
index 121c36e4a..000000000
--- a/troggle/export/tocavetab.py
+++ /dev/null
@@ -1,52 +0,0 @@
-import troggle.expo.models as models
-from django.conf import settings
-
-import csv
-import re
-import os
-
-#format of CAVETAB2.CSV is
-headers=['KatasterNumber','KatStatusCode','Entrances','UnofficialNumber','MultipleEntrances','AutogenFile','LinkFile','LinkEntrance','Name','UnofficialName',
- 'Comment','Area','Explorers','UndergroundDescription','Equipment','QMList','KatasterStatus','References','UndergroundCentreLine','UndergroundDrawnSurvey',
- 'SurvexFile','Length','Depth','Extent','Notes','EntranceName','TagPoint','OtherPoint','DescriptionOfOtherPoint','ExactEntrance','TypeOfFix','GPSpreSA',
- 'GPSpostSA','Northing','Easting','Altitude','Bearings','Map','Location','Approach','EntranceDescription','PhotoOfLocation','Marking','MarkingComment',
- 'Findability','FindabilityComment']
-
-def cavetabRow(cave):
- #mapping of troggle models to table columns is: (guess this could just be a tuple of tuples rather than a dictionary actually)
- columnsToModelFields={
- 'Name':cave.official_name,
- 'Area':cave.kat_area(),
- 'KatStatusCode':cave.kataster_code,
- 'KatasterNumber':cave.kataster_number,
- 'UnofficialNumber':cave.unofficial_number,
- #'' : cave.entrances This is a multiple foreignkey now, may be tricky to dump back into csv. Work on this.
- 'Explorers':cave.explorers,
- 'UndergroundDescription':cave.underground_description,
- 'Equipment':cave.equipment,
- 'References':cave.references,
- 'UndergroundDrawnSurvey':cave.survey,
- 'KatasterStatus':cave.kataster_status,
- 'UndergroundCentreLine':cave.underground_centre_line,
- 'Notes':cave.notes,
- 'Length':cave.length,
- 'Depth':cave.depth,
- 'Extent':cave.extent,
- 'SurvexFile':cave.survex_file,
- }
-
- caveRow=['' for x in range(len(headers))]
- for column, modelField in columnsToModelFields.items():
- if modelField:
- # Very sorry about the atrocious replace below. I will fix this soon if noone beats me to it. - AC
- caveRow[headers.index(column)]=modelField.replace(u'\xd7','x').replace(u'\u201c','').replace(u'\u2013','').replace(u'\xbd','')
- return caveRow
-
-def writeCaveTab(path):
- outfile=file(path,'w')
- cavewriter=csv.writer(outfile,lineterminator='\r')
- cavewriter.writerow(headers)
- for cave in models.Cave.objects.all():
- cavewriter.writerow(cavetabRow(cave))
-
-
diff --git a/troggle/export/tologbooks.py b/troggle/export/tologbooks.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/troggle/export/toqms.py b/troggle/export/toqms.py
deleted file mode 100644
index 0597da6d3..000000000
--- a/troggle/export/toqms.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import troggle.expo.models as models
-from django.conf import settings
-
-import csv
-import re
-import os
-
-#format of QM tables
-headers=['Number','Grade','Area','Description','Page reference','Nearest station','Completion description','Comment']
-
-def qmRow(qm):
- #mapping of troggle models to table columns is: (guess this could just be a tuple of tuples rather than a dictionary actually)
- columnsToModelFields={
- 'Number':str(qm.number),
- 'Grade':qm.grade,
- 'Area':qm.area,
- 'Description':qm.location_description,
- #'Page reference': #not implemented
- 'Nearest station':qm.nearest_station_description,
- 'Completion description':qm.completion_description,
- 'Comment':qm.comment
- }
-
- qmRow=['' for x in range(len(headers))]
- for column, modelField in columnsToModelFields.items():
- if modelField:
- # Very sorry about the atrocious replace below. I will fix this soon if noone beats me to it. - AC
- qmRow[headers.index(column)]=modelField.replace(u'\xd7','x').replace(u'\u201c','').replace(u'\u2013','').replace(u'\xbd','')
- return qmRow
-
-def writeQmTable(path,cave):
- outfile=file(path,'w')
- cavewriter=csv.writer(outfile,lineterminator='\r')
- cavewriter.writerow(headers)
- for qm in cave.get_QMs():
- cavewriter.writerow(qmRow(qm))
-
\ No newline at end of file
diff --git a/troggle/imagekit/__init__.py b/troggle/imagekit/__init__.py
deleted file mode 100644
index 2965bbd70..000000000
--- a/troggle/imagekit/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-"""
-
-Django ImageKit
-
-Author: Justin Driscoll
-Version: 0.2
-
-"""
-VERSION = "0.2"
-
-
-
-
\ No newline at end of file
diff --git a/troggle/imagekit/defaults.py b/troggle/imagekit/defaults.py
deleted file mode 100644
index e1a05f600..000000000
--- a/troggle/imagekit/defaults.py
+++ /dev/null
@@ -1,21 +0,0 @@
-""" Default ImageKit configuration """
-
-from imagekit.specs import ImageSpec
-from imagekit import processors
-
-class ResizeThumbnail(processors.Resize):
- width = 100
- height = 50
- crop = True
-
-class EnhanceSmall(processors.Adjustment):
- contrast = 1.2
- sharpness = 1.1
-
-class SampleReflection(processors.Reflection):
- size = 0.5
- background_color = "#000000"
-
-class DjangoAdminThumbnail(ImageSpec):
- access_as = 'admin_thumbnail'
- processors = [ResizeThumbnail, EnhanceSmall, SampleReflection]
diff --git a/troggle/imagekit/lib.py b/troggle/imagekit/lib.py
deleted file mode 100644
index 65646a44e..000000000
--- a/troggle/imagekit/lib.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Required PIL classes may or may not be available from the root namespace
-# depending on the installation method used.
-try:
- import Image
- import ImageFile
- import ImageFilter
- import ImageEnhance
- import ImageColor
-except ImportError:
- try:
- from PIL import Image
- from PIL import ImageFile
- from PIL import ImageFilter
- from PIL import ImageEnhance
- from PIL import ImageColor
- except ImportError:
- raise ImportError('ImageKit was unable to import the Python Imaging Library. Please confirm it`s installed and available on your current Python path.')
\ No newline at end of file
diff --git a/troggle/imagekit/management/__init__.py b/troggle/imagekit/management/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/troggle/imagekit/management/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/troggle/imagekit/management/commands/__init__.py b/troggle/imagekit/management/commands/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/troggle/imagekit/management/commands/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/troggle/imagekit/management/commands/ikflush.py b/troggle/imagekit/management/commands/ikflush.py
deleted file mode 100644
index c03440f43..000000000
--- a/troggle/imagekit/management/commands/ikflush.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from django.db.models.loading import cache
-from django.core.management.base import BaseCommand, CommandError
-from optparse import make_option
-from imagekit.models import ImageModel
-from imagekit.specs import ImageSpec
-
-
-class Command(BaseCommand):
- help = ('Clears all ImageKit cached files.')
- args = '[apps]'
- requires_model_validation = True
- can_import_settings = True
-
- def handle(self, *args, **options):
- return flush_cache(args, options)
-
-def flush_cache(apps, options):
- """ Clears the image cache
-
- """
- apps = [a.strip(',') for a in apps]
- if apps:
- print 'Flushing cache for %s...' % ', '.join(apps)
- else:
- print 'Flushing caches...'
-
- for app_label in apps:
- app = cache.get_app(app_label)
- models = [m for m in cache.get_models(app) if issubclass(m, ImageModel)]
-
- for model in models:
- for obj in model.objects.all():
- for spec in model._ik.specs:
- prop = getattr(obj, spec.name(), None)
- if prop is not None:
- prop._delete()
- if spec.pre_cache:
- prop._create()
diff --git a/troggle/imagekit/models.py b/troggle/imagekit/models.py
deleted file mode 100644
index 140715ebc..000000000
--- a/troggle/imagekit/models.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import os
-from datetime import datetime
-from django.conf import settings
-from django.core.files.base import ContentFile
-from django.db import models
-from django.db.models.base import ModelBase
-from django.utils.translation import ugettext_lazy as _
-
-from imagekit import specs
-from imagekit.lib import *
-from imagekit.options import Options
-from imagekit.utils import img_to_fobj
-
-# Modify image file buffer size.
-ImageFile.MAXBLOCK = getattr(settings, 'PIL_IMAGEFILE_MAXBLOCK', 256 * 2 ** 10)
-
-# Choice tuples for specifying the crop origin.
-# These are provided for convenience.
-CROP_HORZ_CHOICES = (
- (0, _('left')),
- (1, _('center')),
- (2, _('right')),
-)
-
-CROP_VERT_CHOICES = (
- (0, _('top')),
- (1, _('center')),
- (2, _('bottom')),
-)
-
-
-class ImageModelBase(ModelBase):
- """ ImageModel metaclass
-
- This metaclass parses IKOptions and loads the specified specification
- module.
-
- """
- def __init__(cls, name, bases, attrs):
- parents = [b for b in bases if isinstance(b, ImageModelBase)]
- if not parents:
- return
- user_opts = getattr(cls, 'IKOptions', None)
- opts = Options(user_opts)
- try:
- module = __import__(opts.spec_module, {}, {}, [''])
- except ImportError:
- raise ImportError('Unable to load imagekit config module: %s' % \
- opts.spec_module)
- for spec in [spec for spec in module.__dict__.values() \
- if isinstance(spec, type) \
- and issubclass(spec, specs.ImageSpec) \
- and spec != specs.ImageSpec]:
- setattr(cls, spec.name(), specs.Descriptor(spec))
- opts.specs.append(spec)
- setattr(cls, '_ik', opts)
-
-
-class ImageModel(models.Model):
- """ Abstract base class implementing all core ImageKit functionality
-
- Subclasses of ImageModel are augmented with accessors for each defined
- image specification and can override the inner IKOptions class to customize
- storage locations and other options.
-
- """
- __metaclass__ = ImageModelBase
-
- class Meta:
- abstract = True
-
- class IKOptions:
- pass
-
- def admin_thumbnail_view(self):
- if not self._imgfield:
- return None
- prop = getattr(self, self._ik.admin_thumbnail_spec, None)
- if prop is None:
- return 'An "%s" image spec has not been defined.' % \
- self._ik.admin_thumbnail_spec
- else:
- if hasattr(self, 'get_absolute_url'):
- return u'
' % \
- (self.get_absolute_url(), prop.url)
- else:
- return u'
' % \
- (self._imgfield.url, prop.url)
- admin_thumbnail_view.short_description = _('Thumbnail')
- admin_thumbnail_view.allow_tags = True
-
- @property
- def _imgfield(self):
- return getattr(self, self._ik.image_field)
-
- def _clear_cache(self):
- for spec in self._ik.specs:
- prop = getattr(self, spec.name())
- prop._delete()
-
- def _pre_cache(self):
- for spec in self._ik.specs:
- if spec.pre_cache:
- prop = getattr(self, spec.name())
- prop._create()
-
- def save(self, clear_cache=True, *args, **kwargs):
- is_new_object = self._get_pk_val is None
- super(ImageModel, self).save(*args, **kwargs)
- if is_new_object:
- clear_cache = False
- spec = self._ik.preprocessor_spec
- if spec is not None:
- newfile = self._imgfield.storage.open(str(self._imgfield))
- img = Image.open(newfile)
- img = spec.process(img, None)
- format = img.format or 'JPEG'
- if format != 'JPEG':
- imgfile = img_to_fobj(img, format)
- else:
- imgfile = img_to_fobj(img, format,
- quality=int(spec.quality),
- optimize=True)
- content = ContentFile(imgfile.read())
- newfile.close()
- name = str(self._imgfield)
- self._imgfield.storage.delete(name)
- self._imgfield.storage.save(name, content)
- if clear_cache and self._imgfield != '':
- self._clear_cache()
- self._pre_cache()
-
- def delete(self):
- assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
- self._clear_cache()
- models.Model.delete(self)
diff --git a/troggle/imagekit/options.py b/troggle/imagekit/options.py
deleted file mode 100644
index 022cc9ef6..000000000
--- a/troggle/imagekit/options.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Imagekit options
-from imagekit import processors
-from imagekit.specs import ImageSpec
-
-
-class Options(object):
- """ Class handling per-model imagekit options
-
- """
- image_field = 'image'
- crop_horz_field = 'crop_horz'
- crop_vert_field = 'crop_vert'
- preprocessor_spec = None
- cache_dir = 'cache'
- save_count_as = None
- cache_filename_format = "%(filename)s_%(specname)s.%(extension)s"
- admin_thumbnail_spec = 'admin_thumbnail'
- spec_module = 'imagekit.defaults'
-
- def __init__(self, opts):
- for key, value in opts.__dict__.iteritems():
- setattr(self, key, value)
- self.specs = []
\ No newline at end of file
diff --git a/troggle/imagekit/processors.py b/troggle/imagekit/processors.py
deleted file mode 100644
index 6f6b480ef..000000000
--- a/troggle/imagekit/processors.py
+++ /dev/null
@@ -1,134 +0,0 @@
-""" Imagekit Image "ImageProcessors"
-
-A processor defines a set of class variables (optional) and a
-class method named "process" which processes the supplied image using
-the class properties as settings. The process method can be overridden as well allowing user to define their
-own effects/processes entirely.
-
-"""
-from imagekit.lib import *
-
-class ImageProcessor(object):
- """ Base image processor class """
- @classmethod
- def process(cls, image, obj=None):
- return image
-
-
-class Adjustment(ImageProcessor):
- color = 1.0
- brightness = 1.0
- contrast = 1.0
- sharpness = 1.0
-
- @classmethod
- def process(cls, image, obj=None):
- for name in ['Color', 'Brightness', 'Contrast', 'Sharpness']:
- factor = getattr(cls, name.lower())
- if factor != 1.0:
- image = getattr(ImageEnhance, name)(image).enhance(factor)
- return image
-
-
-class Reflection(ImageProcessor):
- background_color = '#FFFFFF'
- size = 0.0
- opacity = 0.6
-
- @classmethod
- def process(cls, image, obj=None):
- # convert bgcolor string to rgb value
- background_color = ImageColor.getrgb(cls.background_color)
- # copy orignial image and flip the orientation
- reflection = image.copy().transpose(Image.FLIP_TOP_BOTTOM)
- # create a new image filled with the bgcolor the same size
- background = Image.new("RGB", image.size, background_color)
- # calculate our alpha mask
- start = int(255 - (255 * cls.opacity)) # The start of our gradient
- steps = int(255 * cls.size) # the number of intermedite values
- increment = (255 - start) / float(steps)
- mask = Image.new('L', (1, 255))
- for y in range(255):
- if y < steps:
- val = int(y * increment + start)
- else:
- val = 255
- mask.putpixel((0, y), val)
- alpha_mask = mask.resize(image.size)
- # merge the reflection onto our background color using the alpha mask
- reflection = Image.composite(background, reflection, alpha_mask)
- # crop the reflection
- reflection_height = int(image.size[1] * cls.size)
- reflection = reflection.crop((0, 0, image.size[0], reflection_height))
- # create new image sized to hold both the original image and the reflection
- composite = Image.new("RGB", (image.size[0], image.size[1]+reflection_height), background_color)
- # paste the orignal image and the reflection into the composite image
- composite.paste(image, (0, 0))
- composite.paste(reflection, (0, image.size[1]))
- # return the image complete with reflection effect
- return composite
-
-
-class Resize(ImageProcessor):
- width = None
- height = None
- crop = False
- upscale = False
-
- @classmethod
- def process(cls, image, obj=None):
- cur_width, cur_height = image.size
- if cls.crop:
- crop_horz = getattr(obj, obj._ik.crop_horz_field, 1)
- crop_vert = getattr(obj, obj._ik.crop_vert_field, 1)
- ratio = max(float(cls.width)/cur_width, float(cls.height)/cur_height)
- resize_x, resize_y = ((cur_width * ratio), (cur_height * ratio))
- crop_x, crop_y = (abs(cls.width - resize_x), abs(cls.height - resize_y))
- x_diff, y_diff = (int(crop_x / 2), int(crop_y / 2))
- box_left, box_right = {
- 0: (0, cls.width),
- 1: (int(x_diff), int(x_diff + cls.width)),
- 2: (int(crop_x), int(resize_x)),
- }[crop_horz]
- box_upper, box_lower = {
- 0: (0, cls.height),
- 1: (int(y_diff), int(y_diff + cls.height)),
- 2: (int(crop_y), int(resize_y)),
- }[crop_vert]
- box = (box_left, box_upper, box_right, box_lower)
- image = image.resize((int(resize_x), int(resize_y)), Image.ANTIALIAS).crop(box)
- else:
- if not cls.width is None and not cls.height is None:
- ratio = min(float(cls.width)/cur_width,
- float(cls.height)/cur_height)
- else:
- if cls.width is None:
- ratio = float(cls.height)/cur_height
- else:
- ratio = float(cls.width)/cur_width
- new_dimensions = (int(round(cur_width*ratio)),
- int(round(cur_height*ratio)))
- if new_dimensions[0] > cur_width or \
- new_dimensions[1] > cur_height:
- if not cls.upscale:
- return image
- image = image.resize(new_dimensions, Image.ANTIALIAS)
- return image
-
-
-class Transpose(ImageProcessor):
- """ Rotates or flips the image
-
- Method should be one of the following strings:
- - FLIP_LEFT RIGHT
- - FLIP_TOP_BOTTOM
- - ROTATE_90
- - ROTATE_270
- - ROTATE_180
-
- """
- method = 'FLIP_LEFT_RIGHT'
-
- @classmethod
- def process(cls, image, obj=None):
- return image.transpose(getattr(Image, cls.method))
diff --git a/troggle/imagekit/specs.py b/troggle/imagekit/specs.py
deleted file mode 100644
index a6832ba9d..000000000
--- a/troggle/imagekit/specs.py
+++ /dev/null
@@ -1,119 +0,0 @@
-""" ImageKit image specifications
-
-All imagekit specifications must inherit from the ImageSpec class. Models
-inheriting from ImageModel will be modified with a descriptor/accessor for each
-spec found.
-
-"""
-import os
-from StringIO import StringIO
-from imagekit.lib import *
-from imagekit.utils import img_to_fobj
-from django.core.files.base import ContentFile
-
-class ImageSpec(object):
- pre_cache = False
- quality = 70
- increment_count = False
- processors = []
-
- @classmethod
- def name(cls):
- return getattr(cls, 'access_as', cls.__name__.lower())
-
- @classmethod
- def process(cls, image, obj):
- processed_image = image.copy()
- for proc in cls.processors:
- processed_image = proc.process(processed_image, obj)
- return processed_image
-
-
-class Accessor(object):
- def __init__(self, obj, spec):
- self._img = None
- self._obj = obj
- self.spec = spec
-
- def _get_imgfile(self):
- format = self._img.format or 'JPEG'
- if format != 'JPEG':
- imgfile = img_to_fobj(self._img, format)
- else:
- imgfile = img_to_fobj(self._img, format,
- quality=int(self.spec.quality),
- optimize=True)
- return imgfile
-
- def _create(self):
- if self._exists():
- return
- # process the original image file
- fp = self._obj._imgfield.storage.open(self._obj._imgfield.name)
- fp.seek(0)
- fp = StringIO(fp.read())
- try:
- self._img = self.spec.process(Image.open(fp), self._obj)
- # save the new image to the cache
- content = ContentFile(self._get_imgfile().read())
- self._obj._imgfield.storage.save(self.name, content)
- except IOError:
- pass
-
- def _delete(self):
- self._obj._imgfield.storage.delete(self.name)
-
- def _exists(self):
- return self._obj._imgfield.storage.exists(self.name)
-
- def _basename(self):
- filename, extension = \
- os.path.splitext(os.path.basename(self._obj._imgfield.name))
- return self._obj._ik.cache_filename_format % \
- {'filename': filename,
- 'specname': self.spec.name(),
- 'extension': extension.lstrip('.')}
-
- @property
- def name(self):
- return os.path.join(self._obj._ik.cache_dir, self._basename())
-
- @property
- def url(self):
- self._create()
- if self.spec.increment_count:
- fieldname = self._obj._ik.save_count_as
- if fieldname is not None:
- current_count = getattr(self._obj, fieldname)
- setattr(self._obj, fieldname, current_count + 1)
- self._obj.save(clear_cache=False)
- return self._obj._imgfield.storage.url(self.name)
-
- @property
- def file(self):
- self._create()
- return self._obj._imgfield.storage.open(self.name)
-
- @property
- def image(self):
- if self._img is None:
- self._create()
- if self._img is None:
- self._img = Image.open(self.file)
- return self._img
-
- @property
- def width(self):
- return self.image.size[0]
-
- @property
- def height(self):
- return self.image.size[1]
-
-
-class Descriptor(object):
- def __init__(self, spec):
- self._spec = spec
-
- def __get__(self, obj, type=None):
- return Accessor(obj, self._spec)
diff --git a/troggle/imagekit/tests.py b/troggle/imagekit/tests.py
deleted file mode 100644
index 8c2eb5ea5..000000000
--- a/troggle/imagekit/tests.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import os
-import tempfile
-import unittest
-from django.conf import settings
-from django.core.files.base import ContentFile
-from django.db import models
-from django.test import TestCase
-
-from imagekit import processors
-from imagekit.models import ImageModel
-from imagekit.specs import ImageSpec
-from imagekit.lib import Image
-
-
-class ResizeToWidth(processors.Resize):
- width = 100
-
-class ResizeToHeight(processors.Resize):
- height = 100
-
-class ResizeToFit(processors.Resize):
- width = 100
- height = 100
-
-class ResizeCropped(ResizeToFit):
- crop = ('center', 'center')
-
-class TestResizeToWidth(ImageSpec):
- access_as = 'to_width'
- processors = [ResizeToWidth]
-
-class TestResizeToHeight(ImageSpec):
- access_as = 'to_height'
- processors = [ResizeToHeight]
-
-class TestResizeCropped(ImageSpec):
- access_as = 'cropped'
- processors = [ResizeCropped]
-
-class TestPhoto(ImageModel):
- """ Minimal ImageModel class for testing """
- image = models.ImageField(upload_to='images')
-
- class IKOptions:
- spec_module = 'imagekit.tests'
-
-
-class IKTest(TestCase):
- """ Base TestCase class """
- def setUp(self):
- # create a test image using tempfile and PIL
- self.tmp = tempfile.TemporaryFile()
- Image.new('RGB', (800, 600)).save(self.tmp, 'JPEG')
- self.tmp.seek(0)
- self.p = TestPhoto()
- self.p.image.save(os.path.basename('test.jpg'),
- ContentFile(self.tmp.read()))
- self.p.save()
- # destroy temp file
- self.tmp.close()
-
- def test_setup(self):
- self.assertEqual(self.p.image.width, 800)
- self.assertEqual(self.p.image.height, 600)
-
- def test_to_width(self):
- self.assertEqual(self.p.to_width.width, 100)
- self.assertEqual(self.p.to_width.height, 75)
-
- def test_to_height(self):
- self.assertEqual(self.p.to_height.width, 133)
- self.assertEqual(self.p.to_height.height, 100)
-
- def test_crop(self):
- self.assertEqual(self.p.cropped.width, 100)
- self.assertEqual(self.p.cropped.height, 100)
-
- def test_url(self):
- tup = (settings.MEDIA_URL, self.p._ik.cache_dir, 'test_to_width.jpg')
- self.assertEqual(self.p.to_width.url, "%s%s/%s" % tup)
-
- def tearDown(self):
- # make sure image file is deleted
- path = self.p.image.path
- self.p.delete()
- self.failIf(os.path.isfile(path))
diff --git a/troggle/imagekit/utils.py b/troggle/imagekit/utils.py
deleted file mode 100644
index 352d40ff2..000000000
--- a/troggle/imagekit/utils.py
+++ /dev/null
@@ -1,15 +0,0 @@
-""" ImageKit utility functions """
-
-import tempfile
-
-def img_to_fobj(img, format, **kwargs):
- tmp = tempfile.TemporaryFile()
- if format != 'JPEG':
- try:
- img.save(tmp, format, **kwargs)
- return
- except KeyError:
- pass
- img.save(tmp, format, **kwargs)
- tmp.seek(0)
- return tmp
diff --git a/troggle/localsettingsserver.py b/troggle/localsettingsserver.py
deleted file mode 100644
index 4148336ca..000000000
--- a/troggle/localsettingsserver.py
+++ /dev/null
@@ -1,31 +0,0 @@
-DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-DATABASE_NAME = 'troggle' # Or path to database file if using sqlite3.
-DATABASE_USER = 'undemocracy' # Not used with sqlite3.
-DATABASE_PASSWORD = 'aiGohsh5' # Not used with sqlite3.
-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
-
-SURVEX_DATA = '/home/mjg/loser/'
-CAVERN = 'cavern'
-EXPOWEB = '/home/mjg/expoweb/'
-SURVEYS = '/home/mjg/surveys/'
-
-SURVEYS_URL = 'http://framos.lawoftheland.co.uk/troggle/survey_scans/'
-FILES = "http://framos.lawoftheland.co.uk/troggle/survey_files/"
-
-SVX_URL = 'http://framos.lawoftheland.co.uk/troggle/survex/'
-
-PYTHON_PATH = '/home/mjg/expoweb/troggle/'
-
-MEDIA_URL = 'http://framos.lawoftheland.co.uk/troggle/site_media/'
-
-MEDIA_ROOT = '/home/mjg/expoweb/troggle/media/'
-
-URL_ROOT = "http://framos.lawoftheland.co.uk/troggle/"
-
-TEMPLATE_DIRS = (
- "/home/mjg/expoweb/troggle/templates",
- # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
- # Always use forward slashes, even on Windows.
- # Don't forget to use absolute paths, not relative paths.
-)
diff --git a/troggle/localsettingsubuntu.py b/troggle/localsettingsubuntu.py
deleted file mode 100644
index 22d3d2c3f..000000000
--- a/troggle/localsettingsubuntu.py
+++ /dev/null
@@ -1,20 +0,0 @@
-DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-DATABASE_NAME = 'troggle' # Or path to database file if using sqlite3.
-DATABASE_USER = 'troggler3' # Not used with sqlite3.
-DATABASE_PASSWORD = 'ggg' # Not used with sqlite3.
-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
-PYTHON_PATH = '/home/goatchurch/expoweb/troggle/'
-
-SURVEX_DATA = '/home/goatchurch/loser/'
-CAVERN = 'cavern'
-EXPOWEB = '/home/goatchurch/expoweb'
-URL_ROOT = '/troggle/'
-
-TEMPLATE_DIRS = (
- "/home/goatchurch/expoweb/troggle/templates",
- # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
- # Always use forward slashes, even on Windows.
- # Don't forget to use absolute paths, not relative paths.
-)
-
diff --git a/troggle/localsettingswindows.py b/troggle/localsettingswindows.py
deleted file mode 100644
index 53225b2a1..000000000
--- a/troggle/localsettingswindows.py
+++ /dev/null
@@ -1,49 +0,0 @@
-DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-DATABASE_NAME = '' # Or path to database file if using sqlite3.
-DATABASE_USER = '' # Not used with sqlite3.
-DATABASE_PASSWORD = '' # Not used with sqlite3.
-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
-
-SURVEX_DATA = 'c:\\Expo\\loser\\'
-CAVERN = 'cavern'
-EXPOWEB = 'C:\\Expo\\expoweb\\'
-SURVEYS = 'E:\\surveys\\'
-SURVEY_SCANS = 'E:\\surveys\\surveyscans'
-
-LOGFILE = open(EXPOWEB+'troggle\\parsing_log.txt',"a+b")
-
-PHOTOS = 'C:\\Expo\\expoweb\\photos'
-
-URL_ROOT = 'http://127.0.0.1:8000'
-
-PYTHON_PATH = 'C:\\expoweb\\troggle\\'
-
-MEDIA_ROOT = 'C:/Expo/expoweb/troggle/media/'
-
-#FILES = "http://framos.lawoftheland.co.uk/troggle/survey_files/"
-
-EMAIL_HOST = "smtp.gmail.com"
-
-EMAIL_HOST_USER = "cuccexpo@gmail.com"
-
-EMAIL_HOST_PASSWORD = ""
-
-EMAIL_PORT=587
-
-EMAIL_USE_TLS = True
-
-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
-# trailing slash if there is a path component (optional in other cases).
-# Examples: "http://media.lawrence.com", "http://example.com/media/"
-
-
-
-
-TEMPLATE_DIRS = (
- "C:/Expo/expoweb/troggle/templates",
-
- # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
- # Always use forward slashes, even on Windows.
- # Don't forget to use absolute paths, not relative paths.
-)
\ No newline at end of file
diff --git a/troggle/manage.py b/troggle/manage.py
deleted file mode 100644
index b8c4be8eb..000000000
--- a/troggle/manage.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python
-from django.core.management import execute_manager
-try:
- import settings # Assumed to be in the same directory.
-except ImportError:
- import sys
- sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
- sys.exit(1)
-
-if __name__ == "__main__":
- execute_manager(settings)
diff --git a/troggle/media/204plan.gif b/troggle/media/204plan.gif
deleted file mode 100644
index b89da049c..000000000
Binary files a/troggle/media/204plan.gif and /dev/null differ
diff --git a/troggle/media/SilkRoadsilouetteAndrew.png b/troggle/media/SilkRoadsilouetteAndrew.png
deleted file mode 100644
index 2ab357ae7..000000000
Binary files a/troggle/media/SilkRoadsilouetteAndrew.png and /dev/null differ
diff --git a/troggle/media/css/main2.css b/troggle/media/css/main2.css
deleted file mode 100644
index fee993c15..000000000
--- a/troggle/media/css/main2.css
+++ /dev/null
@@ -1,339 +0,0 @@
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, font, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td
- {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- font-weight: inherit;
- font-style: inherit;
- font-size: 100%;
- font-family: inherit;
- vertical-align: baseline;
- }
-
-html, body {
- height: 100%
-}
-
-
-.caption { font-size: 8pt; margin-bottom: 0pt; }
-.centre { text-align: center; }
-.plus2pt { font-size: 160%; }
-
-ul
-{
- list-style: none;
-}
-
-body
-{
- background-color: white;
- color: black;
- font: 100% Verdana, Arial, Helvetica, sans-serif;
- margin: 0;
- padding: 0;
- margin-left: auto;
- margin-right: auto;
-}
-
-div#content
-{
- border: thin black dotted;
- margin: 50px;
-}
-
-
-
-
-div#footer
-{
- clear:both;
- background-color:black;
- color:white;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-#frontPageBanner{ position:relative; width:inherit; height:inherit; }
-
-div.logbookentry
-{
- text-align:left;
-}
-div.logbookentry ul.cavers
-{
- float:left;
- padding-left:20px;
- padding-right:10px;
- margin-top:0px;
-}
-td.author
-{
- background-color:yellow;
-}
-
-div.logbookentry p
-{
- margin:10px;
-}
-
-div#content div#col2
-{
- float:right;
- width:33%;
- background-color:#feeeed;
-}
-
-div#content h2
-{
- text-align:center;
- font-size:200%;
- padding-bottom:30px;
-}
-
-
-table.prevnextexpeditions
-{
- width:100%;
-}
-
-table.prevnextexpeditions td
-{
- padding: 2px;
-}
-
-table.expeditionpersonlist
-{
- width:100%;
-}
-
-table.expeditionpersonlist td
-{
- padding: 2px;
-}
-
-div#content div#col1
-{
- width:66%;
-}
-table.expeditionlogbooks td
-{
- padding: 2px;
-}
-
-ul#expeditionlist
-{
- width: 800px
-}
-
-div.survexblock
-{
- width:50%;
- background-color:#e0e0e0;
-}
-p.indent
-{
- margin-left:10px;
-}
-
-table.survexcontibutions td.date
-{ width:90px; }
-table.survexcontibutions td.roles
-{ width:100px; background-color:#feeeed; }
-table.survexcontibutions td.survexblock
-{ width:260px; background-color:#feeeed; }
-table.survexcontibutions td.trip
-{ width:280px; }
-table.survexcontibutions td.place
-{ width:140px; }
-
-#expoHeader {
- width:100%;
- position:relative;
- left:0;
- right:0;
- height:100px;
-}
-#currentLocation {
- float:right;
- background:#999;
- line-height: 80%;
- font-variant: small-caps;
- margin: 0px;
- padding: 0px;
-}
-#expoHeaderText {
- background:#999;
- position:absolute;
- bottom:0px;
- clip:rect(10px auto auto auto)
-/* filter:alpha(opacity=90);
- -moz-opacity:.90;
- opacity:.90; */
-}
-
-
-
-hr{
- margin:0;
- padding:0;
- height:1px;
- border:thin solid #000;
- border:#000;
- color:#000;
- background:#000;
-}
-
-#expoHeader h1{
- position:relative;
- bottom:-8px;
- vertical-align:top;
-}
-
-#expoFinalDate {
- display: inline;
-}
-
-div.centre img { vertical-align: middle; }
-
-h1 { text-align: center; font-size: 210%; display: inline;}
-h2 { color: #009900; }
-h3 { color: #2c105e; text-align:left; border-bottom:thin solid black; margin-bottom:1em; margin-top:1em }
-h4 { color: #0d664c; }
-h4.navbar {line-height: 0px;}
-img.onright, div.onright { vertical-align: top; float: right;
- margin-left: 10pt; margin-bottom: 10pt;
- margin-right: 8pt; }
-img.onleft, div.onleft { vertical-align: top; float: left;
- margin-right: 10pt; margin-bottom: 10pt;
- margin-left: 8pt; }
-img.icon { vertical-align: middle; }
-img.aligntop { vertical-align: top; }
-blockquote {
- font: Georgia, "Times New Roman", Times, serif;
- font-weight:bold;
- font-variant:small-caps;
- width: 400px;
- background: url(../close-quote.gif) no-repeat right bottom;
- padding-left: 25px;
- text-indent: -25px;
- text-align: right;
- vertical-align:bottom;
- color:#CCCC66;
-}
-blockquote:first-letter {
- background: url(../open-quote.gif) no-repeat left top;
- padding-left: 40px;
- font: italic 1.4em Georgia, "Times New Roman", Times, serif;
-}
-table.imgtable { margin-left: auto; margin-right: auto; }
-table.imgtable td { vertical-align: middle; text-align: center;
- padding: 10px; }
-
-table.normal { border: thin; border-top:solid ; border-left:dotted ; border-bottom:dotted; border-right:hidden ; border-width:1px;}
-table.normal td { border: thin; border-right:dotted ; border-width:1px; border-spacing:0px }
-table.normal th { border-left:thin ; border-right:thin ; text-align: left}
-
-/* "Traditional" table with borders.*/
-table.trad { margin: 0pt; border: 1px solid #000;
- border-color: #c0c0c0 #8d8d8d #8d8d8d #c0c0c0; }
-table.bigfatborder { border-width: 6px; }
-table.trad td, table.trad th { margin: 0pt; border: 1px solid #aaa;
- border-color: #8d8d8d #c0c0c0 #c0c0c0 #8d8d8d; }
-
-/*Divs for layout*/
-html, body, div.contents {
-min-height: 100%;
-height: 100%;
-width:100%;
-}
-html>body, html>body div.contents {
-height: auto;
-}
-body {
-}
-div.contents {
-position: absolute;
-top: 0;
-right: 0;
-}
-
-
-div.main {
-margin-bottom: 3em;
-}
-
-
-/* You are not expected to understand this. It is necessary. */
-table.centre { margin-left: auto; margin-right: auto; }
-table.centre td { text-align: left; }
-
-h2#tophead { text-align: center; margin-bottom: -10pt; }
-table#cavepage { width: 100%; font-size: 160%; }
-table#cavepage th#kat_no { text-align: left; width: 25%; }
-table#cavepage th#name { text-align: center; width: 50%; }
-table#cavepage th#status { text-align: right; width: 25%; }
-
-.command { color: #FF0000; }
-.comment { color: #888888; font-style:italic;}
-
-.thumbnail {
- width: 300px;
-}
-
-table {
- border: thin solid silver;
- border-collapse: collapse;
-}
-td {
- padding:0px;
- border: thin solid silver;
-}
-
-
-#nav {
-
-}
-
-.menuBarItem {
- font-variant: small-caps;
- text-align: right;
- border-top-style: none;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- border-top-width: thin;
- border-right-width: thin;
- border-bottom-width: thin;
- border-left-width: thin;
-}
-.behind {
- display: none;
-}
-div.figure {
- width: 20%;
- border: thin silver solid;
- margin: 0.5em;
- padding: 0.5em;
- display: inline;
- float: left;
-}
-div.figure p {
- text-align: left;
- font-size: smaller;
- text-indent: 0;
-}
-img.thumbnail {
- width: 100%;
-}
-br.clearfloat {
- clear:both;
-}
\ No newline at end of file
diff --git a/troggle/media/css/main3.css b/troggle/media/css/main3.css
deleted file mode 100644
index d875da9e3..000000000
--- a/troggle/media/css/main3.css
+++ /dev/null
@@ -1,374 +0,0 @@
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, font, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td
- {
-
- font-weight: inherit;
- font-style: inherit;
- font-size: 100%;
- font-family: inherit;
- vertical-align: baseline;
- }
-
-html, body {
- height: 100%;
-}
-
-
-.caption { font-size: 8pt; margin-bottom: 0pt; }
-.centre { text-align: center; }
-.plus2pt { font-size: 160%; }
-
-ul
-{
- list-style: none;
-}
-
-div.logbookentry
-{
- text-align:left;
-}
-div.logbookentry ul.cavers
-{
- float:left;
- padding-left:20px;
- padding-right:10px;
- margin-top:0px;
-}
-td.author
-{
- background-color:yellow;
-}
-
-div.logbookentry p
-{
- margin:10px;
-}
-
-div#content div#col2
-{
- float:right;
- width:33%;
- background-color:#feeeed;
-}
-
-div#content h2
-{
- text-align:center;
- font-size:200%;
- padding-bottom:30px;
-}
-
-
-table.prevnextexpeditions
-{
- width:100%;
-}
-
-table.prevnextexpeditions td
-{
- padding: 2px;
-}
-
-table.expeditionpersonlist
-{
- width:100%;
-}
-
-table.expeditionpersonlist td
-{
- padding: 2px;
-}
-
-div#content div#col1
-{
- width:66%;
-}
-table.expeditionlogbooks td
-{
- padding: 2px;
-}
-
-ul#expeditionlist
-{
- width: 300px
-}
-
-div.survexblock
-{
- width:50%;
- background-color:#e0e0e0;
-}
-p.indent
-{
- margin-left:10px;
-}
-
-
-#currentLocation {
- float:right;
- background:#999;
- line-height: 80%;
- font-variant: small-caps;
- margin: 0px;
- padding: 0px;
-}
-
-
-
-hr{
- margin:0;
- padding:0;
- height:1px;
- border:thin solid #000;
- border:#000;
- color:#000;
- background:#000;
-}
-
-div.centre img { vertical-align: middle; }
-
-h1 { text-align: center; font-size: 210%; display: inline;}
-h2 { color: #009900; }
-h3 { color: #000 text-align:left; border-bottom:thin solid black; margin-bottom:1em; margin-top:1em; font-weight:bold}
-h4 { color: #0d664c; }
-h4.navbar {line-height: 0px;}
-img.onright, div.onright { vertical-align: top; float: right;
- margin-left: 10pt; margin-bottom: 10pt;
- margin-right: 8pt; }
-img.onleft, div.onleft { vertical-align: top; float: left;
- margin-right: 10pt; margin-bottom: 10pt;
- margin-left: 8pt; }
-img.icon { vertical-align: middle; }
-img.aligntop { vertical-align: top; }
-blockquote {
- font: Georgia, "Times New Roman", Times, serif;
- font-weight:bold;
- font-variant:small-caps;
- width: 400px;
- background: url(../close-quote.gif) no-repeat right bottom;
- padding-left: 25px;
- text-indent: -25px;
- text-align: right;
- vertical-align:bottom;
- color:#CCCC66;
-}
-blockquote:first-letter {
- background: url(../open-quote.gif) no-repeat left top;
- padding-left: 40px;
- font: italic 1.4em Georgia, "Times New Roman", Times, serif;
-}
-table.imgtable { margin-left: auto; margin-right: auto; }
-table.imgtable td { vertical-align: middle; text-align: center;
- padding: 10px; }
-
-table.normal { border: thin; border-top:solid ; border-left:dotted ; border-bottom:dotted; border-right:hidden ; border-width:1px;}
-table.normal td { border: thin; border-right:dotted ; border-width:1px; border-spacing:0px }
-table.normal th { border-left:thin ; border-right:thin ; text-align: left}
-
-/* "Traditional" table with borders.*/
-table.trad { margin: 0pt; border: 1px solid #000;
- border-color: #c0c0c0 #8d8d8d #8d8d8d #c0c0c0; }
-table.bigfatborder { border-width: 6px; }
-table.trad td, table.trad th { margin: 0pt; border: 1px solid #aaa;
- border-color: #8d8d8d #c0c0c0 #c0c0c0 #8d8d8d; }
-
-
-/* You are not expected to understand this. It is necessary. */
-/* The above is the most fucktarded comment I have ever read :-) AC, 24 APR 2009 */
-table.centre { margin-left: auto; margin-right: auto; }
-table.centre td { text-align: left; }
-
-h2#tophead { text-align: center; margin-bottom: -10pt; }
-table#cavepage { width: 100%; font-size: 160%; }
-table#cavepage th#kat_no { text-align: left; width: 25%; }
-table#cavepage th#name { text-align: center; width: 50%; }
-table#cavepage th#status { text-align: right; width: 25%; }
-
-.command { color: #FF0000; }
-.comment { color: #888888; font-style:italic;}
-
-.thumbnail {
- width: 300px;
-}
-
-table {
- border: thin solid silver;
- border-collapse: collapse;
-}
-td {
- padding:0px;
- border: thin solid silver;
-}
-
-
-.redtext{
- color:#F00;
- }
-
-a.redtext:link {
- color:#F00;
-
-}
-
-.redtext
-
-.menuBarItem {
- font-variant: small-caps;
- text-align: right;
- border-top-style: none;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- border-top-width: thin;
- border-right-width: thin;
- border-bottom-width: thin;
- border-left-width: thin;
-}
-.behind {
- display: none;
-}
-div.figure {
- width: 20%;
- border: thin white solid;
- margin: 0.5em;
- padding: 0.5em;
- display: inline;
- float: left;
-}
-div.figure p {
- text-align: left;
- font-size: smaller;
- text-indent: 0;
-}
-img.thumbnail {
- width: 100%;
-}
-
-#error {
- color: red;
-}
-
-div#header {
- position:fixed;
- left:100px;
- right:100px;
- top:0;
- margin-left:auto;
- margin-right:auto;
- height:50px;
- background-image: url( ../204plan.gif);
- border-bottom:thin solid #000;
- font-family: Arial, Helvetica, sans-serif;
- font-variant: normal;
-}
-
-
-div#editLinks {
- position:absolute;
- background: #999;
- bottom:0px;
- right:0px;
- font-family: "Courier New", Courier, monospace;
- filter:alpha(opacity=75);
- -moz-opacity:.75;
- opacity:.75;
-}
-
-div#editLinks a{
- color:#FFF;
-}
-
-div#content {
- margin-top: 50px;
- margin-left: 120px;
- margin-right: 120px;
- padding-top: 10px;
- padding-left: 5em;
- padding-right: 5em;
- background:#CCC;
-}
-
-
-.footer {
- position:fixed;
- width:100%;
- bottom:0;
- left:0;
-}
-
-body {
- background-color:#000;
- padding-bottom:100px;
-
-}
-
-h1 {
- margin-top:0;
- margin-left:10px;
- vertical-align:top;
-}
-
-
-.rightMargin {
- position:absolute;
- z-index:-2;
- width:130px;
- right:0px;
- top:0px;
- clip: rect(auto,auto,auto,auto);
- background:#000;
-}
-
-.leftMargin {
- position:absolute;
- z-index:-2;
- width:130px;
- top:0px;
- left:0px;
- clip: rect(auto,100px,auto,auto,);
- background:#000;
-}
-
-#footerLinks{
- position:fixed;
- text-align: center;
- bottom:0;
- left:0;
- width:100%;
- background-color:#000;
- color:#999
-}
-
-#footerLinks a{
- color:#FFF
-}
-
-/*.fadeIn {
- display: none;
-}*/
-
-#timeMachine {
- width:auto;
- right:0;
- left:auto;
-}
-
-#surveyHover {
- width:auto;
- right:auto;
- left:auto;
-}
-
-#col1 {
- width:60%
-}
-
-#quicksearch {
- margin-left:40px;
-}
\ No newline at end of file
diff --git a/troggle/media/css/nav.css b/troggle/media/css/nav.css
deleted file mode 100644
index 1c97c51e0..000000000
--- a/troggle/media/css/nav.css
+++ /dev/null
@@ -1,12 +0,0 @@
-div#nav {
- position:fixed;
- width: 12em;
- background: rgb(153, 153, 153);
- margin-top: 0px;
- margin-left: 120px;
- border-top: thin black solid;
-}
-
-div#content {
- padding-left:240px;
-}
\ No newline at end of file
diff --git a/troggle/media/eieshole.jpg b/troggle/media/eieshole.jpg
deleted file mode 100644
index 061bb3613..000000000
Binary files a/troggle/media/eieshole.jpg and /dev/null differ
diff --git a/troggle/media/expoBanner.gif b/troggle/media/expoBanner.gif
deleted file mode 100644
index 232e9add8..000000000
Binary files a/troggle/media/expoBanner.gif and /dev/null differ
diff --git a/troggle/media/goesser.jpg b/troggle/media/goesser.jpg
deleted file mode 100644
index f40675b85..000000000
Binary files a/troggle/media/goesser.jpg and /dev/null differ
diff --git a/troggle/media/js/base.js b/troggle/media/js/base.js
deleted file mode 100644
index 0dc562bc5..000000000
--- a/troggle/media/js/base.js
+++ /dev/null
@@ -1,74 +0,0 @@
-
-$(document).ready(function() {
-
-$('.searchable li').quicksearch({
- position: 'before',
- attached: 'ul.searchable',
- labelText: '',
- loaderText: '',
- delay: 100
-})
-
-$('table.searchable tr').quicksearch({
- position: 'before',
- attached: 'table.searchable:first',
-});
-
-$(".toggleEyeCandy").click(function () {
- $(".leftMargin,.rightMargin").toggle("fade");
- $(".toggleEyeCandy").toggle();
- });
-
-$(".nav").css('opacity','7')
-$(".footer").hide();
-$(".fadeIn").hide();
-setTimeout("$('.leftMargin.fadeIn').fadeIn(3000);",1000);
-setTimeout("$('.rightMargin.fadeIn').fadeIn(3000);",2000);
-
-
-/*$("#footerLinks").hover(
- function() {$(".footer").fadeIn("slow")},
- function() {$(".footer").fadeOut("slow")}
-);*/
-
-function linkHover(hoverLink,image){
-
-$(hoverLink).hover(
- function() {
- $(image).fadeIn("slow");
- $(hoverLink).css("background","gray");
- },
- function() {
- $(image).fadeOut("slow");
- $(hoverLink).css("background","black");
- }
-);
-
-
-
-};
-
-linkHover("#expoWebsiteLink","#richardBanner");
-linkHover("#cuccLink","#timeMachine");
-linkHover("#surveyBinderLink","#surveyHover");
-linkHover("#troggle","#timeMachine");
-
-
-});
-
-function contentHeight(){
-setMaxHeight($(".rightMargin,#content,.leftMargin,#col2"),$("#content"));
-};
-
-function setMaxHeight(group, target) {
- tallest = 0;
- group.each(function() {
- thisHeight = $(this).height();
- if(thisHeight > tallest) {
- tallest = thisHeight;
- }
- });
- target.height(tallest);
-}
-
-
diff --git a/troggle/media/js/jquery.js b/troggle/media/js/jquery.js
deleted file mode 100644
index 926357433..000000000
--- a/troggle/media/js/jquery.js
+++ /dev/null
@@ -1,4376 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.3.2
- * http://jquery.com/
- *
- * Copyright (c) 2009 John Resig
- * Dual licensed under the MIT and GPL licenses.
- * http://docs.jquery.com/License
- *
- * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
- * Revision: 6246
- */
-(function(){
-
-var
- // Will speed up references to window, and allows munging its name.
- window = this,
- // Will speed up references to undefined, and allows munging its name.
- undefined,
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
- // Map over the $ in case of overwrite
- _$ = window.$,
-
- jQuery = window.jQuery = window.$ = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- return new jQuery.fn.init( selector, context );
- },
-
- // A simple way to check for HTML strings or ID strings
- // (both of which we optimize for)
- quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
- // Is it a simple selector
- isSimple = /^.[^:#\[\.,]*$/;
-
-jQuery.fn = jQuery.prototype = {
- init: function( selector, context ) {
- // Make sure that a selection was provided
- selector = selector || document;
-
- // Handle $(DOMElement)
- if ( selector.nodeType ) {
- this[0] = selector;
- this.length = 1;
- this.context = selector;
- return this;
- }
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- // Are we dealing with HTML string or an ID?
- var match = quickExpr.exec( selector );
-
- // Verify a match, and that no context was specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] )
- selector = jQuery.clean( [ match[1] ], context );
-
- // HANDLE: $("#id")
- else {
- var elem = document.getElementById( match[3] );
-
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem && elem.id != match[3] )
- return jQuery().find( selector );
-
- // Otherwise, we inject the element directly into the jQuery object
- var ret = jQuery( elem || [] );
- ret.context = document;
- ret.selector = selector;
- return ret;
- }
-
- // HANDLE: $(expr, [context])
- // (which is just equivalent to: $(content).find(expr)
- } else
- return jQuery( context ).find( selector );
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) )
- return jQuery( document ).ready( selector );
-
- // Make sure that old selector state is passed along
- if ( selector.selector && selector.context ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return this.setArray(jQuery.isArray( selector ) ?
- selector :
- jQuery.makeArray(selector));
- },
-
- // Start with an empty selector
- selector: "",
-
- // The current version of jQuery being used
- jquery: "1.3.2",
-
- // The number of elements contained in the matched element set
- size: function() {
- return this.length;
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num === undefined ?
-
- // Return a 'clean' array
- Array.prototype.slice.call( this ) :
-
- // Return just the object
- this[ num ];
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems, name, selector ) {
- // Build a new jQuery matched element set
- var ret = jQuery( elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
-
- ret.context = this.context;
-
- if ( name === "find" )
- ret.selector = this.selector + (this.selector ? " " : "") + selector;
- else if ( name )
- ret.selector = this.selector + "." + name + "(" + selector + ")";
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Force the current matched set of elements to become
- // the specified array of elements (destroying the stack in the process)
- // You should use pushStack() in order to do this, but maintain the stack
- setArray: function( elems ) {
- // Resetting the length to 0, then using the native Array push
- // is a super-fast way to populate an object with array-like properties
- this.length = 0;
- Array.prototype.push.apply( this, elems );
-
- return this;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem && elem.jquery ? elem[0] : elem
- , this );
- },
-
- attr: function( name, value, type ) {
- var options = name;
-
- // Look for the case where we're accessing a style value
- if ( typeof name === "string" )
- if ( value === undefined )
- return this[0] && jQuery[ type || "attr" ]( this[0], name );
-
- else {
- options = {};
- options[ name ] = value;
- }
-
- // Check to see if we're setting style values
- return this.each(function(i){
- // Set all the styles
- for ( name in options )
- jQuery.attr(
- type ?
- this.style :
- this,
- name, jQuery.prop( this, options[ name ], type, i, name )
- );
- });
- },
-
- css: function( key, value ) {
- // ignore negative width and height values
- if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
- value = undefined;
- return this.attr( key, value, "curCSS" );
- },
-
- text: function( text ) {
- if ( typeof text !== "object" && text != null )
- return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-
- var ret = "";
-
- jQuery.each( text || this, function(){
- jQuery.each( this.childNodes, function(){
- if ( this.nodeType != 8 )
- ret += this.nodeType != 1 ?
- this.nodeValue :
- jQuery.fn.text( [ this ] );
- });
- });
-
- return ret;
- },
-
- wrapAll: function( html ) {
- if ( this[0] ) {
- // The elements to wrap the target around
- var wrap = jQuery( html, this[0].ownerDocument ).clone();
-
- if ( this[0].parentNode )
- wrap.insertBefore( this[0] );
-
- wrap.map(function(){
- var elem = this;
-
- while ( elem.firstChild )
- elem = elem.firstChild;
-
- return elem;
- }).append(this);
- }
-
- return this;
- },
-
- wrapInner: function( html ) {
- return this.each(function(){
- jQuery( this ).contents().wrapAll( html );
- });
- },
-
- wrap: function( html ) {
- return this.each(function(){
- jQuery( this ).wrapAll( html );
- });
- },
-
- append: function() {
- return this.domManip(arguments, true, function(elem){
- if (this.nodeType == 1)
- this.appendChild( elem );
- });
- },
-
- prepend: function() {
- return this.domManip(arguments, true, function(elem){
- if (this.nodeType == 1)
- this.insertBefore( elem, this.firstChild );
- });
- },
-
- before: function() {
- return this.domManip(arguments, false, function(elem){
- this.parentNode.insertBefore( elem, this );
- });
- },
-
- after: function() {
- return this.domManip(arguments, false, function(elem){
- this.parentNode.insertBefore( elem, this.nextSibling );
- });
- },
-
- end: function() {
- return this.prevObject || jQuery( [] );
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: [].push,
- sort: [].sort,
- splice: [].splice,
-
- find: function( selector ) {
- if ( this.length === 1 ) {
- var ret = this.pushStack( [], "find", selector );
- ret.length = 0;
- jQuery.find( selector, this[0], ret );
- return ret;
- } else {
- return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
- return jQuery.find( selector, elem );
- })), "find", selector );
- }
- },
-
- clone: function( events ) {
- // Do the clone
- var ret = this.map(function(){
- if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
- // IE copies events bound via attachEvent when
- // using cloneNode. Calling detachEvent on the
- // clone will also remove the events from the orignal
- // In order to get around this, we use innerHTML.
- // Unfortunately, this means some modifications to
- // attributes in IE that are actually only stored
- // as properties will not be copied (such as the
- // the name attribute on an input).
- var html = this.outerHTML;
- if ( !html ) {
- var div = this.ownerDocument.createElement("div");
- div.appendChild( this.cloneNode(true) );
- html = div.innerHTML;
- }
-
- return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
- } else
- return this.cloneNode(true);
- });
-
- // Copy the events from the original to the clone
- if ( events === true ) {
- var orig = this.find("*").andSelf(), i = 0;
-
- ret.find("*").andSelf().each(function(){
- if ( this.nodeName !== orig[i].nodeName )
- return;
-
- var events = jQuery.data( orig[i], "events" );
-
- for ( var type in events ) {
- for ( var handler in events[ type ] ) {
- jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
- }
- }
-
- i++;
- });
- }
-
- // Return the cloned set
- return ret;
- },
-
- filter: function( selector ) {
- return this.pushStack(
- jQuery.isFunction( selector ) &&
- jQuery.grep(this, function(elem, i){
- return selector.call( elem, i );
- }) ||
-
- jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
- return elem.nodeType === 1;
- }) ), "filter", selector );
- },
-
- closest: function( selector ) {
- var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
- closer = 0;
-
- return this.map(function(){
- var cur = this;
- while ( cur && cur.ownerDocument ) {
- if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
- jQuery.data(cur, "closest", closer);
- return cur;
- }
- cur = cur.parentNode;
- closer++;
- }
- });
- },
-
- not: function( selector ) {
- if ( typeof selector === "string" )
- // test special case where just one selector is passed in
- if ( isSimple.test( selector ) )
- return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
- else
- selector = jQuery.multiFilter( selector, this );
-
- var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
- return this.filter(function() {
- return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
- });
- },
-
- add: function( selector ) {
- return this.pushStack( jQuery.unique( jQuery.merge(
- this.get(),
- typeof selector === "string" ?
- jQuery( selector ) :
- jQuery.makeArray( selector )
- )));
- },
-
- is: function( selector ) {
- return !!selector && jQuery.multiFilter( selector, this ).length > 0;
- },
-
- hasClass: function( selector ) {
- return !!selector && this.is( "." + selector );
- },
-
- val: function( value ) {
- if ( value === undefined ) {
- var elem = this[0];
-
- if ( elem ) {
- if( jQuery.nodeName( elem, 'option' ) )
- return (elem.attributes.value || {}).specified ? elem.value : elem.text;
-
- // We need to handle select boxes special
- if ( jQuery.nodeName( elem, "select" ) ) {
- var index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type == "select-one";
-
- // Nothing was selected
- if ( index < 0 )
- return null;
-
- // Loop through all the selected options
- for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
- var option = options[ i ];
-
- if ( option.selected ) {
- // Get the specifc value for the option
- value = jQuery(option).val();
-
- // We don't need an array for one selects
- if ( one )
- return value;
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- }
-
- // Everything else, we just grab the value
- return (elem.value || "").replace(/\r/g, "");
-
- }
-
- return undefined;
- }
-
- if ( typeof value === "number" )
- value += '';
-
- return this.each(function(){
- if ( this.nodeType != 1 )
- return;
-
- if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
- this.checked = (jQuery.inArray(this.value, value) >= 0 ||
- jQuery.inArray(this.name, value) >= 0);
-
- else if ( jQuery.nodeName( this, "select" ) ) {
- var values = jQuery.makeArray(value);
-
- jQuery( "option", this ).each(function(){
- this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
- jQuery.inArray( this.text, values ) >= 0);
- });
-
- if ( !values.length )
- this.selectedIndex = -1;
-
- } else
- this.value = value;
- });
- },
-
- html: function( value ) {
- return value === undefined ?
- (this[0] ?
- this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
- null) :
- this.empty().append( value );
- },
-
- replaceWith: function( value ) {
- return this.after( value ).remove();
- },
-
- eq: function( i ) {
- return this.slice( i, +i + 1 );
- },
-
- slice: function() {
- return this.pushStack( Array.prototype.slice.apply( this, arguments ),
- "slice", Array.prototype.slice.call(arguments).join(",") );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function(elem, i){
- return callback.call( elem, i, elem );
- }));
- },
-
- andSelf: function() {
- return this.add( this.prevObject );
- },
-
- domManip: function( args, table, callback ) {
- if ( this[0] ) {
- var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
- scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
- first = fragment.firstChild;
-
- if ( first )
- for ( var i = 0, l = this.length; i < l; i++ )
- callback.call( root(this[i], first), this.length > 1 || i > 0 ?
- fragment.cloneNode(true) : fragment );
-
- if ( scripts )
- jQuery.each( scripts, evalScript );
- }
-
- return this;
-
- function root( elem, cur ) {
- return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
- (elem.getElementsByTagName("tbody")[0] ||
- elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
- elem;
- }
- }
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-function evalScript( i, elem ) {
- if ( elem.src )
- jQuery.ajax({
- url: elem.src,
- async: false,
- dataType: "script"
- });
-
- else
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
-
- if ( elem.parentNode )
- elem.parentNode.removeChild( elem );
-}
-
-function now(){
- return +new Date;
-}
-
-jQuery.extend = jQuery.fn.extend = function() {
- // copy reference to target object
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) )
- target = {};
-
- // extend jQuery itself if only one argument is passed
- if ( length == i ) {
- target = this;
- --i;
- }
-
- for ( ; i < length; i++ )
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null )
- // Extend the base object
- for ( var name in options ) {
- var src = target[ name ], copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy )
- continue;
-
- // Recurse if we're merging object values
- if ( deep && copy && typeof copy === "object" && !copy.nodeType )
- target[ name ] = jQuery.extend( deep,
- // Never move original objects, clone them
- src || ( copy.length != null ? [ ] : { } )
- , copy );
-
- // Don't bring in undefined values
- else if ( copy !== undefined )
- target[ name ] = copy;
-
- }
-
- // Return the modified object
- return target;
-};
-
-// exclude the following css properties to add px
-var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
- // cache defaultView
- defaultView = document.defaultView || {},
- toString = Object.prototype.toString;
-
-jQuery.extend({
- noConflict: function( deep ) {
- window.$ = _$;
-
- if ( deep )
- window.jQuery = _jQuery;
-
- return jQuery;
- },
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return toString.call(obj) === "[object Function]";
- },
-
- isArray: function( obj ) {
- return toString.call(obj) === "[object Array]";
- },
-
- // check if an element is in a (or is an) XML document
- isXMLDoc: function( elem ) {
- return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
- !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
- },
-
- // Evalulates a script in a global context
- globalEval: function( data ) {
- if ( data && /\S/.test(data) ) {
- // Inspired by code by Andrea Giammarchi
- // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
- var head = document.getElementsByTagName("head")[0] || document.documentElement,
- script = document.createElement("script");
-
- script.type = "text/javascript";
- if ( jQuery.support.scriptEval )
- script.appendChild( document.createTextNode( data ) );
- else
- script.text = data;
-
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
- // This arises when a base node is used (#2709).
- head.insertBefore( script, head.firstChild );
- head.removeChild( script );
- }
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
- },
-
- // args is for internal usage only
- each: function( object, callback, args ) {
- var name, i = 0, length = object.length;
-
- if ( args ) {
- if ( length === undefined ) {
- for ( name in object )
- if ( callback.apply( object[ name ], args ) === false )
- break;
- } else
- for ( ; i < length; )
- if ( callback.apply( object[ i++ ], args ) === false )
- break;
-
- // A special, fast, case for the most common use of each
- } else {
- if ( length === undefined ) {
- for ( name in object )
- if ( callback.call( object[ name ], name, object[ name ] ) === false )
- break;
- } else
- for ( var value = object[0];
- i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
- }
-
- return object;
- },
-
- prop: function( elem, value, type, i, name ) {
- // Handle executable functions
- if ( jQuery.isFunction( value ) )
- value = value.call( elem, i );
-
- // Handle passing in a number to a CSS property
- return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
- value + "px" :
- value;
- },
-
- className: {
- // internal only, use addClass("class")
- add: function( elem, classNames ) {
- jQuery.each((classNames || "").split(/\s+/), function(i, className){
- if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
- elem.className += (elem.className ? " " : "") + className;
- });
- },
-
- // internal only, use removeClass("class")
- remove: function( elem, classNames ) {
- if (elem.nodeType == 1)
- elem.className = classNames !== undefined ?
- jQuery.grep(elem.className.split(/\s+/), function(className){
- return !jQuery.className.has( classNames, className );
- }).join(" ") :
- "";
- },
-
- // internal only, use hasClass("class")
- has: function( elem, className ) {
- return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
- }
- },
-
- // A method for quickly swapping in/out CSS properties to get correct calculations
- swap: function( elem, options, callback ) {
- var old = {};
- // Remember the old values, and insert the new ones
- for ( var name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- callback.call( elem );
-
- // Revert the old values
- for ( var name in options )
- elem.style[ name ] = old[ name ];
- },
-
- css: function( elem, name, force, extra ) {
- if ( name == "width" || name == "height" ) {
- var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
-
- function getWH() {
- val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
-
- if ( extra === "border" )
- return;
-
- jQuery.each( which, function() {
- if ( !extra )
- val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
- if ( extra === "margin" )
- val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
- else
- val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
- });
- }
-
- if ( elem.offsetWidth !== 0 )
- getWH();
- else
- jQuery.swap( elem, props, getWH );
-
- return Math.max(0, Math.round(val));
- }
-
- return jQuery.curCSS( elem, name, force );
- },
-
- curCSS: function( elem, name, force ) {
- var ret, style = elem.style;
-
- // We need to handle opacity special in IE
- if ( name == "opacity" && !jQuery.support.opacity ) {
- ret = jQuery.attr( style, "opacity" );
-
- return ret == "" ?
- "1" :
- ret;
- }
-
- // Make sure we're using the right name for getting the float value
- if ( name.match( /float/i ) )
- name = styleFloat;
-
- if ( !force && style && style[ name ] )
- ret = style[ name ];
-
- else if ( defaultView.getComputedStyle ) {
-
- // Only "float" is needed here
- if ( name.match( /float/i ) )
- name = "float";
-
- name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
-
- var computedStyle = defaultView.getComputedStyle( elem, null );
-
- if ( computedStyle )
- ret = computedStyle.getPropertyValue( name );
-
- // We should always get a number back from opacity
- if ( name == "opacity" && ret == "" )
- ret = "1";
-
- } else if ( elem.currentStyle ) {
- var camelCase = name.replace(/\-(\w)/g, function(all, letter){
- return letter.toUpperCase();
- });
-
- ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
- // Remember the original values
- var left = style.left, rsLeft = elem.runtimeStyle.left;
-
- // Put in the new values to get a computed value out
- elem.runtimeStyle.left = elem.currentStyle.left;
- style.left = ret || 0;
- ret = style.pixelLeft + "px";
-
- // Revert the changed values
- style.left = left;
- elem.runtimeStyle.left = rsLeft;
- }
- }
-
- return ret;
- },
-
- clean: function( elems, context, fragment ) {
- context = context || document;
-
- // !context.createElement fails in IE with an error but returns typeof 'object'
- if ( typeof context.createElement === "undefined" )
- context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
-
- // If a single string is passed in and it's a single tag
- // just do a createElement and skip the rest
- if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
- var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
- if ( match )
- return [ context.createElement( match[1] ) ];
- }
-
- var ret = [], scripts = [], div = context.createElement("div");
-
- jQuery.each(elems, function(i, elem){
- if ( typeof elem === "number" )
- elem += '';
-
- if ( !elem )
- return;
-
- // Convert html string into DOM nodes
- if ( typeof elem === "string" ) {
- // Fix "XHTML"-style tags in all browsers
- elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
- return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
- all :
- front + ">" + tag + ">";
- });
-
- // Trim whitespace, otherwise indexOf won't work as expected
- var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
-
- var wrap =
- // option or optgroup
- !tags.indexOf("", "" ] ||
-
- !tags.indexOf("", "" ] ||
-
- tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
- [ 1, "" ] ||
-
- !tags.indexOf("
", "" ] ||
-
- // matched above
- (!tags.indexOf(" | ", "
" ] ||
-
- !tags.indexOf("", "" ] ||
-
- // IE can't serialize and
-
-
-
-
-{% block head %}{% endblock %}
-
-
-
-
-
-
- {% block nav %}
-
- {% endblock %}
-
-
-
-
-
- {% block contentheader %}
- {% endblock %}
-
- {% block content %}
- REPLACE : The content
- {% endblock %}
-
-
-
-
-
-
-{% block margins %}
-
-
-{% endblock margins %}
-
-
-
-
-
-