Metadata-Version: 2.1
Name: rssreruns
Version: 0.0.12
Summary: Rebroadcast old RSS/Atom feed items to a new feed, in shuffled or chronological order.
Author-email: Hannah Connolly <hannah.d.connolly@gmail.com>
License: MIT License
        
        Copyright (c) 2023 Hannah Connolly
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://github.com/hannahlog/rss-reruns
Project-URL: Bug Tracker, https://github.com/hannahlog/rss-reruns/issues
Project-URL: Changelog, https://github.com/hannahlog/rss-reruns/blob/main/CHANGELOG.md
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: certifi (>=2022.12.7)
Requires-Dist: charset-normalizer (>=3.0.1)
Requires-Dist: idna (>=3.4)
Requires-Dist: lxml (>=4.9.2)
Requires-Dist: python-dateutil (>=2.8.2)
Requires-Dist: requests (>=2.28.2)
Requires-Dist: six (>=1.16.0)
Requires-Dist: urllib3 (>=1.26.14)
Provides-Extra: dev
Requires-Dist: attrs (==22.2.0) ; extra == 'dev'
Requires-Dist: build (==0.10.0) ; extra == 'dev'
Requires-Dist: cachetools (==5.3.0) ; extra == 'dev'
Requires-Dist: certifi (==2022.12.7) ; extra == 'dev'
Requires-Dist: cfgv (==3.3.1) ; extra == 'dev'
Requires-Dist: chardet (==5.1.0) ; extra == 'dev'
Requires-Dist: charset-normalizer (==3.0.1) ; extra == 'dev'
Requires-Dist: click (==8.1.3) ; extra == 'dev'
Requires-Dist: colorama (==0.4.6) ; extra == 'dev'
Requires-Dist: distlib (==0.3.6) ; extra == 'dev'
Requires-Dist: filelock (==3.9.0) ; extra == 'dev'
Requires-Dist: identify (==2.5.15) ; extra == 'dev'
Requires-Dist: idna (==3.4) ; extra == 'dev'
Requires-Dist: iniconfig (==2.0.0) ; extra == 'dev'
Requires-Dist: lxml (==4.9.2) ; extra == 'dev'
Requires-Dist: lxml-stubs (==0.4.0) ; extra == 'dev'
Requires-Dist: mypy (==0.991) ; extra == 'dev'
Requires-Dist: mypy-extensions (==0.4.3) ; extra == 'dev'
Requires-Dist: nodeenv (==1.7.0) ; extra == 'dev'
Requires-Dist: packaging (==23.0) ; extra == 'dev'
Requires-Dist: pip-tools (==6.12.1) ; extra == 'dev'
Requires-Dist: platformdirs (==2.6.2) ; extra == 'dev'
Requires-Dist: pluggy (==1.0.0) ; extra == 'dev'
Requires-Dist: pre-commit (==3.0.0) ; extra == 'dev'
Requires-Dist: pyproject-api (==1.5.0) ; extra == 'dev'
Requires-Dist: pyproject-hooks (==1.0.0) ; extra == 'dev'
Requires-Dist: pytest (==7.2.1) ; extra == 'dev'
Requires-Dist: python-dateutil (==2.8.2) ; extra == 'dev'
Requires-Dist: pyyaml (==6.0) ; extra == 'dev'
Requires-Dist: requests (==2.28.2) ; extra == 'dev'
Requires-Dist: six (==1.16.0) ; extra == 'dev'
Requires-Dist: tox (==4.3.5) ; extra == 'dev'
Requires-Dist: types-python-dateutil (==2.8.19.6) ; extra == 'dev'
Requires-Dist: types-requests (==2.28.11.8) ; extra == 'dev'
Requires-Dist: types-urllib3 (==1.26.25.4) ; extra == 'dev'
Requires-Dist: typing-extensions (==4.4.0) ; extra == 'dev'
Requires-Dist: urllib3 (==1.26.14) ; extra == 'dev'
Requires-Dist: virtualenv (==20.17.1) ; extra == 'dev'
Requires-Dist: wheel (==0.38.4) ; extra == 'dev'

# RSS-Reruns

Rebroadcast old RSS/Atom feed items to a new feed, in shuffled or chronological order.

## Installation and example usage

To install the latest version from PyPi:
```
pip install rssreruns==0.0.11
```
Example usage to create a feed of reruns, from an existing feed's filepath or URL:
```python
from rssreruns.feedmodifier import FeedModifier as FM
# Initialize from file...
fm = FM.from_file("in/some_old_feed.xml")
# ...or from a URL
fm = FM.from_url("example.org/some_old_feed.xml")
# Add prefixes and/or suffixes to the feed's title
fm.set_feed_title(prefix="[RERUNS:]", suffix="(this is a reruns feed)")
# Add prefixes and/or suffixes to entry titles;
# these can include date formatting for the entry's original pubdate
fm.set_entry_titles(prefix="[From %b %d %Y:]")
# Rebroadcast some entries! Their publication dates will be set to the current datetime
fm.rebroadcast(3)
# Write out the resulting feed to file 
fm.write(path="out/my_output_feed.xml")
# ...or as a string (Not Recommended)
big_output_string = fm.write(path=None, pretty_print=False)
```
The FeedModifier's own settings—the prefixes and suffixes, shuffled vs. chronological order, etc.—are stored in the XML itself, under a separate `reruns` namespace (allowed by both the RSS and Atom standards) for easy serialization and deserialization:
```python
fm = FM.from_file(path="out/my_output_feed.xml")
fm.rebroadcast(1)
fm.write(path="out/my_output_feed.xml")
```
(Hosting the generated feed is up to you.)

## About & Motivation

This is a personal project mainly intended for my own use. I've been using a feed reader for a few years, and have gradually come to follow a number of active blogs related to programming, software development, computer science, math, machine learning, and statistics. 

As well as active blogs, however, I've also found blogs and site archives with many old entries of interest to me, but which are no longer (or very rarely) updated: for example, [Matt Might's blog.](https://matt.might.net/articles/)

I wanted a way to have those old blog posts and essays occasionally show up in my feed reader, sprinkled in with actual updates from the active blogs I follow. This way, slowly reading through those old entries is folded into my routine of checking for new articles to read.

As well as changing the publication date to make an old entry appear newly updated, I ultimately wanted more bells and whistles for Quality Of Life reasons, like being able to show the original publication date in the republished entry titles; specifying random vs. chronological order; toggling whether to keep rebroadcasting entries forever, or stop once every entry has been rebroadcasted; etc.

## Disclaimer

`rssreruns` has been made available on PyPi mostly for my own experience with Python's building and packaging ecosystem, as well as for ease of installation on AWS.

Because it's a personal project, a few decisions were made for learning purposes that I would *not* make for professional work. In particular, `FeedModifier` internally makes use of a wrapper class for interacting with lxml elements, a class I wrote as a personal exercise of Reinventing The Wheel (instead of just using lxml's own `objectify`).

In short, this is a fun little project, not made for Production. See `LICENSE.txt` for the more formal disclaimers.
