]> git.immae.eu Git - github/bastienwirtz/homer.git/blob - src/components/services/qBittorrent.vue
qBittorrent service (#540)
[github/bastienwirtz/homer.git] / src / components / services / qBittorrent.vue
1 <template>
2 <Generic :item="item">
3 <template #content>
4 <p class="title is-4">{{ item.name }}</p>
5 <p class="subtitle is-6">
6 <span v-if="error" class="error">An error has occurred.</span>
7 <template v-else>
8 <span class="down monospace">
9 <p class="fas fa-download "></p> {{ downRate }}
10 </span>
11 <span class="up monospace">
12 <p class="fas fa-upload"></p> {{ upRate }}
13 </span>
14 </template>
15 </p>
16 </template>
17 <template #indicator>
18 <span v-if="!error" class="count">{{ count }}
19 <template v-if="count === 1">torrent</template>
20 <template v-else>torrents</template>
21 </span>
22 </template>
23 </Generic>
24 </template>
25
26 <script>
27 import service from "@/mixins/service.js";
28 import Generic from "./Generic.vue";
29 const units = ["B", "KB", "MB", "GB"];
30
31 // Take the rate in bytes and keep dividing it by 1k until the lowest
32 // value for which we have a unit is determined. Return the value with
33 // up to two decimals as a string and unit/s appended.
34 const displayRate = (rate) => {
35 let i = 0;
36
37 while (rate > 1000 && i < units.length) {
38 rate /= 1000;
39 i++;
40 }
41 return (
42 Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(
43 rate || 0
44 ) + ` ${units[i]}/s`
45 );
46 };
47
48 export default {
49 name: "qBittorrent",
50 mixins: [service],
51 props: { item: Object },
52 components: { Generic },
53 data: () => ({ dl: null, ul: null, count: null, error: null }),
54 computed: {
55 downRate: function () {
56 return displayRate(this.dl);
57 },
58 upRate: function () {
59 return displayRate(this.ul);
60 },
61 },
62 created() {
63 const rateInterval = parseInt(this.item.rateInterval, 10) || 0;
64 const torrentInterval = parseInt(this.item.torrentInterval, 10) || 0;
65 if (rateInterval > 0) {
66 setInterval(() => this.getRate(), rateInterval);
67 }
68 if (torrentInterval > 0) {
69 setInterval(() => this.fetchCount(), torrentInterval);
70 }
71
72 this.getRate();
73 this.fetchCount();
74 },
75 methods: {
76 fetchCount: async function () {
77 try {
78 const body = await this.fetch('/api/v2/torrents/info');
79 this.error = false;
80 this.count = body.length;
81 } catch (e) {
82 this.error = true;
83 console.error(e);
84 }
85 },
86 getRate: async function () {
87 try {
88 const body = await this.fetch('/api/v2/transfer/info');
89 this.error = false;
90 this.dl = body.dl_info_speed;
91 this.ul = body.up_info_speed;
92 } catch (e) {
93 this.error = true;
94 console.error(e);
95 }
96 },
97 },
98 };
99
100 </script>
101
102 <style scoped lang="scss">
103 .error {
104 color: #e51111 !important;
105 }
106
107 .down {
108 margin-right: 1em;
109 }
110
111 .count {
112 color: var(--text);
113 font-size: 0.8em;
114 }
115
116 .monospace {
117 font-weight: 300;
118 font-family: monospace;
119 }
120 </style>