Metadata-Version: 2.1
Name: reader
Version: 3.12
Summary: A Python feed reader library.
Author: lemon24
License: BSD-3-Clause
Project-URL: Documentation, https://reader.readthedocs.io/
Project-URL: Changes, https://reader.readthedocs.io/en/latest/changelog.html
Project-URL: Source Code, https://github.com/lemon24/reader
Project-URL: Issue tracker, https://github.com/lemon24/reader/issues
Keywords: atom,cdf,feed,rdf,rss,json feed,web feed,podcast,feed reader,feed aggregator
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Internet
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: News/Diary
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: typing-extensions>=4
Requires-Dist: feedparser>=6
Requires-Dist: requests>=2.18
Requires-Dist: werkzeug>2
Requires-Dist: iso8601>=1
Requires-Dist: beautifulsoup4>=4.5
Provides-Extra: search
Provides-Extra: readtime
Provides-Extra: cli
Requires-Dist: click>=7; extra == "cli"
Requires-Dist: PyYAML; extra == "cli"
Provides-Extra: app
Requires-Dist: flask>=0.10; extra == "app"
Requires-Dist: humanize!=4.7.*,>=4; extra == "app"
Requires-Dist: PyYAML; extra == "app"
Provides-Extra: unstable-plugins
Requires-Dist: requests; extra == "unstable-plugins"
Requires-Dist: mutagen; extra == "unstable-plugins"
Requires-Dist: requests; extra == "unstable-plugins"
Requires-Dist: beautifulsoup4; extra == "unstable-plugins"
Requires-Dist: blinker>=1.4; extra == "unstable-plugins"
Requires-Dist: beautifulsoup4; extra == "unstable-plugins"
Requires-Dist: tabulate; extra == "unstable-plugins"
Provides-Extra: tests
Requires-Dist: pytest>=4; extra == "tests"
Requires-Dist: pytest-randomly; extra == "tests"
Requires-Dist: pytest-subtests; extra == "tests"
Requires-Dist: flaky; extra == "tests"
Requires-Dist: coverage; extra == "tests"
Requires-Dist: pytest-cov; extra == "tests"
Requires-Dist: requests-mock; extra == "tests"
Requires-Dist: mechanicalsoup; (implementation_name != "pypy" or python_version <= "3.9") and extra == "tests"
Requires-Dist: requests-wsgi-adapter; extra == "tests"
Requires-Dist: lxml; (implementation_name != "pypy" or python_version <= "3.9") and extra == "tests"
Requires-Dist: html5lib; extra == "tests"
Requires-Dist: numpy; (implementation_name != "pypy" and os_name == "posix") and extra == "tests"
Requires-Dist: mypy; implementation_name != "pypy" and extra == "tests"
Requires-Dist: types-requests; extra == "tests"
Requires-Dist: types-beautifulsoup4; extra == "tests"
Provides-Extra: docs
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinx-rtd-theme>=1.3.0rc1; extra == "docs"
Requires-Dist: click>=7; extra == "docs"
Requires-Dist: sphinx-click; extra == "docs"
Requires-Dist: sphinx-hoverxref; extra == "docs"
Requires-Dist: sphinxcontrib-log-cabinet; extra == "docs"
Requires-Dist: setuptools; extra == "docs"
Provides-Extra: dev
Requires-Dist: reader[app,cli,docs,tests,unstable-plugins]; extra == "dev"
Requires-Dist: tox; extra == "dev"
Requires-Dist: pre-commit; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"

.. begin-intro

**reader** is a Python feed reader library.

It is designed to allow writing feed reader applications
without any business code,
and without depending on a particular framework.

.. end-intro


|build-status-github| |code-coverage| |documentation-status| |pypi-status| |type-checking| |code-style|


.. |build-status-github| image:: https://github.com/lemon24/reader/workflows/build/badge.svg
  :target: https://github.com/lemon24/reader/actions?query=workflow%3Abuild
  :alt: build status (GitHub Actions)

.. |code-coverage| image:: https://codecov.io/gh/lemon24/reader/branch/master/graph/badge.svg?token=lcLZaSFysf
  :target: https://codecov.io/gh/lemon24/reader
  :alt: code coverage

.. |documentation-status| image:: https://readthedocs.org/projects/reader/badge/?version=latest&style=flat
  :target: https://reader.readthedocs.io/en/latest/?badge=latest
  :alt: documentation status

.. |pypi-status| image:: https://img.shields.io/pypi/v/reader.svg
  :target: https://pypi.python.org/pypi/reader
  :alt: PyPI status

.. |type-checking| image:: http://www.mypy-lang.org/static/mypy_badge.svg
  :target: http://mypy-lang.org/
  :alt: checked with mypy

.. |code-style| image:: https://img.shields.io/badge/code%20style-black-000000.svg
  :target: https://github.com/psf/black
  :alt: code style: black


.. begin-features

*reader* allows you to:

* retrieve, store, and manage **Atom**, **RSS**, and **JSON** feeds
* mark articles as read or important
* add arbitrary tags/metadata to feeds and articles
* filter feeds and articles
* full-text search articles
* get statistics on feed and user activity
* write plugins to extend its functionality
* skip all the low level stuff and focus on what makes your feed reader different

...all these with:

* a stable, clearly documented API
* excellent test coverage
* fully typed Python

What *reader* doesn't do:

* provide an UI
* provide a REST API (yet)
* depend on a web framework
* have an opinion of how/where you use it

The following exist, but are optional (and frankly, a bit unpolished):

* a minimal web interface

  * that works even with text-only browsers
  * with automatic tag fixing for podcasts (MP3 enclosures)

* a command-line interface

.. end-features


Documentation: `reader.readthedocs.io`_

.. _reader.readthedocs.io: https://reader.readthedocs.io/


Usage:

.. begin-usage

.. code-block:: bash

    $ pip install reader

.. code-block:: python

    >>> from reader import make_reader
    >>>
    >>> reader = make_reader('db.sqlite')
    >>> reader.add_feed('http://www.hellointernet.fm/podcast?format=rss')
    >>> reader.update_feeds()
    >>>
    >>> entries = list(reader.get_entries())
    >>> [e.title for e in entries]
    ['H.I. #108: Project Cyclops', 'H.I. #107: One Year of Weird', ...]
    >>>
    >>> reader.mark_entry_as_read(entries[0])
    >>>
    >>> [e.title for e in reader.get_entries(read=False)]
    ['H.I. #107: One Year of Weird', 'H.I. #106: Water on Mars', ...]
    >>> [e.title for e in reader.get_entries(read=True)]
    ['H.I. #108: Project Cyclops']
    >>>
    >>> reader.update_search()
    >>>
    >>> for e in reader.search_entries('year', limit=3):
    ...     title = e.metadata.get('.title')
    ...     print(title.value, title.highlights)
    ...
    H.I. #107: One Year of Weird (slice(15, 19, None),)
    H.I. #52: 20,000 Years of Torment (slice(17, 22, None),)
    H.I. #83: The Best Kind of Prison ()

.. end-usage
