Compare commits
2 Commits
979d3f50b7
...
d0b7922c9b
Author | SHA1 | Date |
---|---|---|
Ceda EI | d0b7922c9b | |
Ceda EI | e6139b4c33 |
48
nova.py
48
nova.py
|
@ -3,14 +3,21 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from collections import UserList
|
from collections import UserList
|
||||||
|
from datetime import datetime
|
||||||
import os
|
import os
|
||||||
import os.path as path
|
import os.path as path
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
|
|
||||||
|
def gen_name(date, slug):
|
||||||
|
"Returns to file name"
|
||||||
|
return date.strftime("%Y-%m-%d-") + slug
|
||||||
|
|
||||||
|
|
||||||
class EpisodeList(UserList):
|
class EpisodeList(UserList):
|
||||||
"Represents list of episodes"
|
"Represents list of episodes"
|
||||||
def __init__(self, data, output, template):
|
def __init__(self, data, output, template):
|
||||||
|
@ -18,11 +25,20 @@ class EpisodeList(UserList):
|
||||||
self.output = output
|
self.output = output
|
||||||
self.template = template
|
self.template = template
|
||||||
|
|
||||||
def sort(self):
|
def sort(self, *_args, **_kwargs):
|
||||||
"Sorts the EpisodeList"
|
"Sorts the EpisodeList"
|
||||||
|
super().sort(key=lambda x: x.date, reverse=True)
|
||||||
|
|
||||||
def generate_thumnails(self):
|
def generate_thumbnails(self):
|
||||||
"Generates thumbnails for all the videos"
|
"Generates thumbnails for all the videos"
|
||||||
|
if not path.isdir(self.output + "assets"):
|
||||||
|
os.mkdir(self.output + "assets")
|
||||||
|
if not path.isdir(self.output + "assets/thumbnails"):
|
||||||
|
os.mkdir(self.output + "assets/thumbnails")
|
||||||
|
for episode in self.data:
|
||||||
|
location = (self.output + "assets/thumbnails/" +
|
||||||
|
gen_name(episode.date, episode.slug) + ".jpg")
|
||||||
|
episode.store_thumbnail(location)
|
||||||
|
|
||||||
def generate_atom(self):
|
def generate_atom(self):
|
||||||
"Generates the Atom feed"
|
"Generates the Atom feed"
|
||||||
|
@ -33,27 +49,32 @@ class EpisodeList(UserList):
|
||||||
|
|
||||||
class Episode:
|
class Episode:
|
||||||
"Represents one episode of podcast"
|
"Represents one episode of podcast"
|
||||||
def __init__(self, date, slug, title, show_notes):
|
def __init__(self, date, slug, title, show_notes, video_src):
|
||||||
self.date = date
|
self.date = date
|
||||||
self.slug = slug
|
self.slug = slug
|
||||||
self.title = title
|
self.title = title
|
||||||
self.show_notes = show_notes
|
self.show_notes = show_notes
|
||||||
|
self.video = video_src
|
||||||
|
|
||||||
def render(self, template, thumbnail_src, video_src):
|
def render(self, template, thumbnail_src):
|
||||||
"Renders the Episode with the given template"
|
"Renders the Episode with the given template"
|
||||||
return template.render(
|
return template.render(
|
||||||
title=self.title,
|
title=self.title,
|
||||||
show_notes=jinja2.Markup(self.show_notes),
|
show_notes=jinja2.Markup(self.show_notes),
|
||||||
thumbnail_src=thumbnail_src,
|
thumbnail_src=thumbnail_src,
|
||||||
video_src=video_src
|
video_src=self.video
|
||||||
)
|
)
|
||||||
|
|
||||||
def store_thumbnail(self, location):
|
def store_thumbnail(self, location):
|
||||||
"Stores the thumbnail for given image at path"
|
"Stores the thumbnail for given image at path"
|
||||||
|
args = ["ffmpeg", "-i", self.video, "-ss", "00:00:01.000", "-vframes",
|
||||||
|
"1", location]
|
||||||
|
subprocess.run(args, check=False)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"Main method"
|
"Main method"
|
||||||
|
root = path.dirname(sys.argv[0])
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("input_dir", help="Input directory")
|
parser.add_argument("input_dir", help="Input directory")
|
||||||
parser.add_argument("output_dir", help="Output directory")
|
parser.add_argument("output_dir", help="Output directory")
|
||||||
|
@ -71,27 +92,28 @@ def main():
|
||||||
os.mkdir(args.output_dir)
|
os.mkdir(args.output_dir)
|
||||||
|
|
||||||
template = jinja2.Environment(
|
template = jinja2.Environment(
|
||||||
loader=jinja2.FileSystemLoader(input_dir),
|
loader=jinja2.FileSystemLoader(root),
|
||||||
autoescape=jinja2.select_autoescape("html")
|
autoescape=jinja2.select_autoescape("html")
|
||||||
).get_template("index.html")
|
).get_template("index.html")
|
||||||
|
|
||||||
podcast = EpisodeList([], output_dir, template)
|
podcast = EpisodeList([], output_dir, template)
|
||||||
|
|
||||||
split = re.compile(r"((?P<date>\d{4}-[01]?\d-[0123]?\d)-(?P<slug>.*))")
|
split = re.compile(r"((?P<date>\d{4}-[01]?\d-[0123]?\d)-(?P<slug>.*).md)")
|
||||||
for file in os.listdir(input_dir + "md"):
|
for file in os.listdir(input_dir + "md"):
|
||||||
match = split.match(file)
|
match = split.match(file)
|
||||||
if not match:
|
if not match:
|
||||||
print(f"Invalid filename: {file}", file=sys.stderr)
|
print(f"Invalid filename: {file}", file=sys.stderr)
|
||||||
continue
|
continue
|
||||||
date = match.group("date")
|
date = datetime.strptime(match.group("date"), "%Y-%M-%d")
|
||||||
slug = match.group("slug")
|
slug = match.group("slug")
|
||||||
with open(file) as f: # pylint: disable=invalid-name
|
with open(input_dir + "md/" + file) as episode:
|
||||||
title = f.readline()
|
title = episode.readline()
|
||||||
show_notes = f.read()
|
show_notes = episode.read()
|
||||||
podcast.append(Episode(date, slug, title, show_notes))
|
video = input_dir + "videos/" + gen_name(date, slug) + ".mp4"
|
||||||
|
podcast.append(Episode(date, slug, title, show_notes, video))
|
||||||
|
|
||||||
podcast.sort()
|
podcast.sort()
|
||||||
podcast.generate_thumnails()
|
podcast.generate_thumbnails()
|
||||||
podcast.generate_atom()
|
podcast.generate_atom()
|
||||||
podcast.generate_site()
|
podcast.generate_site()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
jinja2
|
||||||
|
markdown
|
Loading…
Reference in New Issue