From 207434484e94ce0f9eb7884c04a409f089bca7f0 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Sat, 20 Jan 2024 21:48:44 +0100 Subject: [PATCH] added a configuration panel instead of manually editing the main of the web_replay --- tools/statistics/__init__.py | 0 tools/statistics/analyse/__init__.py | 0 tools/statistics/main.py | 38 +++++++++++++ tools/statistics/survey/IntegerQuestion.py | 6 +++ tools/statistics/survey/__init__.py | 0 tools/web_replay/main.py | 13 ++--- tools/web_replay/ui/ReplayConfiguration.py | 63 ++++++++++++++++++++++ tools/web_replay/ui/ReplayEngine.py | 20 ++++--- tools/web_replay/ui/ReplayWindow.py | 35 ++++++++---- tools/web_replay/ui/__init__.py | 1 + 10 files changed, 149 insertions(+), 27 deletions(-) create mode 100644 tools/statistics/__init__.py create mode 100644 tools/statistics/analyse/__init__.py create mode 100644 tools/statistics/main.py create mode 100644 tools/statistics/survey/IntegerQuestion.py create mode 100644 tools/statistics/survey/__init__.py create mode 100644 tools/web_replay/ui/ReplayConfiguration.py diff --git a/tools/statistics/__init__.py b/tools/statistics/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/statistics/analyse/__init__.py b/tools/statistics/analyse/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/statistics/main.py b/tools/statistics/main.py new file mode 100644 index 0000000..1117f12 --- /dev/null +++ b/tools/statistics/main.py @@ -0,0 +1,38 @@ +from pathlib import Path + +if __name__ == "__main__": + from source.utils import compress + + directory = Path(r"C:\Users\RC606\Downloads\résultats étude") + + # read every people survey data + for file in directory.rglob("*.rsl"): + # decompress the data + data = compress.uncompress_data(file.read_bytes()) + + + + + ages = sorted(list(map( + lambda data: data["surveys"]["question-age"]["value"], + datas + ))) + + print(ages) + print(sum(ages) / len(ages)) + print(ages[len(ages) // 2]) + print(min(ages)) + print(max(ages)) + + print(datas[1]["surveys"]["question-usage-steam"]) + + usages = sorted(list(map( + lambda data: data["surveys"]["question-usage-steam"]["choices"], + datas + ))) + + print(usages) + print(sum(usages) / len(usages)) + print(usages[len(usages) // 2]) + print(min(usages)) + print(max(usages)) diff --git a/tools/statistics/survey/IntegerQuestion.py b/tools/statistics/survey/IntegerQuestion.py new file mode 100644 index 0000000..828bdfa --- /dev/null +++ b/tools/statistics/survey/IntegerQuestion.py @@ -0,0 +1,6 @@ +class IntegerQuestion: + def get_average(self, datas: list[int]): + return sum(datas) / len(datas) + + def get_median(self, datas: list[int]): + return datas[len(datas) // 2] diff --git a/tools/statistics/survey/__init__.py b/tools/statistics/survey/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/web_replay/main.py b/tools/web_replay/main.py index 163de4e..368cc5a 100644 --- a/tools/web_replay/main.py +++ b/tools/web_replay/main.py @@ -1,7 +1,8 @@ +import json import sys from datetime import datetime -from PyQt6.QtWidgets import QApplication +from PyQt6.QtWidgets import QApplication, QFileDialog from tools.web_replay.ui import ReplayWindow @@ -10,16 +11,8 @@ if __name__ == "__main__": # create the application application = QApplication(sys.argv) - # TODO: cmd arguments ? - from source.utils import compress - with open(r"C:\Users\RC606\PycharmProjects\M1-Recherche\results\c3376670-548d-4494-b963-dc2facf7a3d1.rsl", "rb") as file: - data = compress.uncompress_data(file.read()) - # create the window - window = ReplayWindow( - datetime.fromtimestamp(data["time"]), - data["surveys"]["mission-language"]["event"] - ) + window = ReplayWindow("surveys.json") window.show() # start the application diff --git a/tools/web_replay/ui/ReplayConfiguration.py b/tools/web_replay/ui/ReplayConfiguration.py new file mode 100644 index 0000000..a8749c2 --- /dev/null +++ b/tools/web_replay/ui/ReplayConfiguration.py @@ -0,0 +1,63 @@ +from PyQt6.QtCore import pyqtSignal +from PyQt6.QtWidgets import QWidget, QLineEdit, QPushButton, QVBoxLayout, QFrame, QHBoxLayout, QComboBox, QFileDialog + + +class ReplayConfiguration(QWidget): + signal_start_replay = pyqtSignal([str, str]) + + def __init__(self, missions: list[str]): + super().__init__() + + # layout + layout = QVBoxLayout() + self.setLayout(layout) + + # replay path + self.frame_path = QFrame() + layout.addWidget(self.frame_path) + + layout_path = QHBoxLayout() + self.frame_path.setLayout(layout_path) + + self.entry_path = QLineEdit() + layout_path.addWidget(self.entry_path) + + self.button_path = QPushButton() + layout_path.addWidget(self.button_path) + self.button_path.setText("...") + self.button_path.clicked.connect(self.select_replay) # NOQA: connect exist + + # mission + self.frame_mission = QFrame() + layout.addWidget(self.frame_mission) + + layout_mission = QHBoxLayout() + self.frame_mission.setLayout(layout_mission) + + self.listbox_mission = QComboBox() + layout_mission.addWidget(self.listbox_mission) + + for mission in missions: + self.listbox_mission.addItem(mission) + + # button + self.button_confirm = QPushButton() + layout.addWidget(self.button_confirm) + self.button_confirm.setText("Replay") + self.button_confirm.clicked.connect(self._start_replay) # NOQA: connect exist + + def select_replay(self): + # prompt the user for a file + file, raw_filetype = QFileDialog.getOpenFileName( + caption="Select the file to replay.", + filter="Replay (*.rsl)" + ) + + # if no file were selected, ignore + if not file: + return + + self.entry_path.setText(file) + + def _start_replay(self): + self.signal_start_replay.emit(self.entry_path.text(), self.listbox_mission.currentText()) # NOQA: emit diff --git a/tools/web_replay/ui/ReplayEngine.py b/tools/web_replay/ui/ReplayEngine.py index 6998a85..290bbc4 100644 --- a/tools/web_replay/ui/ReplayEngine.py +++ b/tools/web_replay/ui/ReplayEngine.py @@ -1,10 +1,12 @@ -from datetime import datetime, timedelta +from datetime import datetime +from pathlib import Path from typing import Callable from PyQt6.QtCore import Qt, QUrl, QPointF, QTimer from PyQt6.QtGui import QKeyEvent, QMouseEvent from PyQt6.QtWidgets import QWidget, QVBoxLayout, QApplication, QLabel +from source.utils import compress from tools.web_replay.ui import ReplayWebEngineView, ReplayNavigation @@ -13,11 +15,15 @@ class ReplayEngine(QWidget): This widget allow to replay some event that occurred on a web page """ - def __init__(self, start_time: datetime, replay_data: list): + def __init__(self, replay_path: Path | str, mission: str): super().__init__() - self.start_time = start_time - timedelta(days=1) # remove a day to prevent archive rounding - self.replay_data = replay_data + # load the replay + with open(replay_path, "rb") as file: + replay_data = compress.uncompress_data(file.read()) + + self.start_time = datetime.fromtimestamp(replay_data["time"]) + self.replay_events = replay_data["surveys"][mission]["event"] self.replay_index: int = 0 self.replay_time: float = 0 @@ -152,7 +158,7 @@ class ReplayEngine(QWidget): def next(self): # get event information - event = self.replay_data[self.replay_index] + event = self.replay_events[self.replay_index] self.replay_time = event["time"] self.replay_index = self.replay_index + 1 @@ -173,9 +179,9 @@ class ReplayEngine(QWidget): pass # if there are still events after this one - if self.replay_index < len(self.replay_data): + if self.replay_index < len(self.replay_events): # next event - next_event: dict = self.replay_data[self.replay_index] + next_event: dict = self.replay_events[self.replay_index] next_time: float = next_event["time"] # prepare the timer to play the event at the corresponding time diff --git a/tools/web_replay/ui/ReplayWindow.py b/tools/web_replay/ui/ReplayWindow.py index b71a991..7f9937d 100644 --- a/tools/web_replay/ui/ReplayWindow.py +++ b/tools/web_replay/ui/ReplayWindow.py @@ -1,23 +1,38 @@ -from datetime import datetime +import json +from pathlib import Path from PyQt6.QtWidgets import QMainWindow -from tools.web_replay.ui import ReplayEngine +from tools.web_replay.ui import ReplayConfiguration, ReplayEngine class ReplayWindow(QMainWindow): - def __init__(self, start_time: datetime, replay_data: list): + def __init__(self, survey_path: Path | str): super().__init__() + # get the survey configuration + with open(survey_path, encoding="utf-8") as file: + survey_configuration: dict = json.load(file) + + # get all the missions available in the survey that can be replayed + missions: list[str] = [ + mission_id + for mission_id, mission in survey_configuration["surveys"].items() + if mission["type"] == "mission-web" + ] + # decoration self.setWindowTitle("Survey Engine - Web Replay") - # setup the engine - self.replay_engine = ReplayEngine(start_time, replay_data) + # show the configuration + self.replay_engine = None + self.replay_configuration = ReplayConfiguration(missions=missions) + self.setCentralWidget(self.replay_configuration) + self.replay_configuration.signal_start_replay.connect(self.start_replay) + + def start_replay(self, replay_path: str, mission: str): + # start the replay + self.replay_engine = ReplayEngine(replay_path, mission) self.setCentralWidget(self.replay_engine) - - # show the window as fullscreen self.showFullScreen() - - # TODO: remove ? - self.replay_engine.next() # play the replay + self.replay_engine.next() diff --git a/tools/web_replay/ui/__init__.py b/tools/web_replay/ui/__init__.py index 295e3eb..8c89fb0 100644 --- a/tools/web_replay/ui/__init__.py +++ b/tools/web_replay/ui/__init__.py @@ -1,4 +1,5 @@ from .ReplayWebEngineView import ReplayWebEngineView from .ReplayNavigation import ReplayNavigation from .ReplayEngine import ReplayEngine +from .ReplayConfiguration import ReplayConfiguration from .ReplayWindow import ReplayWindow