first bookshelf

This commit is contained in:
notplants 2024-01-24 19:19:18 -06:00
parent 483c2bef68
commit 6a4aa3643e
4 changed files with 184 additions and 7 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
.idea
static
dist

37
bookshelf.html Normal file
View File

@ -0,0 +1,37 @@
<html>
<head>
<style>
.cover-image {
width: 200px;
}
.book-item {
margin-bottom: 100px;
}
.main {
max-width: 600px;
margin: auto;
}
</style>
</head>
<body>
<div>
bookshelf
</div>
<div class="main">
{% for book in books %}
<div class="book-item">
<div>
<img src="{{book.cover_image_path}}" class="cover-image"/>
</div>
<div>
{{ book.title }} by {{ book.author }} {% if book.published_year %} ({{book.published_year}}) {% endif %}
</div>
</div>
{% endfor %}
</div>
</body>
</html>

151
main.py
View File

@ -1,17 +1,154 @@
import requests
import argparse
import os
import jinja2
def fetch_list(list_url, page):
# 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
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__':
list_url = "https://wyrms.de/user/j12i/books/reading"
list = fetch_list(list_url, page=1)
list_dict = list.json()
for key, val in list_dict.items():
print("{}: {}".format(key, val))
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)

1
run.sh Executable file
View File

@ -0,0 +1 @@
python3 main.py "https://bookwyrm.social/list/2458/s/notplants-2023" --template="bookshelf.html"