2024-01-24 19:19:18 -06:00

155 lines
4.9 KiB
Python

import requests
import argparse
import os
import jinja2
# LIST_URL = "https://bookwyrm.social/list/2458/s/notplants-2023"
# LIST_URL = "https://bookwyrm.social/list/2404/s/2024"
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
# output dirs
OUTPUT_DIR = os.path.join(PROJECT_PATH, 'dist')
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
# input static folder
STATIC_DIR = os.path.join(PROJECT_PATH, 'static')
if not os.path.exists(STATIC_DIR):
os.makedirs(STATIC_DIR)
def build_site(output_dir, relative_template_path, template_vars):
# copy over static files
input_static_dir = os.path.join(STATIC_DIR)
output_static_dir = os.path.join(output_dir, 'static')
if os.path.exists(output_static_dir):
os.system('rm -r {}'.format(output_static_dir))
print('copying static to {}'.format(output_static_dir))
os.system('cp -r {} {}'.format(input_static_dir, output_static_dir))
# render html
template_loader = jinja2.FileSystemLoader(searchpath=PROJECT_PATH)
template_env = jinja2.Environment(loader=template_loader)
page_template = template_env.get_template(relative_template_path)
page_text = page_template.render(template_vars)
output_page_path = os.path.join(output_dir, "bookshelf.html")
with open(output_page_path, 'w') as output_file:
output_file.write(page_text)
def fetch_list_page(list_url, page):
headers = {"accept": "application/ld+json"}
url = list_url + "?page={}".format(page)
result = requests.get(url, headers=headers)
return result.json()
def get_apub_object(object_url):
headers = {"accept": "application/ld+json"}
url = object_url
result = requests.get(url, headers=headers)
return result.json()
def fetch_list(list_url):
more_results = True
page = 1
all_items = []
while more_results:
try:
results = fetch_list_page(list_url=list_url, page=page)
items = results.get("orderedItems")
if items:
all_items += items
next = results.get("next")
if next:
# TODO: alternatively, this could perhaps be re-written more generally
# to use this next field to direct the pagination instead of an increment
page += 1
if not next:
more_results = False
else:
more_results = False
except:
more_results = False
return all_items
def process_list(list_url):
list_items = fetch_list(list_url)
processed_items = []
for index, book in enumerate(list_items):
base_title = book.get("title")
subtitle = book.get("subtitle")
if subtitle:
title = "{}: {}".format(base_title, subtitle)
else:
title = base_title
authors = book.get("authors")
first_author = authors[0]
author = get_apub_object(first_author)
published_date = book.get("publishedDate")
cover_url = book.get("cover").get("url")
if published_date:
published_year = published_date.split("-")[0]
else:
published_year = None
# print
to_print = "{}. {} by {}".format(index, title, author.get("name"))
if published_year:
to_print += " ({})".format(published_year)
print(to_print)
print("cover: {}".format(cover_url))
image_title = book.get("title").replace(" ", "-")
image_title = image_title.replace(":", "")
image_path = "static/{}.jpg".format(image_title)
# return item
item = {
"title": title,
"author": author.get("name"),
"published_year": published_year,
"cover_url": cover_url,
"cover_image_path": image_path
}
processed_items.append(item)
return processed_items
def download_images(processed_items):
for item in processed_items:
image_url = item.get("cover_url")
image_path = item.get("cover_image_path")
if image_url:
print("++ downloading {}".format(image_url))
os.system('wget {} -O "{}"'.format(image_url, image_path))
if __name__ == '__main__':
parser = argparse.ArgumentParser(
prog='bookshelf-generator',
description='generates HTML for a web-page to display a bookshelf using bookwyrm or a csv as input',
epilog='<3')
parser.add_argument('list_url') # bookwyrm list url to use as a source input
parser.add_argument('-t', '--template') # path to jinja file to use as a template for the html
args = parser.parse_args()
print(args.list_url, args.template)
processed_items = process_list(args.list_url)
template_vars = {
"books": processed_items
}
# download_images(processed_items)
build_site(output_dir=OUTPUT_DIR, relative_template_path=args.template, template_vars=template_vars)