From 61f29334d3c14d4d4ea57ad23af5af193cf8e7a4 Mon Sep 17 00:00:00 2001 From: Geir Arne Hjelle Date: Sun, 16 Sep 2018 20:58:11 +0200 Subject: [PATCH 1/5] First simple version of Real Python Feed Reader --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++- reader/__init__.py | 9 +++++++ reader/__main__.py | 22 +++++++++++++++++ reader/feed.py | 38 +++++++++++++++++++++++++++++ reader/viewer.py | 13 ++++++++++ setup.py | 29 ++++++++++++++++++++++ 6 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 reader/__init__.py create mode 100644 reader/__main__.py create mode 100644 reader/feed.py create mode 100644 reader/viewer.py create mode 100644 setup.py diff --git a/README.md b/README.md index b13304c..ea436c3 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ -# reader \ No newline at end of file +# Real Python Feed Reader + +The Real Python Feed Reader is a very simple [web feed](https://en.wikipedia.org/wiki/Web_feed) reader that can download the latest Real Python articles from the [Real Python feed](https://realpython.com/contact/#rss-atom-feed). + +## Installation + +You can install the Real Python Feed Reader from [PyPI](https://pypi.org/project/realpython-reader/): + + pip install realypython-reader + +## How to use + +The Real Python Feed Reader is a command line application. To see a list of the [latest Real Python articles](https://realpython.com/) simply call the program: + + $ realpython + The latest articles from Real Python (https://realpython.com/) + 0 Logging in Python + 1 The Best Python Books + 2 Conditional Statements in Python + 3 Structuring Python Programs + 4 We're Celebrating 1 Million Page Views per Month! + 5 Python Pandas: Tricks & Features You May Not Know + 6 Python Community Interview With Mariatta Wijaya + 7 Primer on Python Decorators + 8 Sets in Python + 9 The Ultimate Guide to Django Redirects + 10 Advanced Git Tips for Python Developers + 11 Python Community Interview With Mike Driscoll + 12 Dictionaries in Python + 13 Socket Programming in Python (Guide) + 14 Python Code Quality: Tools & Best Practices + 15 Documenting Python Code: A Complete Guide + 16 Fast, Flexible, Easy and Intuitive: How to Speed Up Your Pandas Projects + 17 Lists and Tuples in Python + 18 Reading and Writing CSV Files in Python + 19 Generating Random Data in Python (Guide) + +To read one particular article, call the program with the numerical ID of the article as a parameter: + + $ realpython 0 + # Logging in Python + + Logging is a very useful tool in a programmer's toolbox. It can help you + develop a better understanding of the flow of a program and discover scenarios + that you might not even have thought of while developing. + + Logs provide developers with an extra set of eyes that are constantly looking + at the flow that an application is going through. They can store information, + like which user or IP accessed the application. If an error occurs, then they + can provide more insights than a stack trace by telling you what the state of + the program was before it arrived at the line of code where the error + occurred. + +You can also call the Real Python Feed Reader in your own Python code, by importing from the `reader` package: + + >>> from reader import feed + >>> feed.get_titles() + ['Logging in Python', 'The Best Python Books', ...] + diff --git a/reader/__init__.py b/reader/__init__.py new file mode 100644 index 0000000..9750af8 --- /dev/null +++ b/reader/__init__.py @@ -0,0 +1,9 @@ +"""Real Python feed reader + +asdf +""" +# Version of realpython-reader package +__version__ = "0.0.1" + +# URL of Real Python feed +URL = "https://realpython.com/atom.xml" diff --git a/reader/__main__.py b/reader/__main__.py new file mode 100644 index 0000000..8b96e8e --- /dev/null +++ b/reader/__main__.py @@ -0,0 +1,22 @@ +import sys + +from reader import feed +from reader import viewer + + +def main() -> None: + """Read the Real Python article feed""" + # An article ID is given, show article + if len(sys.argv) > 1: + article = feed.get_article(sys.argv[1]) + viewer.show(article) + + # No ID is given, show list of articles + else: + site = feed.get_site() + titles = feed.get_titles() + viewer.show_list(site, titles) + + +if __name__ == "__main__": + main() diff --git a/reader/feed.py b/reader/feed.py new file mode 100644 index 0000000..b975a1c --- /dev/null +++ b/reader/feed.py @@ -0,0 +1,38 @@ +from typing import List +import feedparser +import html2text +import reader + +_CACHED_FEED = feedparser.FeedParserDict() + + +def _feed() -> feedparser.FeedParserDict: + """Cache contents of the feed, so it's only read once""" + if not _CACHED_FEED: + _CACHED_FEED.update(feedparser.parse(reader.URL)) + return _CACHED_FEED + + +def get_site() -> str: + """Get name and link to web site of the feed""" + info = _feed().feed + return f"{info.title} ({info.link})" + + +def get_article(article_id: str) -> str: + """Get article from feed with the given ID""" + articles = _feed().entries + try: + article = articles[int(article_id)] + except (IndexError, ValueError): + raise SystemExit("Error: Unknown article ID") + + html = article.content[0].value + text = html2text.html2text(html) + return f"# {article.title}\n\n{text}" + + +def get_titles() -> List[str]: + """List titles in feed""" + articles = _feed().entries + return [a.title for a in articles] diff --git a/reader/viewer.py b/reader/viewer.py new file mode 100644 index 0000000..2e32543 --- /dev/null +++ b/reader/viewer.py @@ -0,0 +1,13 @@ +from typing import List + + +def show(article: str) -> None: + """Show one article""" + print(article) + + +def show_list(site: str, titles: List[str]) -> None: + """Show list of articles""" + print(f"The latest articles from {site}") + for article_id, title in enumerate(titles): + print(f"{article_id:>3} {title}") diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..531cec4 --- /dev/null +++ b/setup.py @@ -0,0 +1,29 @@ +import pathlib +from setuptools import find_packages, setup + +# The directory containing this file +HERE = pathlib.Path(__file__).parent + + +setup( + name="realpython-reader", + version="0.0.1", + description="Read Real Python Articles", + long_description=(HERE / "README.md").read_text(), + url="https://github.com/realpython/reader", + author="Real Python", + author_email="office@realpython.com", + license="MIT", + classifiers=[ + "License :: OSI Approved :: MIT License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + ], + packages=find_packages(exclude=("tests",)), + install_requires=["feedparser", "html2text"], + entry_points={ + "console_scripts": [ + "realpython=reader.__main__:main", + ] + }, +) From 5ea0686df17ca015753c975582a08d9ad65f7efe Mon Sep 17 00:00:00 2001 From: Geir Arne Hjelle Date: Sun, 16 Sep 2018 21:03:31 +0200 Subject: [PATCH 2/5] Add an example in __init__.py docstring --- reader/__init__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/reader/__init__.py b/reader/__init__.py index 9750af8..80877cc 100644 --- a/reader/__init__.py +++ b/reader/__init__.py @@ -1,6 +1,12 @@ """Real Python feed reader -asdf +Import the `feed` module to work with the Real Python feed: + + >>> from reader import feed + >>> feed.get_titles() + ['Logging in Python', 'The Best Python Books', ...] + +See https://github.com/realpython/reader/ for more information """ # Version of realpython-reader package __version__ = "0.0.1" From d190f04c995c8c4165a49ed1d6236f376efb9774 Mon Sep 17 00:00:00 2001 From: Geir Arne Hjelle Date: Sun, 16 Sep 2018 21:07:55 +0200 Subject: [PATCH 3/5] Articles -> Tutorials to be consistent with web site --- README.md | 8 ++++---- reader/viewer.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ea436c3..d581599 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Real Python Feed Reader -The Real Python Feed Reader is a very simple [web feed](https://en.wikipedia.org/wiki/Web_feed) reader that can download the latest Real Python articles from the [Real Python feed](https://realpython.com/contact/#rss-atom-feed). +The Real Python Feed Reader is a very simple [web feed](https://en.wikipedia.org/wiki/Web_feed) reader that can download the latest Real Python tutorials from the [Real Python feed](https://realpython.com/contact/#rss-atom-feed). ## Installation @@ -10,10 +10,10 @@ You can install the Real Python Feed Reader from [PyPI](https://pypi.org/project ## How to use -The Real Python Feed Reader is a command line application. To see a list of the [latest Real Python articles](https://realpython.com/) simply call the program: +The Real Python Feed Reader is a command line application. To see a list of the [latest Real Python tutorials](https://realpython.com/) simply call the program: $ realpython - The latest articles from Real Python (https://realpython.com/) + The latest tutorials from Real Python (https://realpython.com/) 0 Logging in Python 1 The Best Python Books 2 Conditional Statements in Python @@ -35,7 +35,7 @@ The Real Python Feed Reader is a command line application. To see a list of the 18 Reading and Writing CSV Files in Python 19 Generating Random Data in Python (Guide) -To read one particular article, call the program with the numerical ID of the article as a parameter: +To read one particular tutorial, call the program with the numerical ID of the tutorial as a parameter: $ realpython 0 # Logging in Python diff --git a/reader/viewer.py b/reader/viewer.py index 2e32543..b04db27 100644 --- a/reader/viewer.py +++ b/reader/viewer.py @@ -8,6 +8,6 @@ def show(article: str) -> None: def show_list(site: str, titles: List[str]) -> None: """Show list of articles""" - print(f"The latest articles from {site}") + print(f"The latest tutorials from {site}") for article_id, title in enumerate(titles): print(f"{article_id:>3} {title}") From bcf6ae502e1470fb73f4582cdef1762327c887aa Mon Sep 17 00:00:00 2001 From: Geir Arne Hjelle Date: Sun, 16 Sep 2018 22:17:33 +0200 Subject: [PATCH 4/5] Add content type for long description --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 531cec4..5f5ddb6 100644 --- a/setup.py +++ b/setup.py @@ -10,6 +10,7 @@ version="0.0.1", description="Read Real Python Articles", long_description=(HERE / "README.md").read_text(), + long_description_content_type="text/markdown", url="https://github.com/realpython/reader", author="Real Python", author_email="office@realpython.com", From a856215e63a72c82baa9bb4d913d2f1ae14b0c11 Mon Sep 17 00:00:00 2001 From: Geir Arne Hjelle Date: Sun, 16 Sep 2018 22:17:50 +0200 Subject: [PATCH 5/5] Articles -> Tutorials to be consistent with web site --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5f5ddb6..9db3bec 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name="realpython-reader", version="0.0.1", - description="Read Real Python Articles", + description="Read Real Python Tutorials", long_description=(HERE / "README.md").read_text(), long_description_content_type="text/markdown", url="https://github.com/realpython/reader",