ddapi 0.1.0__tar.gz → 0.1.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.
- {ddapi-0.1.0 → ddapi-0.1.2}/PKG-INFO +1 -2
- ddapi-0.1.2/ddapi/ddapi/DDnetApiPy/main.py +61 -0
- ddapi-0.1.2/ddapi/ddapi/__init__.py +6 -0
- ddapi-0.1.2/ddapi/ddapi/dataclass.py +251 -0
- ddapi-0.1.2/ddapi/ddapi/errors.py +2 -0
- ddapi-0.1.2/ddapi/ddapi/misc.py +26 -0
- {ddapi-0.1.0 → ddapi-0.1.2/ddapi}/ddapi/qwikDDnetApiPy/main.py +15 -6
- {ddapi-0.1.0 → ddapi-0.1.2}/ddapi/ddapi.egg-info/PKG-INFO +1 -2
- ddapi-0.1.2/ddapi/ddapi.egg-info/SOURCES.txt +18 -0
- {ddapi-0.1.0 → ddapi-0.1.2}/ddapi/ddapi.egg-info/requires.txt +0 -1
- ddapi-0.1.2/ddapi/ddapi.egg-info/top_level.txt +1 -0
- {ddapi-0.1.0 → ddapi-0.1.2}/pyproject.toml +2 -3
- {ddapi-0.1.0 → ddapi-0.1.2}/setup.cfg +1 -1
- {ddapi-0.1.0 → ddapi-0.1.2}/setup.py +1 -1
- ddapi-0.1.0/ddapi/DDnetApiPy/main.py +0 -48
- ddapi-0.1.0/ddapi/ddapi.egg-info/SOURCES.txt +0 -14
- ddapi-0.1.0/ddapi/ddapi.egg-info/top_level.txt +0 -2
- {ddapi-0.1.0 → ddapi-0.1.2}/LICENSE +0 -0
- {ddapi-0.1.0 → ddapi-0.1.2}/README.md +0 -0
- {ddapi-0.1.0 → ddapi-0.1.2/ddapi}/ddapi/DDnetApiPy/__init__.py +0 -0
- {ddapi-0.1.0 → ddapi-0.1.2/ddapi}/ddapi/qwikDDnetApiPy/__init__.py +0 -0
- {ddapi-0.1.0 → ddapi-0.1.2}/ddapi/ddapi.egg-info/dependency_links.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ddapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: ddapi
|
|
5
5
|
Home-page: https://github.com/ByFox213/ddapi
|
|
6
6
|
Author: ByFox
|
|
@@ -36,7 +36,6 @@ Description-Content-Type: text/markdown
|
|
|
36
36
|
License-File: LICENSE
|
|
37
37
|
Requires-Dist: pydantic
|
|
38
38
|
Requires-Dist: aiohttp
|
|
39
|
-
Requires-Dist: orjson
|
|
40
39
|
Provides-Extra: dev
|
|
41
40
|
Requires-Dist: pydantic; extra == "dev"
|
|
42
41
|
Requires-Dist: aiohttp; extra == "dev"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import aiohttp
|
|
2
|
+
from aiohttp import ClientSession
|
|
3
|
+
from typing import Union
|
|
4
|
+
from json import JSONDecoder
|
|
5
|
+
from aiohttp.typedefs import DEFAULT_JSON_DECODER
|
|
6
|
+
from ..errors import ExceptConnection
|
|
7
|
+
from ..dataclass import DDPlayer
|
|
8
|
+
from ..misc import username_encode
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DDnetApi:
|
|
12
|
+
def __init__(self,
|
|
13
|
+
session: ClientSession = None,
|
|
14
|
+
on_raise: bool = True,
|
|
15
|
+
json_loads: JSONDecoder = DEFAULT_JSON_DECODER):
|
|
16
|
+
self.session = session
|
|
17
|
+
self.on_raise = on_raise
|
|
18
|
+
self.json_loads = json_loads
|
|
19
|
+
self.url = "https://ddstats.qwik.space/player/json?player={0}"
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def closed(self):
|
|
23
|
+
return self.session.closed is None or self.session.closed
|
|
24
|
+
|
|
25
|
+
async def _ch_start(self) -> None:
|
|
26
|
+
if self.session is None:
|
|
27
|
+
self.session = aiohttp.ClientSession()
|
|
28
|
+
|
|
29
|
+
async def _send(self, url: str) -> Union[dict, None]:
|
|
30
|
+
await self._ch_start()
|
|
31
|
+
try:
|
|
32
|
+
async with self.session.get(url) as req:
|
|
33
|
+
if req.status == 200:
|
|
34
|
+
usr = await req.text()
|
|
35
|
+
if usr == '{}' or usr is None:
|
|
36
|
+
return
|
|
37
|
+
del usr
|
|
38
|
+
return await req.json(loads=self.json_loads)
|
|
39
|
+
return
|
|
40
|
+
except Exception as ex:
|
|
41
|
+
if self.on_raise:
|
|
42
|
+
raise ExceptConnection(f"This hosting may not be available at the moment: {ex}")
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
async def close(self) -> None:
|
|
46
|
+
return await self.session.close()
|
|
47
|
+
|
|
48
|
+
async def player(self, player: str) -> Union[DDPlayer, None]:
|
|
49
|
+
dat = await self._send(f"https://ddnet.org/players/?json2={username_encode(player)}")
|
|
50
|
+
if dat is None:
|
|
51
|
+
return
|
|
52
|
+
return DDPlayer(**dat)
|
|
53
|
+
|
|
54
|
+
async def dict_player(self, player: str) -> Union[dict, None]:
|
|
55
|
+
dat = await self._send(f"https://ddnet.org/players/?json2={username_encode(player)}")
|
|
56
|
+
if dat is None:
|
|
57
|
+
return
|
|
58
|
+
return dat
|
|
59
|
+
|
|
60
|
+
async def master(self) -> Union[dict, None]:
|
|
61
|
+
return await self._send("https://master1.ddnet.org/ddnet/15/servers.json")
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# ddnet
|
|
6
|
+
class DPoints(BaseModel):
|
|
7
|
+
total: Optional[int] = Field(default=None)
|
|
8
|
+
points: Optional[int] = Field(default=None)
|
|
9
|
+
rank: Optional[int] = Field(default=None)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DRank(BaseModel):
|
|
13
|
+
points: Optional[int] = Field(default=None)
|
|
14
|
+
rank: Optional[int] = Field(default=None)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class FirstFinish(BaseModel):
|
|
18
|
+
timestamp: Optional[float] = Field(default=None)
|
|
19
|
+
map: Optional[str] = Field(default=None)
|
|
20
|
+
time: Optional[float] = Field(default=None)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class LastFinish(BaseModel):
|
|
24
|
+
timestamp: Optional[float] = Field(default=None)
|
|
25
|
+
map: Optional[str] = Field(default=None)
|
|
26
|
+
time: Optional[float] = Field(default=None)
|
|
27
|
+
country: Optional[str] = Field(default=None)
|
|
28
|
+
type: Optional[str] = Field(default=None)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class FavorPart(BaseModel):
|
|
32
|
+
name: Optional[str] = Field(default=None)
|
|
33
|
+
finishes: Optional[int] = Field(default=None)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DData(BaseModel):
|
|
37
|
+
points: Optional[DPoints] = Field(default=None)
|
|
38
|
+
team_rank: Optional[DRank] = Field(default=None)
|
|
39
|
+
rank: Optional[DRank] = Field(default=None)
|
|
40
|
+
maps: Optional[dict] = Field(default=None)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class DDType(BaseModel):
|
|
44
|
+
Novice: Optional[DData] = Field(default=None)
|
|
45
|
+
Moderate: Optional[DData] = Field(default=None)
|
|
46
|
+
Brutal: Optional[DData] = Field(default=None)
|
|
47
|
+
Insane: Optional[DData] = Field(default=None)
|
|
48
|
+
Dummy: Optional[DData] = Field(default=None)
|
|
49
|
+
DDmaX_Easy: Optional[DData] = Field(default=None, validation_alias='DDmaX.Easy')
|
|
50
|
+
DDmaX_Next: Optional[DData] = Field(default=None, validation_alias='DDmaX.Next')
|
|
51
|
+
DDmaX_Nut: Optional[DData] = Field(default=None, validation_alias='DDmaX.Nut')
|
|
52
|
+
DDmaX_Pro: Optional[DData] = Field(default=None, validation_alias='DDmaX.Pro')
|
|
53
|
+
Oldschool: Optional[DData] = Field(default=None)
|
|
54
|
+
Race: Optional[DData] = Field(default=None)
|
|
55
|
+
Solo: Optional[DData] = Field(default=None)
|
|
56
|
+
total: Optional[DData] = Field(default=None)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class DActiov(BaseModel):
|
|
60
|
+
date: Optional[str] = Field(default=None)
|
|
61
|
+
hours_played: Optional[int] = Field(default=None)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class DDPlayer(BaseModel):
|
|
65
|
+
player: Optional[str] = Field(default=None)
|
|
66
|
+
points: Optional[DPoints] = Field(default=None)
|
|
67
|
+
team_rank: Optional[DRank] = Field(default=None)
|
|
68
|
+
rank: Optional[DRank] = Field(default=None)
|
|
69
|
+
points_last_month: Optional[DRank] = Field(default=None)
|
|
70
|
+
points_last_week: Optional[DRank] = Field(default=None)
|
|
71
|
+
first_finish: Optional[FirstFinish] = Field(default=None)
|
|
72
|
+
last_finishes: Optional[list[LastFinish]] = Field(default=None)
|
|
73
|
+
favorite_partners: Optional[list[FavorPart]] = Field(default=None)
|
|
74
|
+
types: Optional[DDType] = Field(default=None)
|
|
75
|
+
activity: Optional[list[DActiov]] = Field(default=None)
|
|
76
|
+
hours_played_past_365_days: Optional[int] = Field(default=None)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# qwik
|
|
80
|
+
class Skin(BaseModel):
|
|
81
|
+
name: Optional[str] = Field(default=None)
|
|
82
|
+
color_body: Optional[int] = Field(default=None)
|
|
83
|
+
color_feet: Optional[int] = Field(default=None)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class PData(BaseModel):
|
|
87
|
+
rank: Optional[str] = Field(default=None)
|
|
88
|
+
points: Optional[int] = Field(default=None)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class PPoints(BaseModel):
|
|
92
|
+
Novice: Optional[PData] = Field(default=None)
|
|
93
|
+
Moderate: Optional[PData] = Field(default=None)
|
|
94
|
+
Brutal: Optional[PData] = Field(default=None)
|
|
95
|
+
Insane: Optional[PData] = Field(default=None)
|
|
96
|
+
Dummy: Optional[PData] = Field(default=None)
|
|
97
|
+
DDmaX_Easy: Optional[PData] = Field(default=None, validation_alias='DDmaX.Easy')
|
|
98
|
+
DDmaX_Next: Optional[PData] = Field(default=None, validation_alias='DDmaX.Next')
|
|
99
|
+
DDmaX_Nut: Optional[PData] = Field(default=None, validation_alias='DDmaX.Nut')
|
|
100
|
+
DDmaX_Pro: Optional[PData] = Field(default=None, validation_alias='DDmaX.Pro')
|
|
101
|
+
Oldschool: Optional[PData] = Field(default=None)
|
|
102
|
+
Race: Optional[PData] = Field(default=None)
|
|
103
|
+
Solo: Optional[PData] = Field(default=None)
|
|
104
|
+
total: Optional[PData] = Field(default=None)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class Points(BaseModel):
|
|
108
|
+
points: Optional[PPoints] = Field(default=None)
|
|
109
|
+
rankpoints: Optional[PPoints] = Field(default=None)
|
|
110
|
+
teampoints: Optional[PPoints] = Field(default=None)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class RData(BaseModel):
|
|
114
|
+
Map: Optional[str] = Field(default=None)
|
|
115
|
+
Name: Optional[str] = Field(default=None)
|
|
116
|
+
Time: Optional[float] = Field(default=None)
|
|
117
|
+
Server: Optional[str] = Field(default=None)
|
|
118
|
+
Rank: Optional[int] = Field(default=None)
|
|
119
|
+
Teamrank: Optional[int] = Field(default=None)
|
|
120
|
+
Category: str
|
|
121
|
+
Points: int
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class Rankings(BaseModel):
|
|
125
|
+
Novice: Optional[list[RData]] = Field(default=None)
|
|
126
|
+
Moderate: Optional[list[RData]] = Field(default=None)
|
|
127
|
+
Brutal: Optional[list[RData]] = Field(default=None)
|
|
128
|
+
Insane: Optional[list[RData]] = Field(default=None)
|
|
129
|
+
Dummy: Optional[list[RData]] = Field(default=None)
|
|
130
|
+
DDmaX_Easy: Optional[list[RData]] = Field(default=None, validation_alias='DDmaX.Easy')
|
|
131
|
+
DDmaX_Next: Optional[list[RData]] = Field(default=None, validation_alias='DDmaX.Next')
|
|
132
|
+
DDmaX_Nut: Optional[list[RData]] = Field(default=None, validation_alias='DDmaX.Nut')
|
|
133
|
+
DDmaX_Pro: Optional[list[RData]] = Field(default=None, validation_alias='DDmaX.Pro')
|
|
134
|
+
Oldschool: Optional[list[RData]] = Field(default=None)
|
|
135
|
+
Race: Optional[list[RData]] = Field(default=None)
|
|
136
|
+
Solo: Optional[list[RData]] = Field(default=None)
|
|
137
|
+
Fun: Optional[list[RData]] = Field(default=None)
|
|
138
|
+
total: Optional[list[RData]] = Field(default=None)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class RPointG(BaseModel):
|
|
142
|
+
date: Optional[str] = Field(default=None)
|
|
143
|
+
rankpoints: Optional[int] = Field(default=None)
|
|
144
|
+
teampoints: Optional[int] = Field(default=None)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class PointG(BaseModel):
|
|
148
|
+
date: Optional[str] = Field(default=None)
|
|
149
|
+
points: Optional[int] = Field(default=None)
|
|
150
|
+
maps: Optional[str] = Field(default=None)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class RecentPlayerInfo(BaseModel):
|
|
154
|
+
date: Optional[str] = Field(default=None)
|
|
155
|
+
name: Optional[str] = Field(default=None)
|
|
156
|
+
clan: Optional[str] = Field(default=None)
|
|
157
|
+
country: Optional[int] = Field(default=None)
|
|
158
|
+
skin_name: Optional[str] = Field(default=None)
|
|
159
|
+
skin_color_body: Optional[int] = Field(default=None)
|
|
160
|
+
skin_color_feet: Optional[int] = Field(default=None)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class RecentPlayTime(BaseModel):
|
|
164
|
+
date: Optional[str] = Field(default=None)
|
|
165
|
+
map: Optional[str] = Field(default=None)
|
|
166
|
+
player: Optional[str] = Field(default=None)
|
|
167
|
+
Playtime: Optional[int] = Field(default=None)
|
|
168
|
+
Server: Optional[str] = Field(default=None)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class PlaytimeCategories(BaseModel):
|
|
172
|
+
Category: Optional[str] = Field(default=None)
|
|
173
|
+
Playtime: Optional[int] = Field(default=None)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class PlaytimeGameTypes(BaseModel):
|
|
177
|
+
gametype: Optional[str] = Field(default=None)
|
|
178
|
+
Playtime: Optional[int] = Field(default=None)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class PlaytimeLocation(BaseModel):
|
|
182
|
+
location: Optional[str] = Field(default=None)
|
|
183
|
+
Playtime: Optional[int] = Field(default=None)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class PlaytimePerMonth(BaseModel):
|
|
187
|
+
Year: Optional[str] = Field(default=None)
|
|
188
|
+
Month: Optional[str] = Field(default=None)
|
|
189
|
+
Playtime: Optional[int] = Field(default=None)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class MostPlayedMaps(BaseModel):
|
|
193
|
+
map: Optional[str] = Field(default=None)
|
|
194
|
+
Server: Optional[str] = Field(default=None)
|
|
195
|
+
Playtime: Optional[int] = Field(default=None)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class AllTop10s(BaseModel):
|
|
199
|
+
Server: Optional[str] = Field(default=None)
|
|
200
|
+
Map: Optional[str] = Field(default=None)
|
|
201
|
+
rank: Optional[int] = Field(default=None)
|
|
202
|
+
rtime: Optional[float] = Field(default=None)
|
|
203
|
+
teamrank: Optional[int] = Field(default=None)
|
|
204
|
+
ttime: Optional[float] = Field(default=None)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class AmountOfTop10(BaseModel):
|
|
208
|
+
Name: Optional[str] = Field(default=None)
|
|
209
|
+
Rank: Optional[int] = Field(default=None)
|
|
210
|
+
RankAmount: Optional[int] = Field(default=None)
|
|
211
|
+
TeamRankAmount: Optional[int] = Field(default=None)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class Rank1sPartners(BaseModel):
|
|
215
|
+
Name: Optional[str] = Field(default=None)
|
|
216
|
+
Amount: Optional[int] = Field(default=None)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class RecentTop10s(BaseModel):
|
|
220
|
+
Timestamp: Optional[str] = Field(default=None)
|
|
221
|
+
Server: Optional[str] = Field(default=None)
|
|
222
|
+
Name: Optional[str] = Field(default=None)
|
|
223
|
+
Time: Optional[float] = Field(default=None)
|
|
224
|
+
Map: Optional[str] = Field(default=None)
|
|
225
|
+
Rank: Optional[int] = Field(default=None)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class Player(BaseModel):
|
|
229
|
+
player: Optional[str] = Field(default=None)
|
|
230
|
+
clan: Optional[str] = Field(default=None)
|
|
231
|
+
country: Optional[int] = Field(default=None)
|
|
232
|
+
skin: Optional[Skin] = Field(default=None)
|
|
233
|
+
stamp: Optional[str] = Field(default=None)
|
|
234
|
+
points: Optional[Points] = Field(default=None)
|
|
235
|
+
rankings: Optional[Rankings] = Field(default=None)
|
|
236
|
+
isMapper: Optional[int] = Field(default=None)
|
|
237
|
+
rankedPointsGraph: Optional[list[RPointG]] = Field(default=None)
|
|
238
|
+
pointsGraph: Optional[list[PointG]] = Field(default=None)
|
|
239
|
+
playtime: Optional[dict] = Field(default=None)
|
|
240
|
+
recentPlayerinfo: Optional[list[RecentPlayerInfo]] = Field(default=None)
|
|
241
|
+
recentPlaytime: Optional[list[RecentPlayTime]] = Field(default=None)
|
|
242
|
+
playtimeCategories: Optional[list[PlaytimeCategories]] = Field(default=None)
|
|
243
|
+
playtimeGametypes: Optional[list[PlaytimeGameTypes]] = Field(default=None)
|
|
244
|
+
playtimeLocation: Optional[list[PlaytimeLocation]] = Field(default=None)
|
|
245
|
+
playtimePerMonth: Optional[list[PlaytimePerMonth]] = Field(default=None)
|
|
246
|
+
mostPlayedMaps: Optional[list[MostPlayedMaps]] = Field(default=None)
|
|
247
|
+
allTop10s: Optional[list[AllTop10s]] = Field(default=None)
|
|
248
|
+
AmountOfTop10Placements: Optional[list[AmountOfTop10]] = Field(default=None,
|
|
249
|
+
validation_alias="AmountOfTop10Placements")
|
|
250
|
+
rank1sPartners: Optional[list[Rank1sPartners]] = Field(default=None)
|
|
251
|
+
recentTop10s: Optional[list[RecentTop10s]] = Field(default=None)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
sum_to_encoding = {"␣": "%20", "!": "%21", "\"": "%22", "#": "%23",
|
|
2
|
+
"$": "%24", "%": "%25", "&": "%26", "\'": "%27",
|
|
3
|
+
"(": "%28", ")": "%29", "*": "%2A", "+": "%2B",
|
|
4
|
+
",": "%2C", "/": "%2F", ":": "%3A", ";": "%3B",
|
|
5
|
+
"=": "%3D", "?": "%3F", "@": "%40", "[": "%5B",
|
|
6
|
+
"]": "%5D", "-": "%2D", ".": "%2E", "<": "%3C",
|
|
7
|
+
">": "%3E", "\\": "%5C", "^": "%5E", "_": "%5F",
|
|
8
|
+
"`": "%60", "{": "%7B", "|": "%7C", "}": "%7D",
|
|
9
|
+
"~": "%7E"}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def username_encode(username: str) -> str:
|
|
13
|
+
"""Decodes the line so that http gives out information about the player.
|
|
14
|
+
:param username:
|
|
15
|
+
:type: str
|
|
16
|
+
:return:
|
|
17
|
+
:type: str
|
|
18
|
+
"""
|
|
19
|
+
result: str = ""
|
|
20
|
+
for i in username:
|
|
21
|
+
add: str = sum_to_encoding.get(i)
|
|
22
|
+
if add is not None:
|
|
23
|
+
result += add
|
|
24
|
+
else:
|
|
25
|
+
result += i
|
|
26
|
+
return result
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import aiohttp
|
|
2
|
-
import orjson
|
|
3
2
|
from aiohttp import ClientSession
|
|
3
|
+
from typing import Union
|
|
4
|
+
from json import JSONDecoder
|
|
5
|
+
from aiohttp.typedefs import DEFAULT_JSON_DECODER
|
|
4
6
|
from ..dataclass import Player
|
|
5
7
|
from ..misc import username_encode
|
|
6
8
|
from ..errors import ExceptConnection
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class QwikAPI:
|
|
10
|
-
def __init__(self,
|
|
12
|
+
def __init__(self,
|
|
13
|
+
session: ClientSession = None,
|
|
14
|
+
on_raise: bool = True,
|
|
15
|
+
json_loads: JSONDecoder = DEFAULT_JSON_DECODER):
|
|
11
16
|
self.session = session
|
|
17
|
+
self.on_raise = on_raise
|
|
18
|
+
self.json_loads = json_loads
|
|
12
19
|
self.url = "https://ddstats.qwik.space/player/json?player={0}"
|
|
13
20
|
|
|
14
21
|
@property
|
|
@@ -19,7 +26,7 @@ class QwikAPI:
|
|
|
19
26
|
if self.session is None:
|
|
20
27
|
self.session = aiohttp.ClientSession()
|
|
21
28
|
|
|
22
|
-
async def _send(self, player: str) -> dict
|
|
29
|
+
async def _send(self, player: str) -> Union[dict, None]:
|
|
23
30
|
await self._ch_start()
|
|
24
31
|
try:
|
|
25
32
|
async with self.session.get(self.url.format(username_encode(player))) as req:
|
|
@@ -28,12 +35,14 @@ class QwikAPI:
|
|
|
28
35
|
if usr == '{}' or usr is None:
|
|
29
36
|
return
|
|
30
37
|
del usr
|
|
31
|
-
return await req.json(loads=
|
|
38
|
+
return await req.json(loads=self.json_loads)
|
|
32
39
|
return
|
|
33
40
|
except Exception as ex:
|
|
34
|
-
|
|
41
|
+
if self.on_raise:
|
|
42
|
+
raise ExceptConnection(f"This hosting may not be available at the moment: {ex}")
|
|
43
|
+
return
|
|
35
44
|
|
|
36
|
-
async def player(self, nickname) -> Player
|
|
45
|
+
async def player(self, nickname) -> Union[Player, None]:
|
|
37
46
|
dat = await self._send(nickname)
|
|
38
47
|
if not dat:
|
|
39
48
|
return
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ddapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: ddapi
|
|
5
5
|
Home-page: https://github.com/ByFox213/ddapi
|
|
6
6
|
Author: ByFox
|
|
@@ -36,7 +36,6 @@ Description-Content-Type: text/markdown
|
|
|
36
36
|
License-File: LICENSE
|
|
37
37
|
Requires-Dist: pydantic
|
|
38
38
|
Requires-Dist: aiohttp
|
|
39
|
-
Requires-Dist: orjson
|
|
40
39
|
Provides-Extra: dev
|
|
41
40
|
Requires-Dist: pydantic; extra == "dev"
|
|
42
41
|
Requires-Dist: aiohttp; extra == "dev"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.cfg
|
|
5
|
+
setup.py
|
|
6
|
+
ddapi/ddapi/__init__.py
|
|
7
|
+
ddapi/ddapi/dataclass.py
|
|
8
|
+
ddapi/ddapi/errors.py
|
|
9
|
+
ddapi/ddapi/misc.py
|
|
10
|
+
ddapi/ddapi.egg-info/PKG-INFO
|
|
11
|
+
ddapi/ddapi.egg-info/SOURCES.txt
|
|
12
|
+
ddapi/ddapi.egg-info/dependency_links.txt
|
|
13
|
+
ddapi/ddapi.egg-info/requires.txt
|
|
14
|
+
ddapi/ddapi.egg-info/top_level.txt
|
|
15
|
+
ddapi/ddapi/DDnetApiPy/__init__.py
|
|
16
|
+
ddapi/ddapi/DDnetApiPy/main.py
|
|
17
|
+
ddapi/ddapi/qwikDDnetApiPy/__init__.py
|
|
18
|
+
ddapi/ddapi/qwikDDnetApiPy/main.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ddapi
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ddapi"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "ddapi"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "ByFox" }]
|
|
@@ -17,8 +17,7 @@ classifiers = [
|
|
|
17
17
|
keywords = ["feed", "reader", "tutorial"]
|
|
18
18
|
dependencies = [
|
|
19
19
|
"pydantic",
|
|
20
|
-
"aiohttp"
|
|
21
|
-
'orjson'
|
|
20
|
+
"aiohttp"
|
|
22
21
|
]
|
|
23
22
|
requires-python = ">=3.8"
|
|
24
23
|
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import aiohttp
|
|
2
|
-
import orjson
|
|
3
|
-
from aiohttp import ClientSession
|
|
4
|
-
from ..dataclass import DDPlayer
|
|
5
|
-
from ..misc import username_encode
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class DDnetApi:
|
|
9
|
-
def __init__(self, session: ClientSession = None):
|
|
10
|
-
self.session = session
|
|
11
|
-
self.url = "https://ddstats.qwik.space/player/json?player={0}"
|
|
12
|
-
|
|
13
|
-
@property
|
|
14
|
-
def closed(self):
|
|
15
|
-
return self.session.closed is None or self.session.closed
|
|
16
|
-
|
|
17
|
-
async def _ch_start(self) -> None:
|
|
18
|
-
if self.session is None:
|
|
19
|
-
self.session = aiohttp.ClientSession()
|
|
20
|
-
|
|
21
|
-
async def _send(self, url: str) -> dict | None:
|
|
22
|
-
await self._ch_start()
|
|
23
|
-
async with self.session.get(url) as req:
|
|
24
|
-
if req.status == 200:
|
|
25
|
-
usr = await req.text()
|
|
26
|
-
if usr == '{}' or usr is None:
|
|
27
|
-
return
|
|
28
|
-
del usr
|
|
29
|
-
return await req.json(loads=orjson.loads)
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
async def close(self) -> None:
|
|
33
|
-
return await self.session.close()
|
|
34
|
-
|
|
35
|
-
async def player(self, player: str) -> DDPlayer | None:
|
|
36
|
-
dat = await self._send(f"https://ddnet.org/players/?json2={username_encode(player)}")
|
|
37
|
-
if dat is None:
|
|
38
|
-
return
|
|
39
|
-
return DDPlayer(**dat)
|
|
40
|
-
|
|
41
|
-
async def dict_player(self, player: str) -> dict | None:
|
|
42
|
-
dat = await self._send(f"https://ddnet.org/players/?json2={username_encode(player)}")
|
|
43
|
-
if dat is None:
|
|
44
|
-
return
|
|
45
|
-
return dat
|
|
46
|
-
|
|
47
|
-
async def master(self) -> dict | None:
|
|
48
|
-
return await self._send("https://master1.ddnet.org/ddnet/15/servers.json")
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
setup.cfg
|
|
5
|
-
setup.py
|
|
6
|
-
ddapi/DDnetApiPy/__init__.py
|
|
7
|
-
ddapi/DDnetApiPy/main.py
|
|
8
|
-
ddapi/ddapi.egg-info/PKG-INFO
|
|
9
|
-
ddapi/ddapi.egg-info/SOURCES.txt
|
|
10
|
-
ddapi/ddapi.egg-info/dependency_links.txt
|
|
11
|
-
ddapi/ddapi.egg-info/requires.txt
|
|
12
|
-
ddapi/ddapi.egg-info/top_level.txt
|
|
13
|
-
ddapi/qwikDDnetApiPy/__init__.py
|
|
14
|
-
ddapi/qwikDDnetApiPy/main.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|