refactor to put Martins git stuff in utils

This commit is contained in:
Philip Sargent 2022-07-18 17:37:22 +03:00
parent ee9b808461
commit dd00ff69aa
3 changed files with 58 additions and 58 deletions

@ -5,7 +5,7 @@ import re
import resource import resource
import random import random
import logging import logging
from subprocess import call import subprocess
from urllib.parse import urljoin from urllib.parse import urljoin
from decimal import Decimal, getcontext from decimal import Decimal, getcontext
@ -79,13 +79,61 @@ def GetListDir(sdir):
res.append((f, ff, os.path.isdir(ff))) res.append((f, ff, os.path.isdir(ff)))
return res return res
def write_and_commit(files, message):
"""Writes the content to the filepath and adds and commits the file to git. If this fails, a WriteAndCommitError is raised."""
git = settings.GIT
try:
for filepath, content, encoding in files:
cwd = filepath.parent
filename = filepath.name
# GIT see also core/views/uploads.py dwgupload()
# GIT see also core/views/expo.py editexpopage()
if encoding:
mode = "w"
kwargs = {"encoding": encoding}
else:
mode = "wb"
kwargs = {}
try:
with open(filepath, mode, **kwargs) as f:
print(f'WRITING{cwd}---{filename} ')
# as the wsgi process www-data, we have group write-access but are not owner, so cannot chmod.
# os.chmod(filepath, 0o664) # set file permissions to rw-rw-r--
f.write(content)
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_commit = subprocess.run([git, "commit", "-m", message], 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)
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.')
class WriteAndCommitError(Exception):
"""Exception class for errors writing files and comitting them to git"""
def __init__(self, message):
self.message = message
def __str__(self):
return f'WriteAndCommitError: {self.message}'
def writetrogglefile(filepath, filecontent): def writetrogglefile(filepath, filecontent):
'''Set permissions to rw-rw-r-- and commit the new saved file to git '''Commit the new saved file to git
Callers to cave.writeDataFile() or entrance.writeDataFile() should handle the exception PermissionsError explicitly Callers to cave.writeDataFile() or entrance.writeDataFile() should handle the exception PermissionsError explicitly
''' '''
# GIT see also core/views/expo.py editexpopage() # GIT see also core/views/expo.py editexpopage()
# GIT see also core/views/uploads.py dwgupload() # GIT see also core/views/uploads.py dwgupload()
# Called from core/models/caves.py Cave.writeDataFile() Entrance.writeDataFile()
filepath = Path(filepath) filepath = Path(filepath)
cwd = filepath.parent cwd = filepath.parent
filename = filepath.name filename = filepath.name

@ -21,7 +21,7 @@ from troggle.core.models.caves import Cave
import troggle.core.views.caves import troggle.core.views.caves
import troggle.settings as settings import troggle.settings as settings
from troggle.lib import version_control from troggle.core.utils import write_and_commit, WriteAndCommitError
from troggle.core.views.editor_helpers import HTMLarea from troggle.core.views.editor_helpers import HTMLarea
@ -339,8 +339,8 @@ def editexpopage(request, path):
if request.method == 'POST': # If the form has been submitted... if request.method == 'POST': # If the form has been submitted...
pageform = ExpoPageForm(request.POST) # A form bound to the POST data pageform = ExpoPageForm(request.POST) # A form bound to the POST data
if pageform.is_valid():# Form valid therefore write file if pageform.is_valid():# Form valid therefore write file
print("### \n", str(pageform)[0:300]) #print("### \n", str(pageform)[0:300])
print("### \n csrfmiddlewaretoken: ",request.POST['csrfmiddlewaretoken']) #print("### \n csrfmiddlewaretoken: ",request.POST['csrfmiddlewaretoken'])
if filefound: if filefound:
headmatch = re.match(r"(.*)<title>.*</title>(.*)", head, re.DOTALL + re.IGNORECASE) headmatch = re.match(r"(.*)<title>.*</title>(.*)", head, re.DOTALL + re.IGNORECASE)
if headmatch: if headmatch:
@ -358,12 +358,13 @@ def editexpopage(request, path):
body = body.replace("\r", "") body = body.replace("\r", "")
result = "%s<head%s>%s</head>%s<body%s>\n%s</body>%s" % (preheader, headerargs, head, postheader, bodyargs, body, postbody) result = "%s<head%s>%s</head>%s<body%s>\n%s</body>%s" % (preheader, headerargs, head, postheader, bodyargs, body, postbody)
if result != html: # Check if content changed if result != html: # Check if content changed at all
try: try:
change_message = pageform.cleaned_data["change_message"] change_message = pageform.cleaned_data["change_message"]
version_control.write_and_commit([(filepath, result, "utf-8")], f'{change_message} - online edit of {path}') write_and_commit([(filepath, result, "utf-8")], f'{change_message} - online edit of {path}')
except version_control.WriteAndCommitError as e: except WriteAndCommitError as e:
return render(request,'errors/generic.html', {'message': e.message}) return render(request,'errors/generic.html', {'message': e.message})
return HttpResponseRedirect(reverse('expopage', args=[path])) # Redirect after POST return HttpResponseRedirect(reverse('expopage', args=[path])) # Redirect after POST
else: else:
@ -385,4 +386,4 @@ class ExpoPageForm(forms.Form):
html = forms.CharField(widget=HTMLarea(attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}, html = forms.CharField(widget=HTMLarea(attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"},
preview = True preview = True
)) ))
change_message = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":3, 'placeholder': "Descibe the change made (for git)"})) change_message = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":3, 'placeholder': "Describe the change made (for version control records)"}))

@ -1,49 +0,0 @@
import troggle.settings as settings
import subprocess
def write_and_commit(files, message):
"""Writes the content to the filepath and adds and commits the file to git. If this fails, a WriteAndCommitError is raised."""
git = settings.GIT
try:
for filepath, content, encoding in files:
cwd = filepath.parent
filename = filepath.name
# GIT see also core/models/cave.py writetrogglefile()
# GIT see also core/views/uploads.py dwgupload()
if encoding:
mode = "w"
kwargs = {"encoding": encoding}
else:
mode = "wb"
kwargs = {}
try:
with open(filepath, mode, **kwargs) as f:
print(f'WRITING{cwd}---{filename} ')
# as the wsgi process www-data, we have group write-access but are not owner, so cannot chmod.
# os.chmod(filepath, 0o664) # set file permissions to rw-rw-r--
f.write(content)
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_commit = subprocess.run([git, "commit", "-m", message], 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)
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.')
class WriteAndCommitError(Exception):
"""Exception class for errors writing files and comitting them to git"""
def __init__(self, message):
self.message = message
def __str__(self):
return f'WriteAndCommitError: {self.message}'