29 Commits

Author SHA1 Message Date
0dfb71de00 Merge branch 'master' into add-limit-entries 2023-10-26 14:53:27 +02:00
124a57c033 Merge pull request #18 from tanrax/fix-format-error
Fix format error
2023-10-26 14:52:35 +02:00
16e80795cd Merge pull request #19 from tanrax/dependabot/pip/lxml-4.9.3
Bump lxml from 4.9.2 to 4.9.3
2023-10-26 14:52:05 +02:00
4cd87527bd Merge pull request #23 from tanrax/dependabot/pip/pyinstaller-6.0.0
Bump pyinstaller from 5.13.0 to 6.0.0
2023-10-26 14:51:30 +02:00
0a075bbdc9 Bump pyinstaller from 5.13.0 to 6.0.0
Bumps [pyinstaller](https://github.com/pyinstaller/pyinstaller) from 5.13.0 to 6.0.0.
- [Release notes](https://github.com/pyinstaller/pyinstaller/releases)
- [Changelog](https://github.com/pyinstaller/pyinstaller/blob/develop/doc/CHANGES.rst)
- [Commits](https://github.com/pyinstaller/pyinstaller/compare/v5.13.0...v6.0.0)

---
updated-dependencies:
- dependency-name: pyinstaller
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-25 04:44:00 +00:00
62f24bb204 Bump lxml from 4.9.2 to 4.9.3
Bumps [lxml](https://github.com/lxml/lxml) from 4.9.2 to 4.9.3.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-4.9.2...lxml-4.9.3)

---
updated-dependencies:
- dependency-name: lxml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 04:25:27 +00:00
e8c77f3398 Add general exception
Co-authored-by: Dom Rodriguez <shymega@shymega.org.uk>
2023-07-06 18:17:37 +01:00
dd16696103 Add var config max entries
Use `max_entries` as YAML key.

Co-authored-by: Dom Rodriguez <shymega@shymega.org.uk>
2023-07-06 18:11:15 +01:00
846de90642 Merge pull request #7 from shymega/shymega/prs/remove-unused-var
Remove unused variables, and duplicate assignments
2023-07-06 11:36:48 +02:00
e101803091 Merge pull request #12 from tanrax/dependabot/pip/pyinstaller-5.13.0
Bump pyinstaller from 5.11.0 to 5.13.0
2023-07-06 11:35:33 +02:00
c3708e8899 Bump pyinstaller from 5.11.0 to 5.13.0
Bumps [pyinstaller](https://github.com/pyinstaller/pyinstaller) from 5.11.0 to 5.13.0.
- [Release notes](https://github.com/pyinstaller/pyinstaller/releases)
- [Changelog](https://github.com/pyinstaller/pyinstaller/blob/develop/doc/CHANGES.rst)
- [Commits](https://github.com/pyinstaller/pyinstaller/compare/v5.11.0...v5.13.0)

---
updated-dependencies:
- dependency-name: pyinstaller
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-26 05:12:43 +00:00
cf60155018 Merge pull request #9 from tanrax/dependabot/pip/pyinstaller-5.11.0
Bump pyinstaller from 5.1 to 5.11.0
2023-05-16 16:38:43 +02:00
82b3ff5cfd Merge pull request #10 from tanrax/dependabot/pip/lxml-4.9.2
Bump lxml from 4.9.0 to 4.9.2
2023-05-16 16:38:31 +02:00
f64d68fb8f Bump lxml from 4.9.0 to 4.9.2
Bumps [lxml](https://github.com/lxml/lxml) from 4.9.0 to 4.9.2.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-4.9.0...lxml-4.9.2)

---
updated-dependencies:
- dependency-name: lxml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-16 14:37:28 +00:00
d2813ee689 Bump pyinstaller from 5.1 to 5.11.0
Bumps [pyinstaller](https://github.com/pyinstaller/pyinstaller) from 5.1 to 5.11.0.
- [Release notes](https://github.com/pyinstaller/pyinstaller/releases)
- [Changelog](https://github.com/pyinstaller/pyinstaller/blob/develop/doc/CHANGES.rst)
- [Commits](https://github.com/pyinstaller/pyinstaller/compare/v5.1...v5.11.0)

---
updated-dependencies:
- dependency-name: pyinstaller
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-16 14:37:24 +00:00
9014c78d29 Merge pull request #4 from shymega/shymega/prs/dependabot
Add Dependabot dependency GH support
2023-05-16 16:36:56 +02:00
758733d025 Merge pull request #6 from shymega/shymega/prs/exceptions
Improve Exception handling, and catch explicit Exceptions
2023-05-16 16:36:22 +02:00
bbe24f6364 Merge pull request #8 from shymega/shymega/prs/fix-get_url_from_feed-func-sig
Explicitly define the return type of get_url_from_feed(config)
2023-05-16 16:33:39 +02:00
52ccc2e676 Explicitly define the return type of get_url_from_feed(config)
This commit explicitly defines the return type of the
get_url_from_feed(config) function.

Signed-off-by: Dom Rodriguez <shymega@shymega.org.uk>
2022-09-13 20:19:03 +01:00
df52406dfe Improve Exception handling, and catch explicit Exceptions
This commit improves Exception handling, and made some changes to
try/catch blocks, where the `KeyError` is now explicitly caught. If in
the future, we have reports of other Exceptions being caught, we can
include those in the handling.

For now, I've used BaseException for two try/catch blocks. I need to
check what exceptions can happen there.

Signed-off-by: Dom Rodriguez <shymega@shymega.org.uk>
2022-09-13 19:43:58 +01:00
3347b233de Remove unused variables, and duplicate assignments
This commit removes an unused variable, and the duplicate assignments in
the main entrypoint.

Signed-off-by: Dom Rodriguez <shymega@shymega.org.uk>
2022-09-13 19:30:36 +01:00
ff30f5807b Add Dependabot dependency GH support
This commit adds support for Dependabot, which will alert the maintainer
when things are out of date, including GH Actions and Python packages.

Signed-off-by: Dom Rodriguez <shymega@shymega.org.uk>
2022-09-12 21:57:38 +01:00
1460f92f02 Update README.md 2022-06-28 05:57:07 -07:00
8f499d4c22 Delete rss.service 2022-06-25 13:04:41 +02:00
1a94b51f1a Delete rss.timer 2022-06-25 13:04:34 +02:00
7a8721f6a1 Delete crontab 2022-06-25 13:04:21 +02:00
d622931090 Create FUNDING.yml 2022-06-25 13:03:35 +02:00
6eeda374da Update README.md 2022-06-25 13:02:11 +02:00
cafef51765 Add files via upload 2022-06-25 13:00:47 +02:00
10 changed files with 47 additions and 75 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: tanrax
ko_fi: androsfenollosa

11
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"

View File

@ -2,6 +2,10 @@
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. 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.
<p align="center">
<img src="rssingle.png" width="200" alt="RRSingle">
</p>
## Run ## Run
1. Download the binary. 1. Download the binary.
@ -12,9 +16,11 @@ Generates an RSS file from the list of other feeds (RSS/Atom/JSON). Very handy w
wget https://github.com/tanrax/RSSingle/releases/download/v1.0.0/rssingle wget https://github.com/tanrax/RSSingle/releases/download/v1.0.0/rssingle
``` ```
**MacOS and Windows** **Windows**
Coming soon ``` shell
wget https://github.com/tanrax/RSSingle/releases/download/v1.0.0/rssingle.exe
```
2. Gives execution permissions. 2. Gives execution permissions.
@ -29,6 +35,7 @@ title: My RSS Feed
description: My customised RSS feed with technology news description: My customised RSS feed with technology news
url: https://www.example.com url: https://www.example.com
output: rss.xml output: rss.xml
max_entries: 5 # Delete this line to get all
feeds: feeds:
- https://programadorwebvalencia.com/feed/ - https://programadorwebvalencia.com/feed/
- https://republicaweb.es/feed/ - https://republicaweb.es/feed/
@ -50,6 +57,12 @@ A file called `rss.xml` will be created.
## Development ## Development
Activate Debug messages by console.
```
export SR_LOG_LEVEl=DEBUG
```
### Compiling ### Compiling
```shell ```shell

View File

@ -2,6 +2,7 @@ title: My RSS Feed
description: My customised RSS feed with technology news description: My customised RSS feed with technology news
url: https://www.example.com url: https://www.example.com
output: rss.xml output: rss.xml
max_entries: 2 # Delete this line to get all
feeds: feeds:
- https://programadorwebvalencia.com/feed/ - https://programadorwebvalencia.com/feed/
- https://republicaweb.es/feed/ - https://republicaweb.es/feed/

View File

@ -1,7 +1,7 @@
feedgen==0.9.0 feedgen==0.9.0
feedparser==6.0.10 feedparser==6.0.10
listparser==0.19.0 listparser==0.19.0
lxml==4.9.0 lxml==4.9.3
python-dateutil==2.8.2 python-dateutil==2.8.2
pyyaml==6.0 pyyaml==6.0
pyinstaller==5.1 pyinstaller==6.0.0

View File

@ -1,5 +0,0 @@
# For stdout to file
0 * * * * cd /opt/rss && . ./.env && /opt/rss/singlerss.py > /var/www/html/feeds.xml
# For file direct.
0 * * * * cd /opt/rss && . ./.env && /opt/rss/singlerss.py

View File

@ -1,26 +0,0 @@
[Unit]
Description=Generate combined RSS feed.
[Service]
Type=oneshot
# Make sure to set user and group
# to your setup.
User=nginx
Group=nobody
# Make sure to customise these to your
# system!
WorkingDirectory=/var/www/html/feed.xml
# And this.
EnvironmentFile=/opt/singlerss/.env
# And this.
ExecStart=/opt/rss/singlerss.py
# These don't work on older systemd versions.
# In that case, you should configure singlerss
# to output to file, as documented in the README,
# and comment these directives out.
StandardInput=null
StandardError=journal
StandardOutput=file:$SINGLERSS_FEED_OUT_PATH

View File

@ -1,8 +0,0 @@
[Unit]
Description=Hourly refresh of singlerss
[Timer]
OnCalendar=hourly
[Install]
WantedBy=timers.target

BIN
rssingle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -22,7 +22,6 @@ CONFIG_PATH = "config.yml"
LOG_LEVEL = environ.get("SR_LOG_LEVEl", "ERROR") LOG_LEVEL = environ.get("SR_LOG_LEVEl", "ERROR")
fg = None fg = None
FEED_OUT_PATH = None FEED_OUT_PATH = None
FEED_LIST_PATH = None
FEEDS = [] FEEDS = []
CFG = None CFG = None
@ -45,7 +44,7 @@ def setup_logging() -> None:
return None return None
def get_url_from_feed(config): def get_url_from_feed(config) -> str:
""" """
This function returns the URL from a feed. This function returns the URL from a feed.
""" """
@ -70,9 +69,8 @@ def init_feed() -> None:
fg.link(href=get_url_from_feed(CONFIG), rel="self") fg.link(href=get_url_from_feed(CONFIG), rel="self")
fg.subtitle(CONFIG["description"]) fg.subtitle(CONFIG["description"])
fg.language("en") fg.language("en")
except: except BaseException: # find out what exceptions FeedGenerator can cause as well as KeyError.
log.error("Error initialising the feed!") logging.exception("Error initialising the feed!")
sys.exit(1)
log.debug("Feed initialised!") log.debug("Feed initialised!")
@ -85,7 +83,7 @@ def parse_rss_feed(url) -> feedparser.FeedParserDict:
try: try:
# Hopefully this should parse.. # Hopefully this should parse..
return feedparser.parse(url) return feedparser.parse(url)
except Exception: except BaseException: # find out what exceptions .parse() call can cause.
log.warning("Failed to parse RSS feed.") log.warning("Failed to parse RSS feed.")
# Now, we could handle gracefully. # Now, we could handle gracefully.
@ -99,7 +97,7 @@ def main():
rss = parse_rss_feed(feed) rss = parse_rss_feed(feed)
entries = rss.get("entries") entries = rss.get("entries")
log.debug("Iterating over [input] feed entries..") log.debug("Iterating over [input] feed entries..")
for entry in entries: for entry in entries[:CONFIG["max_entries"]] if "max_entries" in CONFIG else entries:
log.debug("New feed entry created.") log.debug("New feed entry created.")
fe = fg.add_entry() fe = fg.add_entry()
@ -108,21 +106,21 @@ def main():
try: try:
fe.id(entry["id"]) fe.id(entry["id"])
except: except KeyError:
# Deifnitely weird... # Definitely weird...
log.warning("Empty id attribute, defaulting..") log.warning("Empty id attribute, defaulting..")
fe.id("about:blank") fe.id("about:blank")
try: try:
fe.title(entry["title"]) fe.title(entry["title"])
except: except KeyError:
# OK, this is a definite malformed feed! # OK, this is a definite malformed feed!
log.warning("Empty title attribute, defaulting..") log.warning("Empty title attribute, defaulting..")
fe.title("Unspecified") fe.title("Unspecified")
try: try:
fe.link(href=entry["link"]) fe.link(href=entry["link"])
except: except KeyError:
# When we have a empty link attribute, this isn't ideal # When we have a empty link attribute, this isn't ideal
# to set a default value.. :/ # to set a default value.. :/
log.warning("Empty link attribute, defaulting..") log.warning("Empty link attribute, defaulting..")
@ -136,12 +134,12 @@ def main():
try: try:
for author in entry["authors"]: for author in entry["authors"]:
fe.author(author) fe.author(author)
except: except KeyError:
log.debug("Oh dear, a malformed feed! Adjusting.") log.debug("Oh dear, a malformed feed! Adjusting.")
# This is a ugly hack to fix broken feed entries with the author attribute! # This is a ugly hack to fix broken feed entries with the author attribute!
author["email"] = author.pop("href") author["email"] = author.pop("href")
fe.author(author) fe.author(author)
except: except KeyError:
# Sometimes we don't have ANY author attributes, so we # Sometimes we don't have ANY author attributes, so we
# have to set a dummy attribute. # have to set a dummy attribute.
log.warning("Empty authors attribute, defaulting..") log.warning("Empty authors attribute, defaulting..")
@ -155,7 +153,7 @@ def main():
fe.description(entry["description"]) fe.description(entry["description"])
fe.summary(entry["description"]) fe.summary(entry["description"])
fe.content(entry["description"]) fe.content(entry["description"])
except: except KeyError:
# Sometimes feeds don't provide a summary OR description, so we # Sometimes feeds don't provide a summary OR description, so we
# have to set an empty value. # have to set an empty value.
# This is pretty useless for a feed, so hopefully we # This is pretty useless for a feed, so hopefully we
@ -169,11 +167,11 @@ def main():
try: try:
fe.published(entry["published"]) fe.published(entry["published"])
fe.updated(entry["published"]) fe.updated(entry["published"])
except: except KeyError:
fe.published("1970-01/01T00:00:00+00:00") fe.published("1970-01/01T00:00:00+00:00")
fe.updated("1970-01/01T00:00:00+00:00") fe.updated("1970-01/01T00:00:00+00:00")
continue continue
except: except Exception:
# Sometimes feeds don't even provide a publish date, so we default to # Sometimes feeds don't even provide a publish date, so we default to
# the start date &time of the Unix epoch. # the start date &time of the Unix epoch.
log.warning("Empty publish attribute, defaulting..") log.warning("Empty publish attribute, defaulting..")
@ -201,20 +199,6 @@ if __name__ == "__main__":
log.error("This program will NOT run without that set.") log.error("This program will NOT run without that set.")
sys.exit(1) sys.exit(1)
try:
FEED_LIST_PATH = CONFIG["url"]
except:
log.error("*** Configure variable missing! ***")
log.error("`url` variable missing.")
sys.exit(1)
try:
FEED_LIST_PATH = CONFIG["feeds"]
except:
log.error("*** Configure variable missing! ***")
log.error("`feeds` variable missing.")
sys.exit(1)
init_feed() init_feed()
log.debug("Begin processing feeds...") log.debug("Begin processing feeds...")