From 50d753a87b5f6bc4fe31e222a37796cf903133f7 Mon Sep 17 00:00:00 2001 From: Philip Sargent Date: Sun, 24 May 2020 01:57:06 +0100 Subject: [PATCH] Convert codebase for python3 usage --- core/fileAbstraction.py | 9 ++- core/forms.py | 10 +-- core/models.py | 101 +++++++++++++----------- core/models_survex.py | 16 ++-- core/templatetags/link.py | 2 +- core/templatetags/wiki_markup.py | 6 +- core/view_surveys.py | 40 +++++----- core/views.py | 10 +-- core/views_caves.py | 4 +- core/views_logbooks.py | 12 ++- core/views_other.py | 4 +- core/views_survex.py | 3 +- databaseReset.py | 10 +-- docker/requirements.txt | 10 ++- export/toqms.py | 4 +- flatpages/tests.py | 2 +- flatpages/views.py | 35 ++++---- imagekit/management/commands/ikflush.py | 4 +- imagekit/models.py | 9 +-- imagekit/options.py | 2 +- imagekit/specs.py | 2 +- imagekit/tests.py | 2 +- logbooksdump.py | 12 ++- middleware.py | 2 +- modelviz.py | 12 +-- parsers/QMs.py | 10 +-- parsers/caves.py | 9 ++- parsers/cavetab.py | 2 +- parsers/logbooks.py | 39 ++++----- parsers/people.py | 10 +-- parsers/subcaves.py | 2 +- parsers/survex.py | 64 +++++++-------- parsers/surveys.py | 28 +++---- pathreport.py | 8 +- profiles/views.py | 6 +- settings.py | 32 +++++--- urls.py | 10 +-- utils.py | 6 +- 38 files changed, 288 insertions(+), 261 deletions(-) mode change 120000 => 100644 docker/requirements.txt diff --git a/core/fileAbstraction.py b/core/fileAbstraction.py index 86191b7..0ebd6eb 100644 --- a/core/fileAbstraction.py +++ b/core/fileAbstraction.py @@ -1,6 +1,7 @@ import troggle.settings as settings import os -import urllib +import urllib.request, urllib.parse, urllib.error +from functools import reduce def urljoin(x, y): return x + "/" + y @@ -26,8 +27,8 @@ def listdir(*path): else: c = "" c = c.replace("#", "%23") - print("FILE: ", settings.FILES + "listdir/" + c) - return urllib.urlopen(settings.FILES + "listdir/" + c).read() + print(("FILE: ", settings.FILES + "listdir/" + c)) + return urllib.request.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] == "/"] @@ -39,5 +40,5 @@ def readFile(*path): try: f = open(os.path.join(settings.FILES, *path)) except: - f = urllib.urlopen(settings.FILES + "download/" + reduce(urljoin, path)) + f = urllib.request.urlopen(settings.FILES + "download/" + reduce(urljoin, path)) return f.read() \ No newline at end of file diff --git a/core/forms.py b/core/forms.py index 8265178..b8d2e07 100644 --- a/core/forms.py +++ b/core/forms.py @@ -1,5 +1,5 @@ from django.forms import ModelForm -from models import Cave, Person, PersonExpedition, LogbookEntry, QM, Expedition, Entrance, CaveAndEntrance +from .models import Cave, Person, PersonExpedition, LogbookEntry, QM, Expedition, Entrance, CaveAndEntrance import django.forms as forms from django.forms.models import modelformset_factory from django.contrib.admin.widgets import AdminDateWidget @@ -114,8 +114,7 @@ def getTripForm(expedition): class TripForm(forms.Form): date = forms.DateField() title = forms.CharField(max_length=200) - caves = [cave.reference() for cave in Cave.objects.all()] - caves.sort() + caves = sorted([cave.reference() for cave in Cave.objects.all()]) caves = ["-----"] + caves cave = forms.ChoiceField([(c, c) for c in caves], required=False) location = forms.CharField(max_length=200, required=False) @@ -123,7 +122,7 @@ def getTripForm(expedition): html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30})) def clean(self): - print(dir(self)) + print((dir(self))) if self.cleaned_data.get("caveOrLocation") == "cave" and not self.cleaned_data.get("cave"): self._errors["cave"] = self.error_class(["This field is required"]) if self.cleaned_data.get("caveOrLocation") == "location" and not self.cleaned_data.get("location"): @@ -131,8 +130,7 @@ def getTripForm(expedition): return self.cleaned_data class PersonTripForm(forms.Form): - names = [get_name(pe) for pe in PersonExpedition.objects.filter(expedition = expedition)] - names.sort() + names = sorted([get_name(pe) for pe in PersonExpedition.objects.filter(expedition = expedition)]) names = ["-----"] + names name = forms.ChoiceField([(n, n) for n in names]) TU = forms.FloatField(required=False) diff --git a/core/models.py b/core/models.py index 5b9f48c..dc51024 100644 --- a/core/models.py +++ b/core/models.py @@ -1,5 +1,18 @@ -import urllib, urlparse, string, os, datetime, logging, re +import string +import os +import datetime +import logging +import re import subprocess + +from urllib.request import * +from urllib.parse import * +from urllib.error import * +from decimal import Decimal, getcontext +getcontext().prec=2 #use 2 significant figures for decimal calculations + +import settings + from django.forms import ModelForm from django.db import models from django.contrib import admin @@ -8,12 +21,8 @@ from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.db.models import Min, Max from django.conf import settings -from decimal import Decimal, getcontext from django.core.urlresolvers import reverse -from imagekit.models import ImageModel from django.template import Context, loader -import settings -getcontext().prec=2 #use 2 significant figures for decimal calculations from troggle.core.models_survex import * @@ -30,7 +39,7 @@ def get_related_by_wikilinks(wiki_text): number = qmdict['number']) res.append(qm) except QM.DoesNotExist: - print('fail on '+str(wikilink)) + print(('fail on '+str(wikilink))) return res @@ -52,7 +61,7 @@ class TroggleModel(models.Model): return self._meta.object_name def get_admin_url(self): - return urlparse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk)) + return urllib.parse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk)) class Meta: abstract = True @@ -64,7 +73,7 @@ class TroggleImageModel(models.Model): return self._meta.object_name def get_admin_url(self): - return urlparse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk)) + return urllib.parse.urljoin(settings.URL_ROOT, "/admin/core/" + self.object_name().lower() + "/" + str(self.pk)) class Meta: @@ -85,7 +94,7 @@ class Expedition(TroggleModel): get_latest_by = 'year' def get_absolute_url(self): - return urlparse.urljoin(settings.URL_ROOT, reverse('expedition', args=[self.year])) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('expedition', args=[self.year])) # construction function. should be moved out def get_expedition_day(self, date): @@ -117,10 +126,9 @@ class ExpeditionDay(TroggleModel): personexpeditions = self.persontrip_set.filter(expeditionday=self) return personexpeditions and personexpeditions[0] or None -# -# single Person, can go on many years -# class Person(TroggleModel): + """single Person, can go on many years + """ first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) fullname = models.CharField(max_length=200) @@ -132,7 +140,7 @@ class Person(TroggleModel): orderref = models.CharField(max_length=200) # for alphabetic user = models.OneToOneField(User, null=True, blank=True) def get_absolute_url(self): - return urlparse.urljoin(settings.URL_ROOT,reverse('person',kwargs={'first_name':self.first_name,'last_name':self.last_name})) + return urllib.parse.urljoin(settings.URL_ROOT,reverse('person',kwargs={'first_name':self.first_name,'last_name':self.last_name})) class Meta: verbose_name_plural = "People" @@ -153,7 +161,7 @@ class Person(TroggleModel): for personexpedition in self.personexpedition_set.all(): if not personexpedition.is_guest: - print(personexpedition.expedition.year) + print((personexpedition.expedition.year)) notability += Decimal(1) / (max_expo_val - int(personexpedition.expedition.year)) return notability @@ -178,10 +186,9 @@ class Person(TroggleModel): #self.notability = 0.0 # set temporarily -# -# Person's attenance to one Expo -# class PersonExpedition(TroggleModel): + """Person's attendance to one Expo + """ expedition = models.ForeignKey(Expedition) person = models.ForeignKey(Person) slugfield = models.SlugField(max_length=50,blank=True,null=True) @@ -213,7 +220,6 @@ class PersonExpedition(TroggleModel): 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: @@ -223,7 +229,7 @@ class PersonExpedition(TroggleModel): return self.person.first_name def get_absolute_url(self): - return urlparse.urljoin(settings.URL_ROOT, reverse('personexpedition',kwargs={'first_name':self.person.first_name,'last_name':self.person.last_name,'year':self.expedition.year})) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('personexpedition',kwargs={'first_name':self.person.first_name,'last_name':self.person.last_name,'year':self.expedition.year})) def surveyedleglength(self): survexblocks = [personrole.survexblock for personrole in self.personrole_set.all() ] @@ -238,11 +244,9 @@ class PersonExpedition(TroggleModel): res = self.persontrip_set.all().aggregate(day_max=Max("expeditionday__date")) return res["day_max"] -# -# Single parsed entry from Logbook -# class LogbookEntry(TroggleModel): - + """Single parsed entry from Logbook + """ LOGBOOK_ENTRY_TYPES = ( ("wiki", "Wiki style logbook"), ("html", "Html style logbook") @@ -265,22 +269,27 @@ class LogbookEntry(TroggleModel): ordering = ('-date',) def __getattribute__(self, item): - if item == "cave": #Allow a logbookentries cave to be directly accessed despite not having a proper foreignkey - return CaveSlug.objects.get(slug = self.cave_slug).cave - return super(LogbookEntry, self).__getattribute__(item) + if item == "cave": + #Allow a logbookentries cave to be directly accessed despite not having a proper foreignkey + return CaveSlug.objects.get(slug = self.cave_slug).cave + # parse error in python3.8 + # https://stackoverflow.com/questions/41343263/provide-classcell-example-for-python-3-6-metaclass + return super(LogbookEntry, self).__getattribute__(item) def __init__(self, *args, **kwargs): - if "cave" in kwargs.keys(): + if "cave" in list(kwargs.keys()): if kwargs["cave"] is not None: kwargs["cave_slug"] = CaveSlug.objects.get(cave=kwargs["cave"], primary=True).slug kwargs.pop("cave") + # parse error in python3.8 + # https://stackoverflow.com/questions/41343263/provide-classcell-example-for-python-3-6-metaclass return super(LogbookEntry, self).__init__(*args, **kwargs) def isLogbookEntry(self): # Function used in templates return True def get_absolute_url(self): - return urlparse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug})) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('logbookentry',kwargs={'date':self.date,'slug':self.slug})) def __unicode__(self): return "%s: (%s)" % (self.date, self.title) @@ -357,9 +366,9 @@ class Area(TroggleModel): parent = models.ForeignKey('Area', blank=True, null=True) def __unicode__(self): if self.parent: - return unicode(self.parent) + u" - " + unicode(self.short_name) + return str(self.parent) + " - " + str(self.short_name) else: - return unicode(self.short_name) + return str(self.short_name) def kat_area(self): if self.short_name in ["1623", "1626"]: return self.short_name @@ -371,7 +380,7 @@ class CaveAndEntrance(models.Model): 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) + return str(self.cave) + str(self.entrance_letter) class CaveSlug(models.Model): cave = models.ForeignKey('Cave') @@ -454,10 +463,10 @@ class Cave(TroggleModel): else: href = self.official_name.lower() #return settings.URL_ROOT + '/cave/' + href + '/' - return urlparse.urljoin(settings.URL_ROOT, reverse('cave',kwargs={'cave_id':href,})) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('cave',kwargs={'cave_id':href,})) - def __unicode__(self, sep = u": "): - return unicode("slug:"+self.slug()) + def __unicode__(self, sep = ": "): + return str("slug:"+self.slug()) def get_QMs(self): return QM.objects.filter(found_by__cave_slug=self.caveslug_set.all()) @@ -539,7 +548,7 @@ def getCaveByReference(reference): area = Area.objects.get(short_name = areaname) #print(area) foundCaves = list(Cave.objects.filter(area = area, kataster_number = code).all()) + list(Cave.objects.filter(area = area, unofficial_number = code).all()) - print(list(foundCaves)) + print((list(foundCaves))) if len(foundCaves) == 1: return foundCaves[0] else: @@ -549,7 +558,7 @@ class OtherCaveName(TroggleModel): name = models.CharField(max_length=160) cave = models.ForeignKey(Cave) def __unicode__(self): - return unicode(self.name) + return str(self.name) class EntranceSlug(models.Model): entrance = models.ForeignKey('Entrance') @@ -597,7 +606,7 @@ class Entrance(TroggleModel): cached_primary_slug = models.CharField(max_length=200,blank=True,null=True) def __unicode__(self): - return unicode(self.slug()) + return str(self.slug()) def exact_location(self): return SurvexStation.objects.lookup(self.exact_station) @@ -714,12 +723,12 @@ class CaveDescription(TroggleModel): def __unicode__(self): if self.long_name: - return unicode(self.long_name) + return str(self.long_name) else: - return unicode(self.short_name) + return str(self.short_name) def get_absolute_url(self): - return urlparse.urljoin(settings.URL_ROOT, reverse('cavedescription', args=(self.short_name,))) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('cavedescription', args=(self.short_name,))) def save(self): """ @@ -734,7 +743,7 @@ class CaveDescription(TroggleModel): class NewSubCave(TroggleModel): name = models.CharField(max_length=200, unique = True) def __unicode__(self): - return unicode(self.name) + return str(self.name) class QM(TroggleModel): #based on qm.csv in trunk/expoweb/1623/204 which has the fields: @@ -762,14 +771,14 @@ class QM(TroggleModel): comment=models.TextField(blank=True,null=True) def __unicode__(self): - return u"%s %s" % (self.code(), self.grade) + return "%s %s" % (self.code(), self.grade) def code(self): - return u"%s-%s-%s" % (unicode(self.found_by.cave)[6:], self.found_by.date.year, self.number) + return "%s-%s-%s" % (str(self.found_by.cave)[6:], self.found_by.date.year, self.number) 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 urlparse.urljoin(settings.URL_ROOT, reverse('qm',kwargs={'cave_id':self.found_by.cave.kataster_number,'year':self.found_by.date.year,'qm_id':self.number,'grade':self.grade})) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('qm',kwargs={'cave_id':self.found_by.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) @@ -778,7 +787,7 @@ class QM(TroggleModel): return QM.objects.get(id=self.id-1) def wiki_link(self): - return u"%s%s%s" % ('[[QM:',self.code(),']]') + return "%s%s%s" % ('[[QM:',self.code(),']]') #photoFileStorage = FileSystemStorage(location=settings.PHOTOS_ROOT, base_url=settings.PHOTOS_URL) #class DPhoto(TroggleImageModel): @@ -880,4 +889,4 @@ class DataIssue(TroggleModel): ordering = ['date'] def __unicode__(self): - return u"%s - %s" % (self.parser, self.message) + return "%s - %s" % (self.parser, self.message) diff --git a/core/models_survex.py b/core/models_survex.py index 448cea9..6ab6f8a 100644 --- a/core/models_survex.py +++ b/core/models_survex.py @@ -1,7 +1,7 @@ from django.db import models from django.conf import settings import os -import urlparse +import urllib.parse import re from django.core.urlresolvers import reverse @@ -128,8 +128,8 @@ class SurvexBlock(models.Model): def isSurvexBlock(self): # Function used in templates return True - def __unicode__(self): - return self.name and unicode(self.name) or 'no name' + def __str__(self): + return self.name and str(self.name) or 'no name' def GetPersonroles(self): res = [ ] @@ -185,7 +185,7 @@ class SurvexPersonRole(models.Model): expeditionday = models.ForeignKey("ExpeditionDay", null=True) def __unicode__(self): - return unicode(self.person) + " - " + unicode(self.survexblock) + " - " + unicode(self.nrole) + return str(self.person) + " - " + str(self.survexblock) + " - " + str(self.nrole) class SurvexScansFolder(models.Model): @@ -196,10 +196,10 @@ class SurvexScansFolder(models.Model): ordering = ('walletname',) def get_absolute_url(self): - return urlparse.urljoin(settings.URL_ROOT, reverse('surveyscansfolder', kwargs={"path":re.sub("#", "%23", self.walletname)})) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('surveyscansfolder', kwargs={"path":re.sub("#", "%23", self.walletname)})) def __unicode__(self): - return unicode(self.walletname) + " (Survey Scans Folder)" + return str(self.walletname) + " (Survey Scans Folder)" class SurvexScanSingle(models.Model): ffile = models.CharField(max_length=200) @@ -210,10 +210,10 @@ class SurvexScanSingle(models.Model): ordering = ('name',) def get_absolute_url(self): - return urlparse.urljoin(settings.URL_ROOT, reverse('surveyscansingle', kwargs={"path":re.sub("#", "%23", self.survexscansfolder.walletname), "file":self.name})) + return urllib.parse.urljoin(settings.URL_ROOT, reverse('surveyscansingle', kwargs={"path":re.sub("#", "%23", self.survexscansfolder.walletname), "file":self.name})) def __unicode__(self): - return "Survey Scan Image: " + unicode(self.name) + " in " + unicode(self.survexscansfolder) + return "Survey Scan Image: " + str(self.name) + " in " + str(self.survexscansfolder) class TunnelFile(models.Model): diff --git a/core/templatetags/link.py b/core/templatetags/link.py index cb861ad..a17dd4b 100644 --- a/core/templatetags/link.py +++ b/core/templatetags/link.py @@ -5,5 +5,5 @@ register = template.Library() @register.filter() def link(value): - return mark_safe(""%value.get_absolute_url()+unicode(value)+"") + return mark_safe(""%value.get_absolute_url()+str(value)+"") diff --git a/core/templatetags/wiki_markup.py b/core/templatetags/wiki_markup.py index 25c7103..024b9b7 100644 --- a/core/templatetags/wiki_markup.py +++ b/core/templatetags/wiki_markup.py @@ -4,7 +4,7 @@ from django.template.defaultfilters import stringfilter from django.utils.safestring import mark_safe from django.conf import settings from troggle.core.models import QM, LogbookEntry, Cave -import re, urlparse +import re, urllib.parse register = template.Library() @@ -94,7 +94,7 @@ def wiki_to_html_short(value, autoescape=None): qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'], found_by__date__year = qmdict['year'], number = qmdict['number']) - return r'%s' % (qm.get_absolute_url(), qm.code, unicode(qm)) + return r'%s' % (qm.get_absolute_url(), qm.code, str(qm)) except QM.DoesNotExist: #bother aaron to make him clean up the below code - AC try: placeholder=LogbookEntry.objects.get(date__year=qmdict['year'],cave__kataster_number=qmdict['cave'], title__icontains='placeholder') @@ -105,7 +105,7 @@ def wiki_to_html_short(value, autoescape=None): title='placeholder' ) qm=QM(found_by = placeholder, number = qmdict['number']) - return r'%s' % (qm.get_absolute_url(), qm.code, unicode(qm)) + return r'%s' % (qm.get_absolute_url(), qm.code, str(qm)) value = re.sub(qmMatchPattern,qmrepl, value, re.DOTALL) diff --git a/core/view_surveys.py b/core/view_surveys.py index aad48c3..65a4f30 100644 --- a/core/view_surveys.py +++ b/core/view_surveys.py @@ -1,12 +1,12 @@ from django.conf import settings -import fileAbstraction +from . import fileAbstraction from django.shortcuts import render_to_response from django.http import HttpResponse, Http404 import os, stat import re from troggle.core.models import SurvexScansFolder, SurvexScanSingle, SurvexBlock, TunnelFile import parsers.surveys -import urllib +import urllib.request, urllib.parse, urllib.error # inline fileabstraction into here if it's not going to be useful anywhere else # keep things simple and ignore exceptions everywhere for now @@ -113,19 +113,19 @@ def UniqueFile(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) + print(("hihihihi", fdata, settings.SURVEYS)) fimgdir = os.path.join(settings.SURVEYS, imgdir) if not os.path.isdir(fimgdir): - print "*** Making directory", 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 + print("*** Making directory", fprojdir) os.path.mkdir(fprojdir) - print "hhh" + print("hhh") fname = os.path.join(fprojdir, name) - print fname, "fff" + print(fname, "fff") fname = UniqueFile(fname) p2, p1 = os.path.split(fname) @@ -133,7 +133,7 @@ def SaveImageInDir(name, imgdir, project, fdata, bbinary): p4, p3 = os.path.split(p3) res = os.path.join(p3, p2, p1) - print "saving file", fname + print("saving file", fname) fout = open(fname, (bbinary and "wb" or "w")) fout.write(fdata.read()) fout.close() @@ -145,33 +145,33 @@ def SaveImageInDir(name, imgdir, project, fdata, bbinary): 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(): + print((project, user, tunnelversion)) + for uploadedfile in list(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 + 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 + 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" + print("gothere") return render_to_response('fileupload.html', {'message':message, 'filesuploaded':filesuploaded, 'settings': settings}) def surveyscansfolder(request, path): #print [ s.walletname for s in SurvexScansFolder.objects.all() ] - survexscansfolder = SurvexScansFolder.objects.get(walletname=urllib.unquote(path)) + survexscansfolder = SurvexScansFolder.objects.get(walletname=urllib.parse.unquote(path)) return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings }) def surveyscansingle(request, path, file): - survexscansfolder = SurvexScansFolder.objects.get(walletname=urllib.unquote(path)) + survexscansfolder = SurvexScansFolder.objects.get(walletname=urllib.parse.unquote(path)) survexscansingle = SurvexScanSingle.objects.get(survexscansfolder=survexscansfolder, name=file) return HttpResponse(content=open(survexscansingle.ffile), content_type=getMimeType(path.split(".")[-1])) #return render_to_response('survexscansfolder.html', { 'survexscansfolder':survexscansfolder, 'settings': settings }) @@ -187,21 +187,21 @@ def tunneldata(request): def tunnelfile(request, path): - tunnelfile = TunnelFile.objects.get(tunnelpath=urllib.unquote(path)) + tunnelfile = TunnelFile.objects.get(tunnelpath=urllib.parse.unquote(path)) tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath) return HttpResponse(content=open(tfile), content_type="text/plain") def tunnelfileupload(request, path): - tunnelfile = TunnelFile.objects.get(tunnelpath=urllib.unquote(path)) + tunnelfile = TunnelFile.objects.get(tunnelpath=urllib.parse.unquote(path)) tfile = os.path.join(settings.TUNNEL_DATA, tunnelfile.tunnelpath) project, user, password, tunnelversion = request.POST["tunnelproject"], request.POST["tunneluser"], request.POST["tunnelpassword"], request.POST["tunnelversion"] - print (project, user, tunnelversion) + print((project, user, tunnelversion)) - assert len(request.FILES.values()) == 1, "only one file to upload" + assert len(list(request.FILES.values())) == 1, "only one file to upload" - uploadedfile = request.FILES.values()[0] + uploadedfile = list(request.FILES.values())[0] if uploadedfile.field_name != "sketch": return HttpResponse(content="Error: non-sketch file uploaded", content_type="text/plain") diff --git a/core/views.py b/core/views.py index 26c2e52..d81e03c 100644 --- a/core/views.py +++ b/core/views.py @@ -1,8 +1,8 @@ # primary namespace -import view_surveys -import views_caves -import views_survex -import views_logbooks -import views_other +from . import view_surveys +from . import views_caves +from . import views_survex +from . import views_logbooks +from . import views_other diff --git a/core/views_caves.py b/core/views_caves.py index 1f9b91e..1a7d077 100644 --- a/core/views_caves.py +++ b/core/views_caves.py @@ -14,9 +14,7 @@ from django import forms from django.core.urlresolvers import reverse from django.http import HttpResponse, HttpResponseRedirect from django.conf import settings -import re -import urlparse -#import urllib.parse +import re, urllib.parse from django.shortcuts import get_object_or_404, render import settings diff --git a/core/views_logbooks.py b/core/views_logbooks.py index 65453fa..b29b72e 100644 --- a/core/views_logbooks.py +++ b/core/views_logbooks.py @@ -62,8 +62,7 @@ def expedition(request, expeditionname): expeditions = Expedition.objects.all() personexpeditiondays = [ ] dateditems = list(this_expedition.logbookentry_set.all()) + list(this_expedition.survexblock_set.all()) - dates = list(set([item.date for item in dateditems])) - dates.sort() + dates = sorted(set([item.date for item in dateditems])) for personexpedition in this_expedition.personexpedition_set.all(): prow = [ ] for date in dates: @@ -115,8 +114,7 @@ def GetPersonChronology(personexpedition): a.setdefault("personroles", [ ]).append(personrole.survexblock) # build up the tables - rdates = res.keys() - rdates.sort() + rdates = sorted(list(res.keys())) res2 = [ ] @@ -206,8 +204,8 @@ def pathsreport(request): ncodes = len(pathsdict) - bycodeslist = sorted(pathsdict.iteritems()) - bypathslist = sorted(pathsdict.iteritems(), key=lambda x: x[1]) + bycodeslist = sorted(pathsdict.items()) + bypathslist = sorted(iter(pathsdict.items()), key=lambda x: x[1]) return render(request, 'pathsreport.html', { "pathsdict":pathsdict, @@ -264,7 +262,7 @@ def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None): 'expeditionyear': expeditionyear}) f.write(template.render(context)) f.close() - print(logbookparsers.parseAutoLogBookEntry(filename)) + print((logbookparsers.parseAutoLogBookEntry(filename))) return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST else: if pslug and pdate: diff --git a/core/views_other.py b/core/views_other.py index 6adca9c..47a071a 100644 --- a/core/views_other.py +++ b/core/views_other.py @@ -60,7 +60,7 @@ def controlPanel(request): databaseReset.dirsredirect() for item in importlist: if item in request.POST: - print("running"+ " databaseReset."+item+"()") + print(("running"+ " databaseReset."+item+"()")) exec("databaseReset."+item+"()") jobs_completed.append(item) else: @@ -180,7 +180,7 @@ def logbook_entry_suggestions(request): try: lbo=LogbookEntry.objects.get(date__year=qm['year'],title__icontains="placeholder for QMs in") except: - print("failed to get placeholder for year "+str(qm['year'])) + print(("failed to get placeholder for year "+str(qm['year']))) temp_QM=QM(found_by=lbo,number=qm['number'],grade=qm['grade']) temp_QM.grade=qm['grade'] diff --git a/core/views_survex.py b/core/views_survex.py index 1e6c1bf..7595ea9 100644 --- a/core/views_survex.py +++ b/core/views_survex.py @@ -266,8 +266,7 @@ def survexcaveslist(request): subdircaves = [ ] # first sort the file list - fnumlist = [ (-int(re.match(r"\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir) ] - fnumlist.sort() + fnumlist = sorted([ (-int(re.match(r"\d*", f).group(0) or "0"), f) for f in os.listdir(cavesdir) ]) print(fnumlist) diff --git a/databaseReset.py b/databaseReset.py index f08e3a6..09b3214 100644 --- a/databaseReset.py +++ b/databaseReset.py @@ -100,7 +100,7 @@ def import_surveyimgs(): for future re-working to manage progress against notes, plans and elevs. """ #import troggle.parsers.surveys - print("NOT Importing survey images") + #print("Importing survey images") #troggle.parsers.surveys.parseSurveys(logfile=settings.LOGFILE) def import_surveyscans(): @@ -258,7 +258,7 @@ class JobQueue(): print("-- ", settings.DATABASES['default']['NAME'], settings.DATABASES['default']['ENGINE']) - #print("-- DATABASES.default", settings.DATABASES['default']) + print("-- DATABASES.default", settings.DATABASES['default']) # but because the user may be expecting to add this to a db with lots of tables already there, # the jobqueue may not start from scratch so we need to initialise the db properly first @@ -334,11 +334,7 @@ class JobQueue(): print(" this", end=' ') else: # prints one place to the left of where you expect - if r[len(r)-1]: - s = r[i]-r[len(r)-1] - else: - s = 0 - days = (s)/(24*60*60) + days = (r[i]-r[len(r)-1])/(24*60*60) print('%8.2f' % days, end=' ') elif r[i]: print('%8.1f' % r[i], end=' ') diff --git a/docker/requirements.txt b/docker/requirements.txt deleted file mode 120000 index d561bd8..0000000 --- a/docker/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requirements.txt.dj-1.7.11 \ No newline at end of file diff --git a/docker/requirements.txt b/docker/requirements.txt new file mode 100644 index 0000000..7a197bd --- /dev/null +++ b/docker/requirements.txt @@ -0,0 +1,9 @@ +Django==1.7.11 +django-registration==2.1.2 +mysql +#imagekit +django-imagekit +Image +django-tinymce==2.7.0 +smartencoding +unidecode diff --git a/export/toqms.py b/export/toqms.py index 2564094..69e565c 100644 --- a/export/toqms.py +++ b/export/toqms.py @@ -22,10 +22,10 @@ def qmRow(qm): } qmRow=['' for x in range(len(headers))] - for column, modelField in columnsToModelFields.items(): + for column, modelField in list(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','') + qmRow[headers.index(column)]=modelField.replace('\xd7','x').replace('\u201c','').replace('\u2013','').replace('\xbd','') return qmRow def writeQmTable(outfile,cave): diff --git a/flatpages/tests.py b/flatpages/tests.py index 2247054..c7c4668 100644 --- a/flatpages/tests.py +++ b/flatpages/tests.py @@ -12,7 +12,7 @@ class SimpleTest(TestCase): """ Tests that 1 + 1 always equals 2. """ - self.failUnlessEqual(1 + 1, 2) + self.assertEqual(1 + 1, 2) __test__ = {"doctest": """ Another way to test that 1 + 1 is equal to 2. diff --git a/flatpages/views.py b/flatpages/views.py index d265c75..27f0cd0 100644 --- a/flatpages/views.py +++ b/flatpages/views.py @@ -1,18 +1,19 @@ -import troggle.settings as settings -from troggle.helper import login_required_if_public -from django.shortcuts import render +import os +import re +from django.shortcuts import render from django.http import HttpResponse, HttpResponseRedirect, Http404 -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse from django.template import Context, loader import django.forms as forms + from tinymce.widgets import TinyMCE + +from troggle.helper import login_required_if_public from troggle.flatpages.models import Redirect, EntranceRedirect from troggle.core.models import Cave import troggle.core.views_caves - -import os -import re +import troggle.settings as settings def flatpage(request, path): try: @@ -35,7 +36,7 @@ def flatpage(request, path): if path.startswith("noinfo") and settings.PUBLIC_SITE and not request.user.is_authenticated(): - print("flat path noinfo", path) + print(("flat path noinfo", path)) return HttpResponseRedirect(reverse("auth_login") + '?next=%s' % request.path) if path.endswith("/") or path == "": @@ -57,32 +58,32 @@ def flatpage(request, path): if path.endswith(".htm") or path.endswith(".html"): html = o.read() - m = re.search(r"(.*)<\s*head([^>]*)>(.*)<\s*/head\s*>(.*)<\s*body([^>]*)>(.*)<\s*/body\s*>(.*)", html, re.DOTALL + re.IGNORECASE) + m = re.search(rb'(.*)<\s*head([^>]*)>(.*)<\s*/head\s*>(.*)<\s*body([^>]*)>(.*)<\s*/body\s*>(.*)', html, re.DOTALL + re.IGNORECASE) if m: preheader, headerattrs, head, postheader, bodyattrs, body, postbody = m.groups() else: return HttpResponse(html + "Page could not be split into header and body") - m = re.search(r"(.*)", head, re.DOTALL + re.IGNORECASE) + m = re.search(rb"(.*)", head, re.DOTALL + re.IGNORECASE) if m: title, = m.groups() else: title = "" - m = re.search(r"]*)noedit", head, re.DOTALL + re.IGNORECASE) + m = re.search(rb"]*)noedit", head, re.DOTALL + re.IGNORECASE) if m: editable = False else: editable = True has_menu = False - menumatch = re.match('(.*)