strictly use socket.io class based namespaces

This commit is contained in:
Patrick Jentsch 2024-11-07 12:12:42 +01:00
parent d41ebc6efe
commit bd0a9c60f8
11 changed files with 48 additions and 90 deletions

View File

@ -1,47 +0,0 @@
from flask_login import current_user
from flask_socketio import join_room, leave_room
from app import hashids, socketio
from app.decorators import socketio_login_required
from app.models import User
@socketio.on('GET /users/<user_id>')
@socketio_login_required
def get_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
if user is None:
return {'status': 404, 'statusText': 'Not found'}
if not (user == current_user or current_user.is_administrator):
return {'status': 403, 'statusText': 'Forbidden'}
return {
'body': user.to_json_serializeable(backrefs=True, relationships=True),
'status': 200,
'statusText': 'OK'
}
@socketio.on('SUBSCRIBE /users/<user_id>')
@socketio_login_required
def subscribe_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
if user is None:
return {'status': 404, 'statusText': 'Not found'}
if not (user == current_user or current_user.is_administrator):
return {'status': 403, 'statusText': 'Forbidden'}
join_room(f'/users/{user.hashid}')
return {'status': 200, 'statusText': 'OK'}
@socketio.on('UNSUBSCRIBE /users/<user_id>')
@socketio_login_required
def unsubscribe_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
if user is None:
return {'status': 404, 'statusText': 'Not found'}
if not (user == current_user or current_user.is_administrator):
return {'status': 403, 'statusText': 'Forbidden'}
leave_room(f'/users/{user.hashid}')
return {'status': 200, 'statusText': 'OK'}

View File

@ -43,7 +43,7 @@ def resource_after_delete(mapper, connection, resource):
} }
] ]
room = f'/users/{resource.user_hashid}' room = f'/users/{resource.user_hashid}'
socketio.emit('PATCH', jsonpatch, room=room) socketio.emit('patch_user', jsonpatch, namespace='/users', room=room)
def cfa_after_delete(mapper, connection, cfa): def cfa_after_delete(mapper, connection, cfa):
@ -55,7 +55,7 @@ def cfa_after_delete(mapper, connection, cfa):
} }
] ]
room = f'/users/{cfa.corpus.user.hashid}' room = f'/users/{cfa.corpus.user.hashid}'
socketio.emit('PATCH', jsonpatch, room=room) socketio.emit('patch_user', jsonpatch, namespace='/users', room=room)
def resource_after_insert(mapper, connection, resource): def resource_after_insert(mapper, connection, resource):
@ -70,7 +70,7 @@ def resource_after_insert(mapper, connection, resource):
} }
] ]
room = f'/users/{resource.user_hashid}' room = f'/users/{resource.user_hashid}'
socketio.emit('PATCH', jsonpatch, room=room) socketio.emit('patch_user', jsonpatch, namespace='/users', room=room)
def cfa_after_insert(mapper, connection, cfa): def cfa_after_insert(mapper, connection, cfa):
@ -84,7 +84,7 @@ def cfa_after_insert(mapper, connection, cfa):
} }
] ]
room = f'/users/{cfa.corpus.user.hashid}' room = f'/users/{cfa.corpus.user.hashid}'
socketio.emit('PATCH', jsonpatch, room=room) socketio.emit('patch_user', jsonpatch, namespace='/users', room=room)
def resource_after_update(mapper, connection, resource): def resource_after_update(mapper, connection, resource):
@ -110,7 +110,7 @@ def resource_after_update(mapper, connection, resource):
) )
if jsonpatch: if jsonpatch:
room = f'/users/{resource.user_hashid}' room = f'/users/{resource.user_hashid}'
socketio.emit('PATCH', jsonpatch, room=room) socketio.emit('patch_user', jsonpatch, namespace='/users', room=room)
def job_after_update(mapper, connection, job): def job_after_update(mapper, connection, job):

View File

@ -1,29 +1,32 @@
nopaque.App = class App { nopaque.App = class App {
#promises;
constructor() { constructor() {
this.data = { this.data = {
promises: {getUser: {}, subscribeUser: {}}, users: {}
users: {},
}; };
this.sockets = {};
this.sockets['/users'] = io( this.#promises = {
'/users', getUser: {},
{ subscribeUser: {}
transports: ['websocket'], };
upgrade: false
} this.sockets = {
); users: io('/users', {transports: ['websocket'], upgrade: false})
// this.socket = io({transports: ['websocket'], upgrade: false}); };
this.socket = this.sockets['/users'];
this.socket.on('PATCH', (patch) => {this.onPatch(patch);}); this.sockets.users.on('patch_user', (patch) => {this.onPatch(patch);});
} }
getUser(userId) { getUser(userId) {
if (userId in this.data.promises.getUser) { if (userId in this.#promises.getUser) {
return this.data.promises.getUser[userId]; return this.#promises.getUser[userId];
} }
this.data.promises.getUser[userId] = new Promise((resolve, reject) => { let socket = this.sockets.users;
this.socket.emit('get_user', userId, (response) => {
this.#promises.getUser[userId] = new Promise((resolve, reject) => {
socket.emit('get_user', userId, (response) => {
if (response.status === 200) { if (response.status === 200) {
this.data.users[userId] = response.body; this.data.users[userId] = response.body;
resolve(this.data.users[userId]); resolve(this.data.users[userId]);
@ -33,25 +36,27 @@ nopaque.App = class App {
}); });
}); });
return this.data.promises.getUser[userId]; return this.#promises.getUser[userId];
} }
subscribeUser(userId) { subscribeUser(userId) {
if (userId in this.data.promises.subscribeUser) { if (userId in this.#promises.subscribeUser) {
return this.data.promises.subscribeUser[userId]; return this.#promises.subscribeUser[userId];
} }
this.data.promises.subscribeUser[userId] = new Promise((resolve, reject) => { let socket = this.sockets.users;
this.socket.emit('subscribe_user', userId, (response) => {
if (response.status !== 200) { this.#promises.subscribeUser[userId] = new Promise((resolve, reject) => {
socket.emit('subscribe_user', userId, (response) => {
if (response.status === 200) {
resolve(response);
} else {
reject(response); reject(response);
return;
} }
resolve(response);
}); });
}); });
return this.data.promises.subscribeUser[userId]; return this.#promises.subscribeUser[userId];
} }
flash(message, category) { flash(message, category) {

View File

@ -8,7 +8,7 @@ nopaque.resource_displays.ResourceDisplay = class ResourceDisplay {
if (this.userId) { if (this.userId) {
app.subscribeUser(this.userId) app.subscribeUser(this.userId)
.then((response) => { .then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });

View File

@ -15,7 +15,7 @@ nopaque.resource_lists.CorpusFileList = class CorpusFileList extends nopaque.res
this.hasPermissionManageFiles = listContainerElement.dataset?.hasPermissionManageFiles == 'true' || false; this.hasPermissionManageFiles = listContainerElement.dataset?.hasPermissionManageFiles == 'true' || false;
if (this.userId === undefined || this.corpusId === undefined) {return;} if (this.userId === undefined || this.corpusId === undefined) {return;}
app.subscribeUser(this.userId).then((response) => { app.subscribeUser(this.userId).then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });

View File

@ -13,7 +13,7 @@ nopaque.resource_lists.CorpusFollowerList = class CorpusFollowerList extends nop
this.corpusId = listContainerElement.dataset.corpusId; this.corpusId = listContainerElement.dataset.corpusId;
if (this.userId === undefined || this.corpusId === undefined) {return;} if (this.userId === undefined || this.corpusId === undefined) {return;}
app.subscribeUser(this.userId).then((response) => { app.subscribeUser(this.userId).then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });

View File

@ -12,7 +12,7 @@ nopaque.resource_lists.CorpusList = class CorpusList extends nopaque.resource_li
this.userId = listContainerElement.dataset.userId; this.userId = listContainerElement.dataset.userId;
if (this.userId === undefined) {return;} if (this.userId === undefined) {return;}
app.subscribeUser(this.userId).then((response) => { app.subscribeUser(this.userId).then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });

View File

@ -13,7 +13,7 @@ nopaque.resource_lists.JobList = class JobList extends nopaque.resource_lists.Re
this.userId = listContainerElement.dataset.userId; this.userId = listContainerElement.dataset.userId;
if (this.userId === undefined) {return;} if (this.userId === undefined) {return;}
app.subscribeUser(this.userId).then((response) => { app.subscribeUser(this.userId).then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });

View File

@ -9,7 +9,7 @@ nopaque.resource_lists.JobResultList = class JobResultList extends nopaque.resou
this.jobId = listContainerElement.dataset.jobId; this.jobId = listContainerElement.dataset.jobId;
if (this.userId === undefined || this.jobId === undefined) {return;} if (this.userId === undefined || this.jobId === undefined) {return;}
app.subscribeUser(this.userId).then((response) => { app.subscribeUser(this.userId).then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });

View File

@ -9,7 +9,7 @@ nopaque.resource_lists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelLi
this.userId = listContainerElement.dataset.userId; this.userId = listContainerElement.dataset.userId;
if (this.userId === undefined) {return;} if (this.userId === undefined) {return;}
app.subscribeUser(this.userId).then((response) => { app.subscribeUser(this.userId).then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });

View File

@ -9,7 +9,7 @@ nopaque.resource_lists.TesseractOCRPipelineModelList = class TesseractOCRPipelin
this.userId = listContainerElement.dataset.userId; this.userId = listContainerElement.dataset.userId;
if (this.userId === undefined) {return;} if (this.userId === undefined) {return;}
app.subscribeUser(this.userId).then((response) => { app.subscribeUser(this.userId).then((response) => {
app.socket.on('PATCH', (patch) => { app.sockets.users.on('patch_user', (patch) => {
if (this.isInitialized) {this.onPatch(patch);} if (this.isInitialized) {this.onPatch(patch);}
}); });
}); });