diff --git a/.env.sample b/.env.sample deleted file mode 100644 index bfd8665..0000000 --- a/.env.sample +++ /dev/null @@ -1,3 +0,0 @@ -SINGLERSS_FEED_OUT_PATH= -SINGLERSS_FEED_LIST_PATH= -SINGLERSS_FEED_OUT_TYPE= diff --git a/README.md b/README.md index d1438fd..fe7bea8 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,41 @@ -singlerss -========= +# RSSingle -# Description +Generates an RSS file from the list of other feeds (RSS/Atom/JSON). Very handy when you want to centralise the list of your feeds in one place and all your devices feed from the same place. -singlerss combines all feeds described in a OPML file into one feed. This can -either be outputted into `stdout` or a file, as specifed by program arguments, -and configured by the environment variables. +## Run -# Configuration +1. Download the binary. -SingleRSS is configured by environment variables. +``` shell +wget +``` -See `.env.sample`. You _must_ copy `.env.sample` to `.env`. +2. Gives execution permissions. -`SINGLERSS_FEED_OUT_PATH` defines the relative OR absolute path to output the -feed to, _IF_ `SINGLERSS_FEED_OUT_TYPE` is set to `file`. If -`SINGLERSS_FEED_OUT_TYPE` is set to `stdout`, you must redirect output to the -file you want it written to. +``` shell +chmod +x rssingle +``` -`SINGLERSS_FEED_LIST_PATH` must be set to the input list of feeds you want to be -collated into one feed. This _must_ be a newline delimited file of URLs. +3. In the same directory as the binary, you can create a local `config.yml` file in this format: -## Running +``` yaml +title: My RSS Feed +description: My customised RSS feed with technology news +feeds: + - https://programadorwebvalencia.com/feed/ + - https://republicaweb.es/feed/ +``` -You may run this directly, after sourcing `.env` and exporting the variables, -with `./singlerss.py`. Alternatively, I have provided a systemd unit and timer, -which I will offer support for, and a basic crontab. I do not use cron, so I -cannot offer support for it. +If not, you can download the example in the repository. -# Licensing +4. Run the binary. -This program is [licensed][license] under the Apache License 2.0. +``` shell +./rssingle +``` -Copyright (c) Dom Rodriguez (shymega) 2020. +A file called `rss.xml` will be created. -[license]: /LICENSE +## Thanks + +@shymega for his original project [singlerss](https://github.com/shymega/singlerss). \ No newline at end of file diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..3d1af89 --- /dev/null +++ b/config.yml @@ -0,0 +1,7 @@ +title: My RSS Feed +description: My customised RSS feed with technology news +url: https://www.example.com +output: rss.xml +feeds: + - https://programadorwebvalencia.com/feed/ + - https://republicaweb.es/feed/ \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 70e58be..259e088 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ feedgen==0.9.0 -feedparser==5.2.1 -lxml==4.6.5 -python-dateutil==2.8.1 -six==1.15.0 +feedparser==6.0.10 +listparser==0.19.0 +lxml==4.9.0 +python-dateutil==2.8.2 +pyyaml==6.0 +pyinstaller==5.1 \ No newline at end of file diff --git a/rss.xml b/rss.xml new file mode 100644 index 0000000..1a5d170 --- /dev/null +++ b/rss.xml @@ -0,0 +1,2 @@ + +My RSS Feedhttps://www.example.com/index.xmlMy customised RSS feed with technology newshttp://www.rssboard.org/rss-specificationRSSingle/v1.0.0enSun, 19 Jun 2022 16:09:40 +0000 \ No newline at end of file diff --git a/singlerss.py b/rssingle.py similarity index 78% rename from singlerss.py rename to rssingle.py index dca252f..fdd2c90 100755 --- a/singlerss.py +++ b/rssingle.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # Copyright (c) Dom Rodriguez 2020 +# Copyright (c) Andros Fenollosa 2022 # Licensed under the Apache License 2.0 import os @@ -11,18 +12,23 @@ import listparser from os import environ from feedgen.feed import FeedGenerator import json +import yaml + + +# Varaibles log = None +CONFIG_PATH = "config.yml" LOG_LEVEL = environ.get("SR_LOG_LEVEl", "ERROR") fg = None FEED_OUT_PATH = None -FEED_OUT_TYPE = None FEED_LIST_PATH = None FEEDS = [] CFG = None + def setup_logging() -> None: """ This function intiialises the logger framework. @@ -38,6 +44,11 @@ def setup_logging() -> None: return None +def get_url_from_feed(config): + """ + This function returns the URL from a feed. + """ + return config["url"] + "/" + config["output"] def init_feed() -> None: """ @@ -51,11 +62,11 @@ def init_feed() -> None: try: fg = FeedGenerator() # Setup [root] feed attributes - fg.id("https://rss.shymega.org.uk/feed.xml") - fg.title("SingleRSS - Combined Feed") - fg.generator("SingleRSS/v1.0.0") - fg.link(href="https:/rss.shymega.org.uk/feed.xml", rel="self") - fg.subtitle("Combined feed for RSS feeds") + fg.id(get_url_from_feed(CONFIG)) + fg.title(CONFIG["title"]) + fg.generator("RSSingle/v1.0.0") + fg.link(get_url_from_feed(CONFIG), rel="self") + fg.subtitle(CONFIG["description"]) fg.language('en') except: log.error("Error initialising the feed!") @@ -80,7 +91,7 @@ def parse_rss_feed(url) -> feedparser.FeedParserDict: def main(): log.debug("Loading feed list into memory..") feeds = None - with open(FEED_LIST_PATH, "r") as infile: + with open(CONFIG_PATH, "r") as infile: feeds = infile.read().splitlines() log.debug("Iterating over feed list..") @@ -180,44 +191,39 @@ if __name__ == "__main__": setup_logging() log.debug("Initialising...") + global CONFIG + + with open('config.yml', 'r') as file: + CONFIG = yaml.safe_load(file) + log.debug("Assiging variables..") try: - # Configuration is specified with environemnt variables. - log.debug("Assignment attempt: SINGLERSS_FEED_OUT_PATH") - FEED_OUT_PATH = os.environ["SINGLERSS_FEED_OUT_PATH"] + # Configuration is specified with configure variables. + log.debug("Assignment attempt: output") + FEED_OUT_PATH = CONFIG["output"] except KeyError: - log.error("*** Environment variable missing! ***") - log.error("`SINGLERSS_FEED_OUT_PATH` variable missing.") + log.error("*** Configure variable missing! ***") + log.error("`output` variable missing.") log.error("This program will NOT run without that set.") sys.exit(1) try: - FEED_LIST_PATH = os.environ["SINGLERSS_FEED_LIST_PATH"] + FEED_LIST_PATH = CONFIG["url"] except: - log.error("*** Environment variable missing! ***") - log.error("`SINGLERSS_FEED_LIST_PATH` variable missing.") + log.error("*** Configure variable missing! ***") + log.error("`url` variable missing.") sys.exit(1) try: - FEED_OUT_TYPE = os.environ["SINGLERSS_FEED_OUT_TYPE"] - except KeyError: - log.error("*** Environment variable missing! ***") - log.error("`SINGLERSS_FEED_OUT_TYPE` variable missing.") - log.error("This program will NOT run without that set.") + FEED_LIST_PATH = CONFIG["feeds"] + except: + log.error("*** Configure variable missing! ***") + log.error("`feeds` variable missing.") sys.exit(1) - log.debug("Begin initialising variables..") init_feed() log.debug("Begin processing feeds...") main() - if FEED_OUT_TYPE == "stdout": - log.debug("stdout output specified, outputting to stdout.") - print(fg.rss_str().decode('utf-8')) - elif FEED_OUT_TYPE == "file": - log.debug("File output specified, outputting to specified file..") - fg.rss_file(FEED_OUT_PATH) - else: - log.error("Unknown type of output preference, cannot run.") - sys.exit(1) + fg.rss_file(FEED_OUT_PATH) \ No newline at end of file