#!/usr/bin/env python3 # -*-coding:UTF-8 -* import json import os import sys sys.path.append(os.environ['AIL_BIN']) ################################## # Import Project packages ################################## from lib.ConfigLoader import ConfigLoader config_loader = ConfigLoader() r_rel = config_loader.get_db_conn("Kvrocks_Relationships") config_loader = None RELATIONSHIPS = { "forwarded_from", "forwarded_to", # forwarded_to "in", "mention" } RELATIONSHIPS_OBJS = { # TODO forward user-account "forwarded_from": { 'chat': {'message'}, 'message': {'chat', 'user-account'} }, "forwarded_to": { 'chat': {'chat'}, 'user-account': {'chat'}, }, "in": { 'chat': {'message'}, 'message': {'chat'} }, "mention": { 'chat': {'chat', 'user-account', 'message'}, 'message': {'chat', 'user-account'}, 'user-account': {'chat', 'message'}, }, } def get_relationships(): return RELATIONSHIPS def sanitize_relationships(relationships): rels = get_relationships() if relationships: relationships = set(relationships).intersection(rels) if not relationships: relationships = rels if not relationships: return [] return relationships def get_relationship_obj_types(relationship): return RELATIONSHIPS_OBJS.get(relationship, {}) def get_relationship_objs(relationship, obj_type): return get_relationship_obj_types(relationship).get(obj_type, set()) def sanityze_obj_types(relationship, obj_type, filter_types): objs_types = get_relationship_objs(relationship, obj_type) if filter_types: filter_types = objs_types.intersection(filter_types) else: filter_types = objs_types # if not filter_types: # filter_types = objs_types # if not filter_types: # return [] return filter_types # TODO check obj_type # TODO sanitize relationships def get_obj_relationships_by_type(obj_global_id, relationship, filter_types=set()): obj_type = obj_global_id.split(':', 1)[0] relationships = {} filter_types = sanityze_obj_types(relationship, obj_type, filter_types) for o_type in filter_types: relationships[o_type] = r_rel.smembers(f'rel:{relationship}:{obj_global_id}:{o_type}') return relationships def get_obj_nb_relationships_by_type(obj_global_id, relationship, filter_types=set()): obj_type = obj_global_id.split(':', 1)[0] relationships = {} filter_types = sanityze_obj_types(relationship, obj_type, filter_types) for o_type in filter_types: relationships[o_type] = r_rel.scard(f'rel:{relationship}:{obj_global_id}:{o_type}') return relationships def get_obj_relationships(obj_global_id, relationships=set(), filter_types=set()): all_relationships = [] for relationship in relationships: obj_relationships = get_obj_relationships_by_type(obj_global_id, relationship, filter_types=filter_types) for obj_type in obj_relationships: for rel in obj_relationships[obj_type]: meta = {'relationship': relationship} direction, obj_id = rel.split(':', 1) if direction == 'i': meta['source'] = obj_id meta['target'] = obj_global_id else: meta['target'] = obj_id meta['source'] = obj_global_id meta['id'] = obj_id # meta['direction'] = direction all_relationships.append(meta) return all_relationships def get_obj_nb_relationships(obj_global_id): # TODO########################################################################################### nb = {} for relationship in get_relationships(): nb[relationship] = get_obj_nb_relationships_by_type(obj_global_id, relationship) return nb # TODO Filter by obj type ??? def add_obj_relationship(source, target, relationship): source_type = source.split(':', 1)[0] target_type = target.split(':', 1)[0] r_rel.sadd(f'rel:{relationship}:{source}:{target_type}', f'o:{target}') r_rel.sadd(f'rel:{relationship}:{target}:{source_type}', f'i:{source}') def get_relationship_graph(obj_global_id, relationships=[], filter_types=[], max_nodes=300, level=1, objs_hidden=set()): links = [] nodes = set() meta = {'complete': True, 'objs': set()} done = set() done_link = set() _get_relationship_graph(obj_global_id, links, nodes, meta, level, max_nodes, relationships=relationships, filter_types=filter_types, objs_hidden=objs_hidden, done=done, done_link=done_link) return nodes, links, meta def _get_relationship_graph(obj_global_id, links, nodes, meta, level, max_nodes, relationships=[], filter_types=[], objs_hidden=set(), done=set(), done_link=set()): meta['objs'].add(obj_global_id) nodes.add(obj_global_id) for rel in get_obj_relationships(obj_global_id, relationships=relationships, filter_types=filter_types): meta['objs'].add(rel['id']) if rel['id'] in done: continue if len(nodes) > max_nodes != 0: meta['complete'] = False break nodes.add(rel['id']) str_link = f"{rel['source']}{rel['target']}{rel['relationship']}" if str_link not in done_link: links.append({"source": rel['source'], "target": rel['target'], "relationship": rel['relationship']}) done_link.add(str_link) if level > 0: next_level = level - 1 _get_relationship_graph(rel['id'], links, nodes, meta, next_level, max_nodes, relationships=relationships, filter_types=filter_types, objs_hidden=objs_hidden, done=done, done_link=done_link) # done.add(rel['id']) # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # ## # # # # # # ## # # # # # # ## # # # # # # ## # # # # def get_chat_forward_stats_out(obj_global_id): nb = {} for rel in get_obj_relationships(obj_global_id, relationships={'forwarded_from'}, filter_types={'message'}): chat_mess = rel['source'].split('/') chat_target = f'chat:{chat_mess[0][9:]}:{chat_mess[2]}' if chat_target not in nb: nb[chat_target] = 0 nb[chat_target] += 1 return nb def get_chat_forward_stats_in(obj_global_id): nb = {} for rel in get_obj_relationships(obj_global_id, relationships={'in'}, filter_types={'message'}): r = get_obj_relationships(rel['source'], relationships={'forwarded_from'}, filter_types={'chat', 'user-account'}) if r: if not r[0]['target'] in nb: nb[r[0]['target']] = 0 nb[r[0]['target']] += 1 # chat_mess = rel['source'].split('/') # # chat_target = f'chat:{chat_mess[0][9:]}:{chat_mess[2]}' # print(chat_target, chat, chat_target == chat) # if chat is None or chat_target == chat: # if chat_target not in nb: # nb[chat_target] = 0 # nb[chat_target] += 1 # # print(json.dumps(nb, indent=4)) return nb def get_chat_forward_stats(obj_global_id): # objs_hidden data = [] # print(get_obj_relationships(obj_global_id, relationships=['forwarded_from'], filter_types=['message'])) in_mess = get_chat_forward_stats_out(obj_global_id) out_mess = get_chat_forward_stats_in(obj_global_id) # if rel['target'] == obj_global_id: # # print(rel) # nb_chats[rel['source']] = get_chat_forward_stats_out(rel['source'], chat=obj_global_id) # for target in in_mess: data.append({'source': obj_global_id, 'target': target, 'value': in_mess[target]}) for source in out_mess: data.append({'source': source, 'target': obj_global_id, 'value': out_mess[source]}) # print() # print(in_mess) # print() # print(out_mess) return data ################################################################## def get_chat_mention_stats_in(obj_global_id): nb = {} for rel in get_obj_relationships(obj_global_id, relationships={'mention'}, filter_types={'message'}): chat_mess = rel['source'].split('/') chat_source = f'chat:{chat_mess[0][9:]}:{chat_mess[2]}' if chat_source not in nb: nb[chat_source] = 0 nb[chat_source] += 1 return nb def get_chat_mention_stats_out(obj_global_id): nb = {} for rel in get_obj_relationships(obj_global_id, relationships={'in'}, filter_types={'message'}): r = get_obj_relationships(rel['source'], relationships={'mention'}, filter_types={'chat', 'user-account'}) if r: if not r[0]['target'] in nb: nb[r[0]['target']] = 0 nb[r[0]['target']] += 1 # chat_mess = rel['source'].split('/') # # chat_target = f'chat:{chat_mess[0][9:]}:{chat_mess[2]}' # print(chat_target, chat, chat_target == chat) # if chat is None or chat_target == chat: # if chat_target not in nb: # nb[chat_target] = 0 # nb[chat_target] += 1 # # print(json.dumps(nb, indent=4)) return nb def get_chat_mentions_stats(obj_global_id): # objs_hidden data = [] # print(get_obj_relationships(obj_global_id, relationships=['forwarded_from'], filter_types=['message'])) out_mess = get_chat_mention_stats_in(obj_global_id) in_mess = get_chat_mention_stats_out(obj_global_id) # for target in in_mess: data.append({'source': obj_global_id, 'target': target, 'value': in_mess[target]}) for source in out_mess: data.append({'source': source, 'target': obj_global_id, 'value': out_mess[source]}) # print() # print(in_mess) # print() # print(out_mess) return data