From 288cbaa2da61200dc0d14fe50ac7b273f3a5a1ae Mon Sep 17 00:00:00 2001 From: Giga77 <2777446+Giga77@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:38:43 +0200 Subject: [PATCH 1/4] Add working path --- custom_components/ecole_directe/config_flow.py | 4 +++- custom_components/ecole_directe/coordinator.py | 4 +++- custom_components/ecole_directe/ecole_directe_helper.py | 8 +++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/custom_components/ecole_directe/config_flow.py b/custom_components/ecole_directe/config_flow.py index ec9cdf2..92257ab 100644 --- a/custom_components/ecole_directe/config_flow.py +++ b/custom_components/ecole_directe/config_flow.py @@ -49,7 +49,9 @@ async def async_step_user(self, user_input: dict | None = None) -> FlowResult: try: self._user_inputs.update(user_input) session = await self.hass.async_add_executor_job( - get_ecoledirecte_session, self._user_inputs + get_ecoledirecte_session, + self._user_inputs, + self.hass.config.config_dir, ) if session is None: diff --git a/custom_components/ecole_directe/coordinator.py b/custom_components/ecole_directe/coordinator.py index c9976ab..ecf23cf 100644 --- a/custom_components/ecole_directe/coordinator.py +++ b/custom_components/ecole_directe/coordinator.py @@ -55,7 +55,9 @@ async def _async_update_data(self) -> dict[Platform, dict[str, Any]]: data = self.config_entry.data - session = await self.hass.async_add_executor_job(get_ecoledirecte_session, data) + session = await self.hass.async_add_executor_job( + get_ecoledirecte_session, data, self.hass.config.config_dir + ) if session is None: _LOGGER.error("Unable to init ecole directe client") diff --git a/custom_components/ecole_directe/ecole_directe_helper.py b/custom_components/ecole_directe/ecole_directe_helper.py index 7a10511..11cce0e 100644 --- a/custom_components/ecole_directe/ecole_directe_helper.py +++ b/custom_components/ecole_directe/ecole_directe_helper.py @@ -284,7 +284,7 @@ def __init__(self, data): self.elements_programme = "" -def get_ecoledirecte_session(data) -> EDSession | None: +def get_ecoledirecte_session(data, config_path) -> EDSession | None: """Function connecting to Ecole Directe""" try: payload = ( @@ -299,7 +299,7 @@ def get_ecoledirecte_session(data) -> EDSession | None: # Si connexion initiale if login["code"] == 250: with open( - "config/custom_components/ecole_directe/qcm.json", + config_path + "/custom_components/ecole_directe/qcm.json", encoding="utf-8", ) as f: qcm_json = json.load(f) @@ -336,7 +336,7 @@ def get_ecoledirecte_session(data) -> EDSession | None: qcm_json[question] = rep with open( - "config/custom_components/ecole_directe/qcm.json", + config_path + "/custom_components/ecole_directe/qcm.json", "w", encoding="utf-8", ) as f: @@ -371,6 +371,8 @@ def get_ecoledirecte_session(data) -> EDSession | None: login["data"]["accounts"][0]["identifiant"], ) return EDSession(login) + except QCMError: + raise except Exception as err: _LOGGER.critical(err) return None From 333d0c26ae2805192ae7c6232cbc1a66aca3ddec Mon Sep 17 00:00:00 2001 From: Giga77 <2777446+Giga77@users.noreply.github.com> Date: Sun, 21 Apr 2024 21:04:20 +0200 Subject: [PATCH 2/4] add QCM error --- custom_components/ecole_directe/config_flow.py | 3 +++ custom_components/ecole_directe/ecole_directe_helper.py | 3 +++ custom_components/ecole_directe/strings.json | 1 + custom_components/ecole_directe/translations/en.json | 1 + custom_components/ecole_directe/translations/fr.json | 1 + 5 files changed, 9 insertions(+) diff --git a/custom_components/ecole_directe/config_flow.py b/custom_components/ecole_directe/config_flow.py index 92257ab..1d1f4e6 100644 --- a/custom_components/ecole_directe/config_flow.py +++ b/custom_components/ecole_directe/config_flow.py @@ -13,6 +13,7 @@ from homeassistant.core import callback from .ecole_directe_helper import ( + QCMError, get_ecoledirecte_session, ) @@ -60,6 +61,8 @@ async def async_step_user(self, user_input: dict | None = None) -> FlowResult: return self.async_create_entry( title=session.identifiant, data=self._user_inputs ) + except QCMError: + errors["base"] = "double_auth" except InvalidAuth: errors["base"] = "invalid_auth" diff --git a/custom_components/ecole_directe/ecole_directe_helper.py b/custom_components/ecole_directe/ecole_directe_helper.py index 11cce0e..335ebb9 100644 --- a/custom_components/ecole_directe/ecole_directe_helper.py +++ b/custom_components/ecole_directe/ecole_directe_helper.py @@ -312,6 +312,9 @@ def get_ecoledirecte_session(data, config_path) -> EDSession | None: question = base64.b64decode(qcm["question"]).decode("utf-8") if qcm_json is not None and question in qcm_json: + if len(qcm_json[question]) > 1: + try_login -= 1 + continue reponse = base64.b64encode( bytes(qcm_json[question][0], "utf-8") ).decode("ascii") diff --git a/custom_components/ecole_directe/strings.json b/custom_components/ecole_directe/strings.json index 99186bf..a7d823a 100644 --- a/custom_components/ecole_directe/strings.json +++ b/custom_components/ecole_directe/strings.json @@ -19,6 +19,7 @@ "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", + "double_auth": "[%key:common::config_flow::error::double_auth%]", "unknown": "[%key:common::config_flow::error::unknown%]" }, "abort": { diff --git a/custom_components/ecole_directe/translations/en.json b/custom_components/ecole_directe/translations/en.json index 979fe2a..5f93fe1 100644 --- a/custom_components/ecole_directe/translations/en.json +++ b/custom_components/ecole_directe/translations/en.json @@ -8,6 +8,7 @@ "error": { "cannot_connect": "Failed to connect", "invalid_auth": "Invalid authentication", + "double_auth": "Check the file qcm.json", "unknown": "Unexpected error" }, "step": { diff --git a/custom_components/ecole_directe/translations/fr.json b/custom_components/ecole_directe/translations/fr.json index b816678..b667976 100644 --- a/custom_components/ecole_directe/translations/fr.json +++ b/custom_components/ecole_directe/translations/fr.json @@ -8,6 +8,7 @@ "error": { "cannot_connect": "Impossible de se connecter", "invalid_auth": "Erreur d'authentification", + "double_auth": "Vérifier le fichier qcm.json", "unknown": "Une erreur est survenue" }, "step": { From 95b54d6d0e78743b9f41dcbbbc2aa24ccc7b6e4f Mon Sep 17 00:00:00 2001 From: Giga77 <2777446+Giga77@users.noreply.github.com> Date: Mon, 22 Apr 2024 21:24:59 +0200 Subject: [PATCH 3/4] add event for new queston on qcm --- custom_components/ecole_directe/config_flow.py | 2 ++ custom_components/ecole_directe/coordinator.py | 2 +- .../ecole_directe/ecole_directe_helper.py | 13 +++++-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/custom_components/ecole_directe/config_flow.py b/custom_components/ecole_directe/config_flow.py index 1d1f4e6..5f2aa70 100644 --- a/custom_components/ecole_directe/config_flow.py +++ b/custom_components/ecole_directe/config_flow.py @@ -20,6 +20,7 @@ from .const import ( DOMAIN, DEFAULT_REFRESH_INTERVAL, + EVENT_TYPE, ) _LOGGER = logging.getLogger(__name__) @@ -53,6 +54,7 @@ async def async_step_user(self, user_input: dict | None = None) -> FlowResult: get_ecoledirecte_session, self._user_inputs, self.hass.config.config_dir, + self.hass, ) if session is None: diff --git a/custom_components/ecole_directe/coordinator.py b/custom_components/ecole_directe/coordinator.py index ecf23cf..258abc1 100644 --- a/custom_components/ecole_directe/coordinator.py +++ b/custom_components/ecole_directe/coordinator.py @@ -56,7 +56,7 @@ async def _async_update_data(self) -> dict[Platform, dict[str, Any]]: data = self.config_entry.data session = await self.hass.async_add_executor_job( - get_ecoledirecte_session, data, self.hass.config.config_dir + get_ecoledirecte_session, data, self.hass.config.config_dir, self.hass ) if session is None: diff --git a/custom_components/ecole_directe/ecole_directe_helper.py b/custom_components/ecole_directe/ecole_directe_helper.py index 335ebb9..d25af54 100644 --- a/custom_components/ecole_directe/ecole_directe_helper.py +++ b/custom_components/ecole_directe/ecole_directe_helper.py @@ -7,6 +7,8 @@ import base64 import requests +from .const import EVENT_TYPE + _LOGGER = logging.getLogger(__name__) APIURL = "https://api.ecoledirecte.com/v3" @@ -284,7 +286,7 @@ def __init__(self, data): self.elements_programme = "" -def get_ecoledirecte_session(data, config_path) -> EDSession | None: +def get_ecoledirecte_session(data, config_path, hass) -> EDSession | None: """Function connecting to Ecole Directe""" try: payload = ( @@ -344,6 +346,8 @@ def get_ecoledirecte_session(data, config_path) -> EDSession | None: encoding="utf-8", ) as f: json.dump(qcm_json, f, ensure_ascii=False, indent=4) + event_data = {"type": "new_qcm", "question": question} + hass.bus.async_fire(EVENT_TYPE, event_data) try_login -= 1 @@ -506,10 +510,3 @@ def get_headers(token): headers["X-Token"] = token return headers - - -def is_login(session): - """Ckeck valid login""" - if session.token is not None and session.id is not None: - return True - return False From e1f3b96c094f4445c910e833de83cc0af3a92c49 Mon Sep 17 00:00:00 2001 From: Giga77 <2777446+Giga77@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:43:48 +0200 Subject: [PATCH 4/4] Don't raise an error on setup if double authentication is required --- .../ecole_directe/config_flow.py | 25 ++++++++++++------- .../ecole_directe/ecole_directe_helper.py | 15 +++++++++-- custom_components/ecole_directe/qcm.json | 2 -- 3 files changed, 29 insertions(+), 13 deletions(-) delete mode 100644 custom_components/ecole_directe/qcm.json diff --git a/custom_components/ecole_directe/config_flow.py b/custom_components/ecole_directe/config_flow.py index 5f2aa70..4fd633c 100644 --- a/custom_components/ecole_directe/config_flow.py +++ b/custom_components/ecole_directe/config_flow.py @@ -2,9 +2,10 @@ from __future__ import annotations +import json +import os.path import logging from typing import Any - import voluptuous as vol from homeassistant import config_entries @@ -13,14 +14,12 @@ from homeassistant.core import callback from .ecole_directe_helper import ( - QCMError, - get_ecoledirecte_session, + check_ecoledirecte_session, ) from .const import ( DOMAIN, DEFAULT_REFRESH_INTERVAL, - EVENT_TYPE, ) _LOGGER = logging.getLogger(__name__) @@ -47,24 +46,32 @@ async def async_step_user(self, user_input: dict | None = None) -> FlowResult: """Handle a flow initialized by the user.""" _LOGGER.debug("ED - Setup process initiated by user.") errors: dict[str, str] = {} + + path = self.hass.config.config_dir + "/custom_components/ecole_directe/qcm.json" + if not os.path.isfile(path): + with open( + path, + "w", + encoding="utf-8", + ) as f: + json.dump({}, f, ensure_ascii=False, indent=4) + if user_input is not None: try: self._user_inputs.update(user_input) session = await self.hass.async_add_executor_job( - get_ecoledirecte_session, + check_ecoledirecte_session, self._user_inputs, self.hass.config.config_dir, self.hass, ) - if session is None: + if not session: raise InvalidAuth return self.async_create_entry( - title=session.identifiant, data=self._user_inputs + title=self._user_inputs["username"], data=self._user_inputs ) - except QCMError: - errors["base"] = "double_auth" except InvalidAuth: errors["base"] = "invalid_auth" diff --git a/custom_components/ecole_directe/ecole_directe_helper.py b/custom_components/ecole_directe/ecole_directe_helper.py index d25af54..f7d1088 100644 --- a/custom_components/ecole_directe/ecole_directe_helper.py +++ b/custom_components/ecole_directe/ecole_directe_helper.py @@ -286,6 +286,16 @@ def __init__(self, data): self.elements_programme = "" +def check_ecoledirecte_session(data, config_path, hass) -> bool: + """check if credentials to Ecole Directe are ok""" + try: + session = get_ecoledirecte_session(data, config_path, hass) + except QCMError: + return True + + return session is not None + + def get_ecoledirecte_session(data, config_path, hass) -> EDSession | None: """Function connecting to Ecole Directe""" try: @@ -353,7 +363,7 @@ def get_ecoledirecte_session(data, config_path, hass) -> EDSession | None: if try_login == 0: raise QCMError( - "Vérifiez le fichier qcm.json, et recharchez l'intégration Ecole Directe." + "Vérifiez le fichier qcm.json, et rechargez l'intégration Ecole Directe." ) _LOGGER.debug("cn: [%s] - cv: [%s]", cn, cv) @@ -378,7 +388,8 @@ def get_ecoledirecte_session(data, config_path, hass) -> EDSession | None: login["data"]["accounts"][0]["identifiant"], ) return EDSession(login) - except QCMError: + except QCMError as err: + _LOGGER.warning(err) raise except Exception as err: _LOGGER.critical(err) diff --git a/custom_components/ecole_directe/qcm.json b/custom_components/ecole_directe/qcm.json deleted file mode 100644 index 7a73a41..0000000 --- a/custom_components/ecole_directe/qcm.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file