Source code for moddb.pages.article

import logging

import bs4

from ..boxes import PartialTag, Profile, Thumbnail
from ..enums import ArticleCategory, Difficulty, ThumbnailType, TutorialCategory
from ..utils import LOGGER, concat_docs, get_date, get_views, join
from .base import BaseMetaClass


[docs] @concat_docs class Article(BaseMetaClass): """This object represents an news article, a tutorial or a feature. Parameters ----------- html : bs4.BeautifulSoup The html to parse. Allows for finer control. Filtering ---------- category : :class:`.ArticleCategory` Type of the article (news, feature) timeframe : :class:`.TimeFrame` The time period this was released in (last 24hr, last week, last month) game : Union[:class:`.Game`, :class:`.Object`] An game object or an object with an id attribute which represents the game the article belongs to. Sorting -------- * **ranktoday** - order by daily ranking, asc is highest ranked, desc is lowest rank * **visitstotal** - order by most views, asc is highest views, desc is lowest views * **dateup** - order by article date, asc is most recent first, desc is oldest first * **name** - order alphabetically, asc is a-z, desc is z-a * **member** - order by member??? * **date** - order by upload date, asc is most recent first, desc is oldest first Exclusive to tutorials * **meta** - sort by difficulty, asc is most difficult, desc is least difficult * **subtype** - sort by the area the tutorial covers Attributes ----------- category : ArticleCategory Whether this article is a news article, a tutorial or a feature name : str The name of the article profile : Profile The profile object of the moddb model the article is for (engine, game, mod...). Can be none if it is not rattached to anything, such as for site news. tags : List[PartialTag] A list of partial tags. You can use `get_tags` and then use the name id to get the right one. views : int Total amount of times this article was viewed today : int amount of time the article has been viewed today intro : int The intro/teaser paragraph of the article author : Thumbnail A member type thumbnail of the member who published the article date : datetime.datetime The date the article was published html : str The html of the article plaintext : str The article text without any html summary : str plaintext intro to the article tutorial_category : TutorialCategory If the article category is tutorial, this represents the area the tutorial covers, else it is None difficulty : Difficulty If the article category is tutorial, this represents how hard the tutorial is. """ def __init__(self, html: bs4.BeautifulSoup): try: self.name = html.find("span", itemprop="headline").string except AttributeError: self.name = html.find("span", itemprop="heading").string super().__init__(html) raw_type = html.find("h5", string="Browse").parent.span.a.string self.category = ArticleCategory[raw_type.lower()] try: raw = html.find("span", string=raw_type[0:-1]).parent.parent.parent.find( "div", class_="table tablemenu" ) except AttributeError: raw = html.find("span", string=raw_type).parent.parent.parent.find( "div", class_="table tablemenu" ) try: self.profile = Profile(html) except AttributeError: LOGGER.info("'%s' has no profile", self.name, exc_info=LOGGER.level >= logging.DEBUG) self.profile = None try: raw_tags = html.find("form", attrs={"name": "tagsform"}).find_all("a") self.tags = [ PartialTag(x.string, join(x["href"]), x["href"].split("/")[-1]) for x in raw_tags if x.string is not None ] except AttributeError: self.tags = [] LOGGER.info( "'%s' '%s' has no tags", self.__class__.__name__, self.name, exc_info=LOGGER.level >= logging.DEBUG, ) views_raw = raw.find("h5", string="Views").parent.span.a.string self.views, self.today = get_views(views_raw) self.intro = html.find("p", itemprop="description").string author = html.find("span", itemprop="author").span.a self.author = Thumbnail(name=author.string, url=author["href"], type=ThumbnailType.member) self.date = get_date(html.find("time", itemprop="datePublished")["datetime"]) self.html = str(html.find("div", itemprop="articleBody")) self.plaintext = html.find("div", itemprop="articleBody").text self.summary = html.find("p", class_="introductiontext").string if self.category == ArticleCategory.tutorials: cat = html.find("span", itemprop="proficiencyLevel").nextSibling.strip() self.tutorial_category = TutorialCategory[ cat.replace("/", "_").replace(" ", "_").lower() ] self.difficulty = Difficulty[ html.find("span", itemprop="proficiencyLevel").string.lower() ] def __repr__(self): return f"<Article title={self.name} type={self.category.name}>"
[docs] @concat_docs class Blog(BaseMetaClass): """Object used to represent a member blog. Filtering ---------- timeframe : :class:`.TimeFrame` The time period this was released in (last 24hr, last week, last month) Sorting -------- * **ranktoday** - order by daily ranking, asc is highest ranked, desc is lowest rank * **visitstotal** - order by most views, asc is highest views, desc is lowest views * **dateup** - order by blog date, asc is most recent first, desc is oldest first * **name** - order alphabetically, asc is a-z, desc is z-a * **member** - order by member??? * **date** - order by upload date, asc is most recent first, desc is oldest first Attributes ----------- name_id : str The name_id of the member, cannot be changed, it's a mix of the original username lowercased with spaces removed and shortened. """ def __init__(self, *, heading, text): author = heading.find("span", class_="subheading").a self.author = Thumbnail(url=author["href"], name=author.string, type=ThumbnailType.member) self.date = get_date(heading.find("span", class_="date").time["datetime"]) title = heading.div.h4.a self.name = title.string self.url = join(title["href"]) self.name_id = self.url.split("/")[0] self.html = str(text.content) self.plaintext = text.text def __repr__(self): return f"<Blog title={self.name}>"