예제 #1
0
 def __ignored(self, content: Content, sender: ID, msg: ReliableMessage) -> bool:
     # check robot
     if sender.type in [NetworkType.ROBOT, NetworkType.STATION]:
         Log.info('Dialog > ignore message from another robot: %s' % sender)
         return True
     # check time
     now = int(time.time())
     dt = now - msg.time
     if dt > 600:
         # Old message, ignore it
         return True
     # check group message
     if content.group is None:
         # not a group message
         return False
     text = content.text
     if text is None:
         raise ValueError('text content error: %s' % content)
     # checking '@nickname'
     receiver = msg.receiver
     at = '@%s' % self.facebook.name(identifier=receiver)
     if text.find(at) < 0:
         Log.info('ignore group message that not querying me: %s' % text)
         return True
     # TODO: remove all '@nickname'
     text = text.replace(at, '')
     content.text = text
예제 #2
0
def create_server(identifier: str, host: str, port: int = 9394) -> Station:
    """ Create Local Server """
    identifier = ID.parse(identifier=identifier)
    server = Station(identifier=identifier, host=host, port=port)
    g_facebook.cache_user(user=server)
    Log.info('local station created: %s' % server)
    return server
예제 #3
0
 def process_command(self, cmd: Command, source: tuple) -> bool:
     Log.info('received cmd: %s' % cmd)
     # noinspection PyBroadException
     try:
         return super().process_command(cmd=cmd, source=source)
     except Exception:
         traceback.print_exc()
         return False
예제 #4
0
def load_station(identifier: Union[ID, str], facebook: CommonFacebook) -> Station:
    """ Load station info from 'etc' directory

        :param identifier - station ID
        :param facebook - social network data source
        :return station with info from 'dims/etc/{address}/*'
    """
    identifier = ID.parse(identifier=identifier)
    # check meta
    meta = facebook.meta(identifier=identifier)
    if meta is None:
        # load from 'etc' directory
        meta = Meta.parse(meta=load_station_info(identifier=identifier, filename='meta.js'))
        if meta is None:
            raise LookupError('failed to get meta for station: %s' % identifier)
        elif not facebook.save_meta(meta=meta, identifier=identifier):
            raise ValueError('meta error: %s' % meta)
    # check private key
    private_key = facebook.private_key_for_signature(identifier=identifier)
    if private_key is None:
        # load from 'etc' directory
        private_key = PrivateKey.parse(key=load_station_info(identifier=identifier, filename='secret.js'))
        if private_key is None:
            pass
        elif not facebook.save_private_key(key=private_key, identifier=identifier):
            raise AssertionError('failed to save private key for ID: %s, %s' % (identifier, private_key))
    # check profile
    profile = load_station_info(identifier=identifier, filename='profile.js')
    if profile is None:
        raise LookupError('failed to get profile for station: %s' % identifier)
    Log.info('station profile: %s' % profile)
    name = profile.get('name')
    host = profile.get('host')
    port = profile.get('port')
    # create station
    if private_key is None:
        # remote station
        station = Station(identifier=identifier, host=host, port=port)
    else:
        # create profile
        profile = Document.create(doc_type=Document.PROFILE, identifier=identifier)
        profile.set_property('name', name)
        profile.set_property('host', host)
        profile.set_property('port', port)
        profile.sign(private_key=private_key)
        if not facebook.save_document(document=profile):
            raise AssertionError('failed to save profile: %s' % profile)
        # local station
        station = Station(identifier=identifier, host=host, port=port)
    facebook.cache_user(user=station)
    Log.info('station loaded: %s' % station)
    return station
예제 #5
0
def load_freshmen() -> List[ID]:
    freshmen = []
    text = Storage.read_text(path=freshmen_file)
    if text is None:
        return freshmen
    array = text.splitlines()
    for item in array:
        identifier = ID.parse(identifier=item)
        if identifier is None:
            Log.error('ID error: %s' % item)
        elif identifier.type == NetworkType.MAIN:
            freshmen.append(identifier)
        else:
            # Log.error('Not a user ID: %s' % identifier)
            pass
    return freshmen
예제 #6
0
 def message(self, signature: str) -> Optional[dict]:
     msg = self.msg_table.load(signature=signature)
     if msg is None:
         Log.error('failed to load message: %s' % signature)
         return None
     # message content
     content = msg.get('content')
     if content is None:
         data = msg['data']
         content = Content.parse(content=json.loads(data))
         assert isinstance(content, TextContent), 'content error: %s' % data
         msg['content'] = content.dictionary
     # message url
     link = msg.get('link')
     if link is None:
         link = msg_url(signature=signature)
         msg['link'] = link
     return msg.dictionary
예제 #7
0
 def process(self, content: Content, msg: ReliableMessage) -> Optional[Content]:
     assert isinstance(content, TextContent), 'text content error: %s' % content
     sender = msg.sender
     nickname = self.facebook.name(identifier=sender)
     if self.__ignored(content=content, sender=sender, msg=msg):
         return None
     Log.debug('Received text message from %s: %s' % (nickname, content))
     response = self.__query(content=content, sender=sender)
     if response is not None:
         assert isinstance(response, TextContent)
         question = content.text
         answer = response.text
         group = content.group
         if group is None:
             # personal message
             Log.debug('Dialog > %s(%s): "%s" -> "%s"' % (nickname, sender, question, answer))
         else:
             # group message
             Log.debug('Group Dialog > %s(%s)@%s: "%s" -> "%s"' % (nickname, sender, group.name, question, answer))
             if self.messenger.send_content(sender=None, receiver=group, content=response):
                 text = 'Group message responded'
                 return ReceiptCommand(message=text)
             else:
                 text = 'Group message respond failed'
                 return ReceiptCommand(message=text)
         return response
예제 #8
0
def load_user(identifier: str, facebook: CommonFacebook) -> User:
    identifier = ID.parse(identifier=identifier)
    # check meta
    try:
        meta = facebook.meta(identifier=identifier)
    except AssertionError:
        meta = None
    if meta is None:
        # load from 'etc' directory
        meta = Meta.parse(meta=load_robot_info(identifier=identifier, filename='meta.js'))
        if meta is None:
            raise LookupError('failed to get meta for robot: %s' % identifier)
        elif not facebook.save_meta(meta=meta, identifier=identifier):
            raise ValueError('meta error: %s' % meta)
    # check private key
    private_key = facebook.private_key_for_signature(identifier=identifier)
    if private_key is None:
        # load from 'etc' directory
        private_key = PrivateKey.parse(key=load_robot_info(identifier=identifier, filename='secret.js'))
        if private_key is None:
            raise AssertionError('private key not found for ID: %s' % identifier)
        elif not facebook.save_private_key(key=private_key, identifier=identifier):
            raise AssertionError('failed to save private key for ID: %s, %s' % (identifier, private_key))
    # check profile
    profile = load_robot_info(identifier=identifier, filename='profile.js')
    if profile is None:
        raise LookupError('failed to get profile for robot: %s' % identifier)
    Log.info('robot profile: %s' % profile)
    name = profile.get('name')
    avatar = profile.get('avatar')
    # create profile
    profile = Document.create(doc_type=Document.VISA, identifier=identifier)
    profile.set_property('name', name)
    profile.set_property('avatar', avatar)
    profile.sign(private_key=private_key)
    if not facebook.save_document(document=profile):
        raise AssertionError('failed to save profile: %s' % profile)
    # create local user
    return facebook.user(identifier=identifier)
예제 #9
0
 def process_message(self, msg: Message, source: tuple) -> bool:
     Log.info('received msg from %s:\n\t%s' % (source, json.dumps(msg, cls=FieldValueEncoder)))
     # return super().process_message(msg=msg, source=source)
     return True
예제 #10
0
#
#  Configurations
#
from etc.cfg_apns import apns_credentials, apns_use_sandbox, apns_topic
from etc.cfg_db import base_dir, ans_reserved_records
from etc.cfg_admins import administrators
from etc.cfg_gsp import all_stations, local_servers
from etc.cfg_gsp import station_id, station_host, station_port, station_name
from etc.cfg_bots import group_assistants

from etc.cfg_loader import load_station

from .receptionist import Receptionist
from .monitor import Monitor

Log.info("local storage directory: %s" % base_dir)
Storage.root = base_dir

g_database = Database()
"""
    Address Name Service
    ~~~~~~~~~~~~~~~~~~~~

    A map for short name to ID, just like DNS
"""
g_ans = AddressNameServer()
"""
    Facebook
    ~~~~~~~~

    Barrack for cache entities
예제 #11
0
 def error(self, msg: str):
     Log.error('%s >\t%s' % (self.__class__.__name__, msg))
예제 #12
0
 def info(self, msg: str):
     Log.info('%s >\t%s' % (self.__class__.__name__, msg))
예제 #13
0
 def warning(self, msg: str):
     Log.warning('Storage::%s >\t%s' % (self.__class__.__name__, msg))
예제 #14
0
 def debug(self, msg: str):
     Log.debug('Storage::%s >\t%s' % (self.__class__.__name__, msg))
예제 #15
0
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)

from libs.utils import Log
from libs.utils.mtp import Server as UDPServer

from station.handler import RequestHandler
from station.config import g_receptionist, g_dispatcher, current_station

if __name__ == '__main__':

    g_receptionist.start()
    g_dispatcher.start()

    # start UDP Server
    Log.info('>>> UDP server (%s:%d) starting ...' %
             (current_station.host, current_station.port))
    g_udp_server = UDPServer(host=current_station.host,
                             port=current_station.port)
    g_udp_server.start()

    # start TCP Server
    try:
        TCPServer.allow_reuse_address = True
        server = ThreadingTCPServer(server_address=(current_station.host,
                                                    current_station.port),
                                    RequestHandlerClass=RequestHandler)
        Log.info('server (%s:%s) is listening...' %
                 (current_station.host, current_station.port))
        server.serve_forever()
    except KeyboardInterrupt as ex:
        Log.info('~~~~~~~~ %s' % ex)
예제 #16
0
 def __query(self, content: Content, sender: ID) -> TextContent:
     dialog = self.dialog
     try:
         return dialog.query(content=content, sender=sender)
     except URLError as error:
         Log.error('%s' % error)
예제 #17
0
def load_naruto():
    gid = ID.parse(identifier=group_naruto)
    Log.info('naruto group: %s' % gid)
    meta = Meta.parse(meta=load_robot_info(gid, 'meta.js'))
    g_facebook.save_meta(identifier=gid, meta=meta)
예제 #18
0
 def send_command(self, cmd: Command, destination: tuple) -> Departure:
     Log.info('sending cmd to %s:\n\t%s' % (destination, cmd))
     return super().send_command(cmd=cmd, destination=destination)
예제 #19
0
 def suspend_message(self, msg: Union[InstantMessage, ReliableMessage]) -> bool:
     Log.info('TODO: suspending message')
     return True
예제 #20
0
 def save_message(self, msg: InstantMessage) -> bool:
     Log.info('TODO: saving message')
     return True
예제 #21
0
 def send_message(self, msg: Message, destination: tuple) -> Departure:
     Log.info('sending msg to %s:\n\t%s' % (destination, json.dumps(msg, cls=FieldValueEncoder)))
     return super().send_message(msg=msg, destination=destination)
예제 #22
0
from libs.client import Server, Terminal, ClientMessenger, ClientFacebook

#
#  Configurations
#
from etc.cfg_db import base_dir, ans_reserved_records
from etc.cfg_gsp import station_id, all_stations
from etc.cfg_bots import group_assistants
from etc.cfg_bots import group_naruto
from etc.cfg_bots import lingling_id, xiaoxiao_id, chatroom_id, tokentalkteam_id

from etc.cfg_loader import load_robot_info, load_station

g_released = True

Log.info("local storage directory: %s" % base_dir)
Storage.root = base_dir


"""
    Current Station
    ~~~~~~~~~~~~~~~
"""
station_id = ID.parse(identifier=station_id)

station_host = '127.0.0.1'
# station_host = '134.175.87.98'  # dimchat-gz
# station_host = '124.156.108.150'  # dimchat-hk
station_port = 9394

g_station = Server(identifier=station_id, host=station_host, port=station_port)