ddapi 0.10.0__tar.gz → 0.12.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.
@@ -1,22 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ddapi
3
- Version: 0.10.0
3
+ Version: 0.12.0
4
4
  Summary: DDnet api
5
5
  Home-page: https://github.com/ByFox213/ddapi
6
6
  Author: ByFox
7
- License: "MIT"
7
+ License: MIT
8
8
  Project-URL: Github, https://github.com/ByFox213/ddapi
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
9
  Requires-Python: >=3.8
13
10
  Description-Content-Type: text/markdown
14
11
  License-File: LICENSE
15
12
  Dynamic: author
16
- Dynamic: classifier
17
13
  Dynamic: description
18
14
  Dynamic: description-content-type
19
15
  Dynamic: home-page
16
+ Dynamic: license
20
17
  Dynamic: license-file
21
18
  Dynamic: project-url
22
19
  Dynamic: requires-python
@@ -42,28 +39,28 @@ DDnet
42
39
 
43
40
  ```python
44
41
  import asyncio
42
+
45
43
  from ddapi import DDnetApi, DDPlayer
46
44
 
47
45
 
48
46
  async def main():
49
- obj = DDnetApi()
50
- nickname = "Cor"
51
- user: DDPlayer = await obj.player(nickname)
52
- if user is None:
53
- return "Player not found"
54
-
55
- print(f"{user.player}: {user.points.points}")
56
- # Cor: 31473
57
- await obj.close() # Closing client Not necessary
58
- assert isinstance(user, DDPlayer)
47
+ async with DDnetApi() as obj:
48
+ user: DDPlayer = await obj.player("Cor")
49
+ if user is not None:
50
+ text = f"{user.player}: {user.points.points}/{user.points.total}"
51
+ percent = round(user.points.total / user.points.points * 100)
52
+ print(f"{text}({percent}%)")
53
+ # Cor: 32950/32950(100%)
54
+ else:
55
+ print("Player not found")
59
56
 
60
57
 
61
58
  asyncio.run(main())
62
59
  ```
63
60
 
64
61
  Tested on Python
65
- | 3.9 | 3.10 | 3.11 | 3.12 |
66
- |-----|------|------|------|
67
- | ? | ? | ✅ | ✅ |
62
+ | 3.10 | 3.11 | 3.12 |
63
+ |------|------|------|
64
+ | ✅ | ✅ | ✅ |
68
65
 
69
66
  [other examples](https://github.com/ByFox213/ddapi/tree/main/example)
ddapi-0.12.0/README.md ADDED
@@ -0,0 +1,45 @@
1
+ ddapi is an api from the ddnet and qwik website
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ pip install ddapi
7
+ ```
8
+
9
+ or
10
+
11
+ ```bash
12
+ pip install git+https://github.com/ByFox213/ddapi
13
+ ```
14
+
15
+ ## Usage/Examples
16
+
17
+ DDnet
18
+
19
+ ```python
20
+ import asyncio
21
+
22
+ from ddapi import DDnetApi, DDPlayer
23
+
24
+
25
+ async def main():
26
+ async with DDnetApi() as obj:
27
+ user: DDPlayer = await obj.player("Cor")
28
+ if user is not None:
29
+ text = f"{user.player}: {user.points.points}/{user.points.total}"
30
+ percent = round(user.points.total / user.points.points * 100)
31
+ print(f"{text}({percent}%)")
32
+ # Cor: 32950/32950(100%)
33
+ else:
34
+ print("Player not found")
35
+
36
+
37
+ asyncio.run(main())
38
+ ```
39
+
40
+ Tested on Python
41
+ | 3.10 | 3.11 | 3.12 |
42
+ |------|------|------|
43
+ | ✅ | ✅ | ✅ |
44
+
45
+ [other examples](https://github.com/ByFox213/ddapi/tree/main/example)
@@ -1,7 +1,7 @@
1
1
  """the module is made for the convenience of users to download and use"""
2
2
  from .main import DDnetApi, DDstats, Status
3
- from .scheme import *
3
+ from .scheme import * # noqa: F403
4
4
 
5
- __version__ = "0.10.0"
6
- __author__ = 'ByFox'
5
+ __version__ = "0.12.0"
6
+ __author__ = "ByFox"
7
7
  __LICENSE__ = "MIT"
@@ -1,43 +1,66 @@
1
+ import asyncio
1
2
  from abc import ABC
2
- from typing import Optional, TypeVar, Type, Any
3
+ from typing import Optional, Type, Any
3
4
 
4
5
  import aiohttp
5
- from aiohttp import ClientSession, ClientConnectorError
6
- from aiohttp.typedefs import DEFAULT_JSON_DECODER
6
+ from aiohttp import ClientSession
7
7
 
8
- ModelType = TypeVar('ModelType', bound='Model')
8
+ from ddapi.types import T
9
+
10
+ try:
11
+ import orjson
12
+
13
+ DEFAULT_JSON_DECODER = orjson.loads
14
+ except ImportError:
15
+ from aiohttp.typedefs import DEFAULT_JSON_DECODER
9
16
 
10
17
 
11
18
  class API(ABC):
12
19
  def __init__(
13
20
  self,
14
21
  session: ClientSession = None,
22
+ autoclose: bool = True,
15
23
  json_loads: Any = DEFAULT_JSON_DECODER
16
24
  ):
17
25
  self.__session = session
18
26
  self.json_loads = json_loads
27
+ self.autoclose = autoclose
19
28
 
20
- @staticmethod
21
- def powered() -> None:
22
- return None
29
+ if self.__session is None:
30
+ self.__session = aiohttp.ClientSession()
23
31
 
24
- async def _get(self, url: str) -> Optional[dict]:
25
- """Send a GET request to the given URL and return the response as JSON."""
32
+ async def __aenter__(self):
26
33
  if self.__session is None:
27
34
  self.__session = aiohttp.ClientSession()
35
+ return self
28
36
 
29
- try:
30
- async with self.__session.get(url) as req:
31
- return await req.json(loads=self.json_loads) if req.status == 200 else None
32
- except ClientConnectorError:
33
- return
37
+ async def __aexit__(self, _exc_type, _exc_val, _exc_tb):
38
+ if self.autoclose:
39
+ await self.close()
40
+
41
+ def __del__(self):
42
+ if self.__session is not None and not self.__session.closed:
43
+ loop = asyncio.get_event_loop()
44
+ if loop.is_running():
45
+ loop.create_task(self.close())
46
+ else:
47
+ loop.run_until_complete(self.close())
48
+
49
+ async def _get(self, url: str) -> Optional[dict]:
50
+ """Send a GET request to the given URL and return the response as JSON."""
51
+ async with self.__session.get(url) as req:
52
+ return (
53
+ await req.json(loads=self.json_loads)
54
+ if req.status == 200
55
+ else None
56
+ )
34
57
 
35
58
  async def _generate_model_instance(
36
59
  self,
37
60
  url: str,
38
- model: Type[ModelType],
61
+ model: Type[T],
39
62
  k: Optional[str] = None
40
- ) -> Optional[ModelType]:
63
+ ) -> Optional[T]:
41
64
  """Generate a model instance from the given URL and optional keyword arguments.
42
65
 
43
66
  Args:
@@ -64,3 +87,11 @@ class API(ABC):
64
87
  if self.__session is not None:
65
88
  await self.__session.close()
66
89
  self.__session = None
90
+
91
+ @property
92
+ def domain(self) -> str:
93
+ return "ddnet.org"
94
+
95
+ @staticmethod
96
+ def powered() -> None:
97
+ return None
@@ -1,7 +1,10 @@
1
+ from enum import StrEnum
1
2
  from urllib.parse import quote
2
3
 
3
4
  from .api import API
4
- from .scheme import *
5
+ from .scheme import DDPlayer, DDStatus, ReleasesMaps, Query, QueryMap, QueryMapper, \
6
+ Master, DMap, DProfile, SMap, Maps, Player, Info, BannedMaster, List, ListData, \
7
+ ListPl, ListPlData, MasterTw, ServerTwOne, Charts, ChartEnum, Stats
5
8
 
6
9
  __all__ = (
7
10
  "MasterEnum",
@@ -12,16 +15,16 @@ __all__ = (
12
15
 
13
16
 
14
17
  class MasterEnum(StrEnum):
15
- master1 = "master1"
16
- master2 = "master2"
17
- master3 = "master3"
18
- master4 = "master4"
18
+ master1 = "1"
19
+ master2 = "2"
20
+ master3 = "3"
21
+ master4 = "4"
19
22
 
20
23
 
21
24
  class DDnetApi(API):
22
- def __init__(self):
23
- super().__init__()
24
- self.domain = "ddnet.org"
25
+ @property
26
+ def domain(self) -> str:
27
+ return "ddnet.org"
25
28
 
26
29
  @staticmethod
27
30
  def powered() -> str:
@@ -58,19 +61,19 @@ class DDnetApi(API):
58
61
  return await self._generate_model_instance(
59
62
  f"https://{self.domain}/maps/?query={quote(map_name)}",
60
63
  QueryMap,
61
- 'maps',
64
+ "maps",
62
65
  )
63
66
 
64
67
  async def query_mapper(self, player: str) -> QueryMapper:
65
68
  return await self._generate_model_instance(
66
69
  f"https://{self.domain}/maps/?qmapper={quote(player)}",
67
70
  QueryMapper,
68
- 'players',
71
+ "players",
69
72
  )
70
73
 
71
- async def master(self, master: MasterEnum = MasterEnum.master1) -> Master:
74
+ async def master(self, number: MasterEnum = MasterEnum.master1) -> Master:
72
75
  return await self._generate_model_instance(
73
- f"https://{master}.{self.domain}/ddnet/15/servers.json",
76
+ f"https://master{number}.{self.domain}/ddnet/15/servers.json",
74
77
  Master
75
78
  )
76
79
 
@@ -82,9 +85,9 @@ class DDnetApi(API):
82
85
 
83
86
 
84
87
  class DDstats(API):
85
- def __init__(self):
86
- super().__init__()
87
- self.domain = 'ddstats.tw'
88
+ @property
89
+ def domain(self) -> str:
90
+ return "ddstats.tw"
88
91
 
89
92
  @staticmethod
90
93
  def powered() -> str:
@@ -99,7 +102,7 @@ class DDstats(API):
99
102
 
100
103
  async def map(self, map_name: str) -> SMap:
101
104
  return await self._generate_model_instance(
102
- f"https://ddstats.tw/map/json?map={quote(map_name)}",
105
+ f"https://{self.domain}/map/json?map={quote(map_name)}",
103
106
  SMap
104
107
  )
105
108
 
@@ -119,9 +122,9 @@ class DDstats(API):
119
122
 
120
123
 
121
124
  class Status(API):
122
- def __init__(self):
123
- super().__init__()
124
- self.domain = 'status.tw'
125
+ @property
126
+ def domain(self) -> str:
127
+ return "status.tw"
125
128
 
126
129
  @staticmethod
127
130
  def powered() -> str:
@@ -193,7 +196,12 @@ class Status(API):
193
196
  ServerTwOne,
194
197
  )
195
198
 
196
- async def server_charts(self, ip: str, port: int | str, chart: ChartEnum = ChartEnum.day) -> Charts:
199
+ async def server_charts(
200
+ self,
201
+ ip: str,
202
+ port: int | str,
203
+ chart: ChartEnum = ChartEnum.day
204
+ ) -> Charts:
197
205
  return await self._generate_model_instance(
198
206
  f"https://api.{self.domain}/server/{quote(ip)}/{port}/chart/{chart}",
199
207
  Charts,
@@ -0,0 +1,4 @@
1
+ from .base import * # noqa: F403
2
+ from .ddnet import * # noqa: F403
3
+ from .ddstats_tw import * # noqa: F403
4
+ from .status_tw import * # noqa: F403
@@ -0,0 +1,21 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from ddapi import DData
6
+
7
+
8
+ class DDType(BaseModel):
9
+ Novice: Optional[DData] = None
10
+ Moderate: Optional[DData] = None
11
+ Brutal: Optional[DData] = None
12
+ Insane: Optional[DData] = None
13
+ Dummy: Optional[DData] = None
14
+ DDmaX_Easy: Optional[DData] = Field(default=None, validation_alias="DDmaX.Easy")
15
+ DDmaX_Next: Optional[DData] = Field(default=None, validation_alias="DDmaX.Next")
16
+ DDmaX_Nut: Optional[DData] = Field(default=None, validation_alias="DDmaX.Nut")
17
+ DDmaX_Pro: Optional[DData] = Field(default=None, validation_alias="DDmaX.Pro")
18
+ Oldschool: Optional[DData] = Field(default=None)
19
+ Race: Optional[DData] = None
20
+ Solo: Optional[DData] = None
21
+ total: Optional[DData] = None
@@ -5,7 +5,9 @@ from typing import Optional, Any
5
5
 
6
6
  from pydantic import BaseModel, Field
7
7
 
8
- rm_list = ["DD-Persian", "/vDQMHSss8W", '']
8
+ from .base import DDType
9
+
10
+ rm_list = ["DD-Persian", "/vDQMHSss8W", ""]
9
11
 
10
12
 
11
13
  class DPoints(BaseModel):
@@ -94,22 +96,6 @@ class DData(BaseModel):
94
96
  maps: Optional[dict] = Field(default=None)
95
97
 
96
98
 
97
- class DDType(BaseModel):
98
- Novice: Optional[DData] = None
99
- Moderate: Optional[DData] = None
100
- Brutal: Optional[DData] = None
101
- Insane: Optional[DData] = None
102
- Dummy: Optional[DData] = None
103
- DDmaX_Easy: Optional[DData] = Field(default=None, validation_alias='DDmaX.Easy')
104
- DDmaX_Next: Optional[DData] = Field(default=None, validation_alias='DDmaX.Next')
105
- DDmaX_Nut: Optional[DData] = Field(default=None, validation_alias='DDmaX.Nut')
106
- DDmaX_Pro: Optional[DData] = Field(default=None, validation_alias='DDmaX.Pro')
107
- Oldschool: Optional[DData] = Field(default=None)
108
- Race: Optional[DData] = None
109
- Solo: Optional[DData] = None
110
- total: Optional[DData] = None
111
-
112
-
113
99
  class Activity(BaseModel):
114
100
  date: str
115
101
  hours_played: int
@@ -220,7 +206,7 @@ class Master(BaseModel):
220
206
  client.clan
221
207
  for server in self.servers
222
208
  for client in server.info.clients
223
- if client != ''
209
+ if client != ""
224
210
  )
225
211
 
226
212
  for i in remove_list:
@@ -4,7 +4,7 @@ from typing import Optional
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
7
- rm_list = ["DD-Persian", "/vDQMHSss8W", '']
7
+ from .base import DDType
8
8
 
9
9
 
10
10
  class PData(BaseModel):
@@ -12,22 +12,6 @@ class PData(BaseModel):
12
12
  points: int
13
13
 
14
14
 
15
- class PPoints(BaseModel):
16
- Novice: Optional[PData] = None
17
- Moderate: Optional[PData] = None
18
- Brutal: Optional[PData] = None
19
- Insane: Optional[PData] = None
20
- Dummy: Optional[PData] = None
21
- DDmaX_Easy: Optional[PData] = Field(default=None, validation_alias='DDmaX.Easy')
22
- DDmaX_Next: Optional[PData] = Field(default=None, validation_alias='DDmaX.Next')
23
- DDmaX_Nut: Optional[PData] = Field(default=None, validation_alias='DDmaX.Nut')
24
- DDmaX_Pro: Optional[PData] = Field(default=None, validation_alias='DDmaX.Pro')
25
- Oldschool: Optional[PData] = None
26
- Race: Optional[PData] = None
27
- Solo: Optional[PData] = None
28
- total: Optional[PData] = None
29
-
30
-
31
15
  class PointG(BaseModel):
32
16
  date: str
33
17
  points: int
@@ -117,9 +101,9 @@ class Points(BaseModel):
117
101
  weekly_points: Optional[PData] = None
118
102
  monthly_points: Optional[PData] = None
119
103
  yearly_points: Optional[PData] = None
120
- points: PPoints
121
- rank_points: PPoints
122
- team_points: PPoints
104
+ points: DDType
105
+ rank_points: DDType
106
+ team_points: DDType
123
107
 
124
108
 
125
109
  class RecentActivity(BaseModel):
@@ -0,0 +1,131 @@
1
+ # Status.tw
2
+ from datetime import datetime
3
+ from enum import StrEnum
4
+ from typing import Optional
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class ChartEnum(StrEnum):
10
+ day = "day"
11
+ week = "week"
12
+ month = "month"
13
+
14
+
15
+ class DataTw(BaseModel):
16
+ name: str
17
+ created_at: datetime = Field(serialization_alias="createdAt")
18
+
19
+
20
+ class VersionTw(BaseModel):
21
+ version: str
22
+ created_at: datetime = Field(serialization_alias="createdAt")
23
+
24
+
25
+ class CountryTw(BaseModel):
26
+ identifier: str
27
+ code: int
28
+ icon_url: str = Field(serialization_alias="iconUrl")
29
+
30
+
31
+ class ClientTw(BaseModel):
32
+ name: str
33
+ country: CountryTw
34
+ score: int
35
+ is_player: bool = Field(serialization_alias="isPlayer")
36
+ is_afk: bool = Field(serialization_alias="isAfk")
37
+ team: int
38
+ created_at: datetime = Field(serialization_alias="createdAt")
39
+ clan: DataTw | None
40
+ server: "ServerTw" = None
41
+
42
+
43
+ class ServerTw(BaseModel):
44
+ ip: str
45
+ port: int
46
+ name: str
47
+ num_clients: int = Field(serialization_alias="numClients")
48
+ num_players: int = Field(serialization_alias="numPlayers")
49
+ max_clients: int = Field(serialization_alias="maxClients")
50
+ max_players: int = Field(serialization_alias="maxPlayers")
51
+ has_password: bool = Field(serialization_alias="hasPassword")
52
+ supports6: bool
53
+ supports7: bool
54
+ created_at: datetime = Field(serialization_alias="createdAt")
55
+ relevance_score: int = Field(serialization_alias="relevanceScore")
56
+ client_score_kind: str | None = Field(serialization_alias="clientScoreKind")
57
+ logo_url: str = Field(serialization_alias="logoUrl")
58
+ map: DataTw
59
+ website: Optional[str] = None
60
+ discord_invite: Optional[str] = Field(None, serialization_alias="discordInvite")
61
+ description: Optional[str] = None
62
+ game_type: DataTw = Field(serialization_alias="gameType")
63
+ version: VersionTw
64
+ clients: list[ClientTw]
65
+
66
+
67
+ class ServerTwOne(BaseModel):
68
+ ip: str
69
+ port: int
70
+ online: ServerTw
71
+
72
+
73
+ class Chart(BaseModel):
74
+ avg_players: float = Field(serialization_alias="avgPlayers")
75
+ max_players: int = Field(serialization_alias="maxPlayers")
76
+ min_players: int = Field(serialization_alias="minPlayers")
77
+ timestamp: datetime
78
+
79
+
80
+ class Charts(BaseModel):
81
+ charts: list[Chart]
82
+
83
+
84
+ class MasterTw(BaseModel):
85
+ servers: list[ServerTw]
86
+
87
+
88
+ class Info(BaseModel):
89
+ app: str
90
+ version: str
91
+
92
+
93
+ class BannedMasterData(BaseModel):
94
+ ip: str
95
+ is_active: bool = Field(serialization_alias="isActive")
96
+ reason: str | None
97
+ unban_date: datetime | None = Field(serialization_alias="unbanDate")
98
+ created_at: datetime = Field(serialization_alias="createdAt")
99
+
100
+
101
+ class BannedMaster(BaseModel):
102
+ servers: list[BannedMasterData]
103
+
104
+
105
+ class ListData(BaseModel):
106
+ name: str
107
+ created_at: datetime = Field(serialization_alias="createdAt")
108
+ servers: list[ServerTw]
109
+
110
+
111
+ class List(BaseModel):
112
+ data: list[ListData]
113
+
114
+
115
+ class ListPlData(BaseModel):
116
+ name: str
117
+ created_at: datetime = Field(serialization_alias="createdAt")
118
+ players: list[ClientTw]
119
+
120
+
121
+ class ListPl(BaseModel):
122
+ data: list[ListPlData]
123
+
124
+
125
+ class Stats(BaseModel):
126
+ num_players: int = Field(serialization_alias="numPlayers")
127
+ num_clans: int = Field(serialization_alias="numClans")
128
+ num_servers: int = Field(serialization_alias="numServers")
129
+ num_maps: int = Field(serialization_alias="numMaps")
130
+ num_game_types: int = Field(serialization_alias="numGameTypes")
131
+ num_versions: int = Field(serialization_alias="numVersions")
@@ -0,0 +1,3 @@
1
+ from typing import TypeVar
2
+
3
+ T = TypeVar("T")
@@ -1,22 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ddapi
3
- Version: 0.10.0
3
+ Version: 0.12.0
4
4
  Summary: DDnet api
5
5
  Home-page: https://github.com/ByFox213/ddapi
6
6
  Author: ByFox
7
- License: "MIT"
7
+ License: MIT
8
8
  Project-URL: Github, https://github.com/ByFox213/ddapi
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
9
  Requires-Python: >=3.8
13
10
  Description-Content-Type: text/markdown
14
11
  License-File: LICENSE
15
12
  Dynamic: author
16
- Dynamic: classifier
17
13
  Dynamic: description
18
14
  Dynamic: description-content-type
19
15
  Dynamic: home-page
16
+ Dynamic: license
20
17
  Dynamic: license-file
21
18
  Dynamic: project-url
22
19
  Dynamic: requires-python
@@ -42,28 +39,28 @@ DDnet
42
39
 
43
40
  ```python
44
41
  import asyncio
42
+
45
43
  from ddapi import DDnetApi, DDPlayer
46
44
 
47
45
 
48
46
  async def main():
49
- obj = DDnetApi()
50
- nickname = "Cor"
51
- user: DDPlayer = await obj.player(nickname)
52
- if user is None:
53
- return "Player not found"
54
-
55
- print(f"{user.player}: {user.points.points}")
56
- # Cor: 31473
57
- await obj.close() # Closing client Not necessary
58
- assert isinstance(user, DDPlayer)
47
+ async with DDnetApi() as obj:
48
+ user: DDPlayer = await obj.player("Cor")
49
+ if user is not None:
50
+ text = f"{user.player}: {user.points.points}/{user.points.total}"
51
+ percent = round(user.points.total / user.points.points * 100)
52
+ print(f"{text}({percent}%)")
53
+ # Cor: 32950/32950(100%)
54
+ else:
55
+ print("Player not found")
59
56
 
60
57
 
61
58
  asyncio.run(main())
62
59
  ```
63
60
 
64
61
  Tested on Python
65
- | 3.9 | 3.10 | 3.11 | 3.12 |
66
- |-----|------|------|------|
67
- | ? | ? | ✅ | ✅ |
62
+ | 3.10 | 3.11 | 3.12 |
63
+ |------|------|------|
64
+ | ✅ | ✅ | ✅ |
68
65
 
69
66
  [other examples](https://github.com/ByFox213/ddapi/tree/main/example)
@@ -5,11 +5,13 @@ setup.py
5
5
  ddapi/ddapi/__init__.py
6
6
  ddapi/ddapi/api.py
7
7
  ddapi/ddapi/main.py
8
+ ddapi/ddapi/types.py
8
9
  ddapi/ddapi.egg-info/PKG-INFO
9
10
  ddapi/ddapi.egg-info/SOURCES.txt
10
11
  ddapi/ddapi.egg-info/dependency_links.txt
11
12
  ddapi/ddapi.egg-info/top_level.txt
12
13
  ddapi/ddapi/scheme/__init__.py
14
+ ddapi/ddapi/scheme/base.py
13
15
  ddapi/ddapi/scheme/ddnet.py
14
16
  ddapi/ddapi/scheme/ddstats_tw.py
15
17
  ddapi/ddapi/scheme/status_tw.py
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = ddapi
3
- version = 0.10.0
3
+ version = 0.12.0
4
4
  author = ByFox
5
5
  description = DDnet api
6
6
  long_description = file: README.md
@@ -8,13 +8,13 @@ long_description_content_type = text/markdown
8
8
  url = https://github.com/ByFox213/ddapi
9
9
  project_urls =
10
10
  github = https://github.com/ByFox213/ddapi
11
- license = "MIT"
11
+ license_files = LICENSE
12
12
 
13
13
  [options]
14
14
  package_dir =
15
15
  = ddapi
16
16
  packages = find:
17
- python_requires = >=3.8
17
+ python_requires = >=3.9
18
18
 
19
19
  [options.packages.find]
20
20
  where = ddapi
@@ -5,20 +5,16 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="ddapi",
8
- version="0.10.0",
8
+ version="0.12.0",
9
9
  author="ByFox",
10
10
  description="DDnet api",
11
11
  long_description=long_description,
12
12
  long_description_content_type="text/markdown",
13
13
  url="https://github.com/ByFox213/ddapi",
14
+ license="MIT",
14
15
  project_urls={
15
16
  "Github": "https://github.com/ByFox213/ddapi"
16
17
  },
17
- classifiers=[
18
- "Programming Language :: Python :: 3",
19
- "License :: OSI Approved :: MIT License",
20
- "Operating System :: OS Independent",
21
- ],
22
18
  package_dir={"": "ddapi"},
23
19
  packages=setuptools.find_packages(where="ddapi"),
24
20
  python_requires=">=3.8"
ddapi-0.10.0/README.md DELETED
@@ -1,45 +0,0 @@
1
- ddapi is an api from the ddnet and qwik website
2
-
3
- ## Installation
4
-
5
- ```bash
6
- pip install ddapi
7
- ```
8
-
9
- or
10
-
11
- ```bash
12
- pip install git+https://github.com/ByFox213/ddapi
13
- ```
14
-
15
- ## Usage/Examples
16
-
17
- DDnet
18
-
19
- ```python
20
- import asyncio
21
- from ddapi import DDnetApi, DDPlayer
22
-
23
-
24
- async def main():
25
- obj = DDnetApi()
26
- nickname = "Cor"
27
- user: DDPlayer = await obj.player(nickname)
28
- if user is None:
29
- return "Player not found"
30
-
31
- print(f"{user.player}: {user.points.points}")
32
- # Cor: 31473
33
- await obj.close() # Closing client Not necessary
34
- assert isinstance(user, DDPlayer)
35
-
36
-
37
- asyncio.run(main())
38
- ```
39
-
40
- Tested on Python
41
- | 3.9 | 3.10 | 3.11 | 3.12 |
42
- |-----|------|------|------|
43
- | ? | ? | ✅ | ✅ |
44
-
45
- [other examples](https://github.com/ByFox213/ddapi/tree/main/example)
@@ -1,3 +0,0 @@
1
- from .ddnet import *
2
- from .ddstats_tw import *
3
- from .status_tw import *
@@ -1,131 +0,0 @@
1
- # Status.tw
2
- from datetime import datetime
3
- from enum import StrEnum
4
- from typing import Optional
5
-
6
- from pydantic import BaseModel
7
-
8
-
9
- class ChartEnum(StrEnum):
10
- day = "day"
11
- week = "week"
12
- month = "month"
13
-
14
-
15
- class DataTw(BaseModel):
16
- name: str
17
- createdAt: datetime
18
-
19
-
20
- class VersionTw(BaseModel):
21
- version: str
22
- createdAt: datetime
23
-
24
-
25
- class CountryTw(BaseModel):
26
- identifier: str
27
- code: int
28
- iconUrl: str
29
-
30
-
31
- class ClientTw(BaseModel):
32
- name: str
33
- country: CountryTw
34
- score: int
35
- isPlayer: bool
36
- isAfk: bool
37
- team: int
38
- createdAt: datetime
39
- clan: DataTw | None
40
- server: "ServerTw" = None
41
-
42
-
43
- class ServerTw(BaseModel):
44
- ip: str
45
- port: int
46
- name: str
47
- numClients: int
48
- numPlayers: int
49
- maxClients: int
50
- maxPlayers: int
51
- hasPassword: bool
52
- supports6: bool
53
- supports7: bool
54
- createdAt: datetime
55
- relevanceScore: int
56
- clientScoreKind: str | None
57
- logoUrl: str
58
- map: DataTw
59
- website: Optional[str] = None
60
- discordInvite: Optional[str] = None
61
- description: Optional[str] = None
62
- gameType: DataTw
63
- version: VersionTw
64
- clients: list[ClientTw]
65
-
66
-
67
- class ServerTwOne(BaseModel):
68
- ip: str
69
- port: int
70
- online: ServerTw
71
-
72
-
73
- class Chart(BaseModel):
74
- avgPlayers: float
75
- maxPlayers: int
76
- minPlayers: int
77
- timestamp: datetime
78
-
79
-
80
- class Charts(BaseModel):
81
- charts: list[Chart]
82
-
83
-
84
- class MasterTw(BaseModel):
85
- servers: list[ServerTw]
86
-
87
-
88
- class Info(BaseModel):
89
- app: str
90
- version: str
91
-
92
-
93
- class BannedMasterData(BaseModel):
94
- ip: str
95
- isActive: bool
96
- reason: str | None
97
- unbanDate: datetime | None
98
- createdAt: datetime
99
-
100
-
101
- class BannedMaster(BaseModel):
102
- servers: list[BannedMasterData]
103
-
104
-
105
- class ListData(BaseModel):
106
- name: str
107
- createdAt: datetime
108
- servers: list[ServerTw]
109
-
110
-
111
- class List(BaseModel):
112
- data: list[ListData]
113
-
114
-
115
- class ListPlData(BaseModel):
116
- name: str
117
- createdAt: datetime
118
- players: list[ClientTw]
119
-
120
-
121
- class ListPl(BaseModel):
122
- data: list[ListPlData]
123
-
124
-
125
- class Stats(BaseModel):
126
- numPlayers: int
127
- numClans: int
128
- numServers: int
129
- numMaps: int
130
- numGameTypes: int
131
- numVersions: int
File without changes