diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/forms.py | 12 | ||||
-rw-r--r-- | core/models/caves.py | 27 | ||||
-rw-r--r-- | core/utils.py | 23 | ||||
-rw-r--r-- | core/views/caves.py | 70 |
4 files changed, 82 insertions, 50 deletions
diff --git a/core/forms.py b/core/forms.py index f3df10a..a277806 100644 --- a/core/forms.py +++ b/core/forms.py @@ -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) diff --git a/core/models/caves.py b/core/models/caves.py index d6650c0..e1783c6 100644 --- a/core/models/caves.py +++ b/core/models/caves.py @@ -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) diff --git a/core/utils.py b/core/utils.py index 9aa4679..5da6303 100644 --- a/core/utils.py +++ b/core/utils.py @@ -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.') diff --git a/core/views/caves.py b/core/views/caves.py index c98d28e..26ac87f 100644 --- a/core/views/caves.py +++ b/core/views/caves.py @@ -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): |