backblogger/backblogger.py

91 lines
3.3 KiB
Python

# Backblogger.py : Scan directories for images, and scaffold into a blog post.
import os
import json
from datetime import datetime, date
import cv2
def markdown_date(ts):
d = datetime.fromtimestamp(ts)
return f"{d.year}-{d.month}-{d.day}"
IMG_WIDTH = 760
def resize_rename(imgpath, article_number, image_number, destpath=None, target_width=IMG_WIDTH):
new_fn = f"article{str(article_number).zfill(2)}_image{str(image_number).zfill(2)}.{imgpath.split('.')[-1]}"
if destpath is None:
destpath = os.path.join('.', imgpath.replace(os.path.basename(imgpath), ''))
dest_fn = os.path.join(destpath, new_fn)
img = cv2.imread(imgpath)
h, w = img.shape[:2]
print(h, w)
if w <= target_width:
cv2.imwrite(dest_fn, img)
return
ratio = target_width / float(w)
new_h = int(h * ratio)
print(ratio, target_width, new_h)
new_img = cv2.resize(img, (target_width, new_h), interpolation=cv2.INTER_AREA)
cv2.imwrite(dest_fn, new_img)
class BlogScaffold:
def __init__(self, path):
self.path = os.path.abspath(path)
self.data = { "images": [],
"blogfile": None
}
# Check the path for backblog metadata
self.scanned = os.path.exists(os.path.join(self.path, "backblog.json"))
if not self.scanned:
self.scan()
return
with open(os.path.join(self.path, "backblog.json"), "r") as f:
self.data = json.loads(f.read())
def scan(self):
_, _, files = next(os.walk(self.path))
for f in files:
self.data['images'].append({
"path": f,
"date": os.stat(os.path.join(self.path, f)).st_ctime
})
self.scanned = True
self.save()
def save(self):
with open(os.path.join(self.path, "backblog.json"), "w") as f:
f.write(json.dumps(self.data))
def image_times(self):
for i in self.data['images']:
yield datetime.fromtimestamp(i['date'])
def markdown_template(self, article_number):
replace = {
"{{TITLE}}": "Backblog basic template about " + self.path,
"{{SLUG}}": os.path.basename(self.path),
"{{CATEGORY}}": "category",
"{{EARLIESTDATE}}": markdown_date(min([i['date'] for i in self.data['images']])),
"{{TODAY}}": str(date.today()),
"{{ARTICLENUM}}": article_number.zfill(2)
}
txt = None
with open("template.md", "r") as f:
txt = f.read()
img_template = txt.split("%%%")[1]
img_txt = ""
for i, image in enumerate(self.data['images']):
img_fn = resize_rename(image['path'], article_number, i)
this_txt = img_template
this_txt.replace("{{IMG_FN}}", img_fn)
def __repr__(self):
if not self.scanned:
return f"<BlogScaffold path={self.path}, scanned=False>"
return f"<BlogScaffold path={self.path}, blogfile={self.data['blogfile']}, {len(self.data['images'])} image files>"
if __name__ == '__main__':
subdirs = os.listdir('..')
# don't scan program's directory
subdirs.remove(os.path.basename(os.path.abspath('.')))
scaffolds = [BlogScaffold(os.path.join('..', sd)) for sd in subdirs]