aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/components/services/Rtorrent.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/services/Rtorrent.vue')
-rw-r--r--src/components/services/Rtorrent.vue115
1 files changed, 63 insertions, 52 deletions
diff --git a/src/components/services/Rtorrent.vue b/src/components/services/Rtorrent.vue
index 75efb7b..ed8e7a6 100644
--- a/src/components/services/Rtorrent.vue
+++ b/src/components/services/Rtorrent.vue
@@ -8,14 +8,13 @@
8 <span class="down"> 8 <span class="down">
9 <i class="fas fa-download"></i> {{ downRate }} 9 <i class="fas fa-download"></i> {{ downRate }}
10 </span> 10 </span>
11 <span class="up"> 11 <span class="up"> <i class="fas fa-upload"></i> {{ upRate }} </span>
12 <i class="fas fa-upload"></i> {{ upRate }}
13 </span>
14 </template> 12 </template>
15 </p> 13 </p>
16 </template> 14 </template>
17 <template #indicator> 15 <template #indicator>
18 <span v-if="!error" class="count">{{ count }} 16 <span v-if="!error" class="count"
17 >{{ count }}
19 <template v-if="count === 1">torrent</template> 18 <template v-if="count === 1">torrent</template>
20 <template v-else>torrents</template> 19 <template v-else>torrents</template>
21 </span> 20 </span>
@@ -24,38 +23,41 @@
24</template> 23</template>
25 24
26<script> 25<script>
27import Generic from './Generic.vue'; 26import Generic from "./Generic.vue";
28 27
29// Units to add to download and upload rates. 28// Units to add to download and upload rates.
30const units = ['B', 'kiB', 'MiB', 'GiB']; 29const units = ["B", "kiB", "MiB", "GiB"];
31 30
32// Take the rate in bytes and keep dividing it by 1k until the lowest 31// Take the rate in bytes and keep dividing it by 1k until the lowest
33// value for which we have a unit is determined. Return the value with 32// value for which we have a unit is determined. Return the value with
34// up to two decimals as a string and unit/s appended. 33// up to two decimals as a string and unit/s appended.
35const displayRate = (rate) => { 34const displayRate = (rate) => {
36 let i = 0; 35 let i = 0;
37 36
38 while (rate > 1000 && i < units.length) { 37 while (rate > 1000 && i < units.length) {
39 rate /= 1000; 38 rate /= 1000;
40 i++; 39 i++;
41 } 40 }
42 41
43 return Intl.NumberFormat(undefined, {maximumFractionDigits: 2}) 42 return (
44 .format(rate || 0) + ` ${units[i]}/s`; 43 Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(
45} 44 rate || 0
45 ) + ` ${units[i]}/s`
46 );
47};
46 48
47export default { 49export default {
48 name: 'rTorrent', 50 name: "rTorrent",
49 props: {item: Object}, 51 props: { item: Object },
50 components: {Generic}, 52 components: { Generic },
51 // Properties for download, upload, torrent count and errors. 53 // Properties for download, upload, torrent count and errors.
52 data: () => ({dl: null, ul: null, count: null, error: null}), 54 data: () => ({ dl: null, ul: null, count: null, error: null }),
53 // Computed properties for the rate labels. 55 // Computed properties for the rate labels.
54 computed: { 56 computed: {
55 downRate: function() { 57 downRate: function () {
56 return displayRate(this.dl); 58 return displayRate(this.dl);
57 }, 59 },
58 upRate: function() { 60 upRate: function () {
59 return displayRate(this.ul); 61 return displayRate(this.ul);
60 }, 62 },
61 }, 63 },
@@ -72,7 +74,7 @@ export default {
72 if (torrentInterval > 0) { 74 if (torrentInterval > 0) {
73 setInterval(() => this.fetchCount(), torrentInterval); 75 setInterval(() => this.fetchCount(), torrentInterval);
74 } 76 }
75 77
76 // Fetch the initial values. 78 // Fetch the initial values.
77 this.fetchRates(); 79 this.fetchRates();
78 this.fetchCount(); 80 this.fetchCount();
@@ -81,62 +83,71 @@ export default {
81 // Perform two calls to the XML-RPC service and fetch download 83 // Perform two calls to the XML-RPC service and fetch download
82 // and upload rates. Values are saved to the `ul` and `dl` 84 // and upload rates. Values are saved to the `ul` and `dl`
83 // properties. 85 // properties.
84 fetchRates: async function() { 86 fetchRates: async function () {
85 this.getRate('throttle.global_up.rate') 87 this.getRate("throttle.global_up.rate")
86 .then((ul) => this.ul = ul) 88 .then((ul) => (this.ul = ul))
87 .catch(() => this.error = true); 89 .catch(() => (this.error = true));
88 90
89 this.getRate('throttle.global_down.rate') 91 this.getRate("throttle.global_down.rate")
90 .then((dl) => this.dl = dl) 92 .then((dl) => (this.dl = dl))
91 .catch(() => this.error = true); 93 .catch(() => (this.error = true));
92 }, 94 },
93 // Perform a call to the XML-RPC service to fetch the number of 95 // Perform a call to the XML-RPC service to fetch the number of
94 // torrents. 96 // torrents.
95 fetchCount: async function() { 97 fetchCount: async function () {
96 this.getCount().catch(() => this.error = true); 98 this.getCount().catch(() => (this.error = true));
97 }, 99 },
98 // Fetch a numeric value from the XML-RPC service by requesting 100 // Fetch a numeric value from the XML-RPC service by requesting
99 // the specified method name and parsing the XML. The response 101 // the specified method name and parsing the XML. The response
100 // is expected to adhere to the structure of a single numeric 102 // is expected to adhere to the structure of a single numeric
101 // value. 103 // value.
102 getRate: async function(methodName) { 104 getRate: async function (methodName) {
103 return this.getXml(methodName) 105 return this.getXml(methodName).then((xml) =>
104 .then((xml) => parseInt(xml.getElementsByTagName('value')[0].firstChild.textContent, 10)); 106 parseInt(
107 xml.getElementsByTagName("value")[0].firstChild.textContent,
108 10
109 )
110 );
105 }, 111 },
106 // Fetch the numer of torrents by requesting the download list 112 // Fetch the numer of torrents by requesting the download list
107 // and counting the number of entries therein. 113 // and counting the number of entries therein.
108 getCount: async function() { 114 getCount: async function () {
109 return this.getXml('download_list') 115 return this.getXml("download_list").then((xml) => {
110 .then((xml) => { 116 const arrayEl = xml.getElementsByTagName("array");
111 const arrayEl = xml.getElementsByTagName('array'); 117 this.count = arrayEl
112 this.count = arrayEl ? arrayEl[0].getElementsByTagName('value').length : 0; 118 ? arrayEl[0].getElementsByTagName("value").length
113 }); 119 : 0;
120 });
114 }, 121 },
115 // Perform a call to the XML-RPC service and parse the response 122 // Perform a call to the XML-RPC service and parse the response
116 // as XML, which is then returned. 123 // as XML, which is then returned.
117 getXml: async function(methodName) { 124 getXml: async function (methodName) {
118 const headers = {'Content-Type': 'text/xml'}; 125 const headers = { "Content-Type": "text/xml" };
119 126
120 if (this.item.username && this.item.password) { 127 if (this.item.username && this.item.password) {
121 headers['Authorization'] = `${this.item.username}:${this.item.password}`; 128 headers[
129 "Authorization"
130 ] = `${this.item.username}:${this.item.password}`;
122 } 131 }
123 132
124 return fetch(`${this.item.xmlrpc.replace(/\/$/, '')}/RPC2`, { 133 return fetch(`${this.item.xmlrpc.replace(/\/$/, "")}/RPC2`, {
125 method: 'POST', 134 method: "POST",
126 headers, 135 headers,
127 body: `<methodCall><methodName>${methodName}</methodName></methodCall>` 136 body: `<methodCall><methodName>${methodName}</methodName></methodCall>`,
128 }) 137 })
129 .then((response) => { 138 .then((response) => {
130 if (!response.ok) { 139 if (!response.ok) {
131 throw Error(response.statusText); 140 throw Error(response.statusText);
132 } 141 }
133 142
134 return response.text(); 143 return response.text();
135 }) 144 })
136 .then((text) => Promise.resolve(new DOMParser().parseFromString(text, 'text/xml'))); 145 .then((text) =>
137 } 146 Promise.resolve(new DOMParser().parseFromString(text, "text/xml"))
138 } 147 );
139} 148 },
149 },
150};
140</script> 151</script>
141 152
142<style scoped lang="scss"> 153<style scoped lang="scss">
@@ -150,4 +161,4 @@ export default {
150 color: var(--text); 161 color: var(--text);
151 font-size: 0.8em; 162 font-size: 0.8em;
152} 163}
153</style> \ No newline at end of file 164</style>