예제 #1
0
    @property
    def messenger(self) -> ServerMessenger:
        return super().messenger

    @messenger.setter
    def messenger(self, transceiver: ServerMessenger):
        CommandProcessor.messenger.__set__(self, transceiver)

    @property
    def session_server(self) -> SessionServer:
        return self.messenger.session_server

    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(cmd, Command), 'command error: %s' % cmd
        facebook = self.facebook
        users = self.session_server.random_users()
        results = {}
        for item in users:
            meta = facebook.meta(identifier=item)
            if isinstance(meta, Meta):
                results[str(item)] = meta.dictionary
        return SearchCommand(users=list(users), results=results)


# register
spu = SearchCommandProcessor()
CommandProcessor.register(command=SearchCommand.SEARCH,
                          cpu=SearchCommandProcessor())
CommandProcessor.register(command=SearchCommand.ONLINE_USERS,
                          cpu=UsersCommandProcessor())
예제 #2
0
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    login protocol
"""

from typing import Optional

from dimp import ID
from dimp import InstantMessage
from dimp import Content
from dimp import Command
from dimsdk import ReceiptCommand
from dimsdk import CommandProcessor


class LoginCommandProcessor(CommandProcessor):

    #
    #   main
    #
    def process(self, content: Content, sender: ID,
                msg: InstantMessage) -> Optional[Content]:
        assert isinstance(content, Command), 'command error: %s' % content
        # TODO: update login status
        return ReceiptCommand.new(message='Login received')


# register
CommandProcessor.register(command='login',
                          processor_class=LoginCommandProcessor)
예제 #3
0
    def __put(self, cmd: Command, sender: ID) -> Content:
        # receive encrypted contacts, save it
        if self.database.save_contacts_command(cmd=cmd, sender=sender):
            self.info('contacts command saved for %s' % sender)
            return ReceiptCommand.new(message='Contacts of %s received!' %
                                      sender)
        else:
            self.error('failed to save contacts command: %s' % cmd)
            return TextContent.new(text='Contacts not stored %s!' % cmd)

    #
    #   main
    #
    def process(self, content: Content, sender: ID,
                msg: InstantMessage) -> Content:
        if type(self) != ContactsCommandProcessor:
            raise AssertionError('override me!')
        assert isinstance(content, Command), 'command error: %s' % content
        if 'data' in content or 'contacts' in content:
            # upload contacts, save it
            return self.__put(cmd=content, sender=sender)
        else:
            # query contacts, load it
            return self.__get(sender=sender)


# register
CommandProcessor.register(command='contacts',
                          processor_class=ContactsCommandProcessor)
예제 #4
0
            return stored
        else:
            # return TextContent.new(text='Sorry, block-list of %s not found.' % sender)
            # TODO: here should response an empty HistoryCommand: 'block'
            res = Command.new(command='block')
            res['list'] = []
            return res

    def __put(self, cmd: BlockCommand, sender: ID) -> Content:
        # receive block command, save it
        if self.database.save_block_command(cmd=cmd, sender=sender):
            return ReceiptCommand.new(message='Block command of %s received!' % sender)
        else:
            return TextContent.new(text='Sorry, block-list not stored: %s!' % cmd)

    #
    #   main
    #
    def process(self, content: Content, sender: ID, msg: InstantMessage) -> Content:
        assert isinstance(content, BlockCommand), 'block command error: %s' % content
        if 'list' in content:
            # upload block-list, save it
            return self.__put(cmd=content, sender=sender)
        else:
            # query block-list, load it
            return self.__get(sender=sender)


# register
CommandProcessor.register(command='block', processor_class=BlockCommandProcessor)
예제 #5
0
        assert isinstance(content, Command), 'command error: %s' % content
        # welcome back!
        self.receptionist.add_guest(identifier=sender)
        session = self.messenger.current_session(identifier=sender)
        if isinstance(session, Session):
            session.active = True
        return ReceiptCommand.new(message='Client online received')


class OfflineCommandProcessor(ReportCommandProcessor):

    #
    #   main
    #
    def process(self, content: Content, sender: ID, msg: InstantMessage) -> Optional[Content]:
        assert isinstance(content, Command), 'command error: %s' % content
        # goodbye!
        session = self.messenger.current_session(identifier=sender)
        if isinstance(session, Session):
            session.active = False
        return ReceiptCommand.new(message='Client offline received')


# register
CommandProcessor.register(command='report', processor_class=ReportCommandProcessor)
CommandProcessor.register(command='broadcast', processor_class=ReportCommandProcessor)

CommandProcessor.register(command='apns', processor_class=APNsCommandProcessor)
CommandProcessor.register(command='online', processor_class=OnlineCommandProcessor)
CommandProcessor.register(command='offline', processor_class=OfflineCommandProcessor)
예제 #6
0
from dimsdk import CommandProcessor, GroupCommandProcessor


class QueryCommandProcessor(GroupCommandProcessor):

    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(cmd, QueryCommand), 'group command error: %s' % cmd
        facebook = self.facebook
        group: ID = cmd.group
        # 1. check permission
        if not facebook.exists_member(member=msg.sender, group=group):
            if not facebook.exists_assistant(member=msg.sender, group=group):
                raise AssertionError('only member/assistant can query: %s, %s' % (group, msg.sender))
        # 2. get group members
        members = facebook.members(identifier=group)
        if members is None or len(members) == 0:
            text = 'Group members not found: %s' % group
            return TextContent(text=text)
        # 3. response group members for sender
        user = facebook.current_user
        assert user is not None, 'current user not set'
        if facebook.is_owner(member=user.identifier, group=group):
            return GroupCommand.reset(group=group, members=members)
        else:
            return GroupCommand.invite(group=group, members=members)


# register
CommandProcessor.register(command=GroupCommand.QUERY, cpu=QueryCommandProcessor())
예제 #7
0
            session.active = True
        # post notification
        post_notification(session=session, sender=self)
        # TODO: notification for pushing offline message(s) from 'last_time'
        return ReceiptCommand(message='Client online received')


class OfflineCommandProcessor(ReportCommandProcessor):
    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(
            cmd, ReportCommand), 'offline report command error: %s' % cmd
        # goodbye!
        session = self.messenger.current_session(identifier=msg.sender)
        if isinstance(session, Session):
            session.active = False
        # post notification
        post_notification(session=session, sender=self)
        return ReceiptCommand(message='Client offline received')


# register
rpu = ReportCommandProcessor()
CommandProcessor.register(command=ReportCommand.REPORT, cpu=rpu)
CommandProcessor.register(command='broadcast', cpu=rpu)

CommandProcessor.register(command='apns', cpu=APNsCommandProcessor())
CommandProcessor.register(command=ReportCommand.ONLINE,
                          cpu=OnlineCommandProcessor())
CommandProcessor.register(command=ReportCommand.OFFLINE,
                          cpu=OfflineCommandProcessor())
예제 #8
0
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Handshake Protocol
"""

from typing import Optional

from dimp import ReliableMessage
from dimp import Content
from dimp import Command
from dimsdk import HandshakeCommand
from dimsdk import CommandProcessor


class HandshakeCommandProcessor(CommandProcessor):
    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(cmd, HandshakeCommand), 'command error: %s' % cmd
        message = cmd.message
        if 'DIM?' == message:
            # station ask client to handshake again
            return HandshakeCommand.restart(session=cmd.session)
        elif 'DIM!' == message:
            # handshake accepted by station
            server = self.messenger.server
            server.handshake_success()


# register
CommandProcessor.register(command=Command.HANDSHAKE,
                          cpu=HandshakeCommandProcessor())
예제 #9
0
    @staticmethod
    def __ask(session_key: str) -> Content:
        # station ask client to handshake again
        return HandshakeCommand.restart(session=session_key)

    def __success(self) -> Optional[Content]:
        # handshake accepted by station
        return self.delegate.handshake_success()

    #
    #   main
    #
    def process(self, content: Content, sender: ID, msg: InstantMessage) -> Content:
        if type(self) != HandshakeCommandProcessor:
            raise AssertionError('override me!')
        assert isinstance(content, HandshakeCommand), 'command error: %s' % content
        message = content.message
        if 'DIM!' == message:
            # S -> C
            return self.__success()
        elif 'DIM?' == message:
            # S -> C
            return self.__ask(session_key=content.session)
        else:
            # C -> S: Hello world!
            return self.__offer(session_key=content.session, sender=sender)


# register
CommandProcessor.register(command=Command.HANDSHAKE, processor_class=HandshakeCommandProcessor)
예제 #10
0
        if stored is not None:
            # response the stored mute command directly
            return stored
        else:
            # return TextContent.new(text='Sorry, mute-list of %s not found.' % sender)
            # TODO: here should response an empty HistoryCommand: 'mute'
            res = Command(command=MuteCommand.MUTE)
            res['list'] = []
            return res

    def __put(self, cmd: MuteCommand, sender: ID) -> Content:
        # receive mute command, save it
        if self.database.save_mute_command(cmd=cmd, sender=sender):
            return ReceiptCommand(message='Mute command of %s received!' %
                                  sender)
        else:
            return TextContent(text='Sorry, mute-list not stored %s!' % cmd)

    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(cmd, MuteCommand), 'command error: %s' % cmd
        if 'list' in cmd:
            # upload mute-list, save it
            return self.__put(cmd=cmd, sender=msg.sender)
        else:
            # query mute-list, load it
            return self.__get(sender=msg.sender)


# register
CommandProcessor.register(command=MuteCommand.MUTE, cpu=MuteCommandProcessor())
예제 #11
0
        assert isinstance(cmd, LoginCommand), 'command error: %s' % cmd
        sender = msg.sender
        # check roaming
        sid = self.__roaming(cmd=cmd, sender=sender)
        if sid is not None:
            self.info('%s is roamer to: %s' % (sender, sid))
            octopus.roaming(roamer=sender, station=sid)
        # update login info
        if not self.database.save_login(cmd=cmd, msg=msg):
            return None
        # respond nothing
        return None


# register
CommandProcessor.register(command=Command.LOGIN, cpu=LoginCommandProcessor())


class InnerMessenger(ClientMessenger):
    """ Messenger for processing message from local station """
    def __init__(self):
        super().__init__()
        self.accepted = False

    # Override
    def process_reliable_message(
            self, msg: ReliableMessage) -> Optional[ReliableMessage]:
        if self.accepted:
            return octopus.departure(msg=msg)
        else:
            return super().process_reliable_message(msg=msg)
예제 #12
0
from dimsdk import CommandProcessor

from ..utils import Log


class ReceiptCommandProcessor(CommandProcessor):
    def __init__(self, messenger):
        super().__init__(messenger=messenger)

    def info(self, msg: str):
        Log.info('%s >\t%s' % (self.__class__.__name__, msg))

    def error(self, msg: str):
        Log.error('%s >\t%s' % (self.__class__.__name__, msg))

    #
    #   main
    #
    def process(self, content: Content, sender: ID,
                msg: InstantMessage) -> Optional[Content]:
        assert isinstance(content,
                          ReceiptCommand), 'text content error: %s' % content
        nickname = self.facebook.nickname(identifier=sender)
        self.info('Received receipt message from %s: %s' % (nickname, content))
        return None


# register
CommandProcessor.register(command=Command.RECEIPT,
                          processor_class=ReceiptCommandProcessor)
예제 #13
0
    def __process_contacts(self, cmd: StorageCommand, sender: ID) -> Content:
        if cmd.data is None and 'contacts' not in cmd:
            # query contacts, load it
            return self.__get_contacts(sender=sender)
        else:
            # upload contacts, save it
            return self.__put_contacts(cmd=cmd, sender=sender)

    #
    #   main
    #
    def process(self, content: Content, sender: ID,
                msg: InstantMessage) -> Content:
        assert isinstance(content,
                          StorageCommand), 'command error: %s' % content
        title = content.title
        if title == StorageCommand.CONTACTS:
            return self.__process_contacts(cmd=content, sender=sender)
        # error
        return TextContent.new(
            text='Storage command (title: %s) not support yet!' % title)


# register
CommandProcessor.register(command=StorageCommand.STORAGE,
                          processor_class=StorageCommandProcessor)
CommandProcessor.register(command=StorageCommand.CONTACTS,
                          processor_class=StorageCommandProcessor)
CommandProcessor.register(command=StorageCommand.PRIVATE_KEY,
                          processor_class=StorageCommandProcessor)
예제 #14
0
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ==============================================================================
"""
    Receipt Command Processor
    ~~~~~~~~~~~~~~~~~~~~~~~~~

"""

from typing import Optional

from dimp import ReliableMessage
from dimp import Content, Command
from dimsdk import ReceiptCommand
from dimsdk import CommandProcessor


class ReceiptCommandProcessor(CommandProcessor):
    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(cmd,
                          ReceiptCommand), 'receipt command error: %s' % cmd
        # nickname = self.facebook.name(identifier=sender)
        return None


# register
CommandProcessor.register(command=Command.RECEIPT,
                          cpu=ReceiptCommandProcessor())
예제 #15
0
        # results
        results = content.get('results')
        if results is not None:
            print('      results:', json.dumps(results))
        return None


class UsersCommandProcessor(CommandProcessor):

    #
    #   main
    #
    def process(self, content: Content, sender: ID,
                msg: InstantMessage) -> Optional[Content]:
        assert isinstance(content, Command), 'command error: %s' % content
        # message
        message = content.get('message')
        print('online users response: %s' % message)
        # users
        users = content.get('users')
        if users is not None:
            print('      users:', json.dumps(users))
        return None


# register
CommandProcessor.register(command='search',
                          processor_class=SearchCommandProcessor)
CommandProcessor.register(command='users',
                          processor_class=UsersCommandProcessor)
예제 #16
0
            # response the stored block command directly
            return stored
        else:
            # return TextContent.new(text='Sorry, block-list of %s not found.' % sender)
            # TODO: here should response an empty HistoryCommand: 'block'
            res = Command(command=BlockCommand.BLOCK)
            res['list'] = []
            return res

    def __put(self, cmd: BlockCommand, sender: ID) -> Content:
        # receive block command, save it
        if self.database.save_block_command(cmd=cmd, sender=sender):
            return ReceiptCommand(message='Block command of %s received!' %
                                  sender)
        else:
            return TextContent(text='Sorry, block-list not stored: %s!' % cmd)

    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(cmd, BlockCommand), 'block command error: %s' % cmd
        if 'list' in cmd:
            # upload block-list, save it
            return self.__put(cmd=cmd, sender=msg.sender)
        else:
            # query block-list, load it
            return self.__get(sender=msg.sender)


# register
CommandProcessor.register(command=BlockCommand.BLOCK,
                          cpu=BlockCommandProcessor())
예제 #17
0
    def __put_contacts(self, cmd: StorageCommand, sender: ID) -> Content:
        # receive encrypted contacts, save it
        if self.database.save_contacts_command(cmd=cmd, sender=sender):
            return ReceiptCommand(message='Contacts of %s received!' % sender)
        else:
            return TextContent(text='Contacts not stored %s!' % cmd)

    def __process_contacts(self, cmd: StorageCommand, sender: ID) -> Content:
        if cmd.data is None and 'contacts' not in cmd:
            # query contacts, load it
            return self.__get_contacts(sender=sender)
        else:
            # upload contacts, save it
            return self.__put_contacts(cmd=cmd, sender=sender)

    def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
        assert isinstance(cmd, StorageCommand), 'command error: %s' % cmd
        title = cmd.title
        if title == StorageCommand.CONTACTS:
            return self.__process_contacts(cmd=cmd, sender=msg.sender)
        # error
        return TextContent(text='Storage command (title: %s) not support yet!' % title)


# register
spu = StorageCommandProcessor()
CommandProcessor.register(command=StorageCommand.STORAGE, cpu=spu)
CommandProcessor.register(command=StorageCommand.CONTACTS, cpu=spu)
CommandProcessor.register(command=StorageCommand.PRIVATE_KEY, cpu=spu)
예제 #18
0
            return res

    def __put(self, cmd: Command, sender: ID) -> Content:
        # receive mute command, save it
        if self.database.save_mute_command(cmd=cmd, sender=sender):
            self.info('mute command saved for %s' % sender)
            return ReceiptCommand.new(message='Mute command of %s received!' %
                                      sender)
        else:
            self.error('failed to save mute command: %s' % cmd)
            return TextContent.new(text='Mute-list not stored %s!' % cmd)

    #
    #   main
    #
    def process(self, content: Content, sender: ID,
                msg: InstantMessage) -> Content:
        if type(self) != MuteCommandProcessor:
            raise AssertionError('override me!')
        assert isinstance(content, Command), 'command error: %s' % content
        if 'list' in content:
            # upload mute-list, save it
            return self.__put(cmd=content, sender=sender)
        else:
            # query mute-list, load it
            return self.__get(sender=sender)


# register
CommandProcessor.register(command='mute', processor_class=MuteCommandProcessor)