diff --git a/core/views/caves.py b/core/views/caves.py
index 3bdc6f4..d7699d0 100644
--- a/core/views/caves.py
+++ b/core/views/caves.py
@@ -46,7 +46,65 @@ todo = """
own directory 16xx/NNN/ even if they have no images to put in it.
"""
+# def cavepagefwd(request, karea=None, subpath=None):
+ # """archaic, just send to the caves list page
+ # """
+ # return redirect("/caves")
+
+def get_cave_from_slug(caveslug):
+ """This is the old way of doing it, usingt eh CaveSlug intermediate object which does
+ the many:many relationship between slugs and caves - whcih we don't do (and never did in practice)
+ """
+ caves = []
+
+ print(f"get_cave_from_slug(): {caveslug} ...")
+ areacode = caveslug[:4] # e.g. 1623
+ id = caveslug[5:] # e.g. 161 or 2023-MM-02
+ thisarea = Cave.objects.filter(areacode=areacode)
+
+ caves_k = thisarea.filter(kataster_number=id)
+ if len(caves_k) == 1:
+ caves.append(caves_k[0])
+ print(f"get_cave_from_slug(): {caves_k=} {len(caves_k)=}")
+
+ caves_id = thisarea.filter(unofficial_number=id)
+ if len(caves_id) == 1:
+ caves.append(caves_id[0])
+ print(f"get_cave_from_slug(): {caves_id=} {len(caves_id)=}")
+
+ if len(caves) > 1:
+ print(f"get_cave_from_slug(): {caveslug} More than 1 \n{caves}")
+ if len(caves) <1:
+ print(f"get_cave_from_slug(): {caveslug} Nowt found..")
+ cave = caves[0]
+ print(f"get_cave_from_slug(): {caveslug} FOUND {cave}")
+
+ try:
+ cave_zero = Cave.objects.get(caveslug__slug=caveslug)
+ print(f"Getting cave from '{caveslug}'")
+ if cave_zero != cave:
+ print(f"get_cave_from_slug(): {caveslug} BAD DISCREPANCY {cave_zero=} {cave=}")
+ else:
+ print(f"get_cave_from_slug(): {caveslug} SUCCESS")
+
+ return cave_zero
+ except:
+ return None
+
+def caveslugfwd(request, slug):
+ """This is ass backwards. It would be better style to have the slug-identified request be the master, and have
+ other paths redirect to it, rather than what we have here.
+ Pending a change where we remove cave.url as a field and have an explicit fixed convention instead.
+ """
+ if not slug:
+ message = f"Failed to find cave from identifier given: {slug}."
+ return render(request, "errors/generic.html", {"message": message})
+ Gcavelookup = GetCaveLookup()
+ if slug in Gcavelookup:
+ cave = Gcavelookup[slug]
+
+ return redirect(f"/{cave.url}")
def getCaves(cave_id):
@@ -93,7 +151,7 @@ def pad5(x):
def padnumber(x):
- return re.sub("\d+", pad5, x) # SyntaxWarning: invalid escape sequence '\d'
+ return re.sub(r"\d+", pad5, x)
def numericalcmp(x, y):
@@ -311,24 +369,7 @@ def rendercave(request, cave, slug, cave_id=""):
) # crashes here with NoReverseMatch if url not set up for 'edit_cave' in urls.py
return r
-def cavepagefwd(request, karea=None, subpath=None):
- """archaic, just send to the caves list page
- """
- return redirect("/caves")
-def caveslugfwd(request, slug):
- """This is ass backwards. It would be better style to have the slug-identified request be the master, and have
- other paths redirect to it, rather than what we have here.
- Pending a change where we remove cave.url as a field and have an explicit fixed convention instead.
- """
- if slug:
- Gcavelookup = GetCaveLookup()
- if slug in Gcavelookup:
- cave = Gcavelookup[slug]
- else:
- message = f"Failed to find cave from identifier given: {slug}."
- return render(request, "errors/generic.html", {"message": message})
- return redirect(f"/{cave.url}")
def cavepage(request, karea=None, subpath=None):
"""Displays a cave description page
@@ -368,9 +409,7 @@ def cavepage(request, karea=None, subpath=None):
subparts = parts[0].split(".")
caveid = subparts[0]
slug = f"{karea}-{caveid}"
- caves = Cave.objects.filter(caveslug__slug=slug)
- if len(caves) == 1:
- cave = caves[0]
+ if cave:= get_cave_from_slug(slug): # walrus operator
return redirect(f"/{cave.url}")
else:
return redirect(f"/caves")
@@ -410,31 +449,31 @@ def edit_cave(request, path="", slug=None):
"""
print(f"edit_cave(): {path=} {slug=}")
message = ""
- if slug is not None:
- print(f"{slug=}")
- try:
- cave = Cave.objects.get(caveslug__slug=slug)
- except:
- return render(request, "errors/badslug.html", {"badslug": f"{slug} - from edit_cave()"})
+ if slug is None:
+ cave = Cave() # create a New Cave
else:
- cave = Cave()
+ print(f"{slug=}")
+ if not (cave:= get_cave_from_slug(slug)): # walrus operator
+ return render(request, "errors/badslug.html", {"badslug": f"for cave {caveslug} - from edit_cave()"})
+
if request.POST:
form = CaveForm(request.POST, instance=cave)
#ceFormSet = CaveAndEntranceFormSet(request.POST)
if form.is_valid(): # and ceFormSet.is_valid():
- # print(f'! POST is valid. {cave}')
+ print(f'edit_cave(): POST is valid. Editing {cave}')
cave = form.save(commit=False)
- print(cave)
+ # print(cave)
if not cave.filename:
cave.filename = cave.areacode + "-" + cave.number() + ".html"
if not cave.url:
cave.url = cave.areacode + "/" + cave.number()
cave.save()
- form.save_m2m()
+ form.save_m2m() # this does the many-to-many relationship saving between caves and entrances
if slug is None:
# it is not visible on the form so it always will be None
slug = f"{cave.areacode}-{cave.number()}"
cs = CaveSlug(cave=cave, slug=slug, primary=True)
+ print(f"edit_cave(): New CaveSlug saved {slug}")
cs.save()
#ceinsts = ceFormSet.save(commit=False)
#for ceinst in ceinsts:
@@ -450,6 +489,8 @@ def edit_cave(request, path="", slug=None):
except subprocess.SubprocessError:
message = f"CANNOT git on server for this file {cave.filename}. Edits may not be committed.\nAsk a nerd to fix this."
return render(request, "errors/generic.html", {"message": message})
+ except:
+ raise
if cave.entrances().count() > 0:
return HttpResponseRedirect("/" + cave.url)
else:
@@ -458,8 +499,8 @@ def edit_cave(request, path="", slug=None):
else:
if slug is not None:
# re-read cave data from file.
- #print(f"edit_cave(): {cave=} {cave.filename=}")
- #print(f"edit_cave(): {cave.slug()=}")
+ print(f"edit_cave(): {cave=} {cave.filename=}")
+ print(f"edit_cave(): {cave.slug()=}")
if cave.filename:
try:
read_cave(cave.filename, cave=cave)
@@ -472,7 +513,8 @@ def edit_cave(request, path="", slug=None):
else:
form = CaveForm()
#ceFormSet = CaveAndEntranceFormSet(queryset=CaveAndEntrance.objects.none())
-
+
+ print(f"edit_cave(): returning render()")
return render(
request,
"editcave.html",
@@ -486,6 +528,7 @@ def edit_cave(request, path="", slug=None):
)
+
@login_required_if_public
def edit_entrance(request, path="", caveslug=None, entslug=None):
"""This is the form that edits the entrance data for a single entrance and writes out
@@ -497,6 +540,9 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
It does save the data into into the database directly, not by parsing the file.
+ 'path' comes from the urls.py regex but is usually empty (!)
+ So we make the proper path for storing the images ourselves.
+
GET RID of all this entranceletter stuff. Far too overcomplexified.
We don't need it. Just the entrance slug is fine, then check uniqueness.
"""
@@ -526,9 +572,7 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
nextletter = chr(ord(letter)+1)
return check_new_slugname_ok(slug, nextletter)
- try:
- cave = Cave.objects.get(caveslug__slug=caveslug)
- except:
+ if not (cave:= get_cave_from_slug(caveslug)): # walrus operator
return render(request, "errors/badslug.html", {"badslug": f"for cave {caveslug} - from edit_entrance()"})
if entslug:
@@ -541,7 +585,7 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
entrance = None
if entslug:
- print(f"{caveslug=} {entslug=} {path=} number of ents:{cave.entrances().count()}")
+ print(f"Edit Entrance {caveslug=} {entslug=} {path=} number of ents:{cave.entrances().count()}")
caveAndEntrance = CaveAndEntrance.objects.get(entrance=entrance, cave=cave)
entlettereditable = False
else:
@@ -556,6 +600,11 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
print(f"{entlettereditable=}")
# if the entletter is not editable, then the entletterform does not appear and so is always invalid.
+
+ print(f"{caveslug=}")
+ print(f"{cave=}")
+ imgpath = Path(path) / cave.areacode / cave.number()
+ print(f"Edit Entrance {imgpath=}")
if request.POST:
print(f"POST Online edit of entrance: '{entrance}' where {cave=}")
@@ -683,7 +732,7 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
"entletter": entletter,
"entletterform": entletterform, # is unset if not being used
"entlettereditable": entlettereditable,
- "path": path + "/", # used for saving images if attached
+ "path": str(imgpath) + "/", # used for saving images if attached
},
)
@@ -719,9 +768,7 @@ def caveslist(request):
{"caves": caves, "year": current_expo()},
)
def get_entrances(request, caveslug):
- try:
- cave = Cave.objects.get(caveslug__slug=caveslug)
- except:
+ if not (cave:= get_cave_from_slug(caveslug)): # walrus operator
return render(request, "errors/badslug.html", {"badslug": f"{caveslug} - from get_entrances()"})
return render(
request, "options.html", {"year": current_expo(), "items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]}
@@ -733,9 +780,7 @@ def caveQMs(request, slug, open=False):
relies on the template to find all the QMs for the cave specified in the slug, e.g. '1623-161'
Now working in July 2022
"""
- try:
- cave = Cave.objects.get(caveslug__slug=slug)
- except:
+ if not (cave:= get_cave_from_slug(caveslug)): # walrus operator
return render(request, "errors/badslug.html", {"badslug": f"{slug} - from caveQMs()"})
if cave.non_public and settings.PUBLIC_SITE and not request.user.is_authenticated:
diff --git a/core/views/editor_helpers.py b/core/views/editor_helpers.py
index 0c3f5b6..9db71c2 100644
--- a/core/views/editor_helpers.py
+++ b/core/views/editor_helpers.py
@@ -26,6 +26,11 @@ THUMBNAIL_HEIGHT = 200
It uses a lot of opinionated Django default magic, none of which I am familiar with.
Philip
+
+The function image_selector() is only called from a template file doing a popup input form,
+but it stores files directly in expoweb/i /l /t instead of in
+/expoweb/1623/2018-MS-01/i , /l, /t
+so ALL new caves have photos in the smae place, which makes the default upload EXTREMELY CONFUSING
"""
def get_dir(path):
@@ -38,7 +43,10 @@ def get_dir(path):
def image_selector(request, path):
- """Returns available images"""
+ """Returns available images
+ called from
+ templates/html_editor_scripts_css.html: $('#image_popup_content').load("{% url 'image_selector' path %}" + path, function() {
+ """
directory = get_dir(path)
print(f" - image selector {directory=} {path=}")
thumbnailspath = Path(settings.EXPOWEB) / directory / "t"
@@ -89,15 +97,23 @@ def reorient_image(img, exif_dict):
def new_image_form(request, path):
"""Manages a form to upload new images"""
directory = get_dir(path)
+ print(f"new_image_form(): {directory=} {path=}")
if request.method == "POST":
+ print(f"new_image_form(): POST ")
form = NewWebImageForm(request.POST, request.FILES, directory=directory)
if form.is_valid():
+ print(f"new_image_form(): form is valid ")
+ print(f"new_image_form(): files: {request.FILES["file_"]}")
f = request.FILES["file_"]
binary_data = io.BytesIO()
for chunk in f.chunks():
binary_data.write(chunk)
+ print(f"new_image_form(): binary chnks written")
i = Image.open(binary_data)
+ print(f"new_image_form(): {i=}")
if "exif" in i.info:
+ print(f"new_image_form(): exif: {i=}")
+
exif_dict = piexif.load(i.info["exif"])
i = reorient_image(i, exif_dict)
exif_dict['Exif'][41729] = b'1'
@@ -109,13 +125,21 @@ def new_image_form(request, path):
else:
exif = None
+ print(f"new_image_form(): No exif problems")
width, height = i.size
+ print(f"new_image_form(): {i.size=}")
if width > MAX_IMAGE_WIDTH or height > MAX_IMAGE_HEIGHT:
+ print(f"new_image_form(): rescaling ")
scale = max(width / MAX_IMAGE_WIDTH, height / MAX_IMAGE_HEIGHT)
- i = i.resize((int(width / scale), int(height / scale)), Image.ANTIALIAS)
+ print(f"new_image_form(): rescaling {scale=}")
+ try:
+ i = i.resize((int(width / scale), int(height / scale)), Image.LANCZOS)
+ except Exception as e:
+ print(f"new_image_form(): rescaling exception: {e} ")
+
+ print(f"new_image_form(): rescaled ")
tscale = max(width / THUMBNAIL_WIDTH, height / THUMBNAIL_HEIGHT)
- thumbnail = i.resize((int(width / tscale), int(height / tscale)), Image.ANTIALIAS)
-
+ thumbnail = i.resize((int(width / tscale), int(height / tscale)), Image.LANCZOS)
ib = io.BytesIO()
i = i.convert('RGB')
i.save(ib, format="jpeg", quality = 75)
@@ -123,6 +147,7 @@ def new_image_form(request, path):
thumbnail = thumbnail.convert('RGB')
thumbnail.save(tb, format="jpeg", quality = 70)
image_rel_path, thumb_rel_path, desc_rel_path = form.get_rel_paths()
+ print(f"new_image_form(): \n {image_rel_path=}\n {thumb_rel_path=}\n {desc_rel_path=}")
image_page_template = loader.get_template("image_page_template.html") # this is the .html file in the /l/ folder
image_page = image_page_template.render(
{
@@ -149,14 +174,21 @@ def new_image_form(request, path):
f"{change_message} - online adding of an image",
)
except WriteAndCommitError as e:
+ print(f"new_image_form(): WriteAndCommitError: {e.message}")
return JsonResponse({"error": e.message})
+ except Exception as e:
+ print(f"new_image_form(): EXCEPTION: {e.message}")
+ return JsonResponse({"error": e.message})
+
linked_image_template = loader.get_template("linked_image_template.html")
html_snippet = linked_image_template.render(
{"thumbnail_url": f"/{thumb_rel_path}", "page_url": f"/{desc_rel_path}"}, request
)
return JsonResponse({"html": html_snippet})
else:
+ print(f"new_image_form(): not POST ")
form = NewWebImageForm(directory=directory)
+ print(f"new_image_form(): POST and not POST ")
template = loader.get_template("new_image_form.html")
htmlform = template.render({"form": form, "path": path}, request)
return JsonResponse({"form": htmlform})
diff --git a/templates/dataformat/cave.xml b/templates/dataformat/cave.xml
index c6032f0..e2bf6dd 100644
--- a/templates/dataformat/cave.xml
+++ b/templates/dataformat/cave.xml
@@ -16,8 +16,8 @@ the form documented at
-{{ cave.non_public }}{% for slug in cave.caveslug_set.all %}
-
+{{ cave.non_public }}
+
{{ cave.official_name|default_if_none:""|safe }}
{{cave.areacode |safe }}
{{ cave.kataster_code|default_if_none:"-"|safe }}