2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2024-11-25 08:41:51 +00:00

Allow entrances to be edited with the correct parent url. Commit changes to caves when adding a new entrance. Order entrances alphabetically

This commit is contained in:
Martin Green 2022-08-01 16:04:22 +02:00
parent fa6758b9a0
commit f491264b9e
5 changed files with 87 additions and 51 deletions

View File

@ -116,11 +116,21 @@ class EntranceForm(ModelForm):
CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=('cave',))
class EntranceLetterForm(ModelForm):
'''Can't see what this does at all. called twice from views.caves
'''Form to link entrances to caves, along with an entrance number.
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.
'''
class Meta:
model = CaveAndEntrance
exclude = ('cave', 'entrance')
def full_clean(self):
super(EntranceLetterForm, self).full_clean()
try:
self.instance.validate_unique()
except forms.ValidationError as e:
self._update_errors(e)

View File

@ -62,6 +62,10 @@ class CaveAndEntrance(models.Model):
cave = models.ForeignKey('Cave',on_delete=models.CASCADE)
entrance = models.ForeignKey('Entrance',on_delete=models.CASCADE)
entrance_letter = models.CharField(max_length=20,blank=True, null=True)
class Meta:
unique_together = [['cave', 'entrance'], ['cave', 'entrance_letter']]
ordering = ['entrance_letter']
def __str__(self):
return str(self.cave) + str(self.entrance_letter)
@ -176,7 +180,7 @@ class Cave(TroggleModel):
# res=QM.objects.filter(found_by__date__year=year, found_by__cave_slug=self.slug).order_by('-number')[0]
# except IndexError:
# return 1
# return res.number+1
# return res.number+1CaveAndEntrance
def kat_area(self):
for a in self.area.all():
@ -228,7 +232,15 @@ class Cave(TroggleModel):
u = t.render(c)
writetrogglefile(filepath, u)
return
def file_output(self):
filepath = Path(os.path.join(settings.CAVEDESCRIPTIONS, self.filename))
t = loader.get_template('dataformat/cave.xml')
#c = Context({'cave': self})
c = dict({'cave': self})
content = t.render(c)
return (filepath, content, "utf8")
def getArea(self):
areas = self.area.all()
@ -287,6 +299,9 @@ class Entrance(TroggleModel):
url = models.CharField(max_length=200,blank=True, null=True)
filename = models.CharField(max_length=200)
cached_primary_slug = models.CharField(max_length=200,blank=True, null=True)
class Meta:
ordering = ['caveandentrance__entrance_letter']
def __str__(self):
return str(self.slug())
@ -338,7 +353,7 @@ class Entrance(TroggleModel):
def has_photo(self):
if self.photo:
if (self.photo.find("<img") > -1 or self.photo.find("<a") > -1 or self.photo.find("<IMG") > -1 or self.photo.find("<A") > -1):
return "Yecaves"
return "Yes"
else:
return "Missing"
else:
@ -394,6 +409,14 @@ class Entrance(TroggleModel):
def get_file_path(self):
return Path(settings.ENTRANCEDESCRIPTIONS, self.filename)
def file_output(self):
filepath = Path(os.path.join(settings.ENTRANCEDESCRIPTIONS, self.filename))
t = loader.get_template('dataformat/entrance.xml')
c = dict({'entrance': self})
content = t.render(c)
return (filepath, content, "utf8")
def writeDataFile(self):
filepath = os.path.join(settings.ENTRANCEDESCRIPTIONS, self.filename)

View File

@ -129,7 +129,7 @@ def write_and_commit(files, message):
kwargs = {"encoding": encoding}
else:
mode = "wb"
kwargs = {}
kwargs = {}
try:
with open(filepath, mode, **kwargs) as f:
print(f'WRITING{cwd}---{filename} ')
@ -139,18 +139,21 @@ def write_and_commit(files, message):
except PermissionError:
raise WriteAndCommitError(f'CANNOT save this file.\nPERMISSIONS incorrectly set on server for this file {filename}. Ask a nerd to fix this.')
cp_add = subprocess.run([git, "add", filename], cwd=cwd, capture_output=True, text=True)
if cp_add.returncode != 0:
msgdata = 'Ask a nerd to fix this.\n\n' + cp_add.stderr + '\n\n' + cp_add.stdout + '\n\nreturn code: ' + str(cp_add.returncode)
raise WriteAndCommitError(f'CANNOT git on server for this file {filename}. Edits saved but not added to git.\n\n' + msgdata)
cp_diff = subprocess.run([git, "diff", filename], cwd=cwd, capture_output=True, text=True)
if cp_diff.returncode == 0:
cp_add = subprocess.run([git, "add", filename], cwd=cwd, capture_output=True, text=True)
if cp_add.returncode != 0:
msgdata = 'Ask a nerd to fix this.\n\n' + cp_add.stderr + '\n\n' + cp_add.stdout + '\n\nreturn code: ' + str(cp_add.returncode)
raise WriteAndCommitError(f'CANNOT git on server for this file {filename}. Edits saved but not added to git.\n\n' + msgdata)
else:
print("No change %s" % filepah)
cp_commit = subprocess.run([git, "commit", "-m", message], cwd=cwd, capture_output=True, text=True)
cp_status = subprocess.run([git, "status"], cwd=cwd, capture_output=True, text=True)
# This produces return code = 1 if it commits OK, but when the repo still needs to be pushed to origin/expoweb
if cp_commit.returncode != 0 and cp_commit.stdout != 'nothing to commit, working tree clean':
msgdata = 'Ask a nerd to fix this.\n\n' + cp_commit.stderr + '\n\n' + cp_commit.stdout + '\n\nreturn code: ' + str(cp_commit.returncode)
print(msgdata)
if cp_status.stdout.split("\n")[-2] != 'nothing to commit, working tree clean':
print("FOO: ", cp_status.stdout.split("\n")[-2])
msgdata = 'Ask a nerd to fix this.\n\n' + cp_status.stderr + '\n\n' + cp_status.stdout + '\n\nreturn code: ' + str(cp_status.returncode)
raise WriteAndCommitError(f'Error code with git on server for this file {filename}. Edits saved, added to git, but NOT committed.\n\n' + msgdata)
except subprocess.SubprocessError:
raise WriteAndCommitError(f'CANNOT git on server for this file {filename}. Subprocess error. Edits not saved.\nAsk a nerd to fix this.')

View File

@ -19,6 +19,7 @@ from troggle.core.views import expo
from troggle.core.models.troggle import Expedition, DataIssue
from troggle.core.models.caves import CaveSlug, Cave, CaveAndEntrance, QM, EntranceSlug, Entrance, Area, SurvexStation, GetCaveLookup
from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, EntranceForm, EntranceLetterForm
from troggle.core.utils import writetrogglefile, write_and_commit
from .auth import login_required_if_public
'''Manages the complex procedures to assemble a cave description out of the compnoents
@ -187,7 +188,7 @@ def file3d(request, cave, cave_id):
# These if statements need refactoring more cleanly
if cave.survex_file:
#print(" - cave.survex_file '{}'".format(cave.survex_file))
if threedpath.is_file():
if threedpath.Pathis_file():
#print(" - threedpath '{}'".format(threedpath))
# possible error here as several .svx files of same names in different directories will overwrite in /3d/
if survexpath.is_file():
@ -342,7 +343,8 @@ def edit_cave(request, path = "", slug=None):
ceinst.cave = cave
ceinst.save()
try:
cave.writeDataFile()
cave_file = cave.file_output()
write_and_commit([cave_file], "Online edit of %s" % cave)
# leave other exceptions unhandled so that they bubble up to user interface
except PermissionError:
message = f'CANNOT save this file.\nPERMISSIONS incorrectly set on server for this file {cave.filename}. Ask a nerd to fix this.'
@ -375,27 +377,28 @@ def edit_entrance(request, path = "", caveslug=None, slug=None):
It does save the data into into the database directly, not by parsing the file.
'''
message = ""
if caveslug is not None:
try:
cave = Cave.objects.get(caveslug__slug = caveslug)
except:
return render(request,'errors/badslug.html', {'badslug': caveslug})
else:
cave = Cave()
if slug is not None:
try:
cave = Cave.objects.get(caveslug__slug = caveslug)
except:
return render(request,'errors/badslug.html', {'badslug': caveslug})
if slug:
entrance = Entrance.objects.get(entranceslug__slug = slug)
caveAndEntrance = CaveAndEntrance.objects.get(entrance = entrance, cave = cave)
entlettereditable = False
else:
entrance = Entrance()
caveAndEntrance = CaveAndEntrance(cave = cave, entrance = entrance)
entlettereditable = True
if request.POST:
form = EntranceForm(request.POST, instance = entrance)
entletter = EntranceLetterForm(request.POST, instance = caveAndEntrance)
#versionControlForm = VersionControlCommentForm(request.POST)
if slug is None:
entletter = EntranceLetterForm(request.POST)
else:
entletter = None
if form.is_valid() and (slug is not None or entletter.is_valid()):
if form.is_valid() and entletter.is_valid():
entrance = form.save(commit = False)
entrance_letter = entletter.save(commit = False)
if slug is None:
if entletter.cleaned_data["entrance_letter"]:
slugname = cave.slug() + entletter.cleaned_data["entrance_letter"]
@ -407,36 +410,29 @@ def edit_entrance(request, path = "", caveslug=None, slug=None):
if slug is None:
es = EntranceSlug(entrance = entrance, slug = slugname, primary = True)
es.save()
el = entletter.save(commit = False)
el.cave = cave
el.entrance = entrance
el.save()
try:
entrance.writeDataFile()
# leave other exceptions unhandled so that they bubble up to user interface
except PermissionError:
message = f'CANNOT save this file.\nPERMISSIONS incorrectly set on server for this file {entrance.filename}. Ask a nerd to fix this.'
return render(request,'errors/generic.html', {'message': message})
except subprocess.SubprocessError:
message = f'CANNOT git on server for this file {entrance.filename}. Edits may not be committed.\nAsk a nerd to fix this.'
return render(request,'errors/generic.html', {'message': message})
entrance_file = entrance.file_output()
cave_file = cave.file_output()
write_and_commit([entrance_file, cave_file], "Online edit of %s%s" % (cave, entletter))
entrance.save()
if slug is None:
entrance_letter.save()
return HttpResponseRedirect("/" + cave.url)
else:
message = f'! POST data is INVALID {cave}'
print(message)
else:
form = EntranceForm(instance = entrance)
#versionControlForm = VersionControlCommentForm()
if slug is None:
entletter = EntranceLetterForm(request.POST)
entletter = EntranceLetterForm()
else:
entletter = None
entletter = caveAndEntrance.entrance_letter
return render(request,
'editentrance.html',
{'form': form, 'cave': cave, 'message': message,
{'form': form,
'cave': cave,
#'versionControlForm': versionControlForm,
'entletter': entletter
'entletter': entletter,
'entlettereditable': entlettereditable
})
def ent(request, cave_id, ent_letter):

View File

@ -8,8 +8,12 @@
<h1>Edit Entrance - at cave {{cave.official_name|safe}} - {{cave.kataster_number}}</h1>
{% include 'html_editor_pop_ups.html' %}
<h2>{{message}}</h2>
<p>{{entletter}}
<form action="" method="post">{% csrf_token %}
{% if entlettereditable %}
<table>{{ entletter }}</table>
{% else %}
<table><tr><th>Entrance Letter</th><td>{{ entletter }}</td></table>
{% endif %}
<table>{{ form }}</table>
{{ versionControlForm }}
<p><input type="submit" value="Submit" /></p>