mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-15 06:17:07 +00:00
bugfixes and more comments
This commit is contained in:
@@ -45,6 +45,8 @@ todo = """
|
|||||||
class CaveForm(ModelForm):
|
class CaveForm(ModelForm):
|
||||||
"""Only those fields for which we want to override defaults are listed here
|
"""Only those fields for which we want to override defaults are listed here
|
||||||
the other fields of the class Cave are present on the form, but use the default presentation style
|
the other fields of the class Cave are present on the form, but use the default presentation style
|
||||||
|
|
||||||
|
see https://docs.djangoproject.com/en/5.1/topics/forms/modelforms/
|
||||||
"""
|
"""
|
||||||
unofficial_number= forms.CharField(required=False,
|
unofficial_number= forms.CharField(required=False,
|
||||||
label="Unofficial Number used to construct internal identifiers",
|
label="Unofficial Number used to construct internal identifiers",
|
||||||
@@ -143,6 +145,8 @@ class CaveForm(ModelForm):
|
|||||||
class EntranceForm(ModelForm):
|
class EntranceForm(ModelForm):
|
||||||
"""Only those fields for which we want to override defaults are listed here
|
"""Only those fields for which we want to override defaults are listed here
|
||||||
the other fields are present on the form, but use the default presentation style
|
the other fields are present on the form, but use the default presentation style
|
||||||
|
|
||||||
|
see https://docs.djangoproject.com/en/5.1/topics/forms/modelforms/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = forms.CharField(required=False, widget=forms.TextInput(attrs={"size": "45", "placeholder": "usually leave this blank"}))
|
name = forms.CharField(required=False, widget=forms.TextInput(attrs={"size": "45", "placeholder": "usually leave this blank"}))
|
||||||
@@ -240,7 +244,6 @@ class EntranceForm(ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
# # This next line is sufficient to create an entire entry for for the cave fields automatically
|
# # This next line is sufficient to create an entire entry for for the cave fields automatically
|
||||||
# # using django built-in Deep Magic. https://docs.djangoproject.com/en/dev/topics/forms/modelforms/
|
|
||||||
# # for forms which map directly onto a Django Model
|
# # for forms which map directly onto a Django Model
|
||||||
# CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=("cave",))
|
# CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=("cave",))
|
||||||
# # This is used only in templates/editcave.html which is called only to edit caves in core/views/cave.py
|
# # This is used only in templates/editcave.html which is called only to edit caves in core/views/cave.py
|
||||||
@@ -250,6 +253,8 @@ class EntranceLetterForm(ModelForm):
|
|||||||
|
|
||||||
Nb. The relationship between caves and entrances has historically been a many to many relationship.
|
Nb. The relationship between caves and entrances has historically been a many to many relationship.
|
||||||
With entrances gaining new caves and letters when caves are joined.
|
With entrances gaining new caves and letters when caves are joined.
|
||||||
|
|
||||||
|
see https://docs.djangoproject.com/en/5.1/topics/forms/modelforms/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# This only needs to be required=True for the second and subsequent entrances, not the first. Tricky.
|
# This only needs to be required=True for the second and subsequent entrances, not the first. Tricky.
|
||||||
|
|||||||
@@ -555,6 +555,13 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
|
|||||||
|
|
||||||
GET RID of all this entranceletter stuff. Far too overcomplexified.
|
GET RID of all this entranceletter stuff. Far too overcomplexified.
|
||||||
We don't need it. Just the entrance slug is fine, then check uniqueness.
|
We don't need it. Just the entrance slug is fine, then check uniqueness.
|
||||||
|
|
||||||
|
A whole new form is created just to edit the entranceletter.
|
||||||
|
To Do: put the entranceletter field on the Entrance, and delete the whole
|
||||||
|
CaveandEntrance class and form thing.
|
||||||
|
Don't use the existance of a CaveandEntrance object to see if the letter is valid,
|
||||||
|
just count the entrances instead.
|
||||||
|
We can do this simplification as troggle now assumes only 1 cave per entrance.
|
||||||
"""
|
"""
|
||||||
def check_new_slugname_ok(slug, letter):
|
def check_new_slugname_ok(slug, letter):
|
||||||
"""In Nov.2023 it is possible to create a 2nd entrance and not set an entrance letter,
|
"""In Nov.2023 it is possible to create a 2nd entrance and not set an entrance letter,
|
||||||
@@ -808,9 +815,14 @@ def qm(request, cave_id, qm_id, year, grade=None, blockname=None):
|
|||||||
Needs refactoring though! Uses extremely baroque way of getting the QMs instead of querying for QM objects
|
Needs refactoring though! Uses extremely baroque way of getting the QMs instead of querying for QM objects
|
||||||
directly, presumably as a result of a baroque history.
|
directly, presumably as a result of a baroque history.
|
||||||
|
|
||||||
Many caves have several QMS with the same number, grade, year (2018) and first 8 chars of the survexblock. This crashes things, so the terminal char of the survexblock name was added
|
Many caves have several QMS with the same number, grade, year (2018) and first 8 chars of the survexblock.
|
||||||
|
This crashes things, so the terminal char of the survexblock name was added to disambiguate
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not qm_id:
|
||||||
|
message = f"No qm_id specified {cave_id=} {year=} {blockname=}"
|
||||||
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
|
|
||||||
year = int(year)
|
year = int(year)
|
||||||
|
|
||||||
if blockname == "" or not blockname:
|
if blockname == "" or not blockname:
|
||||||
|
|||||||
@@ -71,8 +71,14 @@ def map(request):
|
|||||||
def mapfile(request, path):
|
def mapfile(request, path):
|
||||||
"""Serves unadorned file: everything in the /map/... folder tree"""
|
"""Serves unadorned file: everything in the /map/... folder tree"""
|
||||||
fn = Path(settings.EXPOWEB, "map", path)
|
fn = Path(settings.EXPOWEB, "map", path)
|
||||||
print(f"MAP cuttout. \n{path=}\n{fn=} mime:{getmimetype(fn)}")
|
if fn.is_file():
|
||||||
return HttpResponse(content=open(fn, "r"), content_type=getmimetype(fn))
|
print(f"MAP cuttout. \n{path=}\n{fn=} mime:{getmimetype(fn)}")
|
||||||
|
return HttpResponse(content=open(fn, "r"), content_type=getmimetype(fn))
|
||||||
|
else:
|
||||||
|
message = f"### File not found ### {fn}"
|
||||||
|
print(message)
|
||||||
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def expofilessingle(request, filepath):
|
def expofilessingle(request, filepath):
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import re
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.views.generic.list import ListView
|
from django.views.generic.list import ListView
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
import troggle.settings as settings
|
import troggle.settings as settings
|
||||||
from troggle.core.models.logbooks import QM, LogbookEntry, PersonLogEntry, writelogbook
|
from troggle.core.models.logbooks import QM, LogbookEntry, PersonLogEntry, writelogbook
|
||||||
@@ -307,8 +308,17 @@ def logreport(request, year=1999):
|
|||||||
return render(request, "errors/generic.html", {"message": msg})
|
return render(request, "errors/generic.html", {"message": msg})
|
||||||
|
|
||||||
def logbookentry(request, date, slug):
|
def logbookentry(request, date, slug):
|
||||||
# start = time.time()
|
"""Displays a single logbook entry
|
||||||
trips = LogbookEntry.objects.filter(date=date) # all the trips not just this one
|
however, if an author has not used the correct URL in an image or a reference, then a link from
|
||||||
|
inside a logbook entry can arrive with this default address prefix. So we
|
||||||
|
have to handle that error without crashing.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
trips = LogbookEntry.objects.filter(date=date) # all the trips not just this one
|
||||||
|
except ValidationError:
|
||||||
|
msg = f' Logbook entry invalid date:"{date}" probably because of relative (not absolute) addressing of "src=" or "haref=" in the text'
|
||||||
|
print(msg)
|
||||||
|
return render(request, "errors/generic.html", {"message": msg})
|
||||||
this_logbookentry = trips.filter(date=date, slug=slug)
|
this_logbookentry = trips.filter(date=date, slug=slug)
|
||||||
year = slug[:4]
|
year = slug[:4]
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ class LogbookEditForm(forms.Form): # not a model-form, just a form-form
|
|||||||
@login_required_if_public
|
@login_required_if_public
|
||||||
def edittxtpage(request, path, filepath):
|
def edittxtpage(request, path, filepath):
|
||||||
"""Editing a .txt file on expoweb/
|
"""Editing a .txt file on expoweb/
|
||||||
|
Yes this is a security hazard as arbitrary text can be uploaded and it is not enclosed in any HTML furniture.
|
||||||
"""
|
"""
|
||||||
def simple_get(viewtext):
|
def simple_get(viewtext):
|
||||||
form = ExpotextfileForm()
|
form = ExpotextfileForm()
|
||||||
@@ -175,9 +176,10 @@ def edittxtpage(request, path, filepath):
|
|||||||
message=""
|
message=""
|
||||||
|
|
||||||
if not filepath.is_file():
|
if not filepath.is_file():
|
||||||
|
message = f"File not found '{filepath}\n\nfailure detected in expowebpage() in views.expo.py"
|
||||||
print(f"Not a file: {filepath}")
|
print(f"Not a file: {filepath}")
|
||||||
errpage = f"<html>" + default_head + f"<h3>File not found '{filepath}'<br><br>failure detected in expowebpage() in views.expo.py</h3> </body>"
|
return render(request, "errors/generic.html", {"message": message})
|
||||||
return HttpResponse(errpage)
|
|
||||||
try:
|
try:
|
||||||
with open(filepath, "r") as f:
|
with open(filepath, "r") as f:
|
||||||
originaltext = f.read()
|
originaltext = f.read()
|
||||||
@@ -207,6 +209,9 @@ def edittxtpage(request, path, filepath):
|
|||||||
if "Save" in request.POST:
|
if "Save" in request.POST:
|
||||||
print("submitted for saving..")
|
print("submitted for saving..")
|
||||||
|
|
||||||
|
# should insert sanitization in here
|
||||||
|
# but user cannot rename the file, and cannot create new files
|
||||||
|
# and this is only used for .txt files
|
||||||
if newtext != originaltext: # Check if content has changed at all
|
if newtext != originaltext: # Check if content has changed at all
|
||||||
print("text changed.. saving and committing")
|
print("text changed.. saving and committing")
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -20,6 +20,15 @@ class TroggleModelAdmin(admin.ModelAdmin):
|
|||||||
NB any *Admin class is used in the Django control panel only.
|
NB any *Admin class is used in the Django control panel only.
|
||||||
|
|
||||||
The jquery links have been REMOVED from the templates as they were not used anywhere.
|
The jquery links have been REMOVED from the templates as they were not used anywhere.
|
||||||
|
Martin include jQuery in his HTML editor though, using the default copy provided by Djangon in the
|
||||||
|
/media/admin/js/vendor/jquery/ folder
|
||||||
|
which is
|
||||||
|
"jQuery JavaScript Library v3.5.1"
|
||||||
|
Date: 2020-05-04T22:49Z
|
||||||
|
as distributed with Django 4.2 I think.
|
||||||
|
|
||||||
|
CaveView is big, so we do not include it with the troggle software repo.
|
||||||
|
It is Debian packed software and installed ont he server as a Debian package.
|
||||||
|
|
||||||
templates/editentrance.html:
|
templates/editentrance.html:
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% block nav %}{% endblock %}
|
{% block nav %}{% endblock %}
|
||||||
<h2>{{logbookentry.title|safe}}</h2>
|
<h2>{{logbookentry.title|safe}}</h2>
|
||||||
|
|
||||||
<div id="related">
|
<div id="relatedentries">
|
||||||
<p><a href="{{ logbookentry.expedition.get_absolute_url }}">{{logbookentry.expedition.year}} calendar page</a>
|
<p><a href="{{ logbookentry.expedition.get_absolute_url }}">{{logbookentry.expedition.year}} calendar page</a>
|
||||||
<a href="/years/{{logbookentry.expedition.year}}/{{logbookentry.expedition.logbookfile}}">full logbook</a>
|
<a href="/years/{{logbookentry.expedition.year}}/{{logbookentry.expedition.logbookfile}}">full logbook</a>
|
||||||
<a href="/logreport/{{logbookentry.expedition.year}}">logbook report</a>
|
<a href="/logreport/{{logbookentry.expedition.year}}">logbook report</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user