first bookshelf
This commit is contained in:
parent
483c2bef68
commit
6a4aa3643e
|
@ -1 +1,3 @@
|
||||||
.idea
|
.idea
|
||||||
|
static
|
||||||
|
dist
|
||||||
|
|
|
@ -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
151
main.py
|
@ -1,17 +1,154 @@
|
||||||
import requests
|
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"}
|
headers = {"accept": "application/ld+json"}
|
||||||
url = list_url + "?page={}".format(page)
|
url = list_url + "?page={}".format(page)
|
||||||
result = requests.get(url, headers=headers)
|
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__':
|
if __name__ == '__main__':
|
||||||
list_url = "https://wyrms.de/user/j12i/books/reading"
|
parser = argparse.ArgumentParser(
|
||||||
list = fetch_list(list_url, page=1)
|
prog='bookshelf-generator',
|
||||||
list_dict = list.json()
|
description='generates HTML for a web-page to display a bookshelf using bookwyrm or a csv as input',
|
||||||
for key, val in list_dict.items():
|
epilog='<3')
|
||||||
print("{}: {}".format(key, val))
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue