Skip to content

Commit 5145efa

Browse files
committed
feat(api): Added disk stats to status
1 parent 8e0ce23 commit 5145efa

File tree

7 files changed

+150
-11
lines changed

7 files changed

+150
-11
lines changed

.eslintrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
{ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
2929
]
3030
}
31-
]
31+
],
32+
"no-async-promise-executor": "off"
3233
},
3334
"overrides": [
3435
{

apps/graphql-api/src/shared/torrent/torrent.service.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ export class TorrentService {
105105
maxConns: 55 // Is the default
106106
})
107107

108-
this.webTorrent.on('error', (error) => {
108+
this.webTorrent.on('error', (err) => {
109+
const error = err instanceof Error ? err.message : err
109110
this.logger.error('Webtorrent threw error', error)
110111

111112
this.backgroundDownloading = false
@@ -391,7 +392,8 @@ export class TorrentService {
391392
let updatingModel = false
392393

393394
torrent.on('error', async (err) => {
394-
this.logger.error(`[${download._id}]: Torrent error`, err)
395+
const error = err instanceof Error ? err.message : err
396+
this.logger.error(`[${download._id}]: Torrent error`, error)
395397

396398
await this.updateOne(item, {
397399
download: {
@@ -522,7 +524,7 @@ export class TorrentService {
522524
*/
523525
public async updateOne(item: Model<Download | Movie | Episode>, update): Promise<Download | Movie | Episode> {
524526
// Apply the update
525-
if (Object.keys(update).length === 1 && update.hasOwnProperty('download')) {
527+
if (Object.keys(update).length === 1 && update.download) {
526528
this.logger.debug(`[${item._id}]: Update download info to "${JSON.stringify(update.download)}"`)
527529

528530
item.download = {
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
const sizes = ['Bytes/s', 'KB/s', 'MB/s']
1+
const sizes = ['Bytes', 'KB', 'MB', 'GB']
22

33
/**
44
* Formats bytes to a nice string
55
*
66
* @param bytes
7+
* @param perSecond
78
*/
8-
export default (bytes: number): string => {
9+
export default (bytes: number, perSecond = true): string => {
10+
const postFix = perSecond ? '/s' : ''
911
if (!bytes || bytes === 0) {
10-
return '0 Byte'
12+
return `0 Byte${postFix}`
1113
}
1214

1315
const i = parseInt(
@@ -17,5 +19,5 @@ export default (bytes: number): string => {
1719
10
1820
)
1921

20-
return `${(bytes / (1024 ** i)).toFixed(2)} ${sizes[i]}`
22+
return `${(bytes / (1024 ** i)).toFixed(2)} ${sizes[i]}${postFix}`
2123
}

apps/graphql-api/src/status/status.object-type.ts

+26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
import { Field, ObjectType } from '@nestjs/graphql'
22

3+
@ObjectType()
4+
export class Disk {
5+
6+
@Field({ description: 'The free size left available.' })
7+
free: string
8+
9+
@Field({ description: 'The size of the downloads folder.' })
10+
used: string
11+
12+
@Field({ description: 'The size of the disk.' })
13+
size: string
14+
15+
@Field({ description: 'Percentage of the disk free.' })
16+
freePercentage: number
17+
18+
@Field({ description: 'Percentage of the disk used for downloads.' })
19+
usedPercentage: number
20+
21+
@Field({ description: 'Percentage of the disk used.' })
22+
sizePercentage: number
23+
24+
}
25+
326
@ObjectType()
427
export class Status {
528

@@ -15,4 +38,7 @@ export class Status {
1538
@Field({ description: 'The total amount of episodes in the database.' })
1639
totalEpisodes: number
1740

41+
@Field({ description: 'Stats of the download location.' })
42+
disk: Disk
43+
1844
}

apps/graphql-api/src/status/status.service.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { Injectable } from '@nestjs/common'
22
import { InjectModel } from '@nestjs/mongoose'
33
import { Model } from 'mongoose'
4+
import { checkSync } from 'diskusage'
5+
import * as getFolderSize from 'get-folder-size'
46

57
import { Movie, Show, Episode } from '@pct-org/mongo-models'
68

79
import { Status } from './status.object-type'
810
import { StatusScraper } from './status-scraper.object-type'
11+
import { ConfigService } from '../shared/config/config.service'
12+
import { formatKbToString } from '../shared/utils'
913

1014
@Injectable()
1115
export class StatusService {
@@ -17,14 +21,34 @@ export class StatusService {
1721
private readonly showModel: Model<Show>,
1822
@InjectModel('Episodes')
1923
private readonly episodesModel: Model<Episode>,
24+
private readonly configService: ConfigService
2025
) {}
2126

2227
async getStatus(): Promise<Status> {
28+
const disk = await checkSync(
29+
this.configService.get(ConfigService.DOWNLOAD_LOCATION)
30+
)
31+
32+
const folderSize = await this.getFolderSize()
33+
34+
const freePercentage = parseFloat(((disk.available / disk.total) * 100).toFixed(2))
35+
const usedPercentage = parseFloat(((folderSize / (disk.total - disk.available)) * 100).toFixed(2))
36+
const sizePercentage = parseFloat((((disk.total - disk.available - folderSize) / disk.total) * 100).toFixed(2))
37+
2338
return {
2439
version: 'unknown', // TODO:: Get git tag
2540
totalMovies: this.movieModel.countDocuments(),
2641
totalShows: this.showModel.countDocuments(),
27-
totalEpisodes: this.episodesModel.countDocuments()
42+
totalEpisodes: this.episodesModel.countDocuments(),
43+
disk: {
44+
free: formatKbToString(disk.available, false),
45+
used: formatKbToString(folderSize, false),
46+
size: formatKbToString(disk.total, false),
47+
48+
freePercentage,
49+
usedPercentage,
50+
sizePercentage
51+
}
2852
}
2953
}
3054

@@ -41,4 +65,12 @@ export class StatusService {
4165
}
4266
}
4367

68+
private getFolderSize(): Promise<number> {
69+
return new Promise((resolve) => {
70+
getFolderSize(this.configService.get(ConfigService.DOWNLOAD_LOCATION), (err, size) => {
71+
resolve(err ? 0 : size)
72+
})
73+
})
74+
}
75+
4476
}

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@
5050
"apollo-server-fastify": "2.12.0",
5151
"bytes": "^3.1.0",
5252
"class-validator": "0.12.2",
53+
"diskusage": "^1.1.3",
5354
"dotenv": "8.2.0",
5455
"fastify-static": "2.7.0",
56+
"get-folder-size": "^2.0.1",
5557
"graphql": "15.3.0",
5658
"graphql-subscriptions": "^1.1.0",
5759
"ical-generator": "^1.10.0",
@@ -77,6 +79,7 @@
7779
"@nrwl/workspace": "10.2.1",
7880
"@types/jest": "26.0.14",
7981
"@types/node": "~14.11.2",
82+
"@types/webtorrent": "^0.107.2",
8083
"@typescript-eslint/eslint-plugin": "4.2.0",
8184
"@typescript-eslint/parser": "4.2.0",
8285
"dotenv": "6.2.0",

yarn.lock

+75-2
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,13 @@
12571257
dependencies:
12581258
"@babel/types" "^7.3.0"
12591259

1260+
"@types/bittorrent-protocol@*":
1261+
version "3.1.1"
1262+
resolved "https://registry.yarnpkg.com/@types/bittorrent-protocol/-/bittorrent-protocol-3.1.1.tgz#76bfd5903d0f7c7b23289763f39aca9337b3b723"
1263+
integrity sha512-YY3j5aJNTjAt5SA1P+4mK4cU4QuxSN79T1mzdQMLeQL1eTrruU5AxKcgxKZOuatPET3wCDx5JQnq+4XWpFEb/A==
1264+
dependencies:
1265+
"@types/node" "*"
1266+
12601267
"@types/body-parser@*":
12611268
version "1.19.0"
12621269
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f"
@@ -1451,6 +1458,13 @@
14511458
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
14521459
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
14531460

1461+
"@types/magnet-uri@*":
1462+
version "5.1.2"
1463+
resolved "https://registry.yarnpkg.com/@types/magnet-uri/-/magnet-uri-5.1.2.tgz#7860417399d52ddc0be1021d570b4ac93ffc133e"
1464+
integrity sha512-bXFPXskwHoEYP6t8rq4nWchOlbUzXkyhnfCVZmq+zb25R5pWkasw7BmTIqDKQ6RAQmq89jll1v23yLa/SvPfAw==
1465+
dependencies:
1466+
"@types/node" "*"
1467+
14541468
"@types/mime@*":
14551469
version "2.0.3"
14561470
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a"
@@ -1501,6 +1515,22 @@
15011515
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
15021516
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
15031517

1518+
"@types/parse-torrent-file@*":
1519+
version "4.0.2"
1520+
resolved "https://registry.yarnpkg.com/@types/parse-torrent-file/-/parse-torrent-file-4.0.2.tgz#40c96fc075aec256514807c6c381d11d9035bd9e"
1521+
integrity sha512-EzdzpcN0sStQ35sUV2SChTJErLsbotsxZ/RYeR9gf3zXKlPLKaA7aIAoS/nuLRvfxH8mbrWQmXSw76alKecSdg==
1522+
dependencies:
1523+
"@types/node" "*"
1524+
1525+
"@types/parse-torrent@*":
1526+
version "5.8.3"
1527+
resolved "https://registry.yarnpkg.com/@types/parse-torrent/-/parse-torrent-5.8.3.tgz#ff4e987d09ad27ccc1c8893b3a2c6a31a3bc4042"
1528+
integrity sha512-c0xAjnpov+Xk/2HTtpaBm0tukNIAoZoxrqgTDwSaIu6IVCynY+2YD9zcQNk2P6H4atcXzD78/LI2CQzLlMmAJg==
1529+
dependencies:
1530+
"@types/magnet-uri" "*"
1531+
"@types/node" "*"
1532+
"@types/parse-torrent-file" "*"
1533+
15041534
"@types/prettier@^2.0.0":
15051535
version "2.1.1"
15061536
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.1.tgz#be148756d5480a84cde100324c03a86ae5739fb5"
@@ -1531,6 +1561,13 @@
15311561
"@types/express-serve-static-core" "*"
15321562
"@types/mime" "*"
15331563

1564+
"@types/simple-peer@*":
1565+
version "9.6.0"
1566+
resolved "https://registry.yarnpkg.com/@types/simple-peer/-/simple-peer-9.6.0.tgz#b5828d835b7f42dde27db584ba127e7a9f9072f4"
1567+
integrity sha512-X2y6s+vE/3j03hkI90oqld2JH2J/m1L7yFCYYPyFV/whrOK1h4neYvJL3GIE+UcACJacXZqzdmDKudwec18RbA==
1568+
dependencies:
1569+
"@types/node" "*"
1570+
15341571
"@types/source-list-map@*":
15351572
version "0.1.2"
15361573
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
@@ -1588,6 +1625,16 @@
15881625
"@types/webpack-sources" "*"
15891626
source-map "^0.6.0"
15901627

1628+
"@types/webtorrent@^0.107.2":
1629+
version "0.107.2"
1630+
resolved "https://registry.yarnpkg.com/@types/webtorrent/-/webtorrent-0.107.2.tgz#f8d6dba86ef11dfd5087dc82288a3137a03a0523"
1631+
integrity sha512-Jd8NzoF2FqQSo3Y7vPfJDW/vKCv8VDs+22yhzib4YdYEi4q5CfS+1wLZLvL5OpdpVnaxsVmXoVvTZTgrO7y6Qw==
1632+
dependencies:
1633+
"@types/bittorrent-protocol" "*"
1634+
"@types/node" "*"
1635+
"@types/parse-torrent" "*"
1636+
"@types/simple-peer" "*"
1637+
15911638
"@types/ws@^7.0.0":
15921639
version "7.2.6"
15931640
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.2.6.tgz#516cbfb818310f87b43940460e065eb912a4178d"
@@ -4405,6 +4452,14 @@ dir-glob@^3.0.1:
44054452
dependencies:
44064453
path-type "^4.0.0"
44074454

4455+
diskusage@^1.1.3:
4456+
version "1.1.3"
4457+
resolved "https://registry.yarnpkg.com/diskusage/-/diskusage-1.1.3.tgz#680d7dbf1b679168a195c9240eb3552cbd2c067b"
4458+
integrity sha512-EAyaxl8hy4Ph07kzlzGTfpbZMNAAAHXSZtNEMwdlnSd1noHzvA6HsgKt4fEMSvaEXQYLSphe5rPMxN4WOj0hcQ==
4459+
dependencies:
4460+
es6-promise "^4.2.5"
4461+
nan "^2.14.0"
4462+
44084463
dlnacasts@^0.1.0:
44094464
version "0.1.0"
44104465
resolved "https://registry.yarnpkg.com/dlnacasts/-/dlnacasts-0.1.0.tgz#f805211dcac74f6bb3a4d5d5541ad783b1b67d22"
@@ -4739,7 +4794,7 @@ es6-iterator@^2.0.3, es6-iterator@~2.0.3:
47394794
es5-ext "^0.10.35"
47404795
es6-symbol "^3.1.1"
47414796

4742-
es6-promise@^4.0.3:
4797+
es6-promise@^4.0.3, es6-promise@^4.2.5:
47434798
version "4.2.8"
47444799
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
47454800
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
@@ -5660,6 +5715,11 @@ functional-red-black-tree@^1.0.1:
56605715
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
56615716
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
56625717

5718+
gar@^1.0.4:
5719+
version "1.0.4"
5720+
resolved "https://registry.yarnpkg.com/gar/-/gar-1.0.4.tgz#f777bc7db425c0572fdeb52676172ca1ae9888b8"
5721+
integrity sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==
5722+
56635723
gauge@~2.7.3:
56645724
version "2.7.4"
56655725
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
@@ -5694,6 +5754,14 @@ get-caller-file@^2.0.1:
56945754
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
56955755
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
56965756

5757+
get-folder-size@^2.0.1:
5758+
version "2.0.1"
5759+
resolved "https://registry.yarnpkg.com/get-folder-size/-/get-folder-size-2.0.1.tgz#3fe0524dd3bad05257ef1311331417bcd020a497"
5760+
integrity sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==
5761+
dependencies:
5762+
gar "^1.0.4"
5763+
tiny-each-async "2.0.3"
5764+
56975765
get-package-type@^0.1.0:
56985766
version "0.1.0"
56995767
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
@@ -8309,7 +8377,7 @@ [email protected], mute-stream@~0.0.4:
83098377
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
83108378
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
83118379

8312-
nan@^2.12.1:
8380+
nan@^2.12.1, nan@^2.14.0:
83138381
version "2.14.1"
83148382
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
83158383
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
@@ -11339,6 +11407,11 @@ timers-ext@^0.1.5, timers-ext@^0.1.7:
1133911407
es5-ext "~0.10.46"
1134011408
next-tick "1"
1134111409

11410+
11411+
version "2.0.3"
11412+
resolved "https://registry.yarnpkg.com/tiny-each-async/-/tiny-each-async-2.0.3.tgz#8ebbbfd6d6295f1370003fbb37162afe5a0a51d1"
11413+
integrity sha1-jru/1tYpXxNwAD+7NxYq/loKUdE=
11414+
1134211415
tiny-lru@^7.0.2:
1134311416
version "7.0.6"
1134411417
resolved "https://registry.yarnpkg.com/tiny-lru/-/tiny-lru-7.0.6.tgz#b0c3cdede1e5882aa2d1ae21cb2ceccf2a331f24"

0 commit comments

Comments
 (0)