aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-10-29 16:54:39 +0100
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-10-29 16:54:39 +0100
commit3b308c48415811ffcefef62be8a9c6439f556a5c (patch)
tree10d35bcb4062d74b69f09f2db0be6f00a0e01111
parent33fa1bacec308d9eb65a645fcbd92c95dfc7c86a (diff)
Starts to work, but I have to add the request optimization for structure paging to work.
-rwxr-xr-xsgdfi/_dbs/_dept.py27
-rwxr-xr-xsgdfi/_dbs/_st.py4
-rwxr-xr-xsgdfi/_dbs/_stspe.py2
-rwxr-xr-xsgdfi/_dbs/_ststatus.py10
-rwxr-xr-xsgdfi/_decode.py39
-rwxr-xr-xsgdfi/_intranet.py92
-rwxr-xr-xsgdfi/_repr.py10
-rwxr-xr-xsgdfi/_util.py5
8 files changed, 143 insertions, 46 deletions
diff --git a/sgdfi/_dbs/_dept.py b/sgdfi/_dbs/_dept.py
index b33c212..5c55ce7 100755
--- a/sgdfi/_dbs/_dept.py
+++ b/sgdfi/_dbs/_dept.py
@@ -343,6 +343,9 @@ class Department(_Enum):
MONDE = 999
_DepartmentData = {
+ Department.UNKNOWN: \
+ (None, "Tous", -1),
+
Department.NONE: \
("00", "Non précisé", 9023),
Department.AIN: \
@@ -567,7 +570,7 @@ def _normalize(value):
""" Normalize a string for comparison. """
return ''.join(c for c in _udnormalize('NFD', value.casefold()) \
- if c in 'abcdefghijklmnopqrstuvwxyz')
+ if c in 'abcdefghijklmnopqrstuvwxyz0123456789')
# Leads are the following:
# - intranet internal identifier.
@@ -579,14 +582,16 @@ def _normalize(value):
_DepartmentLeads = {}
_DepartmentLeads.update({_normalize(name): i for i, (dcode, name, ii) \
in _DepartmentData.items()})
-_DepartmentLeads.update({dcode: i for i, (dcode, name, ii) \
- in _DepartmentData.items()})
+_DepartmentLeads.update({_normalize(dcode): i for i, (dcode, name, ii) \
+ in _DepartmentData.items() if dcode is not None})
_DepartmentLeads.update({ii: i for i, (dcode, name, ii) \
in _DepartmentData.items()})
_DepartmentLeads.update({str(ii): i for i, (dcode, name, ii) \
in _DepartmentData.items()})
_DepartmentLeads.update({_normalize(f"{dcode} - {name}"): i \
- for i, (dcode, name, ii) in _DepartmentData.items()})
+ for i, (dcode, name, ii) in _DepartmentData.items() if dcode is not None})
+_DepartmentLeads.update({_normalize(f"{name} - {dcode}"): i \
+ for i, (dcode, name, ii) in _DepartmentData.items() if dcode is not None})
class DepartmentData:
""" Department data (id, name, …). """
@@ -605,29 +610,29 @@ class DepartmentData:
self.__ii = None
data = None
- if isinstance(value, StructureTypeData):
+ if isinstance(value, DepartmentData):
self.__id = value.id
self.__ii = value.iid
self.__dcode = value.displayed_code
self.__name = value.name
elif isid(value):
- value = StructureType(value)
+ value = Department(value)
self.__id = value
- data = _StructureTypeData.get(value, None)
+ data = _DepartmentData.get(value, None)
else:
lead = value
if type(lead) == str:
lead = _normalize(lead)
try:
- self.__id = _StructureTypeLeads[lead]
- data = _StructureTypeData.get(self.__id, None)
+ self.__id = _DepartmentLeads[lead]
+ data = _DepartmentData.get(self.__id, None)
except KeyError:
if type(value) == str:
self.__name = value
else:
- raise ValueError("Could not determine a structure type.") \
+ raise ValueError("Could not determine a department.") \
from None
if data is not None:
@@ -644,7 +649,7 @@ class DepartmentData:
if self.__name is not None:
p.append(f"name = {repr(self.__name)}")
if self.__ii is not None:
- p.append(f"iid = {repr(self.__iid)}")
+ p.append(f"iid = {repr(self.__ii)}")
return f"{self.__class__.__name__}({', '.join(p)})"
diff --git a/sgdfi/_dbs/_st.py b/sgdfi/_dbs/_st.py
index 0b9e92c..e5f669a 100755
--- a/sgdfi/_dbs/_st.py
+++ b/sgdfi/_dbs/_st.py
@@ -61,6 +61,8 @@ class StructureType(_Enum):
# - internal code.
_StructureTypeData = {
+ StructureType.UNKNOWN: ("Tous", -1),
+
StructureType.AUTRES: ("Autres", 1211),
StructureType.SOMMET: ("Sommet", 1205),
@@ -138,7 +140,7 @@ class StructureTypeData:
if self.__name is not None:
p.append(f"name = {repr(self.__name)}")
if self.__ii is not None:
- p.append(f"iid = {repr(self.__iid)}")
+ p.append(f"iid = {repr(self.__ii)}")
return f"{self.__class__.__name__}({', '.join(p)})"
diff --git a/sgdfi/_dbs/_stspe.py b/sgdfi/_dbs/_stspe.py
index 55da554..f85001a 100755
--- a/sgdfi/_dbs/_stspe.py
+++ b/sgdfi/_dbs/_stspe.py
@@ -28,6 +28,8 @@ class StructureSpeciality(_Enum):
# - internal code.
_StructureSpecialityData = {
+ StructureSpeciality.UNKNOWN: ("Toutes", -1),
+
StructureSpeciality.WITHOUT: ("sans spécialité", 624),
StructureSpeciality.MARINE: ("Marine", 622),
StructureSpeciality.VENT_DU_LARGE: ("Vent du Large", 623),
diff --git a/sgdfi/_dbs/_ststatus.py b/sgdfi/_dbs/_ststatus.py
index d77df05..192c0fe 100755
--- a/sgdfi/_dbs/_ststatus.py
+++ b/sgdfi/_dbs/_ststatus.py
@@ -12,22 +12,24 @@ __all__ = ["StructureStatus", "StructureStatusData"]
@_unique
class StructureStatus(_Enum):
""" The default status (unknown). """
- UNKNOWN = 0
+ UNKNOWN = -1
""" Ouverte. """
- OPEN = 1
+ OPEN = 0
""" Fermée. """
- CLOSED = 2
+ CLOSED = 1
""" Suspendue. """
- SUSPENDED = 3
+ SUSPENDED = 2
# Structure status data.
# - name.
# - internal identifier on the intranet.
_StructureStatusData = {
+ StructureStatus.UNKNOWN: ("Tous", -1),
+
StructureStatus.OPEN: ("Ouverte", 0),
StructureStatus.CLOSED: ("Fermée", 1),
StructureStatus.SUSPENDED: ("Suspendue", 2)
diff --git a/sgdfi/_decode.py b/sgdfi/_decode.py
index 383e2c3..b6b359f 100755
--- a/sgdfi/_decode.py
+++ b/sgdfi/_decode.py
@@ -395,6 +395,8 @@ class Decoder:
else:
raise ValueError(f"unknown type: {repr(type)}")
+ return result
+
# ---
# HTML pages decoding.
# ---
@@ -435,7 +437,9 @@ class Decoder:
numpages = 1
more = False
- return _Pagination(curpage, numpages, more)
+ pgn = _Pagination(curpage, numpages, more)
+ print(pgn)
+ return pgn
def _decode_html_intranet_operations(self, tree):
""" Decode the HTML operations from a BeautifulSoup decoded
@@ -700,16 +704,39 @@ class Decoder:
""" Decode the HTML search results for structures from a
BeautifulSoup decoded content. """
- print(tree)
-
parent = tree.find(id = 'ctl00_Popup__recherche__gvResultats')
elts = []
# Récupération de la pagination.
- #elts.append(self.__get_html_pagination(parent))
-
- # TODO: récupération des structures.
+ pgn = self.__get_html_pagination(parent)
+ elts.append(pgn)
+
+ # Récupération des structures.
+
+ search_attrs = {'class': ['ligne1', 'ligne2']}
+ for tr in parent.find_all('tr', attrs = search_attrs):
+ tds = tr.find_all('td')
+ name = tds[1].find('span').text
+ sta = tds[2].find('span').text
+ dep = tds[3].find('span').text
+ typ = tds[4].find('span').text
+ telsp = tds[5].find('span')
+ tel = telsp.text if telsp is not None else ""
+
+ code, *name = name.split('-')
+ code = code.rstrip()
+ name = '-'.join(name).lstrip()
+
+ st = _Structure()
+ st.name = name
+ st.code = code
+ st.status = sta
+ st.department = dep
+ st.type = typ
+ st.phone = tel
+
+ elts.append(st)
return elts
diff --git a/sgdfi/_intranet.py b/sgdfi/_intranet.py
index c37c46c..497a1e9 100755
--- a/sgdfi/_intranet.py
+++ b/sgdfi/_intranet.py
@@ -27,9 +27,18 @@ from ._util import InvalidCredentialsError as _InvalidCredentialsError, \
UnauthorizedAccountError as _UnauthorizedAccountError, \
RedirectError as _RedirectError, BadRequestError as _BadRequestError, \
NotFoundError as _NotFoundError, Pagination as _Pagination
+from ._dbs import StructureType as _StructureType, \
+ StructureTypeData as _StructureTypeData, \
+ StructureStatus as _StructureStatus, \
+ StructureStatusData as _StructureStatusData, \
+ StructureSpeciality as _StructureSpeciality, \
+ StructureSpecialityData as _StructureSpecialityData, \
+ Department as _Department, \
+ DepartmentData as _DepartmentData
__all__ = ["AnonymousIntranetSession", "IntranetSession"]
+_type = type
_monotime = lambda: _getclocktime(_MONOCLOCK)
# ---
@@ -561,19 +570,22 @@ class IntranetSession(AnonymousIntranetSession):
# Récupération du document et décodage.
resp = self._get_ops_page(ent_type, ent_iid, page)
- pgn = next(e for e in resp if isinstance(e, _Pagination))
- # Si `pgn.current < page`, alors c'est un bug connu de l'intranet
- # où une page est déclarée mais inaccessible, on arrête donc là.
+ pgn_idx = next(idx for idx, e in enumerate(result) \
+ if isinstance(e, _Pagination))
+ pgn = result.pop(pgn_idx)
+
+ # If `pgn.current < page`, then its a known bug of the intranet
+ # where page is declared but inaccessible, so let's stop here.
if pgn.current < page:
break
- # Ajout des activités à la liste totale.
+ # Let's add the obtained structures to the result.
activities.extend(resp)
- # Vérifions si on est arrivés au bout.
+ # And check if we're at the end.
if page == pgn.number and not pgn.more:
break
@@ -594,40 +606,80 @@ class IntranetSession(AnonymousIntranetSession):
pl.iid = iid
return pl
- def _get_structures_page(self, page):
+ def _get_structures_page(self, page, st_name, st_dept, st_type, st_spe,
+ st_sta):
""" Get a structures page. """
- # FIXME: this matches the URL, ~headers and POST parameters of the
- # request on the Firefox DevTools, still, it doesn't get the
- # freaking results and I don't freaking know why!!!!
-
iid = _IID('fCx2YIJV6Qq+qLBWSyMcwA==')
path = '/Specialisation/Sgdf/Popups/RechercheStructure.aspx?' \
f'dummy=1&operations={iid.urlsafe()}'
- result = self.get_page(path, {
+ args = {
'__EVENTARGUMENT': f"Page${page}",
'__EVENTTARGET': 'ctl00$Popup$_recherche$_gvResultats',
'ctl00_Popup__recherche__pnlFormulaire_CurrentState': 'true',
'ctl00$Popup$_recherche': {
- '_ddDepartement': '-1',
- '_ddSpecialite': '-1',
- '_ddStatut': '-1',
- '_ddTypeStructure': '-1',
+ '_ddDepartement': st_dept,
+ '_ddSpecialite': st_spe,
+ '_ddStatut': st_sta,
+ '_ddTypeStructure': st_type,
'_tbCodePostal': '',
'_tbCodeStructure': '',
'_tbLocalite': '',
'_tbMarqueur': '',
- '_tbNom': '',
+ '_tbNom': st_name,
'Rechercher': None,
- '_btnAnnuler': None}},
- method = self.METHOD_FORM,
+ 'Rechercher.x': '45',
+ 'Rechercher.y': '5',
+ '_btnAnnuler': None}}
+
+ return self.get_page(path, args, method = self.METHOD_FORM,
hint = 'intranet_structure_search')
- def get_structures(self):
+ def get_structures(self, name = "", *_,
+ department = _Department.UNKNOWN,
+ type = _StructureType.UNKNOWN,
+ speciality = _StructureSpeciality.UNKNOWN,
+ status = _StructureStatus.UNKNOWN):
""" Search through structures. """
- return self._get_structures_page(5)
+ if _type(name) != str:
+ raise ValueError("expected a string name")
+ department = _DepartmentData(department)
+ type = _StructureTypeData(type)
+ speciality = _StructureSpecialityData(speciality)
+ status = _StructureStatusData(status)
+
+ # Get each page until the end.
+
+ elts = []
+
+ for page in _count(1):
+ # Get the elements request, and isolate the pagination.
+
+ result = self._get_structures_page(page, name,
+ department.iid, type.iid, speciality.iid, status.iid)
+
+ pgn_idx = next(idx for idx, e in enumerate(result) \
+ if isinstance(e, _Pagination))
+ pgn = result.pop(pgn_idx)
+
+ # If `pgn.current < page`, then its a known bug of the intranet
+ # where page is declared but inaccessible, so let's stop here.
+
+ if pgn.current < page:
+ break
+
+ # Let's add the obtained structures to the result.
+
+ elts.extend(result)
+
+ # And check if we're at the end.
+
+ if page == pgn.number and not pgn.more:
+ break
+
+ return elts
def get_structure(self, st_id):
""" Get a structure's data. """
diff --git a/sgdfi/_repr.py b/sgdfi/_repr.py
index 153c853..c6c6a5c 100755
--- a/sgdfi/_repr.py
+++ b/sgdfi/_repr.py
@@ -13,16 +13,18 @@ from ._util import IID, Enum as _Enum, \
BoolProperty as _BoolProperty, EnumProperty as _EnumProperty, \
ArrayProperty as _ArrayProperty, TextProperty as _TextProperty, \
ObjectProperty as _ObjectProperty, ValueProperty as _ValueProperty
-from ._dbs import OperationType, OperationTypeData as _OperationTypeData, \
+from ._dbs import Department, DepartmentData as _DepartmentData, \
+ OperationType, OperationTypeData as _OperationTypeData, \
Function, FunctionRawData, FunctionData as _FunctionData, StructureType, \
StructureTypeData as _StructureTypeData, StructureStatus, \
- StructureStatusData as _StructureStatusData, \
+ StructureStatusData as _StructureStatusData, StructureSpeciality, \
+ StructureSpecialityData as _StructureSpecialityData, \
AllocationsRegime, EventTypeData as _EventTypeData, Code as _Code
__all__ = ["Base", "IID", "Title", "Structure", "Adherent",
"RallyRegistration", "Camp", "Place", "Operation", "OperationType",
"Function", "Event", "StructureType", "StructureStatus",
- "AllocationsRegime"]
+ "StructureSpeciality", "AllocationsRegime", "Department"]
_Base = Base
@@ -255,7 +257,7 @@ class Structure(_Base):
postal_code = _TextProperty()
town = _TextProperty()
country = _TextProperty(not_empty = True)
- department = _TextProperty()
+ department = _ValueProperty(cls = _DepartmentData)
phone = _TextProperty(not_empty = True)
fax = _TextProperty(not_empty = True)
email = _TextProperty(not_empty = True)
diff --git a/sgdfi/_util.py b/sgdfi/_util.py
index 112f58c..a639c4b 100755
--- a/sgdfi/_util.py
+++ b/sgdfi/_util.py
@@ -568,4 +568,9 @@ class Pagination:
self.number = number
self.more = more
+ def __repr__(self):
+ p = (f"current = {repr(self.current)}",
+ f"number = {repr(self.number)}", f"more = {repr(self.more)}")
+ return f"{self.__class__.__name__}({', '.join(p)})"
+
# End of file.