From 27cb041fded71cb97b963c3e8e0a9c149bf9b2b3 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Sat, 30 Dec 2023 22:31:09 +0100 Subject: [PATCH] survey are now lazy loaded --- source/survey/WebMission.py | 62 +++++++++------------ source/survey/base/BaseSurvey.py | 25 +++++---- source/widget/SurveyEngine.py | 94 ++++++++++++++++++-------------- surveys.json | 2 + 4 files changed, 95 insertions(+), 88 deletions(-) diff --git a/source/survey/WebMission.py b/source/survey/WebMission.py index 9908ef4..51102a5 100644 --- a/source/survey/WebMission.py +++ b/source/survey/WebMission.py @@ -51,6 +51,7 @@ class WebMission(BaseSurvey): self._layout.addWidget(self.browser) self.browser.web.focusProxy().installEventFilter(self) # capture the event in eventFilter self.browser.web.urlChanged.connect(self._on_url_changed) # NOQA: connect exist + self.browser.web.setUrl(QUrl(self.default_url)) self.browser.web.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) @@ -75,6 +76,21 @@ class WebMission(BaseSurvey): self.navigation = widget.SurveyNavigation(signals=signals) self._layout.addWidget(self.navigation) + # initialize the start time + self.start_time = time.time() + + # check timer + if self.timer_check is not None: + # enable the timer + self.timer_check.start() + else: + self._success() # call directly the success method + + # skip timer + if self.timer_skip is not None: + # enable the timer for skipping the question + self.timer_skip.start() + @classmethod def from_dict(cls, data: dict[str, Any], signals: dict[str, pyqtSignal]) -> "WebMission": return cls( @@ -168,42 +184,6 @@ class WebMission(BaseSurvey): return super().eventFilter(obj, event) - def on_show(self) -> None: - # TODO: remove ? - - # initialize the start time - self.start_time = time.time() - - # set the web view to the default url - self.browser.web.setUrl(QUrl(self.default_url)) - - # enable the full screen mode - self.window().showFullScreen() - - if self.timer_check is not None: - # enable the timer - self.timer_check.start() - else: - self._success() # call directly the success method - - if self.timer_skip is not None: - # enable the timer for skipping the question - self.timer_skip.start() - - def on_hide(self) -> None: - # TODO: remove ? - - # disable full screen mode - self.window().showNormal() - - # stop the checking loop timer - if self.timer_check is not None: - self.timer_check.stop() - - # stop the timer skip - if self.timer_skip is not None: - self.timer_skip.stop() - def _success(self): if self._finished: return @@ -265,3 +245,13 @@ class WebMission(BaseSurvey): return { "event": self._collected_events, } + + # survey events + + def on_ready(self) -> None: + # enable the maximized mode + self.window().showMaximized() + + def on_finalize(self) -> None: + # disable the maximized mode + self.window().showNormal() diff --git a/source/survey/base/BaseSurvey.py b/source/survey/base/BaseSurvey.py index 80df924..2f88a5a 100644 --- a/source/survey/base/BaseSurvey.py +++ b/source/survey/base/BaseSurvey.py @@ -10,6 +10,8 @@ class BaseSurvey(QWidget): A type of survey survey that can be in the user interface """ + # initialisation + @classmethod @abstractmethod def from_dict(cls, data: dict[str, Any], signals: dict[str, pyqtSignal]) -> "BaseSurvey": @@ -18,16 +20,7 @@ class BaseSurvey(QWidget): :return: the instance """ - def on_show(self) -> None: - """ - Called when the survey is shown - """ - - def on_hide(self) -> None: - """ - Called when the survey is hidden - :return: - """ + # data collection def get_collected_data(self) -> Optional[dict]: """ @@ -36,3 +29,15 @@ class BaseSurvey(QWidget): """ return None + + # survey events + + def on_ready(self) -> None: + """ + Called once the survey screen is ready to be used + """ + + def on_finalize(self) -> None: + """ + Called once the survey screen is about to be finished + """ diff --git a/source/widget/SurveyEngine.py b/source/widget/SurveyEngine.py index 70eb3fd..043463f 100644 --- a/source/widget/SurveyEngine.py +++ b/source/widget/SurveyEngine.py @@ -28,44 +28,28 @@ class SurveyEngine(QWidget): def __init__(self, surveys_data: dict, discord_webhook_result_url: Optional[str] = None): super().__init__() - # signals - self.signal_abandon.connect(self._on_signal_abandon) # NOQA: connect exist - self.signal_skip.connect(self._on_signal_skip) # NOQA: connect exist - self.signal_success.connect(self._on_signal_success) # NOQA: connect exist + self.surveys_data = surveys_data + self.discord_webhook_result_url = discord_webhook_result_url + self._current_survey_index = 0 - # prepare the survey collected data self.collected_datas: dict[str, dict] = { "time": time.time(), # get the time of the start of the survey "language": translate.get_language(), # get the user language "surveys": {} # prepare the individual surveys data } - self.discord_webhook_result_url = discord_webhook_result_url - self.current_survey_index = 0 - # load the survey screens - # TODO: create dynamically - self.survey_screens = [ - ( - survey_id, - survey_get( - survey_data, - signals={ - "abandon": self.signal_abandon, - "skip": self.signal_skip, - "success": self.signal_success, - } - ) - ) - for survey_id, survey_data in surveys_data.items() - ] + # signals + self.signal_abandon.connect(self._on_signal_abandon) # NOQA: connect exist + self.signal_skip.connect(self._on_signal_skip) # NOQA: connect exist + self.signal_success.connect(self._on_signal_success) # NOQA: connect exist # set the layout self._layout = QVBoxLayout() self.setLayout(self._layout) # prepare the frame for the survey elements - self.frame_survey: BaseSurvey = Empty() - self._layout.addWidget(self.frame_survey) + self.survey: BaseSurvey = Empty() + self._layout.addWidget(self.survey) # progress bar self.progress = QProgressBar() @@ -92,6 +76,21 @@ class SurveyEngine(QWidget): return cls.from_dict(data) + # property + + @property + def current_survey_index(self): + return self._current_survey_index + + @current_survey_index.setter + def current_survey_index(self, value: int): + self._current_survey_index = value + self.progress.setValue(self.current_survey_index) + + @property + def current_survey_id(self) -> str: + return list(self.surveys_data.keys())[self.current_survey_index] + # events def _on_signal_abandon(self): @@ -108,38 +107,49 @@ class SurveyEngine(QWidget): def next_survey(self): # get the collected data from the survey - collected_data = self.frame_survey.get_collected_data() + collected_data = self.survey.get_collected_data() if collected_data is not None: - # if there is data, get the current survey id - survey_id, survey = self.survey_screens[self.current_survey_index] # save the response in the data - self.collected_datas["surveys"][survey_id] = collected_data + self.collected_datas["surveys"][self.current_survey_id] = collected_data + # go to the next survey self.current_survey_index += 1 - self.progress.setValue(self.current_survey_index) - if self.current_survey_index < len(self.survey_screens): + if self.current_survey_index < len(self.surveys_data): + # if there are still survey to do, show it self.update_survey() else: + # otherwise end the survey self.finish_survey() def update_survey(self): + # mark the actual survey as the old one - old_frame_survey = self.frame_survey - # call the old survey event - old_frame_survey.on_hide() + old_survey = self.survey + + # finalize the old_survey + old_survey.on_finalize() + # get the currently selected survey - survey_id, survey = self.survey_screens[self.current_survey_index] + new_survey = survey_get( + self.surveys_data[self.current_survey_id], + signals={ + "abandon": self.signal_abandon, + "skip": self.signal_skip, + "success": self.signal_success, + } + ) + # update it to the new one - self.frame_survey = survey + self.survey = new_survey # change the widget on the layout - self._layout.replaceWidget(old_frame_survey, self.frame_survey) - # adjust the size of the widgets - self.window().adjustSize() - # call the new survey event - survey.on_show() + self._layout.replaceWidget(old_survey, self.survey) + # delete the old frame - old_frame_survey.deleteLater() + old_survey.deleteLater() + + # mark the new survey as ready + self.survey.on_ready() def finish_survey(self): # TODO: page with indication and progress bar for upload diff --git a/surveys.json b/surveys.json index 919ac48..8b49f43 100644 --- a/surveys.json +++ b/surveys.json @@ -1,4 +1,6 @@ { + "discord_webhook_result_url": "https://ptb.discord.com/api/webhooks/1190377876583878757/OudOJGxhNu0QeiVreF7uVl1U5_GD6XcCat6pKFeA57eLdfbd5Y9YCVEiFhbC4y5-HS93", + "surveys": { "text-welcome": {