|
1 |
| -"""Handler for bulk subscribing to URLs saved to a Google Sheet.""" |
| 1 | +""" |
| 2 | +Handler for bulk subscribing to URLs saved to a Google Sheet. |
| 3 | +
|
| 4 | +SETUP: |
| 5 | +
|
| 6 | +Step 1: Set Up Google Cloud Project |
| 7 | +- Go to the Google Cloud Console: https://console.cloud.google.com/ |
| 8 | +- Create a new project. |
| 9 | +- Enable the Google Sheets API for the project: https://console.cloud.google.com/apis/dashboard |
| 10 | +- See: https://docs.gspread.org/en/latest/oauth2.html |
| 11 | +
|
| 12 | +Step 2: Create Service Account |
| 13 | +- In the Google Cloud Console, go to IAM & Admin > Service Accounts. |
| 14 | +- Create a new service account. |
| 15 | +- Download the JSON key file for the service account. |
| 16 | +
|
| 17 | +Step 3: Share Google Sheet |
| 18 | +- Open the Google Sheet you want to interact with. |
| 19 | +- Share the sheet with the service account email (found in the JSON key file). |
| 20 | +""" |
| 21 | + |
| 22 | +from enum import Enum |
| 23 | +from pathlib import Path |
| 24 | +from typing import Literal |
| 25 | + |
| 26 | +from gspread.auth import authorize |
| 27 | +from gspread.client import Client |
| 28 | +from gspread.worksheet import Worksheet |
| 29 | +from oauth2client.service_account import ServiceAccountCredentials |
| 30 | +from pydantic import BaseModel |
| 31 | + |
| 32 | +from common.logs import log |
| 33 | + |
| 34 | +GOOGLE_CLOUD_CREDENTIALS_JSON = Path.cwd() / "rss/subscriptions/add/.secrets/google-cloud-service-account.json" |
| 35 | +GOOGLE_CLOUD_SCOPES = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"] |
| 36 | +SHEET_NAME = "RSS Feed Wish List 🔖" |
| 37 | +STATUS_COLUMN_INDEX = 3 |
| 38 | +URL_COLUMN_NAME = "URL to subscribe to" |
| 39 | + |
| 40 | + |
| 41 | +class Status(Enum): |
| 42 | + SUBSCRIBED = "Subscribed" |
| 43 | + ERROR = "Error" |
| 44 | + |
| 45 | + |
| 46 | +class Row(BaseModel): |
| 47 | + index: int |
| 48 | + url: str |
| 49 | + status: Status | Literal[""] |
| 50 | + |
| 51 | + |
| 52 | +# Authenticate and create a client |
| 53 | +def get_authenticated_sheets_client( |
| 54 | + credentials_json: Path = GOOGLE_CLOUD_CREDENTIALS_JSON, |
| 55 | + scopes: list[str] = GOOGLE_CLOUD_SCOPES, |
| 56 | +) -> Client: |
| 57 | + # TODO: get keyfile from 1Password? |
| 58 | + creds = ServiceAccountCredentials.from_json_keyfile_name(credentials_json, scopes) |
| 59 | + client = authorize(creds) |
| 60 | + return client |
| 61 | + |
| 62 | + |
| 63 | +def get_worksheet(client: Client, sheet_name: str = SHEET_NAME) -> Worksheet: |
| 64 | + return client.open(sheet_name).sheet1 |
| 65 | + |
| 66 | + |
| 67 | +def get_rows(sheet: Worksheet) -> list[Row]: |
| 68 | + data = sheet.get_all_records() |
| 69 | + |
| 70 | + return [ |
| 71 | + Row( |
| 72 | + index=i, |
| 73 | + url=str(row[URL_COLUMN_NAME]), |
| 74 | + status=Status(row["Status"]) if row["Status"] else "", |
| 75 | + ) |
| 76 | + for i, row in enumerate(data, start=1) |
| 77 | + ] |
| 78 | + |
| 79 | + |
| 80 | +# TODO: return what happened |
| 81 | +def update_row_status( |
| 82 | + *, |
| 83 | + sheet: Worksheet, |
| 84 | + row: int, |
| 85 | + col: int = STATUS_COLUMN_INDEX, |
| 86 | + status: Status, |
| 87 | +) -> None: |
| 88 | + sheet.update_cell(row, col, status.value) |
| 89 | + |
| 90 | + |
| 91 | +def main() -> None: |
| 92 | + client = get_authenticated_sheets_client() |
| 93 | + sheet = get_worksheet(client) |
| 94 | + rows = get_rows(sheet) |
| 95 | + log.debug(f"🔍 rows: {rows}") |
| 96 | + |
| 97 | + # TODO: Subscribe to URLs |
| 98 | + |
| 99 | + # Update status for the first URL |
| 100 | + # update_row_status(sheet=sheet, row=2, status=Status.SUBSCRIBED) |
| 101 | + |
| 102 | + |
| 103 | +if __name__ == "__main__": |
| 104 | + main() |
2 | 105 |
|
3 |
| -# TODO: get authenticated sheets client |
4 | 106 | # TODO: get URLs from sheet
|
5 | 107 | # TODO: subscribe to URLs
|
6 | 108 | # TODO: update status in sheet
|
|
0 commit comments