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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ddapi
3
- Version: 0.1.0
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,6 @@
1
+ from .DDnetApiPy.main import *
2
+ from .qwikDDnetApiPy.main import *
3
+ from .dataclass import DDPlayer, Player
4
+
5
+ __version__ = "0.3.5"
6
+ __author__ = 'ByFox'
@@ -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,2 @@
1
+ class ExceptConnection(Exception):
2
+ pass
@@ -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, session: ClientSession = None):
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 | None:
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=orjson.loads)
38
+ return await req.json(loads=self.json_loads)
32
39
  return
33
40
  except Exception as ex:
34
- raise ExceptConnection(f"This hosting may not be available at the moment: {ex}")
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 | None:
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.0
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
@@ -1,6 +1,5 @@
1
1
  pydantic
2
2
  aiohttp
3
- orjson
4
3
 
5
4
  [dev]
6
5
  pydantic
@@ -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.0"
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,6 +1,6 @@
1
1
  [metadata]
2
2
  name = ddapi
3
- version = 0.10
3
+ version = 0.1.2
4
4
  author = ByFox
5
5
  description = DDnet api
6
6
  long_description = file: README.md
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="ddapi-py",
8
- version="0.10",
8
+ version="0.1.2",
9
9
  author="ByFox",
10
10
  description="DDnet api",
11
11
  long_description=long_description,
@@ -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
@@ -1,2 +0,0 @@
1
- DDnetApiPy
2
- qwikDDnetApiPy
File without changes
File without changes