From cb006fa8d850ee67e7c7f7a26baba6ace5fcbf51 Mon Sep 17 00:00:00 2001 From: Francisco Penedo Date: Thu, 26 Oct 2023 00:47:39 +0200 Subject: [PATCH] Test the ttrss API --- ttrss_api.ipynb | 435 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 435 insertions(+) create mode 100644 ttrss_api.ipynb diff --git a/ttrss_api.ipynb b/ttrss_api.ipynb new file mode 100644 index 0000000..912c02c --- /dev/null +++ b/ttrss_api.ipynb @@ -0,0 +1,435 @@ +{ + "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 +}