aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-10-03 00:11:49 +0200
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-10-03 00:11:49 +0200
commit28639f99735430dc9a933a6bbd1885e4b783dca9 (patch)
treed36a26e33e36297688869118d7b35390407b121a
parent5d450d4f8ca23c00e2e0beb0287c7221dd8a207e (diff)
Starting to work well!
-rwxr-xr-xsgdfi/__main__.py10
-rwxr-xr-xsgdfi/_manager.py8
-rwxr-xr-xsgdfi/_repr.py336
-rwxr-xr-xsgdfi/_util.py18
4 files changed, 354 insertions, 18 deletions
diff --git a/sgdfi/__main__.py b/sgdfi/__main__.py
index 2b78129..27fda05 100755
--- a/sgdfi/__main__.py
+++ b/sgdfi/__main__.py
@@ -29,7 +29,7 @@ def test_repr():
op = _Operation()
op.time = _datetime(2018, 10, 1, 0, 17, 38)
- op.typename = "Individu / Abonnement "
+ op.type = "Individu / Abonnement "
op.author = "LEFEBVRE CAROLE"
op.fields = "Revue: Revue Louveteau-Jeannette, Type: Gratuit, " \
"Fin: 31/08/2019, Prix: 0,00€ "
@@ -56,12 +56,14 @@ def test_load():
man = Manager()
ret = man.load("2018100222113100-operations.html")
- print(ret)
+ for op in ret:
+ print(op)
+ print()
if __name__ == '__main__':
#test_repr()
- #test_session()
+ test_session()
#test_save()
- test_load()
+ #test_load()
# End of file.
diff --git a/sgdfi/_manager.py b/sgdfi/_manager.py
index 616f31a..62cdd48 100755
--- a/sgdfi/_manager.py
+++ b/sgdfi/_manager.py
@@ -321,7 +321,8 @@ class Manager:
except:
pass
- ch = iter(elt.find_all('td'))
+ td = elt.find_all('td')
+ ch = iter(td)
edate = next(ch).text.strip()
ename = next(ch).text.strip()
@@ -340,13 +341,12 @@ class Manager:
op = _Operation()
op.time = dt
- op.typename = etype
+ op.type = etype
op.author = ename
op.fields = edesc
# Objects decoding.
- objs = []
for link in eobjs.find_all('a'):
name = link.text
url = _urlparse(link['href'])
@@ -376,6 +376,8 @@ class Manager:
la.name = name
op.related.add(la)
+ elts.append(op)
+
return elts
def __feed_html_lieu(self, content):
diff --git a/sgdfi/_repr.py b/sgdfi/_repr.py
index 72cfc81..c1c0ac7 100755
--- a/sgdfi/_repr.py
+++ b/sgdfi/_repr.py
@@ -75,6 +75,332 @@ class Place(_Base):
# Operations (called events on the intranet).
# ---
+class OperationType(_Enum):
+ """ The default type (unknown). """
+ UNKNOWN = 0
+
+ """ Animation / Création d'une date. """
+ ANIM_DATE_NEW = 1
+
+ """ Animation / Modification d'une date. """
+ ANIM_DATE_EDIT = 2
+
+ """ Animation / Suppression d'une date. """
+ ANIM_DATE_DEL = 47
+
+ """ Bulletin d'adhésion / Impression locale d'un bulletin d'adhésion. """
+ BUL_PRINT = 3
+
+ """ Camp / Ajout d'un animateur à un camp. """
+ CAMP_ANIM_ADD = 4
+
+ """ Camp / Ajout d'un directeur à un camp. """
+ CAMP_DIR_ADD = 5
+
+ """ Camp / Ajout d'une étape d'itinéraire à un camp. """
+ CAMP_ITIN_ADD = 6
+
+ """ Camp / Commentaire pour le responsable d'accueil. """
+ CAMP_COMMENT = 7
+
+ """ Camp / Création d'un camp. """
+ CAMP_NEW = 8
+
+ """ Camp / Sauvegarde de fichier. """
+ CAMP_FILE_SAVE = 9
+
+ """ Camp / Suivi Jeunesse et Sports. """
+ CAMP_JS = 10
+
+ """ Camp / Suppression d'une étape d'itinéraire d'un camp. """
+ CAMP_ITIN_DEL = 11
+
+ """ Camp / Modification d'un animateur d'un camp. """
+ CAMP_ANIM_EDIT = 12
+
+ """ Camp / Modification d'un camp. """
+ CAMP_EDIT = 13
+
+ """ Camp / Modification d'une étape d'itinéraire d'un camp. """
+ CAMP_ITIN_EDIT = 14
+
+ """ Camp / Validation d'une étape d'un camp. """
+ CAMP_STEP_VAL = 15
+
+ """ Déclaration J&S / Affectation TAM d'un intervenant. """
+ JS_TAM_ASSIGN = 16
+
+ """ Déclaration J&S / Déclaration TAM d'un intervenant. """
+ JS_TAM_DECL = 17
+
+ """ Formation / Création d'une action de formation. """
+ TRAIN_NEW = 19
+
+ """ Formation / Envoi de notification. """
+ TRAIN_NOTIFY = 20
+
+ """ Formation / Modification d'une action de formation. """
+ TRAIN_EDIT = 21
+
+ """ Individu / Abonnement. """
+ IN_SUB = 48
+
+ """ Individu / Adhésion. """
+ IN_MEMBERSHIP = 22
+
+ """ Individu / Création. """
+ IN_NEW = 23
+
+ """ Individu / Demande de nomination. """
+ IN_NOMIN_REQUEST = 24
+
+ """ Individu / Edition de la carte d'adhérent. """
+ IN_CARD_EDIT = 25
+
+ """ Individu / Edition d'un reçu fiscal. """
+ IN_RECEIPT_EDIT = 26
+
+ """ Individu / Inscription. """
+ IN_REG = 27
+
+ """ Individu / Règlement de famille. """
+ IN_PAYMENT = 28
+
+ """ Individu / Validation demande de nomination. """
+ IN_NOMIN_REQUEST_VAL = 29
+
+ """ Individu / Validation nomination. """
+ IN_NOMIN_VAL = 30
+
+ """ Inscription / Annulation d'une demande d'inscription. """
+ REG_REQUEST_CAN = 31
+
+ """ Inscription / Création d'une demande d'inscription. """
+ REG_REQUEST_NEW = 32
+
+ """ Inscription / Validation d'une demande d'inscription. """
+ REG_REQUEST_VAL = 33
+
+ """ Inscription rassemblement / Création Demande. """
+ RALREG_REQUEST_NEW = 34
+
+ """ Inscription rassemblement / Validation Intermédiaire Demande. """
+ RALREG_REQUEST_MID_VAL = 35
+
+ """ Lieu d'activité / Création d'un lieu d'activité. """
+ PL_NEW = 36
+
+ """ Lieu d'activité / Modification d'un lieu d'activité. """
+ PL_EDIT = 37
+
+ """ Patrimoine / Assurance. """
+ PAT_INSURE = 38
+
+ """ Patrimoine / Demande d'assurance. """
+ PAT_INSURE_REQUEST = 39
+
+ """ Patrimoine / Modification. """
+ PAT_EDIT = 40
+
+ """ Projet pédagogique / Import d'un fichier matrice. """
+ PEDA_XLS_IMPORT = 41
+
+ """ Projet pédagogique / Suppression d'un fichier matrice. """
+ PEDA_XLS_DEL = 42
+
+ """ Structure / Création. """
+ ST_NEW = 43
+
+ """ Structure / Définition date début d'activité. """
+ ST_START = 44
+
+ """ Structure / Modification spécialités. """
+ ST_SPEC = 45
+
+ """ Structure / Recopie nouvelle saison. """
+ ST_COPY = 46
+
+ # TODO: other types (last index: 49).
+
+_OperationTypeCodes = {
+ "Animation / Création d'une date": \
+ OperationType.ANIM_DATE_NEW,
+ "Animation / Modification d'une date": \
+ OperationType.ANIM_DATE_EDIT,
+ "Animation / Suppression d'une date": \
+ OperationType.ANIM_DATE_DEL,
+ "Bulletin d'adhésion / Impression locale d'un bulletin d'adhésion": \
+ OperationType.BUL_PRINT,
+ "Camp / Ajout d'un animateur à un camp": \
+ OperationType.CAMP_ANIM_ADD,
+ "Camp / Ajout d'un directeur à un camp": \
+ OperationType.CAMP_DIR_ADD,
+ "Camp / Ajout d'une étape d'itinéraire à un camp": \
+ OperationType.CAMP_ITIN_ADD,
+ "Camp / Commentaire pour le responsable d'accueil": \
+ OperationType.CAMP_COMMENT,
+ "Camp / Création d'un camp": \
+ OperationType.CAMP_NEW,
+ "Camp / Sauvegarde de fichier": \
+ OperationType.CAMP_FILE_SAVE,
+ "Camp / Suivi Jeunesse et Sports": \
+ OperationType.CAMP_JS,
+ "Camp / Suppression d'une étape d'itinéraire d'un camp": \
+ OperationType.CAMP_ITIN_DEL,
+ "Camp / Modification d'un animateur d'un camp": \
+ OperationType.CAMP_ANIM_EDIT,
+ "Camp / Modification d'un camp": \
+ OperationType.CAMP_EDIT,
+ "Camp / Modification d'une étape d'itinéraire d'un camp": \
+ OperationType.CAMP_ITIN_EDIT,
+ "Camp / Validation d'une étape d'un camp": \
+ OperationType.CAMP_STEP_VAL,
+ "Déclaration J&S / Affectation TAM d'un intervenant": \
+ OperationType.JS_TAM_ASSIGN,
+ "Déclaration J&S / Déclaration TAM d'un intervenant": \
+ OperationType.JS_TAM_DECL,
+ "Formation / Création d'une action de formation": \
+ OperationType.TRAIN_NEW,
+ "Formation / Envoi de notification": \
+ OperationType.TRAIN_NOTIFY,
+ "Formation / Modification d'une action de formation": \
+ OperationType.TRAIN_EDIT,
+ "Individu / Abonnement": \
+ OperationType.IN_SUB,
+ "Individu / Adhésion": \
+ OperationType.IN_MEMBERSHIP,
+ "Individu / Création": \
+ OperationType.IN_NEW,
+ "Individu / Demande de nomination": \
+ OperationType.IN_NOMIN_REQUEST,
+ "Individu / Edition de la carte d'adhérent": \
+ OperationType.IN_CARD_EDIT,
+ "Individu / Edition d'un reçu fiscal": \
+ OperationType.IN_RECEIPT_EDIT,
+ "Individu / Inscription": \
+ OperationType.IN_REG,
+ "Individu / Règlement de famille": \
+ OperationType.IN_PAYMENT,
+ "Individu / Validation demande de nomination": \
+ OperationType.IN_NOMIN_REQUEST_VAL,
+ "Individu / Validation nomination": \
+ OperationType.IN_NOMIN_VAL,
+ "Inscription / Annulation d'une demande d'inscription": \
+ OperationType.REG_REQUEST_CAN,
+ "Inscription / Création d'une demande d'inscription": \
+ OperationType.REG_REQUEST_NEW,
+ "Inscription / Validation d'une demande d'inscription": \
+ OperationType.REG_REQUEST_VAL,
+ "Inscription rassemblement / Création Demande": \
+ OperationType.RALREG_REQUEST_NEW,
+ "Inscription rassemblement / Validation Intermédiaire Demande": \
+ OperationType.RALREG_REQUEST_MID_VAL,
+ "Lieu d'activité / Création d'un lieu d'activité": \
+ OperationType.PL_NEW,
+ "Lieu d'activité / Modification d'un lieu d'activité": \
+ OperationType.PL_EDIT,
+ "Patrimoine / Assurance": \
+ OperationType.PAT_INSURE,
+ "Patrimoine / Demande d'assurance": \
+ OperationType.PAT_INSURE_REQUEST,
+ "Patrimoine / Modification": \
+ OperationType.PAT_EDIT,
+ "Projet pédagogique / Import d'un fichier matrice": \
+ OperationType.PEDA_XLS_IMPORT,
+ "Projet pédagogique / Suppression d'un fichier matrice": \
+ OperationType.PEDA_XLS_DEL,
+ "Structure / Création": \
+ OperationType.ST_NEW,
+ "Structure / Définition date début d'activité": \
+ OperationType.ST_START,
+ "Structure / Modification spécialités": \
+ OperationType.ST_SPEC,
+ "Structure / Recopie nouvelle saison": \
+ OperationType.ST_COPY,
+}
+
+_OperationTypeCodes = {a.strip().casefold(): b \
+ for a, b in _OperationTypeCodes.items()}
+_OperationTypeNames = {b: a for a, b in _OperationTypeCodes.items()}
+
+class _OperationTypeData:
+ """ Operation type data (name and id). """
+
+ def __init__(self, code, name):
+ self.__code = code
+ self.__name = name
+ self.__ncmp = name.strip().casefold() if name is not None else None
+
+ def __repr__(self):
+ p = [f"code = {repr(self.__code)}"]
+ if self.__name is not None:
+ p.append(f"name = {repr(self.__name)}")
+
+ return f"{self.__class__.__name__}({', '.join(p)})"
+
+ def __eq__(self, value):
+ if isinstance(value, _OperationTypeData):
+ if value.name is None:
+ return self.__code == value.code
+ else:
+ return self.__ncmp == value.name.strip().casefold()
+ elif type(value) == str:
+ return self.__ncmp == value.strip().casefold()
+ else:
+ return self.__code == value
+
+ def __str__(self):
+ if self.__name is not None:
+ return self.__name
+ else:
+ return "Inconnu"
+
+ @property
+ def code(self):
+ """ The type code, as one of the operation types defined in the
+ OperationType enumeration. """
+
+ return self.__code
+
+ @property
+ def name(self):
+ """ The type name as defined in the operations journal. """
+
+ return self.__name
+
+class _OperationTypeProperty(_Property):
+ """ Operation type. """
+
+ def init(self):
+ self.__data = None
+
+ def get(self):
+ return self.__data
+
+ def set(self, value):
+ if value is None:
+ self.__data = None
+ return
+
+ try:
+ value = OperationType(value)
+ self.__data = _OperationTypeData(value,
+ _OperationTypeNames.get(value, None))
+ return
+ except ValueError:
+ pass
+
+ if type(value) != str:
+ raise ValueError("Expected either a string, an OperationType " \
+ "or None.")
+
+ can = value.strip().casefold()
+ self.__data = _OperationTypeData(_OperationTypeCodes.get(can,
+ OperationType.UNKNOWN), value)
+
+ def delete(self):
+ self.__data = None
+
class _OperationFieldsProperty(_Property):
""" Operation fields. """
@@ -129,19 +455,11 @@ class _OperationFieldsProperty(_Property):
def delete(self):
self.__value = None
-class OperationType(_Enum):
- """ The default type (unknown). """
- UNKNOWN = 0
-
- # TODO: other types.
-
class Operation(_Base):
""" An event on the website.. """
time = _DateProperty()
- type = _EnumProperty(enum = OperationType,
- default = OperationType.UNKNOWN)
- typename = _TextProperty()
+ type = _OperationTypeProperty()
author = _TextProperty()
fields = _OperationFieldsProperty()
related = _ArrayProperty(types = (Structure, Adherent,
diff --git a/sgdfi/_util.py b/sgdfi/_util.py
index def9ecd..1156705 100755
--- a/sgdfi/_util.py
+++ b/sgdfi/_util.py
@@ -7,6 +7,7 @@
directly. """
from inspect import getargspec as _getargspec
+from copy import deepcopy as _deepcopy
from urllib.parse import quote as _quote
from enum import Enum
from datetime import datetime as _datetime
@@ -353,16 +354,29 @@ class TextProperty(Property):
class Base:
""" The base class for all complex objects. """
+ def __init__(self):
+ for name in self.__findprops():
+ super().__setattr__(name,
+ _deepcopy(super().__getattribute__(name)))
+
def __repr__(self):
def getproperty(self, name):
return super().__getattribute__(name)
attrs = lambda: (f"{i} = {repr(getproperty(self, i).get())}" \
- for i in dir(self) if not i.startswith('_') \
- and isinstance(getproperty(self, i), Property))
+ for i in self.__findprops())
return f"{self.__class__.__name__}({', '.join(attrs())})"
+ def __findprops(self):
+ """ Find the properties' names. """
+
+ def getproperty(self, name):
+ return super().__getattribute__(name)
+
+ return [i for i in dir(self) if not i.startswith('_') \
+ and isinstance(getproperty(self, i), Property)]
+
def __getattribute__(self, name):
try:
attr = super().__getattribute__(name)