Update config.json and workspace context as of 27. Dezember 2025
This commit is contained in:
parent
4780f68a23
commit
803f35ef39
BIN
data/aniworld.db-shm
Normal file
BIN
data/aniworld.db-shm
Normal file
Binary file not shown.
0
data/aniworld.db-wal
Normal file
0
data/aniworld.db-wal
Normal file
@ -17,7 +17,7 @@
|
|||||||
"keep_days": 30
|
"keep_days": 30
|
||||||
},
|
},
|
||||||
"other": {
|
"other": {
|
||||||
"master_password_hash": "$pbkdf2-sha256$29000$aq3VOsfY21sLwfgfQwghJA$d33KHoETVV5.zpCfR.BqM.ICe.DwjDcfATrsrsZ/3yM",
|
"master_password_hash": "$pbkdf2-sha256$29000$LkUohZASQmgthdD6n9Nayw$6VmJzv/pYSdyW7..eU57P.YJpjK/6fXvXvef0L6PLDg",
|
||||||
"anime_directory": "/mnt/server/serien/Serien/"
|
"anime_directory": "/mnt/server/serien/Serien/"
|
||||||
},
|
},
|
||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* AniWorld - WebSocket Client Module
|
* AniWorld - WebSocket Client Module
|
||||||
*
|
*
|
||||||
* WebSocket connection management and event handling.
|
* Native WebSocket connection management with Socket.IO-style interface.
|
||||||
|
* Uses FastAPI native WebSocket backend with room-based messaging.
|
||||||
*
|
*
|
||||||
* Dependencies: constants.js
|
* Dependencies: constants.js
|
||||||
*/
|
*/
|
||||||
@ -13,9 +14,24 @@ AniWorld.WebSocketClient = (function() {
|
|||||||
|
|
||||||
const WS_EVENTS = AniWorld.Constants.WS_EVENTS;
|
const WS_EVENTS = AniWorld.Constants.WS_EVENTS;
|
||||||
|
|
||||||
let socket = null;
|
let ws = null;
|
||||||
let isConnected = false;
|
let isConnected = false;
|
||||||
let eventHandlers = {};
|
let eventHandlers = {};
|
||||||
|
let rooms = new Set();
|
||||||
|
let messageQueue = [];
|
||||||
|
let reconnectAttempts = 0;
|
||||||
|
const maxReconnectAttempts = 5;
|
||||||
|
const reconnectDelay = 1000;
|
||||||
|
let autoReconnect = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get WebSocket URL based on current page URL
|
||||||
|
*/
|
||||||
|
function getWebSocketUrl() {
|
||||||
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
|
const host = window.location.host;
|
||||||
|
return protocol + '//' + host + '/ws/connect';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize WebSocket connection
|
* Initialize WebSocket connection
|
||||||
@ -25,62 +41,181 @@ AniWorld.WebSocketClient = (function() {
|
|||||||
handlers = handlers || {};
|
handlers = handlers || {};
|
||||||
eventHandlers = handlers;
|
eventHandlers = handlers;
|
||||||
|
|
||||||
// Check if Socket.IO is available
|
connect();
|
||||||
if (typeof io === 'undefined') {
|
}
|
||||||
console.error('Socket.IO not loaded');
|
|
||||||
|
/**
|
||||||
|
* Connect to WebSocket server
|
||||||
|
*/
|
||||||
|
function connect() {
|
||||||
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
console.log('WebSocket already connected');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket = io();
|
try {
|
||||||
|
const url = getWebSocketUrl();
|
||||||
|
console.log('Connecting to WebSocket:', url);
|
||||||
|
ws = new WebSocket(url);
|
||||||
|
|
||||||
// Handle connection events
|
ws.onopen = function() {
|
||||||
socket.on('connected', function(data) {
|
console.log('WebSocket connected');
|
||||||
console.log('WebSocket connection confirmed', data);
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on('connect', function() {
|
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
console.log('Connected to server');
|
reconnectAttempts = 0;
|
||||||
|
|
||||||
// Subscribe to rooms
|
// Emit connect event to handlers
|
||||||
if (socket.join) {
|
emitToHandlers('connect');
|
||||||
socket.join('scan');
|
|
||||||
socket.join('downloads');
|
// Join default rooms for this application
|
||||||
socket.join('queue');
|
joinRoom('scan');
|
||||||
}
|
joinRoom('downloads');
|
||||||
|
joinRoom('queue');
|
||||||
|
|
||||||
|
// Rejoin any previously joined rooms
|
||||||
|
rejoinRooms();
|
||||||
|
|
||||||
|
// Process queued messages
|
||||||
|
processMessageQueue();
|
||||||
|
|
||||||
// Call custom connect handler if provided
|
// Call custom connect handler if provided
|
||||||
if (eventHandlers.onConnect) {
|
if (eventHandlers.onConnect) {
|
||||||
eventHandlers.onConnect();
|
eventHandlers.onConnect();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
socket.on('disconnect', function() {
|
ws.onmessage = function(event) {
|
||||||
|
handleMessage(event.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onerror = function(error) {
|
||||||
|
console.error('WebSocket error:', error);
|
||||||
|
emitToHandlers('error', { error: 'WebSocket connection error' });
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onclose = function(event) {
|
||||||
|
console.log('WebSocket disconnected', event.code, event.reason);
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
console.log('Disconnected from server');
|
emitToHandlers('disconnect', { code: event.code, reason: event.reason });
|
||||||
|
|
||||||
// Call custom disconnect handler if provided
|
// Call custom disconnect handler if provided
|
||||||
if (eventHandlers.onDisconnect) {
|
if (eventHandlers.onDisconnect) {
|
||||||
eventHandlers.onDisconnect();
|
eventHandlers.onDisconnect();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Set up event handlers for common events
|
// Attempt reconnection
|
||||||
setupDefaultHandlers();
|
if (autoReconnect && reconnectAttempts < maxReconnectAttempts) {
|
||||||
|
reconnectAttempts++;
|
||||||
|
var delay = reconnectDelay * reconnectAttempts;
|
||||||
|
console.log('Attempting reconnection in ' + delay + 'ms (attempt ' + reconnectAttempts + ')');
|
||||||
|
setTimeout(connect, delay);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to create WebSocket connection:', error);
|
||||||
|
emitToHandlers('error', { error: 'Failed to connect' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up default event handlers
|
* Handle incoming WebSocket message
|
||||||
|
* @param {string} data - Raw message data
|
||||||
*/
|
*/
|
||||||
function setupDefaultHandlers() {
|
function handleMessage(data) {
|
||||||
if (!socket) return;
|
try {
|
||||||
|
var message = JSON.parse(data);
|
||||||
|
var type = message.type;
|
||||||
|
var payload = message.data;
|
||||||
|
|
||||||
// Register any events that have handlers
|
console.log('WebSocket message: type=' + type, payload);
|
||||||
Object.keys(eventHandlers).forEach(function(eventName) {
|
|
||||||
if (eventName !== 'onConnect' && eventName !== 'onDisconnect') {
|
// Emit event to registered handlers
|
||||||
socket.on(eventName, eventHandlers[eventName]);
|
if (type) {
|
||||||
|
emitToHandlers(type, payload || {});
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to parse WebSocket message:', error, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit event to registered handlers (internal)
|
||||||
|
* @param {string} event - Event name
|
||||||
|
* @param {*} data - Event data
|
||||||
|
*/
|
||||||
|
function emitToHandlers(event, data) {
|
||||||
|
if (eventHandlers[event]) {
|
||||||
|
try {
|
||||||
|
if (data !== undefined) {
|
||||||
|
eventHandlers[event](data);
|
||||||
|
} else {
|
||||||
|
eventHandlers[event]();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error in event handler for ' + event + ':', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message to server
|
||||||
|
* @param {string} action - Action type
|
||||||
|
* @param {Object} data - Data payload
|
||||||
|
*/
|
||||||
|
function send(action, data) {
|
||||||
|
var message = JSON.stringify({
|
||||||
|
action: action,
|
||||||
|
data: data || {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (isConnected && ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
ws.send(message);
|
||||||
|
} else {
|
||||||
|
console.warn('WebSocket not connected, queueing message');
|
||||||
|
messageQueue.push(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Join a room (subscribe to topic)
|
||||||
|
* @param {string} room - Room name
|
||||||
|
*/
|
||||||
|
function joinRoom(room) {
|
||||||
|
rooms.add(room);
|
||||||
|
if (isConnected) {
|
||||||
|
send('join', { room: room });
|
||||||
|
console.log('Joined room:', room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leave a room (unsubscribe from topic)
|
||||||
|
* @param {string} room - Room name
|
||||||
|
*/
|
||||||
|
function leaveRoom(room) {
|
||||||
|
rooms.delete(room);
|
||||||
|
if (isConnected) {
|
||||||
|
send('leave', { room: room });
|
||||||
|
console.log('Left room:', room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rejoin all rooms after reconnection
|
||||||
|
*/
|
||||||
|
function rejoinRooms() {
|
||||||
|
rooms.forEach(function(room) {
|
||||||
|
send('join', { room: room });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process queued messages after connection
|
||||||
|
*/
|
||||||
|
function processMessageQueue() {
|
||||||
|
while (messageQueue.length > 0 && isConnected) {
|
||||||
|
var message = messageQueue.shift();
|
||||||
|
ws.send(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,14 +224,7 @@ AniWorld.WebSocketClient = (function() {
|
|||||||
* @param {Function} handler - The handler function
|
* @param {Function} handler - The handler function
|
||||||
*/
|
*/
|
||||||
function on(eventName, handler) {
|
function on(eventName, handler) {
|
||||||
if (!socket) {
|
|
||||||
console.warn('Socket not initialized');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
eventHandlers[eventName] = handler;
|
eventHandlers[eventName] = handler;
|
||||||
socket.off(eventName); // Remove existing handler
|
|
||||||
socket.on(eventName, handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,24 +232,20 @@ AniWorld.WebSocketClient = (function() {
|
|||||||
* @param {string} eventName - The event name
|
* @param {string} eventName - The event name
|
||||||
*/
|
*/
|
||||||
function off(eventName) {
|
function off(eventName) {
|
||||||
if (!socket) return;
|
|
||||||
|
|
||||||
delete eventHandlers[eventName];
|
delete eventHandlers[eventName];
|
||||||
socket.off(eventName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emit an event to the server
|
* Emit an event to the server (Socket.IO compatibility)
|
||||||
* @param {string} eventName - The event name
|
* @param {string} eventName - The event name
|
||||||
* @param {*} data - The data to send
|
* @param {*} data - The data to send
|
||||||
*/
|
*/
|
||||||
function emit(eventName, data) {
|
function emit(eventName, data) {
|
||||||
if (!socket || !isConnected) {
|
if (!isConnected) {
|
||||||
console.warn('Socket not connected');
|
console.warn('WebSocket not connected');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
send(eventName, data);
|
||||||
socket.emit(eventName, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,20 +257,29 @@ AniWorld.WebSocketClient = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the socket instance
|
* Get the WebSocket instance (for compatibility)
|
||||||
* @returns {Object} The Socket.IO socket instance
|
* @returns {Object} The WebSocket instance wrapped with event methods
|
||||||
*/
|
*/
|
||||||
function getSocket() {
|
function getSocket() {
|
||||||
return socket;
|
// Return a wrapper object that provides Socket.IO-like interface
|
||||||
|
return {
|
||||||
|
on: on,
|
||||||
|
off: off,
|
||||||
|
emit: emit,
|
||||||
|
join: joinRoom,
|
||||||
|
leave: leaveRoom,
|
||||||
|
connected: isConnected
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect from server
|
* Disconnect from server
|
||||||
*/
|
*/
|
||||||
function disconnect() {
|
function disconnect() {
|
||||||
if (socket) {
|
autoReconnect = false;
|
||||||
socket.disconnect();
|
if (ws) {
|
||||||
socket = null;
|
ws.close(1000, 'Client disconnected');
|
||||||
|
ws = null;
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,6 +290,9 @@ AniWorld.WebSocketClient = (function() {
|
|||||||
on: on,
|
on: on,
|
||||||
off: off,
|
off: off,
|
||||||
emit: emit,
|
emit: emit,
|
||||||
|
send: send,
|
||||||
|
join: joinRoom,
|
||||||
|
leave: leaveRoom,
|
||||||
isConnected: getConnectionStatus,
|
isConnected: getConnectionStatus,
|
||||||
getSocket: getSocket,
|
getSocket: getSocket,
|
||||||
disconnect: disconnect
|
disconnect: disconnect
|
||||||
|
|||||||
@ -440,9 +440,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Socket.IO -->
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script>
|
|
||||||
|
|
||||||
<!-- Shared Modules (load in dependency order) -->
|
<!-- Shared Modules (load in dependency order) -->
|
||||||
<script src="/static/js/shared/constants.js"></script>
|
<script src="/static/js/shared/constants.js"></script>
|
||||||
<script src="/static/js/shared/auth.js"></script>
|
<script src="/static/js/shared/auth.js"></script>
|
||||||
|
|||||||
@ -233,9 +233,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Socket.IO -->
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script>
|
|
||||||
|
|
||||||
<!-- Shared Modules (load in dependency order) -->
|
<!-- Shared Modules (load in dependency order) -->
|
||||||
<script src="/static/js/shared/constants.js"></script>
|
<script src="/static/js/shared/constants.js"></script>
|
||||||
<script src="/static/js/shared/auth.js"></script>
|
<script src="/static/js/shared/auth.js"></script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user