2024-04-25 14:50:42 +02:00
|
|
|
import { readable } from "svelte/store";
|
|
|
|
|
2025-03-27 12:52:45 +01:00
|
|
|
type SocketResults = {
|
|
|
|
connected: boolean,
|
|
|
|
file_stats_init: boolean,
|
|
|
|
file_stats: FileStats
|
|
|
|
limits_init: boolean,
|
|
|
|
limits: Limits,
|
|
|
|
}
|
|
|
|
|
|
|
|
type FileStats = {
|
|
|
|
views: number,
|
|
|
|
downloads: number,
|
|
|
|
bandwidth: number,
|
|
|
|
bandwidth_paid: number,
|
|
|
|
}
|
|
|
|
|
|
|
|
type Limits = {
|
|
|
|
server_overload: boolean,
|
|
|
|
speed_limit: number,
|
|
|
|
download_limit: number,
|
|
|
|
download_limit_used: number,
|
|
|
|
transfer_limit: number,
|
|
|
|
transfer_limit_used: number,
|
|
|
|
}
|
|
|
|
|
|
|
|
type SocketCommand = {
|
|
|
|
type: string,
|
|
|
|
data?: Object,
|
2024-04-25 14:50:42 +02:00
|
|
|
}
|
|
|
|
|
2025-03-27 12:52:45 +01:00
|
|
|
let results: SocketResults = {
|
|
|
|
file_stats: {} as FileStats,
|
|
|
|
limits: {} as Limits,
|
|
|
|
} as SocketResults
|
|
|
|
|
2024-04-25 14:50:42 +02:00
|
|
|
export const stats = readable(
|
|
|
|
results,
|
|
|
|
(set) => {
|
|
|
|
start_sock(set)
|
2024-04-28 18:49:29 +02:00
|
|
|
return () => stop_sock(set)
|
2024-04-25 14:50:42 +02:00
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2025-03-27 12:52:45 +01:00
|
|
|
let socket: WebSocket = null
|
|
|
|
const start_sock = (set_func: (value: SocketResults) => void) => {
|
2024-04-25 14:50:42 +02:00
|
|
|
if (socket !== null) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2025-03-27 12:52:45 +01:00
|
|
|
console.log("Initializing stats socket")
|
2024-04-25 14:50:42 +02:00
|
|
|
socket = new WebSocket(location.origin.replace(/^http/, 'ws') + "/api/file_stats")
|
|
|
|
|
|
|
|
socket.onopen = () => {
|
|
|
|
results.connected = true
|
2025-03-27 12:52:45 +01:00
|
|
|
// set_func(results)
|
2024-04-25 14:50:42 +02:00
|
|
|
|
|
|
|
// Subscribe to the rate limit feed. This will also process any queued
|
|
|
|
// commands built up while the socket was down
|
|
|
|
send_cmd({ type: "limits" })
|
|
|
|
}
|
2025-03-27 12:52:45 +01:00
|
|
|
socket.onmessage = (msg: MessageEvent) => {
|
2024-04-25 14:50:42 +02:00
|
|
|
let j = JSON.parse(msg.data)
|
|
|
|
console.debug("WS update", j)
|
|
|
|
|
|
|
|
if (j.type === "file_stats") {
|
|
|
|
results.file_stats = j.file_stats
|
|
|
|
results.file_stats_init = true
|
|
|
|
set_func(results)
|
|
|
|
} else if (j.type === "limits") {
|
|
|
|
results.limits = j.limits
|
|
|
|
results.limits_init = true
|
|
|
|
set_func(results)
|
|
|
|
} else {
|
|
|
|
console.error("Unknown ws message type", j.type, "data", msg.data)
|
|
|
|
}
|
|
|
|
}
|
2025-03-27 12:52:45 +01:00
|
|
|
socket.onerror = (err: Event) => {
|
|
|
|
console.error("Stats socket error", err)
|
2024-04-25 14:50:42 +02:00
|
|
|
stop_sock(set_func)
|
|
|
|
window.setTimeout(() => start_sock(set_func), 2000)
|
|
|
|
}
|
2025-03-27 12:52:45 +01:00
|
|
|
socket.onclose = (e: CloseEvent) => {
|
|
|
|
console.debug("Stats socket close", e)
|
2024-04-25 14:50:42 +02:00
|
|
|
stop_sock(set_func)
|
|
|
|
window.setTimeout(() => start_sock(set_func), 2000)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-03-27 12:52:45 +01:00
|
|
|
const stop_sock = (set_func: (value: SocketResults) => void) => {
|
2024-04-25 14:50:42 +02:00
|
|
|
if (socket === null) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prevent error handlers from re-initializing the socket
|
|
|
|
socket.onerror = null
|
|
|
|
socket.onclose = null
|
|
|
|
|
|
|
|
// Close and delete the socket
|
|
|
|
socket.close()
|
|
|
|
socket = null
|
|
|
|
|
|
|
|
// Reset the state
|
|
|
|
results.connected = false
|
|
|
|
results.file_stats_init = false
|
|
|
|
results.limits_init = false
|
|
|
|
set_func(results)
|
|
|
|
}
|
|
|
|
|
2025-03-27 12:52:45 +01:00
|
|
|
|
|
|
|
export const set_file = (file_id: string) => {
|
2024-04-25 14:50:42 +02:00
|
|
|
send_cmd({
|
|
|
|
type: "file_stats",
|
|
|
|
data: { file_id: file_id },
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
let queued_commands = []
|
2025-03-27 12:52:45 +01:00
|
|
|
const send_cmd = (cmd: SocketCommand) => {
|
2024-04-25 14:50:42 +02:00
|
|
|
if (socket !== null && socket.readyState === WebSocket.OPEN) {
|
|
|
|
|
|
|
|
// First empty the queue
|
|
|
|
while (queued_commands.length !== 0) {
|
|
|
|
socket.send(JSON.stringify(queued_commands.shift()))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send the requested command
|
|
|
|
socket.send(JSON.stringify(cmd))
|
|
|
|
} else if (cmd !== null) {
|
|
|
|
queued_commands.push(cmd)
|
|
|
|
console.debug("Socket is closed, command", cmd, "added to queue")
|
|
|
|
}
|
|
|
|
}
|