mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2024-11-25 16:51:54 +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:
parent
fa6758b9a0
commit
f491264b9e
@ -116,11 +116,21 @@ class EntranceForm(ModelForm):
|
|||||||
CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=('cave',))
|
CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=('cave',))
|
||||||
|
|
||||||
class EntranceLetterForm(ModelForm):
|
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:
|
class Meta:
|
||||||
model = CaveAndEntrance
|
model = CaveAndEntrance
|
||||||
exclude = ('cave', 'entrance')
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +62,10 @@ class CaveAndEntrance(models.Model):
|
|||||||
cave = models.ForeignKey('Cave',on_delete=models.CASCADE)
|
cave = models.ForeignKey('Cave',on_delete=models.CASCADE)
|
||||||
entrance = models.ForeignKey('Entrance',on_delete=models.CASCADE)
|
entrance = models.ForeignKey('Entrance',on_delete=models.CASCADE)
|
||||||
entrance_letter = models.CharField(max_length=20,blank=True, null=True)
|
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):
|
def __str__(self):
|
||||||
return str(self.cave) + str(self.entrance_letter)
|
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]
|
# res=QM.objects.filter(found_by__date__year=year, found_by__cave_slug=self.slug).order_by('-number')[0]
|
||||||
# except IndexError:
|
# except IndexError:
|
||||||
# return 1
|
# return 1
|
||||||
# return res.number+1
|
# return res.number+1CaveAndEntrance
|
||||||
|
|
||||||
def kat_area(self):
|
def kat_area(self):
|
||||||
for a in self.area.all():
|
for a in self.area.all():
|
||||||
@ -229,6 +233,14 @@ class Cave(TroggleModel):
|
|||||||
writetrogglefile(filepath, u)
|
writetrogglefile(filepath, u)
|
||||||
return
|
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):
|
def getArea(self):
|
||||||
areas = self.area.all()
|
areas = self.area.all()
|
||||||
@ -288,6 +300,9 @@ class Entrance(TroggleModel):
|
|||||||
filename = models.CharField(max_length=200)
|
filename = models.CharField(max_length=200)
|
||||||
cached_primary_slug = models.CharField(max_length=200,blank=True, null=True)
|
cached_primary_slug = models.CharField(max_length=200,blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['caveandentrance__entrance_letter']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.slug())
|
return str(self.slug())
|
||||||
|
|
||||||
@ -338,7 +353,7 @@ class Entrance(TroggleModel):
|
|||||||
def has_photo(self):
|
def has_photo(self):
|
||||||
if self.photo:
|
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):
|
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:
|
else:
|
||||||
return "Missing"
|
return "Missing"
|
||||||
else:
|
else:
|
||||||
@ -395,6 +410,14 @@ class Entrance(TroggleModel):
|
|||||||
def get_file_path(self):
|
def get_file_path(self):
|
||||||
return Path(settings.ENTRANCEDESCRIPTIONS, self.filename)
|
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):
|
def writeDataFile(self):
|
||||||
filepath = os.path.join(settings.ENTRANCEDESCRIPTIONS, self.filename)
|
filepath = os.path.join(settings.ENTRANCEDESCRIPTIONS, self.filename)
|
||||||
|
|
||||||
|
@ -139,18 +139,21 @@ def write_and_commit(files, message):
|
|||||||
except PermissionError:
|
except PermissionError:
|
||||||
raise WriteAndCommitError(f'CANNOT save this file.\nPERMISSIONS incorrectly set on server for this file {filename}. Ask a nerd to fix this.')
|
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)
|
cp_diff = subprocess.run([git, "diff", filename], cwd=cwd, capture_output=True, text=True)
|
||||||
if cp_add.returncode != 0:
|
if cp_diff.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)
|
cp_add = subprocess.run([git, "add", filename], cwd=cwd, capture_output=True, text=True)
|
||||||
raise WriteAndCommitError(f'CANNOT git on server for this file {filename}. Edits saved but not added to git.\n\n' + msgdata)
|
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_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
|
# 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':
|
if cp_status.stdout.split("\n")[-2] != '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("FOO: ", cp_status.stdout.split("\n")[-2])
|
||||||
print(msgdata)
|
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)
|
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:
|
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.')
|
raise WriteAndCommitError(f'CANNOT git on server for this file {filename}. Subprocess error. Edits not saved.\nAsk a nerd to fix this.')
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ from troggle.core.views import expo
|
|||||||
from troggle.core.models.troggle import Expedition, DataIssue
|
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.models.caves import CaveSlug, Cave, CaveAndEntrance, QM, EntranceSlug, Entrance, Area, SurvexStation, GetCaveLookup
|
||||||
from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, EntranceForm, EntranceLetterForm
|
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
|
from .auth import login_required_if_public
|
||||||
|
|
||||||
'''Manages the complex procedures to assemble a cave description out of the compnoents
|
'''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
|
# These if statements need refactoring more cleanly
|
||||||
if cave.survex_file:
|
if cave.survex_file:
|
||||||
#print(" - cave.survex_file '{}'".format(cave.survex_file))
|
#print(" - cave.survex_file '{}'".format(cave.survex_file))
|
||||||
if threedpath.is_file():
|
if threedpath.Pathis_file():
|
||||||
#print(" - threedpath '{}'".format(threedpath))
|
#print(" - threedpath '{}'".format(threedpath))
|
||||||
# possible error here as several .svx files of same names in different directories will overwrite in /3d/
|
# possible error here as several .svx files of same names in different directories will overwrite in /3d/
|
||||||
if survexpath.is_file():
|
if survexpath.is_file():
|
||||||
@ -342,7 +343,8 @@ def edit_cave(request, path = "", slug=None):
|
|||||||
ceinst.cave = cave
|
ceinst.cave = cave
|
||||||
ceinst.save()
|
ceinst.save()
|
||||||
try:
|
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
|
# leave other exceptions unhandled so that they bubble up to user interface
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
message = f'CANNOT save this file.\nPERMISSIONS incorrectly set on server for this file {cave.filename}. Ask a nerd to fix this.'
|
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.
|
It does save the data into into the database directly, not by parsing the file.
|
||||||
'''
|
'''
|
||||||
message = ""
|
|
||||||
if caveslug is not None:
|
try:
|
||||||
try:
|
cave = Cave.objects.get(caveslug__slug = caveslug)
|
||||||
cave = Cave.objects.get(caveslug__slug = caveslug)
|
except:
|
||||||
except:
|
return render(request,'errors/badslug.html', {'badslug': caveslug})
|
||||||
return render(request,'errors/badslug.html', {'badslug': caveslug})
|
|
||||||
else:
|
if slug:
|
||||||
cave = Cave()
|
|
||||||
if slug is not None:
|
|
||||||
entrance = Entrance.objects.get(entranceslug__slug = slug)
|
entrance = Entrance.objects.get(entranceslug__slug = slug)
|
||||||
|
caveAndEntrance = CaveAndEntrance.objects.get(entrance = entrance, cave = cave)
|
||||||
|
entlettereditable = False
|
||||||
else:
|
else:
|
||||||
entrance = Entrance()
|
entrance = Entrance()
|
||||||
|
caveAndEntrance = CaveAndEntrance(cave = cave, entrance = entrance)
|
||||||
|
entlettereditable = True
|
||||||
|
|
||||||
if request.POST:
|
if request.POST:
|
||||||
form = EntranceForm(request.POST, instance = entrance)
|
form = EntranceForm(request.POST, instance = entrance)
|
||||||
|
entletter = EntranceLetterForm(request.POST, instance = caveAndEntrance)
|
||||||
#versionControlForm = VersionControlCommentForm(request.POST)
|
#versionControlForm = VersionControlCommentForm(request.POST)
|
||||||
if slug is None:
|
if form.is_valid() and entletter.is_valid():
|
||||||
entletter = EntranceLetterForm(request.POST)
|
|
||||||
else:
|
|
||||||
entletter = None
|
|
||||||
if form.is_valid() and (slug is not None or entletter.is_valid()):
|
|
||||||
entrance = form.save(commit = False)
|
entrance = form.save(commit = False)
|
||||||
|
entrance_letter = entletter.save(commit = False)
|
||||||
if slug is None:
|
if slug is None:
|
||||||
if entletter.cleaned_data["entrance_letter"]:
|
if entletter.cleaned_data["entrance_letter"]:
|
||||||
slugname = cave.slug() + 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:
|
if slug is None:
|
||||||
es = EntranceSlug(entrance = entrance, slug = slugname, primary = True)
|
es = EntranceSlug(entrance = entrance, slug = slugname, primary = True)
|
||||||
es.save()
|
es.save()
|
||||||
el = entletter.save(commit = False)
|
entrance_file = entrance.file_output()
|
||||||
el.cave = cave
|
cave_file = cave.file_output()
|
||||||
el.entrance = entrance
|
write_and_commit([entrance_file, cave_file], "Online edit of %s%s" % (cave, entletter))
|
||||||
el.save()
|
entrance.save()
|
||||||
try:
|
if slug is None:
|
||||||
entrance.writeDataFile()
|
entrance_letter.save()
|
||||||
# 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})
|
|
||||||
|
|
||||||
return HttpResponseRedirect("/" + cave.url)
|
return HttpResponseRedirect("/" + cave.url)
|
||||||
else:
|
|
||||||
message = f'! POST data is INVALID {cave}'
|
|
||||||
print(message)
|
|
||||||
else:
|
else:
|
||||||
form = EntranceForm(instance = entrance)
|
form = EntranceForm(instance = entrance)
|
||||||
#versionControlForm = VersionControlCommentForm()
|
#versionControlForm = VersionControlCommentForm()
|
||||||
if slug is None:
|
if slug is None:
|
||||||
entletter = EntranceLetterForm(request.POST)
|
entletter = EntranceLetterForm()
|
||||||
else:
|
else:
|
||||||
entletter = None
|
entletter = caveAndEntrance.entrance_letter
|
||||||
|
|
||||||
return render(request,
|
return render(request,
|
||||||
'editentrance.html',
|
'editentrance.html',
|
||||||
{'form': form, 'cave': cave, 'message': message,
|
{'form': form,
|
||||||
|
|
||||||
|
'cave': cave,
|
||||||
#'versionControlForm': versionControlForm,
|
#'versionControlForm': versionControlForm,
|
||||||
'entletter': entletter
|
'entletter': entletter,
|
||||||
|
'entlettereditable': entlettereditable
|
||||||
})
|
})
|
||||||
|
|
||||||
def ent(request, cave_id, ent_letter):
|
def ent(request, cave_id, ent_letter):
|
||||||
|
@ -8,8 +8,12 @@
|
|||||||
<h1>Edit Entrance - at cave {{cave.official_name|safe}} - {{cave.kataster_number}}</h1>
|
<h1>Edit Entrance - at cave {{cave.official_name|safe}} - {{cave.kataster_number}}</h1>
|
||||||
{% include 'html_editor_pop_ups.html' %}
|
{% include 'html_editor_pop_ups.html' %}
|
||||||
<h2>{{message}}</h2>
|
<h2>{{message}}</h2>
|
||||||
<p>{{entletter}}
|
|
||||||
<form action="" method="post">{% csrf_token %}
|
<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>
|
<table>{{ form }}</table>
|
||||||
{{ versionControlForm }}
|
{{ versionControlForm }}
|
||||||
<p><input type="submit" value="Submit" /></p>
|
<p><input type="submit" value="Submit" /></p>
|
||||||
|
Loading…
Reference in New Issue
Block a user