mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-01-17 21:40:34 +00:00
Compare commits
No commits in common. "07103ee4e5aa34065c539d2ec8c4d61964cb68f2" and "e816a2fb15e65a5392ba000f9092f694e6f2ae0f" have entirely different histories.
07103ee4e5
...
e816a2fb15
@ -17,4 +17,3 @@ def before_request():
|
|||||||
|
|
||||||
|
|
||||||
from . import cli, cqi_over_socketio, files, followers, routes, json_routes
|
from . import cli, cqi_over_socketio, files, followers, routes, json_routes
|
||||||
from . import cqi_over_sio
|
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
from cqi import CQiClient
|
|
||||||
from cqi.errors import CQiException
|
|
||||||
from flask import session
|
|
||||||
from flask_login import current_user
|
|
||||||
from flask_socketio import ConnectionRefusedError
|
|
||||||
from threading import Lock
|
|
||||||
from app import db, hashids, socketio
|
|
||||||
from app.decorators import socketio_login_required
|
|
||||||
from app.models import Corpus, CorpusStatus
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
This package tunnels the Corpus Query interface (CQi) protocol through
|
|
||||||
Socket.IO (SIO) by wrapping each CQi function in a seperate SIO event.
|
|
||||||
|
|
||||||
This module only handles the SIO connect/disconnect, which handles the setup
|
|
||||||
and teardown of necessary ressources for later use. Each CQi function has a
|
|
||||||
corresponding SIO event. The event handlers are spread across the different
|
|
||||||
modules within this package.
|
|
||||||
|
|
||||||
Basic concept:
|
|
||||||
1. A client connects to the SIO namespace and provides the id of a corpus to be
|
|
||||||
analysed.
|
|
||||||
1.1 The analysis session counter of the corpus is incremented.
|
|
||||||
1.2 A CQiClient and a (Mutex) Lock belonging to it is created.
|
|
||||||
1.3 Wait until the CQP server is running.
|
|
||||||
1.4 Connect the CQiClient to the server.
|
|
||||||
1.5 Save the CQiClient and the Lock in the session for subsequential use.
|
|
||||||
2. A client emits an event and may provide a single json object with necessary
|
|
||||||
arguments for the targeted CQi function.
|
|
||||||
3. A SIO event handler (decorated with cqi_over_socketio) gets executed.
|
|
||||||
- The event handler function defines all arguments. Hence the client
|
|
||||||
is sent as a single json object, the decorator decomposes it to fit
|
|
||||||
the functions signature. This also includes type checking and proper
|
|
||||||
use of the lock (acquire/release) mechanism.
|
|
||||||
4. Wait for more events
|
|
||||||
5. The client disconnects from the SIO namespace
|
|
||||||
1.1 The analysis session counter of the corpus is decremented.
|
|
||||||
1.2 The CQiClient and (Mutex) Lock belonging to it are teared down.
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
NAMESPACE = '/cqi_over_sio'
|
|
||||||
|
|
||||||
|
|
||||||
from .cqi import * # noqa
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('connect', namespace=NAMESPACE)
|
|
||||||
@socketio_login_required
|
|
||||||
def connect(auth):
|
|
||||||
# the auth variable is used in a hacky way. It contains the corpus id for
|
|
||||||
# which a corpus analysis session should be started.
|
|
||||||
corpus_id = hashids.decode(auth['corpus_id'])
|
|
||||||
corpus = Corpus.query.get(corpus_id)
|
|
||||||
if corpus is None:
|
|
||||||
# return {'code': 404, 'msg': 'Not Found'}
|
|
||||||
raise ConnectionRefusedError('Not Found')
|
|
||||||
if not (corpus.user == current_user
|
|
||||||
or current_user.is_following_corpus(corpus)
|
|
||||||
or current_user.is_administrator()):
|
|
||||||
# return {'code': 403, 'msg': 'Forbidden'}
|
|
||||||
raise ConnectionRefusedError('Forbidden')
|
|
||||||
if corpus.status not in [
|
|
||||||
CorpusStatus.BUILT,
|
|
||||||
CorpusStatus.STARTING_ANALYSIS_SESSION,
|
|
||||||
CorpusStatus.RUNNING_ANALYSIS_SESSION,
|
|
||||||
CorpusStatus.CANCELING_ANALYSIS_SESSION
|
|
||||||
]:
|
|
||||||
# return {'code': 424, 'msg': 'Failed Dependency'}
|
|
||||||
raise ConnectionRefusedError('Failed Dependency')
|
|
||||||
if corpus.num_analysis_sessions is None:
|
|
||||||
corpus.num_analysis_sessions = 0
|
|
||||||
db.session.commit()
|
|
||||||
corpus.num_analysis_sessions = Corpus.num_analysis_sessions + 1
|
|
||||||
db.session.commit()
|
|
||||||
retry_counter = 20
|
|
||||||
while corpus.status != CorpusStatus.RUNNING_ANALYSIS_SESSION:
|
|
||||||
if retry_counter == 0:
|
|
||||||
corpus.num_analysis_sessions = Corpus.num_analysis_sessions - 1
|
|
||||||
db.session.commit()
|
|
||||||
return {'code': 408, 'msg': 'Request Timeout'}
|
|
||||||
socketio.sleep(3)
|
|
||||||
retry_counter -= 1
|
|
||||||
db.session.refresh(corpus)
|
|
||||||
cqi_client = CQiClient(f'cqpserver_{corpus_id}')
|
|
||||||
session['cqi_over_sio'] = {
|
|
||||||
'corpus_id': corpus_id,
|
|
||||||
'cqi_client': cqi_client,
|
|
||||||
'cqi_client_lock': Lock(),
|
|
||||||
}
|
|
||||||
# return {'code': 200, 'msg': 'OK'}
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('disconnect', namespace=NAMESPACE)
|
|
||||||
def disconnect():
|
|
||||||
try:
|
|
||||||
cqi_client: CQiClient = session['cqi_over_sio']['cqi_client']
|
|
||||||
cqi_client_lock: Lock = session['cqi_over_sio']['cqi_client_lock']
|
|
||||||
except KeyError:
|
|
||||||
return
|
|
||||||
cqi_client_lock.acquire()
|
|
||||||
try:
|
|
||||||
cqi_client.api.ctrl_bye()
|
|
||||||
except (BrokenPipeError, CQiException):
|
|
||||||
pass
|
|
||||||
cqi_client_lock.release()
|
|
||||||
corpus = Corpus.query.get(session['cqi_over_sio']['corpus_id'])
|
|
||||||
corpus.num_analysis_sessions = Corpus.num_analysis_sessions - 1
|
|
||||||
db.session.commit()
|
|
||||||
session.pop('cqi_over_sio')
|
|
||||||
# return {'code': 200, 'msg': 'OK'}
|
|
@ -1,114 +0,0 @@
|
|||||||
from cqi import CQiClient
|
|
||||||
from cqi.errors import CQiException
|
|
||||||
from cqi.status import CQiStatus
|
|
||||||
from flask import session
|
|
||||||
from inspect import signature
|
|
||||||
from threading import Lock
|
|
||||||
from typing import Callable, Dict, List
|
|
||||||
from app import socketio
|
|
||||||
from app.decorators import socketio_login_required
|
|
||||||
from . import NAMESPACE as ns
|
|
||||||
|
|
||||||
|
|
||||||
CQI_API_FUNCTIONS: List[str] = [
|
|
||||||
'ask_feature_cl_2_3',
|
|
||||||
'ask_feature_cqi_1_0',
|
|
||||||
'ask_feature_cqp_2_3',
|
|
||||||
'cl_alg2cpos',
|
|
||||||
'cl_attribute_size',
|
|
||||||
'cl_cpos2alg',
|
|
||||||
'cl_cpos2id',
|
|
||||||
'cl_cpos2lbound',
|
|
||||||
'cl_cpos2rbound',
|
|
||||||
'cl_cpos2str',
|
|
||||||
'cl_cpos2struc',
|
|
||||||
'cl_drop_attribute',
|
|
||||||
'cl_id2cpos',
|
|
||||||
'cl_id2freq',
|
|
||||||
'cl_id2str',
|
|
||||||
'cl_idlist2cpos',
|
|
||||||
'cl_lexicon_size',
|
|
||||||
'cl_regex2id',
|
|
||||||
'cl_str2id',
|
|
||||||
'cl_struc2cpos',
|
|
||||||
'cl_struc2str',
|
|
||||||
'corpus_alignment_attributes',
|
|
||||||
'corpus_charset',
|
|
||||||
'corpus_drop_corpus',
|
|
||||||
'corpus_full_name',
|
|
||||||
'corpus_info',
|
|
||||||
'corpus_list_corpora',
|
|
||||||
'corpus_positional_attributes',
|
|
||||||
'corpus_properties',
|
|
||||||
'corpus_structural_attribute_has_values',
|
|
||||||
'corpus_structural_attributes',
|
|
||||||
'cqp_drop_subcorpus',
|
|
||||||
'cqp_dump_subcorpus',
|
|
||||||
'cqp_fdist_1',
|
|
||||||
'cqp_fdist_2',
|
|
||||||
'cqp_list_subcorpora',
|
|
||||||
'cqp_query',
|
|
||||||
'cqp_subcorpus_has_field',
|
|
||||||
'cqp_subcorpus_size',
|
|
||||||
'ctrl_bye',
|
|
||||||
'ctrl_connect',
|
|
||||||
'ctrl_last_general_error',
|
|
||||||
'ctrl_ping',
|
|
||||||
'ctrl_user_abort'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('cqi_client.api', namespace=ns)
|
|
||||||
@socketio_login_required
|
|
||||||
def cqi_over_sio(fn_data):
|
|
||||||
try:
|
|
||||||
fn_name: str = fn_data['fn_name']
|
|
||||||
if fn_name not in CQI_API_FUNCTIONS:
|
|
||||||
raise KeyError
|
|
||||||
except KeyError:
|
|
||||||
return {'code': 400, 'msg': 'Bad Request'}
|
|
||||||
fn_name: str = fn_data['fn_name']
|
|
||||||
fn_args: Dict = fn_data.get('fn_args', {})
|
|
||||||
try:
|
|
||||||
cqi_client: CQiClient = session['cqi_over_sio']['cqi_client']
|
|
||||||
cqi_client_lock: Lock = session['cqi_over_sio']['cqi_client_lock']
|
|
||||||
except KeyError:
|
|
||||||
return {'code': 424, 'msg': 'Failed Dependency'}
|
|
||||||
fn: Callable = getattr(cqi_client.api, fn_name)
|
|
||||||
for param in signature(fn).parameters.values():
|
|
||||||
if param.default is param.empty:
|
|
||||||
if param.name not in fn_args:
|
|
||||||
return {'code': 400, 'msg': 'Bad Request'}
|
|
||||||
else:
|
|
||||||
if param.name not in fn_args:
|
|
||||||
continue
|
|
||||||
if type(fn_args[param.name]) is not param.annotation:
|
|
||||||
return {'code': 400, 'msg': 'Bad Request'}
|
|
||||||
cqi_client_lock.acquire()
|
|
||||||
try:
|
|
||||||
return_value = fn(**fn_args)
|
|
||||||
except BrokenPipeError:
|
|
||||||
return_value = {
|
|
||||||
'code': 500,
|
|
||||||
'msg': 'Internal Server Error'
|
|
||||||
}
|
|
||||||
except CQiException as e:
|
|
||||||
return_value = {
|
|
||||||
'code': 502,
|
|
||||||
'msg': 'Bad Gateway',
|
|
||||||
'payload': {
|
|
||||||
'code': e.code,
|
|
||||||
'desc': e.description,
|
|
||||||
'msg': e.__class__.__name__
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally:
|
|
||||||
cqi_client_lock.release()
|
|
||||||
if isinstance(return_value, CQiStatus):
|
|
||||||
payload = {
|
|
||||||
'code': return_value.code,
|
|
||||||
'msg': return_value.__class__.__name__
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
payload = return_value
|
|
||||||
return {'code': 200, 'msg': 'OK', 'payload': payload}
|
|
@ -49,7 +49,7 @@ def cqi_over_socketio(f):
|
|||||||
'payload': {
|
'payload': {
|
||||||
'code': e.code,
|
'code': e.code,
|
||||||
'desc': e.description,
|
'desc': e.description,
|
||||||
'msg': e.__class__.__name__
|
'msg': e.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally:
|
finally:
|
||||||
|
@ -1,598 +0,0 @@
|
|||||||
cqi.api.APIClient = class APIClient {
|
|
||||||
constructor(host, corpus_id, version = '0.1') {
|
|
||||||
this.host = host;
|
|
||||||
this.version = version;
|
|
||||||
this.socket = io(
|
|
||||||
this.host,
|
|
||||||
{
|
|
||||||
auth: {corpus_id: corpus_id},
|
|
||||||
transports: ['websocket'],
|
|
||||||
upgrade: false
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} fn_name
|
|
||||||
* @param {object} [fn_args={}]
|
|
||||||
* @returns {Promise<cqi.status.StatusConnectOk>}
|
|
||||||
*/
|
|
||||||
#request(fn_name, fn_args = {}) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.socket.emit('cqi_client.api', {fn_name: fn_name, fn_args: fn_args}, (response) => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
resolve(response.payload);
|
|
||||||
}
|
|
||||||
if (response.code === 500) {
|
|
||||||
reject(new Error(`[${response.code}] ${response.msg}`));
|
|
||||||
}
|
|
||||||
if (response.code === 502) {
|
|
||||||
reject(new cqi.errors.lookup[response.payload.code]());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} username
|
|
||||||
* @param {string} password
|
|
||||||
* @returns {Promise<cqi.status.StatusConnectOk>}
|
|
||||||
*/
|
|
||||||
async ctrl_connect(username, password) {
|
|
||||||
const fn_name = 'ctrl_connect';
|
|
||||||
const fn_args = {username: username, password: password};
|
|
||||||
let payload = await this.#request(fn_name, fn_args);
|
|
||||||
return new cqi.status.lookup[payload.code]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.status.StatusByeOk>}
|
|
||||||
*/
|
|
||||||
async ctrl_bye() {
|
|
||||||
const fn_name = 'ctrl_bye';
|
|
||||||
let payload = await this.#request(fn_name);
|
|
||||||
return new cqi.status.lookup[payload.code]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<null>}
|
|
||||||
*/
|
|
||||||
async ctrl_user_abort() {
|
|
||||||
const fn_name = 'ctrl_user_abort';
|
|
||||||
return await this.#request(fn_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.status.StatusPingOk>}
|
|
||||||
*/
|
|
||||||
async ctrl_ping() {
|
|
||||||
const fn_name = 'ctrl_ping';
|
|
||||||
let payload = await this.#request(fn_name);
|
|
||||||
return new cqi.status.lookup[payload.code]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Full-text error message for the last general error reported
|
|
||||||
* by the CQi server
|
|
||||||
*
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async ctrl_last_general_error() {
|
|
||||||
const fn_name = 'ctrl_last_general_error';
|
|
||||||
return await this.#request(fn_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
async ask_feature_cqi_1_0() {
|
|
||||||
const fn_name = 'ask_feature_cqi_1_0';
|
|
||||||
return await this.#request(fn_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
async ask_feature_cl_2_3() {
|
|
||||||
const fn_name = 'ask_feature_cl_2_3';
|
|
||||||
return await this.#request(fn_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
async ask_feature_cqp_2_3() {
|
|
||||||
const fn_name = 'ask_feature_cqp_2_3';
|
|
||||||
return await this.#request(fn_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async corpus_list_corpora() {
|
|
||||||
const fn_name = 'corpus_list_corpora';
|
|
||||||
return await this.#request(fn_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async corpus_charset(corpus) {
|
|
||||||
const fn_name = 'corpus_charset';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async corpus_properties(corpus) {
|
|
||||||
const fn_name = 'corpus_properties';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async corpus_positional_attributes(corpus) {
|
|
||||||
const fn_name = 'corpus_positional_attributes';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async corpus_structural_attributes(corpus) {
|
|
||||||
const fn_name = 'corpus_structural_attributes';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpus
|
|
||||||
* @param {string} attribute
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
async corpus_structural_attribute_has_values(corpus, attribute) {
|
|
||||||
const fn_name = 'corpus_structural_attribute_has_values';
|
|
||||||
const fn_args = {corpus: corpus, attribute: attribute};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async corpus_alignment_attributes(corpus) {
|
|
||||||
const fn_name = 'corpus_alignment_attributes';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the full name of <corpus> as specified in its registry entry
|
|
||||||
*
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async corpus_full_name(corpus) {
|
|
||||||
const fn_name = 'corpus_full_name';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the contents of the .info file of <corpus> as a list of lines
|
|
||||||
*
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async corpus_info(corpus) {
|
|
||||||
const fn_name = 'corpus_info';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* try to unload a corpus and all its attributes from memory
|
|
||||||
*
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async corpus_drop_corpus(corpus) {
|
|
||||||
const fn_name = 'corpus_drop_corpus';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
let payload = await this.#request(fn_name, fn_args);
|
|
||||||
return new cqi.status.lookup[payload.code]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the size of <attribute>:
|
|
||||||
* - number of tokens (positional)
|
|
||||||
* - number of regions (structural)
|
|
||||||
* - number of alignments (alignment)
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @returns {Promise<number>}
|
|
||||||
*/
|
|
||||||
async cl_attribute_size(attribute) {
|
|
||||||
const fn_name = 'cl_attribute_size';
|
|
||||||
const fn_args = {attribute: attribute};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the number of entries in the lexicon of a positional attribute;
|
|
||||||
*
|
|
||||||
* valid lexicon IDs range from 0 .. (lexicon_size - 1)
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @returns {Promise<number>}
|
|
||||||
*/
|
|
||||||
async cl_lexicon_size(attribute) {
|
|
||||||
const fn_name = 'cl_lexicon_size';
|
|
||||||
const fn_args = {attribute: attribute};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unload attribute from memory
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async cl_drop_attribute(attribute) {
|
|
||||||
const fn_name = 'cl_drop_attribute';
|
|
||||||
const fn_args = {attribute: attribute};
|
|
||||||
let payload = await this.#request(fn_name, fn_args);
|
|
||||||
return new cqi.status.lookup[payload.code]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: simple (scalar) mappings are applied to lists (the returned list
|
|
||||||
* has exactly the same length as the list passed as an argument)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns -1 for every string in <strings> that is not found in the lexicon
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {strings[]} string
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_str2id(attribute, strings) {
|
|
||||||
const fn_name = 'cl_str2id';
|
|
||||||
const fn_args = {attribute: attribute, strings: strings};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns "" for every ID in <id> that is out of range
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} id
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async cl_id2str(attribute, id) {
|
|
||||||
const fn_name = 'cl_id2str';
|
|
||||||
const fn_args = {attribute: attribute, id: id};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns 0 for every ID in <id> that is out of range
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} id
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_id2freq(attribute, id) {
|
|
||||||
const fn_name = 'cl_id2freq';
|
|
||||||
const fn_args = {attribute: attribute, id: id};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns -1 for every corpus position in <cpos> that is out of range
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} cpos
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_cpos2id(attribute, cpos) {
|
|
||||||
const fn_name = 'cl_cpos2id';
|
|
||||||
const fn_args = {attribute: attribute, cpos: cpos};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns "" for every corpus position in <cpos> that is out of range
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} cpos
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async cl_cpos2str(attribute, cpos) {
|
|
||||||
const fn_name = 'cl_cpos2str';
|
|
||||||
const fn_args = {attribute: attribute, cpos: cpos};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns -1 for every corpus position not inside a structure region
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} cpos
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_cpos2struc(attribute, cpos) {
|
|
||||||
const fn_name = 'cl_cpos2struc';
|
|
||||||
const fn_args = {attribute: attribute, cpos: cpos};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: temporary addition for the Euralex2000 tutorial, but should
|
|
||||||
* probably be included in CQi specs
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns left boundary of s-attribute region enclosing cpos,
|
|
||||||
* -1 if not in region
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} cpos
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_cpos2lbound(attribute, cpos) {
|
|
||||||
const fn_name = 'cl_cpos2lbound';
|
|
||||||
const fn_args = {attribute: attribute, cpos: cpos};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns right boundary of s-attribute region enclosing cpos,
|
|
||||||
* -1 if not in region
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} cpos
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_cpos2rbound(attribute, cpos) {
|
|
||||||
const fn_name = 'cl_cpos2rbound';
|
|
||||||
const fn_args = {attribute: attribute, cpos: cpos};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns -1 for every corpus position not inside an alignment
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} cpos
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_cpos2alg(attribute, cpos) {
|
|
||||||
const fn_name = 'cl_cpos2alg';
|
|
||||||
const fn_args = {attribute: attribute, cpos: cpos};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns annotated string values of structure regions in <strucs>;
|
|
||||||
* "" if out of range
|
|
||||||
*
|
|
||||||
* check corpus_structural_attribute_has_values(<attribute>) first
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} strucs
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async cl_struc2str(attribute, strucs) {
|
|
||||||
const fn_name = 'cl_struc2str';
|
|
||||||
const fn_args = {attribute: attribute, strucs: strucs};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: the following mappings take a single argument and return multiple
|
|
||||||
* values, including lists of arbitrary size
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns all corpus positions where the given token occurs
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number} id
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_id2cpos(attribute, id) {
|
|
||||||
const fn_name = 'cl_id2cpos';
|
|
||||||
const fn_args = {attribute: attribute, id: id};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns all corpus positions where one of the tokens in <id_list> occurs;
|
|
||||||
* the returned list is sorted as a whole, not per token id
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number[]} id_list
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_idlist2cpos(attribute, id_list) {
|
|
||||||
const fn_name = 'cl_idlist2cpos';
|
|
||||||
const fn_args = {attribute: attribute, id_list: id_list};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns lexicon IDs of all tokens that match <regex>;
|
|
||||||
* the returned list may be empty (size 0);
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {string} regex
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cl_regex2id(attribute, regex) {
|
|
||||||
const fn_name = 'cl_regex2id';
|
|
||||||
const fn_args = {attribute: attribute, regex: regex};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns start and end corpus positions of structure region <struc>
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number} struc
|
|
||||||
* @returns {Promise<[number, number]>}
|
|
||||||
*/
|
|
||||||
async cl_struc2cpos(attribute, struc) {
|
|
||||||
const fn_name = 'cl_struc2cpos';
|
|
||||||
const fn_args = {attribute: attribute, struc: struc};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns (src_start, src_end, target_start, target_end)
|
|
||||||
*
|
|
||||||
* @param {string} attribute
|
|
||||||
* @param {number} alg
|
|
||||||
* @returns {Promise<[number, number, number, number]>}
|
|
||||||
*/
|
|
||||||
async alg2cpos(attribute, alg) {
|
|
||||||
const fn_name = 'alg2cpos';
|
|
||||||
const fn_args = {attribute: attribute, alg: alg};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <query> must include the ';' character terminating the query.
|
|
||||||
*
|
|
||||||
* @param {string} mother_corpus
|
|
||||||
* @param {string} subcorpus_name
|
|
||||||
* @param {string} query
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async cqp_query(mother_corpus, subcorpus_name, query) {
|
|
||||||
const fn_name = 'cqp_query';
|
|
||||||
const fn_args = {mother_corpus: mother_corpus, subcorpus_name: subcorpus_name, query: query};
|
|
||||||
let payload = await this.#request(fn_name, fn_args);
|
|
||||||
return new cqi.status.lookup[payload.code]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpus
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async cqp_list_subcorpora(corpus) {
|
|
||||||
const fn_name = 'cqp_list_subcorpora';
|
|
||||||
const fn_args = {corpus: corpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} subcorpus
|
|
||||||
* @returns {Promise<number>}
|
|
||||||
*/
|
|
||||||
async cqp_subcorpus_size(subcorpus) {
|
|
||||||
const fn_name = 'cqp_subcorpus_size';
|
|
||||||
const fn_args = {subcorpus: subcorpus};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} subcorpus
|
|
||||||
* @param {number} field
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
async cqp_subcorpus_has_field(subcorpus, field) {
|
|
||||||
const fn_name = 'cqp_subcorpus_has_field';
|
|
||||||
const fn_args = {subcorpus: subcorpus, field: field};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump the values of <field> for match ranges <first> .. <last>
|
|
||||||
* in <subcorpus>. <field> is one of the CQI_CONST_FIELD_* constants.
|
|
||||||
*
|
|
||||||
* @param {string} subcorpus
|
|
||||||
* @param {number} field
|
|
||||||
* @param {number} first
|
|
||||||
* @param {number} last
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cqp_dump_subcorpus(subcorpus, field, first, last) {
|
|
||||||
const fn_name = 'cqp_dump_subcorpus';
|
|
||||||
const fn_args = {subcorpus: subcorpus, field: field, first: first, last: last};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* delete a subcorpus from memory
|
|
||||||
*
|
|
||||||
* @param {string} subcorpus
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async cqp_drop_subcorpus(subcorpus) {
|
|
||||||
const fn_name = 'cqp_drop_subcorpus';
|
|
||||||
const fn_args = {subcorpus: subcorpus};
|
|
||||||
let payload = await this.#request(fn_name, fn_args);
|
|
||||||
return new cqi.status.lookup[payload.code]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: The following two functions are temporarily included for the
|
|
||||||
* Euralex 2000 tutorial demo
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* frequency distribution of single tokens
|
|
||||||
*
|
|
||||||
* returns <n> (id, frequency) pairs flattened into a list of size 2*<n>
|
|
||||||
* field is one of
|
|
||||||
* - CQI_CONST_FIELD_MATCH
|
|
||||||
* - CQI_CONST_FIELD_TARGET
|
|
||||||
* - CQI_CONST_FIELD_KEYWORD
|
|
||||||
*
|
|
||||||
* NB: pairs are sorted by frequency desc.
|
|
||||||
*
|
|
||||||
* @param {string} subcorpus
|
|
||||||
* @param {number} cutoff
|
|
||||||
* @param {number} field
|
|
||||||
* @param {string} attribute
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cqp_fdist_1(subcorpus, cutoff, field, attribute) {
|
|
||||||
const fn_name = 'cqp_fdist_1';
|
|
||||||
const fn_args = {subcorpus: subcorpus, cutoff: cutoff, field: field, attribute: attribute};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* frequency distribution of pairs of tokens
|
|
||||||
*
|
|
||||||
* returns <n> (id1, id2, frequency) pairs flattened into a list of
|
|
||||||
* size 3*<n>
|
|
||||||
*
|
|
||||||
* NB: triples are sorted by frequency desc.
|
|
||||||
*
|
|
||||||
* @param {string} subcorpus
|
|
||||||
* @param {number} cutoff
|
|
||||||
* @param {number} field1
|
|
||||||
* @param {string} attribute1
|
|
||||||
* @param {number} field2
|
|
||||||
* @param {string} attribute2
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cqp_fdist_2(subcorpus, cutoff, field1, attribute1, field2, attribute2) {
|
|
||||||
const fn_name = 'cqp_fdist_2';
|
|
||||||
const fn_args = {subcorpus: subcorpus, cutoff: cutoff, field1: field1, attribute1: attribute1, field2: field2, attribute2: attribute2};
|
|
||||||
return await this.#request(fn_name, fn_args);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1 +0,0 @@
|
|||||||
cqi.api = {};
|
|
@ -1,57 +0,0 @@
|
|||||||
cqi.CQiClient = class CQiClient {
|
|
||||||
/**
|
|
||||||
* @param {string} host
|
|
||||||
* @param {string} corpusId
|
|
||||||
* @param {string} [version=0.1] version
|
|
||||||
*/
|
|
||||||
constructor(host, corpusId, version = '0.1') {
|
|
||||||
/** @type {cqi.api.APIClient} */
|
|
||||||
this.api = new cqi.api.APIClient(host, corpusId, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {cqi.models.corpora.CorpusCollection}
|
|
||||||
*/
|
|
||||||
get corpora() {
|
|
||||||
return new cqi.models.corpora.CorpusCollection(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.status.StatusByeOk>}
|
|
||||||
*/
|
|
||||||
async bye() {
|
|
||||||
return await this.api.ctrl_bye();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} username
|
|
||||||
* @param {string} password
|
|
||||||
* @returns {Promise<cqi.status.StatusConnectOk>}
|
|
||||||
*/
|
|
||||||
async connect(username, password) {
|
|
||||||
return await this.api.ctrl_connect(username, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.status.StatusPingOk>}
|
|
||||||
*/
|
|
||||||
async ping() {
|
|
||||||
return await this.api.ctrl_ping();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<null>}
|
|
||||||
*/
|
|
||||||
async userAbort() {
|
|
||||||
return await this.api.ctrl_user_abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for "bye" method
|
|
||||||
*
|
|
||||||
* @returns {Promise<cqi.status.StatusByeOk>}
|
|
||||||
*/
|
|
||||||
async disconnect() {
|
|
||||||
return await this.api.ctrl_bye();
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,185 +0,0 @@
|
|||||||
cqi.errors = {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class from which all other errors inherit.
|
|
||||||
* If you want to catch all errors that the CQi package might throw,
|
|
||||||
* catch this base error.
|
|
||||||
*/
|
|
||||||
cqi.errors.CQiError = class CQiError extends Error {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = undefined;
|
|
||||||
this.description = undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.Error = class Error extends cqi.errors.CQiError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.ErrorGeneralError = class ErrorGeneralError extends cqi.errors.Error {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 513;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.ErrorConnectRefused = class ErrorConnectRefused extends cqi.errors.Error {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 514;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.ErrorUserAbort = class ErrorUserAbort extends cqi.errors.Error {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 515;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.ErrorSyntaxError = class ErrorSyntaxError extends cqi.errors.Error {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 516;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLError = class Error extends cqi.errors.CQiError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 4;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLErrorNoSuchAttribute = class CLErrorNoSuchAttribute extends cqi.errors.CLError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1025;
|
|
||||||
this.description = "CQi server couldn't open attribute";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLErrorWrongAttributeType = class CLErrorWrongAttributeType extends cqi.errors.CLError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1026;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLErrorOutOfRange = class CLErrorOutOfRange extends cqi.errors.CLError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1027;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLErrorRegex = class CLErrorRegex extends cqi.errors.CLError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1028;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLErrorCorpusAccess = class CLErrorCorpusAccess extends cqi.errors.CLError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1029;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLErrorOutOfMemory = class CLErrorOutOfMemory extends cqi.errors.CLError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1030;
|
|
||||||
this.description = 'CQi server has run out of memory; try discarding some other corpora and/or subcorpora';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CLErrorInternal = class CLErrorInternal extends cqi.errors.CLError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1031;
|
|
||||||
this.description = "The classical 'please contact technical support' error";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CQPError = class Error extends cqi.errors.CQiError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 5;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CQPErrorGeneral = class CQPErrorGeneral extends cqi.errors.CQPError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1281;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CQPErrorNoSuchCorpus = class CQPErrorNoSuchCorpus extends cqi.errors.CQPError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1282;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CQPErrorInvalidField = class CQPErrorInvalidField extends cqi.errors.CQPError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1283;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.CQPErrorOutOfRange = class CQPErrorOutOfRange extends cqi.errors.CQPError {
|
|
||||||
constructor(message) {
|
|
||||||
super(message);
|
|
||||||
this.code = 1284;
|
|
||||||
this.description = 'A number is out of range';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.errors.lookup = {
|
|
||||||
2: cqi.errors.Error,
|
|
||||||
513: cqi.errors.ErrorGeneralError,
|
|
||||||
514: cqi.errors.ErrorConnectRefused,
|
|
||||||
515: cqi.errors.ErrorUserAbort,
|
|
||||||
516: cqi.errors.ErrorSyntaxError,
|
|
||||||
4: cqi.errors.CLError,
|
|
||||||
1025: cqi.errors.CLErrorNoSuchAttribute,
|
|
||||||
1026: cqi.errors.CLErrorWrongAttributeType,
|
|
||||||
1027: cqi.errors.CLErrorOutOfRange,
|
|
||||||
1028: cqi.errors.CLErrorRegex,
|
|
||||||
1029: cqi.errors.CLErrorCorpusAccess,
|
|
||||||
1030: cqi.errors.CLErrorOutOfMemory,
|
|
||||||
1031: cqi.errors.CLErrorInternal,
|
|
||||||
5: cqi.errors.CQPError,
|
|
||||||
1281: cqi.errors.CQPErrorGeneral,
|
|
||||||
1282: cqi.errors.CQPErrorNoSuchCorpus,
|
|
||||||
1283: cqi.errors.CQPErrorInvalidField,
|
|
||||||
1284: cqi.errors.CQPErrorOutOfRange
|
|
||||||
};
|
|
@ -1,289 +0,0 @@
|
|||||||
cqi.models.attributes = {};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.Attribute = class Attribute extends cqi.models.resource.Model {
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get apiName() {
|
|
||||||
return this.attrs.api_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get name() {
|
|
||||||
return this.attrs.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
get size() {
|
|
||||||
return this.attrs.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async drop() {
|
|
||||||
return await this.client.api.cl_drop_attribute(this.apiName);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.AttributeCollection = class AttributeCollection extends cqi.models.resource.Collection {
|
|
||||||
/** @type{typeof cqi.models.attributes.Attribute} */
|
|
||||||
static model = cqi.models.attributes.Attribute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {cqi.CQiClient} client
|
|
||||||
* @param {cqi.models.corpora.Corpus} corpus
|
|
||||||
*/
|
|
||||||
constructor(client, corpus) {
|
|
||||||
super(client);
|
|
||||||
/** @type {cqi.models.corpora.Corpus} */
|
|
||||||
this.corpus = corpus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} attributeName
|
|
||||||
* @returns {Promise<object>}
|
|
||||||
*/
|
|
||||||
async _get(attributeName) {
|
|
||||||
/** @type{string} */
|
|
||||||
let apiName = `${this.corpus.apiName}.${attributeName}`;
|
|
||||||
return {
|
|
||||||
api_name: apiName,
|
|
||||||
name: attributeName,
|
|
||||||
size: await this.client.api.cl_attribute_size(apiName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} attributeName
|
|
||||||
* @returns {Promise<cqi.models.attributes.Attribute>}
|
|
||||||
*/
|
|
||||||
async get(attributeName) {
|
|
||||||
return this.prepareModel(await this._get(attributeName));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.AlignmentAttribute = class AlignmentAttribute extends cqi.models.attributes.Attribute {
|
|
||||||
/**
|
|
||||||
* @param {number} id
|
|
||||||
* @returns {Promise<[number, number, number, number]>}
|
|
||||||
*/
|
|
||||||
async cposById(id) {
|
|
||||||
return await this.client.api.cl_alg2cpos(this.apiName, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} cposList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async idsByCpos(cposList) {
|
|
||||||
return await this.client.api.cl_cpos2alg(this.apiName, cposList);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.AlignmentAttributeCollection = class AlignmentAttributeCollection extends cqi.models.attributes.AttributeCollection {
|
|
||||||
/** @type{typeof cqi.models.attributes.AlignmentAttribute} */
|
|
||||||
static model = cqi.models.attributes.AlignmentAttribute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.models.attributes.AlignmentAttribute[]>}
|
|
||||||
*/
|
|
||||||
async list() {
|
|
||||||
/** @type {string[]} */
|
|
||||||
let alignmentAttributeNames = await this.client.api.corpus_alignment_attributes(this.corpus.apiName);
|
|
||||||
/** @type {cqi.models.attributes.AlignmentAttribute[]} */
|
|
||||||
let alignmentAttributes = [];
|
|
||||||
for (let alignmentAttributeName of alignmentAttributeNames) {
|
|
||||||
alignmentAttributes.push(await this.get(alignmentAttributeName));
|
|
||||||
}
|
|
||||||
return alignmentAttributes;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.PositionalAttribute = class PositionalAttribute extends cqi.models.attributes.Attribute {
|
|
||||||
/**
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
get lexiconSize() {
|
|
||||||
return this.attrs.lexicon_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} id
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cposById(id) {
|
|
||||||
return await this.client.api.cl_id2cpos(this.apiName, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} idList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async cposByIds(idList) {
|
|
||||||
return await this.client.api.cl_idlist2cpos(this.apiName, idList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} idList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async freqsByIds(idList) {
|
|
||||||
return await this.client.api.cl_id2freq(this.apiName, idList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} cposList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async idsByCpos(cposList) {
|
|
||||||
return await this.client.api.cl_cpos2id(this.apiName, cposList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} regex
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async idsByRegex(regex) {
|
|
||||||
return await this.client.api.cl_regex2id(this.apiName, regex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string[]} valueList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async idsByValues(valueList) {
|
|
||||||
return await this.client.api.cl_str2id(this.apiName, valueList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} cposList
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async valuesByCpos(cposList) {
|
|
||||||
return await this.client.api.cl_cpos2str(this.apiName, cposList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} idList
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async valuesByIds(idList) {
|
|
||||||
return await this.client.api.cl_id2str(this.apiName, idList);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.PositionalAttributeCollection = class PositionalAttributeCollection extends cqi.models.attributes.AttributeCollection {
|
|
||||||
/** @type{typeof cqi.models.attributes.PositionalAttribute} */
|
|
||||||
static model = cqi.models.attributes.PositionalAttribute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} positionalAttributeName
|
|
||||||
* @returns {Promise<object>}
|
|
||||||
*/
|
|
||||||
async _get(positionalAttributeName) {
|
|
||||||
let positionalAttribute = await super._get(positionalAttributeName);
|
|
||||||
positionalAttribute.lexicon_size = await this.client.api.cl_lexicon_size(positionalAttribute.api_name);
|
|
||||||
return positionalAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.models.attributes.PositionalAttribute[]>}
|
|
||||||
*/
|
|
||||||
async list() {
|
|
||||||
let positionalAttributeNames = await this.client.api.corpus_positional_attributes(this.corpus.apiName);
|
|
||||||
let positionalAttributes = [];
|
|
||||||
for (let positionalAttributeName of positionalAttributeNames) {
|
|
||||||
positionalAttributes.push(await this.get(positionalAttributeName));
|
|
||||||
}
|
|
||||||
return positionalAttributes;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.StructuralAttribute = class StructuralAttribute extends cqi.models.attributes.Attribute {
|
|
||||||
/**
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
get hasValues() {
|
|
||||||
return this.attrs.has_values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} id
|
|
||||||
* @returns {Promise<[number, number]>}
|
|
||||||
*/
|
|
||||||
async cposById(id) {
|
|
||||||
return await this.client.api.cl_struc2cpos(this.apiName, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} cposList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async idsByCpos(cposList) {
|
|
||||||
return await this.client.api.cl_cpos2struc(this.apiName, cposList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} cposList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async lboundByCpos(cposList) {
|
|
||||||
return await this.client.api.cl_cpos2lbound(this.apiName, cposList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} cposList
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async rboundByCpos(cposList) {
|
|
||||||
return await this.client.api.cl_cpos2rbound(this.apiName, cposList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number[]} idList
|
|
||||||
* @returns {Promise<string[]>}
|
|
||||||
*/
|
|
||||||
async valuesByIds(idList) {
|
|
||||||
return await this.client.api.cl_struc2str(this.apiName, idList);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.attributes.StructuralAttributeCollection = class StructuralAttributeCollection extends cqi.models.attributes.AttributeCollection {
|
|
||||||
/** @type{typeof cqi.models.attributes.StructuralAttribute} */
|
|
||||||
static model = cqi.models.attributes.StructuralAttribute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} structuralAttributeName
|
|
||||||
* @returns {Promise<object>}
|
|
||||||
*/
|
|
||||||
async _get(structuralAttributeName) {
|
|
||||||
let structuralAttribute = await super._get(structuralAttributeName);
|
|
||||||
structuralAttribute.has_values = await this.client.api.cl_has_values(structuralAttribute.api_name);
|
|
||||||
return structuralAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.models.attributes.StructuralAttribute[]>}
|
|
||||||
*/
|
|
||||||
async list() {
|
|
||||||
let structuralAttributeNames = await this.client.api.corpus_structural_attributes(this.corpus.apiName);
|
|
||||||
let structuralAttributes = [];
|
|
||||||
for (let structuralAttributeName of structuralAttributeNames) {
|
|
||||||
structuralAttributes.push(await this.get(structuralAttributeName));
|
|
||||||
}
|
|
||||||
return structuralAttributes;
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,127 +0,0 @@
|
|||||||
cqi.models.corpora = {};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.corpora.Corpus = class Corpus extends cqi.models.resource.Model {
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get apiName() {
|
|
||||||
return this.attrs.api_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get name() {
|
|
||||||
return this.attrs.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
get size() {
|
|
||||||
return this.attrs.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get charset() {
|
|
||||||
return this.attrs.charset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string[]}
|
|
||||||
*/
|
|
||||||
get properties() {
|
|
||||||
return this.attrs?.properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {cqi.models.attributes.AlignmentAttributeCollection}
|
|
||||||
*/
|
|
||||||
get alignmentAttributes() {
|
|
||||||
return new cqi.models.attributes.AlignmentAttributeCollection(this.client, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {cqi.models.attributes.PositionalAttributeCollection}
|
|
||||||
*/
|
|
||||||
get positionalAttributes() {
|
|
||||||
return new cqi.models.attributes.PositionalAttributeCollection(this.client, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {cqi.models.attributes.StructuralAttributeCollection}
|
|
||||||
*/
|
|
||||||
get structuralAttributes() {
|
|
||||||
return new cqi.models.attributes.StructuralAttributeCollection(this.client, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {cqi.models.subcorpora.SubcorpusCollection}
|
|
||||||
*/
|
|
||||||
get subcorpora() {
|
|
||||||
return new cqi.models.subcorpora.SubcorpusCollection(this.client, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async drop() {
|
|
||||||
return await this.client.api.corpus_drop_corpus(this.apiName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} subcorpusName
|
|
||||||
* @param {string} query
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async query(subcorpusName, query) {
|
|
||||||
return await this.client.api.cqp_query(this.apiName, subcorpusName, query);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.corpora.CorpusCollection = class CorpusCollection extends cqi.models.resource.Collection {
|
|
||||||
/** @type {typeof cqi.models.corpora.Corpus} */
|
|
||||||
static model = cqi.models.corpora.Corpus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpusName
|
|
||||||
* @returns {Promise<object>}
|
|
||||||
*/
|
|
||||||
async _get(corpusName) {
|
|
||||||
return {
|
|
||||||
api_name: corpusName,
|
|
||||||
charset: await this.client.api.corpus_charset(corpusName),
|
|
||||||
// full_name: await this.client.api.corpus_full_name(api_name),
|
|
||||||
// info: await this.client.api.corpus_info(api_name),
|
|
||||||
name: corpusName,
|
|
||||||
properties: await this.client.api.corpus_properties(corpusName),
|
|
||||||
size: await this.client.api.cl_attribute_size(`${corpusName}.word`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} corpusName
|
|
||||||
* @returns {Promise<cqi.models.corpora.Corpus>}
|
|
||||||
*/
|
|
||||||
async get(corpusName) {
|
|
||||||
return this.prepareModel(await this._get(corpusName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.models.corpora.Corpus[]>}
|
|
||||||
*/
|
|
||||||
async list() {
|
|
||||||
/** @type {string[]} */
|
|
||||||
let corpusNames = await this.client.api.corpus_list_corpora();
|
|
||||||
/** @type {cqi.models.corpora.Corpus[]} */
|
|
||||||
let corpora = [];
|
|
||||||
for (let corpusName of corpusNames) {
|
|
||||||
corpora.push(await this.get(corpusName));
|
|
||||||
}
|
|
||||||
return corpora;
|
|
||||||
}
|
|
||||||
};
|
|
@ -1 +0,0 @@
|
|||||||
cqi.models = {};
|
|
@ -1,90 +0,0 @@
|
|||||||
cqi.models.resource = {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class for representing a single object on the server.
|
|
||||||
*/
|
|
||||||
cqi.models.resource.Model = class Model {
|
|
||||||
/**
|
|
||||||
* @param {object} attrs
|
|
||||||
* @param {cqi.CQiClient} client
|
|
||||||
* @param {cqi.models.resource.Collection} collection
|
|
||||||
*/
|
|
||||||
constructor(attrs, client, collection) {
|
|
||||||
/**
|
|
||||||
* A client pointing at the server that this object is on.
|
|
||||||
*
|
|
||||||
* @type {cqi.CQiClient}
|
|
||||||
*/
|
|
||||||
this.client = client;
|
|
||||||
/**
|
|
||||||
* The collection that this model is part of.
|
|
||||||
*
|
|
||||||
* @type {cqi.models.resource.Collection}
|
|
||||||
*/
|
|
||||||
this.collection = collection;
|
|
||||||
/**
|
|
||||||
* The raw representation of this object from the API
|
|
||||||
*
|
|
||||||
* @type {object}
|
|
||||||
*/
|
|
||||||
this.attrs = attrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get apiName() {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async reload() {
|
|
||||||
this.attrs = await this.collection.get(this.apiName).attrs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class for representing all objects of a particular type on the server.
|
|
||||||
*/
|
|
||||||
cqi.models.resource.Collection = class Collection {
|
|
||||||
/**
|
|
||||||
* The type of object this collection represents, set by subclasses
|
|
||||||
*
|
|
||||||
* @type {typeof cqi.models.resource.Model}
|
|
||||||
*/
|
|
||||||
static model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {cqi.CQiClient} client
|
|
||||||
*/
|
|
||||||
constructor(client) {
|
|
||||||
/**
|
|
||||||
* A client pointing at the server that this object is on.
|
|
||||||
*
|
|
||||||
* @type {cqi.CQiClient}
|
|
||||||
*/
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
async list() {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
async get() {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a model from a set of attributes.
|
|
||||||
*
|
|
||||||
* @param {object} attrs
|
|
||||||
* @returns {cqi.models.resource.Model}
|
|
||||||
*/
|
|
||||||
prepareModel(attrs) {
|
|
||||||
return new this.constructor.model(attrs, this.client, this);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,155 +0,0 @@
|
|||||||
cqi.models.subcorpora = {};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.subcorpora.Subcorpus = class Subcorpus extends cqi.models.resource.Model {
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get apiName() {
|
|
||||||
return this.attrs.api_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
get fields() {
|
|
||||||
return this.attrs.fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
get name() {
|
|
||||||
return this.attrs.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
get size() {
|
|
||||||
return this.attrs.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.status.StatusOk>}
|
|
||||||
*/
|
|
||||||
async drop() {
|
|
||||||
return await this.client.api.cqp_drop_subcorpus(this.apiName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} field
|
|
||||||
* @param {number} first
|
|
||||||
* @param {number} last
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async dump(field, first, last) {
|
|
||||||
return await this.client.api.cqp_dump_subcorpus(
|
|
||||||
this.apiName,
|
|
||||||
field,
|
|
||||||
first,
|
|
||||||
last
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} cutoff
|
|
||||||
* @param {number} field
|
|
||||||
* @param {cqi.models.attributes.PositionalAttribute} attribute
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async fdist1(cutoff, field, attribute) {
|
|
||||||
return await this.client.api.cqp_fdist_1(
|
|
||||||
this.apiName,
|
|
||||||
cutoff,
|
|
||||||
field,
|
|
||||||
attribute.apiName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} cutoff
|
|
||||||
* @param {number} field1
|
|
||||||
* @param {cqi.models.attributes.PositionalAttribute} attribute1
|
|
||||||
* @param {number} field2
|
|
||||||
* @param {cqi.models.attributes.PositionalAttribute} attribute2
|
|
||||||
* @returns {Promise<number[]>}
|
|
||||||
*/
|
|
||||||
async fdist2(cutoff, field1, attribute1, field2, attribute2) {
|
|
||||||
return await this.client.api.cqp_fdist_2(
|
|
||||||
this.apiName,
|
|
||||||
cutoff,
|
|
||||||
field1,
|
|
||||||
attribute1.apiName,
|
|
||||||
field2,
|
|
||||||
attribute2.apiName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.models.subcorpora.SubcorpusCollection = class SubcorpusCollection extends cqi.models.resource.Collection {
|
|
||||||
/** @type {typeof cqi.models.subcorpora.Subcorpus} */
|
|
||||||
static model = cqi.models.subcorpora.Subcorpus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {cqi.CQiClient} client
|
|
||||||
* @param {cqi.models.corpora.Corpus} corpus
|
|
||||||
*/
|
|
||||||
constructor(client, corpus) {
|
|
||||||
super(client);
|
|
||||||
/** @type {cqi.models.corpora.Corpus} */
|
|
||||||
this.corpus = corpus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} subcorpusName
|
|
||||||
* @returns {Promise<object>}
|
|
||||||
*/
|
|
||||||
async _get(subcorpusName) {
|
|
||||||
/** @type {string} */
|
|
||||||
let apiName = `${this.corpus.apiName}:${subcorpusName}`;
|
|
||||||
/** @type {object} */
|
|
||||||
let fields = {};
|
|
||||||
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_MATCH)) {
|
|
||||||
fields.match = cqi.CONST_FIELD_MATCH;
|
|
||||||
}
|
|
||||||
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_MATCHEND)) {
|
|
||||||
fields.matchend = cqi.CONST_FIELD_MATCHEND
|
|
||||||
}
|
|
||||||
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_TARGET)) {
|
|
||||||
fields.target = cqi.CONST_FIELD_TARGET
|
|
||||||
}
|
|
||||||
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_KEYWORD)) {
|
|
||||||
fields.keyword = cqi.CONST_FIELD_KEYWORD
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
api_name: apiName,
|
|
||||||
fields: fields,
|
|
||||||
name: subcorpusName,
|
|
||||||
size: await this.client.api.cqp_subcorpus_size(apiName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} subcorpusName
|
|
||||||
* @returns {Promise<cqi.models.subcorpora.Subcorpus>}
|
|
||||||
*/
|
|
||||||
async get(subcorpusName) {
|
|
||||||
return this.prepareModel(await this._get(subcorpusName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<cqi.models.subcorpora.Subcorpus[]>}
|
|
||||||
*/
|
|
||||||
async list() {
|
|
||||||
/** @type {string[]} */
|
|
||||||
let subcorpusNames = await this.client.api.cqp_list_subcorpora(this.corpus.apiName);
|
|
||||||
/** @type {cqi.models.subcorpora.Subcorpus[]} */
|
|
||||||
let subcorpora = [];
|
|
||||||
for (let subcorpusName of subcorpusNames) {
|
|
||||||
subcorpora.push(await this.get(subcorpusName));
|
|
||||||
}
|
|
||||||
return subcorpora;
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,6 +0,0 @@
|
|||||||
var cqi = {};
|
|
||||||
|
|
||||||
cqi.CONST_FIELD_KEYWORD = 9;
|
|
||||||
cqi.CONST_FIELD_MATCH = 16;
|
|
||||||
cqi.CONST_FIELD_MATCHEND = 17;
|
|
||||||
cqi.CONST_FIELD_TARGET = 0;
|
|
@ -1,51 +0,0 @@
|
|||||||
cqi.status = {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class from which all other status inherit.
|
|
||||||
*/
|
|
||||||
cqi.status.CQiStatus = class CQiStatus {
|
|
||||||
constructor() {
|
|
||||||
this.code = undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.status.StatusOk = class StatusOk extends cqi.status.CQiStatus {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.code = 257;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.status.StatusConnectOk = class StatusConnectOk extends cqi.status.CQiStatus {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.code = 258;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.status.StatusByeOk = class StatusByeOk extends cqi.status.CQiStatus {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.code = 259;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.status.StatusPingOk = class StatusPingOk extends cqi.status.CQiStatus {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.code = 260;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cqi.status.lookup = {
|
|
||||||
257: cqi.status.StatusOk,
|
|
||||||
258: cqi.status.StatusConnectOk,
|
|
||||||
259: cqi.status.StatusByeOk,
|
|
||||||
260: cqi.status.StatusPingOk
|
|
||||||
};
|
|
@ -3,23 +3,6 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.4/socket.io.min.js" integrity="sha512-HTENHrkQ/P0NGDFd5nk6ibVtCkcM7jhr2c7GyvXp5O+4X6O5cQO9AhqFzM+MdeBivsX7Hoys2J7pp2wdgMpCvw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.4/socket.io.min.js" integrity="sha512-HTENHrkQ/P0NGDFd5nk6ibVtCkcM7jhr2c7GyvXp5O+4X6O5cQO9AhqFzM+MdeBivsX7Hoys2J7pp2wdgMpCvw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.24.2/plotly.min.js" integrity="sha512-dAXqGCq94D0kgLSPnfvd/pZpCMoJQpGj2S2XQmFQ9Ay1+96kbjss02ISEh+TBNXMggGg/1qoMcOHcxg+Op/Jmw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.24.2/plotly.min.js" integrity="sha512-dAXqGCq94D0kgLSPnfvd/pZpCMoJQpGj2S2XQmFQ9Ay1+96kbjss02ISEh+TBNXMggGg/1qoMcOHcxg+Op/Jmw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
|
||||||
{%- assets
|
|
||||||
filters='rjsmin',
|
|
||||||
output='gen/cqi.%(version)s.js',
|
|
||||||
'js/cqi/package.js',
|
|
||||||
'js/cqi/errors.js',
|
|
||||||
'js/cqi/status.js',
|
|
||||||
'js/cqi/api/package.js',
|
|
||||||
'js/cqi/api/client.js',
|
|
||||||
'js/cqi/models/package.js',
|
|
||||||
'js/cqi/models/resource.js',
|
|
||||||
'js/cqi/models/attributes.js',
|
|
||||||
'js/cqi/models/subcorpora.js',
|
|
||||||
'js/cqi/models/corpora.js',
|
|
||||||
'js/cqi/client.js'
|
|
||||||
%}
|
|
||||||
<script src="{{ ASSET_URL }}"></script>
|
|
||||||
{%- endassets %}
|
|
||||||
{%- assets
|
{%- assets
|
||||||
filters='rjsmin',
|
filters='rjsmin',
|
||||||
output='gen/app.%(version)s.js',
|
output='gen/app.%(version)s.js',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user