cli/ytrssil/fetch.py

65 lines
1.9 KiB
Python
Raw Normal View History

2021-07-30 11:48:32 +02:00
from asyncio import gather, run
from collections.abc import Iterable
from aiohttp import ClientResponse, ClientSession
from inject import autoparams
2021-07-30 11:48:32 +02:00
2021-08-06 00:07:30 +02:00
from ytrssil.config import Configuration
2021-07-30 11:48:32 +02:00
from ytrssil.datatypes import Channel, Video
from ytrssil.protocols import Fetcher, Parser
2021-07-30 11:48:32 +02:00
class FetcherBase:
2021-08-06 00:07:30 +02:00
def fetch_feeds(
self,
urls: Iterable[str],
) -> Iterable[str]: # pragma: no cover
raise NotImplementedError
2021-08-06 00:07:30 +02:00
@autoparams()
def fetch_new_videos(
self,
2021-08-06 00:07:30 +02:00
config: Configuration,
parser: Parser,
) -> tuple[dict[str, Channel], dict[str, Video]]:
2021-08-06 00:07:30 +02:00
feed_urls = config.get_feed_urls()
channels: dict[str, Channel] = {}
new_videos: dict[str, Video] = {}
for feed in self.fetch_feeds(feed_urls):
channel = parser(feed)
channels[channel.channel_id] = channel
new_videos.update(channel.new_videos)
return channels, new_videos
class AioHttpFetcher(FetcherBase):
async def request(
self,
session: ClientSession,
url: str,
) -> ClientResponse:
2021-08-06 00:07:30 +02:00
return await session.get(url=url)
async def async_fetch_feeds(self, urls: Iterable[str]) -> Iterable[str]:
async with ClientSession() as session:
2021-08-06 00:07:30 +02:00
responses: Iterable[ClientResponse] = await gather(*[
self.request(session, url) for url in urls
])
return [
await response.text(encoding='UTF-8')
for response in responses
]
def fetch_feeds(self, urls: Iterable[str]) -> Iterable[str]:
return run(self.async_fetch_feeds(urls))
@autoparams()
def create_fetcher(config: Configuration) -> Fetcher:
fetcher_type = config.fetcher_type
if fetcher_type == 'aiohttp':
return AioHttpFetcher()
else:
raise Exception(f'Unknown feed fetcher type: "{fetcher_type}"')