mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-06-12 09:00:40 +00:00
Update
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
from time import sleep
|
||||
from .. import errors, specification
|
||||
from .. import specification
|
||||
from ..errors import cl_error_lookup, error_lookup, cqp_error_lookup
|
||||
import socket
|
||||
import struct
|
||||
|
||||
@ -434,58 +435,18 @@ class APIClient:
|
||||
byte_data = self.__recv_WORD()
|
||||
response_type = byte_data >> 8
|
||||
if response_type == specification.CL_ERROR:
|
||||
raise self.__create_cl_error(byte_data)
|
||||
raise cl_error_lookup[byte_data]()
|
||||
elif response_type == specification.CQP_ERROR:
|
||||
raise self.__create_cqp_error(byte_data)
|
||||
raise cqp_error_lookup[byte_data]()
|
||||
elif response_type == specification.DATA:
|
||||
return self.__recv_DATA(byte_data)
|
||||
elif response_type == specification.ERROR:
|
||||
raise self.__create_error(byte_data)
|
||||
raise error_lookup[byte_data]()
|
||||
elif response_type == specification.STATUS:
|
||||
return {'code': byte_data, 'msg': specification.lookup[byte_data]}
|
||||
else:
|
||||
raise Exception('Unknown response type: {}'.format(response_type))
|
||||
|
||||
def __create_cl_error(self, error_type):
|
||||
if error_type == specification.CL_ERROR_NO_SUCH_ATTRIBUTE:
|
||||
return errors.CLErrorNoSuchAttribute()
|
||||
elif error_type == specification.CL_ERROR_WRONG_ATTRIBUTE_TYPE:
|
||||
return errors.CLErrorWrongAttributeType()
|
||||
elif error_type == specification.CL_ERROR_OUT_OF_RANGE:
|
||||
return errors.CLErrorOutOfRange()
|
||||
elif error_type == specification.CL_ERROR_REGEX:
|
||||
return errors.CLErrorRegex()
|
||||
elif error_type == specification.CL_ERROR_CORPUS_ACCESS:
|
||||
return errors.CLErrorCorpusAccess()
|
||||
elif error_type == specification.CL_ERROR_OUT_OF_MEMORY:
|
||||
return errors.CLErrorOutOfMemory()
|
||||
elif error_type == specification.CL_ERROR_INTERNAL:
|
||||
return errors.CLErrorInternal()
|
||||
else:
|
||||
return errors.CLError(error_type)
|
||||
|
||||
def __create_cqp_error(self, error_type):
|
||||
if error_type == specification.CQP_ERROR_GENERAL:
|
||||
return errors.CQPErrorGeneral()
|
||||
elif error_type == specification.CQP_ERROR_INVALID_FIELD:
|
||||
return errors.CQPErrorInvalidField()
|
||||
elif error_type == specification.CQP_ERROR_OUT_OF_RANGE:
|
||||
return errors.CQPErrorOutOfRange()
|
||||
else:
|
||||
return errors.CQPError(error_type)
|
||||
|
||||
def __create_error(self, error_type):
|
||||
if error_type == specification.ERROR_GENERAL_ERROR:
|
||||
return errors.ErrorGeneralError()
|
||||
elif error_type == specification.ERROR_CONNECT_REFUSED:
|
||||
return errors.ErrorConnectRefused()
|
||||
elif error_type == specification.ERROR_USER_ABORT:
|
||||
return errors.ErrorUserAbort()
|
||||
elif error_type == specification.ERROR_SYNTAX_ERROR:
|
||||
return errors.ErrorSyntaxError()
|
||||
else:
|
||||
return errors.Error(error_type)
|
||||
|
||||
def __recv_DATA(self, data_type):
|
||||
if data_type == specification.DATA_BYTE:
|
||||
data = self.__recv_DATA_BYTE()
|
||||
|
@ -1,3 +1,6 @@
|
||||
from . import specification
|
||||
|
||||
|
||||
class CQiException(Exception):
|
||||
"""
|
||||
A base class from which all other exceptions inherit.
|
||||
@ -5,100 +8,173 @@ class CQiException(Exception):
|
||||
catch this base exception.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CQiException, self).__init__(*args, **kwargs)
|
||||
self.code = None
|
||||
self.name = None
|
||||
self.description = None
|
||||
|
||||
|
||||
class Error(CQiException):
|
||||
# ERROR = 0x02
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Error, self).__init__(*args, **kwargs)
|
||||
self.code = specification.ERROR
|
||||
|
||||
|
||||
class ErrorGeneralError(Error):
|
||||
# ERROR_GENERAL_ERROR = 0x0201
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ErrorGeneralError, self).__init__(*args, **kwargs)
|
||||
self.code = specification.ERROR_GENERAL_ERROR
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class ErrorConnectRefused(Error):
|
||||
# ERROR_CONNECT_REFUSED = 0x0202
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ErrorConnectRefused, self).__init__(*args, **kwargs)
|
||||
self.code = specification.ERROR_CONNECT_REFUSED
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class ErrorUserAbort(Error):
|
||||
# ERROR_USER_ABORT = 0x0203
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ErrorUserAbort, self).__init__(*args, **kwargs)
|
||||
self.code = specification.ERROR_USER_ABORT
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class ErrorSyntaxError(Error):
|
||||
# ERROR_SYNTAX_ERROR = 0x0204
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ErrorSyntaxError, self).__init__(*args, **kwargs)
|
||||
self.code = specification.ERROR_SYNTAX_ERROR
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CLError(CQiException):
|
||||
# CL_ERROR = 0x04
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLError, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR
|
||||
|
||||
|
||||
class CLErrorNoSuchAttribute(CLError):
|
||||
# CL_ERROR_NO_SUCH_ATTRIBUTE = 0x0401
|
||||
# returned if CQi server couldn't open attribute
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLErrorNoSuchAttribute, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR_NO_SUCH_ATTRIBUTE
|
||||
self.name = specification.lookup[self.code]
|
||||
self.description = "CQi server couldn't open attribute"
|
||||
|
||||
|
||||
class CLErrorWrongAttributeType(CLError):
|
||||
# CL_ERROR_WRONG_ATTRIBUTE_TYPE = 0x0402
|
||||
# CDA_EATTTYPE
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLErrorWrongAttributeType, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR_WRONG_ATTRIBUTE_TYPE
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CLErrorOutOfRange(CLError):
|
||||
# CL_ERROR_OUT_OF_RANGE = 0x0403
|
||||
# CDA_EIDORNG, CDA_EIDXORNG, CDA_EPOSORNG
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLErrorOutOfRange, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR_OUT_OF_RANGE
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CLErrorRegex(CLError):
|
||||
# CL_ERROR_REGEX = 0x0404
|
||||
# CDA_EPATTERN (not used), CDA_EBADREGEX
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLErrorRegex, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR_REGEX
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CLErrorCorpusAccess(CLError):
|
||||
# CL_ERROR_CORPUS_ACCESS = 0x0405
|
||||
# CDA_ENODATA
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLErrorCorpusAccess, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR_CORPUS_ACCESS
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CLErrorOutOfMemory(CLError):
|
||||
# CL_ERROR_OUT_OF_MEMORY = 0x0406
|
||||
# CDA_ENOMEM
|
||||
# this means the CQi server has run out of memory;
|
||||
# try discarding some other corpora and/or subcorpora
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLErrorOutOfMemory, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR_OUT_OF_MEMORY
|
||||
self.name = specification.lookup[self.code]
|
||||
self.description = ('CQi server has run out of memory; try discarding '
|
||||
'some other corpora and/or subcorpora')
|
||||
|
||||
|
||||
class CLErrorInternal(CLError):
|
||||
# CL_ERROR_INTERNAL = 0x0407
|
||||
# CDA_EOTHER, CDA_ENYI
|
||||
# this is the classical 'please contact technical support' error
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CLErrorInternal, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CL_ERROR_INTERNAL
|
||||
self.name = specification.lookup[self.code]
|
||||
self.description = "Classical 'please contact technical support' error"
|
||||
|
||||
|
||||
class CQPError(CQiException):
|
||||
# CQP_ERROR = 0x05
|
||||
# CQP error messages yet to be defined
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CQPError, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CQP_ERROR
|
||||
|
||||
|
||||
class CQPErrorGeneral(CQPError):
|
||||
# CQP_ERROR_GENERAL = 0x0501
|
||||
pass
|
||||
# CQP_ERROR_NO_SUCH_CORPUS = 0x0502
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CQPErrorGeneral, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CQP_ERROR_GENERAL
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CQPErrorNoSuchCorpus(CQPError):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CQPErrorNoSuchCorpus, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CQP_ERROR_NO_SUCH_CORPUS
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CQPErrorInvalidField(CQPError):
|
||||
# CQP_ERROR_INVALID_FIELD = 0x0503
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CQPErrorInvalidField, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CQP_ERROR_INVALID_FIELD
|
||||
self.name = specification.lookup[self.code]
|
||||
|
||||
|
||||
class CQPErrorOutOfRange(CQPError):
|
||||
# CQP_ERROR_OUT_OF_RANGE = 0x0504
|
||||
# various cases where a number is out of range
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CQPErrorOutOfRange, self).__init__(*args, **kwargs)
|
||||
self.code = specification.CQP_ERROR_OUT_OF_RANGE
|
||||
self.name = specification.lookup[self.code]
|
||||
self.description = 'A number is out of range'
|
||||
|
||||
|
||||
error_lookup = {
|
||||
specification.ERROR: Error,
|
||||
specification.ERROR_GENERAL_ERROR: ErrorGeneralError,
|
||||
specification.ERROR_CONNECT_REFUSED: ErrorConnectRefused,
|
||||
specification.ERROR_USER_ABORT: ErrorUserAbort,
|
||||
specification.ERROR_SYNTAX_ERROR: ErrorSyntaxError
|
||||
}
|
||||
|
||||
|
||||
cl_error_lookup = {
|
||||
specification.CL_ERROR: CLError,
|
||||
specification.CL_ERROR_NO_SUCH_ATTRIBUTE: CLErrorNoSuchAttribute,
|
||||
specification.CL_ERROR_WRONG_ATTRIBUTE_TYPE: CLErrorWrongAttributeType,
|
||||
specification.CL_ERROR_OUT_OF_RANGE: CLErrorOutOfRange,
|
||||
specification.CL_ERROR_REGEX: CLErrorRegex,
|
||||
specification.CL_ERROR_CORPUS_ACCESS: CLErrorCorpusAccess,
|
||||
specification.CL_ERROR_OUT_OF_MEMORY: CLErrorOutOfMemory,
|
||||
specification.CL_ERROR_INTERNAL: CLErrorInternal
|
||||
}
|
||||
|
||||
|
||||
cqp_error_lookup = {
|
||||
specification.CQP_ERROR: CQPError,
|
||||
specification.CQP_ERROR_GENERAL: CQPErrorGeneral,
|
||||
specification.CQP_ERROR_NO_SUCH_CORPUS: CQPErrorNoSuchCorpus,
|
||||
specification.CQP_ERROR_INVALID_FIELD: CQPErrorInvalidField,
|
||||
specification.CQP_ERROR_OUT_OF_RANGE: CQPErrorOutOfRange
|
||||
}
|
||||
|
@ -33,37 +33,46 @@ def pj_init_corpus_analysis(corpus_id):
|
||||
def pj_corpus_analysis_query(query):
|
||||
client = pj_corpus_analysis_clients.get(request.sid)
|
||||
if client is None:
|
||||
response = {'code': 404, 'msg': 'Failed Dependency'}
|
||||
response = {'code': 404, 'desc': 'No client found for this session',
|
||||
'msg': 'Failed Dependency'}
|
||||
socketio.emit('pj_corpus_analysis_query', response, room=request.sid)
|
||||
return
|
||||
try:
|
||||
corpus = client.corpora.get('CORPUS')
|
||||
except cqi.errors.CQiException as e:
|
||||
response = {'code': 500, 'desc': None, 'msg': 'Internal Server Error',
|
||||
'payload': {'code': e.code, 'desc': e.description,
|
||||
'msg': e.name}}
|
||||
socketio.emit('pj_corpus_analysis_query', response, room=request.sid)
|
||||
return
|
||||
corpus = client.corpora.get('CORPUS')
|
||||
try:
|
||||
results = corpus.query(query)
|
||||
except cqi.errors.CQiException as e:
|
||||
response = {'code': 1, 'msg': str(e)}
|
||||
response = {'code': 500, 'desc': None, 'msg': 'Internal Server Error',
|
||||
'payload': {'code': e.code, 'desc': e.description,
|
||||
'msg': e.name}}
|
||||
socketio.emit('pj_corpus_analysis_query', response, room=request.sid)
|
||||
else:
|
||||
response = {'code': 200, 'msg': 'OK',
|
||||
'data': {'num_matches': results.size}}
|
||||
socketio.emit('pj_corpus_analysis_query', response, room=request.sid)
|
||||
chunk_size = 100
|
||||
chunk_start = 0
|
||||
context = 100
|
||||
progress = 0
|
||||
while chunk_start <= results.size:
|
||||
chunk = results.export(context=context, offset=chunk_start,
|
||||
cutoff=chunk_size)
|
||||
if (results.size == 0):
|
||||
progress = 100
|
||||
else:
|
||||
progress = ((chunk_start + chunk_size) / results.size) * 100
|
||||
progress = min(100, int(math.ceil(progress)))
|
||||
socketio.emit('pj_corpus_analysis_query_results',
|
||||
{'chunk': chunk,
|
||||
'progress': progress},
|
||||
room=request.sid)
|
||||
chunk_start += chunk_size
|
||||
chunk_size = 250
|
||||
return
|
||||
response = {'code': 200, 'desc': None, 'msg': 'OK',
|
||||
'payload': {'num_matches': results.size}}
|
||||
socketio.emit('pj_corpus_analysis_query', response, room=request.sid)
|
||||
chunk_size = 100
|
||||
chunk_start = 0
|
||||
context = 100
|
||||
progress = 0
|
||||
while chunk_start <= results.size:
|
||||
chunk = results.export(context=context, cutoff=chunk_size,
|
||||
offset=chunk_start)
|
||||
if (results.size == 0):
|
||||
progress = 100
|
||||
else:
|
||||
progress = ((chunk_start + chunk_size) / results.size) * 100
|
||||
progress = min(100, int(math.ceil(progress)))
|
||||
response = {'code': 200, 'desc': None, 'msg': 'OK',
|
||||
'payload': {'chunk': chunk, 'progress': progress}}
|
||||
socketio.emit('pj_corpus_analysis_query_results', response,
|
||||
room=request.sid)
|
||||
chunk_start += chunk_size
|
||||
|
||||
|
||||
def pj_corpus_analysis_session_handler(app, corpus_id, user_id, session_id):
|
||||
@ -72,11 +81,11 @@ def pj_corpus_analysis_session_handler(app, corpus_id, user_id, session_id):
|
||||
corpus = Corpus.query.get(corpus_id)
|
||||
user = User.query.get(user_id)
|
||||
if corpus is None:
|
||||
response = {'code': 404, 'msg': 'Not Found'}
|
||||
response = {'code': 404, 'desc': None, 'msg': 'Not Found'}
|
||||
socketio.emit('pj_corpus_analysis_init', response, room=session_id)
|
||||
return
|
||||
elif not (corpus.creator == user or user.is_administrator()):
|
||||
response = {'code': 403, 'msg': 'Forbidden'}
|
||||
response = {'code': 403, 'desc': None, 'msg': 'Forbidden'}
|
||||
socketio.emit('pj_corpus_analysis_init', response, room=session_id)
|
||||
return
|
||||
while corpus.status != 'analysing':
|
||||
@ -85,8 +94,11 @@ def pj_corpus_analysis_session_handler(app, corpus_id, user_id, session_id):
|
||||
client = cqi.CQiClient('corpus_{}_analysis'.format(corpus_id))
|
||||
try:
|
||||
client.connect()
|
||||
except cqi.errors.CQiException:
|
||||
response = {'code': 500, 'msg': 'Internal Server Error'}
|
||||
except cqi.errors.CQiException as e:
|
||||
response = {'code': 500, 'desc': None,
|
||||
'msg': 'Internal Server Error',
|
||||
'payload': {'code': e.code, 'desc': e.description,
|
||||
'msg': e.name}}
|
||||
socketio.emit('pj_corpus_analysis_init', response, room=session_id)
|
||||
return
|
||||
pj_corpus_analysis_clients[session_id] = client
|
||||
@ -94,7 +106,7 @@ def pj_corpus_analysis_session_handler(app, corpus_id, user_id, session_id):
|
||||
pj_corpus_analysis_sessions[corpus_id] = [session_id]
|
||||
else:
|
||||
pj_corpus_analysis_sessions[corpus_id].append(session_id)
|
||||
response = {'code': 200, 'msg': 'OK'}
|
||||
response = {'code': 200, 'desc': None, 'msg': 'OK'}
|
||||
socketio.emit('pj_corpus_analysis_init', response, room=session_id)
|
||||
''' Observe analysis session '''
|
||||
while session_id in connected_sessions:
|
||||
|
Reference in New Issue
Block a user