mirror of
https://codeberg.org/Reuh/feather.git
synced 2025-10-27 10:09:32 +00:00
refactor: add missing type hints
This commit is contained in:
parent
0fd5ec6458
commit
70b930a820
4 changed files with 32 additions and 43 deletions
|
|
@ -12,7 +12,9 @@ from feather.data import Article, ArticleId, Category
|
|||
|
||||
|
||||
class ClientSession(ABC):
|
||||
config: Config
|
||||
@abstractmethod
|
||||
def __init__(self, config: Config):
|
||||
self.config: Config = config
|
||||
|
||||
@abstractmethod
|
||||
def set_read_flag(self, article_ids: list[ArticleId], read: bool = True):
|
||||
|
|
@ -36,21 +38,19 @@ class ClientSession(ABC):
|
|||
pass
|
||||
|
||||
|
||||
label_name = re.compile("user/.*/label/(.*)")
|
||||
label_name_re = re.compile("user/.*/label/(.*)")
|
||||
|
||||
|
||||
class GReaderSession(ClientSession):
|
||||
"""Google Reader API client"""
|
||||
|
||||
greader: google_reader.Client
|
||||
auth_token: str
|
||||
csrf_token: str
|
||||
|
||||
def __init__(self, config: Config):
|
||||
self.config = config
|
||||
self.greader = google_reader.Client(config.server_url)
|
||||
self.auth_token = self.greader.login(config.server_user, config.server_password)
|
||||
self.csrf_token = self.greader.get_token(self.auth_token)
|
||||
self.config: Config = config
|
||||
self.greader: google_reader.Client = google_reader.Client(config.server_url)
|
||||
self.auth_token: str = self.greader.login(
|
||||
config.server_user, config.server_password
|
||||
)
|
||||
self.csrf_token: str = self.greader.get_token(self.auth_token)
|
||||
|
||||
def set_read_flag(self, article_ids: list[ArticleId], read: bool = True):
|
||||
if read:
|
||||
|
|
@ -76,7 +76,7 @@ class GReaderSession(ClientSession):
|
|||
]
|
||||
categories = []
|
||||
for category in tags:
|
||||
category_name = category.label or label_name.search(category.id).group(1)
|
||||
category_name = category.label or label_name_re.search(category.id).group(1)
|
||||
category_id = category.id
|
||||
categories.append(Category(id=category_id, title=category_name))
|
||||
return categories
|
||||
|
|
@ -134,19 +134,16 @@ class GReaderArticle(Article):
|
|||
class TTRSession(ClientSession):
|
||||
"""Tiny Tiny RSS API client"""
|
||||
|
||||
ttrss: TTRClient
|
||||
feeds: dict
|
||||
|
||||
def __init__(self, config: Config):
|
||||
self.config = config
|
||||
self.ttrss = TTRClient(
|
||||
self.config: Config = config
|
||||
self.ttrss: TTRClient = TTRClient(
|
||||
config.server_url,
|
||||
config.server_user,
|
||||
config.server_password,
|
||||
auto_login=True,
|
||||
)
|
||||
self.ttrss.login()
|
||||
self.feeds = {}
|
||||
self.feeds: dict = {}
|
||||
|
||||
def set_read_flag(self, article_ids: list[ArticleId], read: bool = True):
|
||||
if read:
|
||||
|
|
|
|||
|
|
@ -6,14 +6,13 @@ from zoneinfo import ZoneInfo
|
|||
from pathlib import Path
|
||||
from jinja2 import Template
|
||||
|
||||
default_config_path: Path = Path(__file__).parent / "config.default.toml"
|
||||
|
||||
|
||||
class ConfigurationError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
default_config_path = Path(__file__).parent / "config.default.toml"
|
||||
|
||||
|
||||
class Config:
|
||||
def __init__(self):
|
||||
with default_config_path.open("rb") as f:
|
||||
|
|
|
|||
|
|
@ -48,20 +48,17 @@ type CategoryId = int | str
|
|||
|
||||
|
||||
class Category:
|
||||
id: CategoryId # category id
|
||||
title: str # category name
|
||||
parents: list[Category] # list of parent categories
|
||||
order: int = 0 # category display order, starting from 1 (0 if unknown)
|
||||
|
||||
def fromdict(d):
|
||||
def fromdict(d) -> Category:
|
||||
parents = [Category.fromdict(parent) for parent in d["parents"]]
|
||||
return Category(d["id"], d["title"], parents, d["order"])
|
||||
|
||||
def __init__(self, id, title, parents=[], order=0):
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.parents = parents
|
||||
self.order = order
|
||||
self.id: CategoryId = id # category unique id
|
||||
self.title: str = title # category name
|
||||
self.parents: list[Category] = parents # list of parent categories
|
||||
self.order: int = (
|
||||
order # category display order, starting from 1 (0 if unknown)
|
||||
)
|
||||
|
||||
def asdict(self):
|
||||
return {
|
||||
|
|
@ -106,7 +103,7 @@ class Article(ABC):
|
|||
language: str = "" # article language
|
||||
image_url: str = "" # article main image
|
||||
|
||||
def _get_html_path(self):
|
||||
def _get_html_path(self) -> Path:
|
||||
config = self.config
|
||||
|
||||
# Category directory path
|
||||
|
|
@ -205,7 +202,7 @@ class Article(ABC):
|
|||
"""Delete the JSON file associated with this article."""
|
||||
self.json_path.unlink()
|
||||
|
||||
def has_html(self):
|
||||
def has_html(self) -> bool:
|
||||
"""Check if the HTML file associated with the article exists on disk."""
|
||||
if self.html_path is None:
|
||||
return False
|
||||
|
|
@ -257,7 +254,7 @@ class Article(ABC):
|
|||
self.compute_fields() # recompute formatted datetime & paths from the current configuration
|
||||
self.write() # rewrite JSON & HTML
|
||||
|
||||
def was_updated(self, old_article: Article):
|
||||
def was_updated(self, old_article: Article) -> bool:
|
||||
"""Returns true if the article is different from a previous version in a way that would require regeneration"""
|
||||
return old_article._get_template_dict() != self._get_template_dict()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
|
||||
import asyncio
|
||||
import signal
|
||||
from typing import Iterable
|
||||
|
||||
from feather.config import Config
|
||||
from feather.client import GReaderSession, TTRSession, ClientSession, ArticleId
|
||||
from feather.client import GReaderSession, TTRSession, ClientSession, Article, ArticleId
|
||||
from feather.data import FileArticle
|
||||
|
||||
|
||||
class FeatherApp:
|
||||
config: Config
|
||||
|
||||
def __init__(self, config: Config):
|
||||
self.config = config
|
||||
self._client_session = None
|
||||
|
||||
_client_session: ClientSession
|
||||
self.config: Config = config
|
||||
self._client_session: ClientSession = None
|
||||
|
||||
def get_client_session(self) -> ClientSession:
|
||||
"""Connect to the server and return a ClientSession object; return an existing ClientSession if we are already connected"""
|
||||
|
|
@ -32,7 +29,7 @@ class FeatherApp:
|
|||
)
|
||||
return self._client_session
|
||||
|
||||
def iter_articles(self):
|
||||
def iter_articles(self) -> Iterable[Article]:
|
||||
"""Iterate over all the articles in local storage"""
|
||||
config = self.config
|
||||
for json_path in config.json_root.glob("*.json"):
|
||||
|
|
@ -175,9 +172,8 @@ class FeatherApp:
|
|||
|
||||
async def daemon(self):
|
||||
"""Start the synchronization daemon"""
|
||||
config = self.config
|
||||
print(
|
||||
f"Started in daemon mode; changes will be downloaded from the server every {config.daemon_sync_down_every}s and uploaded every {config.daemon_sync_up_every}s"
|
||||
f"Started in daemon mode; changes will be downloaded from the server every {self.config.daemon_sync_down_every}s and uploaded every {self.config.daemon_sync_up_every}s"
|
||||
)
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
tup = tg.create_task(self.daemon_sync_up_loop())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue