FreshRSS custom service. (#672)

Add FreshRSS custom service.
This commit is contained in:
thedroid 2024-10-26 09:48:03 -05:00 committed by GitHub
parent 0e5106c42a
commit cd25756fd0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 124 additions and 0 deletions

View File

@ -40,6 +40,7 @@ within Homer:
- [OpenHAB](#openhab) - [OpenHAB](#openhab)
- [Jellystat](#jellystat) - [Jellystat](#jellystat)
- [Home Assistant](#home-assistant) - [Home Assistant](#home-assistant)
- [FreshRSS](#freshrss)
> [!IMPORTANT] > [!IMPORTANT]
> Using smart cards will probably requires > Using smart cards will probably requires
@ -500,3 +501,15 @@ You need to set the type to HomeAssistant, provide an api key and enable cors on
``` ```
To create an API token on HomeAssistant, follow the [official documentation here](https://developers.home-assistant.io/docs/auth_api/#long-lived-access-token). To create an API token on HomeAssistant, follow the [official documentation here](https://developers.home-assistant.io/docs/auth_api/#long-lived-access-token).
To enable cors on HomeAssistant, edit your `configuration.yml` and add the IP of Homer to `https: cors_allowed_origins` To enable cors on HomeAssistant, edit your `configuration.yml` and add the IP of Homer to `https: cors_allowed_origins`
## FreshRSS
The FreshRSS service displays unread and subscriptions counts from your FreshRSS server.
```yaml
- name: "FreshRSS"
type: "FreshRSS"
username: "<-- Your username -->"
password: "<-- Your password -->"
updateInterval: 5000 # (Optional) Interval (in ms) for updating the stats
```

View File

@ -0,0 +1,3 @@
SID=username/c7fef7ce380efb8c79a0df25686a3387
LSID=null
Auth=username/c7fef7ce380efb8c79a0df25686a3387

View File

@ -0,0 +1 @@
{"subscriptions":[{"id":"feed/3","title":"Test News","categories":[{"id":"user/-/label/News","label":"News"}],"url":"https://www.reddit.com/r/testnews.rss","htmlUrl":"https://www.reddit.com/r/testnews","iconUrl":"http://192.168.10.165/f.php?b4a11f09"},{"id":"feed/17","title":"Announcements Latest Topics","categories":[{"id":"user/-/label/Technology","label":"Technology"}],"url":"https://forums.testsite.net/forums/forum/7-announcements.xml","htmlUrl":"https://forums.testsite.net/forum/7-announcements/","iconUrl":"http://192.168.10.165/f.php?70b5fd98"},{"id":"feed/16","title":"Blog","categories":[{"id":"user/-/label/Technology","label":"Technology"}],"url":"https://www.firewall.com/blog/rss.xml","htmlUrl":"https://www.firewall.com/blog","iconUrl":"http://192.168.20.165/f.php?0107d102"},{"id":"feed/2","title":"techsite","categories":[{"id":"user/-/label/Technology","label":"Technology"}],"url":"https://techsite.com/rss","htmlUrl":"https://techsite.com/","iconUrl":"http://192.168.10.100/f.php?69ad225d"},{"id":"feed/5","title":"Hackaday","categories":[{"id":"user/-/label/Technology","label":"Technology"}],"url":"https://hackaday.com/feed/","htmlUrl":"https://hackaday.com/","iconUrl":"http://192.168.10.15/f.php?7be93110"},{"id":"feed/7","title":"Self-Hosted Alternatives to Popular Services","categories":[{"id":"user/-/label/Technology","label":"Technology"}],"url":"https://www.reddit.com/r/selfhosted.rss","htmlUrl":"https://www.reddit.com/r/selfhosted","iconUrl":"http://192.168.10.100/f.php?87bdf454"},{"id":"feed/15","title":"UniFi Access PointSwitchLTE | Releases | Ubiquiti Community","categories":[{"id":"user/-/label/Technology","label":"Technology"}],"url":"https://community.ui.com/rss/releases/UniFi-Access-Point-Switch-LTE/9fc3b2fa-9e73-449a-924f-470e79884470","htmlUrl":"https://community.ui.com/","iconUrl":"http://192.168.10.100/f.php?a8b7368a"},{"id":"feed/14","title":"UniFi Network Application | Releases | Ubiquiti Community","categories":[{"id":"user/-/label/Technology","label":"Technology"}],"url":"https://community.ui.com/rss/releases/UniFi-Network-Application/e6712595-81bb-4829-8e42-9e2630fabcfe","htmlUrl":"https://community.ui.com/","iconUrl":"http://192.168.10.100/f.php?87f0ed63"},{"id":"feed/1","title":"FreshRSS releases","categories":[{"id":"user/-/label/Uncategorized","label":"Uncategorized"}],"url":"https://github.com/FreshRSS/FreshRSS/releases.atom","htmlUrl":"https://github.com/FreshRSS/FreshRSS/","iconUrl":"http://192.168.10.100/f.php?261334e9"},{"id":"feed/10","title":"Hooked on Wood","categories":[{"id":"user/-/label/Videos","label":"Videos"}],"url":"https://www.youtube.com/feeds/videos.xml?channel_id=UCuvjeMfKGqSoYc32Xk5MLfQ","htmlUrl":"https://www.youtube.com/channel/UCuvjeMfKGqSoYc32Xk5MLfQ","iconUrl":"http://192.168.10.100/f.php?e6aff645"},{"id":"feed/11","title":"Jeff Geerling","categories":[{"id":"user/-/label/Videos","label":"Videos"}],"url":"https://www.youtube.com/feeds/videos.xml?channel_id=UCR-DXc1voovS8nhAvccRZhg","htmlUrl":"https://www.youtube.com/channel/UCR-DXc1voovS8nhAvccRZhg","iconUrl":"http://192.168.10.100/f.php?5b542c1f"},{"id":"feed/9","title":"Lawrence Systems","categories":[{"id":"user/-/label/Videos","label":"Videos"}],"url":"https://www.youtube.com/feeds/videos.xml?channel_id=UCHkYOD-3fZbuGhwsADBd9ZQ","htmlUrl":"https://www.youtube.com/channel/UCHkYOD-3fZbuGhwsADBd9ZQ","iconUrl":"http://192.168.10.100/f.php?3ab68f8e"},{"id":"feed/13","title":"Thunderf00t","categories":[{"id":"user/-/label/Videos","label":"Videos"}],"url":"https://www.youtube.com/feeds/videos.xml?channel_id=UCmb8hO2ilV9vRa8cilis88A","htmlUrl":"https://www.youtube.com/channel/UCmb8hO2ilV9vRa8cilis88A","iconUrl":"http://192.168.10.100/f.php?d87007ad"}]}

View File

@ -0,0 +1 @@
{"max":1070,"unreadcounts":[{"id":"feed/3","count":234,"newestItemTimestampUsec":"1690915225367106"},{"id":"user/-/label/News","count":234,"newestItemTimestampUsec":"1690915225367106"},{"id":"feed/17","count":48,"newestItemTimestampUsec":"1689390054724200"},{"id":"feed/16","count":17,"newestItemTimestampUsec":"1689796853964422"},{"id":"feed/2","count":219,"newestItemTimestampUsec":"1690916425408239"},{"id":"feed/5","count":199,"newestItemTimestampUsec":"1690915225367107"},{"id":"feed/7","count":211,"newestItemTimestampUsec":"1690916425408242"},{"id":"feed/15","count":22,"newestItemTimestampUsec":"1689663652972458"},{"id":"feed/14","count":21,"newestItemTimestampUsec":"1688368807781577"},{"id":"user/-/label/Technology","count":737,"newestItemTimestampUsec":"1690916425408242"},{"id":"feed/1","count":10,"newestItemTimestampUsec":"1687016967198678"},{"id":"user/-/label/Uncategorized","count":10,"newestItemTimestampUsec":"1687016967198678"},{"id":"feed/10","count":15,"newestItemTimestampUsec":"1688654406671211"},{"id":"feed/11","count":25,"newestItemTimestampUsec":"1690902033356786"},{"id":"feed/9","count":34,"newestItemTimestampUsec":"1690736426018726"},{"id":"feed/13","count":15,"newestItemTimestampUsec":"1690837226605329"},{"id":"user/-/label/Videos","count":89,"newestItemTimestampUsec":"1690902033356786"},{"id":"user/-/state/com.google/reading-list","count":1070,"newestItemTimestampUsec":"1690916425408242"}]}

View File

@ -0,0 +1,106 @@
<template>
<Generic :item="item">
<template #indicator>
<div class="notifs">
<strong v-if="subscriptions > 0" class="notif subscriptions" title="Subscriptions">
{{ subscriptions }}
</strong>
<strong v-if="unread > 0" class="notif unread" title="Unread">
{{ unread }}
</strong>
<strong v-if="serverError" class="notif errors"
title="Connection error to the FreshRSS API, check url username and password in config.yml">?</strong>
</div>
</template>
</Generic>
</template>
<script>
import service from "@/mixins/service.js";
import Generic from "./Generic.vue";
export default {
name: "FreshRSS",
mixins: [service],
props: {
item: Object,
},
components: {
Generic,
},
data: () => {
return {
subscriptions: 0,
unread: 0,
serverError: false,
};
},
created: function () {
const updateInterval = parseInt(this.item.updateInterval, 10) || 0;
if (updateInterval > 0)
setInterval(() => this.fetchConfig(), updateInterval);
this.fetchConfig();
},
methods: {
fetchConfig: async function () {
if (!this.auth) {
const match = await this.fetch(`/api/greader.php/accounts/ClientLogin?Email=${this.item.username}&Passwd=${this.item.password}`, { method: 'GET', cache: "no-cache" }, false)
.then(response => { return response.text(); })
.then(body => { return body.match(/Auth=(([([a-z0-9]+)\/([([a-z0-9]+))/i); });
if (match !== null)
this.auth = match[1];
}
const headers = {
"Authorization": `GoogleLogin auth=${this.auth}`,
};
this.fetch(`/api/greader.php/reader/api/0/subscription/list?output=json`, { headers })
.then((subscription) => {
this.subscriptions = subscription.subscriptions.length;
})
.catch((e) => {
console.error(e);
this.serverError = true;
});
this.fetch(`/api/greader.php/reader/api/0/unread-count?output=json`, { headers })
.then((unreadcount) => {
this.unread = unreadcount.max;
})
.catch((e) => {
console.error(e);
this.serverError = true;
});
},
},
};
</script>
<style scoped lang="scss">
.notifs {
position: absolute;
color: white;
font-family: sans-serif;
top: 0.3em;
right: 0.5em;
.notif {
display: inline-block;
padding: 0.2em 0.35em;
border-radius: 0.25em;
position: relative;
margin-left: 0.3em;
font-size: 0.8em;
&.subscriptions {
background-color: #4fb5d6;
}
&.unread {
background-color: #d08d2e;
}
}
}
</style>