vprikol 0.1.0__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.
vprikol-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,16 @@
1
+ Metadata-Version: 2.1
2
+ Name: vprikol
3
+ Version: 0.1.0
4
+ Summary:
5
+ Author: evans
6
+ Author-email: szx@bk.ru
7
+ Requires-Python: >=3.10,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Requires-Dist: aiohttp (>=3.9.5,<4.0.0)
13
+ Requires-Dist: pydantic (>=2.7.4,<3.0.0)
14
+ Description-Content-Type: text/markdown
15
+
16
+
File without changes
@@ -0,0 +1,17 @@
1
+ [tool.poetry]
2
+ name = "vprikol"
3
+ version = "0.1.0"
4
+ description = ""
5
+ authors = ["evans <szx@bk.ru>"]
6
+ readme = "README.md"
7
+ packages = [{include = "vprikol"}]
8
+
9
+ [tool.poetry.dependencies]
10
+ python = "^3.10"
11
+ pydantic = "^2.7.4"
12
+ aiohttp = "^3.9.5"
13
+
14
+
15
+ [build-system]
16
+ requires = ["poetry-core"]
17
+ build-backend = "poetry.core.masonry.api"
@@ -0,0 +1,3 @@
1
+ from .main import VprikolAPI
2
+
3
+ __all__ = VprikolAPI
@@ -0,0 +1,32 @@
1
+ from typing import Optional, Dict
2
+
3
+ import aiohttp
4
+
5
+ from .model import Response
6
+
7
+
8
+ async def get_json(url: str, params: Optional[Dict] = None, headers: Optional[Dict] = None) -> Response:
9
+ async with aiohttp.ClientSession(headers=headers) as session:
10
+ async with session.get(url, params=params) as response:
11
+ response_json = await response.json()
12
+ if response.ok:
13
+ return Response(data=response_json)
14
+ return Response(error=response_json, success=False)
15
+
16
+
17
+ async def post_json(url: str, params: Optional[Dict] = None, headers: Optional[Dict] = None) -> Response:
18
+ async with aiohttp.ClientSession(headers=headers) as session:
19
+ async with session.post(url, params=params) as response:
20
+ response_json = await response.json()
21
+ if response.ok:
22
+ return Response(data=response_json)
23
+ return Response(error=response_json, success=False)
24
+
25
+
26
+ async def get_bytes(url: str, params: Optional[Dict] = None, headers: Optional[Dict] = None) -> Response:
27
+ async with aiohttp.ClientSession(headers=headers) as session:
28
+ async with session.get(url, params=params) as response:
29
+ response_data = await response.read()
30
+ if response.status == 200:
31
+ return Response(data=response_data)
32
+ return Response(error=(await response.json()), success=False)
@@ -0,0 +1,161 @@
1
+ import asyncio
2
+ import time
3
+ from typing import List, Literal, Optional, Union, Dict
4
+
5
+ from pydantic import parse_obj_as, ValidationError
6
+
7
+ from .api import get_json, post_json, get_bytes
8
+ from .model import (IpAPIResponse, MembersAPIResponse, PlayerInfoAPIResponse, CreatedFindTaskAPIResponse,
9
+ ServerStatusAPIResponse, RatingAPIResponse, CheckRPUsernameAPIResponse, GenerateRPUsernameAPIResponse,
10
+ PlayerInfoNotFound, PlayerOnlineAPIResponse, GhettoZonesAPIResponse, PlayerEstateAPIResponse, PlayersAPIResponse)
11
+
12
+ Gender = Literal['male', 'female']
13
+ Nation = Literal['russian', 'american', 'german', 'french', 'italian', 'japanese', 'latinos', 'swedish', 'danish', 'romanian']
14
+
15
+
16
+ class VprikolAPI:
17
+ def __init__(self, token: str, base_url: str = 'https://api.szx.su/'):
18
+ if not token.startswith('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.'):
19
+ raise Exception('Токен передан неправильно.')
20
+ self.headers = {'Authorization': f'Bearer {token}'}
21
+ self.base_url = base_url
22
+
23
+ async def get_ip_info(self, ip: str) -> IpAPIResponse:
24
+ result = await get_json(url=f'{self.base_url}ip', headers=self.headers, params={'ip': ip})
25
+
26
+ if not result.success:
27
+ raise Exception(result.error)
28
+
29
+ return IpAPIResponse(**result.data)
30
+
31
+ async def get_members(self, server_id: int, fraction_id: Union[int, List[int]]) -> Dict[str, MembersAPIResponse]:
32
+ result = await get_json(url=f'{self.base_url}members', headers=self.headers, params={'server_id': server_id, 'fraction_id': fraction_id})
33
+
34
+ if not result.success:
35
+ raise Exception(result.error)
36
+
37
+ response = {}
38
+ for fraction_id in result.data:
39
+ players = []
40
+ if not fraction_id.isdigit():
41
+ continue
42
+ for player in result.data[fraction_id]['players']:
43
+ players.append({'username': player, 'id': result.data[fraction_id]['players'][player]['id'],
44
+ 'isOnline': result.data[fraction_id]['players'][player]['isOnline'],
45
+ 'isLeader': result.data[fraction_id]['players'][player]['isLeader'],
46
+ 'rank': result.data[fraction_id]['players'][player]['rank'],
47
+ 'rankLabel': result.data[fraction_id]['players'][player]['rankLabel'],
48
+ 'ingameId': result.data[fraction_id]['players'][player]['ingameId'],
49
+ 'lvl': result.data[fraction_id]['players'][player]['lvl'],
50
+ 'ping': result.data[fraction_id]['players'][player]['ping'],
51
+ 'color': result.data[fraction_id]['players'][player]['color']
52
+ }
53
+ )
54
+ result.data[fraction_id]['players'] = players
55
+ response[fraction_id] = MembersAPIResponse(
56
+ **result.data[fraction_id]
57
+ )
58
+
59
+ return response
60
+
61
+ async def get_player_information(self, server_id: int, nickname: str) -> Union[PlayerInfoAPIResponse, PlayerInfoNotFound]:
62
+ task = await post_json(url=f'{self.base_url}find/createTask', headers=self.headers, params={'server': server_id, 'nick': nickname})
63
+
64
+ if not task.success:
65
+ raise Exception(task.error)
66
+
67
+ task = CreatedFindTaskAPIResponse(**task.data)
68
+ while True:
69
+ result = await get_json(url=f'{self.base_url}find/getTaskResult', headers=self.headers, params={'request_id': task.request_id})
70
+
71
+ if not result.success and result.error.error_code and result.error.error_code == 425:
72
+ await asyncio.sleep(0.5)
73
+ continue
74
+
75
+ if result.error and result.error.error_code == 422:
76
+ return PlayerInfoNotFound(**result.error.dict())
77
+
78
+ if result.error and result.error.error_code in [500, 502, 503]:
79
+ raise Exception(result.error.detail)
80
+
81
+ try:
82
+ return PlayerInfoAPIResponse(**result.data)
83
+ except ValidationError:
84
+ return PlayerInfoAPIResponse(**result.data)
85
+
86
+ async def get_server_status(self, server_id: Optional[int] = None) -> Union[List[ServerStatusAPIResponse], ServerStatusAPIResponse]:
87
+ params = {'server': server_id} if server_id else None
88
+
89
+ result = await get_json(url=f'{self.base_url}status', headers=self.headers, params=params)
90
+
91
+ if not result.success:
92
+ raise Exception(result.error)
93
+
94
+ if isinstance(result.data, list):
95
+ return parse_obj_as(List[ServerStatusAPIResponse], result.data)
96
+
97
+ return ServerStatusAPIResponse(**result.data)
98
+
99
+ async def get_rating(self, server_id: int, rating_type: Literal[1, 2, 3]) -> RatingAPIResponse:
100
+ result = await get_json(url=f'{self.base_url}rating', headers=self.headers, params={'type': rating_type, 'server': server_id})
101
+
102
+ if not result.success:
103
+ raise Exception(result.error)
104
+
105
+ return RatingAPIResponse(**result.data)
106
+
107
+ async def check_rp_nickname(self, nickname: str, ai: bool = False) -> CheckRPUsernameAPIResponse:
108
+ result = await get_json(url=f'{self.base_url}checkrp', headers=self.headers, params={'nick': nickname, 'ai': int(ai)})
109
+
110
+ if not result.success:
111
+ raise Exception(result.error)
112
+
113
+ return CheckRPUsernameAPIResponse(**result.data)
114
+
115
+ async def generate_rp_nickname(self, gender: Gender, nation: Nation) -> GenerateRPUsernameAPIResponse:
116
+ result = await get_json(url=f'{self.base_url}rpnick', headers=self.headers, params={'gender': gender, 'nation': nation})
117
+
118
+ if not result.success:
119
+ raise Exception(result.error)
120
+
121
+ return GenerateRPUsernameAPIResponse(**result.data)
122
+
123
+ async def get_player_online(self, nickname: str, server_id: int, count: int = 100, offset: int = 0, date: int = int(time.time())) -> PlayerOnlineAPIResponse:
124
+ result = await get_json(url=f'{self.base_url}online', headers=self.headers, params={'nickname': nickname, 'count': count, 'offset': offset, 'server_id': server_id, 'filter_by_date': date})
125
+
126
+ if not result.success:
127
+ raise Exception(result.error)
128
+
129
+ return PlayerOnlineAPIResponse(**result.data)
130
+
131
+ async def get_ghetto_map(self, server_id: int) -> bytes:
132
+ result = await get_bytes(url=f'{self.base_url}ghetto/map', headers=self.headers, params={'server_id': server_id})
133
+
134
+ if not result.success:
135
+ raise Exception(result.error)
136
+
137
+ return result.data
138
+
139
+ async def get_ghetto_zones(self, server_id: int) -> GhettoZonesAPIResponse:
140
+ result = await get_json(url=f'{self.base_url}ghetto/zones', headers=self.headers, params={'server_id': server_id})
141
+
142
+ if not result.success:
143
+ raise Exception(result.error)
144
+
145
+ return GhettoZonesAPIResponse(**result.data)
146
+
147
+ async def get_estate(self, nickname: str, server_id: int) -> PlayerEstateAPIResponse:
148
+ result = await get_json(url=f'{self.base_url}estate', headers=self.headers, params={'server_id': server_id, 'nickname': nickname})
149
+
150
+ if not result.success:
151
+ raise Exception(result.error)
152
+
153
+ return PlayerEstateAPIResponse(**result.data)
154
+
155
+ async def get_players(self, server_id: int, nicknames: Optional[List[Union[str, int]]] = None) -> PlayersAPIResponse:
156
+ result = await get_json(url=f'{self.base_url}players?nicknames={nicknames}', headers=self.headers, params={'server_id': server_id})
157
+
158
+ if not result.success:
159
+ raise Exception(result.error)
160
+
161
+ return PlayersAPIResponse(**result.data)
@@ -0,0 +1,206 @@
1
+ from typing import TypeVar, List, Optional, Dict, Generic, Union
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ DataT = TypeVar('DataT')
6
+
7
+
8
+ class FastAPIErrorDetail(BaseModel):
9
+ loc: List[str]
10
+ message: str = Field(alias='msg')
11
+ type: str
12
+
13
+
14
+ class FastApiErrorResponse(BaseModel):
15
+ detail: Union[list[FastAPIErrorDetail] , str]
16
+
17
+
18
+ class APIErrorResponse(BaseModel):
19
+ error_code: int
20
+ detail: str
21
+ queue_position: Optional[int] = None
22
+
23
+
24
+ class Response(BaseModel, Generic[DataT]):
25
+ data: Optional[DataT] = None
26
+ error: Optional[Union[FastApiErrorResponse, APIErrorResponse]] = None
27
+ success: bool = True
28
+
29
+
30
+ class MembersAPIPlayer(BaseModel):
31
+ username: str
32
+ id: Optional[int] = None
33
+ is_online: bool = Field(alias='isOnline')
34
+ is_leader: bool = Field(alias='isLeader')
35
+ rank: int
36
+ rank_label: Optional[str] = Field(None, alias='rankLabel')
37
+ ingame_id: Optional[int] = Field(None, alias='ingameId')
38
+ ping: Optional[int]
39
+ lvl: Optional[int]
40
+ color: Optional[int]
41
+
42
+
43
+ class MembersAPIRecord(BaseModel):
44
+ count: int
45
+ date: str
46
+ leader: str
47
+
48
+
49
+ class MembersAPIResponse(BaseModel):
50
+ server_label: str = Field(alias='serverName')
51
+ fraction_label: str = Field(alias='fractionLabel')
52
+ players: List[MembersAPIPlayer]
53
+ record: MembersAPIRecord
54
+ total_players: int = Field(alias='totalPlayers')
55
+ total_online: int = Field(alias='totalOnline')
56
+ leader_nickname: Optional[str] = Field(None, alias='leaderNick')
57
+ is_leader_online: bool = Field(alias='isLeaderOnline')
58
+ online_updated_at: int = Field(alias='onlineUpdatedAt')
59
+ members_updated_at: int = Field(alias='membersUpdatedAt')
60
+
61
+
62
+ class ServerStatusAPIResponse(BaseModel):
63
+ server_number: int = Field(alias='number')
64
+ ip: str
65
+ port: int
66
+ online_players: int = Field(alias='onlinePlayers')
67
+ max_players: int = Field(alias='maxPlayers')
68
+ is_closed: bool = Field(alias='isClosed')
69
+ server_label: str = Field(alias='serverLabel')
70
+
71
+
72
+ class CreatedFindTaskAPIResponse(BaseModel):
73
+ request_id: str
74
+ request_time: int
75
+ queue_position: int
76
+
77
+
78
+ class PlayerInfoAPIResponse(BaseModel):
79
+ account_id: Optional[int] = Field(None, alias='accountId')
80
+ player_id: Optional[int] = Field(None, alias='playerId')
81
+ lvl: Optional[int] = None
82
+ cash: Optional[int] = None
83
+ bank: Optional[int] = None
84
+ individual_account: Optional[int] = Field(None, alias='individualAccount')
85
+ deposit: Optional[int] = None
86
+ total_money: Optional[int] = Field(None, alias='totalMoney')
87
+ is_online: bool = Field(False, alias='isOnline')
88
+ job_label: Optional[str] = Field(None, alias='jobLabel')
89
+ job_id: Optional[int] = Field(None, alias='jobId')
90
+ rank_number: Optional[int] = Field(None, alias='rankNumber')
91
+ rank_label: Optional[str] = Field(None, alias='rankLabel')
92
+ is_leader: bool = Field(False, alias='isLeader')
93
+ org_label: str = Field('', alias='orgLabel')
94
+ org_id: int = Field(0, alias='orgId')
95
+ vip_lvl: Optional[int] = Field(None, alias='vipLvl')
96
+ vip_label: Optional[str] = Field(None, alias='vipLabel')
97
+ phone_number: Optional[int] = Field(None, alias='phoneNumber')
98
+ updated_at: int = Field(0, alias='updatedAt')
99
+ player_nick: str = Field('', alias='playerNick')
100
+ player_server: int = Field(0, alias='playerServer')
101
+ server_name: str = Field('', alias='serverName')
102
+
103
+
104
+ class PlayerInfoNotFound(APIErrorResponse):
105
+ pass
106
+
107
+
108
+ class RatingPlayerInfo(BaseModel):
109
+ number: int
110
+ name: str
111
+ is_online: bool = Field('isOnline')
112
+
113
+
114
+ class RatingAPIResponse(BaseModel):
115
+ server: str
116
+ players: List[RatingPlayerInfo]
117
+
118
+
119
+ class IpAPIResponse(BaseModel):
120
+ ip: str
121
+ country: str
122
+ city: str
123
+ timezone: str
124
+ isp: str
125
+
126
+
127
+ class CheckRPUsernameName(BaseModel):
128
+ rp: bool
129
+ graph: Optional[str] = None
130
+ gpt_answer: Optional[str] = None
131
+
132
+
133
+ class CheckRPUsernameAPIResponse(BaseModel):
134
+ name: CheckRPUsernameName
135
+ surname: CheckRPUsernameName
136
+ nickname: str = Field(alias='nick')
137
+
138
+
139
+ class GhettoZonesData(BaseModel):
140
+ grove: int = Field(alias='2569507584')
141
+ ballas: int = Field(alias='2580283596')
142
+ vagos: int = Field(alias='2568805329')
143
+ rifa: int = Field(alias='2583651942')
144
+ aztec: int = Field(alias='2581790464')
145
+ nw: int = Field(alias='2155378856')
146
+
147
+
148
+ class GhettoZonesAPIResponse(BaseModel):
149
+ data: GhettoZonesData
150
+ server_name: str = Field(alias='serverName')
151
+ updated_at: int = Field(alias='updatedAt')
152
+
153
+
154
+ class AuctionInfo(BaseModel):
155
+ active: bool
156
+ minimal_bet: int = Field("minimalBet")
157
+ time_end: int = Field(alias='timeEnd')
158
+ start_price: int = Field(alias='startPrice')
159
+
160
+
161
+ class Coordinates(BaseModel):
162
+ x: float
163
+ y: float
164
+
165
+
166
+ class EstateItem(BaseModel):
167
+ id: int
168
+ name: Optional[str]
169
+ owner: Optional[str]
170
+ auction: AuctionInfo
171
+ coordinates: Coordinates
172
+
173
+
174
+ class PlayerEstateAPIResponse(BaseModel):
175
+ server_id: int = Field(alias='serverId')
176
+ server_label: str = Field(alias='serverLabel')
177
+ nickname: str = Field(alias='nickname')
178
+ houses: List[EstateItem]
179
+ businesses: List[EstateItem]
180
+
181
+
182
+ class GenerateRPUsernameAPIResponse(BaseModel):
183
+ name: str
184
+ surname: str
185
+
186
+
187
+ class OnlinePlayerInfo(BaseModel):
188
+ login_at: int
189
+ logout_at: int
190
+
191
+
192
+ class PlayerOnlineAPIResponse(BaseModel):
193
+ sessions: List[OnlinePlayerInfo]
194
+
195
+
196
+ class PlayerData(BaseModel):
197
+ ingame_id: Optional[int] = Field(None, alias='ingameId')
198
+ lvl: Optional[int] = None
199
+ ping: Optional[int] = None
200
+ color: Optional[int] = None
201
+
202
+
203
+ class PlayersAPIResponse(BaseModel):
204
+ server_name: str = Field(alias='serverName')
205
+ updated_at: int = Field(alias='updatedAt')
206
+ data: Dict[str, Optional[PlayerData]]