From b678e6fa6894c2c8f735dd531b9694bb01cb04b2 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Fri, 22 Dec 2023 15:53:55 +0000 Subject: [PATCH] First attempt, seems to work Closes: #1 --- backup.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 backup.py diff --git a/backup.py b/backup.py new file mode 100644 index 0000000..a5877da --- /dev/null +++ b/backup.py @@ -0,0 +1,79 @@ +"""Backup list of books from Goodreads.""" + +import configparser +import os +from datetime import date + +from playwright.sync_api import Page, Playwright, sync_playwright # type: ignore + +import_url = "https://www.goodreads.com/review/import" +wait_mins = 10 +refresh_backup = False + +today = date.today().isoformat() # current date in ISO format + +config = configparser.ConfigParser() + +config_file_path = os.path.expanduser( + os.path.join(os.getenv("XDG_CONFIG_HOME", "~/.config"), "goodreads", "config") +) +assert os.path.exists(config_file_path) +config.read(os.path.expanduser(config_file_path)) +script_dir = os.path.dirname(os.path.abspath(__file__)) + + +def login(page: Page) -> None: + """Login to Goodreads.""" + page.goto("https://www.goodreads.com/") + page.get_by_role("link", name="Sign In").click() + page.get_by_role("button", name="Sign in with email").click() + page.get_by_label("Email").fill(config.get("login", "email")) + page.get_by_label("Password").fill(config.get("login", "password")) + page.get_by_label("Sign in").click() + + +def navigate_to_import_and_export(page: Page) -> None: + """Navigate to import and export.""" + page.goto("https://www.goodreads.com/") + page.get_by_role("link", name="My Books").click() + page.get_by_role("link", name="Import and export").click() + + +def run(playwright: Playwright) -> None: + """Download export.""" + browser = playwright.chromium.launch(headless=True) + auth_json = os.path.join(script_dir, "auth.json") + context = browser.new_context(storage_state=auth_json) + page = context.new_page() + page.goto(import_url) + + if refresh_backup: + print("backup requested") + page.get_by_role("button", name="Export Library").click() + print(f"waiting for {wait_mins} minutes") + + page.wait_for_timeout(wait_mins * 60 * 1000) + + print("reloading page") + page.reload() + + print("download export") + export_link = page.get_by_role("link", name="Your export from") + print(export_link.text_content()) + with page.expect_download() as download_info: + page.get_by_role("link", name="Your export from").click() + download = download_info.value + backup_dir = config.get("backup", "dir") + + save_to = os.path.join(backup_dir, f"{today}_goodreads_library_export.csv") + download.save_as(save_to) + page.close() + + # --------------------- + context.storage_state(path=auth_json) + context.close() + browser.close() + + +with sync_playwright() as playwright: + run(playwright)