Publish snippets and Markdown posts through authenticated uploads
This commit is contained in:
@@ -10,6 +10,7 @@ import sys
|
||||
import time
|
||||
|
||||
from app import atomic_json
|
||||
from posts import publish_post
|
||||
|
||||
log = logging.getLogger("publisher")
|
||||
|
||||
@@ -48,6 +49,7 @@ class Publisher:
|
||||
for job in jobs:
|
||||
self.state(job, "publishing")
|
||||
try:
|
||||
outcomes = {}
|
||||
if not (self.repo / ".git").is_dir():
|
||||
self.git("clone", "--branch", self.branch, "--single-branch", "--",
|
||||
self.remote, str(self.repo), directory=self.work)
|
||||
@@ -56,9 +58,31 @@ class Publisher:
|
||||
self.git("reset", "--hard", f"origin/{self.branch}")
|
||||
self.git("config", "user.name", os.environ.get("PHOTO_GIT_NAME", "Photo publisher"))
|
||||
self.git("config", "user.email", os.environ.get("PHOTO_GIT_EMAIL", "photos@theread.me"))
|
||||
# Prepending oldest first leaves the newest snippet at the top.
|
||||
jobs.sort(key=lambda job: (json.loads((self.data / "submissions" / job / "manifest.json").read_text())["date"], job))
|
||||
for job in jobs:
|
||||
submission = self.data / "submissions" / job
|
||||
manifest = json.loads((submission / "manifest.json").read_text())
|
||||
if manifest.get("kind") == "post":
|
||||
entry, url, action, identity = publish_post(self.repo, submission, manifest)
|
||||
self.git("add", "--", str(entry))
|
||||
outcomes[job] = dict(url=url, action=action, post_id=identity)
|
||||
continue
|
||||
if manifest.get("kind") == "snippet":
|
||||
entry = self.repo / "snippets.md"
|
||||
existing = entry.read_text()
|
||||
marker = "<!-- uploaded-snippets -->"
|
||||
if marker not in existing:
|
||||
raise OSError("snippets.md is missing its upload insertion marker")
|
||||
if f'<div id="snippet-{job}"></div>' not in existing:
|
||||
entry.write_text(existing.replace(marker, marker + "\n\n" +
|
||||
(submission / "entry.md").read_text(), 1))
|
||||
images = Path("img/snippets/uploads") / job
|
||||
if manifest["count"]:
|
||||
shutil.copytree(submission / "images", self.repo / images, dirs_exist_ok=True)
|
||||
self.git("add", "--", str(images))
|
||||
self.git("add", "--", "snippets.md")
|
||||
continue
|
||||
entry = Path("_art") / f"{manifest['date'][:10]}-photo-{job}.md"
|
||||
images = Path("img/arts/uploads") / job
|
||||
(self.repo / entry).parent.mkdir(parents=True, exist_ok=True)
|
||||
@@ -66,18 +90,30 @@ class Publisher:
|
||||
shutil.copytree(submission / "images", self.repo / images, dirs_exist_ok=True)
|
||||
self.git("add", "--", str(entry), str(images))
|
||||
if self.git("diff", "--cached", "--name-only"):
|
||||
self.git("commit", "-m", f"Publish {len(jobs)} photo submission(s)")
|
||||
self.git("commit", "-m", f"Publish {len(jobs)} submission(s)")
|
||||
self.git("push", "origin", f"HEAD:refs/heads/{self.branch}")
|
||||
commit = self.git("rev-parse", "HEAD")
|
||||
for job in jobs:
|
||||
self.state(job, "pushed", commit=commit)
|
||||
self.state(job, "pushed", commit=commit, **outcomes.get(job, {}))
|
||||
# A subsequent revision replaces the old one in the rendered site.
|
||||
for job, outcome in outcomes.items():
|
||||
job_date = json.loads((self.data / "submissions" / job / "manifest.json").read_text())["date"]
|
||||
for status_path in (self.data / "status").glob("*.json"):
|
||||
previous = json.loads(status_path.read_text())
|
||||
if status_path.stem == job or previous.get("post_id") != outcome["post_id"]:
|
||||
continue
|
||||
old_manifest = self.data / "submissions" / status_path.stem / "manifest.json"
|
||||
if old_manifest.exists() and json.loads(old_manifest.read_text())["date"] < job_date:
|
||||
previous.update(status="superseded", replaced_by=job)
|
||||
atomic_json(status_path, previous)
|
||||
log.info("Pushed %s submission(s) at %s", len(jobs), commit)
|
||||
except (OSError, subprocess.SubprocessError) as error:
|
||||
except (OSError, ValueError, subprocess.SubprocessError) as error:
|
||||
log.error("Git publication failed: %s", error)
|
||||
if isinstance(error, subprocess.CalledProcessError):
|
||||
log.error("%s", error.stderr)
|
||||
for job in jobs:
|
||||
self.state(job, "failed", error="Git push failed; check publisher logs and retry.")
|
||||
self.state(job, "failed", error=str(error) if isinstance(error, ValueError) else
|
||||
"Git push failed; check publisher logs and retry.")
|
||||
raise
|
||||
|
||||
def run(self, once=False):
|
||||
@@ -86,7 +122,7 @@ class Publisher:
|
||||
while True:
|
||||
try:
|
||||
self.publish()
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
except (OSError, ValueError, subprocess.SubprocessError):
|
||||
if once:
|
||||
raise
|
||||
if once:
|
||||
|
||||
Reference in New Issue
Block a user