Add a script for saving new books that I've read
authorAlex Chan <alex@alexwlchan.net>
Sun, 2 Feb 2020 19:01:00 +0000 (19:01 +0000)
committerAlex Chan <alex@alexwlchan.net>
Sun, 2 Feb 2020 19:01:00 +0000 (19:01 +0000)
requirements.in
requirements.txt
scripts/add_book.py [new file with mode: 0755]
scripts/render_html.py
src/covers/the-ones-who-walk-away-from-omelas.jpg [new file with mode: 0644]
src/reviews/2020/the-ones-who-walk-away-from-omelas.md [new file with mode: 0644]

index 10faa8d..f2f0f6f 100644 (file)
@@ -1,4 +1,6 @@
 attrs
 attrs
+inquirer
 jinja2
 Markdown
 python-frontmatter
 jinja2
 Markdown
 python-frontmatter
+unidecode
index 92ad0d5..f83a622 100644 (file)
@@ -5,12 +5,17 @@
 #    pip-compile
 #
 attrs==19.3.0
 #    pip-compile
 #
 attrs==19.3.0
+blessings==1.7            # via inquirer
+inquirer==2.6.3
 jinja2==2.11.1
 markdown==3.1.1
 markupsafe==1.1.1         # via jinja2
 jinja2==2.11.1
 markdown==3.1.1
 markupsafe==1.1.1         # via jinja2
+python-editor==1.0.4      # via inquirer
 python-frontmatter==0.5.0
 pyyaml==5.3               # via python-frontmatter
 python-frontmatter==0.5.0
 pyyaml==5.3               # via python-frontmatter
-six==1.14.0               # via python-frontmatter
+readchar==2.0.1           # via inquirer
+six==1.14.0               # via blessings, python-frontmatter
+unidecode==1.1.1
 
 # The following packages are considered to be unsafe in a requirements file:
 # setuptools
 
 # The following packages are considered to be unsafe in a requirements file:
 # setuptools
diff --git a/scripts/add_book.py b/scripts/add_book.py
new file mode 100755 (executable)
index 0000000..df75786
--- /dev/null
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+
+import datetime
+import os
+import re
+import subprocess
+from urllib.request import urlretrieve
+
+import frontmatter
+import inquirer
+from unidecode import unidecode
+
+
+def slugify(u):
+    """Convert Unicode string into blog slug."""
+    # https://leancrew.com/all-this/2014/10/asciifying/
+    u = re.sub(u'[–—/:;,.]', '-', u)  # replace separating punctuation
+    a = unidecode(u).lower()          # best ASCII substitutions, lowercased
+    a = re.sub(r'[^a-z0-9 -]', '', a) # delete any other characters
+    a = a.replace(' ', '-')           # spaces to hyphens
+    a = re.sub(r'-+', '-', a)         # condense repeated hyphens
+    return a
+
+
+def get_book_info():
+    questions = [
+        inquirer.List(
+            "entry_type",
+            message="What type of book is this?",
+            choices=[
+                "one I’ve read",
+                "one I’m currently reading",
+                "one I want to read",
+            ],
+        ),
+        inquirer.Text("title", message="What’s the title of the book?"),
+        inquirer.Text("author", message="Who’s the author?"),
+        inquirer.Text("publication_year", message="When was it published?"),
+        inquirer.Text("cover_image_url", message="What’s the cover URL?"),
+        inquirer.Text("cover_desc", message="What’s the cover?"),
+        inquirer.Text("isbn10", message="Do you know the ISBN-10?"),
+        inquirer.Text("isbn13", message="Do you know the ISBN-13?"),
+    ]
+
+    answers = inquirer.prompt(questions)
+
+    answers["entry_type"] = {
+        "one I’ve read": "reviews",
+        "one I’m currently reading": "currently_reading",
+        "one I want to read": "plans",
+    }[answers["entry_type"]]
+
+    return answers
+
+
+def get_review_info():
+    date_read_question1 = [
+        inquirer.List(
+            "date_read",
+            message="When did you finish reading it?",
+            choices=["today", "yesterday", "another day"]
+        )
+    ]
+
+    date_read = inquirer.prompt(date_read_question1)["date_read"]
+
+    today = datetime.datetime.now()
+
+    if date_read == "today":
+        date_read = today.strftime("%Y-%m-%d")
+    elif date_read == "yesterday":
+        yesterday = today - datetime.timedelta(days=1)
+        date_read = yesterday.strftime("%Y-%m-%d")
+    else:
+        date_read_question2 = [
+            inquirer.Text(
+                "date_read",
+                message="When did you finish reading it?"
+            )
+        ]
+
+        date_read = inquirer.prompt(date_read_question2)["date_read"]
+
+    rating_question = [
+        inquirer.List(
+            "rating",
+            message="When’s your rating?",
+            choices=["★★★★★", "★★★★☆", "★★★☆☆", "★★☆☆☆", "★☆☆☆☆"]
+        )
+    ]
+
+    rating = int(inquirer.prompt(rating_question)["rating"].count("★"))
+
+    return {"date_read": date_read, "rating": rating}
+
+
+
+if __name__ == '__main__':
+    book_info = get_book_info()
+
+    slug = slugify(book_info["title"])
+
+    filename, _ = urlretrieve(book_info["cover_image_url"])
+    extension = os.path.splitext(book_info["cover_image_url"])[-1]
+    cover_name = f"{slug}{extension}"
+    os.rename(filename, f"src/covers/{cover_name}")
+
+    new_entry = {
+        "book": {
+            "title": book_info["title"],
+            "author": book_info["author"],
+            "publication_year": book_info["publication_year"],
+            "cover_image": cover_name,
+        }
+    }
+
+    for key in ("cover_desc", "isbn10", "isbn13"):
+        if book_info[key]:
+            new_entry["book"][key] = book_info[key]
+
+    if book_info["entry_type"] == "reviews":
+        review_info = get_review_info()
+
+        new_entry["review"] = {
+            "date_read": review_info["date_read"],
+            "rating": review_info["rating"]
+        }
+
+        year = review_info["date_read"][:4]
+        out_dir = f"reviews/{year}"
+    else:
+        out_dir = book_info["entry_type"]
+
+    out_path = os.path.join("src", out_dir, f"{slug}.md")
+    os.makedirs(os.path.dirname(out_path), exist_ok=True)
+
+    with open(out_path, "wb") as out_file:
+        frontmatter.dump(frontmatter.Post(content=u"", **new_entry), out_file)
+        out_file.write(b"\n")
+
+    subprocess.check_call(["open", out_path])
index e0edc1e..0eb5e4d 100755 (executable)
@@ -23,7 +23,7 @@ class Book:
     author = attr.ib()
     publication_year = attr.ib()
     cover_image = attr.ib()
     author = attr.ib()
     publication_year = attr.ib()
     cover_image = attr.ib()
-    cover_desc = attr.ib()
+    cover_desc = attr.ib(default="")
 
     isbn_13 = attr.ib(default="")
 
 
     isbn_13 = attr.ib(default="")
 
@@ -85,7 +85,7 @@ def render_date(date_value):
     date_obj = datetime.datetime(
         year=int(date_match.group("year")),
         month=int(date_match.group("month")),
     date_obj = datetime.datetime(
         year=int(date_match.group("year")),
         month=int(date_match.group("month")),
-        day=int(date_match.group("day") or "1")
+        day=int(date_match.group("day") or "1"),
     )
 
     if date_match.group("day"):
     )
 
     if date_match.group("day"):
@@ -127,5 +127,5 @@ if __name__ == "__main__":
     template = env.get_template("list_reviews.html")
     html = template.render(all_reviews=all_reviews)
 
     template = env.get_template("list_reviews.html")
     html = template.render(all_reviews=all_reviews)
 
-    out_path = pathlib.Path("_html") / 'reviews/index.html'
+    out_path = pathlib.Path("_html") / "reviews/index.html"
     out_path.write_text(html)
     out_path.write_text(html)
diff --git a/src/covers/the-ones-who-walk-away-from-omelas.jpg b/src/covers/the-ones-who-walk-away-from-omelas.jpg
new file mode 100644 (file)
index 0000000..48950f1
Binary files /dev/null and b/src/covers/the-ones-who-walk-away-from-omelas.jpg differ
diff --git a/src/reviews/2020/the-ones-who-walk-away-from-omelas.md b/src/reviews/2020/the-ones-who-walk-away-from-omelas.md
new file mode 100644 (file)
index 0000000..c7e6840
--- /dev/null
@@ -0,0 +1,10 @@
+---
+book:
+  author: Ursula K. Le Guin
+  cover_image: the-ones-who-walk-away-from-omelas.jpg
+  publication_year: '1973'
+  title: The Ones Who Walk Away From Omelas
+review:
+  date_read: '2020-02-02'
+  rating: 3
+---
\ No newline at end of file