Skip to content
Snippets Groups Projects
Select Git revision
  • adf25906e9babcad58380689430602c3e09e29f5
  • master default protected
  • dev
  • appimage
  • fix_gitlab
  • fixappveyor
  • gitlab
  • fix_ci
  • fix_dbus_error
  • fix_ci_osx
  • sakia020
  • fix_travis#1105
  • feature/backend
  • check_uniq_node_by_endpoints
  • qt5.7
  • feature/agent_architecture
  • translations
  • pyqt5.6
  • qtwebengine
  • pyinstaller
  • landscape
  • 0.53.2
  • 0.53.1
  • 0.53.0
  • 0.52.0
  • 0.51.1
  • 0.51.0
  • 0.50.5
  • 0.50.4
  • 0.50.3
  • 0.50.2
  • 0.50.1
  • 0.50.0
  • 0.33.0rc7
  • 0.33.0rc6
  • 0.33.0rc5
  • 0.33.0rc4
  • 0.33.0rc3
  • 0.33.0rc2
  • 0.33.0rc1
  • 0.32.10post1
41 results

table_model.py

Blame
  • heads.py 5.90 KiB
    import re
    import attr
    
    from ..block_uid import BlockUID
    from ..document import MalformedDocumentError
    from ...constants import (
        WS2P_PUBLIC_PREFIX_REGEX,
        WS2P_PRIVATE_PREFIX_REGEX,
        WS2P_HEAD_REGEX,
        PUBKEY_REGEX,
        SIGNATURE_REGEX,
        WS2PID_REGEX,
        BLOCK_UID_REGEX,
    )
    
    
    @attr.s()
    class API:
        private = attr.ib(type=str)
        public = attr.ib(type=str)
    
        re_inline = re.compile(
            "WS2P({ws2p_private})?({ws2p_public})?".format(
                ws2p_private=WS2P_PRIVATE_PREFIX_REGEX, ws2p_public=WS2P_PUBLIC_PREFIX_REGEX
            )
        )
    
        @classmethod
        def from_inline(cls, inline: str):
            data = API.re_inline.match(inline)
            if data is None:
                raise MalformedDocumentError("WS2P API Document")
            private = "" if data.group(1) is None else data.group(1)
            public = "" if data.group(2) is None else data.group(2)
            return cls(private, public)
    
        def __str__(self) -> str:
            return "WS2P" + self.private + self.public
    
    
    @attr.s()
    class Head:
        version = attr.ib(type=int)
    
        re_inline = re.compile(WS2P_HEAD_REGEX)
    
        @classmethod
        def from_inline(cls, inline: str, signature: str):
            try:
                data = Head.re_inline.match(inline)
                if data is None:
                    raise MalformedDocumentError("Head")
                head = data.group(0).split(":")
                version = int(head[1]) if len(head) == 2 else 0
                return cls(version)
            except AttributeError:
                raise MalformedDocumentError("Head")
    
        def __str__(self) -> str:
            return "HEAD" if self.version == 0 else "HEAD:{}".format(str(self.version))
    
    
    @attr.s()
    class HeadV0(Head):
        signature = attr.ib(type=str)
        api = attr.ib(type=API)
        head = attr.ib(type=Head)
        pubkey = attr.ib(type=str)
        blockstamp = attr.ib(type=BlockUID)
    
        re_inline = re.compile(
            "^(WS2P(?:{ws2p_private})?(?:{ws2p_public})?):({head}):({pubkey}):({blockstamp})(?::)?(.*)".format(
                ws2p_private=WS2P_PRIVATE_PREFIX_REGEX,
                ws2p_public=WS2P_PUBLIC_PREFIX_REGEX,
                head=WS2P_HEAD_REGEX,
                pubkey=PUBKEY_REGEX,
                blockstamp=BLOCK_UID_REGEX,
            )
        )
    
        re_signature = re.compile(SIGNATURE_REGEX)
    
        @classmethod
        def from_inline(cls, inline: str, signature: str):
            try:
                data = HeadV0.re_inline.match(inline)
                if data is None:
                    raise MalformedDocumentError("HeadV0")
                api = API.from_inline(data.group(1))
                head = Head.from_inline(data.group(2), "")
                pubkey = data.group(3)
                blockstamp = BlockUID.from_str(data.group(4))
                offload = data.group(5)
                return cls(head.version, signature, api, head, pubkey, blockstamp), offload
            except AttributeError:
                raise MalformedDocumentError("HeadV0")
    
        def inline(self) -> str:
            values = (
                str(v)
                for v in attr.astuple(
                    self,
                    recurse=False,
                    filter=attr.filters.exclude(
                        attr.fields(HeadV0).version,
                        attr.fields(HeadV0).signature,
                        attr.fields(HeadV0).api,
                    ),
                )
            )
            return "{0}:{1}".format(str(self.api), ":".join(values))
    
    
    @attr.s()
    class HeadV1(HeadV0):
        ws2pid = attr.ib(type=str)
        software = attr.ib(type=str)
        software_version = attr.ib(type=str)
        pow_prefix = attr.ib(type=int)
    
        re_inline = re.compile(
            "({ws2pid}):({software}):({software_version}):({pow_prefix})(?::)?(.*)".format(
                ws2pid=WS2PID_REGEX,
                software="[A-Za-z-_]+",
                software_version="[0-9]+[.][0-9]+[.][0-9]+[-\\w]*",
                pow_prefix="[0-9]+",
            )
        )
    
        @classmethod
        def from_inline(cls, inline: str, signature: str):
            try:
                v0, offload = HeadV0.from_inline(inline, signature)
                data = HeadV1.re_inline.match(offload)
                if data is None:
                    raise MalformedDocumentError("HeadV1")
                ws2pid = data.group(1)
                software = data.group(2)
                software_version = data.group(3)
                pow_prefix = int(data.group(4))
                offload = data.group(5)
                return (
                    cls(
                        v0.version,
                        v0.signature,
                        v0.api,
                        v0.head,
                        v0.pubkey,
                        v0.blockstamp,
                        ws2pid,
                        software,
                        software_version,
                        pow_prefix,
                    ),
                    offload,
                )
            except AttributeError:
                raise MalformedDocumentError("HeadV1")
    
    
    @attr.s
    class HeadV2(HeadV1):
        free_member_room = attr.ib(type=int)
        free_mirror_room = attr.ib(type=int)
    
        re_inline = re.compile(
            "({free_member_room}):({free_mirror_room})(?::)?(.*)".format(
                free_member_room="[0-9]+", free_mirror_room="[0-9]+"
            )
        )
    
        @classmethod
        def from_inline(cls, inline: str, signature: str):
            try:
                v1, offload = HeadV1.from_inline(inline, signature)
                data = HeadV2.re_inline.match(offload)
                if data is None:
                    raise MalformedDocumentError("HeadV2")
                free_member_room = int(data.group(1))
                free_mirror_room = int(data.group(2))
                return (
                    cls(
                        v1.version,
                        v1.signature,
                        v1.api,
                        v1.head,
                        v1.pubkey,
                        v1.blockstamp,
                        v1.ws2pid,
                        v1.software,
                        v1.software_version,
                        v1.pow_prefix,
                        free_member_room,
                        free_mirror_room,
                    ),
                    "",
                )
            except AttributeError:
                raise MalformedDocumentError("HeadV2")