tasks rewrite 2
This commit is contained in:
parent
a74778e047
commit
3125ccb462
@ -231,7 +231,8 @@ class TaskCog(commands.Cog):
|
|||||||
title=article.title,
|
title=article.title,
|
||||||
url=article.url,
|
url=article.url,
|
||||||
subscription=sub_id,
|
subscription=sub_id,
|
||||||
blocked=blocked
|
blocked=blocked,
|
||||||
|
channel_id="-_-"
|
||||||
)
|
)
|
||||||
log.debug("successfully tracked %s", article.guid)
|
log.debug("successfully tracked %s", article.guid)
|
||||||
|
|
||||||
|
138
src/feed.py
138
src/feed.py
@ -16,7 +16,7 @@ from sqlalchemy import select, insert, delete, and_
|
|||||||
from sqlalchemy.exc import NoResultFound
|
from sqlalchemy.exc import NoResultFound
|
||||||
from textwrap import shorten
|
from textwrap import shorten
|
||||||
|
|
||||||
from mutators import mutator_map
|
from mutators import registry as mutator_registry
|
||||||
from errors import IllegalFeed
|
from errors import IllegalFeed
|
||||||
from db import DatabaseManager, RssSourceModel, FeedChannelModel
|
from db import DatabaseManager, RssSourceModel, FeedChannelModel
|
||||||
from utils import get_rss_data, get_unparsed_feed
|
from utils import get_rss_data, get_unparsed_feed
|
||||||
@ -26,8 +26,114 @@ log = logging.getLogger(__name__)
|
|||||||
dumps = lambda _dict: json.dumps(_dict, indent=8)
|
dumps = lambda _dict: json.dumps(_dict, indent=8)
|
||||||
|
|
||||||
|
|
||||||
|
from xml.etree.ElementTree import Element, SubElement, tostring
|
||||||
|
from feedparser import parse
|
||||||
|
|
||||||
|
class RSSItem:
|
||||||
|
def __init__(self, title, link, description, pub_date, guid):
|
||||||
|
self.title = title
|
||||||
|
self.link = link
|
||||||
|
self.description = description
|
||||||
|
self.pub_date = pub_date
|
||||||
|
self.guid = guid
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
def create_mutated_copy(self, mutators):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def create_embed(self, sub, feed):
|
||||||
|
|
||||||
|
title = shorten(markdownify(self.title, strip=["img", "a"]), 256)
|
||||||
|
desc = shorten(markdownify(self.description, strip=["img"]), 4096)
|
||||||
|
|
||||||
|
author = ""
|
||||||
|
author_url = ""
|
||||||
|
|
||||||
|
icon_url = ""
|
||||||
|
thumb_url = ""
|
||||||
|
|
||||||
|
# Replace HTML with Markdown, and shorten text.
|
||||||
|
# author = shorten(self.source.name, 256)
|
||||||
|
|
||||||
|
# validate urls
|
||||||
|
# author_url = self.source.url if validators.url(self.source.url) else None
|
||||||
|
# icon_url = self.source.icon_url if validators.url(self.source.icon_url) else None
|
||||||
|
# thumb_url = await self.get_thumbnail_url(session) # validation done inside func
|
||||||
|
|
||||||
|
# Combined length validation
|
||||||
|
# Can't exceed combined 6000 characters, [400 Bad Request] if failed.
|
||||||
|
combined_length = len(title) + len(desc) + (len(author) * 2)
|
||||||
|
cutoff = combined_length - 6000
|
||||||
|
desc = shorten(desc, cutoff) if cutoff > 0 else desc
|
||||||
|
|
||||||
|
embed = Embed(
|
||||||
|
title=title,
|
||||||
|
description=desc,
|
||||||
|
timestamp=self.published,
|
||||||
|
url=self.link if validators.url(self.link) else None,
|
||||||
|
colour=colour
|
||||||
|
)
|
||||||
|
|
||||||
|
# embed.set_thumbnail(url=icon_url)
|
||||||
|
# embed.set_image(url=thumb_url)
|
||||||
|
# embed.set_author(url=author_url, name=author)
|
||||||
|
# embed.set_footer(text=self.author)
|
||||||
|
|
||||||
|
return embed
|
||||||
|
|
||||||
|
|
||||||
|
class RSSFeed:
|
||||||
|
def __init__(self, title, link, description, language='en-gb', pub_date=None, last_build_date=None):
|
||||||
|
self.title = title
|
||||||
|
self.link = link
|
||||||
|
self.description = description
|
||||||
|
self.language = language
|
||||||
|
self.pub_date = pub_date
|
||||||
|
self.last_build_date = last_build_date
|
||||||
|
self.items = []
|
||||||
|
|
||||||
|
def add_item(self, item: RSSItem):
|
||||||
|
if not isinstance(item, RSSItem):
|
||||||
|
raise TypeError("item must be an instance of RSSItem")
|
||||||
|
|
||||||
|
self.items.append(item)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.guid
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_parsed_feed(cls, parsed_feed):
|
||||||
|
title = parsed_feed.feed.get('title', 'No title')
|
||||||
|
link = parsed_feed.feed.get('link', 'No link')
|
||||||
|
description = parsed_feed.feed.get('description', 'No description')
|
||||||
|
language = parsed_feed.feed.get('language', 'en-gb')
|
||||||
|
pub_date = parsed_feed.feed.get('published', None)
|
||||||
|
last_build_date = parsed_feed.feed.get('updated', None)
|
||||||
|
|
||||||
|
feed = cls(title, link, description, language, pub_date, last_build_date)
|
||||||
|
|
||||||
|
for entry in parsed_feed.entries:
|
||||||
|
item_title = entry.get('title', 'No title')
|
||||||
|
item_link = entry.get('link', 'No link')
|
||||||
|
item_description = entry.get('description', 'No description')
|
||||||
|
item_pub_data = entry.get('published_parsed', None)
|
||||||
|
item_guid = entry.get('id', None) or entry.get("guid", None)
|
||||||
|
|
||||||
|
item_published = datetime(*entry.published_parsed[0:-2]) if published_parsed else None
|
||||||
|
|
||||||
|
item = RSSItem(item_title, item_link, item_description, item_published, item_guid)
|
||||||
|
feed.add_item(item)
|
||||||
|
|
||||||
|
feed.items.reverse()
|
||||||
|
|
||||||
|
return feed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Article:
|
class RSSArticle:
|
||||||
"""Represents a news article, or entry from an RSS feed."""
|
"""Represents a news article, or entry from an RSS feed."""
|
||||||
|
|
||||||
guid: str
|
guid: str
|
||||||
@ -68,21 +174,27 @@ class Article:
|
|||||||
source=source
|
source=source
|
||||||
)
|
)
|
||||||
|
|
||||||
def mutate(self, attr: str, mutator: dict):
|
def mutate(self, attr: str, mutator: dict[str, str]):
|
||||||
"""
|
"""
|
||||||
Apply a mutation to a certain text attribute of
|
Apply a mutation to a certain text attribute of
|
||||||
this Article instance.
|
this Article instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.debug("Applying mutator '%s'", mutator["name"])
|
# WARN:
|
||||||
|
# This could be really bad if the end user is able to effect the 'attr' value.
|
||||||
|
# Shouldn't happen though.
|
||||||
|
|
||||||
mutator_value = mutator["value"]
|
log.debug("applying mutator '%s'", mutator["name"])
|
||||||
|
val = mutator["value"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
mutator = mutator_registry.get_mutator(val)
|
||||||
|
except ValueError as err:
|
||||||
|
log.error(err)
|
||||||
|
|
||||||
|
setattr(self, attr, mutator.mutate(getattr(self, attr)))
|
||||||
|
log.debug("mutated %s, to: %s", attr, getattr(self, attr))
|
||||||
|
|
||||||
if mutator_value in mutator_map:
|
|
||||||
setattr(self, attr, mutator_map[mutator_value](getattr(self, attr)))
|
|
||||||
log.debug("mutated %s, to: %s", attr, getattr(self, attr))
|
|
||||||
else:
|
|
||||||
log.warn("Unknown mutator value '%s', skipping", mutator["value"])
|
|
||||||
|
|
||||||
async def get_thumbnail_url(self, session: aiohttp.ClientSession) -> str | None:
|
async def get_thumbnail_url(self, session: aiohttp.ClientSession) -> str | None:
|
||||||
"""Returns the thumbnail URL for an article.
|
"""Returns the thumbnail URL for an article.
|
||||||
@ -165,8 +277,8 @@ class Article:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Source:
|
class RSSFeedSource:
|
||||||
"""Represents an RSS source."""
|
"""Represents an RSS Feed."""
|
||||||
|
|
||||||
name: str | None
|
name: str | None
|
||||||
description: str | None
|
description: str | None
|
||||||
@ -232,7 +344,7 @@ class Source:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RSSFeed:
|
class RSSFeedSource_:
|
||||||
|
|
||||||
uuid: str
|
uuid: str
|
||||||
name: str
|
name: str
|
||||||
|
Loading…
x
Reference in New Issue
Block a user