From 2e9afc9e92c12b0fe026ec4aa286b812f3c2186c Mon Sep 17 00:00:00 2001 From: gabriel giovanini de souza Date: Tue, 30 Nov 2021 20:49:30 +0100 Subject: Adiciona projeto inicial --- .gitignore | 3 ++ Procfile | 1 + main.py | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 ++ 4 files changed, 94 insertions(+) create mode 100644 .gitignore create mode 100644 Procfile create mode 100644 main.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b22ec92 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +__pycache__/ + diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..60ee589 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: uvicorn main:app --host=0.0.0.0 --port=${PORT} diff --git a/main.py b/main.py new file mode 100644 index 0000000..f86611f --- /dev/null +++ b/main.py @@ -0,0 +1,87 @@ +import re +from functools import reduce +from typing import List, Iterator +from xml.etree.ElementTree import ElementTree, fromstring, tostring, register_namespace + +import httpx +from fastapi import FastAPI +from starlette.responses import Response, PlainTextResponse + +app = FastAPI() + +URL = "https://jovemnerd.com.br/feed-nerdcast/" + +RegexCollection = { + "nerdcast": "NerdCast [0-9]+[a-c]* -", + "empreendedor": "Empreendedor [0-9]+ -", + "mamicas": "Caneca de Mamicas [0-9]+ -", + "english": "Speak English [0-9]+ -", + "nerdcash": "NerdCash [0-9]+ -", + "bunker": "Lá do Bunker [0-9]+ -", +} + +register_namespace("googleplay", "http://www.google.com/schemas/play-podcasts/1.0") +register_namespace("itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd") +register_namespace("atom", "http://www.w3.org/2005/Atom") + + +class XMLResponse(Response): + media_type = "application/xml" + + +def match(title: str, series: List[str]) -> bool: + def _match(s): + return re.match(RegexCollection[s], title) is not None + + return reduce(lambda x, y: x or _match(y), series, False) + + +def filter_xml(xml_str: str, series: List[str]) -> str: + tree = ElementTree(fromstring(xml_str)) + tree_root = tree.getroot() + for channel in tree_root.findall("./channel"): + for item in channel.findall("item"): + title = item.find("title").text + if not match(title, series): + channel.remove(item) + + return tostring(tree_root, encoding='utf8', method='xml') + + +def filter_titles_xml(xml_str) -> Iterator[str]: + tree = ElementTree(fromstring(xml_str)) + tree_root = tree.getroot() + for item in tree_root.findall("./channel/item"): + yield item.find("title").text + + +async def load_and_filter(series: str) -> str: + series = series or 'nerdcast' + series = series.split(',') + async with httpx.AsyncClient() as client: + response = await client.get(URL) + xml_str = response.content + return filter_xml(xml_str, series) + + +async def load_titles() -> Iterator[str]: + async with httpx.AsyncClient() as client: + response = await client.get(URL) + xml_str = response.content + return filter_titles_xml(xml_str) + + +@app.get("/", response_class=XMLResponse) +async def root(q: str = ''): + return await load_and_filter(q) + + +@app.get("/titles", response_class=PlainTextResponse) +async def titles(): + titles = await load_titles() + return "\n".join(titles) + + +@app.get("/series") +async def titles(): + return [i[0] for i in RegexCollection.items()] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..092f079 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +httpx==0.21.1 +fastapi==0.70.0 +uvicorn==0.15.0 -- cgit v1.2.3