nsarchive 0.1a0__tar.gz → 0.2a0__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.
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.1
2
+ Name: nsarchive
3
+ Version: 0.2a0
4
+ Summary:
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
+ Description-Content-Type: text/markdown
15
+
16
+ # nsarchive
17
+
18
+ `nsarchive` est un module Python pour la gestion des entités (utilisateurs et organisations) à l'aide de la base de données Deta. Ce module permet de créer, récupérer, sauvegarder et gérer des entités et leurs attributs spécifiques.
19
+
20
+ ## Pré-requis
21
+
22
+ Listes des choses à avoir afin de pouvoir utiliser le module correctement:
23
+ - [Python 3.10](https://www.python.org/downloads/) ou supérieur
24
+ - Un token [Deta](https://deta.space), donné par un administrateur ou pour votre collection personnelle
25
+ - Un bon capuccino, pour commencer la programmation en bons termes
26
+
27
+ > **Note:** Il vous faudra un token différent pour accéder aux différentes parties de la base de données. Vos tokens n'expireront pas à moins que l'ordre en aura été donné
28
+
29
+ ## Installation
30
+
31
+ Vous pouvez installer ce module via pip :
32
+
33
+ ```sh
34
+ pip install nsarchive
35
+ ```
36
+
37
+ ## Utilisation
38
+
39
+ ### Importation et Initialisation
40
+
41
+ Pour utiliser `nsarchive`, commencez par importer le module et initialiser une instance d'`EntityInstance` avec votre token Deta.
42
+
43
+ ```python
44
+ from nsarchive import EntityInstance
45
+
46
+ # Remplacez 'your_deta_token' par votre véritable token Deta
47
+ entity_instance = EntityInstance(token = 'your_deta_token')
48
+ ```
49
+
50
+ ### Récupérer une Entité
51
+
52
+ Vous pouvez récupérer une entité (Utilisateur ou Organisation) à l'aide de son ID.
53
+
54
+ ```python
55
+ entity = entity_instance.get_entity(id = 'entity_id')
56
+ print(entity.name)
57
+ ```
58
+
59
+ **ATTENTION: Les entités sont identifiées sous une forme hexadécimale. Pour les avoir, vous devez convertir leur ID Discord en hexadécimale puis enlever le préfixe `0x`.**
60
+
61
+ Pour les organisations, l'ID Discord correspondra à la formule suivante: `ID fondateur // 100000`.
62
+
63
+ N'oubliez pas de toujours utiliser un `str` dans les ID pour interagir avec la base de données.
64
+
65
+ ### Sauvegarder une Entité
66
+
67
+ Après avoir modifié une entité, vous pouvez la sauvegarder dans la base de données.
68
+
69
+ ```python
70
+ entity.rename("Nouveau Nom")
71
+ entity_instance.save_entity(entity)
72
+ ```
73
+
74
+ ### Rechercher des Entités
75
+
76
+ Vous pouvez rechercher des entités avec des critères spécifiques.
77
+
78
+ ```python
79
+ entities = entity_instance.fetch(query = {'name': 'Alice'})
80
+ for entity in entities:
81
+ print(entity['name'])
82
+ ```
83
+
84
+ ### Gérer les Organisations
85
+
86
+ Les organisations peuvent avoir des membres et des certifications. Voici comment ajouter un membre ou une certification.
87
+
88
+ ```python
89
+ organization = entity_instance.get_entity(id = 'org_id')
90
+ user = entity_instance.get_entity(id = 'user_id')
91
+
92
+ # Ajouter un membre
93
+ organization.add_member(user)
94
+ entity_instance.save_entity(organization)
95
+
96
+ # Ajouter une certification
97
+ organization.add_certification('Certification Example')
98
+ entity_instance.save_entity(organization)
99
+ ```
100
+
101
+ Les certifications pourront être utilisées pour vérifier l'officialité d'une organisation, mais également pour déterminer si l'on peut accorder (ou non) des permissions à ses membres.
102
+
103
+ ### Exemples de Classes
104
+
105
+ #### `Entity`
106
+
107
+ Classe parente des classes `User` et `Organization`, elle est utilisée lorsque le module ne peut pas déterminer l'appartenance d'une identité à l'une de ces deux classes ou à l'autre.
108
+
109
+ ```python
110
+ from nsarchive.cls.entities import Entity
111
+
112
+ entity = Entity(id='entity_id')
113
+ entity.rename('New Name')
114
+ entity.add_xp(100)
115
+ print(entity.get_level())
116
+ ```
117
+
118
+ #### `User`
119
+
120
+ ```python
121
+ from nsarchive.cls.entities import User
122
+
123
+ user = User(id = 'user_id')
124
+ user.edit_boost(name = 'admin', multiplier = 5) # Négliger le paramètre <multiplier> ou le fixer à un nombre négatif reviendrait à supprimer le boost.
125
+ print(user.boosts)
126
+ ```
127
+
128
+ > **Note:** Lorsqu'on ajoute de l'expérience à un utilisateur via la méthode `add_xp`, le nombre de points ajoutés est automatiquement multiplié par le bonus le plus important dont l'utilisateur bénéficie.
129
+
130
+ #### `Organization`
131
+
132
+ ```python
133
+ from nsarchive.cls.entities import Organization
134
+
135
+ organization = Organization(id = 'org_id')
136
+ organization.set_owner(user)
137
+ organization.add_member(user)
138
+ print(organization.members)
139
+ ```
140
+
141
+ > **Note:** Les attributs `owner` et `members` sont indépendants. L'owner peut être n'importe quelle personne faisant ou non partie des `members`.
142
+
143
+ ## Gestion des Exceptions
144
+
145
+ `nsarchive` fournit des exceptions spécifiques pour gérer les erreurs courantes.
146
+
147
+ #### `NameTooLongError`
148
+
149
+ Lancé lorsque le nom d'une entité dépasse la longueur maximale autorisée (32 caractères).
150
+
151
+ ```python
152
+ from nsarchive.cls.exceptions import NameTooLongError
153
+
154
+ try:
155
+ entity.rename('Ce nom est long, voire même très long, je dirais même extrêmement long')
156
+ except NameTooLongError as e:
157
+ print(e)
158
+ ```
159
+
160
+ #### `EntityTypeError`
161
+
162
+ Lancé lorsque le type d'entité est incorrect. Vous ne devriez normalement pas la rencontrer en utilisant le module, mais elle pourrait vous être utile.
163
+
164
+ ```python
165
+ from nsarchive.cls.exceptions import EntityTypeError
166
+
167
+ try:
168
+ # Code qui peut lancer une EntityTypeError
169
+ except EntityTypeError as e:
170
+ print(e)
171
+ ```
172
+
173
+ ## License
174
+
175
+ Ce projet est sous licence GNU GPL-3.0 - Voir le fichier [LICENSE](LICENSE) pour plus de détails.
@@ -0,0 +1,160 @@
1
+ # nsarchive
2
+
3
+ `nsarchive` est un module Python pour la gestion des entités (utilisateurs et organisations) à l'aide de la base de données Deta. Ce module permet de créer, récupérer, sauvegarder et gérer des entités et leurs attributs spécifiques.
4
+
5
+ ## Pré-requis
6
+
7
+ Listes des choses à avoir afin de pouvoir utiliser le module correctement:
8
+ - [Python 3.10](https://www.python.org/downloads/) ou supérieur
9
+ - Un token [Deta](https://deta.space), donné par un administrateur ou pour votre collection personnelle
10
+ - Un bon capuccino, pour commencer la programmation en bons termes
11
+
12
+ > **Note:** Il vous faudra un token différent pour accéder aux différentes parties de la base de données. Vos tokens n'expireront pas à moins que l'ordre en aura été donné
13
+
14
+ ## Installation
15
+
16
+ Vous pouvez installer ce module via pip :
17
+
18
+ ```sh
19
+ pip install nsarchive
20
+ ```
21
+
22
+ ## Utilisation
23
+
24
+ ### Importation et Initialisation
25
+
26
+ Pour utiliser `nsarchive`, commencez par importer le module et initialiser une instance d'`EntityInstance` avec votre token Deta.
27
+
28
+ ```python
29
+ from nsarchive import EntityInstance
30
+
31
+ # Remplacez 'your_deta_token' par votre véritable token Deta
32
+ entity_instance = EntityInstance(token = 'your_deta_token')
33
+ ```
34
+
35
+ ### Récupérer une Entité
36
+
37
+ Vous pouvez récupérer une entité (Utilisateur ou Organisation) à l'aide de son ID.
38
+
39
+ ```python
40
+ entity = entity_instance.get_entity(id = 'entity_id')
41
+ print(entity.name)
42
+ ```
43
+
44
+ **ATTENTION: Les entités sont identifiées sous une forme hexadécimale. Pour les avoir, vous devez convertir leur ID Discord en hexadécimale puis enlever le préfixe `0x`.**
45
+
46
+ Pour les organisations, l'ID Discord correspondra à la formule suivante: `ID fondateur // 100000`.
47
+
48
+ N'oubliez pas de toujours utiliser un `str` dans les ID pour interagir avec la base de données.
49
+
50
+ ### Sauvegarder une Entité
51
+
52
+ Après avoir modifié une entité, vous pouvez la sauvegarder dans la base de données.
53
+
54
+ ```python
55
+ entity.rename("Nouveau Nom")
56
+ entity_instance.save_entity(entity)
57
+ ```
58
+
59
+ ### Rechercher des Entités
60
+
61
+ Vous pouvez rechercher des entités avec des critères spécifiques.
62
+
63
+ ```python
64
+ entities = entity_instance.fetch(query = {'name': 'Alice'})
65
+ for entity in entities:
66
+ print(entity['name'])
67
+ ```
68
+
69
+ ### Gérer les Organisations
70
+
71
+ Les organisations peuvent avoir des membres et des certifications. Voici comment ajouter un membre ou une certification.
72
+
73
+ ```python
74
+ organization = entity_instance.get_entity(id = 'org_id')
75
+ user = entity_instance.get_entity(id = 'user_id')
76
+
77
+ # Ajouter un membre
78
+ organization.add_member(user)
79
+ entity_instance.save_entity(organization)
80
+
81
+ # Ajouter une certification
82
+ organization.add_certification('Certification Example')
83
+ entity_instance.save_entity(organization)
84
+ ```
85
+
86
+ Les certifications pourront être utilisées pour vérifier l'officialité d'une organisation, mais également pour déterminer si l'on peut accorder (ou non) des permissions à ses membres.
87
+
88
+ ### Exemples de Classes
89
+
90
+ #### `Entity`
91
+
92
+ Classe parente des classes `User` et `Organization`, elle est utilisée lorsque le module ne peut pas déterminer l'appartenance d'une identité à l'une de ces deux classes ou à l'autre.
93
+
94
+ ```python
95
+ from nsarchive.cls.entities import Entity
96
+
97
+ entity = Entity(id='entity_id')
98
+ entity.rename('New Name')
99
+ entity.add_xp(100)
100
+ print(entity.get_level())
101
+ ```
102
+
103
+ #### `User`
104
+
105
+ ```python
106
+ from nsarchive.cls.entities import User
107
+
108
+ user = User(id = 'user_id')
109
+ user.edit_boost(name = 'admin', multiplier = 5) # Négliger le paramètre <multiplier> ou le fixer à un nombre négatif reviendrait à supprimer le boost.
110
+ print(user.boosts)
111
+ ```
112
+
113
+ > **Note:** Lorsqu'on ajoute de l'expérience à un utilisateur via la méthode `add_xp`, le nombre de points ajoutés est automatiquement multiplié par le bonus le plus important dont l'utilisateur bénéficie.
114
+
115
+ #### `Organization`
116
+
117
+ ```python
118
+ from nsarchive.cls.entities import Organization
119
+
120
+ organization = Organization(id = 'org_id')
121
+ organization.set_owner(user)
122
+ organization.add_member(user)
123
+ print(organization.members)
124
+ ```
125
+
126
+ > **Note:** Les attributs `owner` et `members` sont indépendants. L'owner peut être n'importe quelle personne faisant ou non partie des `members`.
127
+
128
+ ## Gestion des Exceptions
129
+
130
+ `nsarchive` fournit des exceptions spécifiques pour gérer les erreurs courantes.
131
+
132
+ #### `NameTooLongError`
133
+
134
+ Lancé lorsque le nom d'une entité dépasse la longueur maximale autorisée (32 caractères).
135
+
136
+ ```python
137
+ from nsarchive.cls.exceptions import NameTooLongError
138
+
139
+ try:
140
+ entity.rename('Ce nom est long, voire même très long, je dirais même extrêmement long')
141
+ except NameTooLongError as e:
142
+ print(e)
143
+ ```
144
+
145
+ #### `EntityTypeError`
146
+
147
+ Lancé lorsque le type d'entité est incorrect. Vous ne devriez normalement pas la rencontrer en utilisant le module, mais elle pourrait vous être utile.
148
+
149
+ ```python
150
+ from nsarchive.cls.exceptions import EntityTypeError
151
+
152
+ try:
153
+ # Code qui peut lancer une EntityTypeError
154
+ except EntityTypeError as e:
155
+ print(e)
156
+ ```
157
+
158
+ ## License
159
+
160
+ Ce projet est sous licence GNU GPL-3.0 - Voir le fichier [LICENSE](LICENSE) pour plus de détails.
@@ -0,0 +1,138 @@
1
+ import time
2
+
3
+ import deta
4
+
5
+ from .cls.entities import *
6
+ from .cls.votes import *
7
+
8
+ from .cls.exceptions import *
9
+
10
+ class EntityInstance:
11
+ def __init__(self, token: str) -> None:
12
+ self.db = deta.Deta(token)
13
+ self.base = self.db.Base('entities')
14
+ self.electors = self.db.Base('electors')
15
+
16
+ def get_entity(self, id: str) -> User | Organization | Entity:
17
+ id = id.upper()
18
+ _data = self.base.get(id)
19
+
20
+ if _data is None:
21
+ return Entity("0")
22
+
23
+ if _data['_type'] == 'user':
24
+ entity = User(id)
25
+ elif _data['_type'] == 'organization':
26
+ entity = Organization(id)
27
+ else:
28
+ entity = Entity(id)
29
+
30
+ entity.name = _data['name']
31
+ entity.legalPosition = _data['legalPosition'] # Métier si c'est un utilisateur, domaine professionnel si c'est un collectif
32
+ entity.registerDate = _data['registerDate']
33
+ entity.xp = _data['xp']
34
+
35
+ if type(entity) == Organization:
36
+ entity.owner = self.get_entity(_data['owner_id'].upper())
37
+ entity.members = [
38
+ self.get_entity(_id) for _id in _data['members']
39
+ ]
40
+
41
+ entity.certifications = _data['certifications']
42
+ elif type(entity) == User:
43
+ entity.boosts = _data['boosts']
44
+
45
+ return entity
46
+
47
+ def save_entity(self, entity: Entity) -> None:
48
+ _base = self.base
49
+ _data = {
50
+ '_type': 'user' if type(entity) == User else 'organization' if type(entity) == Organization else 'unknown',
51
+ 'name': entity.name,
52
+ 'legalPosition': entity.legalPosition,
53
+ 'registerDate': entity.registerDate,
54
+ 'xp': entity.xp
55
+ }
56
+
57
+ if type(entity) == Organization:
58
+ _data['owner_id'] = entity.owner.id.upper() if entity.owner else Entity("0")
59
+ _data['members'] = [ member.id.upper() for member in entity.members ] if entity.members else []
60
+ _data['certifications'] = entity.certifications
61
+ elif type(entity) == User:
62
+ _data['boosts'] = entity.boosts
63
+
64
+ _base.put(_data, entity.id.upper(), expire_in = 3 * 31536000) # Données supprimées tous les trois ans
65
+
66
+ def get_elector(self, id: str) -> Elector:
67
+ id = id.upper()
68
+ _data = self.electors.get(id)
69
+
70
+ if _data is None:
71
+ return Elector('0')
72
+
73
+ elector = Elector(id)
74
+ elector.votes = _data['votes']
75
+
76
+ return elector
77
+
78
+ def save_elector(self, elector: Elector):
79
+ _data = {
80
+ "votes": elector.votes
81
+ }
82
+
83
+ self.electors.put(_data, elector.id.upper())
84
+
85
+ def fetch(self, query = None, listquery: dict | None = None) -> list:
86
+ _res = self.base.fetch(query).items
87
+
88
+ if listquery is not None:
89
+ for item in _res:
90
+ for target, value in listquery:
91
+ if value not in item[target]:
92
+ _res.remove(item)
93
+
94
+ return _res
95
+
96
+ def get_entity_groups(self, id: int) -> list[Organization]:
97
+ groups = self.fetch({'_type': 'organization'}, {'members': str(id)})
98
+
99
+ return [ self.get_entity(int(group['id'], 16)) for group in groups ]
100
+
101
+ class RepublicInstance:
102
+ def __init__(self, token: str) -> None:
103
+ self.db = deta.Deta(token)
104
+ self.votes = self.db.Base('votes')
105
+
106
+ def get_vote(self, id: str) -> Vote | ClosedVote:
107
+ id = id.upper()
108
+ _data = self.votes.get(id)
109
+
110
+ if _data is None:
111
+ return None
112
+
113
+ if _data['_type'] == 'open':
114
+ vote = Vote(id, _data['title'], tuple(_data['choices'].keys()))
115
+ elif _data['_type'] == 'closed':
116
+ vote = ClosedVote(id, _data['title'])
117
+ else:
118
+ vote = Vote('0', 'Unknown Vote', ())
119
+
120
+ vote.author = _data['author']
121
+ vote.startDate = _data['startDate']
122
+ vote.endDate = _data['endDate']
123
+ vote.choices = _data['choices']
124
+
125
+ return vote
126
+
127
+ def save_vote(self, vote: Vote | ClosedVote):
128
+ _base = self.base
129
+ _data = {
130
+ '_type': 'open' if type(vote) == Vote else 'closed' if type(vote) == ClosedVote else 'unknown',
131
+ 'title': vote.title,
132
+ 'author': vote.author,
133
+ 'startDate': vote.startDate,
134
+ 'endDate': vote.endDate,
135
+ 'choices': vote.choices
136
+ }
137
+
138
+ _base.put(_data, vote.id.upper())
@@ -62,4 +62,29 @@ class Organization(Entity):
62
62
  self.members.remove(member)
63
63
 
64
64
  def set_owner(self, member: User) -> None:
65
- self.owner = member
65
+ self.owner = member
66
+
67
+ class Elector(User):
68
+ def __init__(self, id: str) -> None:
69
+ self.id: str = id
70
+ self.votes: list[str] = []
71
+
72
+ class FunctionalUser(User):
73
+ def __init__(self, id: str):
74
+ super().__init__(id)
75
+
76
+ self.permissions: dict = {
77
+ 'approve_project': False,
78
+ 'create_org': False,
79
+ 'destroy_gov': False,
80
+ 'destroy_org': False,
81
+ 'propose_projects': False
82
+ }
83
+
84
+ self.mandates: int = 0
85
+ self.contribs: dict = {
86
+ 'projects': 0,
87
+ 'approved_projects': 0,
88
+ 'admin_actions': 0,
89
+ 'law_votes': 0
90
+ }
@@ -0,0 +1,16 @@
1
+ import time
2
+
3
+ from .entities import FunctionalUser
4
+
5
+ class Vote:
6
+ def __init__(self, id: str, title: str, choices: tuple[str]) -> None:
7
+ self.id: str = id
8
+ self.title: str = title
9
+ self.choices = { choice : 0 for choice in choices }
10
+ self.author: FunctionalUser
11
+ self.startDate: int = 0
12
+ self.endDate: int = 0
13
+
14
+ class ClosedVote(Vote):
15
+ def __init__(self, id: str, title: str) -> None:
16
+ super().__init__(id, title, ('yes', 'no', 'blank'))
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "nsarchive"
3
- version = "0.1-alpha.0"
3
+ version = "0.2-alpha.0"
4
4
  description = ""
5
5
  authors = ["happex <110610727+okayhappex@users.noreply.github.com>"]
6
6
  license = "GPL-3.0"
nsarchive-0.1a0/PKG-INFO DELETED
@@ -1,17 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: nsarchive
3
- Version: 0.1a0
4
- Summary:
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
- Description-Content-Type: text/markdown
15
-
16
- # 1ns-archive
17
-
nsarchive-0.1a0/README.md DELETED
@@ -1 +0,0 @@
1
- # 1ns-archive
@@ -1,77 +0,0 @@
1
- import time
2
-
3
- import deta
4
-
5
- from .cls.entities import *
6
- from .cls.exceptions import *
7
-
8
- class EntityInstance:
9
- def __init__(self, token: str) -> None:
10
- self.db = deta.Deta(token)
11
- self.base = self.db.Base('entities')
12
-
13
- def get_entity(self, id: str) -> User | Organization | Entity:
14
- _base = self.base
15
- _data = _base.get(id)
16
-
17
- if _data is None:
18
- return Entity("0")
19
-
20
- if _data['_type'] == 'user':
21
- entity = User(id)
22
- elif _data['_type'] == 'organization':
23
- entity = Organization(id)
24
- else:
25
- entity = Entity(id)
26
-
27
- entity.name = _data['name']
28
- entity.legalPosition = _data['legalPosition'] # Métier si c'est un utilisateur, domaine professionnel si c'est un collectif
29
- entity.registerDate = _data['registerDate']
30
- entity.xp = _data['xp']
31
-
32
- if type(entity) == Organization:
33
- entity.owner = self.get_entity(_data['owner_id'])
34
- entity.members = [
35
- self.get_entity(_id) for _id in _data['members']
36
- ]
37
-
38
- entity.certifications = _data['certifications']
39
- elif type(entity) == User:
40
- entity.boosts = _data['boosts']
41
-
42
- return entity
43
-
44
- def save_entity(self, entity: Entity) -> None:
45
- _base = self.base
46
- _data = {
47
- '_type': 'user' if type(entity) == User else 'organization' if type(entity) == Organization else 'unknown',
48
- 'name': entity.name,
49
- 'legalPosition': entity.legalPosition,
50
- 'registerDate': entity.registerDate,
51
- 'xp': entity.xp
52
- }
53
-
54
- if type(entity) == Organization:
55
- _data['owner_id'] = entity.owner.id if entity.owner else Entity(0)
56
- _data['members'] = [ member.id for member in entity.members ] if entity.members else []
57
- _data['certifications'] = entity.certifications
58
- elif type(entity) == User:
59
- _data['boosts'] = entity.boosts
60
-
61
- _base.put(_data, entity.id, expire_in = 3 * 31536000) # Données supprimées tous les trois ans
62
-
63
- def fetch(self, query = None, listquery: dict | None = None) -> list:
64
- _res = self.base.fetch(query).items
65
-
66
- if listquery is not None:
67
- for item in _res:
68
- for target, value in listquery:
69
- if value not in item[target]:
70
- _res.remove(item)
71
-
72
- return _res
73
-
74
- def get_entity_groups(self, id: int) -> list[Organization]:
75
- groups = self.fetch({'_type': 'organization'}, {'members': str(id)})
76
-
77
- return [ self.get_entity(int(group['id'], 16)) for group in groups ]
@@ -1,7 +0,0 @@
1
- import time
2
-
3
- class Vote:
4
- def __init__(self, id: int, title: str, choices: list[str]) -> None:
5
- self.id: int = id
6
- self.title: str = title
7
- self.choices = { choice : 0 for choice in choices }
File without changes