Skip to content

Commit 8668f22

Browse files
committed
feat: Add the basic functions
0 parents  commit 8668f22

12 files changed

Lines changed: 1270 additions & 0 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.venv
2+
.idea
3+
cli.py

src/StealthIM/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import logging
2+
3+
logger = logging.getLogger(__name__)
4+
console_handler = logging.StreamHandler()
5+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
6+
7+
logger.setLevel(logging.DEBUG)
8+
console_handler.setLevel(logging.DEBUG)
9+
console_handler.setFormatter(formatter)
10+
logger.addHandler(console_handler)
11+
12+
from . import apis
13+
14+
from .user import User
15+
from .server import Server

src/StealthIM/apis/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import common
2+
from . import user
3+
from . import util

src/StealthIM/apis/common.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import dataclasses
2+
from typing import Any
3+
4+
import aiohttp
5+
6+
7+
@dataclasses.dataclass
8+
class Result:
9+
code: int
10+
msg: str
11+
12+
@dataclasses.dataclass
13+
class NoValResult:
14+
result: Result
15+
16+
17+
async def request(
18+
url: str,
19+
method: str,
20+
data: dict = None,
21+
body: dict = None,
22+
headers: dict = None,
23+
retry: int = 3
24+
) -> dict[str, Any]:
25+
"""
26+
Make a request to the server.
27+
28+
Args:
29+
url (str): The URL of the server.
30+
method (str): The HTTP method to use (default is "GET").
31+
data (dict): The data to send in the request (default is None).
32+
body (dict): The body of the request (default is None).
33+
headers (dict): The headers to include in the request (default is None).
34+
retry (int): The number of times to retry the request in case of failure (default is 3).
35+
36+
Returns:
37+
dict[str, Any]: The response data from the server.
38+
Raises:
39+
RuntimeError: If the server returns an internal error too many times.
40+
"""
41+
current_retry = 0
42+
while True:
43+
async with aiohttp.ClientSession() as session:
44+
async with session.request(method, url, data=data, headers=headers, json=body) as response:
45+
if response.status != 200:
46+
raise RuntimeError(f"Request failed with status: {response.status}")
47+
response_data = await response.json()
48+
49+
if 900 <= response_data["result"]["code"] <= 999:
50+
current_retry += 1
51+
continue
52+
53+
return response_data
54+
raise RuntimeError(f"Request failed with code: {response_data['result']['code']}")

src/StealthIM/apis/group.py

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
import dataclasses
2+
import enum
3+
4+
from .common import request, Result, NoValResult
5+
from .. import logger
6+
7+
8+
@dataclasses.dataclass
9+
class GetGroupsResult:
10+
groups: list[int]
11+
result: Result
12+
13+
class GroupMemberType(enum.Enum):
14+
Member = 0
15+
Manager = 1
16+
Owner = 2
17+
18+
@dataclasses.dataclass
19+
class GroupMember:
20+
name: str
21+
type: GroupMemberType
22+
23+
@dataclasses.dataclass
24+
class GroupInfoResult:
25+
members: list[GroupMember]
26+
result: Result
27+
28+
@dataclasses.dataclass
29+
class GroupPublicInfoResult:
30+
create_at: str
31+
name: str
32+
result: Result
33+
34+
@dataclasses.dataclass
35+
class CreateGroupResult:
36+
groupid: int
37+
result: Result
38+
39+
JoinGroupResult = NoValResult
40+
InviteGroupResult = NoValResult
41+
SetMemberRoleResult = NoValResult
42+
KickMemberResult = NoValResult
43+
ChangeGroupNameResult = NoValResult
44+
ChangeGroupPasswordResult = NoValResult
45+
46+
47+
async def get_groups(
48+
url: str,
49+
session: str,
50+
) -> GetGroupsResult:
51+
api_address = f"{url}/api/v1/group/"
52+
logger.debug(f"Called API get_groups with url: {api_address}")
53+
header = {
54+
"Authorization": f"Bearer {session}"
55+
}
56+
57+
response_data = await request(api_address, "GET", headers=header)
58+
logger.debug(f"Response data: {response_data}")
59+
60+
return GetGroupsResult(
61+
groups=response_data["groups"],
62+
result=Result(
63+
code=response_data["result"]["code"],
64+
msg=response_data["result"]["msg"]
65+
)
66+
)
67+
68+
async def get_group_info(
69+
url: str,
70+
session: str,
71+
groupid: int,
72+
):
73+
api_address = f"{url}/api/v1/group/{groupid}"
74+
logger.debug(f"Called API get_group_info with url: {api_address}")
75+
header = {
76+
"Authorization": f"Bearer {session}"
77+
}
78+
79+
response_data = await request(api_address, "GET", headers=header)
80+
logger.debug(f"Response data: {response_data}")
81+
82+
return GroupInfoResult(
83+
members=[
84+
GroupMember(
85+
name=member["name"],
86+
type=GroupMemberType(member.get("type", 0)),
87+
) for member in response_data["members"]
88+
],
89+
result=Result(
90+
code=response_data["result"]["code"],
91+
msg=response_data["result"]["msg"]
92+
)
93+
)
94+
95+
async def get_group_public_info(
96+
url: str,
97+
session: str,
98+
groupid: int,
99+
) -> GroupPublicInfoResult:
100+
api_address = f"{url}/api/v1/group/{groupid}/public"
101+
logger.debug(f"Called API get_group_public_info with url: {api_address}")
102+
header = {
103+
"Authorization": f"Bearer {session}"
104+
}
105+
106+
response_data = await request(api_address, "GET", headers=header)
107+
logger.debug(f"Response data: {response_data}")
108+
109+
return GroupPublicInfoResult(
110+
create_at=response_data["create_at"],
111+
name=response_data["name"],
112+
result=Result(
113+
code=response_data["result"]["code"],
114+
msg=response_data["result"]["msg"]
115+
)
116+
)
117+
118+
async def create_group(
119+
url: str,
120+
session: str,
121+
group_name: str,
122+
) -> CreateGroupResult:
123+
api_address = f"{url}/api/v1/group"
124+
logger.debug(f"Called API create_group with url: {api_address}")
125+
header = {
126+
"Authorization": f"Bearer {session}"
127+
}
128+
body = {
129+
"name": group_name,
130+
}
131+
132+
response_data = await request(api_address, "POST", headers=header, body=body)
133+
logger.debug(f"Response data: {response_data}")
134+
135+
return CreateGroupResult(
136+
groupid=response_data["groupid"],
137+
result=Result(
138+
code=response_data["result"]["code"],
139+
msg=response_data["result"]["msg"]
140+
)
141+
)
142+
143+
async def join_group(
144+
url: str,
145+
session: str,
146+
groupid: int,
147+
password: str,
148+
) -> JoinGroupResult:
149+
api_address = f"{url}/api/v1/group/{groupid}/join"
150+
logger.debug(f"Called API join_group with url: {api_address}")
151+
header = {
152+
"Authorization": f"Bearer {session}"
153+
}
154+
body = {
155+
"password": password,
156+
}
157+
158+
response_data = await request(api_address, "POST", headers=header, body=body)
159+
logger.debug(f"Response data: {response_data}")
160+
161+
return JoinGroupResult(
162+
result=Result(
163+
code=response_data["result"]["code"],
164+
msg=response_data["result"]["msg"]
165+
)
166+
)
167+
168+
async def invite_group(
169+
url: str,
170+
session: str,
171+
groupid: int,
172+
username: str,
173+
) -> InviteGroupResult:
174+
api_address = f"{url}/api/v1/group/{groupid}/invite"
175+
logger.debug(f"Called API invite_group with url: {api_address}")
176+
header = {
177+
"Authorization": f"Bearer {session}"
178+
}
179+
body = {
180+
"username": username,
181+
}
182+
183+
response_data = await request(api_address, "POST", headers=header, body=body)
184+
logger.debug(f"Response data: {response_data}")
185+
186+
return InviteGroupResult(
187+
result=Result(
188+
code=response_data["result"]["code"],
189+
msg=response_data["result"]["msg"]
190+
)
191+
)
192+
193+
async def set_user_role(
194+
url: str,
195+
session: str,
196+
groupid: int,
197+
username: str,
198+
user_type: GroupMemberType,
199+
) -> SetMemberRoleResult:
200+
api_address = f"{url}/api/v1/group/{groupid}/{username}"
201+
logger.debug(f"Called API set_user_type with url: {api_address}")
202+
header = {
203+
"Authorization": f"Bearer {session}"
204+
}
205+
body = {
206+
"type": user_type.value,
207+
}
208+
209+
response_data = await request(api_address, "PUT", headers=header, body=body)
210+
logger.debug(f"Response data: {response_data}")
211+
212+
return SetMemberRoleResult(
213+
result=Result(
214+
code=response_data["result"]["code"],
215+
msg=response_data["result"]["msg"]
216+
)
217+
)
218+
219+
async def kick_user(
220+
url: str,
221+
session: str,
222+
groupid: int,
223+
username: str,
224+
) -> KickMemberResult:
225+
api_address = f"{url}/api/v1/group/{groupid}/{username}"
226+
logger.debug(f"Called API kick_user with url: {api_address}")
227+
header = {
228+
"Authorization": f"Bearer {session}"
229+
}
230+
231+
response_data = await request(api_address, "DELETE", headers=header)
232+
logger.debug(f"Response data: {response_data}")
233+
234+
return KickMemberResult(
235+
result=Result(
236+
code=response_data["result"]["code"],
237+
msg=response_data["result"]["msg"]
238+
)
239+
)
240+
241+
async def change_group_name(
242+
url: str,
243+
session: str,
244+
groupid: int,
245+
name: str,
246+
) -> ChangeGroupNameResult:
247+
api_address = f"{url}/api/v1/group/{groupid}/name"
248+
logger.debug(f"Called API change_group_name with url: {api_address}")
249+
header = {
250+
"Authorization": f"Bearer {session}"
251+
}
252+
body = {
253+
"name": name,
254+
}
255+
256+
response_data = await request(api_address, "PATCH", headers=header, body=body)
257+
logger.debug(f"Response data: {response_data}")
258+
259+
return ChangeGroupNameResult(
260+
result=Result(
261+
code=response_data["result"]["code"],
262+
msg=response_data["result"]["msg"]
263+
)
264+
)
265+
266+
async def change_group_password(
267+
url: str,
268+
session: str,
269+
groupid: int,
270+
password: str,
271+
) -> ChangeGroupPasswordResult:
272+
api_address = f"{url}/api/v1/group/{groupid}/password"
273+
logger.debug(f"Called API change_group_password with url: {api_address}")
274+
header = {
275+
"Authorization": f"Bearer {session}"
276+
}
277+
body = {
278+
"password": password,
279+
}
280+
281+
response_data = await request(api_address, "PATCH", headers=header, body=body)
282+
logger.debug(f"Response data: {response_data}")
283+
284+
return ChangeGroupPasswordResult(
285+
result=Result(
286+
code=response_data["result"]["code"],
287+
msg=response_data["result"]["msg"]
288+
)
289+
)

0 commit comments

Comments
 (0)