Skip to content

Commit 4799eb6

Browse files
Improve some logic
1 parent 96f419d commit 4799eb6

File tree

11 files changed

+82
-48
lines changed

11 files changed

+82
-48
lines changed

build-rel.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@echo off&cd /d %~dp0
22

33
set "ISCC_PATH=C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
4-
set VERSION_NUM=1.0.1
4+
set VERSION_NUM=1.0.2
55

66
mkdir build\asmr-dl-ng
77
@rem xcopy bin build\asmr-dl-ng\bin /E /I /Q

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "asmr-dl-ng",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"description": "ASMR Direct Downloader (New Generation)",
55
"author": "daydreamer-json <[email protected]> (https://github.com/daydreamer-json)",
66
"license": "AGPL-3.0-or-later",

setup/main.iss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#define MyAppName "asmr-dl-ng"
2-
#define MyAppVersion "1.0.1"
2+
#define MyAppVersion "1.0.2"
33
#define MyAppPublisher "daydreamer-json"
44
#define MyAppURL "https://github.com/daydreamer-json/asmr-dl-ng"
55
#define MyAppExeName "asmr-dl-ng.exe"

src/cmd.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ async function parseCommand() {
3030
const yargsInstance = yargs(hideBin(process.argv));
3131
await yargsInstance
3232
.command(
33-
['download [id]', 'dl'],
33+
['download [id...]', 'dl'],
3434
'Download work',
3535
(yargs) => {
3636
yargs
@@ -104,7 +104,7 @@ async function parseCommand() {
104104
wrapHandler(cmds.download),
105105
)
106106
.command(
107-
['info [id]'],
107+
['info [id...]'],
108108
'Show metadata of work',
109109
(yargs) => {
110110
yargs

src/cmds/download.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import logger from '../utils/logger.js';
99
import termPrettyUtils from '../utils/termPretty.js';
1010

1111
async function mainCmdHandler() {
12-
if (!('id' in argvUtils.getArgv())) {
12+
if (!('id' in argvUtils.getArgv()) || argvUtils.getArgv()['id'].length === 0) {
1313
logger.warn('Work ID has not been specified. Requesting ...');
1414
const idRsp: number = (
1515
await prompts(
@@ -22,30 +22,32 @@ async function mainCmdHandler() {
2222
},
2323
)
2424
).value;
25-
argvUtils.setArgv({ ...argvUtils.getArgv(), id: idRsp });
25+
argvUtils.setArgv({ ...argvUtils.getArgv(), id: [idRsp] });
2626
}
2727
apiUtils.setBaseUri(argvUtils.getArgv()['server'] as TypesApi.ServerName);
2828

29-
await (async () => {
30-
const spinner = !argvUtils.getArgv()['no-show-progress']
31-
? ora({ text: 'Checking API health ...', color: 'cyan', spinner: 'dotsCircle' }).start()
32-
: undefined;
33-
const apiHealthRsp = await apiUtils.api.health();
34-
spinner?.stop();
35-
if (apiHealthRsp.available === true) {
36-
logger.info('API health check succeeded');
37-
} else {
38-
throw new Error('API health check failed');
39-
}
40-
})();
29+
for (const workId of argvUtils.getArgv()['id']) {
30+
await (async () => {
31+
const spinner = !argvUtils.getArgv()['no-show-progress']
32+
? ora({ text: 'Checking API health ...', color: 'cyan', spinner: 'dotsCircle' }).start()
33+
: undefined;
34+
const apiHealthRsp = await apiUtils.api.health();
35+
spinner?.stop();
36+
if (apiHealthRsp.available === true) {
37+
logger.info('API health check succeeded');
38+
} else {
39+
throw new Error('API health check failed');
40+
}
41+
})();
4142

42-
const workApiRsp = await downloadUtils.downloadMeta(argvUtils.getArgv()['id']);
43+
const workApiRsp = await downloadUtils.downloadMeta(workId);
4344

44-
console.log(termPrettyUtils.printWorkInfo(workApiRsp));
45+
console.log(termPrettyUtils.printWorkInfo(workApiRsp));
4546

46-
const selectedFilesUuid = await downloadUtils.filterFileEntry(workApiRsp.fileEntry.transformed);
47+
const selectedFilesUuid = await downloadUtils.filterFileEntry(workApiRsp.fileEntry.transformed);
4748

48-
await downloadUtils.downloadWork(workApiRsp, selectedFilesUuid);
49+
await downloadUtils.downloadWork(workApiRsp, selectedFilesUuid);
50+
}
4951
}
5052

5153
export default mainCmdHandler;

src/utils/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type ConfigType = AllRequired<
1616
Freeze<{
1717
network: {
1818
asmrApi: {
19+
// all values are base64
1920
baseDomain: {
2021
latest: string;
2122
original: string;
@@ -84,7 +85,7 @@ const initialConfig: ConfigType = {
8485
},
8586
threadCount: {
8687
network: 8,
87-
hashing: 32,
88+
hashing: 16,
8889
},
8990
cli: {
9091
autoExit: false,

src/utils/configEmbed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import semver from 'semver';
22

33
export default {
44
APPLICATION_NAME: 'asmr-dl-ng',
5-
VERSION_NUMBER: semver.valid('1.0.1'),
5+
VERSION_NUMBER: semver.valid('1.0.2'),
66
};

src/utils/configUser.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@ type AllRequired<T> = Required<{
1414
type ConfigType = AllRequired<
1515
Freeze<{
1616
file: {
17+
// Output root directory
1718
outputDirPath: string;
19+
// Naming convention for subfolders generated within the outputDirPath
1820
outputDirPattern: string;
21+
// When set to true, the file selection prompt before download is skipped, and the filterRegex is automatically applied
1922
useAutoFilterRegex: boolean;
23+
// Regular expressions used to efficiently specify files to download
24+
// Files are selected where the path matches at least one include and does not match any excludes
2025
filterRegex: {
2126
include: string[];
2227
exclude: string[];

src/utils/download.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -212,19 +212,30 @@ async function downloadWork(
212212
const outFilePath = path.join(tempOutputDirPath, fileEntry.uuid);
213213
let dledDataSize = 0; // bytes
214214
let retriedCount = 0;
215+
const rateMeterFile = new rateMeterUtils.RateMeter(1000 * rateMeterAvgFactor, true);
215216
const progBarSub =
216217
process.stdout.rows > queue.concurrency + 3
217218
? progBar?.create(
218219
fileEntry.size,
219220
dledDataSize,
220-
termPrettyUtils.progBarTextFmter.download.sub(dledDataSize, fileEntry.size, fileEntry.path.at(-1) ?? ''),
221+
termPrettyUtils.progBarTextFmter.download.sub(
222+
dledDataSize,
223+
fileEntry.size,
224+
rateMeterFile.getRate(),
225+
fileEntry.path.at(-1) ?? '',
226+
),
221227
{ format: termPrettyUtils.progBarFmtCfg.download.sub },
222228
)
223229
: undefined;
224230
const progBarUpdateFunc = (subCurrent: number) => {
225231
progBarSub?.update(
226232
subCurrent,
227-
termPrettyUtils.progBarTextFmter.download.sub(subCurrent, fileEntry.size, fileEntry.path.at(-1) ?? ''),
233+
termPrettyUtils.progBarTextFmter.download.sub(
234+
subCurrent,
235+
fileEntry.size,
236+
rateMeterFile.getRate(),
237+
fileEntry.path.at(-1) ?? '',
238+
),
228239
);
229240
const tmpRootPayload = termPrettyUtils.progBarTextFmter.download.root(
230241
dledFileEntry.length,
@@ -242,20 +253,17 @@ async function downloadWork(
242253

243254
while (retriedCount <= appConfig.network.retryCount) {
244255
const abortController = new AbortController();
245-
const rateMeterFile = new rateMeterUtils.RateMeter(1000, true);
246256
let timeoutTimer: NodeJS.Timeout | null = null;
247257
let lastNonZeroRateTime = Date.now();
248-
258+
rateMeterFile.reset();
249259
try {
250260
timeoutTimer = setInterval(() => {
251-
if (rateMeterFile.getRate() === 0) {
252-
if (Date.now() - lastNonZeroRateTime > appConfig.network.timeout) {
253-
abortController.abort(new Error('Download timeout due to zero speed'));
254-
}
255-
} else {
256-
lastNonZeroRateTime = Date.now();
261+
rateMeterFile.increment(0);
262+
progBarUpdateFunc(dledDataSize);
263+
if (Date.now() - lastNonZeroRateTime > appConfig.network.timeout) {
264+
abortController.abort();
257265
}
258-
}, 1000);
266+
}, 250);
259267

260268
const progressStream = new stream.Transform({
261269
transform(chunk, _encoding, callback) {
@@ -264,9 +272,7 @@ async function downloadWork(
264272
rateMeterFile.increment(chunk.length);
265273
dledDataSize += chunk.length;
266274
progBarUpdateFunc(dledDataSize);
267-
if (rateMeterFile.getRate() > 0) {
268-
lastNonZeroRateTime = Date.now();
269-
}
275+
lastNonZeroRateTime = Date.now();
270276
this.push(chunk);
271277
callback();
272278
},
@@ -281,6 +287,7 @@ async function downloadWork(
281287
stream.Readable.fromWeb(response.body as any),
282288
progressStream,
283289
fs.createWriteStream(outFilePath, { flags: 'wx' }),
290+
{ signal: abortController.signal },
284291
);
285292
progBarUpdateFunc(fileEntry.size);
286293
dledFileEntry.push(fileEntry);
@@ -307,6 +314,7 @@ async function downloadWork(
307314
// `Download failed, retrying... (${retriedCount}/${appConfig.network.retryCount}): ${fileEntry.path.join('/')}`,
308315
// );
309316
dledDataSizeGlobal -= dledDataSize;
317+
dledDataSize = 0;
310318
}
311319

312320
if (timeoutTimer) clearInterval(timeoutTimer);

src/utils/downloadPost.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ async function calculateHashes(
2828
) {
2929
logger.info('Calculating file hashes ...');
3030

31-
// Worker script is hardcoded here to avoid bun build issue
31+
//! Worker script is hardcoded here to avoid bun build issue
3232
const workerScript = `{{{HASH_WORKER_PLACEHOLDER}}}`;
3333
const workerBlob = new Blob([workerScript], { type: 'application/javascript' });
3434
const workerUrl = URL.createObjectURL(workerBlob);
@@ -73,6 +73,7 @@ async function calculateHashes(
7373
const filePath = path.join(tempOutputDirPath, fileEntry.uuid);
7474

7575
let finishDataSize = 0;
76+
const rateMeterFile = new rateMeterUtils.RateMeter(1000 * rateMeterAvgFactor, true);
7677
const progBarSub =
7778
process.stdout.rows > queue.concurrency + 3
7879
? progBar?.create(
@@ -81,6 +82,7 @@ async function calculateHashes(
8182
termPrettyUtils.progBarTextFmter.download.sub(
8283
finishDataSize,
8384
fileEntry.size,
85+
rateMeterFile.getRate(),
8486
fileEntry.path.at(-1) ?? '',
8587
),
8688
{ format: termPrettyUtils.progBarFmtCfg.download.sub },
@@ -94,7 +96,12 @@ async function calculateHashes(
9496
const progBarUpdateFunc = (subCurrent: number) => {
9597
progBarSub?.update(
9698
subCurrent,
97-
termPrettyUtils.progBarTextFmter.download.sub(subCurrent, fileEntry.size, fileEntry.path.at(-1) ?? ''),
99+
termPrettyUtils.progBarTextFmter.download.sub(
100+
subCurrent,
101+
fileEntry.size,
102+
rateMeterFile.getRate(),
103+
fileEntry.path.at(-1) ?? '',
104+
),
98105
);
99106
const tmpRootPayload = termPrettyUtils.progBarTextFmter.download.root(
100107
results.length,
@@ -123,6 +130,7 @@ async function calculateHashes(
123130
finishDataSizeGlobal += data.chunk_size;
124131
finishDataSize += data.chunk_size;
125132
rateMeterInstRoot.increment(data.chunk_size);
133+
rateMeterFile.increment(data.chunk_size);
126134
progBarUpdateFunc(finishDataSize);
127135
break;
128136
case 'done':

0 commit comments

Comments
 (0)