nsarchive 2.0.0a7__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 +57 -3
- nsarchive/cls/entities.py +6 -3
- nsarchive/instances/_entities.py +7 -5
- nsarchive/utils.py +26 -0
- {nsarchive-2.0.0a7.dist-info → nsarchive-2.0.0a8.dist-info}/METADATA +1 -1
- {nsarchive-2.0.0a7.dist-info → nsarchive-2.0.0a8.dist-info}/RECORD +8 -8
- nsarchive/utils/assets.py +0 -15
- {nsarchive-2.0.0a7.dist-info → nsarchive-2.0.0a8.dist-info}/LICENSE +0 -0
- {nsarchive-2.0.0a7.dist-info → nsarchive-2.0.0a8.dist-info}/WHEEL +0 -0
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
|
-
|
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
|
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 ..
|
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:
|
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 =
|
141
|
+
self.avatar: bytes = utils.open_asset('default_avatar.png')
|
139
142
|
|
140
143
|
self.certifications: dict = {}
|
141
144
|
self.members: list[GroupMember] = []
|
nsarchive/instances/_entities.py
CHANGED
@@ -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:
|
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
|
|
@@ -198,7 +201,6 @@ class EntityInstance(Instance):
|
|
198
201
|
|
199
202
|
id = NSID(id)
|
200
203
|
groups = self.fetch_entities(_type = 'organization')
|
201
|
-
groups.extend(self.fetch_entities(_type = 'organization', owner_id = id))
|
202
204
|
|
203
205
|
for group in groups:
|
204
206
|
if group is None:
|
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,16 +1,16 @@
|
|
1
1
|
nsarchive/__init__.py,sha256=_hwIocDyD7R-4rS7ypca8jZex93H6mK-b9NpTpt-Rvo,724
|
2
2
|
nsarchive/assets/default_avatar.png,sha256=n-4vG_WPke8LvbY3ZU6oA-H-OtRoIu7woKnRq9DCIlI,51764
|
3
3
|
nsarchive/cls/archives.py,sha256=HHQhGKdnl7vD5zC8-bbXeQLhp8A98bBlneJTkztOmMg,2007
|
4
|
-
nsarchive/cls/base.py,sha256=
|
4
|
+
nsarchive/cls/base.py,sha256=7MXIsvJdBoWqUPcsQI22EFIx0pJKcx78WFOD1TrPbgg,5306
|
5
5
|
nsarchive/cls/economy.py,sha256=fnzmliHsUBEdu5RrrSkimpcgou_HFnivP_lmzLKCaDI,1360
|
6
|
-
nsarchive/cls/entities.py,sha256=
|
6
|
+
nsarchive/cls/entities.py,sha256=hY4_cO-LtH69NMm8lK_INU8-qGmM5Qzmm0md3bNvoyU,6667
|
7
7
|
nsarchive/cls/exceptions.py,sha256=QN6Qn7cxTkGoC4lO50hBAq4gZCgo7scQvCkb-xKl6Xs,692
|
8
8
|
nsarchive/cls/republic.py,sha256=4amjvCS5BnrvEgbjjDx_tOit3TbOSCMTsns6ifceL_8,2464
|
9
9
|
nsarchive/instances/_economy.py,sha256=7p1Ofu17hhuN2RWVWxwA28EDlMP8sAueT3bCOVlvRsY,7444
|
10
|
-
nsarchive/instances/_entities.py,sha256=
|
10
|
+
nsarchive/instances/_entities.py,sha256=zWgaPH-ITCXHuGv1Ua4UNN1cui-_pv8ZMwRuygOHwlA,10469
|
11
11
|
nsarchive/instances/_republic.py,sha256=5-6XjPWNcR8sHxm1ipWlQXUIi-UKmfo2OHir9QSQvWM,10106
|
12
|
-
nsarchive/utils
|
13
|
-
nsarchive-2.0.
|
14
|
-
nsarchive-2.0.
|
15
|
-
nsarchive-2.0.
|
16
|
-
nsarchive-2.0.
|
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()
|
File without changes
|
File without changes
|