Skip to content

Instantly share code, notes, and snippets.

@Terrance
Created December 20, 2025 20:46
Show Gist options
  • Select an option

  • Save Terrance/a161a9df6601ddb7176d154d0bebafc2 to your computer and use it in GitHub Desktop.

Select an option

Save Terrance/a161a9df6601ddb7176d154d0bebafc2 to your computer and use it in GitHub Desktop.
Script to show book series reading completion from The StoryGraph.
#!/usr/bin/env python3
from collections.abc import Iterable
import os
from staff import StoryGraph, Book, Series, Status
def check_book(book: Book):
read = book.status == Status.READ
if read:
icon = "\033[92m\N{HEAVY CHECK MARK}"
else:
icon = "\033[91m\N{HEAVY BALLOT X}"
pos = ""
if book.series_position:
pos = f"#{book.series_position} "
print(f"{icon} {pos}{book.title}\033[0m")
return read
def check_books(books: Iterable[Book]):
total = read = 0
for book in books:
total += 1
if check_book(book):
read += 1
return (total, read)
def check_series(series: Series):
print(f"\033[1m{series.name}\033[0m")
total, read = check_books(series.major_books())
if total == 0:
total, read = check_books(series.other_books())
print(f"{read} of {total} read.")
print()
def main():
with StoryGraph(os.path.expanduser("~/.local/state/storygraph.json")) as sg:
done = set[str]()
print()
try:
for read in sg.read_books():
if not read.series_id or read.series_id in done:
continue
done.add(read.series_id)
check_series(read.series)
except KeyboardInterrupt:
return
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment