mirror of https://github.com/Lissy93/dashy.git
Sabnzbd Widget
This commit is contained in:
parent
cb74ce9c77
commit
b10a88b022
|
@ -54,6 +54,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
|
|||
- [Nextcloud System](#nextcloud-system)
|
||||
- [Nextcloud Stats](#nextcloud-stats)
|
||||
- [Nextcloud PHP Opcache](#nextcloud-php-opcache-stats)
|
||||
- [Sabnzbd](#sabnzbd)
|
||||
- **[System Resource Monitoring](#system-resource-monitoring)**
|
||||
- [CPU Usage Current](#current-cpu-usage)
|
||||
- [CPU Usage Per Core](#cpu-usage-per-core)
|
||||
|
@ -1790,6 +1791,42 @@ Shows statistics about PHP Opcache perforamnce on your Nextcloud server.
|
|||
|
||||
---
|
||||
|
||||
### Sabnzbd
|
||||
|
||||
Shows queue information regarding your self hosted Sabnzbd server.
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/5TTSRyM/sabnzbd.png" alt="Sabnzbd" /></p>
|
||||
|
||||
##### Options
|
||||
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`sabnzbdUrl`** | `string` | Required | The URL of the Sabnzbd server. No trailing `/`.
|
||||
**`apiKey`** | `string` | Required | API key for Sabnzbd access. Located under `Config` -> `General` -> `Security` -> `API Key`.
|
||||
**`hideDetails`** | `boolean` | _Optional_ | Hides extra server queue details.
|
||||
**`hideQueue`** | `boolean` | _Optional_ | Hides the queue list in an expandable dropdown.
|
||||
|
||||
|
||||
##### Example
|
||||
|
||||
```yaml
|
||||
- type: sabnzbd
|
||||
options:
|
||||
sabnzbdUrl: 'https://sabnzbd.example.com'
|
||||
apiKey: XXXXXXXXXXXXXXXXXX
|
||||
hideDetails: false
|
||||
hideQueue: false
|
||||
```
|
||||
|
||||
##### Info
|
||||
- **CORS**: 🟠 Proxied
|
||||
- **Auth**: 🟢 Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: Self-Hosted (see [Sabnzbd](https://sabnzbd.org/))
|
||||
- **Privacy**: _See [Sabnzbd Privacy Policy](https://forums.sabnzbd.org/ucp.php?mode=privacy)_
|
||||
|
||||
---
|
||||
|
||||
## System Resource Monitoring
|
||||
|
||||
The easiest method for displaying system info and resource usage in Dashy is with [Glances](https://nicolargo.github.io/glances/).
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
<template>
|
||||
<div class="sabznbd">
|
||||
<!-- Sabznbd Header -->
|
||||
<div class="intro">
|
||||
<p class="download">{{ download_speed }}</p>
|
||||
<i :class="`fas fa-${status}`"></i>
|
||||
</div>
|
||||
<!-- Sabnzbd Details, If hideDetails set False -->
|
||||
<div class="details" v-if="sabnzbdDetails.length > 0">
|
||||
<div class="info-wrap" v-for="(section, indx) in sabnzbdDetails" :key="indx">
|
||||
<p class="info-line" v-for="sabznbd in section" :key="sabznbd.label">
|
||||
<span class="lbl">{{sabznbd.label}}</span>
|
||||
<span class="val">{{ sabznbd.value }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Queue Details, If hideQueue set False -->
|
||||
<div class="details" v-if="showQueue && sabnzbdQueue.length > 0">
|
||||
<div class="info-wrap">
|
||||
<p class="info-line" v-for="sabznbd in sabnzbdQueue" :key="sabznbd.label">
|
||||
<i :class="`fas fa-${sabznbd.status}`"></i>
|
||||
<span class="lbl">{{ sabznbd.filename }}</span>
|
||||
<span class="lbl">{{ sabznbd.percentage }}%</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Show/ hide toggle button for Queue-->
|
||||
<p class="more-details-btn" @click="toggleQueue" v-if="sabnzbdQueue.length > 0">
|
||||
{{ showQueue ? "Hide Queue" : "Show Queue" }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin],
|
||||
data() {
|
||||
return {
|
||||
download_speed: null,
|
||||
status: null,
|
||||
sabnzbdDetails: [],
|
||||
showQueue: false,
|
||||
sabnzbdQueue: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.checkProps();
|
||||
},
|
||||
computed: {
|
||||
endpoint() {
|
||||
const { apiKey, sabnzbdUrl } = this.options;
|
||||
return `${sabnzbdUrl}/sabnzbd/api?output=json&apikey=${apiKey}&mode=queue`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/* Reads the kbpersec value of the server status, converts to mb/s if over 1024 kb. */
|
||||
processKBperSec(kbpersec) {
|
||||
if (kbpersec <= 1024) {
|
||||
return `${Number(kbpersec).toFixed(0)} kb/s`;
|
||||
} else {
|
||||
return `${Number(kbpersec / 1024).toFixed(1)} mb/s`;
|
||||
}
|
||||
},
|
||||
/* Reads the bool status output of the server status to append the correct icon */
|
||||
processPaused(paused) {
|
||||
if (paused === true) {
|
||||
return 'pause';
|
||||
} else {
|
||||
return 'play';
|
||||
}
|
||||
},
|
||||
/* Reads the string status output of the queue list to append the correct icon */
|
||||
processPausedStr(paused) {
|
||||
if (['Queued', 'Paused'].includes(paused)) {
|
||||
return 'pause';
|
||||
} else {
|
||||
return 'play';
|
||||
}
|
||||
},
|
||||
fetchData() {
|
||||
this.makeRequest(this.endpoint).then(this.processData);
|
||||
},
|
||||
/* Fetches the Sabnzbd status, and processes results */
|
||||
processData(data) {
|
||||
this.download_speed = this.processKBperSec(data.queue.kbpersec);
|
||||
this.status = this.processPaused(data.queue.paused);
|
||||
if (!this.options.hideDetails) {
|
||||
this.makeSabnzbdataData(data);
|
||||
}
|
||||
if (!this.options.hideQueue) {
|
||||
this.makeSabnzbdataQueueData(data);
|
||||
}
|
||||
},
|
||||
/* If showing Details, then Creates the object required */
|
||||
makeSabnzbdataData(data) {
|
||||
this.sabnzbdDetails = [
|
||||
[
|
||||
{ label: 'Time Left', value: data.queue.timeleft },
|
||||
{ label: 'Queue', value: data.queue.noofslots_total },
|
||||
|
||||
],
|
||||
[
|
||||
{ label: 'Status', value: data.queue.status },
|
||||
{ label: 'Size Left', value: data.queue.sizeleft },
|
||||
],
|
||||
];
|
||||
},
|
||||
/* If showing Queue, Creates list of downloads that are in the sabnzbd list */
|
||||
makeSabnzbdataQueueData(data) {
|
||||
this.sabnzbdQueue = [];
|
||||
let i = 0;
|
||||
for (i; i < data.queue.slots.length; i += 1) {
|
||||
this.sabnzbdQueue.push({
|
||||
status: this.processPausedStr(data.queue.slots[i].status),
|
||||
filename: data.queue.slots[i].filename.substring(0, 25),
|
||||
percentage: data.queue.slots[i].percentage,
|
||||
});
|
||||
}
|
||||
},
|
||||
/* Show/ hide Queue list */
|
||||
toggleQueue() {
|
||||
this.showQueue = !this.showQueue;
|
||||
},
|
||||
/* Validate input props, and print warning if incorrect */
|
||||
checkProps() {
|
||||
const ops = this.options;
|
||||
if (!ops.sabnzbdUrl) this.error('Missing URL for Sabnzbd. Configure sabnzbdUrl in config file.');
|
||||
if (!ops.apiKey) this.error('Missing API key for Sabnzbd. Configure apiKey in config file.');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.loader {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
}
|
||||
p {
|
||||
color: var(--widget-text-color);
|
||||
}
|
||||
|
||||
.sabznbd {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
.intro {
|
||||
grid-column-start: span 2;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
.fas {
|
||||
font-size: 2rem;
|
||||
color: var(--widget-text-color);
|
||||
margin: 2;
|
||||
}
|
||||
.download {
|
||||
font-size: 2rem;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.more-details-btn {
|
||||
grid-column-start: span 2;
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
text-align: center;
|
||||
width: fit-content;
|
||||
margin: 0.25rem auto;
|
||||
padding: 0.1rem 0.25rem;
|
||||
border: 1px solid transparent;
|
||||
opacity: var(--dimming-factor);
|
||||
border-radius: var(--curve-factor);
|
||||
&:hover {
|
||||
border: 1px solid var(--widget-text-color);
|
||||
}
|
||||
&:focus, &:active {
|
||||
background: var(--widget-text-color);
|
||||
color: var(--widget-background-color);
|
||||
}
|
||||
}
|
||||
// More sabznbd details table
|
||||
.details {
|
||||
grid-column-start: span 2;
|
||||
display: flex;
|
||||
.fas {
|
||||
font-size: 1rem;
|
||||
color: var(--widget-text-color);
|
||||
margin: 2;
|
||||
}
|
||||
.info-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
opacity: var(--dimming-factor);
|
||||
p.info-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0.1rem 0.5rem;
|
||||
padding: 0.1rem 0;
|
||||
color: var(--widget-text-color);
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px dashed var(--widget-text-color);
|
||||
}
|
||||
span.lbl {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
|
@ -97,6 +97,7 @@ const COMPAT = {
|
|||
'public-holidays': 'PublicHolidays',
|
||||
'public-ip': 'PublicIp',
|
||||
'rss-feed': 'RssFeed',
|
||||
sabnzbd: 'Sabnzbd',
|
||||
'sports-scores': 'SportsScores',
|
||||
'stat-ping': 'StatPing',
|
||||
'stock-price-chart': 'StockPriceChart',
|
||||
|
|
Loading…
Reference in New Issue