dimples 1.0.0__tar.gz → 1.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dimples-1.0.0 → dimples-1.0.2}/PKG-INFO +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/__init__.py +2 -0
- dimples-1.0.2/dimples/conn/flexible.py +168 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/gate.py +9 -11
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/gatekeeper.py +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/mars.py +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/mtp.py +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/protocol/__init__.py +4 -2
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/protocol/ws.py +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/session.py +2 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/ws.py +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/base.py +4 -15
- {dimples-1.0.0 → dimples-1.0.2}/dimples/edge/octopus.py +6 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/edge/shared.py +2 -2
- {dimples-1.0.0 → dimples-1.0.2}/dimples/register/run.py +2 -2
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/session.py +0 -12
- {dimples-1.0.0 → dimples-1.0.2}/dimples/station/shared.py +2 -2
- {dimples-1.0.0 → dimples-1.0.2}/dimples/utils/__init__.py +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples/utils/cache.py +1 -2
- {dimples-1.0.0 → dimples-1.0.2}/dimples/utils/dos.py +99 -48
- {dimples-1.0.0 → dimples-1.0.2}/dimples.egg-info/PKG-INFO +1 -1
- {dimples-1.0.0 → dimples-1.0.2}/dimples.egg-info/SOURCES.txt +2 -2
- {dimples-1.0.0 → dimples-1.0.2}/setup.py +1 -1
- dimples-1.0.0/dimples/utils/singleton.py +0 -43
- {dimples-1.0.0 → dimples-1.0.2}/README.md +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/archivist.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/checkpoint.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/commands.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/creator.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/group.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/grp_expel.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/grp_invite.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/grp_join.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/grp_query.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/grp_quit.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/grp_reset.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/grp_resign.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/cpu/handshake.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/facebook.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/messenger.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/network/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/network/session.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/network/state.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/network/transition.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/packer.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/processor.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/client/terminal.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/anonymous.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/ans.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/archivist.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/compat/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/compat/btc.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/compat/compatible.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/compat/entity.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/compat/meta.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/compat/network.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/dbi/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/dbi/account.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/dbi/message.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/dbi/session.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/facebook.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/messenger.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/packer.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/processer.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/protocol/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/protocol/ans.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/protocol/block.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/protocol/handshake.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/protocol/login.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/protocol/mute.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/protocol/report.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/register.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/common/session.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/protocol/mars.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/queue.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/conn/seeker.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/account.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/document.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/group.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/group_history.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/group_keys.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/login.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/meta.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/private.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/station.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/dos/user.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/message.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/session.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_cipherkey.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_document.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_group.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_group_history.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_group_keys.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_login.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_message.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_meta.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_private.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_station.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/database/t_user.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/edge/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/edge/start.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/admin.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/builder.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/delegate.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/emitter.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/helper.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/manager.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/group/packer.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/register/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/register/base.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/register/ext.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/register/shared.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/archivist.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/cpu/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/cpu/ans.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/cpu/document.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/cpu/handshake.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/cpu/login.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/cpu/report.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/dispatcher.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/messenger.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/packer.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/processor.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/push.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/session_center.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/server/trace.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/station/__init__.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/station/handler.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/station/start.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/utils/config.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples/utils/log.py +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples.egg-info/dependency_links.txt +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples.egg-info/entry_points.txt +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples.egg-info/requires.txt +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/dimples.egg-info/top_level.txt +0 -0
- {dimples-1.0.0 → dimples-1.0.2}/setup.cfg +0 -0
|
@@ -63,6 +63,7 @@ from .protocol import WebSocket, NetMsg, NetMsgHead, NetMsgSeq
|
|
|
63
63
|
from .ws import WSArrival, WSDeparture, WSDocker
|
|
64
64
|
from .mars import MarsStreamArrival, MarsStreamDeparture, MarsStreamDocker
|
|
65
65
|
from .mtp import MTPStreamArrival, MTPStreamDeparture, MTPStreamDocker
|
|
66
|
+
from .flexible import FlexibleDocker
|
|
66
67
|
from .gate import CommonGate, TCPServerGate, TCPClientGate, UDPServerGate, UDPClientGate
|
|
67
68
|
# from .gatekeeper import GateKeeper
|
|
68
69
|
from .queue import MessageWrapper, MessageQueue
|
|
@@ -107,6 +108,7 @@ __all__ = [
|
|
|
107
108
|
'WSArrival', 'WSDeparture', 'WSDocker',
|
|
108
109
|
'MarsStreamArrival', 'MarsStreamDeparture', 'MarsStreamDocker',
|
|
109
110
|
'MTPStreamArrival', 'MTPStreamDeparture', 'MTPStreamDocker',
|
|
111
|
+
'FlexibleDocker',
|
|
110
112
|
'CommonGate', 'TCPServerGate', 'TCPClientGate', 'UDPServerGate', 'UDPClientGate',
|
|
111
113
|
# 'GateKeeper',
|
|
112
114
|
'MessageWrapper', 'MessageQueue',
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Star Gate: Interfaces for network connection
|
|
4
|
+
#
|
|
5
|
+
# Written in 2024 by Moky <albert.moky@gmail.com>
|
|
6
|
+
#
|
|
7
|
+
# ==============================================================================
|
|
8
|
+
# MIT License
|
|
9
|
+
#
|
|
10
|
+
# Copyright (c) 2024 Albert Moky
|
|
11
|
+
#
|
|
12
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
# in the Software without restriction, including without limitation the rights
|
|
15
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
# furnished to do so, subject to the following conditions:
|
|
18
|
+
#
|
|
19
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
# copies or substantial portions of the Software.
|
|
21
|
+
#
|
|
22
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
# SOFTWARE.
|
|
29
|
+
# ==============================================================================
|
|
30
|
+
|
|
31
|
+
from typing import Optional, Union, List
|
|
32
|
+
|
|
33
|
+
from startrek.types import SocketAddress
|
|
34
|
+
from startrek.fsm import Runner
|
|
35
|
+
from startrek import Connection
|
|
36
|
+
from startrek import Arrival, Departure
|
|
37
|
+
from startrek import StarDocker
|
|
38
|
+
|
|
39
|
+
from .protocol import DeparturePacker
|
|
40
|
+
|
|
41
|
+
from .ws import WSDocker
|
|
42
|
+
from .mtp import MTPStreamDocker, TransactionID, MTPHelper
|
|
43
|
+
from .mars import MarsStreamDocker, MarsHelper
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class FlexibleDocker(StarDocker, DeparturePacker):
|
|
47
|
+
|
|
48
|
+
def __init__(self, remote: SocketAddress, local: Optional[SocketAddress]):
|
|
49
|
+
super().__init__(remote=remote, local=local)
|
|
50
|
+
self.__docker: Optional[StarDocker] = None
|
|
51
|
+
|
|
52
|
+
def _get_docker(self, data: bytes) -> Optional[StarDocker]:
|
|
53
|
+
docker = self.__docker
|
|
54
|
+
if docker is not None or len(data) == 0:
|
|
55
|
+
return docker
|
|
56
|
+
# check data for packer
|
|
57
|
+
if WSDocker.check(data=data):
|
|
58
|
+
docker = WSDocker(remote=self.remote_address, local=self.local_address)
|
|
59
|
+
elif MTPStreamDocker.check(data=data):
|
|
60
|
+
docker = MTPStreamDocker(remote=self.remote_address, local=self.local_address)
|
|
61
|
+
elif MarsStreamDocker.check(data=data):
|
|
62
|
+
docker = MarsStreamDocker(remote=self.remote_address, local=self.local_address)
|
|
63
|
+
else:
|
|
64
|
+
print('[FlexibleDocker] unsupported data format: %s' % data)
|
|
65
|
+
return None
|
|
66
|
+
# OK
|
|
67
|
+
docker.delegate = self.delegate
|
|
68
|
+
Runner.async_run(coroutine=docker.set_connection(conn=self.connection))
|
|
69
|
+
self.__docker = docker
|
|
70
|
+
return docker
|
|
71
|
+
|
|
72
|
+
# Override
|
|
73
|
+
async def set_connection(self, conn: Optional[Connection]):
|
|
74
|
+
await super().set_connection(conn=conn)
|
|
75
|
+
docker = self.__docker
|
|
76
|
+
if docker is not None:
|
|
77
|
+
await docker.set_connection(conn=conn)
|
|
78
|
+
|
|
79
|
+
# Override
|
|
80
|
+
async def send_ship(self, ship: Departure) -> bool:
|
|
81
|
+
docker = self.__docker
|
|
82
|
+
if docker is not None:
|
|
83
|
+
return await docker.send_ship(ship=ship)
|
|
84
|
+
|
|
85
|
+
# Override
|
|
86
|
+
async def process_received(self, data: bytes):
|
|
87
|
+
docker = self._get_docker(data=data)
|
|
88
|
+
if docker is not None:
|
|
89
|
+
return await docker.process_received(data=data)
|
|
90
|
+
|
|
91
|
+
# Override
|
|
92
|
+
def _get_arrivals(self, data: bytes) -> List[Arrival]:
|
|
93
|
+
raise AssertionError('should not happen')
|
|
94
|
+
|
|
95
|
+
# Override
|
|
96
|
+
async def _check_arrival(self, ship: Arrival) -> Optional[Arrival]:
|
|
97
|
+
raise AssertionError('should not happen')
|
|
98
|
+
|
|
99
|
+
# Override
|
|
100
|
+
async def _check_response(self, ship: Arrival) -> Optional[Departure]:
|
|
101
|
+
raise AssertionError('should not happen')
|
|
102
|
+
|
|
103
|
+
# Override
|
|
104
|
+
def _assemble_arrival(self, ship: Arrival) -> Optional[Arrival]:
|
|
105
|
+
raise AssertionError('should not happen')
|
|
106
|
+
|
|
107
|
+
# Override
|
|
108
|
+
def _next_departure(self, now: float) -> Optional[Departure]:
|
|
109
|
+
raise AssertionError('should not happen')
|
|
110
|
+
|
|
111
|
+
# Override
|
|
112
|
+
def purge(self, now: float = 0) -> int:
|
|
113
|
+
cnt = super().purge(now=now)
|
|
114
|
+
docker = self.__docker
|
|
115
|
+
if docker is not None:
|
|
116
|
+
cnt += docker.purge(now=now)
|
|
117
|
+
return cnt
|
|
118
|
+
|
|
119
|
+
# Override
|
|
120
|
+
async def close(self):
|
|
121
|
+
await self.set_connection(conn=None)
|
|
122
|
+
docker = self.__docker
|
|
123
|
+
if docker is not None:
|
|
124
|
+
self.__docker = None
|
|
125
|
+
await docker.close()
|
|
126
|
+
|
|
127
|
+
# Override
|
|
128
|
+
async def process(self) -> bool:
|
|
129
|
+
docker = self.__docker
|
|
130
|
+
if docker is not None:
|
|
131
|
+
return await docker.process()
|
|
132
|
+
|
|
133
|
+
# Override
|
|
134
|
+
async def send_data(self, payload: Union[bytes, bytearray]) -> bool:
|
|
135
|
+
docker = self.__docker
|
|
136
|
+
if docker is None:
|
|
137
|
+
# docker not ready
|
|
138
|
+
return False
|
|
139
|
+
elif isinstance(docker, WSDocker):
|
|
140
|
+
ship = docker.pack(payload=payload)
|
|
141
|
+
return await docker.send_ship(ship=ship)
|
|
142
|
+
elif isinstance(docker, MTPStreamDocker):
|
|
143
|
+
# sn = TransactionID.from_data(data=ship.sn)
|
|
144
|
+
sn = TransactionID.generate()
|
|
145
|
+
pack = MTPHelper.create_message(body=payload, sn=sn)
|
|
146
|
+
return await docker.send_package(pack=pack)
|
|
147
|
+
elif isinstance(docker, MarsStreamDocker):
|
|
148
|
+
mars = MarsHelper.create_push(payload=payload)
|
|
149
|
+
ship = MarsStreamDocker.create_departure(mars=mars)
|
|
150
|
+
return await docker.send_ship(ship=ship)
|
|
151
|
+
else:
|
|
152
|
+
# error
|
|
153
|
+
return await docker.send_data(payload=payload)
|
|
154
|
+
|
|
155
|
+
# Override
|
|
156
|
+
async def heartbeat(self):
|
|
157
|
+
docker = self.__docker
|
|
158
|
+
if docker is not None:
|
|
159
|
+
await docker.heartbeat()
|
|
160
|
+
|
|
161
|
+
# Override
|
|
162
|
+
def pack(self, payload: bytes, priority: int = 0) -> Optional[Departure]:
|
|
163
|
+
docker = self.__docker
|
|
164
|
+
if docker is None:
|
|
165
|
+
return None
|
|
166
|
+
else:
|
|
167
|
+
assert isinstance(docker, DeparturePacker), 'docker error: %s' % docker
|
|
168
|
+
return docker.pack(payload=payload, priority=priority)
|
|
@@ -45,6 +45,7 @@ from ..utils import Logging
|
|
|
45
45
|
from .mtp import TransactionID, MTPStreamDocker, MTPHelper
|
|
46
46
|
from .mars import MarsStreamArrival, MarsStreamDocker, MarsHelper
|
|
47
47
|
from .ws import WSDocker
|
|
48
|
+
from .flexible import FlexibleDocker
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
H = TypeVar('H')
|
|
@@ -112,7 +113,9 @@ class CommonGate(StarGate, Logging, Generic[H], ABC):
|
|
|
112
113
|
async def send_response(self, payload: bytes, ship: Arrival,
|
|
113
114
|
remote: SocketAddress, local: Optional[SocketAddress]) -> bool:
|
|
114
115
|
worker = self._get_docker(remote=remote, local=local)
|
|
115
|
-
if isinstance(worker,
|
|
116
|
+
if isinstance(worker, FlexibleDocker):
|
|
117
|
+
return await worker.send_data(payload=payload)
|
|
118
|
+
elif isinstance(worker, MTPStreamDocker):
|
|
116
119
|
# sn = TransactionID.from_data(data=ship.sn)
|
|
117
120
|
sn = TransactionID.generate()
|
|
118
121
|
pack = MTPHelper.create_message(body=payload, sn=sn)
|
|
@@ -204,16 +207,11 @@ class TCPServerGate(CommonGate, Generic[H]):
|
|
|
204
207
|
def _create_docker(self, parties: List[bytes],
|
|
205
208
|
remote: SocketAddress, local: Optional[SocketAddress]) -> Docker:
|
|
206
209
|
count = len(parties)
|
|
207
|
-
if count == 0
|
|
208
|
-
# return MTPStreamDocker(remote=remote, local=local, gate=self)
|
|
209
|
-
assert False, 'data empty'
|
|
210
|
-
data = parties[0]
|
|
211
|
-
for i in range(1, count):
|
|
212
|
-
data = data + parties[i]
|
|
213
|
-
if len(data) == 0:
|
|
214
|
-
assert False, 'data empty'
|
|
210
|
+
data = b'' if count == 0 else parties[count - 1]
|
|
215
211
|
# check data format before creating docker
|
|
216
|
-
if
|
|
212
|
+
if len(data) == 0:
|
|
213
|
+
docker = FlexibleDocker(remote=remote, local=local)
|
|
214
|
+
elif MTPStreamDocker.check(data=data):
|
|
217
215
|
docker = MTPStreamDocker(remote=remote, local=local)
|
|
218
216
|
elif MarsStreamDocker.check(data=data):
|
|
219
217
|
docker = MarsStreamDocker(remote=remote, local=local)
|
|
@@ -233,7 +231,7 @@ class UDPServerGate(CommonGate, Generic[H]):
|
|
|
233
231
|
count = len(parties)
|
|
234
232
|
if count == 0:
|
|
235
233
|
# return MTPStreamDocker(remote=remote, local=local, gate=self)
|
|
236
|
-
assert False, 'data empty'
|
|
234
|
+
assert False, 'data empty: %s -> %s' % (remote, local)
|
|
237
235
|
data = parties[count - 1]
|
|
238
236
|
# check data format before creating docker
|
|
239
237
|
if MTPStreamDocker.check(data=data):
|
|
@@ -276,7 +276,7 @@ class GateKeeper(Runner, DockerDelegate, Logging):
|
|
|
276
276
|
self.error(msg='gate error, failed to send data')
|
|
277
277
|
return ok
|
|
278
278
|
|
|
279
|
-
async def _docker_pack(self, payload: bytes, priority: int = 0) -> Departure:
|
|
279
|
+
async def _docker_pack(self, payload: bytes, priority: int = 0) -> Optional[Departure]:
|
|
280
280
|
docker = await self.gate.fetch_docker([], remote=self.remote_address, local=None)
|
|
281
281
|
assert isinstance(docker, DeparturePacker), 'departure packer error: %s' % docker
|
|
282
282
|
return docker.pack(payload=payload, priority=priority)
|
|
@@ -292,7 +292,7 @@ class MarsStreamDocker(PlainDocker, DeparturePacker):
|
|
|
292
292
|
pass
|
|
293
293
|
|
|
294
294
|
# Override
|
|
295
|
-
def pack(self, payload: bytes, priority: int = 0) -> Departure:
|
|
295
|
+
def pack(self, payload: bytes, priority: int = 0) -> Optional[Departure]:
|
|
296
296
|
mars = MarsHelper.create_push(payload=payload)
|
|
297
297
|
return self.create_departure(mars=mars, priority=priority)
|
|
298
298
|
|
|
@@ -197,7 +197,7 @@ class MTPStreamDocker(PackageDocker, DeparturePacker):
|
|
|
197
197
|
return MTPHelper.respond_message(sn=sn, pages=pages, index=index, body=OK)
|
|
198
198
|
|
|
199
199
|
# Override
|
|
200
|
-
def pack(self, payload: bytes, priority: int = 0) -> Departure:
|
|
200
|
+
def pack(self, payload: bytes, priority: int = 0) -> Optional[Departure]:
|
|
201
201
|
pkg = MTPHelper.create_message(body=payload)
|
|
202
202
|
return self._create_departure(pack=pkg, priority=priority)
|
|
203
203
|
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from abc import ABC
|
|
31
|
+
from abc import ABC, abstractmethod
|
|
32
|
+
from typing import Optional
|
|
32
33
|
|
|
33
34
|
from startrek import Departure
|
|
34
35
|
|
|
@@ -38,7 +39,8 @@ from .mars import NetMsg, NetMsgHead, NetMsgSeq
|
|
|
38
39
|
|
|
39
40
|
class DeparturePacker(ABC):
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def pack(self, payload: bytes, priority: int = 0) -> Optional[Departure]:
|
|
42
44
|
raise NotImplemented
|
|
43
45
|
|
|
44
46
|
|
|
@@ -172,7 +172,7 @@ class WebSocket:
|
|
|
172
172
|
mask = None
|
|
173
173
|
# 4. get payload
|
|
174
174
|
if stream_len < pos + msg_len:
|
|
175
|
-
Log.info(msg='incomplete ws package for payload: %d' % stream_len)
|
|
175
|
+
Log.info(msg='incomplete ws package for payload: %d, msg len: %d' % (stream_len, msg_len))
|
|
176
176
|
return None, stream
|
|
177
177
|
payload = stream[pos:pos+msg_len]
|
|
178
178
|
pos += msg_len
|
|
@@ -87,7 +87,8 @@ class BaseSession(GateKeeper, Session, ABC):
|
|
|
87
87
|
# Override
|
|
88
88
|
async def queue_message_package(self, msg: ReliableMessage, data: bytes, priority: int = 0) -> bool:
|
|
89
89
|
ship = await self._docker_pack(payload=data, priority=priority)
|
|
90
|
-
|
|
90
|
+
if ship is not None:
|
|
91
|
+
return self._queue_append(msg=msg, ship=ship)
|
|
91
92
|
|
|
92
93
|
#
|
|
93
94
|
# Transmitter
|
|
@@ -217,7 +217,7 @@ class WSDocker(PlainDocker, DeparturePacker):
|
|
|
217
217
|
pass
|
|
218
218
|
|
|
219
219
|
# Override
|
|
220
|
-
def pack(self, payload: bytes, priority: int = 0) -> Departure:
|
|
220
|
+
def pack(self, payload: bytes, priority: int = 0) -> Optional[Departure]:
|
|
221
221
|
req_pack = WebSocket.pack(payload=payload)
|
|
222
222
|
return WSDeparture(package=req_pack, payload=payload, priority=priority)
|
|
223
223
|
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
# ==============================================================================
|
|
25
25
|
|
|
26
|
-
import os
|
|
27
26
|
from typing import Optional, Union
|
|
28
27
|
|
|
29
28
|
from ...utils import template_replace
|
|
30
29
|
from ...utils import Log
|
|
31
|
-
from ...utils import
|
|
30
|
+
from ...utils import Path
|
|
31
|
+
from ...utils import TextFile, JSONFile
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
"""
|
|
@@ -69,7 +69,7 @@ class Storage:
|
|
|
69
69
|
return template
|
|
70
70
|
else:
|
|
71
71
|
# relative path
|
|
72
|
-
return
|
|
72
|
+
return Path.join(self._public, template)
|
|
73
73
|
|
|
74
74
|
def private_path(self, template: str):
|
|
75
75
|
""" replace '{PRIVATE}' with private directory """
|
|
@@ -82,11 +82,7 @@ class Storage:
|
|
|
82
82
|
return template
|
|
83
83
|
else:
|
|
84
84
|
# relative path
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
@classmethod
|
|
88
|
-
def exists(cls, path: str) -> bool:
|
|
89
|
-
return File(path=path).exists(path=path)
|
|
85
|
+
return Path.join(self._public, template)
|
|
90
86
|
|
|
91
87
|
@classmethod
|
|
92
88
|
def read_text(cls, path: str) -> Optional[str]:
|
|
@@ -123,13 +119,6 @@ class Storage:
|
|
|
123
119
|
except Exception as error:
|
|
124
120
|
Log.error(msg='Storage >\t%s' % error)
|
|
125
121
|
|
|
126
|
-
@classmethod
|
|
127
|
-
def remove(cls, path: str) -> bool:
|
|
128
|
-
try:
|
|
129
|
-
return File(path=path).remove()
|
|
130
|
-
except Exception as error:
|
|
131
|
-
Log.error(msg='Storage >\t%s' % error)
|
|
132
|
-
|
|
133
122
|
#
|
|
134
123
|
# Logging
|
|
135
124
|
#
|
|
@@ -380,10 +380,15 @@ def create_messenger(facebook: ClientFacebook, database: MessageDBI,
|
|
|
380
380
|
def create_terminal(messenger: OctopusMessenger) -> Terminal:
|
|
381
381
|
terminal = Terminal(messenger=messenger)
|
|
382
382
|
messenger.terminal = terminal
|
|
383
|
-
|
|
383
|
+
thr = threading.Thread(target=_start_terminal, args=(terminal,))
|
|
384
|
+
thr.start()
|
|
384
385
|
return terminal
|
|
385
386
|
|
|
386
387
|
|
|
388
|
+
def _start_terminal(terminal: Terminal):
|
|
389
|
+
Runner.sync_run(main=terminal.start())
|
|
390
|
+
|
|
391
|
+
|
|
387
392
|
async def update_station(station: Station, database: SessionDBI):
|
|
388
393
|
Log.info(msg='update station: %s' % station)
|
|
389
394
|
# SP ID
|
|
@@ -31,10 +31,10 @@ from typing import Optional, Tuple
|
|
|
31
31
|
from dimsdk import ID, Station
|
|
32
32
|
|
|
33
33
|
from ..utils import Singleton, Config
|
|
34
|
+
from ..utils import Path
|
|
34
35
|
from ..common import AccountDBI, MessageDBI, SessionDBI
|
|
35
36
|
from ..common import ProviderInfo
|
|
36
37
|
from ..database import AccountDatabase, MessageDatabase, SessionDatabase
|
|
37
|
-
from ..database import Storage
|
|
38
38
|
from ..client import ClientSession, ClientFacebook, ClientArchivist
|
|
39
39
|
|
|
40
40
|
|
|
@@ -85,7 +85,7 @@ def create_config(app_name: str, default_config: str) -> Config:
|
|
|
85
85
|
# check config filepath
|
|
86
86
|
if ini_file is None:
|
|
87
87
|
ini_file = default_config
|
|
88
|
-
if not
|
|
88
|
+
if not Path.exists(path=ini_file):
|
|
89
89
|
show_help(cmd=cmd, app_name=app_name, default_config=default_config)
|
|
90
90
|
print('')
|
|
91
91
|
print('!!! config file not exists: %s' % ini_file)
|
|
@@ -37,8 +37,8 @@ path = os.path.dirname(path)
|
|
|
37
37
|
sys.path.insert(0, path)
|
|
38
38
|
|
|
39
39
|
from dimples.utils import Log, Config
|
|
40
|
+
from dimples.utils import Path
|
|
40
41
|
from dimples.utils import Runner
|
|
41
|
-
from dimples.database import Storage
|
|
42
42
|
|
|
43
43
|
from dimples.register.shared import GlobalVariable
|
|
44
44
|
from dimples.register.shared import create_database
|
|
@@ -93,7 +93,7 @@ async def main():
|
|
|
93
93
|
# check config filepath
|
|
94
94
|
if ini_file is None:
|
|
95
95
|
ini_file = DEFAULT_CONFIG
|
|
96
|
-
if not
|
|
96
|
+
if not Path.exists(path=ini_file):
|
|
97
97
|
show_help()
|
|
98
98
|
print('')
|
|
99
99
|
print('!!! config file not exists: %s' % ini_file)
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
|
|
38
38
|
import socket
|
|
39
39
|
import traceback
|
|
40
|
-
import weakref
|
|
41
40
|
from typing import Optional, List, Tuple
|
|
42
41
|
|
|
43
42
|
from dimsdk import ID, EntityType
|
|
@@ -45,7 +44,6 @@ from dimsdk import ReliableMessage
|
|
|
45
44
|
|
|
46
45
|
from startrek import Docker, DockerStatus
|
|
47
46
|
from startrek import Arrival, Departure
|
|
48
|
-
from startrek.net.channel import is_closed
|
|
49
47
|
|
|
50
48
|
from ..utils import Log, Runner
|
|
51
49
|
from ..utils import hex_encode, random_bytes
|
|
@@ -85,7 +83,6 @@ class ServerSession(BaseSession):
|
|
|
85
83
|
|
|
86
84
|
def __init__(self, remote: Tuple[str, int], sock: socket.socket, database: SessionDBI):
|
|
87
85
|
super().__init__(remote=remote, sock=sock, database=database)
|
|
88
|
-
self.__sock = weakref.ref(sock)
|
|
89
86
|
self.__key = generate_session_key()
|
|
90
87
|
|
|
91
88
|
@property
|
|
@@ -109,15 +106,6 @@ class ServerSession(BaseSession):
|
|
|
109
106
|
Runner.async_run(coroutine=load_cached_messages(session=self))
|
|
110
107
|
return True
|
|
111
108
|
|
|
112
|
-
@property # Override
|
|
113
|
-
def running(self) -> bool:
|
|
114
|
-
if super().running:
|
|
115
|
-
# gate = self.gate
|
|
116
|
-
# conn = gate.get_channel(remote=self.remote_address, local=None)
|
|
117
|
-
# return not (conn is None or conn.closed)
|
|
118
|
-
sock = self.__sock()
|
|
119
|
-
return not (sock is None or is_closed(sock=sock))
|
|
120
|
-
|
|
121
109
|
# Override
|
|
122
110
|
async def start(self):
|
|
123
111
|
await super().start()
|
|
@@ -31,12 +31,12 @@ from typing import Optional, Tuple
|
|
|
31
31
|
from dimsdk import ID
|
|
32
32
|
|
|
33
33
|
from ..utils import Singleton, Config
|
|
34
|
+
from ..utils import Path
|
|
34
35
|
from ..common import AddressNameServer, ANSFactory
|
|
35
36
|
from ..common import CommonFacebook, CommonMessenger
|
|
36
37
|
from ..common import AccountDBI, MessageDBI, SessionDBI
|
|
37
38
|
from ..common import ProviderInfo
|
|
38
39
|
from ..database import AccountDatabase, MessageDatabase, SessionDatabase
|
|
39
|
-
from ..database import Storage
|
|
40
40
|
from ..server import ServerArchivist
|
|
41
41
|
from ..server import ServerSession
|
|
42
42
|
from ..server import ServerMessenger
|
|
@@ -93,7 +93,7 @@ def create_config(app_name: str, default_config: str) -> Config:
|
|
|
93
93
|
# check config filepath
|
|
94
94
|
if ini_file is None:
|
|
95
95
|
ini_file = default_config
|
|
96
|
-
if not
|
|
96
|
+
if not Path.exists(path=ini_file):
|
|
97
97
|
show_help(cmd=cmd, app_name=app_name, default_config=default_config)
|
|
98
98
|
print('')
|
|
99
99
|
print('!!! config file not exists: %s' % ini_file)
|
|
@@ -50,12 +50,12 @@ from dimsdk import DocumentHelper
|
|
|
50
50
|
|
|
51
51
|
from dimplugins.crypto.aes import random_bytes
|
|
52
52
|
|
|
53
|
+
from startrek.fsm import Singleton
|
|
53
54
|
from startrek.fsm import Runnable, Runner, Daemon, DaemonRunner
|
|
54
55
|
from startrek.fsm import Delegate as StateDelegate
|
|
55
56
|
from startrek.net.channel import get_remote_address, get_local_address
|
|
56
57
|
|
|
57
58
|
|
|
58
|
-
from .singleton import Singleton
|
|
59
59
|
from .log import Log, Logging
|
|
60
60
|
from .dos import Path, File, TextFile, JSONFile
|
|
61
61
|
from .cache import CachePool, CacheHolder, CacheManager
|
|
@@ -31,11 +31,10 @@
|
|
|
31
31
|
|
|
32
32
|
from typing import TypeVar, Generic, Optional, Dict, Set, Tuple
|
|
33
33
|
|
|
34
|
+
from startrek.fsm import Singleton
|
|
34
35
|
from startrek.fsm import Runnable, Runner, Daemon
|
|
35
36
|
from dimsdk import DateTime
|
|
36
37
|
|
|
37
|
-
from .singleton import Singleton
|
|
38
|
-
|
|
39
38
|
|
|
40
39
|
K = TypeVar('K')
|
|
41
40
|
V = TypeVar('V')
|