pal-explorer-cli 0.4.12 → 0.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -149
- package/bin/pal.js +63 -2
- package/extensions/@palexplorer/analytics/extension.json +20 -1
- package/extensions/@palexplorer/analytics/index.js +19 -9
- package/extensions/@palexplorer/audit/extension.json +14 -0
- package/extensions/@palexplorer/auth-email/extension.json +15 -0
- package/extensions/@palexplorer/auth-oauth/extension.json +15 -0
- package/extensions/@palexplorer/chat/extension.json +14 -0
- package/extensions/@palexplorer/discovery/extension.json +17 -0
- package/extensions/@palexplorer/discovery/index.js +1 -1
- package/extensions/@palexplorer/email-notifications/extension.json +23 -0
- package/extensions/@palexplorer/groups/extension.json +15 -0
- package/extensions/@palexplorer/share-links/extension.json +15 -0
- package/extensions/@palexplorer/sync/extension.json +16 -0
- package/extensions/@palexplorer/user-mgmt/extension.json +15 -0
- package/lib/capabilities.js +24 -24
- package/lib/commands/analytics.js +175 -175
- package/lib/commands/api-keys.js +131 -131
- package/lib/commands/audit.js +235 -235
- package/lib/commands/auth.js +137 -137
- package/lib/commands/backup.js +76 -76
- package/lib/commands/billing.js +148 -148
- package/lib/commands/chat.js +217 -217
- package/lib/commands/cloud-backup.js +231 -231
- package/lib/commands/comment.js +99 -99
- package/lib/commands/completion.js +203 -203
- package/lib/commands/compliance.js +218 -218
- package/lib/commands/config.js +136 -136
- package/lib/commands/connect.js +44 -44
- package/lib/commands/dept.js +294 -294
- package/lib/commands/device.js +146 -146
- package/lib/commands/download.js +240 -226
- package/lib/commands/explorer.js +178 -178
- package/lib/commands/extension.js +1060 -970
- package/lib/commands/favorite.js +90 -90
- package/lib/commands/federation.js +270 -270
- package/lib/commands/file.js +533 -533
- package/lib/commands/group.js +271 -271
- package/lib/commands/gui-share.js +29 -29
- package/lib/commands/init.js +61 -61
- package/lib/commands/invite.js +59 -59
- package/lib/commands/list.js +58 -58
- package/lib/commands/log.js +116 -116
- package/lib/commands/nearby.js +108 -108
- package/lib/commands/network.js +251 -251
- package/lib/commands/notify.js +198 -198
- package/lib/commands/org.js +273 -273
- package/lib/commands/pal.js +403 -180
- package/lib/commands/permissions.js +216 -216
- package/lib/commands/pin.js +97 -97
- package/lib/commands/protocol.js +357 -357
- package/lib/commands/rbac.js +147 -147
- package/lib/commands/recover.js +36 -36
- package/lib/commands/register.js +171 -171
- package/lib/commands/relay.js +131 -131
- package/lib/commands/remote.js +368 -368
- package/lib/commands/revoke.js +50 -50
- package/lib/commands/scanner.js +280 -280
- package/lib/commands/schedule.js +344 -344
- package/lib/commands/scim.js +203 -203
- package/lib/commands/search.js +181 -181
- package/lib/commands/serve.js +438 -438
- package/lib/commands/server.js +350 -350
- package/lib/commands/share-link.js +199 -199
- package/lib/commands/share.js +336 -323
- package/lib/commands/sso.js +200 -200
- package/lib/commands/status.js +145 -145
- package/lib/commands/stream.js +562 -562
- package/lib/commands/su.js +187 -187
- package/lib/commands/sync.js +979 -979
- package/lib/commands/transfers.js +152 -152
- package/lib/commands/uninstall.js +188 -188
- package/lib/commands/update.js +204 -204
- package/lib/commands/user.js +276 -276
- package/lib/commands/vfs.js +84 -84
- package/lib/commands/web-login.js +79 -79
- package/lib/commands/web.js +52 -52
- package/lib/commands/webhook.js +180 -180
- package/lib/commands/whoami.js +59 -59
- package/lib/commands/workspace.js +121 -121
- package/lib/core/billing.js +16 -5
- package/lib/core/dhtDiscovery.js +9 -2
- package/lib/core/discoveryClient.js +13 -7
- package/lib/core/extensions.js +142 -1
- package/lib/core/identity.js +33 -2
- package/lib/core/imageProcessor.js +109 -0
- package/lib/core/imageTorrent.js +167 -0
- package/lib/core/permissions.js +1 -1
- package/lib/core/pro.js +11 -4
- package/lib/core/serverList.js +4 -1
- package/lib/core/shares.js +12 -1
- package/lib/core/signalingServer.js +14 -2
- package/lib/core/su.js +1 -1
- package/lib/core/users.js +1 -1
- package/lib/protocol/messages.js +12 -3
- package/lib/utils/explorer.js +1 -1
- package/lib/utils/help.js +357 -357
- package/lib/utils/torrent.js +1 -0
- package/package.json +4 -3
|
@@ -1,152 +1,152 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import Conf from 'conf';
|
|
5
|
-
import { removeTransfer, setTransferPaused, getTransferStats, pruneOldHistory } from '../core/transfers.js';
|
|
6
|
-
import config from '../utils/config.js';
|
|
7
|
-
|
|
8
|
-
const transferStore = new Conf({
|
|
9
|
-
projectName: 'palexplorer-cli',
|
|
10
|
-
configName: 'transfers',
|
|
11
|
-
defaults: { active: [], history: [] }
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
function formatProgress(t) {
|
|
15
|
-
const pct = t.progress ? `${(t.progress * 100).toFixed(1)}%` : '0%';
|
|
16
|
-
return pct;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function printActive(active) {
|
|
20
|
-
if (active.length === 0) {
|
|
21
|
-
console.log(chalk.gray('No active transfers. Use `
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
console.log('');
|
|
25
|
-
console.log(chalk.cyan('Active Transfers:'));
|
|
26
|
-
active.forEach(t => {
|
|
27
|
-
const status = t.paused ? chalk.yellow('paused') : chalk.blue('downloading');
|
|
28
|
-
const pct = formatProgress(t);
|
|
29
|
-
const name = t.name || 'Unknown';
|
|
30
|
-
const shortMagnet = t.magnet.slice(0, 40) + '...';
|
|
31
|
-
console.log(` ${chalk.white(name)} [${status}] ${pct}`);
|
|
32
|
-
console.log(` ${chalk.gray(t.savePath || '')} ${chalk.gray(shortMagnet)}`);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export default function transfersCommand(program) {
|
|
37
|
-
const cmd = program
|
|
38
|
-
.command('transfers')
|
|
39
|
-
.description('view and manage active file transfers')
|
|
40
|
-
.option('--history', 'Show completed transfers')
|
|
41
|
-
.addHelpText('after', `
|
|
42
|
-
Examples:
|
|
43
|
-
$
|
|
44
|
-
$
|
|
45
|
-
$
|
|
46
|
-
`)
|
|
47
|
-
.action((opts) => {
|
|
48
|
-
if (program.opts().json) {
|
|
49
|
-
const active = transferStore.get('active') || [];
|
|
50
|
-
const history = transferStore.get('history') || [];
|
|
51
|
-
console.log(JSON.stringify(opts.history ? { history } : { active }, null, 2));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (opts.history) {
|
|
55
|
-
const history = transferStore.get('history') || [];
|
|
56
|
-
if (history.length === 0) {
|
|
57
|
-
console.log(chalk.gray('No completed transfers.'));
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
console.log('');
|
|
61
|
-
console.log(chalk.cyan('Completed Transfers:'));
|
|
62
|
-
history.forEach(t => {
|
|
63
|
-
console.log(` ${chalk.white(t.name || 'Unknown')} ${chalk.green('✔ done')} ${chalk.gray(t.completedAt || '')}`);
|
|
64
|
-
console.log(` ${chalk.gray(t.savePath || '')}`);
|
|
65
|
-
});
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const active = transferStore.get('active') || [];
|
|
69
|
-
printActive(active);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
cmd
|
|
73
|
-
.command('cancel <magnet>')
|
|
74
|
-
.description('remove a transfer from tracking by its magnet URI')
|
|
75
|
-
.action((magnet) => {
|
|
76
|
-
removeTransfer(magnet);
|
|
77
|
-
console.log(chalk.green('✔ Transfer removed from tracking.'));
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
cmd
|
|
81
|
-
.command('pause <magnet>')
|
|
82
|
-
.description('pause a transfer')
|
|
83
|
-
.action((magnet) => {
|
|
84
|
-
const active = transferStore.get('active') || [];
|
|
85
|
-
const found = active.find(t => t.magnet === magnet);
|
|
86
|
-
if (!found) {
|
|
87
|
-
console.log(chalk.red('Transfer not found.'));
|
|
88
|
-
process.exitCode = 1; return;
|
|
89
|
-
}
|
|
90
|
-
if (found.paused) {
|
|
91
|
-
console.log(chalk.yellow('Transfer is already paused.'));
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
setTransferPaused(magnet, true);
|
|
95
|
-
console.log(chalk.green('✔ Transfer paused.'));
|
|
96
|
-
const pidPath = path.join(path.dirname(config.path), 'serve.pid');
|
|
97
|
-
if (fs.existsSync(pidPath)) {
|
|
98
|
-
console.log(chalk.yellow('Note: Restart `
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
cmd
|
|
103
|
-
.command('resume <magnet>')
|
|
104
|
-
.description('resume a paused transfer')
|
|
105
|
-
.action((magnet) => {
|
|
106
|
-
const active = transferStore.get('active') || [];
|
|
107
|
-
const found = active.find(t => t.magnet === magnet);
|
|
108
|
-
if (!found) {
|
|
109
|
-
console.log(chalk.red('Transfer not found.'));
|
|
110
|
-
process.exitCode = 1; return;
|
|
111
|
-
}
|
|
112
|
-
if (!found.paused) {
|
|
113
|
-
console.log(chalk.yellow('Transfer is not paused.'));
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
setTransferPaused(magnet, false);
|
|
117
|
-
console.log(chalk.green('✔ Transfer resumed.'));
|
|
118
|
-
const pidPath = path.join(path.dirname(config.path), 'serve.pid');
|
|
119
|
-
if (fs.existsSync(pidPath)) {
|
|
120
|
-
console.log(chalk.yellow('Note: Restart `
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
cmd
|
|
125
|
-
.command('stats')
|
|
126
|
-
.description('show transfer statistics')
|
|
127
|
-
.option('--days <n>', 'Number of days to include', '90')
|
|
128
|
-
.action((opts) => {
|
|
129
|
-
const days = parseInt(opts.days, 10) || 90;
|
|
130
|
-
pruneOldHistory(days);
|
|
131
|
-
const stats = getTransferStats(days);
|
|
132
|
-
console.log('');
|
|
133
|
-
console.log(chalk.cyan(`Transfer Stats (last ${days} days):`));
|
|
134
|
-
console.log(` Total transfers: ${chalk.white(stats.totalTransfers)}`);
|
|
135
|
-
console.log(` Total data: ${chalk.white(formatBytes(stats.totalBytes))}`);
|
|
136
|
-
console.log(` Avg speed: ${chalk.white(formatBytes(stats.avgSpeed) + '/s')}`);
|
|
137
|
-
if (Object.keys(stats.perDay).length > 0) {
|
|
138
|
-
console.log('');
|
|
139
|
-
console.log(chalk.cyan(' Per day:'));
|
|
140
|
-
for (const [day, count] of Object.entries(stats.perDay).sort()) {
|
|
141
|
-
console.log(` ${day}: ${count} transfer(s)`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function formatBytes(bytes) {
|
|
148
|
-
if (bytes === 0) return '0 B';
|
|
149
|
-
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
150
|
-
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
151
|
-
return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${units[i]}`;
|
|
152
|
-
}
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import Conf from 'conf';
|
|
5
|
+
import { removeTransfer, setTransferPaused, getTransferStats, pruneOldHistory } from '../core/transfers.js';
|
|
6
|
+
import config from '../utils/config.js';
|
|
7
|
+
|
|
8
|
+
const transferStore = new Conf({
|
|
9
|
+
projectName: 'palexplorer-cli',
|
|
10
|
+
configName: 'transfers',
|
|
11
|
+
defaults: { active: [], history: [] }
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
function formatProgress(t) {
|
|
15
|
+
const pct = t.progress ? `${(t.progress * 100).toFixed(1)}%` : '0%';
|
|
16
|
+
return pct;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function printActive(active) {
|
|
20
|
+
if (active.length === 0) {
|
|
21
|
+
console.log(chalk.gray('No active transfers. Use `pal download <magnet>` to start one.'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.log('');
|
|
25
|
+
console.log(chalk.cyan('Active Transfers:'));
|
|
26
|
+
active.forEach(t => {
|
|
27
|
+
const status = t.paused ? chalk.yellow('paused') : chalk.blue('downloading');
|
|
28
|
+
const pct = formatProgress(t);
|
|
29
|
+
const name = t.name || 'Unknown';
|
|
30
|
+
const shortMagnet = t.magnet.slice(0, 40) + '...';
|
|
31
|
+
console.log(` ${chalk.white(name)} [${status}] ${pct}`);
|
|
32
|
+
console.log(` ${chalk.gray(t.savePath || '')} ${chalk.gray(shortMagnet)}`);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default function transfersCommand(program) {
|
|
37
|
+
const cmd = program
|
|
38
|
+
.command('transfers')
|
|
39
|
+
.description('view and manage active file transfers')
|
|
40
|
+
.option('--history', 'Show completed transfers')
|
|
41
|
+
.addHelpText('after', `
|
|
42
|
+
Examples:
|
|
43
|
+
$ pal transfers Show active transfers
|
|
44
|
+
$ pal transfers --history Show completed transfers
|
|
45
|
+
$ pal transfers cancel <magnet> Cancel a transfer
|
|
46
|
+
`)
|
|
47
|
+
.action((opts) => {
|
|
48
|
+
if (program.opts().json) {
|
|
49
|
+
const active = transferStore.get('active') || [];
|
|
50
|
+
const history = transferStore.get('history') || [];
|
|
51
|
+
console.log(JSON.stringify(opts.history ? { history } : { active }, null, 2));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (opts.history) {
|
|
55
|
+
const history = transferStore.get('history') || [];
|
|
56
|
+
if (history.length === 0) {
|
|
57
|
+
console.log(chalk.gray('No completed transfers.'));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
console.log('');
|
|
61
|
+
console.log(chalk.cyan('Completed Transfers:'));
|
|
62
|
+
history.forEach(t => {
|
|
63
|
+
console.log(` ${chalk.white(t.name || 'Unknown')} ${chalk.green('✔ done')} ${chalk.gray(t.completedAt || '')}`);
|
|
64
|
+
console.log(` ${chalk.gray(t.savePath || '')}`);
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const active = transferStore.get('active') || [];
|
|
69
|
+
printActive(active);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
cmd
|
|
73
|
+
.command('cancel <magnet>')
|
|
74
|
+
.description('remove a transfer from tracking by its magnet URI')
|
|
75
|
+
.action((magnet) => {
|
|
76
|
+
removeTransfer(magnet);
|
|
77
|
+
console.log(chalk.green('✔ Transfer removed from tracking.'));
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
cmd
|
|
81
|
+
.command('pause <magnet>')
|
|
82
|
+
.description('pause a transfer')
|
|
83
|
+
.action((magnet) => {
|
|
84
|
+
const active = transferStore.get('active') || [];
|
|
85
|
+
const found = active.find(t => t.magnet === magnet);
|
|
86
|
+
if (!found) {
|
|
87
|
+
console.log(chalk.red('Transfer not found.'));
|
|
88
|
+
process.exitCode = 1; return;
|
|
89
|
+
}
|
|
90
|
+
if (found.paused) {
|
|
91
|
+
console.log(chalk.yellow('Transfer is already paused.'));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
setTransferPaused(magnet, true);
|
|
95
|
+
console.log(chalk.green('✔ Transfer paused.'));
|
|
96
|
+
const pidPath = path.join(path.dirname(config.path), 'serve.pid');
|
|
97
|
+
if (fs.existsSync(pidPath)) {
|
|
98
|
+
console.log(chalk.yellow('Note: Restart `pal serve` for the change to take effect on the running daemon.'));
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
cmd
|
|
103
|
+
.command('resume <magnet>')
|
|
104
|
+
.description('resume a paused transfer')
|
|
105
|
+
.action((magnet) => {
|
|
106
|
+
const active = transferStore.get('active') || [];
|
|
107
|
+
const found = active.find(t => t.magnet === magnet);
|
|
108
|
+
if (!found) {
|
|
109
|
+
console.log(chalk.red('Transfer not found.'));
|
|
110
|
+
process.exitCode = 1; return;
|
|
111
|
+
}
|
|
112
|
+
if (!found.paused) {
|
|
113
|
+
console.log(chalk.yellow('Transfer is not paused.'));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
setTransferPaused(magnet, false);
|
|
117
|
+
console.log(chalk.green('✔ Transfer resumed.'));
|
|
118
|
+
const pidPath = path.join(path.dirname(config.path), 'serve.pid');
|
|
119
|
+
if (fs.existsSync(pidPath)) {
|
|
120
|
+
console.log(chalk.yellow('Note: Restart `pal serve` for the change to take effect on the running daemon.'));
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
cmd
|
|
125
|
+
.command('stats')
|
|
126
|
+
.description('show transfer statistics')
|
|
127
|
+
.option('--days <n>', 'Number of days to include', '90')
|
|
128
|
+
.action((opts) => {
|
|
129
|
+
const days = parseInt(opts.days, 10) || 90;
|
|
130
|
+
pruneOldHistory(days);
|
|
131
|
+
const stats = getTransferStats(days);
|
|
132
|
+
console.log('');
|
|
133
|
+
console.log(chalk.cyan(`Transfer Stats (last ${days} days):`));
|
|
134
|
+
console.log(` Total transfers: ${chalk.white(stats.totalTransfers)}`);
|
|
135
|
+
console.log(` Total data: ${chalk.white(formatBytes(stats.totalBytes))}`);
|
|
136
|
+
console.log(` Avg speed: ${chalk.white(formatBytes(stats.avgSpeed) + '/s')}`);
|
|
137
|
+
if (Object.keys(stats.perDay).length > 0) {
|
|
138
|
+
console.log('');
|
|
139
|
+
console.log(chalk.cyan(' Per day:'));
|
|
140
|
+
for (const [day, count] of Object.entries(stats.perDay).sort()) {
|
|
141
|
+
console.log(` ${day}: ${count} transfer(s)`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function formatBytes(bytes) {
|
|
148
|
+
if (bytes === 0) return '0 B';
|
|
149
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
150
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
151
|
+
return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${units[i]}`;
|
|
152
|
+
}
|