mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 04:12:45 +00:00 
			
		
		
		
	Update javascript app structure
This commit is contained in:
		@@ -9,8 +9,8 @@ from threading import Lock
 | 
			
		||||
from app import db, docker_client, hashids, socketio
 | 
			
		||||
from app.decorators import socketio_login_required
 | 
			
		||||
from app.models import Corpus, CorpusStatus
 | 
			
		||||
from . import cqi_extensions
 | 
			
		||||
from .utils import CQiOverSocketIOSessionManager
 | 
			
		||||
from . import cqi_extension_functions
 | 
			
		||||
from .utils import SessionManager
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
@@ -85,6 +85,16 @@ CQI_API_FUNCTION_NAMES = [
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CQI_EXTENSION_FUNCTION_NAMES = [
 | 
			
		||||
    'ext_corpus_update_db',
 | 
			
		||||
    'ext_corpus_static_data',
 | 
			
		||||
    'ext_corpus_paginate_corpus',
 | 
			
		||||
    'ext_cqp_paginate_subcorpus',
 | 
			
		||||
    'ext_cqp_partial_export_subcorpus',
 | 
			
		||||
    'ext_cqp_export_subcorpus',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CQiOverSocketIONamespace(Namespace):
 | 
			
		||||
    @socketio_login_required
 | 
			
		||||
    def on_connect(self):
 | 
			
		||||
@@ -135,25 +145,25 @@ class CQiOverSocketIONamespace(Namespace):
 | 
			
		||||
        cqi_client = CQiClient(cqpserver_ip_address)
 | 
			
		||||
        cqi_client_lock = Lock()
 | 
			
		||||
 | 
			
		||||
        CQiOverSocketIOSessionManager.setup()
 | 
			
		||||
        CQiOverSocketIOSessionManager.set_corpus_id(corpus_id)
 | 
			
		||||
        CQiOverSocketIOSessionManager.set_cqi_client(cqi_client)
 | 
			
		||||
        CQiOverSocketIOSessionManager.set_cqi_client_lock(cqi_client_lock)
 | 
			
		||||
        SessionManager.setup()
 | 
			
		||||
        SessionManager.set_corpus_id(corpus_id)
 | 
			
		||||
        SessionManager.set_cqi_client(cqi_client)
 | 
			
		||||
        SessionManager.set_cqi_client_lock(cqi_client_lock)
 | 
			
		||||
 | 
			
		||||
        return {'code': 200, 'msg': 'OK'}
 | 
			
		||||
 | 
			
		||||
    @socketio_login_required
 | 
			
		||||
    def on_exec(self, fn_name: str, fn_args: dict = {}) -> dict:
 | 
			
		||||
        try:
 | 
			
		||||
            cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
            cqi_client_lock = CQiOverSocketIOSessionManager.get_cqi_client_lock()
 | 
			
		||||
            cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
            cqi_client_lock = SessionManager.get_cqi_client_lock()
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            return {'code': 424, 'msg': 'Failed Dependency'}
 | 
			
		||||
 | 
			
		||||
        if fn_name in CQI_API_FUNCTION_NAMES:
 | 
			
		||||
            fn = getattr(cqi_client.api, fn_name)
 | 
			
		||||
        elif fn_name in cqi_extensions.CQI_EXTENSION_FUNCTION_NAMES:
 | 
			
		||||
            fn = getattr(cqi_extensions, fn_name)
 | 
			
		||||
        elif fn_name in cqi_extension_functions.CQI_EXTENSION_FUNCTION_NAMES:
 | 
			
		||||
            fn = getattr(cqi_extension_functions, fn_name)
 | 
			
		||||
        else:
 | 
			
		||||
            return {'code': 400, 'msg': 'Bad Request'}
 | 
			
		||||
 | 
			
		||||
@@ -198,10 +208,10 @@ class CQiOverSocketIONamespace(Namespace):
 | 
			
		||||
 | 
			
		||||
    def on_disconnect(self):
 | 
			
		||||
        try:
 | 
			
		||||
            corpus_id = CQiOverSocketIOSessionManager.get_corpus_id()
 | 
			
		||||
            cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
            cqi_client_lock = CQiOverSocketIOSessionManager.get_cqi_client_lock()
 | 
			
		||||
            CQiOverSocketIOSessionManager.teardown()
 | 
			
		||||
            corpus_id = SessionManager.get_corpus_id()
 | 
			
		||||
            cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
            cqi_client_lock = SessionManager.get_cqi_client_lock()
 | 
			
		||||
            SessionManager.teardown()
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,22 +8,12 @@ import json
 | 
			
		||||
import math
 | 
			
		||||
from app import db
 | 
			
		||||
from app.models import Corpus
 | 
			
		||||
from .utils import CQiOverSocketIOSessionManager
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CQI_EXTENSION_FUNCTION_NAMES = [
 | 
			
		||||
    'ext_corpus_update_db',
 | 
			
		||||
    'ext_corpus_static_data',
 | 
			
		||||
    'ext_corpus_paginate_corpus',
 | 
			
		||||
    'ext_cqp_paginate_subcorpus',
 | 
			
		||||
    'ext_cqp_partial_export_subcorpus',
 | 
			
		||||
    'ext_cqp_export_subcorpus',
 | 
			
		||||
]
 | 
			
		||||
from .utils import SessionManager
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ext_corpus_update_db(corpus: str) -> CQiStatusOk:
 | 
			
		||||
    corpus_id = CQiOverSocketIOSessionManager.get_corpus_id()
 | 
			
		||||
    cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
    corpus_id = SessionManager.get_corpus_id()
 | 
			
		||||
    cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
    db_corpus = Corpus.query.get(corpus_id)
 | 
			
		||||
    cqi_corpus = cqi_client.corpora.get(corpus)
 | 
			
		||||
    db_corpus.num_tokens = cqi_corpus.size
 | 
			
		||||
@@ -32,7 +22,7 @@ def ext_corpus_update_db(corpus: str) -> CQiStatusOk:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ext_corpus_static_data(corpus: str) -> dict:
 | 
			
		||||
    corpus_id = CQiOverSocketIOSessionManager.get_corpus_id()
 | 
			
		||||
    corpus_id = SessionManager.get_corpus_id()
 | 
			
		||||
    db_corpus = Corpus.query.get(corpus_id)
 | 
			
		||||
 | 
			
		||||
    static_data_file_path = db_corpus.path / 'cwb' / 'static.json.gz'
 | 
			
		||||
@@ -40,7 +30,7 @@ def ext_corpus_static_data(corpus: str) -> dict:
 | 
			
		||||
        with static_data_file_path.open('rb') as f:
 | 
			
		||||
            return f.read()
 | 
			
		||||
 | 
			
		||||
    cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
    cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
    cqi_corpus = cqi_client.corpora.get(corpus)
 | 
			
		||||
    cqi_p_attrs = cqi_corpus.positional_attributes.list()
 | 
			
		||||
    cqi_s_attrs = cqi_corpus.structural_attributes.list()
 | 
			
		||||
@@ -168,7 +158,7 @@ def ext_corpus_paginate_corpus(
 | 
			
		||||
    page: int = 1,
 | 
			
		||||
    per_page: int = 20
 | 
			
		||||
) -> dict:
 | 
			
		||||
    cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
    cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
    cqi_corpus = cqi_client.corpora.get(corpus)
 | 
			
		||||
    # Sanity checks
 | 
			
		||||
    if (
 | 
			
		||||
@@ -215,7 +205,7 @@ def ext_cqp_paginate_subcorpus(
 | 
			
		||||
    per_page: int = 20
 | 
			
		||||
) -> dict:
 | 
			
		||||
    corpus_name, subcorpus_name = subcorpus.split(':', 1)
 | 
			
		||||
    cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
    cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
    cqi_corpus = cqi_client.corpora.get(corpus_name)
 | 
			
		||||
    cqi_subcorpus = cqi_corpus.subcorpora.get(subcorpus_name)
 | 
			
		||||
    # Sanity checks
 | 
			
		||||
@@ -262,7 +252,7 @@ def ext_cqp_partial_export_subcorpus(
 | 
			
		||||
    context: int = 50
 | 
			
		||||
) -> dict:
 | 
			
		||||
    corpus_name, subcorpus_name = subcorpus.split(':', 1)
 | 
			
		||||
    cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
    cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
    cqi_corpus = cqi_client.corpora.get(corpus_name)
 | 
			
		||||
    cqi_subcorpus = cqi_corpus.subcorpora.get(subcorpus_name)
 | 
			
		||||
    cqi_subcorpus_partial_export = _partial_export_subcorpus(cqi_subcorpus, match_id_list, context=context)
 | 
			
		||||
@@ -271,7 +261,7 @@ def ext_cqp_partial_export_subcorpus(
 | 
			
		||||
 | 
			
		||||
def ext_cqp_export_subcorpus(subcorpus: str, context: int = 50) -> dict:
 | 
			
		||||
    corpus_name, subcorpus_name = subcorpus.split(':', 1)
 | 
			
		||||
    cqi_client = CQiOverSocketIOSessionManager.get_cqi_client()
 | 
			
		||||
    cqi_client = SessionManager.get_cqi_client()
 | 
			
		||||
    cqi_corpus = cqi_client.corpora.get(corpus_name)
 | 
			
		||||
    cqi_subcorpus = cqi_corpus.subcorpora.get(subcorpus_name)
 | 
			
		||||
    cqi_subcorpus_export = _export_subcorpus(cqi_subcorpus, context=context)
 | 
			
		||||
@@ -3,7 +3,7 @@ from threading import Lock
 | 
			
		||||
from flask import session
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CQiOverSocketIOSessionManager:
 | 
			
		||||
class SessionManager:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def setup():
 | 
			
		||||
        session['cqi_over_sio'] = {}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										116
									
								
								app/namespaces/users.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								app/namespaces/users.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
from flask import current_app, Flask
 | 
			
		||||
from flask_login import current_user
 | 
			
		||||
from flask_socketio import join_room, leave_room, Namespace
 | 
			
		||||
from app import db, hashids, socketio
 | 
			
		||||
from app.decorators import socketio_login_required
 | 
			
		||||
from app.models import User
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _delete_user(app: Flask, user_id: int):
 | 
			
		||||
    with app.app_context():
 | 
			
		||||
        user = User.query.get(user_id)
 | 
			
		||||
        user.delete()
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UsersNamespace(Namespace):
 | 
			
		||||
    @socketio_login_required
 | 
			
		||||
    def on_get(self, user_hashid: str) -> dict:
 | 
			
		||||
        user_id = hashids.decode(user_hashid)
 | 
			
		||||
 | 
			
		||||
        if not isinstance(user_id, int):
 | 
			
		||||
            return {'status': 400, 'statusText': 'Bad Request'}
 | 
			
		||||
 | 
			
		||||
        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_login_required
 | 
			
		||||
    def on_subscribe(self, user_hashid: str) -> dict:
 | 
			
		||||
        user_id = hashids.decode(user_hashid)
 | 
			
		||||
 | 
			
		||||
        if not isinstance(user_id, int):
 | 
			
		||||
            return {'status': 400, 'statusText': 'Bad Request'}
 | 
			
		||||
 | 
			
		||||
        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_login_required
 | 
			
		||||
    def on_unsubscribe(self, user_hashid: str) -> dict:
 | 
			
		||||
        user_id = hashids.decode(user_hashid)
 | 
			
		||||
 | 
			
		||||
        if not isinstance(user_id, int):
 | 
			
		||||
            return {'status': 400, 'statusText': 'Bad Request'}
 | 
			
		||||
 | 
			
		||||
        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'}
 | 
			
		||||
 | 
			
		||||
    @socketio_login_required
 | 
			
		||||
    def on_delete(self, user_hashid: str) -> dict:
 | 
			
		||||
        user_id = hashids.decode(user_hashid)
 | 
			
		||||
 | 
			
		||||
        if not isinstance(user_id, int):
 | 
			
		||||
            return {'status': 400, 'statusText': 'Bad Request'}
 | 
			
		||||
 | 
			
		||||
        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'}
 | 
			
		||||
 | 
			
		||||
        socketio.start_background_task(
 | 
			
		||||
            _delete_user,
 | 
			
		||||
            current_app._get_current_object(),
 | 
			
		||||
            user.id
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            'body': f'User "{user.username}" marked for deletion',
 | 
			
		||||
            'status': 202,
 | 
			
		||||
            'statusText': 'Accepted'
 | 
			
		||||
        }
 | 
			
		||||
		Reference in New Issue
	
	Block a user