mirror of
https://github.com/ail-project/ail-framework.git
synced 2024-11-29 17:27:17 +00:00
chg: [language messages] add nb languages stats by chat/subchannel objects
This commit is contained in:
parent
59ca8c5d31
commit
b9c37167ad
6 changed files with 87 additions and 48 deletions
|
@ -324,24 +324,32 @@ def get_objs_languages(obj_type, obj_subtype=''):
|
||||||
def get_obj_languages(obj_type, obj_subtype, obj_id):
|
def get_obj_languages(obj_type, obj_subtype, obj_id):
|
||||||
return r_lang.smembers(f'obj:lang:{obj_type}:{obj_subtype}:{obj_id}')
|
return r_lang.smembers(f'obj:lang:{obj_type}:{obj_subtype}:{obj_id}')
|
||||||
|
|
||||||
|
def get_obj_language_stats(obj_type, obj_subtype, obj_id):
|
||||||
|
return r_lang.zrange(f'obj:langs:stat:{obj_type}:{obj_subtype}:{obj_id}', 0, -1, withscores=True)
|
||||||
|
|
||||||
# TODO ADD language to CHAT GLOBAL SET
|
# TODO ADD language to CHAT GLOBAL SET
|
||||||
def add_obj_language(language, obj_type, obj_subtype, obj_id): # (s)
|
def add_obj_language(language, obj_type, obj_subtype, obj_id, objs_containers=set()): # (s)
|
||||||
if not obj_subtype:
|
if not obj_subtype:
|
||||||
obj_subtype = ''
|
obj_subtype = ''
|
||||||
obj_global_id = f'{obj_type}:{obj_subtype}:{obj_id}'
|
obj_global_id = f'{obj_type}:{obj_subtype}:{obj_id}'
|
||||||
|
|
||||||
r_lang.sadd(f'objs:langs:{obj_type}', language)
|
r_lang.sadd(f'objs:langs:{obj_type}', language)
|
||||||
r_lang.sadd(f'objs:lang:{obj_type}:{obj_subtype}', language)
|
r_lang.sadd(f'objs:lang:{obj_type}:{obj_subtype}', language)
|
||||||
r_lang.sadd(f'obj:lang:{obj_global_id}', language)
|
new = r_lang.sadd(f'obj:lang:{obj_global_id}', language)
|
||||||
|
|
||||||
r_lang.sadd(f'languages:{language}', f'{obj_type}:{obj_subtype}') ################### REMOVE ME ???
|
r_lang.sadd(f'languages:{language}', f'{obj_type}:{obj_subtype}') ################### REMOVE ME ???
|
||||||
r_lang.sadd(f'langs:{obj_type}:{obj_subtype}:{language}', obj_global_id)
|
r_lang.sadd(f'langs:{obj_type}:{obj_subtype}:{language}', obj_global_id)
|
||||||
|
|
||||||
def remove_obj_language(language, obj_type, obj_subtype, obj_id):
|
if new:
|
||||||
|
for global_id in objs_containers:
|
||||||
|
r_lang.zincrby(f'obj:langs:stat:{global_id}', 1, language)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_obj_language(language, obj_type, obj_subtype, obj_id, objs_containers=set()):
|
||||||
if not obj_subtype:
|
if not obj_subtype:
|
||||||
obj_subtype = ''
|
obj_subtype = ''
|
||||||
obj_global_id = f'{obj_type}:{obj_subtype}:{obj_id}'
|
obj_global_id = f'{obj_type}:{obj_subtype}:{obj_id}'
|
||||||
r_lang.srem(f'obj:lang:{obj_global_id}', language)
|
rem = r_lang.srem(f'obj:lang:{obj_global_id}', language)
|
||||||
|
|
||||||
delete_obj_translation(obj_global_id, language)
|
delete_obj_translation(obj_global_id, language)
|
||||||
|
|
||||||
|
@ -353,27 +361,33 @@ def remove_obj_language(language, obj_type, obj_subtype, obj_id):
|
||||||
if r_lang.scard(f'objs:langs:{obj_type}') <= 1:
|
if r_lang.scard(f'objs:langs:{obj_type}') <= 1:
|
||||||
r_lang.srem(f'objs:langs:{obj_type}', language)
|
r_lang.srem(f'objs:langs:{obj_type}', language)
|
||||||
|
|
||||||
|
if rem:
|
||||||
|
for global_id in objs_containers:
|
||||||
|
r = r_lang.zincrby(f'obj:langs:stat:{global_id}', -1, language)
|
||||||
|
if r < 1:
|
||||||
|
r_lang.zrem(f'obj:langs:stat:{global_id}', language)
|
||||||
|
|
||||||
# TODO handle fields
|
# TODO handle fields
|
||||||
def detect_obj_language(obj_type, obj_subtype, obj_id, content):
|
def detect_obj_language(obj_type, obj_subtype, obj_id, content, objs_containers=set()):
|
||||||
detector = LanguagesDetector(nb_langs=1)
|
detector = LanguagesDetector(nb_langs=1)
|
||||||
language = detector.detect(content)
|
language = detector.detect(content)
|
||||||
if language:
|
if language:
|
||||||
language = language[0]
|
language = language[0]
|
||||||
previous_lang = get_obj_languages(obj_type, obj_subtype, obj_id)
|
previous_lang = get_obj_languages(obj_type, obj_subtype, obj_id)
|
||||||
if previous_lang:
|
if previous_lang:
|
||||||
previous_lang = previous_lang[0]
|
previous_lang = previous_lang.pop()
|
||||||
if language != previous_lang:
|
if language != previous_lang:
|
||||||
remove_obj_language(language, obj_type, obj_subtype, obj_id)
|
remove_obj_language(previous_lang, obj_type, obj_subtype, obj_id, objs_containers=objs_containers)
|
||||||
add_obj_language(language, obj_type, obj_subtype, obj_id)
|
add_obj_language(language, obj_type, obj_subtype, obj_id, objs_containers=objs_containers)
|
||||||
else:
|
else:
|
||||||
add_obj_language(language, obj_type, obj_subtype, obj_id)
|
add_obj_language(language, obj_type, obj_subtype, obj_id, objs_containers=objs_containers)
|
||||||
return language
|
return language
|
||||||
|
|
||||||
## Translation
|
## Translation
|
||||||
def _get_obj_translation(obj_global_id, language, field=''):
|
def r_get_obj_translation(obj_global_id, language, field=''):
|
||||||
return r_lang.hget(f'tr:{obj_global_id}:{field}', language)
|
return r_lang.hget(f'tr:{obj_global_id}:{field}', language)
|
||||||
|
|
||||||
def get_obj_translation(obj_global_id, language, source=None, content=None, field=''):
|
def _get_obj_translation(obj_global_id, language, source=None, content=None, field='', objs_containers=set()):
|
||||||
"""
|
"""
|
||||||
Returns translated content
|
Returns translated content
|
||||||
"""
|
"""
|
||||||
|
@ -385,17 +399,20 @@ def get_obj_translation(obj_global_id, language, source=None, content=None, fiel
|
||||||
# r_cache.expire(f'translation:{language}:{obj_global_id}:{field}', 0)
|
# r_cache.expire(f'translation:{language}:{obj_global_id}:{field}', 0)
|
||||||
return translation
|
return translation
|
||||||
# TODO HANDLE FIELDS TRANSLATION
|
# TODO HANDLE FIELDS TRANSLATION
|
||||||
translation = _get_obj_translation(obj_global_id, language, field=field)
|
translation = r_get_obj_translation(obj_global_id, language, field=field)
|
||||||
if not translation:
|
if not translation:
|
||||||
source, translation = LanguageTranslator().translate(content, source=source, target=language)
|
source, translation = LanguageTranslator().translate(content, source=source, target=language)
|
||||||
if source and translation:
|
if source and translation:
|
||||||
obj_type, subtype, obj_id = obj_global_id.split(':', 2)
|
obj_type, subtype, obj_id = obj_global_id.split(':', 2)
|
||||||
add_obj_language(source, obj_type, subtype, obj_id)
|
add_obj_language(source, obj_type, subtype, obj_id, objs_containers=objs_containers)
|
||||||
if translation:
|
if translation:
|
||||||
r_cache.set(f'translation:{language}:{obj_global_id}:{field}', translation)
|
r_cache.set(f'translation:{language}:{obj_global_id}:{field}', translation)
|
||||||
r_cache.expire(f'translation:{language}:{obj_global_id}:{field}', 300)
|
r_cache.expire(f'translation:{language}:{obj_global_id}:{field}', 300)
|
||||||
return translation
|
return translation
|
||||||
|
|
||||||
|
def get_obj_translation(obj_global_id, language, source=None, content=None, field='', objs_containers=set()):
|
||||||
|
return _get_obj_translation(obj_global_id, language, source=source, content=content, field=field, objs_containers=objs_containers)
|
||||||
|
|
||||||
|
|
||||||
# TODO Force to edit ????
|
# TODO Force to edit ????
|
||||||
|
|
||||||
|
|
|
@ -480,7 +480,6 @@ def api_manually_translate_message(message_id, source, translation_target, trans
|
||||||
return {"status": "error", "reason": "Max Size reached"}, 400
|
return {"status": "error", "reason": "Max Size reached"}, 400
|
||||||
all_languages = Language.get_translation_languages()
|
all_languages = Language.get_translation_languages()
|
||||||
if source not in all_languages:
|
if source not in all_languages:
|
||||||
print(source)
|
|
||||||
return {"status": "error", "reason": "Unknown source Language"}, 400
|
return {"status": "error", "reason": "Unknown source Language"}, 400
|
||||||
message_language = message.get_language()
|
message_language = message.get_language()
|
||||||
if message_language != source:
|
if message_language != source:
|
||||||
|
|
|
@ -103,8 +103,17 @@ class Message(AbstractObject):
|
||||||
return message_id
|
return message_id
|
||||||
|
|
||||||
def get_chat_id(self): # TODO optimize -> use me to tag Chat
|
def get_chat_id(self): # TODO optimize -> use me to tag Chat
|
||||||
chat_id = self.get_basename().rsplit('_', 1)[0]
|
c_id = self.id.split('/')
|
||||||
return chat_id
|
return c_id[2]
|
||||||
|
|
||||||
|
def get_chat(self):
|
||||||
|
c_id = self.id.split('/')
|
||||||
|
return f'chat:{c_id[0]}:{c_id[2]}'
|
||||||
|
|
||||||
|
def get_subchannel(self):
|
||||||
|
subchannel = self.get_correlation('chat-subchannel')
|
||||||
|
if subchannel.get('chat-subchannel'):
|
||||||
|
return f'user-account:{subchannel["chat-subchannel"].pop()}'
|
||||||
|
|
||||||
def get_thread(self):
|
def get_thread(self):
|
||||||
for child in self.get_childrens():
|
for child in self.get_childrens():
|
||||||
|
@ -183,25 +192,6 @@ class Message(AbstractObject):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_translation(self, content=None, source=None, target='fr'):
|
|
||||||
"""
|
|
||||||
Returns translated content
|
|
||||||
"""
|
|
||||||
|
|
||||||
# return self._get_field('translated')
|
|
||||||
global_id = self.get_global_id()
|
|
||||||
translation = r_cache.get(f'translation:{target}:{global_id}')
|
|
||||||
r_cache.expire(f'translation:{target}:{global_id}', 0)
|
|
||||||
if translation:
|
|
||||||
return translation
|
|
||||||
if not content:
|
|
||||||
content = self.get_content()
|
|
||||||
translation = Language.LanguageTranslator().translate(content, source=source, target=target)
|
|
||||||
if translation:
|
|
||||||
r_cache.set(f'translation:{target}:{global_id}', translation)
|
|
||||||
r_cache.expire(f'translation:{target}:{global_id}', 300)
|
|
||||||
return translation
|
|
||||||
|
|
||||||
def _set_translation(self, translation):
|
def _set_translation(self, translation):
|
||||||
"""
|
"""
|
||||||
Set translated content
|
Set translated content
|
||||||
|
@ -305,6 +295,8 @@ class Message(AbstractObject):
|
||||||
else:
|
else:
|
||||||
source = None
|
source = None
|
||||||
meta['translation'] = self.translate(content=meta.get('content'), source=source, target=translation_target)
|
meta['translation'] = self.translate(content=meta.get('content'), source=source, target=translation_target)
|
||||||
|
if 'language' in options:
|
||||||
|
meta['language'] = self.get_language()
|
||||||
|
|
||||||
# meta['encoding'] = None
|
# meta['encoding'] = None
|
||||||
return meta
|
return meta
|
||||||
|
@ -318,11 +310,29 @@ class Message(AbstractObject):
|
||||||
# self._set_translation(translated)
|
# self._set_translation(translated)
|
||||||
# return translated
|
# return translated
|
||||||
|
|
||||||
def create(self, content, translation=None, tags=[]):
|
## Language ##
|
||||||
|
|
||||||
|
def get_objs_container(self):
|
||||||
|
objs_containers = set()
|
||||||
|
# chat
|
||||||
|
objs_containers.add(self.get_chat())
|
||||||
|
subchannel = self.get_subchannel()
|
||||||
|
if subchannel:
|
||||||
|
objs_containers.add(subchannel)
|
||||||
|
# thread = self.get_thread() # TODO Get current thread
|
||||||
|
# if thread:
|
||||||
|
# objs_containers.add(thread)
|
||||||
|
return objs_containers
|
||||||
|
|
||||||
|
#- Language -#
|
||||||
|
|
||||||
|
def create(self, content, language=None, translation=None, tags=[]):
|
||||||
self._set_field('content', content)
|
self._set_field('content', content)
|
||||||
# r_content.get(f'content:{self.type}:{self.get_subtype(r_str=True)}:{self.id}', content)
|
if not language and content:
|
||||||
if translation:
|
language = self.detect_language()
|
||||||
|
if translation and content:
|
||||||
self._set_translation(translation)
|
self._set_translation(translation)
|
||||||
|
self.set_translation(language, translation)
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
self.add_tag(tag)
|
self.add_tag(tag)
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ from lib import Duplicate
|
||||||
from lib.correlations_engine import get_nb_correlations, get_correlations, add_obj_correlation, delete_obj_correlation, delete_obj_correlations, exists_obj_correlation, is_obj_correlated, get_nb_correlation_by_correl_type, get_obj_inter_correlation
|
from lib.correlations_engine import get_nb_correlations, get_correlations, add_obj_correlation, delete_obj_correlation, delete_obj_correlations, exists_obj_correlation, is_obj_correlated, get_nb_correlation_by_correl_type, get_obj_inter_correlation
|
||||||
from lib.Investigations import is_object_investigated, get_obj_investigations, delete_obj_investigations
|
from lib.Investigations import is_object_investigated, get_obj_investigations, delete_obj_investigations
|
||||||
from lib.relationships_engine import get_obj_nb_relationships, add_obj_relationship
|
from lib.relationships_engine import get_obj_nb_relationships, add_obj_relationship
|
||||||
from lib.Language import get_obj_languages, add_obj_language, remove_obj_language, detect_obj_language, get_obj_translation, set_obj_translation, delete_obj_translation
|
from lib.Language import get_obj_languages, add_obj_language, remove_obj_language, detect_obj_language, get_obj_language_stats, get_obj_translation, set_obj_translation, delete_obj_translation
|
||||||
from lib.Tracker import is_obj_tracked, get_obj_trackers, delete_obj_trackers
|
from lib.Tracker import is_obj_tracked, get_obj_trackers, delete_obj_trackers
|
||||||
|
|
||||||
logging.config.dictConfig(ail_logger.get_config(name='ail'))
|
logging.config.dictConfig(ail_logger.get_config(name='ail'))
|
||||||
|
@ -302,26 +302,33 @@ class AbstractObject(ABC):
|
||||||
|
|
||||||
## -Relationship- ##
|
## -Relationship- ##
|
||||||
|
|
||||||
|
def get_objs_container(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
## Language ##
|
## Language ##
|
||||||
|
|
||||||
def get_languages(self):
|
def get_languages(self):
|
||||||
return get_obj_languages(self.type, self.get_subtype(r_str=True), self.id)
|
return get_obj_languages(self.type, self.get_subtype(r_str=True), self.id)
|
||||||
|
|
||||||
def add_language(self, language):
|
def add_language(self, language):
|
||||||
return add_obj_language(language, self.type, self.get_subtype(r_str=True), self.id)
|
return add_obj_language(language, self.type, self.get_subtype(r_str=True), self.id, objs_containers=self.get_objs_container())
|
||||||
|
|
||||||
def remove_language(self, language):
|
def remove_language(self, language):
|
||||||
return remove_obj_language(language, self.type, self.get_subtype(r_str=True), self.id)
|
return remove_obj_language(language, self.type, self.get_subtype(r_str=True), self.id, objs_containers=self.get_objs_container())
|
||||||
|
|
||||||
def edit_language(self, old_language, new_language):
|
def edit_language(self, old_language, new_language):
|
||||||
self.remove_language(old_language)
|
if old_language:
|
||||||
|
self.remove_language(old_language)
|
||||||
self.add_language(new_language)
|
self.add_language(new_language)
|
||||||
|
|
||||||
def detect_language(self, field=''):
|
def detect_language(self, field=''):
|
||||||
return detect_obj_language(self.type, self.get_subtype(r_str=True), self.id, self.get_content())
|
return detect_obj_language(self.type, self.get_subtype(r_str=True), self.id, self.get_content(), objs_containers=self.get_objs_container())
|
||||||
|
|
||||||
|
def get_obj_language_stats(self):
|
||||||
|
return get_obj_language_stats(self.type, self.get_subtype(r_str=True), self.id)
|
||||||
|
|
||||||
def get_translation(self, language, field=''):
|
def get_translation(self, language, field=''):
|
||||||
return get_obj_translation(self.get_global_id(), language, field=field)
|
return get_obj_translation(self.get_global_id(), language, field=field, objs_containers=self.get_objs_container())
|
||||||
|
|
||||||
def set_translation(self, language, translation, field=''):
|
def set_translation(self, language, translation, field=''):
|
||||||
return set_obj_translation(self.get_global_id(), language, translation, field=field)
|
return set_obj_translation(self.get_global_id(), language, translation, field=field)
|
||||||
|
@ -333,7 +340,7 @@ class AbstractObject(ABC):
|
||||||
global_id = self.get_global_id()
|
global_id = self.get_global_id()
|
||||||
if not content:
|
if not content:
|
||||||
content = self.get_content()
|
content = self.get_content()
|
||||||
translation = get_obj_translation(global_id, target, source=source, content=content, field=field)
|
translation = get_obj_translation(global_id, target, source=source, content=content, field=field, objs_containers=self.get_objs_container())
|
||||||
return translation
|
return translation
|
||||||
|
|
||||||
## -Language- ##
|
## -Language- ##
|
||||||
|
|
|
@ -253,7 +253,10 @@ def objects_message_translate():
|
||||||
if resp[1] != 200:
|
if resp[1] != 200:
|
||||||
return create_json_response(resp[0], resp[1])
|
return create_json_response(resp[0], resp[1])
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('chats_explorer.objects_message', id=message_id, target=target))
|
if request.referrer:
|
||||||
|
return redirect(request.referrer)
|
||||||
|
else:
|
||||||
|
return redirect(url_for('chats_explorer.objects_message', id=message_id, target=target))
|
||||||
|
|
||||||
@chats_explorer.route("/objects/message/detect/language", methods=['GET'])
|
@chats_explorer.route("/objects/message/detect/language", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -265,7 +268,10 @@ def objects_message_detect_language():
|
||||||
if resp[1] != 200:
|
if resp[1] != 200:
|
||||||
return create_json_response(resp[0], resp[1])
|
return create_json_response(resp[0], resp[1])
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('chats_explorer.objects_message', id=message_id, target=target))
|
if request.referrer:
|
||||||
|
return redirect(request.referrer)
|
||||||
|
else:
|
||||||
|
return redirect(url_for('chats_explorer.objects_message', id=message_id, target=target))
|
||||||
|
|
||||||
@chats_explorer.route("/objects/user-account", methods=['GET'])
|
@chats_explorer.route("/objects/user-account", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
</span>
|
</span>
|
||||||
<div class="collapse" id="collapseTrans{{ mess_id_escape }}">
|
<div class="collapse" id="collapseTrans{{ mess_id_escape }}">
|
||||||
<div class="card card-body">
|
<div class="card card-body">
|
||||||
<form method="post" action="{{ url_for('chats_explorer.objects_message_translate') }}" target="_blank">
|
<form method="post" action="{{ url_for('chats_explorer.objects_message_translate') }}">
|
||||||
<input type="text" id="id" name="id" value="{{message['id']}}" hidden>
|
<input type="text" id="id" name="id" value="{{message['id']}}" hidden>
|
||||||
<span class="badge badge-primary">Source:</span>
|
<span class="badge badge-primary">Source:</span>
|
||||||
<span class="">
|
<span class="">
|
||||||
|
|
Loading…
Reference in a new issue