nsarchive 2.0.0a6__py3-none-any.whl → 2.0.0a8__py3-none-any.whl

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/cls/base.py CHANGED
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import typing
2
3
 
3
4
  from supabase import Client
@@ -37,7 +38,7 @@ class Instance:
37
38
  def __init__(self, client: Client):
38
39
  self.db = client
39
40
 
40
- def _select_from_db(self, table: str, key: str, value: str) -> list:
41
+ def _select_from_db(self, table: str, key: str = None, value: str = None) -> list:
41
42
  """
42
43
  Récupère des données JSON d'une table Supabase en fonction de l'ID.
43
44
 
@@ -54,7 +55,10 @@ class Instance:
54
55
  - `None` si aucune donnée n'est trouvée
55
56
  """
56
57
 
57
- res = self.db.from_(table).select("*").eq(key, value).execute()
58
+ if key and value:
59
+ res = self.db.from_(table).select("*").eq(key, value).execute()
60
+ else:
61
+ res = self.db.from_(table).select("*").execute()
58
62
 
59
63
  if res.data:
60
64
  return res.data
@@ -117,9 +121,59 @@ class Instance:
117
121
  if entity is not None:
118
122
  matches.append(entity)
119
123
 
120
- if not matches or len(matches) != len(query):
124
+ if query == {}:
125
+ matches = [ self._select_from_db(table) ]
126
+
127
+ if not matches or (len(matches) != len(query) and query != {}):
121
128
  return []
122
129
 
123
130
  _res = [ item for item in matches[0] if all(item in match for match in matches[1:]) ]
124
131
 
125
132
  return _res
133
+
134
+ def _upload_to_storage(self, bucket: str, data: bytes, path: str, overwrite: bool = False, options: dict = {'content-type': 'image/png'}) -> dict:
135
+ """
136
+ Envoie un fichier dans un bucket Supabase.
137
+
138
+ ## Paramètres
139
+ bucket: `str`\n
140
+ Nom du bucket où le fichier sera stocké
141
+ data: `bytes`\n
142
+ Données à uploader
143
+ path: `str`\n
144
+ Chemin dans le bucket où le fichier sera stocké
145
+
146
+ ## Renvoie
147
+ - `dict` contenant les informations de l'upload si réussi
148
+ - `None` en cas d'échec
149
+ """
150
+
151
+ options["upsert"] = json.dumps(overwrite)
152
+
153
+ if len(data) > 5 * 1000 ** 3:
154
+ raise ValueError("La limite d'un fichier à upload est de 1Mo")
155
+
156
+ res = self.db.storage.from_(bucket).upload(path, data, options)
157
+
158
+ if res.json().get("error"):
159
+ print("Erreur lors de l'upload:", res["error"])
160
+
161
+ return res
162
+
163
+ def _download_from_storage(self, bucket: str, path: str) -> bytes:
164
+ """
165
+ Télécharge un fichier depuis le stockage Supabase.
166
+
167
+ ## Paramètres
168
+ bucket: `str`\n
169
+ Nom du bucket où il faut chercher le fichier
170
+ path: `str`\n
171
+ Chemin du fichier dans le bucket
172
+
173
+ ## Renvoie
174
+ - Le fichier demandé en `bytes`
175
+ """
176
+
177
+ res = self.db.storage.from_(bucket).download(path)
178
+
179
+ return res
nsarchive/cls/entities.py CHANGED
@@ -3,7 +3,7 @@ import time
3
3
  from .exceptions import *
4
4
  from .base import NSID
5
5
 
6
- from ..utils import assets
6
+ from .. import utils
7
7
 
8
8
  class PositionPermissions:
9
9
  """
@@ -38,6 +38,9 @@ class Position:
38
38
  self.id = id
39
39
  self.permissions: PositionPermissions = PositionPermissions()
40
40
 
41
+ def __repr__(self):
42
+ return self.id
43
+
41
44
  class Entity:
42
45
  def __init__(self, id: str | NSID) -> None:
43
46
  self.id: NSID = NSID(id) # ID hexadécimal de l'entité (ou nom dans le cas de l'entreprise)
@@ -52,7 +55,7 @@ class Entity:
52
55
 
53
56
  self.name = new_name
54
57
 
55
- def set_position(self, position: str) -> None:
58
+ def set_position(self, position: Position) -> None:
56
59
  self.position = position
57
60
 
58
61
  def add_link(self, key: str, value: str | int) -> None:
@@ -135,7 +138,7 @@ class Organization(Entity):
135
138
  super().__init__(NSID(id))
136
139
 
137
140
  self.owner: Entity
138
- self.avatar: bytes = assets.open('default_avatar.png')
141
+ self.avatar: bytes = utils.open_asset('default_avatar.png')
139
142
 
140
143
  self.certifications: dict = {}
141
144
  self.members: list[GroupMember] = []
@@ -244,7 +244,7 @@ class EconomyInstance(Instance):
244
244
  if type(archive) == Transaction:
245
245
  _data['_type'] = "transaction"
246
246
  else:
247
- _data['_type'] = "unknown"
247
+ _data['_type'] = "action"
248
248
 
249
249
  self._put_in_db('archives', _data)
250
250
 
@@ -85,11 +85,12 @@ class EntityInstance(Instance):
85
85
 
86
86
  entity.certifications = _data['certifications']
87
87
  entity.parts = _data['parts']
88
+ entity.avatar = self._download_from_storage('organizations', f"avatars/{entity.id}")
88
89
  else:
89
90
  entity = Entity(id)
90
91
 
91
92
  entity.name = _data['name']
92
- entity.position = _data['position'] # Métier si c'est un utilisateur, domaine professionnel si c'est un collectif
93
+ entity.position = self.get_position(_data['position']) # Métier si c'est un utilisateur, domaine professionnel si c'est un collectif
93
94
  entity.registerDate = _data['register_date']
94
95
 
95
96
  for key, value in _data.get('additional', {}).items():
@@ -114,7 +115,7 @@ class EntityInstance(Instance):
114
115
  _data = {
115
116
  'id': entity.id,
116
117
  'name': entity.name,
117
- 'position': entity.position,
118
+ 'position': entity.position.id,
118
119
  'register_date': entity.registerDate,
119
120
  'additional': {},
120
121
  }
@@ -136,7 +137,9 @@ class EntityInstance(Instance):
136
137
  'position': member.permission_level
137
138
  }
138
139
 
139
- _data['members'] += [_member]
140
+ _data['members'] += [_member]
141
+
142
+ self._upload_to_storage('organizations', entity.avatar, f'/avatars/{entity.id}')
140
143
  elif type(entity) == User:
141
144
  _data['xp'] = entity.xp
142
145
  _data['boosts'] = entity.boosts
@@ -155,7 +158,7 @@ class EntityInstance(Instance):
155
158
 
156
159
  self._delete_by_ID('individuals' if isinstance(entity, User) else 'organizations', NSID(entity.id))
157
160
 
158
- def fetch_entities(self, **query: dict) -> list[ Entity | User | Organization ]:
161
+ def fetch_entities(self, **query: typing.Any) -> list[ Entity | User | Organization ]:
159
162
  """
160
163
  Récupère une liste d'entités en fonction d'une requête.
161
164
 
@@ -167,8 +170,20 @@ class EntityInstance(Instance):
167
170
  - `list[Entity | User | Organization]`
168
171
  """
169
172
 
170
- _res = self.fetch('individuals', **query)
171
- _res.extend(self.fetch('organizations', **query))
173
+ if "_type" in query.keys():
174
+ if query["_type"] == "individual":
175
+ del query["_type"]
176
+ _res = self.fetch('individuals', **query)
177
+ elif query["_type"] == "organization":
178
+ del query["_type"]
179
+ _res = self.fetch('organizations', **query)
180
+ else:
181
+ del query["_type"]
182
+ _res = self.fetch('individuals', **query)
183
+ _res.extend(self.fetch('organizations', **query))
184
+ else:
185
+ _res = self.fetch('individuals', **query)
186
+ _res.extend(self.fetch('organizations', **query))
172
187
 
173
188
  return [ self.get_entity(NSID(entity['id'])) for entity in _res if entity is not None ]
174
189
 
@@ -186,7 +201,6 @@ class EntityInstance(Instance):
186
201
 
187
202
  id = NSID(id)
188
203
  groups = self.fetch_entities(_type = 'organization')
189
- groups.extend(self.fetch_entities(_type = 'organization', owner_id = id))
190
204
 
191
205
  for group in groups:
192
206
  if group is None:
@@ -247,7 +261,7 @@ class EntityInstance(Instance):
247
261
  elif type(archive) == Report:
248
262
  _data['_type'] = "report"
249
263
  else:
250
- _data['_type'] = "unknown"
264
+ _data['_type'] = "action"
251
265
 
252
266
  self._put_in_db('archives', _data)
253
267
 
@@ -14,8 +14,8 @@ class RepublicInstance(Instance):
14
14
  Gère les interactions avec les votes, les archives de la république, et les fonctionnaires.
15
15
 
16
16
  ## Informations
17
- - Résultats des votes: `.Vote | .ClosedVote`
18
- - Différentes institutions: `.Institutions | .Administration | .Government | .Assembly | .Court | .PoliceForces`
17
+ - Résultats des votes et procès: `.Vote | .Referendum | .Lawsuit`
18
+ - Différentes institutions: `.State | .Administration | .Government | .Assembly | .Court | .PoliceForces`
19
19
  - Occupants des différents rôles et historique de leurs actions: `.Official`
20
20
  """
21
21
 
@@ -35,7 +35,7 @@ class RepublicInstance(Instance):
35
35
  ID du vote.
36
36
 
37
37
  ## Renvoie
38
- - `.Vote | .ClosedVote`
38
+ - `.Vote | .Referendum | .Lawsuit`
39
39
  """
40
40
 
41
41
  id = NSID(id)
@@ -60,7 +60,7 @@ class RepublicInstance(Instance):
60
60
 
61
61
  return vote
62
62
 
63
- def save_vote(self, vote: Vote | Referendum) -> None:
63
+ def save_vote(self, vote: Vote | Referendum | Lawsuit) -> None:
64
64
  """Sauvegarde un vote dans la base de données."""
65
65
 
66
66
  vote.id = NSID(vote.id)
@@ -222,7 +222,7 @@ class RepublicInstance(Instance):
222
222
  elif type(archive) == Demotion:
223
223
  _data['_type'] = "demotion"
224
224
  else:
225
- _data['_type'] = "unknown"
225
+ _data['_type'] = "action"
226
226
 
227
227
  self._put_in_db('archives', _data)
228
228
  self._put_in_db('mandate', _data) # Ajouter les archives à celle du mandat actuel
nsarchive/utils.py ADDED
@@ -0,0 +1,26 @@
1
+ import io
2
+ import math
3
+ import os
4
+ from PIL import Image
5
+
6
+ def open_asset(path: str) -> bytes:
7
+ curr_dir = os.path.dirname(os.path.abspath(os.path.join(__file__)))
8
+ asset_path = os.path.join(curr_dir, 'assets', path)
9
+
10
+ image = Image.open(asset_path)
11
+ val = io.BytesIO()
12
+
13
+ image.save(val, format = 'PNG')
14
+
15
+ return val.getvalue()
16
+
17
+ def compress_image(data: bytes, _max: int = 1000 ** 2) -> bytes:
18
+ img = Image.open(io.BytesIO(data))
19
+ size = 2 * ( math.floor(math.sqrt(_max),) )
20
+
21
+ img.resize(size)
22
+
23
+ val = io.BytesIO()
24
+ img.save(val)
25
+
26
+ return val.getvalue()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nsarchive
3
- Version: 2.0.0a6
3
+ Version: 2.0.0a8
4
4
  Summary: API-wrapper pour récupérer des données liées à Nation
5
5
  License: GPL-3.0
6
6
  Author: happex
@@ -0,0 +1,16 @@
1
+ nsarchive/__init__.py,sha256=_hwIocDyD7R-4rS7ypca8jZex93H6mK-b9NpTpt-Rvo,724
2
+ nsarchive/assets/default_avatar.png,sha256=n-4vG_WPke8LvbY3ZU6oA-H-OtRoIu7woKnRq9DCIlI,51764
3
+ nsarchive/cls/archives.py,sha256=HHQhGKdnl7vD5zC8-bbXeQLhp8A98bBlneJTkztOmMg,2007
4
+ nsarchive/cls/base.py,sha256=7MXIsvJdBoWqUPcsQI22EFIx0pJKcx78WFOD1TrPbgg,5306
5
+ nsarchive/cls/economy.py,sha256=fnzmliHsUBEdu5RrrSkimpcgou_HFnivP_lmzLKCaDI,1360
6
+ nsarchive/cls/entities.py,sha256=hY4_cO-LtH69NMm8lK_INU8-qGmM5Qzmm0md3bNvoyU,6667
7
+ nsarchive/cls/exceptions.py,sha256=QN6Qn7cxTkGoC4lO50hBAq4gZCgo7scQvCkb-xKl6Xs,692
8
+ nsarchive/cls/republic.py,sha256=4amjvCS5BnrvEgbjjDx_tOit3TbOSCMTsns6ifceL_8,2464
9
+ nsarchive/instances/_economy.py,sha256=7p1Ofu17hhuN2RWVWxwA28EDlMP8sAueT3bCOVlvRsY,7444
10
+ nsarchive/instances/_entities.py,sha256=zWgaPH-ITCXHuGv1Ua4UNN1cui-_pv8ZMwRuygOHwlA,10469
11
+ nsarchive/instances/_republic.py,sha256=5-6XjPWNcR8sHxm1ipWlQXUIi-UKmfo2OHir9QSQvWM,10106
12
+ nsarchive/utils.py,sha256=qpQCZLlbVApOLtCI2ml54QwUld6K8fDxyBfwzofqXzw,610
13
+ nsarchive-2.0.0a8.dist-info/LICENSE,sha256=aFLFZg6LEJFpTlNQ8su3__jw4GfV-xWBmC1cePkKZVw,35802
14
+ nsarchive-2.0.0a8.dist-info/METADATA,sha256=ym4eE13jW1PAY7tUAccqVPcDvwgJi-J-s89e4NXTeQk,5697
15
+ nsarchive-2.0.0a8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
16
+ nsarchive-2.0.0a8.dist-info/RECORD,,
nsarchive/utils/assets.py DELETED
@@ -1,15 +0,0 @@
1
- import io
2
- import os
3
- from PIL import Image
4
-
5
- def open(path: str) -> bytes:
6
- curr_dir = os.path.dirname(os.path.abspath(os.path.join(__file__)))
7
- parent_dir = os.path.dirname(curr_dir)
8
- asset_path = os.path.join(parent_dir, 'assets', path)
9
-
10
- image = Image.open(asset_path)
11
- val = io.BytesIO()
12
-
13
- image.save(val, format = 'PNG')
14
-
15
- return val.getvalue()
@@ -1,16 +0,0 @@
1
- nsarchive/__init__.py,sha256=_hwIocDyD7R-4rS7ypca8jZex93H6mK-b9NpTpt-Rvo,724
2
- nsarchive/assets/default_avatar.png,sha256=n-4vG_WPke8LvbY3ZU6oA-H-OtRoIu7woKnRq9DCIlI,51764
3
- nsarchive/cls/archives.py,sha256=HHQhGKdnl7vD5zC8-bbXeQLhp8A98bBlneJTkztOmMg,2007
4
- nsarchive/cls/base.py,sha256=RWcpUDfo96BjsUR_G49c9mR80qZKGKD82RoZB2do1p8,3606
5
- nsarchive/cls/economy.py,sha256=fnzmliHsUBEdu5RrrSkimpcgou_HFnivP_lmzLKCaDI,1360
6
- nsarchive/cls/entities.py,sha256=hjqCtsQHQZrLFwR57d_n4FssJ53-jdniQMHUAJGuDPY,6612
7
- nsarchive/cls/exceptions.py,sha256=QN6Qn7cxTkGoC4lO50hBAq4gZCgo7scQvCkb-xKl6Xs,692
8
- nsarchive/cls/republic.py,sha256=4amjvCS5BnrvEgbjjDx_tOit3TbOSCMTsns6ifceL_8,2464
9
- nsarchive/instances/_economy.py,sha256=PjdqVJspZIuge5oqeJ_7fWrddfogH2yCEu0EgOhJv90,7445
10
- nsarchive/instances/_entities.py,sha256=VckXexRhsZRq4qLZuMWp74sB5gLeuR4sj8yXxijFI94,9814
11
- nsarchive/instances/_republic.py,sha256=sIaqz2lhmmjz3Y8l4iwY737JVCVt077OwP0-1dPsEaw,10071
12
- nsarchive/utils/assets.py,sha256=WGC03K1VZ5LwGzcVXbqphtGBZ_Vjso-1hmbIkpgL_X8,382
13
- nsarchive-2.0.0a6.dist-info/LICENSE,sha256=aFLFZg6LEJFpTlNQ8su3__jw4GfV-xWBmC1cePkKZVw,35802
14
- nsarchive-2.0.0a6.dist-info/METADATA,sha256=i4aiTtyC5fc5kr8PD7TOCtAfxJwfATw60Gim-t5xY9k,5697
15
- nsarchive-2.0.0a6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
16
- nsarchive-2.0.0a6.dist-info/RECORD,,