Skip to content

dimchat/sdk-py

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Decentralized Instant Messaging (Python SDK)

License PRs Welcome Platform Issues Repo Size Tags Version

Watchers Forks Stars Followers

Dependencies

  • Latest Versions
Name Version Description
Ming Ke Ming (名可名) Version Decentralized User Identity Authentication
Dao Ke Dao (道可道) Version Universal Message Module
DIMP (去中心化通讯协议) Version Decentralized Instant Messaging Protocol

Extensions

Content

extends CustomizedContent

ContentProcessor

from typing import Optional, List, Dict

from dimsdk import *
from dimsdk.cpu import *


class AppCustomizedProcessor(CustomizedContentProcessor):
    """
        Customized Content Processing Unit
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Handle content for application customized
    """

    def __init__(self, facebook: Facebook, messenger: Messenger):
        super().__init__(facebook=facebook, messenger=messenger)
        self.__handlers: Dict[str, CustomizedContentHandler] = {}

    def set_handler(self, app: str, mod: str, handler: CustomizedContentHandler):
        key = '%s:%s' % (app, mod)
        self.__handlers[key] = handler

    # protected
    def get_handler(self, app: str, mod: str) -> Optional[CustomizedContentHandler]:
        key = '%s:%s' % (app, mod)
        return self.__handlers.get(key)

    # Override
    def _filter(self, app: str, mod: str, content: CustomizedContent, msg: ReliableMessage) -> CustomizedContentHandler:
        """ Override for your handler """
        handler = self.get_handler(app=app, mod=mod)
        if handler is not None:
            return handler
        # default handler
        return super()._filter(app=app, mod=mod, content=content, msg=msg)
from typing import Optional, List, Dict

from dimsdk import *
from dimsdk.cpu import *

from ...common import GroupHistory


class GroupHistoryHandler(BaseCustomizedHandler):
    """ Command Transform:

        +===============================+===============================+
        |      Customized Content       |      Group Query Command      |
        +-------------------------------+-------------------------------+
        |   "type" : i2s(0xCC)          |   "type" : i2s(0x88)          |
        |   "sn"   : 123                |   "sn"   : 123                |
        |   "time" : 123.456            |   "time" : 123.456            |
        |   "app"  : "chat.dim.group"   |                               |
        |   "mod"  : "history"          |                               |
        |   "act"  : "query"            |                               |
        |                               |   "command"   : "query"       |
        |   "group"     : "{GROUP_ID}"  |   "group"     : "{GROUP_ID}"  |
        |   "last_time" : 0             |   "last_time" : 0             |
        +===============================+===============================+
    """

    # Override
    async def handle_action(self, act: str, sender: ID, content: CustomizedContent,
                            msg: ReliableMessage) -> List[Content]:
        if content.group is None:
            text = 'Group command error.'
            return self._respond_receipt(text=text, envelope=msg.envelope, content=content)
        elif GroupHistory.ACT_QUERY == act:
            assert GroupHistory.APP == content.application
            assert GroupHistory.MOD == content.module
            return await self.__transform_query_command(content=content, msg=msg)
        else:
            # assert False, 'unknown action: %s, %s, sender: %s' % (act, content, sender)
            return await super().handle_action(act=act, sender=sender, content=content, msg=msg)

    async def __transform_query_command(self, content: CustomizedContent, msg: ReliableMessage) -> List[Content]:
        messenger = self.messenger
        if messenger is None:
            assert False, 'messenger lost'
            # return []
        info = content.copy_dictionary()
        info['type'] = ContentType.COMMAND
        info['command'] = GroupCommand.QUERY
        query = Content.parse(content=info)
        if isinstance(query, QueryCommand):
            return await messenger.process_content(content=query, r_msg=msg)
        # else:
        #     assert False, 'query command error: %s, %s, sender: %s' % (query, content, sender)
        text = 'Query command error.'
        return self._respond_receipt(text=text, envelope=msg.envelope, content=content)

ContentProcessorCreator

from typing import Optional

from dimsdk import *
from dimsdk.cpu import *

from .handshake import *
from .customized import *


class ClientContentProcessorCreator(BaseContentProcessorCreator):

    # noinspection PyMethodMayBeStatic
    def _create_customized_content_processor(self, facebook: Facebook, messenger: Messenger) -> AppCustomizedProcessor:
        cpu = AppCustomizedProcessor(facebook=facebook, messenger=messenger)
        # 'chat.dim.group:history'
        handler = GroupHistoryHandler(facebook=facebook, messenger=messenger)
        cpu.set_handler(app=GroupHistory.APP, mod=GroupHistory.MOD, handler=handler)
        return cpu

    # Override
    def create_content_processor(self, msg_type: str) -> Optional[ContentProcessor]:
        # application customized
        if msg_type == ContentType.APPLICATION or msg_type == 'application':
            return self._create_customized_content_processor(facebook=self.facebook, messenger=self.messenger)
        if msg_type == ContentType.CUSTOMIZED or msg_type == 'customized':
            return self._create_customized_content_processor(facebook=self.facebook, messenger=self.messenger)
        # others
        return super().create_content_processor(msg_type=msg_type)

    # Override
    def create_command_processor(self, msg_type: str, cmd: str) -> Optional[ContentProcessor]:
        # handshake
        if cmd == HandshakeCommand.HANDSHAKE:
            return HandshakeCommandProcessor(facebook=self.facebook, messenger=self.messenger)
        # others
        return super().create_command_processor(msg_type=msg_type, cmd=cmd)

Usage

To let your CustomizedContentProcessor start to work, you must override BaseContentProcessorCreator for message types:

  1. ContentType.APPLICATION
  2. ContentType.CUSTOMIZED

and then set your creator for GeneralContentProcessorFactory in the MessageProcessor.


Copyright © 2018-2025 Albert Moky Followers

About

Decentralized Instant Messaging (Python SDK)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages