<span class="down">
<i class="fas fa-download"></i> {{ downRate }}
</span>
- <span class="up">
- <i class="fas fa-upload"></i> {{ upRate }}
- </span>
+ <span class="up"> <i class="fas fa-upload"></i> {{ upRate }} </span>
</template>
</p>
</template>
<template #indicator>
- <span v-if="!error" class="count">{{ count }}
+ <span v-if="!error" class="count"
+ >{{ count }}
<template v-if="count === 1">torrent</template>
<template v-else>torrents</template>
</span>
</template>
<script>
-import Generic from './Generic.vue';
+import Generic from "./Generic.vue";
// Units to add to download and upload rates.
-const units = ['B', 'kiB', 'MiB', 'GiB'];
+const units = ["B", "kiB", "MiB", "GiB"];
// Take the rate in bytes and keep dividing it by 1k until the lowest
// value for which we have a unit is determined. Return the value with
// up to two decimals as a string and unit/s appended.
const displayRate = (rate) => {
let i = 0;
-
+
while (rate > 1000 && i < units.length) {
rate /= 1000;
i++;
}
- return Intl.NumberFormat(undefined, {maximumFractionDigits: 2})
- .format(rate || 0) + ` ${units[i]}/s`;
-}
+ return (
+ Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(
+ rate || 0
+ ) + ` ${units[i]}/s`
+ );
+};
export default {
- name: 'rTorrent',
- props: {item: Object},
- components: {Generic},
+ name: "rTorrent",
+ props: { item: Object },
+ components: { Generic },
// Properties for download, upload, torrent count and errors.
- data: () => ({dl: null, ul: null, count: null, error: null}),
+ data: () => ({ dl: null, ul: null, count: null, error: null }),
// Computed properties for the rate labels.
computed: {
- downRate: function() {
+ downRate: function () {
return displayRate(this.dl);
},
- upRate: function() {
+ upRate: function () {
return displayRate(this.ul);
},
},
if (torrentInterval > 0) {
setInterval(() => this.fetchCount(), torrentInterval);
}
-
+
// Fetch the initial values.
this.fetchRates();
this.fetchCount();
// Perform two calls to the XML-RPC service and fetch download
// and upload rates. Values are saved to the `ul` and `dl`
// properties.
- fetchRates: async function() {
- this.getRate('throttle.global_up.rate')
- .then((ul) => this.ul = ul)
- .catch(() => this.error = true);
+ fetchRates: async function () {
+ this.getRate("throttle.global_up.rate")
+ .then((ul) => (this.ul = ul))
+ .catch(() => (this.error = true));
- this.getRate('throttle.global_down.rate')
- .then((dl) => this.dl = dl)
- .catch(() => this.error = true);
+ this.getRate("throttle.global_down.rate")
+ .then((dl) => (this.dl = dl))
+ .catch(() => (this.error = true));
},
// Perform a call to the XML-RPC service to fetch the number of
// torrents.
- fetchCount: async function() {
- this.getCount().catch(() => this.error = true);
+ fetchCount: async function () {
+ this.getCount().catch(() => (this.error = true));
},
// Fetch a numeric value from the XML-RPC service by requesting
// the specified method name and parsing the XML. The response
// is expected to adhere to the structure of a single numeric
// value.
- getRate: async function(methodName) {
- return this.getXml(methodName)
- .then((xml) => parseInt(xml.getElementsByTagName('value')[0].firstChild.textContent, 10));
+ getRate: async function (methodName) {
+ return this.getXml(methodName).then((xml) =>
+ parseInt(
+ xml.getElementsByTagName("value")[0].firstChild.textContent,
+ 10
+ )
+ );
},
// Fetch the numer of torrents by requesting the download list
// and counting the number of entries therein.
- getCount: async function() {
- return this.getXml('download_list')
- .then((xml) => {
- const arrayEl = xml.getElementsByTagName('array');
- this.count = arrayEl ? arrayEl[0].getElementsByTagName('value').length : 0;
- });
+ getCount: async function () {
+ return this.getXml("download_list").then((xml) => {
+ const arrayEl = xml.getElementsByTagName("array");
+ this.count = arrayEl
+ ? arrayEl[0].getElementsByTagName("value").length
+ : 0;
+ });
},
// Perform a call to the XML-RPC service and parse the response
// as XML, which is then returned.
- getXml: async function(methodName) {
- const headers = {'Content-Type': 'text/xml'};
+ getXml: async function (methodName) {
+ const headers = { "Content-Type": "text/xml" };
if (this.item.username && this.item.password) {
- headers['Authorization'] = `${this.item.username}:${this.item.password}`;
+ headers[
+ "Authorization"
+ ] = `${this.item.username}:${this.item.password}`;
}
- return fetch(`${this.item.xmlrpc.replace(/\/$/, '')}/RPC2`, {
- method: 'POST',
+ return fetch(`${this.item.xmlrpc.replace(/\/$/, "")}/RPC2`, {
+ method: "POST",
headers,
- body: `<methodCall><methodName>${methodName}</methodName></methodCall>`
+ body: `<methodCall><methodName>${methodName}</methodName></methodCall>`,
})
- .then((response) => {
- if (!response.ok) {
- throw Error(response.statusText);
- }
+ .then((response) => {
+ if (!response.ok) {
+ throw Error(response.statusText);
+ }
- return response.text();
- })
- .then((text) => Promise.resolve(new DOMParser().parseFromString(text, 'text/xml')));
- }
- }
-}
+ return response.text();
+ })
+ .then((text) =>
+ Promise.resolve(new DOMParser().parseFromString(text, "text/xml"))
+ );
+ },
+ },
+};
</script>
<style scoped lang="scss">
color: var(--text);
font-size: 0.8em;
}
-</style>
\ No newline at end of file
+</style>
-<template>\r
- <Generic :item="item">\r
- <template #content>\r
- <p class="title is-4">{{ item.name }}</p>\r
- <p class="subtitle is-6">\r
- <span v-if="error" class="error">An error has occurred.</span>\r
- <template v-else>\r
- <span class="down monospace">\r
- <p class="fas fa-download "></p> {{ downRate }}\r
- </span>\r
- <span class="up monospace">\r
- <p class="fas fa-upload"></p> {{ upRate }}\r
- </span>\r
- </template>\r
- </p>\r
- </template>\r
- <template #indicator>\r
- <span v-if="!error" class="count">{{ count }}\r
- <template v-if="count === 1">torrent</template>\r
- <template v-else>torrents</template>\r
- </span>\r
- </template>\r
- </Generic>\r
-</template>\r
-\r
-<script>\r
-import service from "@/mixins/service.js";\r
-import Generic from "./Generic.vue";\r
-const units = ["B", "KB", "MB", "GB"];\r
-\r
-// Take the rate in bytes and keep dividing it by 1k until the lowest\r
-// value for which we have a unit is determined. Return the value with\r
-// up to two decimals as a string and unit/s appended.\r
-const displayRate = (rate) => {\r
- let i = 0;\r
-\r
- while (rate > 1000 && i < units.length) {\r
- rate /= 1000;\r
- i++;\r
- }\r
- return (\r
- Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(\r
- rate || 0\r
- ) + ` ${units[i]}/s`\r
- );\r
-};\r
-\r
-export default {\r
- name: "qBittorrent",\r
- mixins: [service],\r
- props: { item: Object },\r
- components: { Generic },\r
- data: () => ({ dl: null, ul: null, count: null, error: null }),\r
- computed: {\r
- downRate: function () {\r
- return displayRate(this.dl);\r
- },\r
- upRate: function () {\r
- return displayRate(this.ul);\r
- },\r
- },\r
- created() {\r
- const rateInterval = parseInt(this.item.rateInterval, 10) || 0;\r
- const torrentInterval = parseInt(this.item.torrentInterval, 10) || 0;\r
- if (rateInterval > 0) {\r
- setInterval(() => this.getRate(), rateInterval);\r
- }\r
- if (torrentInterval > 0) {\r
- setInterval(() => this.fetchCount(), torrentInterval);\r
- }\r
-\r
- this.getRate();\r
- this.fetchCount();\r
- },\r
- methods: {\r
- fetchCount: async function () {\r
- try {\r
- const body = await this.fetch('/api/v2/torrents/info');\r
- this.error = false;\r
- this.count = body.length;\r
- } catch (e) {\r
- this.error = true;\r
- console.error(e);\r
- }\r
- },\r
- getRate: async function () {\r
- try {\r
- const body = await this.fetch('/api/v2/transfer/info');\r
- this.error = false;\r
- this.dl = body.dl_info_speed;\r
- this.ul = body.up_info_speed;\r
- } catch (e) {\r
- this.error = true;\r
- console.error(e);\r
- }\r
- },\r
- },\r
-};\r
-\r
-</script>\r
-\r
-<style scoped lang="scss">\r
-.error {\r
- color: #e51111 !important;\r
-}\r
-\r
-.down {\r
- margin-right: 1em;\r
-}\r
-\r
-.count {\r
- color: var(--text);\r
- font-size: 0.8em;\r
-}\r
-\r
-.monospace {\r
- font-weight: 300;\r
- font-family: monospace;\r
-}\r
-</style>
\ No newline at end of file
+<template>
+ <Generic :item="item">
+ <template #content>
+ <p class="title is-4">{{ item.name }}</p>
+ <p class="subtitle is-6">
+ <span v-if="error" class="error">An error has occurred.</span>
+ <template v-else>
+ <span class="down monospace">
+ <p class="fas fa-download"></p>
+ {{ downRate }}
+ </span>
+ <span class="up monospace">
+ <p class="fas fa-upload"></p>
+ {{ upRate }}
+ </span>
+ </template>
+ </p>
+ </template>
+ <template #indicator>
+ <span v-if="!error" class="count"
+ >{{ count }}
+ <template v-if="count === 1">torrent</template>
+ <template v-else>torrents</template>
+ </span>
+ </template>
+ </Generic>
+</template>
+
+<script>
+import service from "@/mixins/service.js";
+import Generic from "./Generic.vue";
+const units = ["B", "KB", "MB", "GB"];
+
+// Take the rate in bytes and keep dividing it by 1k until the lowest
+// value for which we have a unit is determined. Return the value with
+// up to two decimals as a string and unit/s appended.
+const displayRate = (rate) => {
+ let i = 0;
+
+ while (rate > 1000 && i < units.length) {
+ rate /= 1000;
+ i++;
+ }
+ return (
+ Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(
+ rate || 0
+ ) + ` ${units[i]}/s`
+ );
+};
+
+export default {
+ name: "qBittorrent",
+ mixins: [service],
+ props: { item: Object },
+ components: { Generic },
+ data: () => ({ dl: null, ul: null, count: null, error: null }),
+ computed: {
+ downRate: function () {
+ return displayRate(this.dl);
+ },
+ upRate: function () {
+ return displayRate(this.ul);
+ },
+ },
+ created() {
+ const rateInterval = parseInt(this.item.rateInterval, 10) || 0;
+ const torrentInterval = parseInt(this.item.torrentInterval, 10) || 0;
+ if (rateInterval > 0) {
+ setInterval(() => this.getRate(), rateInterval);
+ }
+ if (torrentInterval > 0) {
+ setInterval(() => this.fetchCount(), torrentInterval);
+ }
+
+ this.getRate();
+ this.fetchCount();
+ },
+ methods: {
+ fetchCount: async function () {
+ try {
+ const body = await this.fetch("/api/v2/torrents/info");
+ this.error = false;
+ this.count = body.length;
+ } catch (e) {
+ this.error = true;
+ console.error(e);
+ }
+ },
+ getRate: async function () {
+ try {
+ const body = await this.fetch("/api/v2/transfer/info");
+ this.error = false;
+ this.dl = body.dl_info_speed;
+ this.ul = body.up_info_speed;
+ } catch (e) {
+ this.error = true;
+ console.error(e);
+ }
+ },
+ },
+};
+</script>
+
+<style scoped lang="scss">
+.error {
+ color: #e51111 !important;
+}
+
+.down {
+ margin-right: 1em;
+}
+
+.count {
+ color: var(--text);
+ font-size: 0.8em;
+}
+
+.monospace {
+ font-weight: 300;
+ font-family: monospace;
+}
+</style>