nsarchive 2.0.0b2__tar.gz → 3.0.0a2__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.
- nsarchive-3.0.0a2/PKG-INFO +19 -0
- nsarchive-3.0.0a2/README.md +3 -0
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/nsarchive/__init__.py +2 -5
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/nsarchive/cls/archives.py +24 -7
- nsarchive-3.0.0a2/nsarchive/cls/base.py +237 -0
- nsarchive-3.0.0a2/nsarchive/cls/economy.py +100 -0
- nsarchive-3.0.0a2/nsarchive/cls/entities.py +392 -0
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/nsarchive/cls/republic.py +40 -2
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/nsarchive/instances/_economy.py +85 -24
- nsarchive-3.0.0a2/nsarchive/instances/_entities.py +230 -0
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/nsarchive/instances/_republic.py +64 -20
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/pyproject.toml +1 -2
- nsarchive-2.0.0b2/PKG-INFO +0 -177
- nsarchive-2.0.0b2/README.md +0 -160
- nsarchive-2.0.0b2/nsarchive/cls/base.py +0 -179
- nsarchive-2.0.0b2/nsarchive/cls/economy.py +0 -44
- nsarchive-2.0.0b2/nsarchive/cls/entities.py +0 -180
- nsarchive-2.0.0b2/nsarchive/cls/exceptions.py +0 -25
- nsarchive-2.0.0b2/nsarchive/instances/_entities.py +0 -314
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/LICENSE +0 -0
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/nsarchive/assets/default_avatar.png +0 -0
- {nsarchive-2.0.0b2 → nsarchive-3.0.0a2}/nsarchive/utils.py +0 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: nsarchive
|
3
|
+
Version: 3.0.0a2
|
4
|
+
Summary: API-wrapper pour récupérer des données liées à Nation
|
5
|
+
License: GPL-3.0
|
6
|
+
Author: happex
|
7
|
+
Author-email: 110610727+okayhappex@users.noreply.github.com
|
8
|
+
Requires-Python: >=3.10,<4.0
|
9
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
14
|
+
Requires-Dist: pillow (>=10.4,<11.0)
|
15
|
+
Description-Content-Type: text/markdown
|
16
|
+
|
17
|
+
# NSArchive
|
18
|
+
|
19
|
+
Documentation pas disponible pour l'instant
|
@@ -1,27 +1,24 @@
|
|
1
1
|
"""
|
2
2
|
nsarchive - API-wrapper pour récupérer des données liées à Nation.
|
3
3
|
|
4
|
-
Version:
|
4
|
+
Version: 3.0.0a2
|
5
5
|
License: GPL-3.0
|
6
6
|
Auteur : happex <110610727+okayhappex@users.noreply.github.com>
|
7
7
|
|
8
8
|
Dependencies:
|
9
9
|
- Python ^3.10
|
10
|
-
- supabase ^2.9.1
|
11
10
|
- pillow ^10.4
|
12
11
|
|
13
12
|
Le fichier README.md fournit des détails supplémentaires pour l'utilisation.
|
14
13
|
"""
|
15
14
|
|
16
|
-
# Import des types
|
15
|
+
# Import des types
|
17
16
|
from .cls.base import NSID
|
18
17
|
from .cls.archives import *
|
19
18
|
from .cls.entities import *
|
20
19
|
from .cls.republic import *
|
21
20
|
from .cls.economy import *
|
22
21
|
|
23
|
-
from .cls.exceptions import *
|
24
|
-
|
25
22
|
# Import des instances
|
26
23
|
from .instances._economy import EconomyInstance
|
27
24
|
from .instances._entities import EntityInstance
|
@@ -3,7 +3,24 @@ import time
|
|
3
3
|
from .base import *
|
4
4
|
|
5
5
|
class Archive:
|
6
|
-
def __init__(self, author:
|
6
|
+
def __init__(self, author: NSID = '0', target: NSID = '0'):
|
7
|
+
"""
|
8
|
+
Classe de référence pour toutes les archives.
|
9
|
+
|
10
|
+
## Attributs de base
|
11
|
+
- date: `int`\n
|
12
|
+
Date (timestamp) de l'exécution de l'archive
|
13
|
+
- id: `NSID`\n
|
14
|
+
Clé d'identification des archives (basée sur la date)
|
15
|
+
- author: `NSID`\n
|
16
|
+
ID de l'auteur de l'action
|
17
|
+
- target: `NSID`:
|
18
|
+
ID de la cible de l'action
|
19
|
+
- action: `str`:\n
|
20
|
+
Action effectuée
|
21
|
+
- details: `dict`\n
|
22
|
+
Ensemble de détails que les différents bots peuvent utiliser
|
23
|
+
"""
|
7
24
|
self.date: int = round(time.time())
|
8
25
|
|
9
26
|
self.id: NSID = NSID(self.date)
|
@@ -19,7 +36,7 @@ class Archive:
|
|
19
36
|
# Entities
|
20
37
|
|
21
38
|
class Sanction(Archive):
|
22
|
-
def __init__(self, author:
|
39
|
+
def __init__(self, author: NSID, target: NSID) -> None:
|
23
40
|
super().__init__(author, target)
|
24
41
|
|
25
42
|
self.details: dict = {
|
@@ -29,7 +46,7 @@ class Sanction(Archive):
|
|
29
46
|
}
|
30
47
|
|
31
48
|
class Report(Archive):
|
32
|
-
def __init__(self, author:
|
49
|
+
def __init__(self, author: NSID, target: NSID) -> None:
|
33
50
|
super().__init__(author, target)
|
34
51
|
|
35
52
|
self.details: dict = {
|
@@ -41,7 +58,7 @@ class Report(Archive):
|
|
41
58
|
# Community
|
42
59
|
|
43
60
|
class Election(Archive):
|
44
|
-
def __init__(self, author:
|
61
|
+
def __init__(self, author: NSID, target: NSID, position: str) -> None:
|
45
62
|
super().__init__(author, target)
|
46
63
|
|
47
64
|
self.details = {
|
@@ -51,7 +68,7 @@ class Election(Archive):
|
|
51
68
|
}
|
52
69
|
|
53
70
|
class Promotion(Archive):
|
54
|
-
def __init__(self, author:
|
71
|
+
def __init__(self, author: NSID, target: NSID, position: str) -> None:
|
55
72
|
super().__init__(author, target)
|
56
73
|
|
57
74
|
self.details = {
|
@@ -59,14 +76,14 @@ class Promotion(Archive):
|
|
59
76
|
}
|
60
77
|
|
61
78
|
class Demotion(Archive):
|
62
|
-
def __init__(self, author:
|
79
|
+
def __init__(self, author: NSID, target: NSID) -> None:
|
63
80
|
super().__init__(author, target)
|
64
81
|
|
65
82
|
|
66
83
|
# Bank
|
67
84
|
|
68
85
|
class Transaction(Archive):
|
69
|
-
def __init__(self, author:
|
86
|
+
def __init__(self, author: NSID, target: NSID) -> None:
|
70
87
|
super().__init__(author, target)
|
71
88
|
|
72
89
|
self.details = {
|
@@ -0,0 +1,237 @@
|
|
1
|
+
import io
|
2
|
+
import json
|
3
|
+
import requests
|
4
|
+
import typing
|
5
|
+
import warnings
|
6
|
+
|
7
|
+
class NSID(str):
|
8
|
+
"""
|
9
|
+
Nation Server ID
|
10
|
+
|
11
|
+
ID unique et universel pour l'ensemble des entités et évènements. Il prend les `int`, les `str` et les autres instances `NSID` pour les convertir en un identifiant hexadécimal.
|
12
|
+
"""
|
13
|
+
unknown = "0"
|
14
|
+
admin = "1"
|
15
|
+
gov = "2"
|
16
|
+
court = "3"
|
17
|
+
assembly = "4"
|
18
|
+
office = "5"
|
19
|
+
hexabank = "6"
|
20
|
+
archives = "7"
|
21
|
+
|
22
|
+
maintenance_com = "101"
|
23
|
+
audiovisual_dept = "102"
|
24
|
+
interior_dept = "103"
|
25
|
+
justice_dept = "104"
|
26
|
+
egalitary_com = "105"
|
27
|
+
antifraud_dept = "106"
|
28
|
+
|
29
|
+
def __new__(cls, value):
|
30
|
+
if type(value) == int:
|
31
|
+
value = hex(value)
|
32
|
+
elif type(value) in (str, NSID):
|
33
|
+
value = hex(int(value, 16))
|
34
|
+
else:
|
35
|
+
raise TypeError(f"<{value}> is not NSID serializable")
|
36
|
+
|
37
|
+
if value.startswith("0x"):
|
38
|
+
value = value[2:]
|
39
|
+
|
40
|
+
instance = super(NSID, cls).__new__(cls, value.upper())
|
41
|
+
return instance
|
42
|
+
|
43
|
+
class Instance:
|
44
|
+
"""
|
45
|
+
Instance qui servira de base à toutes les instances.
|
46
|
+
"""
|
47
|
+
|
48
|
+
def __init__(self, url: str, token: str = None):
|
49
|
+
self.url = url
|
50
|
+
self.token = token
|
51
|
+
|
52
|
+
self.default_headers = {
|
53
|
+
"Authorization": f"Bearer {self.token}",
|
54
|
+
"Content-Type": "application/json",
|
55
|
+
}
|
56
|
+
|
57
|
+
def request_token(self, username: str, password: str) -> str | None:
|
58
|
+
res = requests.post(f"{self.url}/auth/login", json = {
|
59
|
+
"username": username,
|
60
|
+
"password": password
|
61
|
+
})
|
62
|
+
|
63
|
+
if res.status_code == 200:
|
64
|
+
return res.json()["token"]
|
65
|
+
elif res.status_code in (401, 403):
|
66
|
+
raise PermissionError(res.json()['message'])
|
67
|
+
else:
|
68
|
+
raise Exception(f"Error {res.status_code}: {res.json()['message']}")
|
69
|
+
|
70
|
+
def _get_item(self, endpoint: str, body: dict = None, headers: dict = None) -> dict:
|
71
|
+
"""
|
72
|
+
Récupère des données JSON depuis l'API
|
73
|
+
|
74
|
+
## Paramètres
|
75
|
+
endpoint: `str`:
|
76
|
+
Endpoint de l'URL
|
77
|
+
headers: `dict` (optional)
|
78
|
+
Headers à envoyer
|
79
|
+
body: `dict` (optional)
|
80
|
+
Données à envoyer
|
81
|
+
|
82
|
+
## Renvoie
|
83
|
+
- `list` de tous les élements correspondants
|
84
|
+
- `None` si aucune donnée n'est trouvée
|
85
|
+
"""
|
86
|
+
|
87
|
+
if not headers:
|
88
|
+
headers = self.default_headers
|
89
|
+
|
90
|
+
res = requests.get(f"{self.url}/{endpoint}", headers = headers, json = body, timeout = 5)
|
91
|
+
|
92
|
+
if 200 <= res.status_code < 300:
|
93
|
+
return res.json()
|
94
|
+
elif res.status_code == 404:
|
95
|
+
return
|
96
|
+
elif res.status_code in (403, 401):
|
97
|
+
raise PermissionError(res.json()['message'])
|
98
|
+
else:
|
99
|
+
raise Exception(f"Error {res.status_code}: {res.json()['message']}")
|
100
|
+
|
101
|
+
def _get_by_ID(self, _class: str, id: NSID) -> dict:
|
102
|
+
_data = self._get_item(f"/model/{_class}/{id}")
|
103
|
+
|
104
|
+
return _data
|
105
|
+
|
106
|
+
def _put_in_db(self, endpoint: str, body: dict, headers: dict = None, use_PUT: bool = False) -> None:
|
107
|
+
"""
|
108
|
+
Publie des données JSON dans une table nation-db.
|
109
|
+
|
110
|
+
## Paramètres
|
111
|
+
endpoint: `str`
|
112
|
+
Endpoint de l'URL
|
113
|
+
body: `dict`
|
114
|
+
Données à envoyer
|
115
|
+
headers: `dict` (optionnel)
|
116
|
+
Headers à envoyer
|
117
|
+
"""
|
118
|
+
|
119
|
+
if not headers:
|
120
|
+
headers = headers
|
121
|
+
|
122
|
+
if use_PUT:
|
123
|
+
res = requests.put(f"{self.url}/{endpoint}", headers = headers, json = body)
|
124
|
+
else:
|
125
|
+
res = requests.post(f"{self.url}/{endpoint}", headers = headers, json = body)
|
126
|
+
|
127
|
+
if 200 <= res.status_code < 300:
|
128
|
+
return res.json()
|
129
|
+
else:
|
130
|
+
print(res.text)
|
131
|
+
res.raise_for_status()
|
132
|
+
|
133
|
+
def _delete(self, _class: str, ids: list[NSID]) -> None:
|
134
|
+
"""
|
135
|
+
Supprime des données JSON dans une table nation-db.
|
136
|
+
|
137
|
+
## Paramètres
|
138
|
+
_class: `str`
|
139
|
+
Classe des entités à supprimer
|
140
|
+
ids: `list[NSID]`
|
141
|
+
ID des entités à supprimer
|
142
|
+
"""
|
143
|
+
|
144
|
+
res = requests.post(f"{self.url}/delete_{_class}", json = { "ids": ids })
|
145
|
+
|
146
|
+
if 200 <= res.status_code < 300:
|
147
|
+
return res.json()
|
148
|
+
elif res.status_code in (403, 401):
|
149
|
+
raise PermissionError(res.json()['message'])
|
150
|
+
else:
|
151
|
+
raise Exception(f"Error {res.status_code}: {res.json()['message']}")
|
152
|
+
|
153
|
+
def _delete_by_ID(self, _class: str, id: NSID):
|
154
|
+
warnings.showwarning("Method '_delete_by_id' is deprecated. Use '_delete' instead.")
|
155
|
+
self._delete(_class, id)
|
156
|
+
|
157
|
+
def fetch(self, _class: str, **query: typing.Any) -> list:
|
158
|
+
res = requests.get(f"{self.url}/fetch/{_class}", params = query)
|
159
|
+
|
160
|
+
if res.status_code == 200:
|
161
|
+
matches = res.json()
|
162
|
+
elif res.status_code in (401, 403):
|
163
|
+
matches = []
|
164
|
+
else:
|
165
|
+
res.raise_for_status()
|
166
|
+
|
167
|
+
return matches
|
168
|
+
|
169
|
+
|
170
|
+
def _upload_file(self, bucket: str, name: str, data: bytes, overwrite: bool = False, headers: dict = None) -> dict:
|
171
|
+
"""
|
172
|
+
Envoie un fichier dans un bucket nation-db.
|
173
|
+
|
174
|
+
## Paramètres
|
175
|
+
bucket: `str`
|
176
|
+
Nom du bucket où le fichier sera stocké
|
177
|
+
name: `str`
|
178
|
+
Nom du fichier dans le drive
|
179
|
+
data: `bytes`
|
180
|
+
Données à uploader
|
181
|
+
overwrite: `bool` (optional)
|
182
|
+
Overwrite ou non
|
183
|
+
headers: `dict` (optional)
|
184
|
+
Headers à envoyer
|
185
|
+
|
186
|
+
## Renvoie
|
187
|
+
- `dict` contenant les informations de l'upload si réussi
|
188
|
+
- `None` en cas d'échec
|
189
|
+
"""
|
190
|
+
|
191
|
+
if not headers:
|
192
|
+
headers = self.default_headers
|
193
|
+
headers['Content-Type'] = 'image/png'
|
194
|
+
|
195
|
+
body = {
|
196
|
+
"name": name,
|
197
|
+
"overwrite": json.dumps(overwrite)
|
198
|
+
}
|
199
|
+
|
200
|
+
file = ("file", "image/png", data)
|
201
|
+
|
202
|
+
res = requests.put(f"{self.url}/upload_file/{bucket}", headers = headers, json = body, files = [ file ])
|
203
|
+
|
204
|
+
if res.status_code == 200:
|
205
|
+
return res.json()
|
206
|
+
elif res.status_code in (403, 401):
|
207
|
+
raise PermissionError(res.json()['message'])
|
208
|
+
elif res.status_code == 409:
|
209
|
+
raise FileExistsError(res.json()['message'])
|
210
|
+
else:
|
211
|
+
raise Exception(f"Error {res.status_code}: {res.json()['message']}")
|
212
|
+
|
213
|
+
def _download_from_storage(self, bucket: str, path: str, headers: dict = None) -> bytes:
|
214
|
+
"""
|
215
|
+
Télécharge un fichier depuis le stockage nation-db.
|
216
|
+
|
217
|
+
## Paramètres
|
218
|
+
bucket: `str`\n
|
219
|
+
Nom du bucket où il faut chercher le fichier
|
220
|
+
path: `str`\n
|
221
|
+
Chemin du fichier dans le bucket
|
222
|
+
|
223
|
+
## Renvoie
|
224
|
+
- Le fichier demandé en `bytes`
|
225
|
+
"""
|
226
|
+
|
227
|
+
if not headers:
|
228
|
+
headers = self.default_headers
|
229
|
+
|
230
|
+
res = requests.get(f"{self.url}/drive/{bucket}/{path}", headers = headers)
|
231
|
+
|
232
|
+
if res.status_code == 200:
|
233
|
+
return res.json()
|
234
|
+
elif res.status_code in (403, 401):
|
235
|
+
raise PermissionError(res.json()['message'])
|
236
|
+
else:
|
237
|
+
raise Exception(f"Error {res.status_code}: {res.json()['message']}")
|
@@ -0,0 +1,100 @@
|
|
1
|
+
from .base import NSID
|
2
|
+
|
3
|
+
class BankAccount:
|
4
|
+
"""
|
5
|
+
Compte en banque d'une entité, individuelle ou collective.
|
6
|
+
|
7
|
+
## Attributs
|
8
|
+
- id: `NSID`\n
|
9
|
+
Identifiant du compte
|
10
|
+
- owner: `NSID`\n
|
11
|
+
Identifiant du titulaire du compte
|
12
|
+
- amount: `int`\n
|
13
|
+
Somme d'argent totale sur le compte
|
14
|
+
- frozen: `bool`\n
|
15
|
+
État gelé ou non du compte
|
16
|
+
- bank: `NSID`\n
|
17
|
+
Identifiant de la banque qui détient le compte
|
18
|
+
- income: `int`\n
|
19
|
+
Somme entrante sur le compte depuis la dernière réinitialisation (tous les ~ 28 jours)
|
20
|
+
"""
|
21
|
+
|
22
|
+
def __init__(self, id: NSID) -> None:
|
23
|
+
self.id: NSID = NSID(id)
|
24
|
+
self.owner: NSID = NSID(0)
|
25
|
+
self.amount: int = 0
|
26
|
+
self.frozen: bool = False
|
27
|
+
self.bank: NSID = NSID("6")
|
28
|
+
|
29
|
+
self.income: int = 0
|
30
|
+
|
31
|
+
class Item:
|
32
|
+
"""
|
33
|
+
Article d'inventaire qui peut circuler sur le serveur
|
34
|
+
|
35
|
+
## Attributs
|
36
|
+
- id: `NSID`\n
|
37
|
+
Identifiant de l'objet
|
38
|
+
- title: `str`\n
|
39
|
+
Nom de l'objet
|
40
|
+
- emoji: `str`\n
|
41
|
+
Emoji lié à l'objet
|
42
|
+
"""
|
43
|
+
|
44
|
+
def __init__(self, id: NSID) -> None:
|
45
|
+
self.id: NSID = NSID(id)
|
46
|
+
self.title: str = "Unknown Object"
|
47
|
+
self.emoji: str = ":light_bulb:"
|
48
|
+
|
49
|
+
class Inventory:
|
50
|
+
"""
|
51
|
+
Inventaire d'un membre
|
52
|
+
|
53
|
+
## Attributs
|
54
|
+
- owner_id: `NSID`\n
|
55
|
+
ID du propriétaire de l'inventaire
|
56
|
+
- objects: `dict[str, NSID]`\n
|
57
|
+
Collection d'objets et leur quantité
|
58
|
+
"""
|
59
|
+
|
60
|
+
def __init__(self, owner_id: NSID) -> None:
|
61
|
+
self.owner_id: NSID = NSID(owner_id)
|
62
|
+
self.objects: dict[str, NSID] = {}
|
63
|
+
|
64
|
+
def append(self, item: Item, quantity: int = 1):
|
65
|
+
if item.id in self.objects.keys():
|
66
|
+
self.objects[item.id] += quantity
|
67
|
+
else:
|
68
|
+
self.objects[item.id] = quantity
|
69
|
+
|
70
|
+
def throw(self, item: Item, quantity: int = 1):
|
71
|
+
if item.id in self.objects.keys():
|
72
|
+
if self.objects[item.id] > quantity:
|
73
|
+
self.objects[item.id] -= quantity
|
74
|
+
else:
|
75
|
+
self.objects[item.id] = 0
|
76
|
+
|
77
|
+
class Sale:
|
78
|
+
"""
|
79
|
+
Vente mettant en jeu un objet
|
80
|
+
|
81
|
+
## Attributs
|
82
|
+
- id: `NSID`\n
|
83
|
+
Identifiant de la vente
|
84
|
+
- item: `NSID`\n
|
85
|
+
Identifiant de l'objet mis en vente
|
86
|
+
- quantity: `int`\n
|
87
|
+
Quantité d'objets mis en vente
|
88
|
+
- price: `int`\n
|
89
|
+
Prix total du lot
|
90
|
+
- seller_id: `NSID`\n
|
91
|
+
Identifiant du vendeur
|
92
|
+
"""
|
93
|
+
|
94
|
+
def __init__(self, id: NSID, item: Item) -> None:
|
95
|
+
self.id: NSID = NSID(id)
|
96
|
+
self.item: NSID = NSID(item.id)
|
97
|
+
self.quantity: int = 1
|
98
|
+
|
99
|
+
self.price: int = 0
|
100
|
+
self.seller_id: NSID = NSID('0')
|