diff --git a/.gitignore b/.gitignore
index 485dee6..c26f7aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
.idea
+static
+dist
diff --git a/bookshelf.html b/bookshelf.html
new file mode 100644
index 0000000..6b71d43
--- /dev/null
+++ b/bookshelf.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+{% for book in books %}
+
+
+
+
+
+
+ {{ book.title }} by {{ book.author }} {% if book.published_year %} ({{book.published_year}}) {% endif %}
+
+
+
+{% endfor %}
+
+
+
+
\ No newline at end of file
diff --git a/main.py b/main.py
index 4805761..0ee17b4 100644
--- a/main.py
+++ b/main.py
@@ -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)
+
+
+
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..a6c7ee6
--- /dev/null
+++ b/run.sh
@@ -0,0 +1 @@
+python3 main.py "https://bookwyrm.social/list/2458/s/notplants-2023" --template="bookshelf.html"
\ No newline at end of file