admin/monitoring: show browsing activity
Massimo Melina committed
Nov 7, 2023 at 16:58 UTC
5e9f023c8178ef9cfd5ad6fb95a81b891b17d310
5 files changed
+21
-8
admin/src/MonitorPage.ts
+5
-3
@@ -4,7 +4,7 @@ import _ from "lodash"
4
import { createElement as h, useMemo, Fragment, useState } from "react"
5
import { apiCall, useApiEvents, useApiEx, useApiList } from "./api"
6
import { PauseCircle, PlayCircle, LinkOff, Lock, Block, FolderZip, Upload, Download } from '@mui/icons-material'
7
-import { Alert, Box, Chip, ChipProps } from '@mui/material'
7
+import { Box, Chip, ChipProps } from '@mui/material'
8
import { DataTable } from './DataTable'
9
import { formatBytes, IconBtn, IconProgress, iconTooltip, ipForUrl, manipulateConfig, useBreakpoint } from "./misc"
10
import { Field, SelectField } from '@hfs/mui-grid-form'
@@ -85,7 +85,7 @@ function Connections() {
85
const [filtered, setFiltered] = useState(true)
86
const [paused, setPaused] = useState(false)
87
const rows = useMemo(() =>
88
- list?.filter((x: any) => !filtered || x.path).map((x: any, id: number) => ({ id, ...x })),
88
+ list?.filter((x: any) => !filtered || x.op).map((x: any, id: number) => ({ id, ...x })),
89
[!paused && list, filtered]) //eslint-disable-line
90
return h(Fragment, {},
91
h(Box, { display: 'flex', alignItems: 'center' },
@@ -144,9 +144,11 @@ function Connections() {
144
row.archive,
145
h(Box, { ml: 2, color: 'text.secondary' }, value)
146
)
147
+ if (!row.op)
148
+ return h(Box, {}, value, h(Box, { fontSize: 'x-small' }, "browsing"))
149
const i = value?.lastIndexOf('/')
150
return h(Fragment, {},
149
- row.op && h(IconProgress, {
151
+ h(IconProgress, {
152
icon: row.op === 'upload' ? Upload : Download,
153
progress: row.opProgress ?? row.opOffset,
154
offset: row.opOffset,
src/api.file_list.ts
+3
@@ -10,6 +10,7 @@ import { HTTP_FOOL, HTTP_METHOD_NOT_ALLOWED, HTTP_NOT_FOUND } from './const'
10
import Koa from 'koa'
11
import { descriptIon, DESCRIPT_ION, getCommentFor, areCommentsEnabled } from './comments'
12
import { basename } from 'path'
13
+import { getConnection, updateConnection } from './connections'
14
15
export interface DirEntry { n:string, s?:number, m?:Date, c?:Date, p?: string, comment?: string, web?: boolean, url?: string }
16
@@ -38,6 +39,8 @@ export const get_file_list: ApiHandler = async ({ uri, offset, limit, search, c
39
if (!list)
40
return { ...props, list: await asyncGeneratorToArray(produceEntries()) }
41
setTimeout(async () => {
42
+ ctx.state.browsing = uri
43
+ updateConnection(getConnection(ctx)!, { ctx })
44
list.props(props)
45
for await (const entry of produceEntries())
46
list.add(entry)
src/api.monitor.ts
+6
-3
@@ -80,13 +80,16 @@ const apis: ApiHandlers = {
80
}
81
82
function fromCtx(ctx?: Koa.Context) {
83
- return ctx && {
83
+ if (!ctx) return
84
+ const path = ctx.state.browsing && decodeURIComponent(ctx.state.browsing)
85
+ || ctx.state.uploadPath && decodeURIComponent(ctx.state.uploadPath)
86
+ || (ctx.fileSource || ctx.state.archive) && decodeURIComponent(ctx.path) // downloads
87
+ return {
88
user: getCurrentUsername(ctx),
89
agent: getBrowser(ctx.get('user-agent')),
90
archive: ctx.state.archive,
91
upload: ctx.state.uploadProgress,
88
- path: ctx.state.uploadPath && decodeURIComponent(ctx.state.uploadPath)
89
- || (ctx.fileSource || ctx.state.archive) && decodeURIComponent(ctx.path) // only uploads and downloads
92
+ ...path && { path },
93
}
94
}
95
},
src/connections.ts
+6
-2
@@ -2,7 +2,7 @@
2
3
import { Socket } from 'net'
4
import events from './events'
5
-import Koa from 'koa'
5
+import { Context } from 'koa'
6
import _ from 'lodash'
7
8
export class Connection {
@@ -15,7 +15,7 @@ export class Connection {
15
opTotal?: number
16
opProgress?: number
17
opOffset?: number
18
- ctx?: Koa.Context
18
+ ctx?: Context
19
private _cachedIp?: string
20
[rest:symbol]: any // let other modules add extra data, but using symbols to avoid name collision
21
@@ -57,6 +57,10 @@ export function socket2connection(socket: Socket) {
57
&& x.socket.remoteAddress === socket.remoteAddress )
58
}
59
60
+export function getConnection(ctx: Context) {
61
+ return _.find(all, { ctx })
62
+}
63
+
64
export function updateConnection(conn: Connection, change: Partial<Connection>) {
65
if (change.op)
66
change.opProgress ??= change.opOffset || 0
src/middlewares.ts
+1
@@ -217,6 +217,7 @@ export const prepareState: Koa.Middleware = async (ctx, next) => {
217
ctx.state.account = undefined
218
const conn = ctx.state.connection = socket2connection(ctx.socket)
219
ctx.state.revProxyPath = ctx.get('x-forwarded-prefix')
220
+ ctx.state.browsing = undefined
221
if (conn)
222
updateConnection(conn, { ctx, op: undefined })
223
await next()