show active downloads/uploads in command "status"
Massimo Melina committed
Apr 16, 2026 at 14:23 UTC
12d60a37af6ba31621982773a20a19926f35d038
2 files changed
+21
-12
src/api.monitor.ts
+17
-11
@@ -72,20 +72,10 @@ export default {
72
73
function fromCtx(ctx?: Koa.Context) {
74
if (!ctx) return
75
- const s = ctx.state // short alias
75
return {
76
user: getCurrentUsername(ctx),
77
agent: shortenAgent(ctx.get('user-agent')),
79
- archive: s.archive,
80
- ...s.browsing ? { op: 'browsing', path: safeDecodeURIComponent(s.browsing) }
81
- : s.uploadPath ? { op: 'upload', path: safeDecodeURIComponent(s.uploadPath) }
82
- : {
83
- op: !s.considerAsGui && (ctx.state.archive || ctx.state.vfsNode) ? 'download' : undefined,
84
- path: safeDecodeURIComponent(ctx.originalUrl),
85
- },
86
- opProgress: _.isNumber(s.opProgress) ? _.round(s.opProgress, 3) : undefined,
87
- opTotal: s.opTotal,
88
- opOffset: s.opOffset,
78
+ ...inferOperation(ctx)
79
}
80
}
81
},
@@ -117,6 +107,22 @@ function ignore(conn: Connection) {
107
return false //conn.socket && isLocalHost(conn)
108
}
109
110
+export function inferOperation(ctx: Koa.Context) {
111
+ const s = ctx.state // short alias
112
+ return {
113
+ archive: s.archive,
114
+ ...s.browsing ? { op: 'browsing', path: safeDecodeURIComponent(s.browsing) }
115
+ : s.uploadPath ? { op: 'upload', path: safeDecodeURIComponent(s.uploadPath) }
116
+ : {
117
+ op: !s.considerAsGui && (ctx.state.archive || ctx.state.vfsNode) ? 'download' : undefined,
118
+ path: safeDecodeURIComponent(ctx.originalUrl),
119
+ },
120
+ opProgress: _.isNumber(s.opProgress) ? _.round(s.opProgress, 3) : undefined,
121
+ opTotal: s.opTotal,
122
+ opOffset: s.opOffset,
123
+ }
124
+}
125
+
126
function getConnAddress(conn: Connection, overrideIp?: string) {
127
return {
128
ip: overrideIp ?? conn.ip,
src/commands.ts
+4
-1
@@ -13,7 +13,8 @@ import { getInactivePlugins, mapPlugins, startPlugin, stopPlugin } from './plugi
13
import { purgeFileAttr } from './fileAttr'
14
import { downloadPlugin } from './github'
15
import { Dict, formatBytes, formatSpeed, formatTimestamp, makeMatcher } from './cross'
16
-import apiMonitor from './api.monitor'
16
+import apiMonitor, { inferOperation } from './api.monitor'
17
+import { getConnections } from './connections'
18
import { argv } from './argv'
19
import { getServerStatus } from './listen'
20
@@ -197,6 +198,8 @@ const commands = {
198
console.log(_.map(ports, (x, k) =>
199
`${k.toUpperCase()} ${x.configuredPort < 0 ? "disabled" : x.listening ? `on port ${x.port}` : (x.error || "not working")}`
200
).join(" – "))
201
+ const operations = _.countBy(getConnections(), x => x.ctx && inferOperation(x.ctx).op)
202
+ console.log(`Active downloads ↑ ${operations.download || 0} – uploads ↓ ${operations.upload || 0}`)
203
const conn = (await apiMonitor.get_connection_stats().next()).value
204
if (conn) {
205
const {sent_got: sg} = conn