"""
This module contains the `Article` class.
"""
from datetime import datetime
[docs]class Article:
"""Article Class
With `Article` object, you can use the following properties and methods:
- article._id
- article.info
- article.responses
- article.is_self_published
- article.content
- article.markdown
- article.json
- article.save_info()
- article.save_content()
- article.save_markdown()
- article.fetch_responses()
Note:
`Article` class is NOT intended to be used directly by importing.
See :obj:`medium_api.medium.Medium.article`.
"""
def __init__(self, article_id, get_resp, fetch_articles, fetch_users, save_info=False):
self.__get_resp = get_resp
self.article_id = str(article_id)
self.__fetch_articles = fetch_articles
self.__fetch_users = fetch_users
self.title = None
self.subtitle = None
self.claps = None
self.author = None
self.url = None
self.published_at = None
self.publication_id = None
self.tags = None
self.topics = None
self.last_modified_at = None
self.reading_time = None
self.word_count = None
self.responses_count = None
self.voters = None
self.lang = None
self.image_url = None
self.is_series = None
self.is_locked = None
self.publication = None
self.__info = None
self.__content = None
self.__markdown = None
self.__response_ids = None
self.__responses = None
if save_info:
self.save_info()
[docs] def save_info(self):
"""Saves the information related to the article
Note:
Only after running ``article.save_info()`` you can use the following
variables:
- ``article.title``
- ``article.subtitle``
- ``article.claps``
- ``article.author``
- ``article.url``
- ``article.published_at``
- ``article.publication_id``
- ``article.tags``
- ``article.topics``
- ``article.last_modified_at``
- ``article.reading_time``
- ``article.word_count``
- ``article.responses_count``
- ``article.voters``
- ``article.lang``
- ``article.is_series``
- ``article.is_locked``
- ``article.image_url``
- ``article.publication``
"""
from medium_api._user import User
from medium_api._publication import Publication
article = self.info
self.title = article.get('title')
self.subtitle = article.get('subtitle')
self.claps = article.get('claps')
self.author = User(user_id=article['author'],
get_resp=self.__get_resp,
fetch_articles=self.__fetch_articles,
fetch_users=self.__fetch_users,
save_info=False) if article.get('author') else None
self.url = article.get('url')
self.published_at = datetime.strptime(article['published_at'], '%Y-%m-%d %H:%M:%S') if article.get('published_at') else None
self.publication_id = article.get('publication_id')
self.tags = article.get('tags')
self.topics = article.get('topics')
self.last_modified_at = datetime.strptime(article['last_modified_at'], '%Y-%m-%d %H:%M:%S') if article.get('last_modified_at') else None
self.reading_time = article.get('reading_time')
self.word_count = article.get('word_count')
self.responses_count = article.get('responses_count')
self.voters = article.get('voters')
self.lang = article.get('lang')
self.is_series = article.get('is_series')
self.is_locked = article.get('is_locked')
self.image_url = article.get('image_url')
if not self.is_self_published:
self.publication = Publication(publication_id=self.publication_id,
get_resp=self.__get_resp,
fetch_articles=self.__fetch_articles,
fetch_users=self.__fetch_users,
save_info=False)
if self.title is None:
print(f"[ERROR]: Could not retrieve article for the given article_id ({self.article_id}). Please check if this article exists.")
print(f"[ERROR]: Link to unknown article: https://medium.com/p/{self.article_id}")
[docs] def save_content(self):
"""Saves the textual content of the article
Can be accessed later using ``article.content``
Returns:
None
"""
self.__content = self.content
[docs] def save_markdown(self):
"""Saves the markdown of the article
Can be accessed later using ``article.markdown``
Returns:
None
"""
self.__markdown = self.markdown
@property
def _id(self):
"""To get the article_id
Returns:
str: Returns article_id of the object.
"""
return self.article_id
@property
def info(self):
"""To get the articles information
Returns:
dict: Returns a dictionary object containing `title, subtitle, claps,
voters, author, publication_id, word_count, etc ...` (excluding `content`)
"""
if self.__info is None:
resp, _ = self.__get_resp(f'/article/{self.article_id}')
self.__info = dict(resp)
return self.__info
@property
def response_ids(self):
"""To get the list of ids of responses (comments) on the article
Returns:
list: Returns a list of `response_ids`.
"""
if self.__response_ids is None:
resp, _ = self.__get_resp(f'/article/{self.article_id}/responses')
self.__response_ids = list(resp['responses'])
return self.__response_ids
@property
def responses(self):
"""To get the list of responses (Article Objects)
Returns:
list[Article]: Returns a list of `Article` Objects.
"""
if self.__responses is None:
self.__responses = [Article(
article_id=response_id,
get_resp=self.__get_resp,
fetch_articles=self.__fetch_articles,
fetch_users=self.__fetch_users,
)
for response_id in self.response_ids]
return self.__responses
[docs] def fetch_responses(self, content=True):
"""To fetch all the responses information and content on an article.
Args:
content (bool, optional): Set it to `True` if you want to fetch the
textual content of the article as well. Otherwise, default is `False`.
Returns:
None: All the fetched information will be access via `user.articles`.
``article.responses[0].content``
``article.responses[1].claps``
"""
self.__fetch_articles(self.responses, content=content)
@property
def is_self_published(self):
"""To check if the article is self-published or not
Returns:
bool: Returns `True` if article is self-published, else `False` if article
is published under a Medium Publication.
"""
article = self.info
if article['publication_id'] != '*Self-Published*':
return False
else:
return True
@property
def content(self):
"""To get the textual content of the article
Returns:
str: A single string containing `kicker, title, subtitle, paragraphs,
image captions, listicles, etc ...` within an article
"""
if self.__content is None:
resp, _ = self.__get_resp(f'/article/{self.article_id}/content')
self.__content = str(resp['content'])
return self.__content
@property
def markdown(self):
"""To get the Markdown of the Medium Article
Returns:
str: A single string containing `kicker, title, subtitle, paragraphs,
images, listicles, etc ...` within an article, in the markdown format
"""
if self.__markdown is None:
resp, _ = self.__get_resp(f'/article/{self.article_id}/markdown')
self.__markdown = str(resp['markdown'])
return self.__markdown
@property
def json(self):
"""To get the articles information in JSON format
Returns:
dict: Returns a JSON object containing article `info`, `content`, and `markdown` if
already fetched. Else, returns an empty object.
"""
ret = {}
if self.__info:
ret.update(self.info)
if self.__content:
ret['content'] = self.content
if self.__markdown:
ret['markdown'] = self.markdown
return ret