From f666b9c3963b321296ec51e5d8c8dd149ff60478 Mon Sep 17 00:00:00 2001
From: Sam Wenham <sam@wenhams.co.uk>
Date: Sat, 30 Mar 2019 13:58:38 +0000
Subject: [PATCH 1/6] Update new management command for DB reset Switch to
 content_type from mimetype Make DB reset not nuke so much Tidy logbook parser

---
 core/management/commands/reset_db.py | 89 ++++++++++++++--------------
 core/views_other.py                  | 37 ++++++------
 databaseReset.py                     | 20 +++----
 parsers/logbooks.py                  | 19 +++---
 parsers/people.py                    |  4 +-
 templates/frontpage.html             |  2 +-
 6 files changed, 85 insertions(+), 86 deletions(-)

diff --git a/core/management/commands/reset_db.py b/core/management/commands/reset_db.py
index 29f8e81..e95ddd9 100644
--- a/core/management/commands/reset_db.py
+++ b/core/management/commands/reset_db.py
@@ -2,6 +2,14 @@ from django.core.management.base import BaseCommand, CommandError
 from optparse import make_option
 from troggle.core.models import Cave
 import settings
+import os
+
+from django.db import connection
+from django.core import management
+from django.contrib.auth.models import User
+from django.core.urlresolvers import reverse
+from troggle.core.models import Cave, Entrance
+import troggle.flatpages.models
 
 databasename=settings.DATABASES['default']['NAME']
 expouser=settings.EXPOUSER
@@ -12,22 +20,13 @@ class Command(BaseCommand):
     help = 'This is normal usage, clear database and reread everything'
 
     option_list = BaseCommand.option_list + (
-        make_option('--foo',
+        make_option('--reset',
                     action='store_true',
-                    dest='foo',
+                    dest='reset',
                     default=False,
-                    help='test'),
+                    help='Reset the entier DB from files'),
     )
 
-    def add_arguments(self, parser):
-
-        parser.add_argument(
-            '--foo',
-            action='store_true',
-            dest='foo',
-            help='Help text',
-        )
-
     def handle(self, *args, **options):
         print(args)
         print(options)
@@ -46,8 +45,8 @@ class Command(BaseCommand):
             self.import_QMs()
         elif "tunnel" in args:
             self.import_tunnelfiles()
-        elif "reset" in args:
-            self.reset()
+        elif options['reset']:
+            self.reset(self)
         elif "survex" in args:
             self.import_survex()
         elif "survexpos" in args:
@@ -61,13 +60,15 @@ class Command(BaseCommand):
             self.dumplogbooks()
         elif "writeCaves" in args:
             self.writeCaves()
-        elif "foo" in args:
-            self.stdout.write('Tesing....')
+        elif options['foo']:
+            self.stdout.write(self.style.WARNING('Tesing....'))
         else:
-            self.stdout.write("%s not recognised" % args)
-            self.usage(options)
+            #self.stdout.write("%s not recognised" % args)
+            #self.usage(options)
+            self.stdout.write("poo")
+            #print(args)
 
-    def reload_db():
+    def reload_db(obj):
         if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.sqlite3':
             try:
                 os.remove(databasename)
@@ -86,22 +87,22 @@ class Command(BaseCommand):
         user.is_superuser = True
         user.save()
 
-    def make_dirs():
+    def make_dirs(obj):
         """Make directories that troggle requires"""
         # should also deal with permissions here.
         if not os.path.isdir(settings.PHOTOS_ROOT):
             os.mkdir(settings.PHOTOS_ROOT)
 
-    def import_caves():
+    def import_caves(obj):
         import parsers.caves
-        print("importing caves")
+        print("Importing Caves")
         parsers.caves.readcaves()
 
-    def import_people():
+    def import_people(obj):
         import parsers.people
         parsers.people.LoadPersonsExpos()
 
-    def import_logbooks():
+    def import_logbooks(obj):
         # The below line was causing errors I didn't understand (it said LOGFILE was a string), and I couldn't be bothered to figure
         # what was going on so I just catch the error with a try. - AC 21 May
         try:
@@ -112,57 +113,57 @@ class Command(BaseCommand):
         import parsers.logbooks
         parsers.logbooks.LoadLogbooks()
 
-    def import_survex():
+    def import_survex(obj):
         import parsers.survex
         parsers.survex.LoadAllSurvexBlocks()
         parsers.survex.LoadPos()
 
-    def import_QMs():
+    def import_QMs(obj):
         import parsers.QMs
 
-    def import_surveys():
+    def import_surveys(obj):
         import parsers.surveys
         parsers.surveys.parseSurveys(logfile=settings.LOGFILE)
 
-    def import_surveyscans():
+    def import_surveyscans(obj):
         import parsers.surveys
         parsers.surveys.LoadListScans()
 
-    def import_tunnelfiles():
+    def import_tunnelfiles(obj):
         import parsers.surveys
         parsers.surveys.LoadTunnelFiles()
 
-    def reset():
+    def reset(self, mgmt_obj):
         """ Wipe the troggle database and import everything from legacy data
         """
-        reload_db()
-        make_dirs()
-        pageredirects()
-        import_caves()
-        import_people()
-        import_surveyscans()
-        import_survex()
-        import_logbooks()
-        import_QMs()
+        self.reload_db()
+        self.make_dirs()
+        self.pageredirects()
+        self.import_caves()
+        self.import_people()
+        self.import_surveyscans()
+        self.import_survex()
+        self.import_logbooks()
+        self.import_QMs()
         try:
-            import_tunnelfiles()
+            self.import_tunnelfiles()
         except:
             print("Tunnel files parser broken.")
 
-        import_surveys()
+        self.import_surveys()
 
-    def pageredirects():
+    def pageredirects(obj):
         for oldURL, newURL in [("indxal.htm", reverse("caveindex"))]:
             f = troggle.flatpages.models.Redirect(originalURL=oldURL, newURL=newURL)
             f.save()
 
-    def writeCaves():
+    def writeCaves(obj):
         for cave in Cave.objects.all():
             cave.writeDataFile()
         for entrance in Entrance.objects.all():
             entrance.writeDataFile()
 
-    def usage(self, parser):
+    def troggle_usage(obj):
         print("""Usage is 'manage.py reset_db <command>'
                  where command is:
                  reset - this is normal usage, clear database and reread everything
diff --git a/core/views_other.py b/core/views_other.py
index d99cc32..6a195b9 100644
--- a/core/views_other.py
+++ b/core/views_other.py
@@ -59,8 +59,8 @@ def controlPanel(request):
             databaseReset.make_dirs()
             for item in importlist:
                 if item in request.POST:
-                    print "running"+ " databaseReset."+item+"()"
-                    exec "databaseReset."+item+"()"
+                    print("running"+ " databaseReset."+item+"()")
+                    exec("databaseReset."+item+"()")
                     jobs_completed.append(item)
         else:
             if request.user.is_authenticated(): #The user is logged in, but is not a superuser.
@@ -72,14 +72,14 @@ def controlPanel(request):
 
 def downloadCavetab(request):
     from export import tocavetab
-    response = HttpResponse(mimetype='text/csv')
+    response = HttpResponse(content_type='text/csv')
     response['Content-Disposition'] = 'attachment; filename=CAVETAB2.CSV'
     tocavetab.writeCaveTab(response)
     return response
 
 def downloadSurveys(request):
     from export import tosurveys
-    response = HttpResponse(mimetype='text/csv')
+    response = HttpResponse(content_type='text/csv')
     response['Content-Disposition'] = 'attachment; filename=Surveys.csv'
     tosurveys.writeCaveTab(response)
     return response
@@ -94,20 +94,19 @@ def downloadLogbook(request,year=None,extension=None,queryset=None):
         logbook_entries=queryset
         filename='logbook'
     else:
+        response = HttpResponse(content_type='text/plain')
         return response(r"Error: Logbook downloader doesn't know what year you want")
     
     if 'year' in request.GET:
         year=request.GET['year']
     if 'extension' in request.GET:
         extension=request.GET['extension']
-    
-    
-    
+
     if extension =='txt':
-        response = HttpResponse(mimetype='text/plain')
+        response = HttpResponse(content_type='text/plain')
         style='2008'
     elif extension == 'html':
-        response = HttpResponse(mimetype='text/html')
+        response = HttpResponse(content_type='text/html')
         style='2005'
         
     template='logbook'+style+'style.'+extension
@@ -124,11 +123,11 @@ def downloadQMs(request):
         try:
             cave=Cave.objects.get(kataster_number=request.GET['cave_id'])
         except Cave.DoesNotExist:
-            cave=Cave.objects.get(name=cave_id)
+            cave=Cave.objects.get(name=request.GET['cave_id'])
 
     from export import toqms
 
-    response = HttpResponse(mimetype='text/csv')
+    response = HttpResponse(content_type='text/csv')
     response['Content-Disposition'] = 'attachment; filename=qm.csv'
     toqms.writeQmTable(response,cave)
     return response
@@ -136,7 +135,7 @@ def downloadQMs(request):
 def ajax_test(request):
     post_text = request.POST['post_data']
     return HttpResponse("{'response_text': '"+post_text+" recieved.'}", 
-                                   mimetype="application/json")
+                                   content_type="application/json")
                                    
 def eyecandy(request):
     return 
@@ -144,9 +143,9 @@ def eyecandy(request):
 def ajax_QM_number(request):
     if request.method=='POST':
         cave=Cave.objects.get(id=request.POST['cave'])
-        print cave
+        print(cave)
         exp=Expedition.objects.get(pk=request.POST['year'])
-        print exp
+        print(exp)
         res=cave.new_QM_number(exp.year)
 
     return HttpResponse(res)
@@ -167,7 +166,7 @@ def logbook_entry_suggestions(request):
     #unwiki_QMs=re.findall(unwiki_QM_pattern,lbo.text)
     unwiki_QMs=[m.groupdict() for m in unwiki_QM_pattern.finditer(lbo.text)]
     
-    print unwiki_QMs
+    print(unwiki_QMs)
     for qm in unwiki_QMs:
         #try:
             if len(qm['year'])==2:
@@ -180,7 +179,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']
@@ -188,7 +187,7 @@ def logbook_entry_suggestions(request):
         #except:
             #print 'failed'
 
-    print unwiki_QMs
+    print(unwiki_QMs)
     
     
     #wikilink_QMs=re.findall(wikilink_QM_pattern,lbo.text)
@@ -199,9 +198,9 @@ def logbook_entry_suggestions(request):
     #for qm in wikilink_QMs:
         #Try to look up the QM. 
         
-    print 'got 208'
+    print('got 208')
     any_suggestions=True
-    print 'got 210'
+    print('got 210')
     return render_with_context(request,'suggestions.html',
         {
         'unwiki_QMs':unwiki_QMs,
diff --git a/databaseReset.py b/databaseReset.py
index c296274..7a5d0fa 100644
--- a/databaseReset.py
+++ b/databaseReset.py
@@ -109,10 +109,10 @@ def import_auto_logbooks():
     for lbe in troggle.core.models.LogbookEntry.objects.all():
         lbe.delete()
     for expedition in troggle.core.models.Expedition.objects.all():
-        directory = os.path.join(settings.EXPOWEB, 
-                                 "years", 
-                                 expedition.year, 
-                                 "autologbook")       
+        directory = os.path.join(settings.EXPOWEB,
+                                 "years",
+                                 expedition.year,
+                                 "autologbook")
         for root, dirs, filenames in os.walk(directory):
             for filename in filenames:
                 print(os.path.join(root, filename))
@@ -195,9 +195,9 @@ if __name__ == "__main__":
     elif "scans" in sys.argv:
         import_surveyscans()
     elif "caves" in sys.argv:
-        reload_db()
-        make_dirs()
-        pageredirects()
+        # reload_db()
+        # make_dirs()
+        # pageredirects()
         import_caves()
     elif "people" in sys.argv:
         import_people()
@@ -218,14 +218,14 @@ if __name__ == "__main__":
         import_descriptions()
         parse_descriptions()
     elif "survex" in sys.argv:
-        management.call_command('syncdb', interactive=False)  # this sets the path so that import settings works in import_survex
+        # management.call_command('syncdb', interactive=False)  # this sets the path so that import settings works in import_survex
         import_survex()
     elif "survexpos" in sys.argv:
-        management.call_command('syncdb', interactive=False)  # this sets the path so that import settings works in import_survex
+        # management.call_command('syncdb', interactive=False)  # this sets the path so that import settings works in import_survex
         import parsers.survex
         parsers.survex.LoadPos()    
     elif "logbooks" in sys.argv:
-        management.call_command('syncdb', interactive=False)  # this sets the path so that import settings works in import_survex
+        # management.call_command('syncdb', interactive=False)  # this sets the path so that import settings works in import_survex
         import_logbooks()
     elif "autologbooks" in sys.argv:
         import_auto_logbooks()
diff --git a/parsers/logbooks.py b/parsers/logbooks.py
index ffd8e21..fbe00a3 100644
--- a/parsers/logbooks.py
+++ b/parsers/logbooks.py
@@ -115,7 +115,7 @@ def ParseDate(tripdate, year):
         assert False, tripdate
     return datetime.date(year, month, day)
 
-# 2007, 2008, 2006
+# 2006, 2008 - 2010
 def Parselogwikitxt(year, expedition, txt):
     trippara = re.findall(r"===(.*?)===([\s\S]*?)(?====)", txt)
     for triphead, triptext in trippara:
@@ -140,9 +140,9 @@ def Parselogwikitxt(year, expedition, txt):
         #print "\n", tripcave, "---   ppp", trippeople, len(triptext)
         EnterLogIntoDbase(date = ldate, place = tripcave, title = tripplace, text = triptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
 
-# 2002, 2004, 2005
+# 2002, 2004, 2005, 2007, 2011 - 2018
 def Parseloghtmltxt(year, expedition, txt):
-    print(" - Using log html parser")
+    #print(" - Starting log html parser")
     tripparas = re.findall(r"<hr\s*/>([\s\S]*?)(?=<hr)", txt)
     logbook_entry_count = 0
     for trippara in tripparas:
@@ -163,7 +163,6 @@ def Parseloghtmltxt(year, expedition, txt):
                 print("can't parse: ", trippara)  # this is 2007 which needs editing
             #assert s, trippara
             continue
-
         tripid, tripid1, tripdate, trippeople, triptitle, triptext, tu = s.groups()
         ldate = ParseDate(tripdate.strip(), year)
         #assert tripid[:-1] == "t" + tripdate, (tripid, tripdate)
@@ -174,7 +173,7 @@ def Parseloghtmltxt(year, expedition, txt):
             tripcave = triptitles[0]
         else:
             tripcave = "UNKNOWN"
-        #print "\n", tripcave, "---   ppp", trippeople, len(triptext)
+        #print("\n", tripcave, "---   ppp", trippeople, len(triptext))
         ltriptext = re.sub(r"</p>", "", triptext)
         ltriptext = re.sub(r"\s*?\n\s*", " ", ltriptext)
         ltriptext = re.sub(r"<p>", "\n\n", ltriptext).strip()
@@ -183,7 +182,7 @@ def Parseloghtmltxt(year, expedition, txt):
         print(" - No trip entrys found in logbook, check the syntax matches htmltxt format")
 
 
-# main parser for pre-2001.  simpler because the data has been hacked so much to fit it
+# main parser for 1991 - 2001.  simpler because the data has been hacked so much to fit it
 def Parseloghtml01(year, expedition, txt):
     tripparas = re.findall(r"<hr[\s/]*>([\s\S]*?)(?=<hr)", txt)
     for trippara in tripparas:
@@ -229,7 +228,7 @@ def Parseloghtml01(year, expedition, txt):
             # could includ the tripid (url link for cross referencing)
         EnterLogIntoDbase(date=ldate, place=tripcave, title=triptitle, text=ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
 
-
+# parser for 2003
 def Parseloghtml03(year, expedition, txt):
     tripparas = re.findall(r"<hr\s*/>([\s\S]*?)(?=<hr)", txt)
     for trippara in tripparas:
@@ -281,8 +280,7 @@ def SetDatesFromLogbookEntries(expedition):
 def LoadLogbookForExpedition(expedition):
     """ Parses all logbook entries for one expedition """
         
-    expowebbase = os.path.join(settings.EXPOWEB, "years")  
-    #year = str(expedition.year)
+    expowebbase = os.path.join(settings.EXPOWEB, "years")
     yearlinks = settings.LOGBOOK_PARSER_SETTINGS
 
     logbook_parseable = False
@@ -294,6 +292,7 @@ def LoadLogbookForExpedition(expedition):
         file_in.close()
         parsefunc = year_settings[1]
         logbook_parseable = True
+        print(" - Parsing logbook: " + year_settings[0] + "\n - Using parser: " + year_settings[1])
     else:
         try:
             file_in = open(os.path.join(expowebbase, expedition.year, settings.DEFAULT_LOGBOOK_FILE))
@@ -304,7 +303,7 @@ def LoadLogbookForExpedition(expedition):
             parsefunc = settings.DEFAULT_LOGBOOK_PARSER
         except (IOError):
             logbook_parseable = False
-            print("Couldn't open default logbook file and nothing set for expo " + expedition.year)
+            print("Couldn't open default logbook file and nothing in settings for expo " + expedition.year)
 
     if logbook_parseable:
         parser = globals()[parsefunc]
diff --git a/parsers/people.py b/parsers/people.py
index 3c3fc03..48d6c17 100644
--- a/parsers/people.py
+++ b/parsers/people.py
@@ -67,8 +67,8 @@ def LoadPersonsExpos():
 
     for personline in personreader:
         name = personline[header["Name"]]
-        name = re.sub("<.*?>", "", name)
-        mname = re.match("(\w+)(?:\s((?:van |ten )?\w+))?(?:\s\(([^)]*)\))?", name)
+        name = re.sub(r"<.*?>", "", name)
+        mname = re.match(r"(\w+)(?:\s((?:van |ten )?\w+))?(?:\s\(([^)]*)\))?", name)
         nickname = mname.group(3) or ""
 	
         lookupAttribs={'first_name':mname.group(1), 'last_name':(mname.group(2) or "")}
diff --git a/templates/frontpage.html b/templates/frontpage.html
index 28206b6..eed6098 100644
--- a/templates/frontpage.html
+++ b/templates/frontpage.html
@@ -16,7 +16,7 @@
                 {% if entry.is_deletion %}
                     {{ entry.object_repr }}
                 {% else %}
-                    <a href="admin/{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
+                    <a href="admin/{{ entry.get_admin_url }}/">{{ entry.object_repr }}</a>
                 {% endif %}
                 <br/>
                 {% if entry.content_type %}

From c8551991b20dd5d4a70048ea5ca1cbb96d0c3414 Mon Sep 17 00:00:00 2001
From: Sam Wenham <sam@wenhams.co.uk>
Date: Sat, 30 Mar 2019 17:02:07 +0000
Subject: [PATCH 2/6] Remove the redundant render_with_context() as django now
 does this just with the render() shortcut Move from mimetype to content_type,
 missed in last commit

---
 core/admin.py                      |  8 ++---
 core/forms.py                      | 14 ++++----
 core/templatetags/survex_markup.py |  2 +-
 core/views_caves.py                | 55 +++++++++++++++---------------
 core/views_logbooks.py             | 27 +++++++--------
 core/views_other.py                | 18 +++++-----
 core/views_survex.py               | 10 +++---
 flatpages/views.py                 | 10 +++---
 templates/editcave2.html           |  1 +
 templates/logbookentry.html        |  6 ++--
 urls.py                            |  4 +--
 utils.py                           | 16 +--------
 12 files changed, 78 insertions(+), 93 deletions(-)

diff --git a/core/admin.py b/core/admin.py
index a8ce55f..59c93f2 100644
--- a/core/admin.py
+++ b/core/admin.py
@@ -74,11 +74,11 @@ class LogbookEntryAdmin(TroggleModelAdmin):
         }
     actions=('export_logbook_entries_as_html','export_logbook_entries_as_txt')
     
-    def export_logbook_entries_as_html(modeladmin, request, queryset):
+    def export_logbook_entries_as_html(self, modeladmin, request, queryset):
         response=downloadLogbook(request=request, queryset=queryset, extension='html')
         return response
         
-    def export_logbook_entries_as_txt(modeladmin, request, queryset):
+    def export_logbook_entries_as_txt(self, modeladmin, request, queryset):
         response=downloadLogbook(request=request, queryset=queryset, extension='txt')
         return response
 
@@ -141,14 +141,14 @@ admin.site.register(SurvexScanSingle)
 
 
 def export_as_json(modeladmin, request, queryset):
-    response = HttpResponse(mimetype="text/json")
+    response = HttpResponse(content_type="text/json")
     response['Content-Disposition'] = 'attachment; filename=troggle_output.json'
     serializers.serialize("json", queryset, stream=response)
     return response
 
 
 def export_as_xml(modeladmin, request, queryset):
-    response = HttpResponse(mimetype="text/xml")
+    response = HttpResponse(content_type="text/xml")
     response['Content-Disposition'] = 'attachment; filename=troggle_output.xml'
     serializers.serialize("xml", queryset, stream=response)
     return response
diff --git a/core/forms.py b/core/forms.py
index b091696..8265178 100644
--- a/core/forms.py
+++ b/core/forms.py
@@ -46,12 +46,12 @@ class EntranceForm(ModelForm):
     #underground_centre_line = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
     #notes = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
     #references = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
-    other_station = forms.CharField(required=False) # Trying to change this to a singl;e line entry
-    tag_station = forms.CharField(required=False) # Trying to change this to a singl;e line entry
-    exact_station = forms.CharField(required=False) # Trying to change this to a singl;e line entry
-    northing = forms.CharField(required=False) # Trying to change this to a singl;e line entry
-    easting = forms.CharField(required=False) # Trying to change this to a singl;e line entry
-    alt = forms.CharField(required=False) # Trying to change this to a singl;e line entry
+    other_station = forms.CharField(required=False) # Trying to change this to a single line entry
+    tag_station = forms.CharField(required=False) # Trying to change this to a single line entry
+    exact_station = forms.CharField(required=False) # Trying to change this to a single line entry
+    northing = forms.CharField(required=False) # Trying to change this to a single line entry
+    easting = forms.CharField(required=False) # Trying to change this to a single line entry
+    alt = forms.CharField(required=False) # Trying to change this to a single line entry
     class Meta:
         model = Entrance
         exclude = ("cached_primary_slug", "filename",)
@@ -123,7 +123,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"):
diff --git a/core/templatetags/survex_markup.py b/core/templatetags/survex_markup.py
index 5b9aa36..d6ddd0e 100644
--- a/core/templatetags/survex_markup.py
+++ b/core/templatetags/survex_markup.py
@@ -47,6 +47,6 @@ def survex_to_html(value, autoescape=None):
     if autoescape:
         value = conditional_escape(value)
     for regex, sub in regexes:
-        print sub
+        print(sub)
         value = regex.sub(sub, value)
     return mark_safe(value)
\ No newline at end of file
diff --git a/core/views_caves.py b/core/views_caves.py
index a785170..af76b1e 100644
--- a/core/views_caves.py
+++ b/core/views_caves.py
@@ -10,11 +10,10 @@ from troggle.helper import login_required_if_public
 from django.forms.models import modelformset_factory
 from django import forms
 from django.core.urlresolvers import reverse
-from utils import render_with_context # see views_logbooks for explanation on this.
 from django.http import HttpResponse, HttpResponseRedirect
 from django.conf import settings
 import re, urlparse
-from django.shortcuts import get_object_or_404
+from django.shortcuts import get_object_or_404, render
 import settings
 
 
@@ -58,7 +57,7 @@ def caveindex(request):
     caves1626 = list(Cave.objects.filter(area__short_name = "1626"))
     caves1623.sort(caveCmp)
     caves1626.sort(caveCmp)
-    return render_with_context(request,'caveindex.html', {'caves1623': caves1623, 'caves1626': caves1626, 'notablecaves':notablecaves, 'cavepage': True})
+    return render(request,'caveindex.html', {'caves1623': caves1623, 'caves1626': caves1626, 'notablecaves':notablecaves, 'cavepage': True})
 
 def millenialcaves(request):
     #RW messing around area
@@ -83,43 +82,43 @@ def cave3d(request, cave_id=''):
 def cave(request, cave_id='', offical_name=''):
     cave=getCave(cave_id)
     if cave.non_public and settings.PUBLIC_SITE and not request.user.is_authenticated():
-        return render_with_context(request,'nonpublic.html', {'instance': cave, 'cavepage': True, 'cave_id': cave_id})
+        return render(request,'nonpublic.html', {'instance': cave, 'cavepage': True, 'cave_id': cave_id})
     else:
-        return render_with_context(request,'cave.html', {'settings': settings, 'cave': cave, 'cavepage': True, 'cave_id': cave_id})
+        return render(request,'cave.html', {'settings': settings, 'cave': cave, 'cavepage': True, 'cave_id': cave_id})
 
 def caveEntrance(request, slug):
     cave = Cave.objects.get(caveslug__slug = slug)
     if cave.non_public and settings.PUBLIC_SITE and not request.user.is_authenticated():
-        return render_with_context(request,'nonpublic.html', {'instance': cave})
+        return render(request,'nonpublic.html', {'instance': cave})
     else:
-        return render_with_context(request,'cave_entrances.html', {'cave': cave})
+        return render(request,'cave_entrances.html', {'cave': cave})
 
 def caveDescription(request, slug):
     cave = Cave.objects.get(caveslug__slug = slug)
     if cave.non_public and settings.PUBLIC_SITE and not request.user.is_authenticated():
-        return render_with_context(request,'nonpublic.html', {'instance': cave})
+        return render(request,'nonpublic.html', {'instance': cave})
     else:
-        return render_with_context(request,'cave_uground_description.html', {'cave': cave})
+        return render(request,'cave_uground_description.html', {'cave': cave})
 
 def caveQMs(request, slug):
     cave = Cave.objects.get(caveslug__slug = slug)
     if cave.non_public and settings.PUBLIC_SITE and not request.user.is_authenticated():
-        return render_with_context(request,'nonpublic.html', {'instance': cave})
+        return render(request,'nonpublic.html', {'instance': cave})
     else:
-        return render_with_context(request,'cave_qms.html', {'cave': cave})
+        return render(request,'cave_qms.html', {'cave': cave})
 def caveLogbook(request, slug):
     cave = Cave.objects.get(caveslug__slug = slug)
     if cave.non_public and settings.PUBLIC_SITE and not request.user.is_authenticated():
-        return render_with_context(request,'nonpublic.html', {'instance': cave})
+        return render(request,'nonpublic.html', {'instance': cave})
     else:
-        return render_with_context(request,'cave_logbook.html', {'cave': cave})
+        return render(request,'cave_logbook.html', {'cave': cave})
 
 def caveSlug(request, slug):
     cave = Cave.objects.get(caveslug__slug = slug)
     if cave.non_public and settings.PUBLIC_SITE and not request.user.is_authenticated():
-        return render_with_context(request,'nonpublic.html', {'instance': cave, 'cave_editable': slug})
+        return render(request,'nonpublic.html', {'instance': cave, 'cave_editable': slug})
     else:
-        return render_with_context(request,'cave.html', {'cave': cave, 'cave_editable': slug})
+        return render(request,'cave.html', {'cave': cave, 'cave_editable': slug})
 
 @login_required_if_public
 def edit_cave(request, slug=None):
@@ -160,7 +159,7 @@ def edit_cave(request, slug=None):
         ceFormSet = CaveAndEntranceFormSet(queryset=cave.caveandentrance_set.all())
         versionControlForm = VersionControlCommentForm()
         
-    return render_with_context(request, 
+    return render(request, 
                                'editcave2.html', 
                                {'form': form,
                                 'caveAndEntranceFormSet': ceFormSet,
@@ -204,7 +203,7 @@ def editEntrance(request, caveslug, slug=None):
             entletter = EntranceLetterForm(request.POST)
         else:
             entletter = None
-    return render_with_context(request, 
+    return render(request, 
                                'editentrance.html', 
                                {'form': form,
                                 'versionControlForm': versionControlForm,
@@ -215,7 +214,7 @@ 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_with_context(request,'qm.html',locals())
+        return render(request,'qm.html',locals())
 
     except QM.DoesNotExist:
         url=urlparse.urljoin(settings.URL_ROOT, r'/admin/core/qm/add/'+'?'+  r'number=' + qm_id)
@@ -228,16 +227,16 @@ def qm(request,cave_id,qm_id,year,grade=None):
 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_with_context(request,'entrance.html', {'cave': cave,
+    return render(request,'entrance.html', {'cave': cave,
                                                 'entrance': cave_and_ent.entrance,
                                                 'letter': cave_and_ent.entrance_letter,})
 
 def entranceSlug(request, slug):
     entrance = Entrance.objects.get(entranceslug__slug = slug)
     if entrance.non_public and not request.user.is_authenticated():
-        return render_with_context(request,'nonpublic.html', {'instance': entrance})
+        return render(request,'nonpublic.html', {'instance': entrance})
     else:
-        return render_with_context(request,'entranceslug.html', {'entrance': entrance})
+        return render(request,'entranceslug.html', {'entrance': entrance})
 
 def survexblock(request, survexpath):
     survexpath = re.sub("/", ".", survexpath)
@@ -245,12 +244,12 @@ def survexblock(request, survexpath):
     survexblock = models.SurvexBlock.objects.get(survexpath=survexpath)
     #ftext = survexblock.filecontents()
     ftext = survexblock.text
-    return render_with_context(request,'survexblock.html', {'survexblock':survexblock, 'ftext':ftext, })
+    return render(request,'survexblock.html', {'survexblock':survexblock, 'ftext':ftext, })
 
 def surveyindex(request):
     surveys=Survey.objects.all()
     expeditions=Expedition.objects.order_by("-year")
-    return render_with_context(request,'survey.html',locals())
+    return render(request,'survey.html',locals())
 
 def survey(request,year,wallet_number):
     surveys=Survey.objects.all()
@@ -263,19 +262,19 @@ def survey(request,year,wallet_number):
             planSketches=current_survey.scannedimage_set.filter(contents='plan')
             elevationSketches=current_survey.scannedimage_set.filter(contents='elevation')
 
-    return render_with_context(request,'survey.html', locals())
+    return render(request,'survey.html', locals())
 
 def cave_description(request, cavedescription_name):
     cave_description = get_object_or_404(CaveDescription, short_name = cavedescription_name)
-    return render_with_context(request,'cave_description.html', locals())
+    return render(request,'cave_description.html', locals())
 
 def get_entrances(request, caveslug):
     cave = Cave.objects.get(caveslug__slug = caveslug)
-    return render_with_context(request,'options.html', {"items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]})
+    return render(request,'options.html', {"items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]})
 
 def get_qms(request, caveslug):
     cave = Cave.objects.get(caveslug__slug = caveslug)
-    return render_with_context(request,'options.html', {"items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]})
+    return render(request,'options.html', {"items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]})
 
 areanames = [
 	#('',     'Location unclear'),
@@ -313,7 +312,7 @@ def prospecting(request):
         caves = list(a.cave_set.all())
         caves.sort(caveCmp)
         areas.append((name, a, caves))
-    return render_with_context(request, 'prospecting.html', {"areas": areas})
+    return render(request, 'prospecting.html', {"areas": areas})
     
 # Parameters for big map and zoomed subarea maps:
 # big map first (zoom factor ignored)
diff --git a/core/views_logbooks.py b/core/views_logbooks.py
index ffd1243..b8069da 100644
--- a/core/views_logbooks.py
+++ b/core/views_logbooks.py
@@ -1,4 +1,4 @@
-from django.shortcuts import render_to_response
+from django.shortcuts import render_to_response, render
 from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, SurvexBlock
 import troggle.core.models as models
 import troggle.settings as settings
@@ -9,7 +9,6 @@ from troggle.core.forms import getTripForm#, get_name, PersonForm
 from  django.core.urlresolvers import reverse
 from django.http import HttpResponseRedirect, HttpResponse
 from django.template import Context, loader
-from utils import render_with_context
 import os.path
 import troggle.parsers.logbooks as logbookparsers
 from django.template.defaultfilters import slugify
@@ -55,7 +54,7 @@ def personindex(request):
             if person.bisnotable():
                 notablepersons.append(person)
 
-    return render_with_context(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, })
+    return render(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons, })
 
 
 def expedition(request, expeditionname):
@@ -77,7 +76,7 @@ def expedition(request, expeditionname):
         
     if "reload" in request.GET:
         LoadLogbookForExpedition(this_expedition)
-    return render_with_context(request,'expedition.html', {'expedition': this_expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'settings':settings, 'dateditems': dateditems })
+    return render(request,'expedition.html', {'expedition': this_expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'settings':settings, 'dateditems': dateditems })
 
 def get_absolute_url(self):
     return ('expedition', (expedition.year))
@@ -102,7 +101,7 @@ def person(request, first_name='', last_name='', ):
             this_person.save()
             return HttpResponseRedirect(reverse('profiles_select_profile'))
     
-    return render_with_context(request,'person.html', {'person': this_person, })
+    return render(request,'person.html', {'person': this_person, })
 
 
 def GetPersonChronology(personexpedition):
@@ -135,17 +134,17 @@ def personexpedition(request, first_name='',  last_name='', year=''):
     this_expedition = Expedition.objects.get(year=year)
     personexpedition = person.personexpedition_set.get(expedition=this_expedition)
     personchronology = GetPersonChronology(personexpedition)
-    return render_with_context(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})
+    return render(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})
 
 
 def logbookentry(request, date, slug):
     this_logbookentry = LogbookEntry.objects.filter(date=date, slug=slug)
 
     if len(this_logbookentry)>1:
-        return render_with_context(request, 'object_list.html',{'object_list':this_logbookentry})
+        return render(request, 'object_list.html',{'object_list':this_logbookentry})
     else:
         this_logbookentry=this_logbookentry[0]
-        return render_with_context(request, 'logbookentry.html', {'logbookentry': this_logbookentry})
+        return render(request, 'logbookentry.html', {'logbookentry': this_logbookentry})
 
 
 def logbookSearch(request, extra):
@@ -156,14 +155,14 @@ def logbookSearch(request, extra):
     entry_query = search.get_query(query_string, ['text','title',])
     found_entries = LogbookEntry.objects.filter(entry_query)
 
-    return render_with_context(request,'logbooksearch.html',
+    return render(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_with_context(request,'personform.html', {'form':form,})
+    return render(request,'personform.html', {'form':form,})
 
 
 def experimental(request):
@@ -180,7 +179,7 @@ def experimental(request):
             
     survexlegs = models.SurvexLeg.objects.all()
     totalsurvexlength = sum([survexleg.tape  for survexleg in survexlegs])
-    return render_with_context(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
+    return render(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })
 
 @login_required_if_public
 def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None):
@@ -239,7 +238,7 @@ def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None):
             tripForm = TripForm() # An unbound form
             personTripFormSet = PersonTripFormSet()
 
-    return render_with_context(request, 'newlogbookentry.html', {
+    return render(request, 'newlogbookentry.html', {
         'tripForm': tripForm,
         'personTripFormSet': personTripFormSet,
 
@@ -261,8 +260,8 @@ def delLogbookEntry(lbe):
 
 def get_people(request, expeditionslug):
     exp = Expedition.objects.get(year = expeditionslug)
-    return render_with_context(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]})
+    return render(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]})
 
 def get_logbook_entries(request, expeditionslug):
     exp = Expedition.objects.get(year = expeditionslug)
-    return render_with_context(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]})
+    return render(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]})
diff --git a/core/views_other.py b/core/views_other.py
index 6a195b9..1297e7f 100644
--- a/core/views_other.py
+++ b/core/views_other.py
@@ -4,11 +4,11 @@ from django.conf import settings
 from django import forms
 from django.template import loader, Context
 from django.db.models import Q
+from django.shortcuts import render
 import databaseReset
 import re
 from django.http import HttpResponse, HttpResponseRedirect
 from django.core.urlresolvers import reverse
-from utils import render_with_context
 from troggle.core.models import *
 from troggle.helper import login_required_if_public
 
@@ -21,18 +21,18 @@ def stats(request):
     statsDict['caveCount'] = int(Cave.objects.count())
     statsDict['personCount'] = int(Person.objects.count())
     statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count())
-    return render_with_context(request,'statistics.html', statsDict)
+    return render(request,'statistics.html', statsDict)
 
 def frontpage(request):
     if request.user.is_authenticated():
-        return render_with_context(request,'tasks.html')
+        return render(request,'tasks.html')
 
     expeditions =  Expedition.objects.order_by("-year")
     logbookentry = LogbookEntry
     cave = Cave
     photo = DPhoto
     from django.contrib.admin.templatetags import log
-    return render_with_context(request,'frontpage.html', locals())
+    return render(request,'frontpage.html', locals())
 
 def todo(request):
     message = "no test message"  #reverse('personn', kwargs={"name":"hkjhjh"}) 
@@ -45,7 +45,7 @@ def todo(request):
 
     expeditions =  Expedition.objects.order_by("-year")
     totallogbookentries = LogbookEntry.objects.count()
-    return render_with_context(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message})
+    return render(request,'index.html', {'expeditions':expeditions, 'all':'all', 'totallogbookentries':totallogbookentries, "message":message})
 
 
 def controlPanel(request):
@@ -64,11 +64,11 @@ def controlPanel(request):
                     jobs_completed.append(item)
         else:
             if request.user.is_authenticated(): #The user is logged in, but is not a superuser.
-                return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'error':'You must be a superuser to use that feature.'})
+                return render(request,'controlPanel.html', {'caves':Cave.objects.all(),'error':'You must be a superuser to use that feature.'})
             else:
                 return HttpResponseRedirect(reverse('auth_login'))
 
-    return render_with_context(request,'controlPanel.html', {'caves':Cave.objects.all(),'expeditions':Expedition.objects.all(),'jobs_completed':jobs_completed})
+    return render(request,'controlPanel.html', {'caves':Cave.objects.all(),'expeditions':Expedition.objects.all(),'jobs_completed':jobs_completed})
 
 def downloadCavetab(request):
     from export import tocavetab
@@ -201,7 +201,7 @@ def logbook_entry_suggestions(request):
     print('got 208')
     any_suggestions=True
     print('got 210')
-    return render_with_context(request,'suggestions.html',
+    return render(request,'suggestions.html',
         {
         'unwiki_QMs':unwiki_QMs,
         'any_suggestions':any_suggestions
@@ -261,7 +261,7 @@ def newFile(request, pslug = None):
 #        else:        
 #            fileform = UploadFileForm() # An unbound form
 
-    return render_with_context(request, 'editfile.html', {
+    return render(request, 'editfile.html', {
         'fileForm': fileform,
 
     })
diff --git a/core/views_survex.py b/core/views_survex.py
index 9fc334a..a0f4637 100644
--- a/core/views_survex.py
+++ b/core/views_survex.py
@@ -178,7 +178,7 @@ def svx(request, survex_file):
 
 def svxraw(request, survex_file):
     svx = open(os.path.join(settings.SURVEX_DATA, survex_file+".svx"), "rb")
-    return HttpResponse(svx, mimetype="text")
+    return HttpResponse(svx, content_type="text")
 
 
 # The cavern running function
@@ -193,20 +193,20 @@ def threed(request, survex_file):
     process(survex_file)
     try:
         threed = open(settings.SURVEX_DATA + survex_file + ".3d", "rb")
-        return HttpResponse(threed, mimetype="model/3d")
+        return HttpResponse(threed, content_type="model/3d")
     except:
         log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
-        return HttpResponse(log, mimetype="text")
+        return HttpResponse(log, content_type="text")
 
 def log(request, survex_file):
     process(survex_file)
     log = open(settings.SURVEX_DATA + survex_file + ".log", "rb")
-    return HttpResponse(log, mimetype="text")
+    return HttpResponse(log, content_type="text")
 
 def err(request, survex_file):
     process(survex_file)
     err = open(settings.SURVEX_DATA + survex_file + ".err", "rb")
-    return HttpResponse(err, mimetype="text")
+    return HttpResponse(err, content_type="text")
 
 
 
diff --git a/flatpages/views.py b/flatpages/views.py
index 8bc25ba..6360393 100644
--- a/flatpages/views.py
+++ b/flatpages/views.py
@@ -1,6 +1,6 @@
 import troggle.settings as settings
 from troggle.helper import login_required_if_public
-from utils import render_with_context
+from django.shortcuts import render
 
 from django.http import HttpResponse, HttpResponseRedirect, Http404
 from  django.core.urlresolvers import reverse
@@ -47,13 +47,13 @@ def flatpage(request, path):
                 o = open(os.path.normpath(settings.EXPOWEB + path + "index.htm"), "rb")
                 path = path + "index.htm"
             except IOError:
-                return render_with_context(request, 'pagenotfound.html', {'path': path})
+                return render(request, 'pagenotfound.html', {'path': path})
     else:        
         try:
             filetobeopened = os.path.normpath(settings.EXPOWEB + path)
             o = open(filetobeopened, "rb")
         except IOError:
-            return render_with_context(request, 'pagenotfound.html', {'path': path})
+            return render(request, 'pagenotfound.html', {'path': path})
     if path.endswith(".htm") or path.endswith(".html"):
         html = o.read()
         
@@ -75,7 +75,7 @@ def flatpage(request, path):
         if re.search(r"iso-8859-1", html):
             body = unicode(body, "iso-8859-1")
             body.strip
-        return render_with_context(request, 'flatpage.html', {'editable': True, 'path': path, 'title': title, 'body': body, 'homepage': (path == "index.htm"), 'has_menu': has_menu})
+        return render(request, 'flatpage.html', {'editable': True, 'path': path, 'title': title, 'body': body, 'homepage': (path == "index.htm"), 'has_menu': has_menu})
     else:
         return HttpResponse(o.read(), content_type=getmimetype(path))
 
@@ -160,7 +160,7 @@ def editflatpage(request, path):
             flatpageForm = FlatPageForm({"html": body, "title": title})
         else:
             flatpageForm = FlatPageForm()
-    return render_with_context(request, 'editflatpage.html', {'path': path, 'form': flatpageForm, })
+    return render(request, 'editflatpage.html', {'path': path, 'form': flatpageForm, })
 
 class FlatPageForm(forms.Form):
     title = forms.CharField(widget=forms.TextInput(attrs={'size':'60'}))
diff --git a/templates/editcave2.html b/templates/editcave2.html
index 85df6e7..03deeea 100644
--- a/templates/editcave2.html
+++ b/templates/editcave2.html
@@ -9,6 +9,7 @@
 <script src="{{ settings.TINY_MCE_MEDIA_URL }}tiny_mce.js" type="text/javascript"></script>
 {% endblock %}
 {% block content %}
+<h1>Edit Cave</h1>
 <form action="" method="post">{% csrf_token %}
     <table>{{ form }}{{caveAndEntranceFormSet}}</table>
     {{ versionControlForm }}
diff --git a/templates/logbookentry.html b/templates/logbookentry.html
index 2b60996..cc1c9f1 100644
--- a/templates/logbookentry.html
+++ b/templates/logbookentry.html
@@ -65,9 +65,9 @@
 </div>
 
 <div id="col1">
-<div class="logbookentry">
-<b>{{logbookentry.date}}</b>
-    {{logbookentry.text|wiki_to_html}}</div>
+  <div class="logbookentry">
+    <b>{{logbookentry.date}}</b>
+    {{logbookentry.text}}</div>
 </div>
 </div>
 
diff --git a/urls.py b/urls.py
index 0dbd9a0..287755b 100644
--- a/urls.py
+++ b/urls.py
@@ -53,7 +53,7 @@ actualurlpatterns = patterns('',
     url(r'^getLogBookEntries/(?P<expeditionslug>.*)', views_logbooks.get_logbook_entries, name = "get_logbook_entries"),
 
     
-    url(r'^cave/new/$', edit_cave, name="newcave"),
+    url(r'^cave/new/$', views_caves.edit_cave, name="newcave"),
     url(r'^cave/(?P<cave_id>[^/]+)/?$', views_caves.cave, name="cave"),
     url(r'^caveslug/([^/]+)/?$', views_caves.caveSlug, name="caveSlug"),
     url(r'^cave/entrance/([^/]+)/?$', views_caves.caveEntrance),
@@ -71,7 +71,7 @@ actualurlpatterns = patterns('',
 #    url(r'^jgtuploadfile$',     view_surveys.jgtuploadfile, name="jgtuploadfile"),
 
     url(r'^cave/(?P<cave_id>[^/]+)/?(?P<ent_letter>[^/])$', ent),
-    url(r'^cave/(?P<slug>[^/]+)/edit/$', edit_cave, name="edit_cave"),
+    url(r'^cave/(?P<slug>[^/]+)/edit/$', views_caves.edit_cave, name="edit_cave"),
     #(r'^cavesearch', caveSearch),
 
     
diff --git a/utils.py b/utils.py
index a91a1aa..d5deeda 100644
--- a/utils.py
+++ b/utils.py
@@ -1,4 +1,5 @@
 from django.conf import settings
+from django.shortcuts import render
 import random, re, logging
 from troggle.core.models import CaveDescription
 
@@ -58,21 +59,6 @@ def save_carefully(objectType, lookupAttribs={}, nonLookupAttribs={}):
     if not created and not instance.new_since_parsing:
         logging.info(str(instance) + " existed in the database unchanged since last parse. It was overwritten by the current script. \n")
     return (instance, created)
-
-def render_with_context(req, *args, **kwargs):
-    """this is the snippet from http://www.djangosnippets.org/snippets/3/
-
-    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 django.shortcuts import render_to_response
-    from django.template import RequestContext
-    kwargs['context_instance'] = RequestContext(req)
-    return render_to_response(*args, **kwargs)
     
 re_body = re.compile(r"\<body[^>]*\>(.*)\</body\>", re.DOTALL)
 re_title = re.compile(r"\<title[^>]*\>(.*)\</title\>", re.DOTALL)

From 9cd8734947766637435ee0527725af3215c98e01 Mon Sep 17 00:00:00 2001
From: Sam Wenham <sam@wenhams.co.uk>
Date: Sun, 31 Mar 2019 15:39:53 +0100
Subject: [PATCH 3/6] Support html and wiki logbook entrys Move nearest_station
 to nearest_station_name and make nearest_station a foreign key to
 SurvexStation Lots of tidying

---
 core/models.py                   | 53 +++++++++++++++++---------------
 core/models_survex.py            |  2 +-
 core/templatetags/wiki_markup.py | 11 +++----
 parsers/QMs.py                   | 20 ++++++------
 parsers/logbooks.py              | 28 ++++++++++-------
 parsers/people.py                | 21 +++----------
 parsers/survex.py                |  4 +--
 templates/logbookentry.html      |  7 ++++-
 8 files changed, 73 insertions(+), 73 deletions(-)

diff --git a/core/models.py b/core/models.py
index 1b2875a..3d9041c 100644
--- a/core/models.py
+++ b/core/models.py
@@ -104,21 +104,19 @@ class Expedition(TroggleModel):
     def day_max(self):
         res = self.expeditionday_set.all()
         return res and res[len(res) - 1] or None
-        
-        
+
 
 class ExpeditionDay(TroggleModel):
     expedition  = models.ForeignKey("Expedition")
     date        = models.DateField()
 
     class Meta:
-        ordering = ('date',)  
+        ordering = ('date',)
 
     def GetPersonTrip(self, personexpedition):
         personexpeditions = self.persontrip_set.filter(expeditionday=self)
         return personexpeditions and personexpeditions[0] or None
-    
-        
+
 #
 # single Person, can go on many years
 #
@@ -247,18 +245,22 @@ class PersonExpedition(TroggleModel):
 # Single parsed entry from Logbook
 #    
 class LogbookEntry(TroggleModel):
-    date    = models.DateField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.
+
+    LOGBOOK_ENTRY_TYPES = (
+        ("wiki", "Wiki style logbook"),
+        ("html", "Html style logbook")
+    )
+
+    date    = models.DateTimeField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.ld()
     expeditionday = models.ForeignKey("ExpeditionDay", null=True)#MJG wants to KILL THIS (redundant information)
     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.
-    # Re: the above- so this field should be "typist" or something, not "author". - AC 15 jun 09
-    #MJG wants to KILL THIS, as it is typically redundant with PersonTrip.is_logbook_entry_author, in the rare it was not redundanty and of actually interest it could be added to the text.
-    title     = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
-    cave_slug = models.SlugField(max_length=50)
-    place     = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
-    text      = models.TextField()
-    slug      = models.SlugField(max_length=50)
-    filename  = models.CharField(max_length=200,null=True)
+    title      = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
+    cave_slug  = models.SlugField(max_length=50)
+    place      = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
+    text       = models.TextField()
+    slug       = models.SlugField(max_length=50)
+    filename   = models.CharField(max_length=200,null=True)
+    entry_type = models.CharField(default="wiki",null=True,choices=LOGBOOK_ENTRY_TYPES,max_length=50)
 
     class Meta:
         verbose_name_plural = "Logbook Entries"
@@ -297,7 +299,7 @@ class LogbookEntry(TroggleModel):
         if self.cave:
             nextQMnumber=self.cave.new_QM_number(self.date.year)
         else:
-            return none
+            return None
         return nextQMnumber
 
     def new_QM_found_link(self):
@@ -307,6 +309,7 @@ class LogbookEntry(TroggleModel):
     def DayIndex(self):
         return list(self.expeditionday.logbookentry_set.all()).index(self)
 
+
 #
 # Single Person going on a trip, which may or may not be written up (accounts for different T/U for people in same logbook entry)
 #
@@ -452,7 +455,7 @@ class Cave(TroggleModel):
         elif self.unofficial_number:
             href = self.unofficial_number
         else:
-            href = official_name.lower()
+            href = self.official_name.lower()
         #return settings.URL_ROOT + '/cave/' + href + '/'
         return urlparse.urljoin(settings.URL_ROOT, reverse('cave',kwargs={'cave_id':href,}))
 
@@ -744,17 +747,17 @@ class QM(TroggleModel):
 
     number = models.IntegerField(help_text="this is the sequential number in the year", )
     GRADE_CHOICES=(
-	('A', 'A: Large obvious lead'),
-	('B', 'B: Average lead'),
-	('C', 'C: Tight unpromising lead'),
-	('D', 'D: Dig'),
-	('X', 'X: Unclimbable aven')
+    ('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)
+    nearest_station_name = models.CharField(max_length=200,blank=True,null=True)
+    nearest_station = models.ForeignKey(SurvexStation,null=True,blank=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)
@@ -834,7 +837,7 @@ class ScannedImage(TroggleImageModel):
     #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 __unicode__(self):
         return get_scan_path(self,'')
 
diff --git a/core/models_survex.py b/core/models_survex.py
index f6b3284..ed581a3 100644
--- a/core/models_survex.py
+++ b/core/models_survex.py
@@ -225,4 +225,4 @@ class TunnelFile(models.Model):
     
     class Meta:
         ordering = ('tunnelpath',)
-    
+
diff --git a/core/templatetags/wiki_markup.py b/core/templatetags/wiki_markup.py
index 3bc5b07..2640594 100644
--- a/core/templatetags/wiki_markup.py
+++ b/core/templatetags/wiki_markup.py
@@ -7,7 +7,6 @@ from troggle.core.models import QM, DPhoto, LogbookEntry, Cave
 import re, urlparse
 
 register = template.Library()
-                
 
 @register.filter()
 def plusone(n):
@@ -77,7 +76,7 @@ def wiki_to_html_short(value, autoescape=None):
         if number>1:
             return '<h'+num+'>'+matchobj.groups()[1]+'</h'+num+'>'
         else:
-            print 'morethanone'
+            print('morethanone')
             return matchobj.group()
     value = re.sub(r"(?m)^(=+)([^=]+)(=+)$",headerrepl,value)
     
@@ -143,13 +142,13 @@ def wiki_to_html_short(value, autoescape=None):
     value = re.sub(photoSrcPattern,photoSrcRepl, value, re.DOTALL)
 
     #make cave links
-    value = re.sub("\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%scave/\1/">\1</a>' % settings.URL_ROOT, value, re.DOTALL)
+    value = re.sub(r"\[\[\s*cave:([^\s]+)\s*\s*\]\]", r'<a href="%scave/\1/">\1</a>' % settings.URL_ROOT, value, re.DOTALL)
     #make people links
-    value = re.sub("\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%sperson/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
+    value = re.sub(r"\[\[\s*person:(.+)\|(.+)\]\]",r'<a href="%sperson/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
     #make subcave links
-    value = re.sub("\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%ssubcave/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
+    value = re.sub(r"\[\[\s*subcave:(.+)\|(.+)\]\]",r'<a href="%ssubcave/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
     #make cavedescription links
-    value = re.sub("\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%scavedescription/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
+    value = re.sub(r"\[\[\s*cavedescription:(.+)\|(.+)\]\]",r'<a href="%scavedescription/\1/">\2</a>' % settings.URL_ROOT, value, re.DOTALL)
 
 
 
diff --git a/parsers/QMs.py b/parsers/QMs.py
index efc8cd6..602b7af 100644
--- a/parsers/QMs.py
+++ b/parsers/QMs.py
@@ -17,19 +17,19 @@ def parseCaveQMs(cave,inputFile):
         try:
             steinBr=Cave.objects.get(official_name="Steinbr&uuml;ckenh&ouml;hle")
         except Cave.DoesNotExist:
-            print "Steinbruckenhoehle is not in the database. Please run parsers.cavetab first."
+            print("Steinbruckenhoehle is not in the database. Please run parsers.cavetab first.")
             return
     elif cave=='hauch':
         try:
             hauchHl=Cave.objects.get(official_name="Hauchh&ouml;hle")
         except Cave.DoesNotExist:
-            print "Hauchhoele is not in the database. Please run parsers.cavetab first."
+            print("Hauchhoele is not in the database. Please run parsers.cavetab first.")
             return
     elif cave =='kh':
         try:
             kh=Cave.objects.get(official_name="Kaninchenh&ouml;hle")
         except Cave.DoesNotExist:
-            print "KH is not in the database. Please run parsers.cavetab first."
+            print("KH is not in the database. Please run parsers.cavetab first.")
         parse_KH_QMs(kh, inputFile=inputFile) 
         return
 
@@ -48,7 +48,7 @@ def parseCaveQMs(cave,inputFile):
             elif cave=='hauch':
                 placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, title="placeholder for QMs in 234", text="QMs temporarily attached to this should be re-attached to their actual trips", defaults={"date": date(year, 1, 1),"cave":hauchHl})            
             if hadToCreate:
-                print cave+" placeholder logbook entry for " + str(year) + " added to database"
+                print(cave + " placeholder logbook entry for " + str(year) + " added to database")
             QMnum=re.match(r".*?-\d*?-X?(?P<numb>\d*)",line[0]).group("numb")
             newQM = QM()
             newQM.found_by=placeholder
@@ -71,19 +71,18 @@ def parseCaveQMs(cave,inputFile):
                 if preexistingQM.new_since_parsing==False:  #if the pre-existing QM has not been modified, overwrite it
                     preexistingQM.delete()
                     newQM.save()
-                    print "overwriting " + str(preexistingQM) +"\r",
-                
+                    print("overwriting " + str(preexistingQM) +"\r")
                 else:  # otherwise, print that it was ignored
-                    print "preserving "+ str(preexistingQM) + ", which was edited in admin \r",
+                    print("preserving " + str(preexistingQM) + ", which was edited in admin \r")
                     
             except QM.DoesNotExist:         #if there is no pre-existing QM, save the new one
                 newQM.save() 
-                print "QM "+str(newQM) + ' added to database\r',
+                print("QM "+str(newQM) + ' added to database\r')
                 
         except KeyError: #check on this one
             continue
         except IndexError:
-            print "Index error in " + str(line)
+            print("Index error in " + str(line))
             continue
 
 def parse_KH_QMs(kh, inputFile):
@@ -104,7 +103,7 @@ def parse_KH_QMs(kh, inputFile):
                 }
             nonLookupArgs={
                 'grade':res['grade'],
-                'nearest_station':res['nearest_station'],
+                'nearest_station_name':res['nearest_station'],
                 'location_description':res['description']
                 }
  
@@ -115,3 +114,4 @@ parseCaveQMs(cave='stein',inputFile=r"1623/204/qm.csv")
 parseCaveQMs(cave='hauch',inputFile=r"1623/234/qm.csv")
 parseCaveQMs(cave='kh', inputFile="1623/161/qmtodo.htm")
 #parseCaveQMs(cave='balkonhoehle',inputFile=r"1623/264/qm.csv")
+
diff --git a/parsers/logbooks.py b/parsers/logbooks.py
index fbe00a3..cecbdb3 100644
--- a/parsers/logbooks.py
+++ b/parsers/logbooks.py
@@ -45,7 +45,7 @@ def GetTripPersons(trippeople, expedition, logtime_underground):
         author = res[-1][0]
     return res, author
 
-def GetTripCave(place):                     #need to be fuzzier about matching here. Already a very slow function...
+def GetTripCave(place):  #need to be fuzzier about matching here. Already a very slow function...
 #    print "Getting cave for " , place
     try:
         katastNumRes=[]
@@ -74,23 +74,23 @@ def GetTripCave(place):                     #need to be fuzzier about matching h
 
 
 noncaveplaces = [ "Journey", "Loser Plateau" ]
-def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_underground):
+def EnterLogIntoDbase(date, place, title, text, trippeople, expedition, logtime_underground, entry_type="wiki"):
     """ saves a logbook entry and related persontrips """
     trippersons, author = GetTripPersons(trippeople, expedition, logtime_underground)
     if not author:
-        print("   - skipping logentry" + title + " no author for entry")
+        print("   - Skipping logentry: " + title + " no author for entry")
         return
-    
-#    tripCave = GetTripCave(place)
-    #
+
+    #tripCave = GetTripCave(place)
+
     lplace = place.lower()
     if lplace not in noncaveplaces:
         cave=GetCaveLookup().get(lplace)
 
     #Check for an existing copy of the current entry, and save
     expeditionday = expedition.get_expedition_day(date)
-    lookupAttribs={'date':date, 'title':title} 
-    nonLookupAttribs={'place':place, 'text':text, 'expedition':expedition, 'cave':cave, 'slug':slugify(title)[:50]}
+    lookupAttribs={'date':date, 'title':title}
+    nonLookupAttribs={'place':place, 'text':text, 'expedition':expedition, 'cave':cave, 'slug':slugify(title)[:50], 'entry_type':entry_type}
     lbo, created=save_carefully(models.LogbookEntry, lookupAttribs, nonLookupAttribs)
     
     for tripperson, time_underground in trippersons:
@@ -177,7 +177,9 @@ def Parseloghtmltxt(year, expedition, txt):
         ltriptext = re.sub(r"</p>", "", triptext)
         ltriptext = re.sub(r"\s*?\n\s*", " ", ltriptext)
         ltriptext = re.sub(r"<p>", "\n\n", ltriptext).strip()
-        EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle, text = ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
+        EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle, text = ltriptext,
+                          trippeople=trippeople, expedition=expedition, logtime_underground=0,
+                          entry_type="html")
     if logbook_entry_count == 0:
         print(" - No trip entrys found in logbook, check the syntax matches htmltxt format")
 
@@ -226,7 +228,9 @@ def Parseloghtml01(year, expedition, txt):
 
         #print ldate, trippeople.strip()
             # could includ the tripid (url link for cross referencing)
-        EnterLogIntoDbase(date=ldate, place=tripcave, title=triptitle, text=ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
+        EnterLogIntoDbase(date=ldate, place=tripcave, title=triptitle, text=ltriptext,
+                          trippeople=trippeople, expedition=expedition, logtime_underground=0,
+                          entry_type="html")
 
 # parser for 2003
 def Parseloghtml03(year, expedition, txt):
@@ -255,7 +259,9 @@ def Parseloghtml03(year, expedition, txt):
         ltriptext = re.sub(r"\s*?\n\s*", " ", ltriptext)
         ltriptext = re.sub(r"<p>", "\n\n", ltriptext).strip()
         ltriptext = re.sub(r"[^\s0-9a-zA-Z\-.,:;'!&()\[\]<>?=+*%]", "_NONASCII_", ltriptext)
-        EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle, text = ltriptext, trippeople=trippeople, expedition=expedition, logtime_underground=0)
+        EnterLogIntoDbase(date = ldate, place = tripcave, title = triptitle,
+                          text = ltriptext, trippeople=trippeople, expedition=expedition,
+                          logtime_underground=0, entry_type="html")
 
 
 def SetDatesFromLogbookEntries(expedition):
diff --git a/parsers/people.py b/parsers/people.py
index 48d6c17..1eb6bcd 100644
--- a/parsers/people.py
+++ b/parsers/people.py
@@ -59,22 +59,19 @@ def LoadPersonsExpos():
         
         save_carefully(models.Expedition, lookupAttribs, nonLookupAttribs)
 
-    
     # make persons
     print("Loading personexpeditions")
-    #expoers2008 = """Edvin Deadman,Kathryn Hopkins,Djuke Veldhuis,Becka Lawson,Julian Todd,Natalie Uomini,Aaron Curtis,Tony Rooke,Ollie Stevens,Frank Tully,Martin Jahnke,Mark Shinwell,Jess Stirrups,Nial Peters,Serena Povia,Olly Madge,Steve Jones,Pete Harley,Eeva Makiranta,Keith Curtis""".split(",")
-    #expomissing = set(expoers2008)
 
     for personline in personreader:
         name = personline[header["Name"]]
         name = re.sub(r"<.*?>", "", name)
         mname = re.match(r"(\w+)(?:\s((?:van |ten )?\w+))?(?:\s\(([^)]*)\))?", name)
         nickname = mname.group(3) or ""
-	
+
         lookupAttribs={'first_name':mname.group(1), 'last_name':(mname.group(2) or "")}
         nonLookupAttribs={'is_vfho':personline[header["VfHO member"]],}
         person, created = save_carefully(models.Person, lookupAttribs, nonLookupAttribs)
-	
+
         parseMugShotAndBlurb(personline=personline, header=header, person=person)
     
         # make person expedition from table
@@ -88,6 +85,8 @@ def LoadPersonsExpos():
 
     # this fills in those people for whom 2008 was their first expo
     #print "Loading personexpeditions 2008"
+    #expoers2008 = """Edvin Deadman,Kathryn Hopkins,Djuke Veldhuis,Becka Lawson,Julian Todd,Natalie Uomini,Aaron Curtis,Tony Rooke,Ollie Stevens,Frank Tully,Martin Jahnke,Mark Shinwell,Jess Stirrups,Nial Peters,Serena Povia,Olly Madge,Steve Jones,Pete Harley,Eeva Makiranta,Keith Curtis""".split(",")
+    #expomissing = set(expoers2008)
     #for name in expomissing:
         # firstname, lastname = name.split()
         # is_guest = name in ["Eeva Makiranta", "Keith Curtis"]
@@ -103,18 +102,6 @@ def LoadPersonsExpos():
         # personexpedition = models.PersonExpedition(person=person, expedition=expedition, nickname="", is_guest=is_guest)
         # personexpedition.save()
 
-    #Notability is now a method of person. Makes no sense to store it in the database; it would need to be recalculated every time something changes. - AC 16 Feb 09
-    # could rank according to surveying as well
-    #print "Setting person notability"
-    #for person in models.Person.objects.all():
-        #person.notability = 0.0
-        #for personexpedition in person.personexpedition_set.all():
-            #if not personexpedition.is_guest:
-                #person.notability += 1.0 / (2012 - int(personexpedition.expedition.year))
-        #person.bisnotable = person.notability > 0.3 # I don't know how to filter by this
-        #person.save()
-        
-        
 # used in other referencing parser functions
 # expedition name lookup cached for speed (it's a very big list)
 Gpersonexpeditionnamelookup = { }
diff --git a/parsers/survex.py b/parsers/survex.py
index 536314f..a999c43 100644
--- a/parsers/survex.py
+++ b/parsers/survex.py
@@ -92,13 +92,13 @@ def RecursiveLoad(survexblock, survexfile, fin, textlines):
     teammembers = [ ]
  
 # uncomment to print out all files during parsing 
-    print("Reading file:", survexblock.survexfile.path)
+    print("Reading file: " + survexblock.survexfile.path)
     while True:
         svxline = fin.readline().decode("latin1")
         if not svxline:
             return
         textlines.append(svxline)
-        
+
         # break the line at the comment
         sline, comment = re.match(r"([^;]*?)\s*(?:;\s*(.*))?\n?$", svxline.strip()).groups()
         
diff --git a/templates/logbookentry.html b/templates/logbookentry.html
index cc1c9f1..0534de9 100644
--- a/templates/logbookentry.html
+++ b/templates/logbookentry.html
@@ -67,7 +67,12 @@
 <div id="col1">
   <div class="logbookentry">
     <b>{{logbookentry.date}}</b>
-    {{logbookentry.text}}</div>
+    {% if logbookentry.entry_type == "html" %}
+      <p>{{logbookentry.text|safe}}</p>
+    {% else %}
+      {{logbookentry.text|wiki_to_html}}
+    {% endif %}
+  </div>
 </div>
 </div>
 

From 40f413ba470fdc449879ed2917f631ca66f5979a Mon Sep 17 00:00:00 2001
From: Sam Wenham <sam@wenhams.co.uk>
Date: Sun, 31 Mar 2019 16:43:21 +0100
Subject: [PATCH 4/6] Ooops shouldn't of commited the DateTime change, yet...

---
 core/models.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/models.py b/core/models.py
index 3d9041c..d978eaa 100644
--- a/core/models.py
+++ b/core/models.py
@@ -251,7 +251,7 @@ class LogbookEntry(TroggleModel):
         ("html", "Html style logbook")
     )
 
-    date    = models.DateTimeField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.ld()
+    date    = models.DateField()#MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.ld()
     expeditionday = models.ForeignKey("ExpeditionDay", null=True)#MJG wants to KILL THIS (redundant information)
     expedition  = models.ForeignKey(Expedition,blank=True,null=True)  # yes this is double-
     title      = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)

From 144610d6c248d9546d60c891ca926f89c5577d1d Mon Sep 17 00:00:00 2001
From: Sam Wenham <sam@wenhams.co.uk>
Date: Sun, 31 Mar 2019 16:44:58 +0100
Subject: [PATCH 5/6] Better error messages

---
 parsers/surveys.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/parsers/surveys.py b/parsers/surveys.py
index 72a05f3..29070e8 100644
--- a/parsers/surveys.py
+++ b/parsers/surveys.py
@@ -99,7 +99,7 @@ def parseSurveyScans(expedition, logfile=None):
                 #scanList = listdir(expedition.year, surveyFolder)
                 scanList=os.listdir(os.path.join(yearPath,surveyFolder))
             except AttributeError:
-                print(surveyFolder + " ignored\r",)
+                print("Folder: " + surveyFolder + " ignored\r")
                 continue
 
             for scan in scanList:
@@ -107,7 +107,7 @@ def parseSurveyScans(expedition, logfile=None):
                     scanChopped=re.match(r'(?i).*(notes|elev|plan|elevation|extend)(\d*)\.(png|jpg|jpeg)',scan).groups()
                     scanType,scanNumber,scanFormat=scanChopped
                 except AttributeError:
-                    print(scan + " ignored\r",)
+                    print("File: " + scan + " ignored\r")
                     continue
                 if scanType == 'elev' or scanType == 'extend':
                     scanType = 'elevation'

From bb8dbb381fe87c3a63e9586a1bf1e993b09c965b Mon Sep 17 00:00:00 2001
From: expoonserver <devnull@localhost>
Date: Mon, 1 Apr 2019 23:03:45 +0100
Subject: [PATCH 6/6] Move cave and entrance data out of 'noinfo'

---
 settings.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/settings.py b/settings.py
index b0656ae..9770fd7 100644
--- a/settings.py
+++ b/settings.py
@@ -45,8 +45,8 @@ NOTABLECAVESHREFS = [ "161", "204", "258", "76", "107", "264" ]
 # Examples: "http://foo.com/media/", "/media/".
 ADMIN_MEDIA_PREFIX = '/troggle/media-admin/'
 PHOTOS_ROOT = os.path.join(EXPOWEB, 'photos')
-CAVEDESCRIPTIONS = os.path.join(EXPOWEB, "noinfo", "cave_data")
-ENTRANCEDESCRIPTIONS = os.path.join(EXPOWEB, "noinfo", "entrance_data")
+CAVEDESCRIPTIONS = os.path.join(EXPOWEB, "cave_data")
+ENTRANCEDESCRIPTIONS = os.path.join(EXPOWEB, "entrance_data")
 
 MEDIA_URL = urlparse.urljoin(URL_ROOT , '/site_media/')
 SURVEYS_URL = urlparse.urljoin(URL_ROOT , '/survey_scans/')