Skip to content

Commit

Permalink
version 0.5.18 (#96)
Browse files Browse the repository at this point in the history
fix: startup works now with only a restore file, but no queue file

feature: mega-nz download full filepaths by default, but have a switch to ignore them

polish: have prettier use semicolon
  • Loading branch information
rlindner81 authored Oct 24, 2022
1 parent 7eb7ebb commit 20eed6b
Show file tree
Hide file tree
Showing 23 changed files with 590 additions and 524 deletions.
1 change: 0 additions & 1 deletion .prettierrc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
---
printWidth: 120
semi: false
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ options:
--retries NUMBER number of retries for failing downloads (defaults to 3)
--limit NUMBER bytes per second limit for download (defaults to 0, no limit)
--router TYPE router for ip refreshing, e.g. fritzbox
--flatten ignore directories
```

Expand Down
37 changes: 17 additions & 20 deletions bin/cli.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
#!/usr/bin/env node
"use strict"
"use strict";

const fs = require("fs")
const { promisify } = require("util")
const { versionText, usageText, parseArgs } = require("../src/args")
const { queue } = require("../src/")
const { versionText, usageText, parseArgs } = require("../src/args");
const { tryAccess } = require("../src/helper");
const { queue } = require("../src/");

const access = promisify(fs.access)

;(async () => {
let options
(async () => {
let options;
try {
options = await parseArgs(process.argv.slice(2))
options = await parseArgs(process.argv.slice(2));
} catch (err) {
console.error("error:", err.message)
return
console.error("error:", err.message);
return;
}

if (!options || options.help) {
return console.info(usageText())
return console.info(usageText());
}

if (options.version) {
return console.info(versionText())
return console.info(versionText());
}

try {
await access(options.queueFile)
} catch (err) {
return console.error(`error: could not access ${options.queueFile}`)
const queueFile = options.restoreFile || options.queueFile;
if (!(await tryAccess(queueFile))) {
return console.error(`error: could not access ${queueFile}`);
}
await queue(options)
})()

await queue(options);
})();
50 changes: 25 additions & 25 deletions bin/daemon.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
#!/usr/bin/env node
"use strict"
"use strict";

const fs = require("fs")
const path = require("path")
const { promisify } = require("util")
const { spawn, execSync } = require("child_process")
const fs = require("fs");
const path = require("path");
const { promisify } = require("util");
const { spawn, execSync } = require("child_process");

const open = promisify(fs.open)
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const open = promisify(fs.open);
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);

const PID_FILE = "qget.pid"
const LOG_FILE = "qget.txt"
const SCRIPT = path.join(__dirname, "cli.js")
const PID_FILE = "qget.pid";
const LOG_FILE = "qget.txt";
const SCRIPT = path.join(__dirname, "cli.js");

const _kill = (pid) => {
if (Number.isFinite(pid)) {
const killCommand = process.platform === "win32" ? `taskkill /f /pid ${pid}` : `kill ${pid}`
execSync(killCommand, { stdio: "ignore" })
const killCommand = process.platform === "win32" ? `taskkill /f /pid ${pid}` : `kill ${pid}`;
execSync(killCommand, { stdio: "ignore" });
}
}
};

;(async () => {
const [command] = process.argv.slice(2)
(async () => {
const [command] = process.argv.slice(2);
try {
const pid = parseFloat((await readFile(PID_FILE)).toString())
_kill(pid)
const pid = parseFloat((await readFile(PID_FILE)).toString());
_kill(pid);
// eslint-disable-next-line no-empty
} catch (err) {}
if (/(?:stop|kill)/gi.test(command)) {
console.log("stopping queueget")
process.exit(0)
console.log("stopping queueget");
process.exit(0);
}

const foutlog = await open(LOG_FILE, "w")
const foutlog = await open(LOG_FILE, "w");
const child = spawn(process.execPath, [SCRIPT].concat(process.argv.slice(2)), {
stdio: ["ignore", foutlog, foutlog],
detached: true,
})
await writeFile(PID_FILE, String(child.pid))
child.unref()
})()
});
await writeFile(PID_FILE, String(child.pid));
child.unref();
})();
4 changes: 2 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"use strict"
"use strict";

// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html
Expand Down Expand Up @@ -187,4 +187,4 @@ module.exports = {

// Whether to use watchman for file crawling
// watchman: true,
}
};
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "queueget",
"version": "0.5.17",
"version": "0.5.18",
"description": "Download links from a queue file",
"bin": {
"qget": "./bin/cli.js",
Expand All @@ -26,7 +26,7 @@
"devDependencies": {
"eslint": "8.20.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-jest": "26.6.0",
"eslint-plugin-jest": "26.7.0",
"jest": "28.1.3",
"prettier": "2.7.1"
},
Expand Down
93 changes: 49 additions & 44 deletions src/args.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict"
"use strict";

const { assert, ordinal } = require("./helper")
const { version } = require("../package.json")
const { assert, ordinal } = require("./helper");
const { version } = require("../package.json");

const usageText = () => `
usage: qget [<options>]
Expand All @@ -13,77 +13,82 @@ options:
--retries NUMBER number of retries for failing downloads (defaults to 3)
--limit NUMBER bytes per second limit for download (defaults to 0, no limit)
--router TYPE router for ip refreshing, e.g. fritzbox
`
--flatten ignore directories
`;

const versionText = () => `version ${version}`
const versionText = () => `version ${version}`;

const _unquoteArg = (arg) => {
return arg.replace(/^'(.+)'$/, "$1").replace(/^"(.+)"$/, "$1")
}
return arg.replace(/^'(.+)'$/, "$1").replace(/^"(.+)"$/, "$1");
};

const parseArgs = (args) => {
let queueFile = "queue.txt"
let historyFile = "queue_history.txt"
let restoreFile = null
let retries = 3
let limit = 0
let routername = null
let help = false
let version = false
let queueFile = "queue.txt";
let historyFile = "queue_history.txt";
let restoreFile = null;
let retries = 3;
let limit = 0;
let routername = null;
let help = false;
let version = false;
let flatten = false;

let parsedOptions = 0
let parsedOptions = 0;
const rest = args
.join(" ")
.trim()
.replace(
/--(help|version|queue|history|restore|retries|limit|router)\s*(.*?)\s*(?=$|--(?:help|version|queue|history|restore|retries|limit|router))/g,
/--(help|version|flatten|queue|history|restore|retries|limit|router)\s*(.*?)\s*(?=$|--(?:help|version|flatten|queue|history|restore|retries|limit|router))/g,
(_, option, arg) => {
const unquotedArg = _unquoteArg(arg)
parsedOptions++
const unquotedArg = _unquoteArg(arg);
parsedOptions++;

assert(
["version", "help"].includes(option) || unquotedArg.length !== 0,
["version", "help", "flatten"].includes(option) || unquotedArg.length !== 0,
`${ordinal(parsedOptions)} option --${option} has no associated argument`
)
);

switch (option) {
case "version":
version = true
break
version = true;
break;
case "help":
help = true
break
help = true;
break;
case "flatten":
flatten = true;
break;
case "queue":
queueFile = unquotedArg
break
queueFile = unquotedArg;
break;
case "history":
historyFile = unquotedArg
break
historyFile = unquotedArg;
break;
case "restore":
restoreFile = unquotedArg
break
restoreFile = unquotedArg;
break;
case "retries":
retries = parseFloat(unquotedArg)
break
retries = parseFloat(unquotedArg);
break;
case "limit":
limit = parseFloat(unquotedArg)
break
limit = parseFloat(unquotedArg);
break;
case "router":
routername = unquotedArg
break
routername = unquotedArg;
break;
default:
assert(false, `encountered unknown option --${option}`)
assert(false, `encountered unknown option --${option}`);
}
return ""
return "";
}
)
assert(rest.length === 0, `missed (partial) arguments '${rest}'`)
);
assert(rest.length === 0, `missed (partial) arguments '${rest}'`);

return { help, version, queueFile, historyFile, restoreFile, retries, limit, routername }
}
return { help, version, flatten, queueFile, historyFile, restoreFile, retries, limit, routername };
};

module.exports = {
versionText,
usageText,
parseArgs,
}
};
40 changes: 40 additions & 0 deletions src/datetime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"use strict";
const TIME_UNITS = Object.freeze({
YEAR: "year",
MONTH: "month",
DAY: "day",
HOUR: "hour",
MINUTE: "minute",
SECOND: "second",
});

const TIME_UNIT_LIMITS = {
[TIME_UNITS.YEAR]: 24 * 60 * 60 * 1000 * 365,
[TIME_UNITS.MONTH]: (24 * 60 * 60 * 1000 * 365) / 12,
[TIME_UNITS.DAY]: 24 * 60 * 60 * 1000,
[TIME_UNITS.HOUR]: 60 * 60 * 1000,
[TIME_UNITS.MINUTE]: 60 * 1000,
[TIME_UNITS.SECOND]: 1000,
};

const _getRelativeDateTime = (d1, d2) => {
let elapsed = d1 - d2;
const result = [];
for (const [unit, limit] of Object.entries(TIME_UNIT_LIMITS)) {
if (Math.abs(elapsed) > limit || unit === TIME_UNITS.SECOND) {
const diff = Math.trunc(elapsed / limit);
elapsed -= limit * diff;
result.push(`${diff} ${diff <= 1 ? unit : unit + "s"}`);
}
}
return result.join(" ");
};

const readableRelativeDateTime = (value, now = new Date()) => {
if (!value) return "";
return _getRelativeDateTime(value, now);
};

module.exports = {
readableRelativeDateTime,
};
Loading

0 comments on commit 20eed6b

Please sign in to comment.