{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "! pip install --quiet requests" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import requests\n", "import os\n", "import json\n", "from typing import Any" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "class TTRSS:\n", " def __init__(self, url: str) -> None:\n", " self.url = url\n", " self.sid = None\n", "\n", " def _make_request(self, op: str, **kwargs: Any) -> Any:\n", " data = {\"op\": op, **kwargs}\n", " if self.sid is not None:\n", " data[\"sid\"] = self.sid\n", "\n", " r = requests.post(self.url, json=data)\n", " r.raise_for_status()\n", " return r.json()\n", "\n", " def login(self, user: str, password: str) -> None:\n", " body = self._make_request(\"login\", user=user, password=password)\n", " if \"session_id\" in body[\"content\"]:\n", " self.sid = body[\"content\"][\"session_id\"]\n", " else:\n", " raise Exception(f\"Login to TTRSS failed with error {body}\")\n", "\n", " def _assert_logged_in(self) -> None:\n", " if self.sid is None:\n", " raise Exception(\"Must be logged in to use this method\")\n", "\n", " def get_feeds(self, cat_id: int = -3) -> list[dict]:\n", " self._assert_logged_in()\n", " return self._make_request(\"getFeeds\", cat_id=cat_id)\n", "\n", " def subscribe(self, feed_url: str, cat_id: int = 0) -> None:\n", " self._assert_logged_in()\n", " body = self._make_request(\n", " \"subscribeToFeed\", feed_url=feed_url, category_id=cat_id\n", " )\n", " if body[\"status\"][\"code\"] != 1:\n", " raise Exception(f\"Failed to subscribe to {feed_url}: {r.json()['status']}\")" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "url = os.environ[\"TTRSS_URL\"]\n", "user = os.environ[\"TTRSS_USER\"]\n", "password = os.environ[\"TTRSS_PASS\"]" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "ttrss = TTRSS(url)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "ttrss.login(user, password)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'seq': 0,\n", " 'status': 0,\n", " 'content': [{'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=45519316&format=atom',\n", " 'title': 'Back, Black, and Ready to Snack',\n", " 'id': 214,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266675,\n", " 'order_id': 0},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=45526351&format=atom',\n", " 'title': 'Harry Potter and the Tri-Wizard Tournament.',\n", " 'id': 213,\n", " 'unread': 4,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265341,\n", " 'order_id': 0},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=50482837&format=atom',\n", " 'title': 'The Space left behind',\n", " 'id': 209,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265586,\n", " 'order_id': 0},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=50222866&format=atom',\n", " 'title': \"They're Everything\",\n", " 'id': 210,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266928,\n", " 'order_id': 0},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=47634778&format=atom',\n", " 'title': 'When Girls Cry',\n", " 'id': 212,\n", " 'unread': 3,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266195,\n", " 'order_id': 0},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=48949555&format=atom',\n", " 'title': 'Yours, Luna Lovegood',\n", " 'id': 211,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698267044,\n", " 'order_id': 0},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=39262482&format=atom',\n", " 'title': 'A voice in my head calling out to me',\n", " 'id': 195,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265345,\n", " 'order_id': 1},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=37308664&format=atom',\n", " 'title': 'Beast',\n", " 'id': 188,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265344,\n", " 'order_id': 2},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=34018147&format=atom',\n", " 'title': \"Butterflies Bearing Beater's Bats\",\n", " 'id': 187,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265344,\n", " 'order_id': 4},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=33977815&format=atom',\n", " 'title': 'Chainmaker',\n", " 'id': 160,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265342,\n", " 'order_id': 5},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=5058703&format=atom',\n", " 'title': 'Dodging Prison and Stealing Witches - Revenge is Best Served Raw',\n", " 'id': 162,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265343,\n", " 'order_id': 7},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=30079221&format=atom',\n", " 'title': 'Draconian Mishap',\n", " 'id': 176,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265343,\n", " 'order_id': 8},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=20168905&format=atom',\n", " 'title': 'Enduring Pain with Patience',\n", " 'id': 179,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265344,\n", " 'order_id': 9},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=13521369&format=atom',\n", " 'title': 'From Ruin',\n", " 'id': 163,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265463,\n", " 'order_id': 10},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=42297078&format=atom',\n", " 'title': 'Harry Potter & the Looming of Shadows',\n", " 'id': 201,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265465,\n", " 'order_id': 11},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=25428937&format=atom',\n", " 'title': 'Harry Potter and the Rotfang Conspiracy',\n", " 'id': 174,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265464,\n", " 'order_id': 12},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=46771207&format=atom',\n", " 'title': 'heart made of glass',\n", " 'id': 205,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265465,\n", " 'order_id': 13},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=31085291&format=atom',\n", " 'title': 'I would know you anywhere',\n", " 'id': 184,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265464,\n", " 'order_id': 15},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=30475743&format=atom',\n", " 'title': 'Inevitable',\n", " 'id': 169,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265463,\n", " 'order_id': 16},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=45438604&format=atom',\n", " 'title': 'it fell to earth',\n", " 'id': 207,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265585,\n", " 'order_id': 17},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=41518284&format=atom',\n", " 'title': 'Magical Little Raven',\n", " 'id': 193,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265584,\n", " 'order_id': 18},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=11069175&format=atom',\n", " 'title': 'magnetism',\n", " 'id': 203,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698265585,\n", " 'order_id': 19},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=40261533&format=atom',\n", " 'title': 'My Dread Lady',\n", " 'id': 198,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266192,\n", " 'order_id': 21},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=37370971&format=atom',\n", " 'title': 'My Two Dead Girlfriends',\n", " 'id': 202,\n", " 'unread': 1,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266193,\n", " 'order_id': 22},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=39071649&format=atom',\n", " 'title': 'Predators',\n", " 'id': 206,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266194,\n", " 'order_id': 23},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=26717155&format=atom',\n", " 'title': 'Sing me to Sleep',\n", " 'id': 199,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266192,\n", " 'order_id': 24},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=29318289&format=atom',\n", " 'title': 'Stop the Monster',\n", " 'id': 183,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266189,\n", " 'order_id': 25},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=38135458&format=atom',\n", " 'title': 'Tether',\n", " 'id': 192,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266190,\n", " 'order_id': 26},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=41517081&format=atom',\n", " 'title': 'The Delicate Art of Raising Thestrals',\n", " 'id': 190,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266190,\n", " 'order_id': 27},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=42969873&format=atom',\n", " 'title': 'The Fallen',\n", " 'id': 196,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266191,\n", " 'order_id': 28},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=3802057&format=atom',\n", " 'title': 'The Rumor',\n", " 'id': 175,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266070,\n", " 'order_id': 29},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=13263753&format=atom',\n", " 'title': \"The Sting of Summer's Winter\",\n", " 'id': 167,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266069,\n", " 'order_id': 30},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=42029700&format=atom',\n", " 'title': 'The Tides Will Take You Home',\n", " 'id': 197,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266191,\n", " 'order_id': 31},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=34466008&format=atom',\n", " 'title': \"things we aren't\",\n", " 'id': 204,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266193,\n", " 'order_id': 32},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=43314273&format=atom',\n", " 'title': 'Two Unbowed Crows',\n", " 'id': 194,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266191,\n", " 'order_id': 33},\n", " {'feed_url': 'https://nas.franpenedo.com/rss-bridge/?action=display&bridge=AO3Bridge&context=Work&id=29400924&format=atom',\n", " 'title': 'when your gay wizarding crush thinks she is straight',\n", " 'id': 173,\n", " 'unread': 0,\n", " 'has_icon': True,\n", " 'cat_id': 11,\n", " 'last_updated': 1698266070,\n", " 'order_id': 35}]}" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttrss.get_feeds(11)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "python-3.11", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.5" } }, "nbformat": 4, "nbformat_minor": 2 }