konfluks/lumbunglib/video.py

144 lines
4.7 KiB
Python
Raw Normal View History

2021-12-15 10:41:35 +00:00
import ast
import datetime
2021-12-15 10:30:10 +00:00
import json
import os
import shutil
2021-12-15 10:55:51 +00:00
from pathlib import Path
2021-12-15 10:41:35 +00:00
2021-12-15 10:30:10 +00:00
import arrow
2021-12-15 10:41:35 +00:00
import jinja2
import peertube
import requests
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
host = "https://tv.lumbung.space"
configuration = peertube.Configuration(host=host + "/api/v1")
client = peertube.ApiClient(configuration)
2021-12-15 10:30:10 +00:00
2021-12-15 10:41:35 +00:00
# jinja filters & config
2021-12-15 10:30:10 +00:00
def duration(n):
"""
convert '6655' in '1:50:55'
"""
2021-12-15 10:41:35 +00:00
return str(datetime.timedelta(seconds=n))
2021-12-15 10:30:10 +00:00
def linebreaks(text):
if not text:
return text
else:
import re
2021-12-15 10:41:35 +00:00
2021-12-15 10:30:10 +00:00
br = re.compile(r"(\r\n|\r|\n)")
return br.sub(r"<br />\n", text)
2021-12-15 11:23:37 +00:00
def create_post(post_directory, video_metadata, host):
2021-12-15 10:41:35 +00:00
global client # lazy
2021-12-15 11:23:37 +00:00
if not os.path.exists(post_directory):
2021-12-15 10:41:35 +00:00
os.mkdir(post_directory)
preview_image = video_metadata["preview_path"].split("/")[-1]
if not os.path.exists(os.path.join(post_directory, preview_image)):
# download preview image
response = requests.get(host + video_metadata["preview_path"], stream=True)
with open(os.path.join(post_directory, preview_image), "wb") as img_file:
shutil.copyfileobj(response.raw, img_file)
print("Downloaded cover image")
# replace the truncated description with the full video description
# peertube api is some broken thing in between a py dict and a json file
api_response = peertube.VideoApi(client).videos_id_description_get(
video_metadata["uuid"]
)
long_description = ast.literal_eval(api_response)
video_metadata["description"] = long_description["description"]
2021-12-15 11:23:37 +00:00
template_dir = os.path.join(Path(__file__).parent.resolve(), "templates")
env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
env.filters["duration"] = duration
env.filters["linebreaks"] = linebreaks
template = env.get_template("video.md")
2021-12-15 10:41:35 +00:00
with open(os.path.join(post_directory, "index.md"), "w") as f:
post = template.render(v=video_metadata, host=host, preview_image=preview_image)
f.write(post)
with open(os.path.join(post_directory, ".timestamp"), "w") as f:
timestamp = arrow.get(video_metadata["updated_at"])
f.write(timestamp.format("X"))
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
def update_post(post_directory, video_metadata, host):
2021-12-15 10:30:10 +00:00
if os.path.exists(post_directory):
2021-12-15 10:41:35 +00:00
if os.path.exists(os.path.join(post_directory, ".timestamp")):
old_timestamp = open(os.path.join(post_directory, ".timestamp")).read()
2021-12-15 10:30:10 +00:00
2021-12-15 10:41:35 +00:00
# FIXME: this is ugly but I need to do this because arrow removes miliseconds
current_timestamp = arrow.get(video_metadata["updated_at"])
current_timestamp = arrow.get(current_timestamp.format("X"))
2021-12-15 10:30:10 +00:00
if current_timestamp > arrow.get(old_timestamp):
2021-12-15 10:41:35 +00:00
print(
"Updating",
video_metadata["name"],
"({})".format(video_metadata["uuid"]),
)
2021-12-15 11:23:37 +00:00
create_post(post_directory, video_metadata, host)
2021-12-15 10:30:10 +00:00
else:
2021-12-15 10:41:35 +00:00
print(
"Video current: ",
video_metadata["name"],
"({})".format(video_metadata["uuid"]),
)
2021-12-15 10:30:10 +00:00
else:
2021-12-15 10:41:35 +00:00
# compat for when there is no timestamp yet..
2021-12-15 11:23:37 +00:00
create_post(post_directory, video_metadata, host)
2022-02-03 15:09:05 +00:00
def sanitize_name(name):
sanitized = "".join([c if c.isalnum() or c == " " else "-" for c in name])
if len(sanitized) > 40:
return sanitized[:40]
return sanitized
2021-12-15 11:23:37 +00:00
def main():
v = peertube.VideoApi(client)
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
response = v.videos_get(count=100, filter="local", tags_one_of="publish")
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
videos = response.to_dict()
videos = videos["data"]
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
output_dir = os.environ.get("OUTPUT_DIR")
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
if not os.path.exists(output_dir):
os.mkdir(output_dir)
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
existing_posts = os.listdir(output_dir)
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
for video_metadata in videos:
2022-02-07 10:45:00 +00:00
post_name = sanitize_name(video_metadata["name"]) + "-" + video_metadata["uuid"]
post_dir = os.path.join(output_dir, post_name)
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
if (
2022-02-07 10:45:00 +00:00
post_name not in existing_posts
2021-12-15 11:23:37 +00:00
): # if there is a video we dont already have, make it
print(
"New: ", video_metadata["name"], "({})".format(video_metadata["uuid"])
)
create_post(post_dir, video_metadata, host)
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
elif (
2022-02-07 10:45:00 +00:00
post_name in existing_posts
2021-12-15 11:23:37 +00:00
): # if we already have the video do nothing, possibly update
update_post(post_dir, video_metadata, host)
existing_posts.remove(
2022-02-07 10:45:00 +00:00
post_name
2021-12-15 11:23:37 +00:00
) # create list of posts which have not been returned by peertube
2021-12-15 10:30:10 +00:00
2021-12-15 11:23:37 +00:00
for post in existing_posts:
print("deleted", post) # rm posts not returned
shutil.rmtree(os.path.join(output_dir, post))