Skip to content

Commit 64b3ddf

Browse files
authored
Merge pull request #1 from realpython/reader
Simple Feed Reader for Real Python tutorials
2 parents 7834ee2 + a856215 commit 64b3ddf

File tree

6 files changed

+177
-1
lines changed

6 files changed

+177
-1
lines changed

README.md

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,59 @@
1-
# reader
1+
# Real Python Feed Reader
2+
3+
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).
4+
5+
## Installation
6+
7+
You can install the Real Python Feed Reader from [PyPI](https://pypi.org/project/realpython-reader/):
8+
9+
pip install realypython-reader
10+
11+
## How to use
12+
13+
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:
14+
15+
$ realpython
16+
The latest tutorials from Real Python (https://realpython.com/)
17+
0 Logging in Python
18+
1 The Best Python Books
19+
2 Conditional Statements in Python
20+
3 Structuring Python Programs
21+
4 We're Celebrating 1 Million Page Views per Month!
22+
5 Python Pandas: Tricks & Features You May Not Know
23+
6 Python Community Interview With Mariatta Wijaya
24+
7 Primer on Python Decorators
25+
8 Sets in Python
26+
9 The Ultimate Guide to Django Redirects
27+
10 Advanced Git Tips for Python Developers
28+
11 Python Community Interview With Mike Driscoll
29+
12 Dictionaries in Python
30+
13 Socket Programming in Python (Guide)
31+
14 Python Code Quality: Tools & Best Practices
32+
15 Documenting Python Code: A Complete Guide
33+
16 Fast, Flexible, Easy and Intuitive: How to Speed Up Your Pandas Projects
34+
17 Lists and Tuples in Python
35+
18 Reading and Writing CSV Files in Python
36+
19 Generating Random Data in Python (Guide)
37+
38+
To read one particular tutorial, call the program with the numerical ID of the tutorial as a parameter:
39+
40+
$ realpython 0
41+
# Logging in Python
42+
43+
Logging is a very useful tool in a programmer's toolbox. It can help you
44+
develop a better understanding of the flow of a program and discover scenarios
45+
that you might not even have thought of while developing.
46+
47+
Logs provide developers with an extra set of eyes that are constantly looking
48+
at the flow that an application is going through. They can store information,
49+
like which user or IP accessed the application. If an error occurs, then they
50+
can provide more insights than a stack trace by telling you what the state of
51+
the program was before it arrived at the line of code where the error
52+
occurred.
53+
54+
You can also call the Real Python Feed Reader in your own Python code, by importing from the `reader` package:
55+
56+
>>> from reader import feed
57+
>>> feed.get_titles()
58+
['Logging in Python', 'The Best Python Books', ...]
59+

reader/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""Real Python feed reader
2+
3+
Import the `feed` module to work with the Real Python feed:
4+
5+
>>> from reader import feed
6+
>>> feed.get_titles()
7+
['Logging in Python', 'The Best Python Books', ...]
8+
9+
See https://github.com/realpython/reader/ for more information
10+
"""
11+
# Version of realpython-reader package
12+
__version__ = "0.0.1"
13+
14+
# URL of Real Python feed
15+
URL = "https://realpython.com/atom.xml"

reader/__main__.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import sys
2+
3+
from reader import feed
4+
from reader import viewer
5+
6+
7+
def main() -> None:
8+
"""Read the Real Python article feed"""
9+
# An article ID is given, show article
10+
if len(sys.argv) > 1:
11+
article = feed.get_article(sys.argv[1])
12+
viewer.show(article)
13+
14+
# No ID is given, show list of articles
15+
else:
16+
site = feed.get_site()
17+
titles = feed.get_titles()
18+
viewer.show_list(site, titles)
19+
20+
21+
if __name__ == "__main__":
22+
main()

reader/feed.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from typing import List
2+
import feedparser
3+
import html2text
4+
import reader
5+
6+
_CACHED_FEED = feedparser.FeedParserDict()
7+
8+
9+
def _feed() -> feedparser.FeedParserDict:
10+
"""Cache contents of the feed, so it's only read once"""
11+
if not _CACHED_FEED:
12+
_CACHED_FEED.update(feedparser.parse(reader.URL))
13+
return _CACHED_FEED
14+
15+
16+
def get_site() -> str:
17+
"""Get name and link to web site of the feed"""
18+
info = _feed().feed
19+
return f"{info.title} ({info.link})"
20+
21+
22+
def get_article(article_id: str) -> str:
23+
"""Get article from feed with the given ID"""
24+
articles = _feed().entries
25+
try:
26+
article = articles[int(article_id)]
27+
except (IndexError, ValueError):
28+
raise SystemExit("Error: Unknown article ID")
29+
30+
html = article.content[0].value
31+
text = html2text.html2text(html)
32+
return f"# {article.title}\n\n{text}"
33+
34+
35+
def get_titles() -> List[str]:
36+
"""List titles in feed"""
37+
articles = _feed().entries
38+
return [a.title for a in articles]

reader/viewer.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from typing import List
2+
3+
4+
def show(article: str) -> None:
5+
"""Show one article"""
6+
print(article)
7+
8+
9+
def show_list(site: str, titles: List[str]) -> None:
10+
"""Show list of articles"""
11+
print(f"The latest tutorials from {site}")
12+
for article_id, title in enumerate(titles):
13+
print(f"{article_id:>3} {title}")

setup.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import pathlib
2+
from setuptools import find_packages, setup
3+
4+
# The directory containing this file
5+
HERE = pathlib.Path(__file__).parent
6+
7+
8+
setup(
9+
name="realpython-reader",
10+
version="0.0.1",
11+
description="Read Real Python Tutorials",
12+
long_description=(HERE / "README.md").read_text(),
13+
long_description_content_type="text/markdown",
14+
url="https://github.com/realpython/reader",
15+
author="Real Python",
16+
author_email="office@realpython.com",
17+
license="MIT",
18+
classifiers=[
19+
"License :: OSI Approved :: MIT License",
20+
"Programming Language :: Python",
21+
"Programming Language :: Python :: 3",
22+
],
23+
packages=find_packages(exclude=("tests",)),
24+
install_requires=["feedparser", "html2text"],
25+
entry_points={
26+
"console_scripts": [
27+
"realpython=reader.__main__:main",
28+
]
29+
},
30+
)

0 commit comments

Comments
 (0)