nsarchive 1.4.0__py3-none-any.whl → 2.0.0a2__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/__init__.py CHANGED
@@ -1,827 +1,27 @@
1
- import time
1
+ """
2
+ nsarchive - API-wrapper pour récupérer des données liées à Nation.
2
3
 
3
- import deta
4
+ Version: 2.0.0
5
+ License: GPL-3.0
6
+ Auteur : happex <110610727+okayhappex@users.noreply.github.com>
4
7
 
5
- from .cls.base import *
6
- from .cls.entities import *
8
+ Dependencies:
9
+ - Python ^3.10
10
+ - supabase ^2.9.1
11
+ - pillow ^10.4
12
+
13
+ Le fichier README.md fournit des détails supplémentaires pour l'utilisation.
14
+ """
15
+
16
+ # Import des types et des exceptions
17
+ from .cls.base import NSID
7
18
  from .cls.archives import *
19
+ from .cls.entities import *
8
20
  from .cls.republic import *
9
- from .cls.economy import *
10
21
 
11
22
  from .cls.exceptions import *
12
23
 
13
- class EntityInstance:
14
- """
15
- Instance qui vous permettra d'interagir avec les profils des membres ainsi que les différents métiers et secteurs d'activité.
16
-
17
- ## Informations disponibles
18
- - Profil des membres et des entreprises: `.User | .Organization | .Entity`
19
- - Participation d'un membre à différent votes: `.User | .Organization | .Entity`
20
- - Appartenance et permissions d'un membre dans un groupe: `.GroupMember.MemberPermissions`
21
- - Position légale et permissions d'une entité: `.Position.Permissions`
22
- - Sanctions et modifications d'une entité: `.Action[ .AdminAction | .Sanction ]`
23
- """
24
-
25
- def __init__(self, token: str) -> None:
26
- self.db = deta.Deta(token)
27
- self.base = self.db.Base('entities')
28
- self.electors = self.db.Base('electors')
29
- self.archives = self.db.Base('archives')
30
- self.avatars = self.db.Drive('avatars')
31
- self.positions = self.db.Base('positions') # Liste des métiers
32
-
33
- def get_entity(self, id: str | NSID) -> User | Organization | Entity:
34
- """
35
- Fonction permettant de récupérer le profil public d'une entité.\n
36
-
37
- ## Paramètres
38
- id: `NSID`\n
39
- ID héxadécimal de l'entité à récupérer
40
-
41
- ## Renvoie
42
- - `.User` dans le cas où l'entité choisie est un membre
43
- - `.Organization` dans le cas où c'est un groupe
44
- - `.Entity` dans le cas où c'est indéterminé
45
- """
46
-
47
- id = NSID(id)
48
- _data = self.base.get(id)
49
- _votes = self.electors.get(id)
50
-
51
- if _data is None:
52
- return None
53
-
54
- if _data['_type'] == 'user':
55
- entity = User(id)
56
-
57
- entity.xp = _data['xp']
58
- entity.boosts = _data['boosts']
59
-
60
- if _votes is None:
61
- entity.votes = []
62
- else:
63
- entity.votes = [ NSID(vote) for vote in _votes['votes'] ]
64
- elif _data['_type'] == 'organization':
65
- entity = Organization(id)
66
-
67
- entity.owner = self.get_entity(NSID(_data['owner_id']))
68
-
69
- for _member in _data['members']:
70
- member = GroupMember(_member['id'])
71
- member.group_permissions.__dict__ = _member['permissions']
72
-
73
- _member_profile = self.get_entity(member.id)
74
-
75
- member.set_name(_member_profile.name)
76
- member.legalPosition = _member_profile.legalPosition
77
- member.registerDate = _member_profile.registerDate
78
-
79
- member.xp = _member_profile.xp
80
- member.boosts = _member_profile.boosts
81
-
82
- member.permissions = _member_profile.permissions
83
- member.votes = _member_profile.votes
84
-
85
- entity.append(member)
86
-
87
- try:
88
- entity.avatar = self.avatars.get(id).read()
89
- except:
90
- entity.avatar = None
91
-
92
- entity.certifications = _data['certifications']
93
- else:
94
- entity = Entity(id)
95
-
96
- entity.name = _data['name']
97
- entity.legalPosition = _data['legalPosition'] # Métier si c'est un utilisateur, domaine professionnel si c'est un collectif
98
- entity.registerDate = _data['registerDate']
99
-
100
- for key, value in _data.get('additional', {}):
101
- if isinstance(value, str) and value.startswith('\n'):
102
- entity.add_link(key, int(value[1:]))
103
- else:
104
- entity.add_link(key, value)
105
-
106
- return entity
107
-
108
- def save_entity(self, entity: Entity) -> None:
109
- """
110
- Fonction permettant de créer ou modifier une entité.
111
-
112
- ## Paramètres
113
- entity: `.Entity` ( `.User | .Organization` )
114
- L'entité à sauvegarder
115
- """
116
-
117
- entity.id = NSID(entity.id)
118
-
119
- _base = self.base
120
- _data = {
121
- '_type': 'user' if type(entity) == User else 'organization' if type(entity) == Organization else 'unknown',
122
- 'name': entity.name,
123
- 'legalPosition': entity.legalPosition,
124
- 'registerDate': entity.registerDate,
125
- 'additional': {}
126
- }
127
-
128
- for key, value in entity.additional.items():
129
- if isinstance(value, int) and len(str(int)) >= 15:
130
- _data['additional'][key] = '\n' + str(value)
131
- elif type(value) in (str, int):
132
- _data['additional'][key] = value
133
-
134
- if type(entity) == Organization:
135
- _data['owner_id'] = NSID(entity.owner.id) if entity.owner else NSID("0")
136
- _data['members'] = []
137
- _data['certifications'] = entity.certifications
138
-
139
- for member in entity.members:
140
- _member = {
141
- 'id': NSID(member.id),
142
- 'permissions': member.group_permissions.__dict__.copy()
143
- }
144
-
145
- _data['members'] += [_member]
146
-
147
- self.avatars.put(name = entity.id, data = entity.avatar)
148
- elif type(entity) == User:
149
- _data['xp'] = entity.xp
150
- _data['boosts'] = entity.boosts
151
-
152
- _votes = []
153
- for vote in entity.votes:
154
- _votes.append(NSID(vote))
155
-
156
- self.electors.put({ "votes": _votes }, entity.id, expire_in = 112 * 84600) # Données supprimées après 16 semaines d'inactivité
157
-
158
- _base.put(_data, entity.id, expire_in = 3 * 31536000) # Pareil après 3 ans
159
-
160
- def delete_entity(self, entity: Entity) -> None:
161
- """
162
- Fonction permettant de supprimer le profil d'une entité
163
-
164
- ## Paramètres
165
- entity: `.Entity` ( `.User | .Organization` )
166
- L'entité à supprimer
167
- """
168
-
169
- self.base.delete(NSID(entity.id))
170
-
171
- if type(entity) == Organization:
172
- self.avatars.delete(NSID(entity.id))
173
-
174
- def fetch_entities(self, query: dict = None, listquery: dict | None = None) -> list[ Entity | User | Organization ]:
175
- """
176
- Récupère une liste d'entités en fonction d'une requête.
177
-
178
- ## Paramètres
179
- query: `dict`
180
- La requête pour filtrer les entités.
181
- listquery: `dict | None`
182
- OBSOLÈTE
183
-
184
- ## Renvoie
185
- - `list[Entity | User | Organization]`
186
- """
187
-
188
- _res = self.base.fetch(query).items
189
-
190
- if listquery:
191
- print("\033[1;33mAvertissement\033[0m Listquery n'est plus pris en charge et sera retiré en version 1.3.0")
192
-
193
- return [ self.get_entity(NSID(entity['key'])) for entity in _res if entity is not None ]
194
-
195
- def get_entity_groups(self, id: str | NSID) -> list[Organization]:
196
- """
197
- Récupère les groupes auxquels appartient une entité.
198
-
199
- ## Paramètres
200
- id: `str | NSID`
201
- ID de l'entité.
202
-
203
- ## Renvoie
204
- - `list[Organization]`
205
- """
206
-
207
- id = NSID(id)
208
- groups = self.fetch_entities({'_type': 'organization'})
209
- groups.extend(self.fetch_entities({'_type': 'organization', 'owner_id': id}))
210
-
211
- for group in groups:
212
- if group is None:
213
- groups.remove(group)
214
- continue
215
-
216
- if group.owner.id == id:
217
- continue
218
-
219
- for member in group.members:
220
- if member.id == id:
221
- break
222
- else:
223
- groups.remove(group)
224
-
225
- return [ group for group in groups if group is not None ]
226
-
227
- def get_position(self, id: str) -> Position:
228
- """
229
- Récupère une position légale (métier, domaine professionnel).
230
-
231
- ## Paramètres
232
- id: `str`
233
- ID de la position (SENSIBLE À LA CASSE !)
234
-
235
- ## Renvoie
236
- - `.Position`
237
- """
238
-
239
- _data = self.positions.get(id)
240
-
241
- if _data is None:
242
- return None
243
-
244
- position = Position(id)
245
- position.name = _data['name']
246
-
247
- for _permission in _data['permissions']:
248
- position.permissions.__setattr__(_permission, True)
249
-
250
- return position
251
-
252
- def _add_archive(self, archive: Action) -> None:
253
- """
254
- Ajoute une archive d'une action (modification au sein d'un groupe ou sanction) dans la base de données.
255
- """
256
-
257
- archive.id = NSID(archive.id)
258
- archive.author = NSID(archive.author)
259
- archive.target = NSID(archive.target)
260
-
261
- _data = archive.__dict__.copy()
262
-
263
- if type(archive) == Sanction:
264
- _data['type'] = "sanction"
265
- elif type(archive) == AdminAction:
266
- _data['type'] = "adminaction"
267
- elif type(archive) == Report:
268
- _data['type'] = "report"
269
- else:
270
- _data['type'] = "unknown"
271
-
272
- self.archives.put(key = archive.id, data = _data)
273
-
274
- def _get_archive(self, id: str | NSID) -> Action | Sanction | AdminAction:
275
- """
276
- Récupère une archive spécifique.
277
-
278
- ## Paramètres
279
- id: `str | NSID`
280
- ID de l'archive.
281
-
282
- ## Renvoie
283
- - `.Action | .Sanction | .AdminAction`
284
- """
285
-
286
- id = NSID(id)
287
- _data = self.archives.get(id)
288
-
289
- if _data is None:
290
- return None
291
-
292
- if _data['type'] == "sanction": # Mute, ban, GAV, kick, détention, prune (xp seulement)
293
- archive = Sanction(_data['author'], _data['target'])
294
-
295
- archive.details = _data['details']
296
- archive.major = _data['major']
297
- archive.duration = _data['duration']
298
- elif _data['type'] == "adminaction": # Renommage, promotion, démotion (au niveau de l'état)
299
- archive = AdminAction(_data['author'], _data['target'])
300
-
301
- archive.details = _data['details']
302
- archive.new_state = _data['new_state']
303
- elif _data['type'] == "report": # Plainte
304
- archive = Report(_data['author'], _data['target'])
305
-
306
- archive.details = _data['details']
307
- else:
308
- archive = Action(_data['author'], _data['target'])
309
-
310
- archive.id = id
311
- archive.action = _data['action']
312
- archive.date = _data['date']
313
-
314
- return archive
315
-
316
- def _fetch_archives(self, **query) -> list[ Action | Sanction | AdminAction ]:
317
- """
318
- Récupère une liste d'archives correspondant à la requête.
319
-
320
- ## Paramètres
321
- query: `dict`
322
- Requête pour filtrer les archives.
323
-
324
- ## Renvoie
325
- - `list[Action | Sanction | AdminAction]`
326
- """
327
-
328
- _res = self.archives.fetch(query).items
329
-
330
- return [ self._get_archive(archive['key']) for archive in _res ]
331
-
332
- class RepublicInstance:
333
- """
334
- Gère les interactions avec les votes, les archives de la république, et les fonctionnaires.
335
-
336
- ## Informations
337
- - Résultats des votes: `.Vote | .ClosedVote`
338
- - Différentes institutions: `.Institutions | .Administration | .Government | .Assembly | .Court | .PoliceForces`
339
- - Occupants des différents rôles et historique de leurs actions: `.Official`
340
- """
341
-
342
- def __init__(self, token: str) -> None:
343
- """Initialise une nouvelle RepublicInstance avec un token Deta."""
344
-
345
- self.db = deta.Deta(token)
346
- self.votes = self.db.Base('votes')
347
- self.archives = self.db.Base('archives')
348
- self.mandate = self.db.Base('mandate')
349
- self.functions = self.db.Base('functions') # Liste des fonctionnaires
350
-
351
- def get_vote(self, id: str | NSID) -> Vote | ClosedVote | Lawsuit:
352
- """
353
- Récupère un vote spécifique.
354
-
355
- ## Paramètres
356
- id: `str | NSID`
357
- ID du vote.
358
-
359
- ## Renvoie
360
- - `.Vote | .ClosedVote`
361
- """
362
-
363
- id = NSID(id)
364
- _data = self.votes.get(id)
365
-
366
- if _data is None:
367
- return None
368
-
369
- if _data['_type'] == 'open':
370
- vote = Vote(id, _data['title'], tuple(_data['choices'].keys()))
371
- elif _data['_type'] == 'closed':
372
- vote = ClosedVote(id, _data['title'])
373
- elif _data['_type'] == 'lawsuit':
374
- vote = Lawsuit(id, _data['title'])
375
- else:
376
- vote = Vote('0', 'Unknown Vote', ())
377
-
378
- vote.author = _data['author']
379
- vote.startDate = _data['startDate']
380
- vote.endDate = _data['endDate']
381
- vote.choices = _data['choices']
382
-
383
- return vote
384
-
385
- def save_vote(self, vote: Vote | ClosedVote) -> None:
386
- """Sauvegarde un vote dans la base de données."""
387
-
388
- vote.id = NSID(vote.id)
389
-
390
- _data = {
391
- '_type':'open' if type(vote) == Vote else\
392
- 'closed' if type(vote) == ClosedVote else\
393
- 'lawsuit' if type(vote) == Lawsuit else\
394
- 'unknown',
395
- 'title': vote.title,
396
- 'author': NSID(vote.author),
397
- 'startDate': vote.startDate,
398
- 'endDate': vote.endDate,
399
- 'choices': vote.choices
400
- }
401
-
402
- self.votes.put(_data, vote.id)
403
-
404
- def get_official(self, id: str | NSID, current_mandate: bool = True) -> Official:
405
- """
406
- Récupère les informations d'un fonctionnaire (mandats, contributions).
407
-
408
- ## Paramètres
409
- id: `str | NSID`
410
- ID du fonctionnaire.
411
- current_mandate: `bool`
412
- Indique si l'on doit récupérer le mandat actuel ou les anciens mandats.
413
-
414
- ## Renvoie
415
- - `.Official`
416
- """
417
-
418
- id = NSID(id)
419
-
420
- archives = self.mandate if current_mandate else self.archives
421
-
422
- _contributions = archives.fetch({'author': id, 'type': 'contrib'}).items
423
- _mandates = archives.fetch({'target': id, 'type': 'election'}).items\
424
- + archives.fetch({'target': id, 'type': 'promotion'}).items
425
-
426
- user = Official(id)
427
- for mandate in _mandates:
428
- if mandate['position'].startswith('MIN'):
429
- mandate['position'] = 'MIN'
430
-
431
- try:
432
- user.mandates[mandate['position']] += 1
433
- except KeyError:
434
- user.mandates[mandate['position']] = 1
435
-
436
- for contrib in _contributions:
437
- try:
438
- user.contributions[contrib['action']] += 1
439
- except KeyError:
440
- user.contributions[contrib['action']] = 1
441
-
442
- return user
443
-
444
- def get_institutions(self) -> Organization:
445
- """Récupère l'état actuel des institutions de la république."""
446
-
447
- admin = Administration()
448
- gov = Government(Official('0'))
449
- assembly = Assembly()
450
- court = Court()
451
- police_forces = PoliceForces()
452
-
453
- _admins = self.functions.get('ADMIN')
454
- admin.members = [ self.get_official(user) for user in _admins['users'] ]
455
- admin.president = self.get_official('F7DB60DD1C4300A') # happex (remplace Kheops pour l'instant)
456
-
457
- gov.president = self.get_official(self.functions.get('PRE_REP')['users'][0])
458
-
459
- minister = lambda code : self.get_official(self.functions.get(f'MIN_{code}')['users'][0])
460
- gov.prime_minister = minister('PRIM')
461
- gov.economy_minister = minister('ECO')
462
- gov.inner_minister = minister('INN')
463
- gov.press_minister = minister('AUD')
464
- gov.justice_minister = minister('JUS')
465
- gov.outer_minister = minister('OUT')
466
-
467
- assembly.president = self.get_official(self.functions.get('PRE_AS')['users'][0])
468
- assembly.members = [ self.get_official(id) for id in self.functions.get('REPR')['users'] ]
469
-
470
- court.president = gov.justice_minister
471
- court.members = [ self.get_official(id) for id in self.functions.get('JUDGE')['users'] ]
472
-
473
- police_forces.president = gov.inner_minister
474
- police_forces.members = [ self.get_official(id) for id in self.functions.get('POLICE')['users'] ]
475
-
476
- instits = Institutions()
477
- instits.administration = admin
478
- instits.government = gov
479
- instits.court = court
480
- instits.assembly = assembly
481
- instits.police = police_forces
482
-
483
- return instits
484
-
485
- def update_institutions(self, institutions: Institutions):
486
- """
487
- Fonction communément appelée après un vote législatif ou une nomination.\n
488
- Celle-ci met à jour: Le gouvernement (président, ministres), les différents députés et leur président, les différents juges, les différents policiers.\n
489
-
490
- ## Paramètres
491
- institutions: `.Institutions`\n
492
- Le nouvel état des institutions, à sauvegarder.
493
- """
494
-
495
- get_ids = lambda institution : [ member.id for member in institutions.__getattribute__(institution).members ]
496
-
497
- self.functions.put(key = 'ADMIN', data = { 'users': get_ids('administration') })
498
- self.functions.put(key = 'REPR', data = { 'users': get_ids('assembly') })
499
- self.functions.put(key = 'JUDGE', data = { 'users': get_ids('court') })
500
- self.functions.put(key = 'POLICE', data = { 'users': get_ids('police') })
501
-
502
- self.functions.put(key = 'PRE_AS', data = { 'users': [ institutions.assembly.president.id ] })
503
- self.functions.put(key = 'PRE_REP', data = { 'users': [ institutions.government.president.id ] })
504
-
505
- self.functions.put(key = 'MIN_PRIM', data = { 'users': [ institutions.government.prime_minister.id ] })
506
- self.functions.put(key = 'MIN_INN', data = { 'users': [ institutions.government.inner_minister.id ] })
507
- self.functions.put(key = 'MIN_JUS', data = { 'users': [ institutions.government.justice_minister.id ] })
508
- self.functions.put(key = 'MIN_ECO', data = { 'users': [ institutions.government.economy_minister.id ] })
509
- self.functions.put(key = 'MIN_AUD', data = { 'users': [ institutions.government.press_minister.id ] })
510
- self.functions.put(key = 'MIN_OUT', data = { 'users': [ institutions.government.outer_minister.id ] })
511
-
512
- def new_mandate(self, institutions: Institutions, weeks: int = 4) -> None:
513
- """
514
- Fonction qui amène à supprimer toutes les archives du mandat précédent
515
- """
516
-
517
- for item in self.mandate.fetch().items:
518
- if item['date'] >= round(time.time()) - weeks * 604800: # On évite de supprimer les informations écrites lors de la période définie
519
- self.mandate.delete(item['id'])
520
-
521
- self.update_institutions(institutions)
522
-
523
- def _add_archive(self, archive: Action) -> None:
524
- """Ajoute une archive d'une action (élection, promotion, ou rétrogradation) dans la base de données."""
525
-
526
- archive.id = NSID(archive.id)
527
- _data = archive.__dict__.copy()
528
-
529
- if type(archive) == Election:
530
- _data['type'] = "election"
531
- elif type(archive) == Promotion:
532
- _data['type'] = "promotion"
533
- elif type(archive) == Demotion:
534
- _data['type'] = "demotion"
535
- else:
536
- _data['type'] = "unknown"
537
-
538
- self.archives.put(key = archive.id, data = _data)
539
- self.mandate.put(key = archive.id, data = _data) # Ajouter les archives à celle du mandat actuel
540
-
541
- def _get_archive(self, id: str | NSID) -> Action | Election | Promotion | Demotion:
542
- """
543
- Récupère une archive spécifique.
544
-
545
- ## Paramètres
546
- id: `str | NSID`
547
- ID de l'archive.
548
-
549
- ## Renvoie
550
- - `.Action | .Election | .Promotion | .Demotion`
551
- """
552
-
553
- id = NSID(id)
554
- _data = self.archives.get(id)
555
-
556
- if _data is None:
557
- return None
558
-
559
- if _data['type'] == "election":
560
- archive = Election(_data['author'], _data['target'], _data['position'])
561
-
562
- archive.positive_votes = _data['positive_votes']
563
- archive.total_votes = _data['total_votes']
564
- elif _data['type'] == "promotion":
565
- archive = Promotion(_data['author'], _data['target'], _data['position'])
566
- elif _data['type'] == "demotion":
567
- archive = Demotion(_data['author'], _data['target'])
568
-
569
- archive.reason = _data['reason']
570
- else:
571
- archive = Action(_data['author'], _data['target'])
572
-
573
- archive.id = id
574
- archive.action = _data['action']
575
- archive.date = _data['date']
576
-
577
- return archive
578
-
579
- def _fetch_archives(self, **query) -> list[ Action | Election | Promotion | Demotion ]:
580
- """
581
- Récupère une liste d'archives correspondant à la requête.
582
-
583
- ## Paramètres
584
- query: `dict`
585
- Requête pour filtrer les archives.
586
-
587
- ## Renvoie
588
- - `list[Action | Election | Promotion | Demotion]`
589
- """
590
-
591
- _res = self.archives.fetch(query).items
592
-
593
- return [ self._get_archive(archive['key']) for archive in _res ]
594
-
595
- class BankInstance:
596
- """Gère les interactions avec les comptes bancaires, les transactions, et le marché."""
597
-
598
- def __init__(self, token: str) -> None:
599
- self.db = deta.Deta(token)
600
- self.archives = self.db.Base('archives')
601
- self.accounts = self.db.Base('accounts')
602
- self.registry = self.db.Base('banks')
603
- self.marketplace = self.db.Base('shop')
604
- self.inventories = self.db.Base('inventories')
605
-
606
- def get_account(self, id: str | NSID) -> BankAccount:
607
- """
608
- Récupère les informations d'un compte bancaire.
609
-
610
- ## Paramètres
611
- id: `str | NSID`
612
- ID du compte.
613
-
614
- ## Renvoie
615
- - `.BankAccount`
616
- """
617
-
618
- id = NSID(id)
619
- _data = self.accounts.get(id)
620
-
621
- if _data is None:
622
- return None
623
-
624
- account = BankAccount(id)
625
- account.amount = _data['amount']
626
- account.locked = _data['locked']
627
- account.owner = _data['owner_id']
628
- account.bank = _data['bank']
629
-
630
- return account
631
-
632
- def save_account(self, account: BankAccount):
633
- """Sauvegarde un compte bancaire dans la base de données."""
634
-
635
- _data = {
636
- 'amount': account.amount,
637
- 'locked': account.locked,
638
- 'owner_id': account.owner,
639
- 'bank': account.bank
640
- }
641
-
642
- self.accounts.put(_data, NSID(account.id))
643
-
644
- def lock_account(self, account: BankAccount):
645
- """Verrouille un compte bancaire pour empêcher toute transaction."""
646
-
647
- account.id = account.id.upper()
648
- account.locked = True
649
-
650
- self.save_account(account)
651
-
652
- def get_sale(self, id: str | NSID) -> Sale | None:
653
- """
654
- Récupère une vente disponible sur le marketplace.
655
-
656
- ## Paramètres
657
- id: `str | NSID`
658
- ID de l'item.
659
-
660
- ## Renvoie
661
- - `.Item | None`
662
- """
663
-
664
- id = NSID(id)
665
-
666
- _data = self.marketplace.get(id)
667
-
668
- if _data is None:
669
- return None
670
-
671
- sale = Sale(NSID(id))
672
-
673
- del _data['key']
674
- sale.__dict__ = _data
675
-
676
- return sale
677
-
678
- def sell_item(self, item: Item, quantity: int, price: int, seller: NSID) -> None:
679
- """
680
- Vend un item sur le marché.
681
-
682
- ## Paramètres
683
- item: `.Item`
684
- Item à vendre
685
- quantity: `int`
686
- Nombre d'items à vendre
687
- price: `int`
688
- Prix à l'unité de chaque objet
689
- seller: `NSID`
690
- ID de l'auteur de la vente
691
- """
692
-
693
- sale = Sale(NSID(round(time.time()) * 16 ** 3), item)
694
- sale.quantity = quantity
695
- sale.price = price
696
- sale.seller_id = seller
697
-
698
- _data = sale.__dict__.copy()
699
- del _data['id']
700
-
701
- self.marketplace.put(key = sale.id, data = _data)
702
-
703
- def delete_sale(self, sale: Sale) -> None:
704
- """Annule une vente sur le marketplace."""
705
-
706
- sale.id = NSID(sale.id)
707
- self.marketplace.delete(sale.id)
708
-
709
- def get_inventory(self, id: NSID) -> Inventory | None:
710
- """
711
- Récupérer un inventaire dans la base des inventaires.
712
-
713
- ## Paramètres
714
- id: `NSID`
715
- ID du propriétaire de l'inventaire
716
-
717
- ## Retourne
718
- - `.Inventory | None`
719
- """
720
- _data = self.inventories.get(id)
721
-
722
- if _data is None:
723
- return None
724
-
725
- inventory = Inventory(id)
726
-
727
- del _data['key']
728
-
729
- for _item in _data['objects']:
730
- item = Item(_item['id'])
731
- item.__dict__ = _item
732
-
733
- inventory.objects.append(item)
734
-
735
- return inventory
736
-
737
- def save_inventory(self, inventory: Inventory) -> None:
738
- """
739
- Sauvegarder un inventaire
740
-
741
- ## Paramètres
742
- inventory: `.Inventory`
743
- Inventaire à sauvegarder
744
- """
745
-
746
- _data = {
747
- "owner_id": inventory.owner_id,
748
- "objects": [ object.__dict__ for object in inventory.objects ]
749
- }
750
-
751
- self.inventories.put(key = inventory.owner_id, data = _data)
752
-
753
- def delete_inventory(self, inventory: Inventory) -> None:
754
- """
755
- Supprime un inventaire
756
-
757
- ## Paramètres
758
- inventory: `.Inventory`
759
- Inventaire à supprimer
760
- """
761
-
762
- self.inventories.delete(inventory.id)
763
-
764
- def _add_archive(self, archive: Action):
765
- """Ajoute une archive d'une transaction ou d'une vente dans la base de données."""
766
-
767
- archive.id = NSID(archive.id)
768
- archive.author = NSID(archive.author)
769
- archive.target = NSID(archive.target)
770
-
771
- _data = archive.__dict__.copy()
772
-
773
- if type(archive) == Transaction:
774
- _data['type'] = "transaction"
775
- archive.currency = archive.currency.upper()
776
- else:
777
- _data['type'] = "unknown"
778
-
779
- self.archives.put(key = archive.id, data = _data)
780
-
781
- def _get_archive(self, id: str | NSID) -> Action | Transaction:
782
- """
783
- Récupère une archive spécifique.
784
-
785
- ## Paramètres
786
- id: `str | NSID`
787
- ID de l'archive.
788
-
789
- ## Renvoie
790
- - `.Action | .Transaction`
791
- """
792
-
793
- id = NSID(id)
794
- _data = self.archives.get(id)
795
-
796
- if _data is None:
797
- return None
798
-
799
- if _data['type'] == "transaction":
800
- archive = Transaction(_data['author'], _data['target'], _data['amount'])
801
-
802
- archive.reason = _data['reason']
803
- archive.currency = _data['currency']
804
- else:
805
- archive = Action(_data['author'], _data['target'])
806
-
807
- archive.id = id
808
- archive.action = _data['action']
809
- archive.date = _data['date']
810
-
811
- return archive
812
-
813
- def _fetch_archives(self, **query) -> list[ Action | Transaction ]:
814
- """
815
- Récupère une liste d'archives correspondant à la requête.
816
-
817
- ## Paramètres
818
- query: `dict`
819
- Requête pour filtrer les archives.
820
-
821
- ## Renvoie
822
- - `list[Action | Transaction]`
823
- """
824
-
825
- _res = self.archives.fetch(query).items
826
-
827
- return [ self._get_archive(archive['key']) for archive in _res ]
24
+ # Import des instances
25
+ from .instances._economy import EconomyInstance
26
+ from .instances._entities import EntityInstance
27
+ from .instances._republic import RepublicInstance