-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbasemodule.py
193 lines (126 loc) · 4.07 KB
/
basemodule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# Copyright (c) 2023 SiumLhahah
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""
ilafalseone.basemodule
Abstract ilafalseone module.
"""
import sqlite3
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Iterable
from .session import Session
from .ilfocore.constants import Key
if TYPE_CHECKING:
from .account import Account
T = None
class Module(ABC):
"""Base module."""
def __init__(self):
"""Init the module.
May be overriden.
"""
self._account: 'Account' = None
def start(self):
"""Called when local account has been initialized and starts.
May be overriden.
"""
def connect(self):
"""Account online.
May be overriden.
"""
def setup_session(self, con: Session):
"""Called by session.Session.setup_common(con).
May be overriden.
"""
# def init(self, con: Session, buf: BufferedReader) -> bool:
# """Handle port setting, return False if not accepted.
# May be overriden.
# """
# return True
def acknowledged(self, con: Session, seq: int):
"""Received ACK message from target.
May be overriden.
"""
def finish_session(self, con: Session):
"""Called when the session is about to finish.
May be overriden.
"""
def close_session(self, con: Session):
"""Called when the session is about to finish.
May be overriden.
"""
def disconnect(self):
"""Called when account offline.
May be overriden.
"""
def stop(self):
"""Stop the threads, called by close().
May be overriden.
"""
def close(self):
"""Close.
May be overriden.
"""
self.stop()
def sendto(self, data: bytes | Iterable[bytes], target: Session | Key
) -> int | dict[Session, int]:
"""Send a module package or a list of module packages.
Return the sequence number of the last module
packet sent, or the sequence numbers of the last
module packets sent in different sessions.
"""
if isinstance(target, Session):
seq = target.send(data)
target.seqs_to_ack.append((seq, self))
return seq
if isinstance(target, Key):
seqs = self._account.node.sendto(data, target)
for con, seq in seqs.items():
con.seqs_to_ack.append((seq, self))
return seqs
raise TypeError
@property
def account(self) -> 'Account':
"""Return the local account."""
return self._account
@account.setter
def account(self, account: 'Account'):
"""Set the local account."""
self._account = account
@classmethod
@property
@abstractmethod
def name(cls) -> str:
"""Module name."""
def __repr__(self) -> str:
return f"module {self.name}"
class Bound[T: Module](ABC):
"""Object binding a module."""
__slots__ = ()
@property
@abstractmethod
def module(self) -> T:
"""The Module which object binding to."""
class DataBased(Module):
"""Module with a database connection."""
def __init__(self):
super().__init__()
self._sql_conn: sqlite3.Connection = None
def load_data(self, conn: sqlite3.Connection):
"""Load data from database."""
self._sql_conn = conn
def start(self):
"""Start the module thread after local account has been initialized.
Call load_data() if module has not connect to the database.
May be overriden.
"""
if self._sql_conn is None:
raise ValueError("Database not loaded")
def close(self):
"""Close the module and the DB connection."""
super().close()
self._sql_conn.close()
@property
def sql_conn(self) -> sqlite3.Connection:
"""Return SQLite database connection."""
return self._sql_conn