prepared final uploading screen

This commit is contained in:
Faraphel 2023-12-31 00:31:39 +01:00
parent 27cb041fde
commit 0a2f45f9b8
7 changed files with 142 additions and 70 deletions

0
source/utils/__init__.py Normal file
View file

22
source/utils/compress.py Normal file
View file

@ -0,0 +1,22 @@
import json
import zlib
def compress_data(data: dict) -> bytes:
"""
Serialize to json and compress a data dictionary
:param data: the data to compress
:return: the data as a dictionnary
"""
return zlib.compress(json.dumps(data, ensure_ascii=False).encode("utf-8"))
def uncompress_data(data: bytes) -> dict:
"""
Decompress and deserialize from json a data dictionary
:param data: the data to decompress
:return: the compressed data
"""
return json.loads(zlib.decompress(data))

View file

@ -0,0 +1,100 @@
import typing
import uuid
from io import BytesIO
from pathlib import Path
from typing import Optional
import nextcord
import requests
from PyQt6.QtCore import Qt, QThread
from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import QWidget, QProgressBar, QVBoxLayout, QLabel, QMessageBox
from source import widget
from source.utils.compress import compress_data
result_path = Path("./results/")
class SavingScreen(QWidget):
def __init__(
self,
collected_datas: dict,
discord_webhook_url: Optional[str] = None
):
super().__init__()
self.compressed_collected_datas = compress_data(collected_datas)
self.discord_webhook_url = discord_webhook_url
# layout
self._layout = QVBoxLayout()
self.setLayout(self._layout)
# prepare the title
self.label_title = QLabel()
self._layout.addWidget(self.label_title)
self.label_title.setText(self.tr("UPLOADING DATA"))
self.label_title.setAlignment(Qt.AlignmentFlag.AlignCenter)
font_title = self.label_title.font()
font_title.setPointSize(24)
font_title.setWeight(QFont.Weight.Bold)
self.label_title.setFont(font_title)
# progress
self.progress = QProgressBar()
self._layout.addWidget(self.progress)
# prepare the filename
filename: str = f"{uuid.uuid4()}.rsl"
# start a thread for the saving
thread = QThread()
thread.started.connect(lambda: self.save(filename)) # NOQA: connect exist
thread.start()
def save(self, filename: str):
# save to a file
self.result_save_file(filename)
# upload to a discord webhook
if self.discord_webhook_url is not None:
try:
self.result_upload_discord(filename)
except nextcord.HTTPException:
# if there is an error while uploading, show a graphical warning to the user
QMessageBox.warning(
self,
title=self.tr("WARNING"),
text=self.tr("COULD NOT UPLOAD TO DISCORD, SEND MANUALLY"),
)
# quit the application
window = typing.cast(widget.SurveyWindow, self.window())
window.quit()
def result_save_file(self, filename: str) -> None:
"""
Save the result data to a file
"""
result_path.mkdir(parents=True, exist_ok=True)
(result_path / filename).write_bytes(self.compressed_collected_datas)
def result_upload_discord(self, filename: str) -> None:
"""
Upload the result to a discord webhook
"""
# create a session
with requests.Session() as session:
# load the configured webhook
webhook = nextcord.SyncWebhook.from_url(self.discord_webhook_url, session=session)
# send the message to discord
message = webhook.send(
file=nextcord.File(fp=BytesIO(self.compressed_collected_datas), filename=filename),
wait=True
)

View file

@ -1,25 +1,17 @@
import json import json
import time import time
import uuid import typing
import zlib
from io import BytesIO
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
import nextcord
import requests
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
from PyQt6.QtWidgets import QVBoxLayout, QProgressBar, QWidget from PyQt6.QtWidgets import QVBoxLayout, QProgressBar, QWidget
from source import translate from source import translate, widget
from source.survey.base import BaseSurvey from source.survey.base import BaseSurvey
from source.survey import Empty, survey_get from source.survey import Empty, survey_get
result_path = Path("./results/")
result_path.mkdir(parents=True, exist_ok=True)
class SurveyEngine(QWidget): class SurveyEngine(QWidget):
signal_abandon = pyqtSignal() signal_abandon = pyqtSignal()
signal_skip = pyqtSignal() signal_skip = pyqtSignal()
@ -95,7 +87,8 @@ class SurveyEngine(QWidget):
def _on_signal_abandon(self): def _on_signal_abandon(self):
# on abandon, quit the survey # on abandon, quit the survey
self.quit() window = typing.cast(widget.SurveyWindow, self.window())
window.quit()
def _on_signal_skip(self): def _on_signal_skip(self):
# on skip, skip to the next survey # on skip, skip to the next survey
@ -152,61 +145,12 @@ class SurveyEngine(QWidget):
self.survey.on_ready() self.survey.on_ready()
def finish_survey(self): def finish_survey(self):
# TODO: page with indication and progress bar for upload saving_screen = widget.SavingScreen(
self.collected_datas,
filename: str = f"{uuid.uuid4()}.rsl" self.discord_webhook_result_url
# save the result in a local file
self.result_save_file(result_path / filename)
# if set, try to send the result to a discord webhook
if self.discord_webhook_result_url is not None:
try:
self.result_upload_discord(filename=filename)
except nextcord.HTTPException:
# TODO: say to send manually the local file
raise
self.quit()
def get_result_data(self) -> bytes:
"""
Return the compressed result data
"""
return zlib.compress(json.dumps(self.collected_datas, ensure_ascii=False).encode("utf-8"))
def result_save_file(self, destination: Path | str) -> None:
"""
Save the result data to a file
:param destination: the path to the file
"""
with open(destination, "wb") as file:
file.write(self.get_result_data())
def result_upload_discord(self, filename: str = "result.rsl") -> None:
"""
Upload the result to a discord webhook
"""
# create a session
with requests.Session() as session:
# load the configured webhook
webhook = nextcord.SyncWebhook.from_url(
self.discord_webhook_result_url,
session=session
) )
# send the message to discord window = typing.cast(widget.SurveyWindow, self.window())
message = webhook.send( window.setCentralWidget(saving_screen)
file=nextcord.File(
fp=BytesIO(self.get_result_data()),
filename=filename),
wait=True
)
def quit(self): self.deleteLater()
# quit the application by closing and deleting the window
self.window().close()
self.window().deleteLater()

View file

@ -17,3 +17,8 @@ class SurveyWindow(QMainWindow):
self.setWindowTitle(self.tr("SURVEY")) self.setWindowTitle(self.tr("SURVEY"))
self.setCentralWidget(widget.SurveyEngine.from_file(survey_path)) self.setCentralWidget(widget.SurveyEngine.from_file(survey_path))
def quit(self):
# quit the application by closing and deleting the window
self.window().close()
self.window().deleteLater()

View file

@ -2,3 +2,4 @@ from .Browser import Browser
from .SurveyEngine import SurveyEngine from .SurveyEngine import SurveyEngine
from .SurveyWindow import SurveyWindow from .SurveyWindow import SurveyWindow
from .SurveyNavigation import SurveyNavigation from .SurveyNavigation import SurveyNavigation
from .SavingScreen import SavingScreen

View file

@ -445,9 +445,9 @@
"sp": "Agradecimientos" "sp": "Agradecimientos"
}, },
"description": { "description": {
"en": "We greatly appreciate your contribution to our survey and your time.\n\nYour collected data is located in the \"results\" folder.", "en": "We greatly appreciate your contribution to our survey and your time.",
"fr": "Nous vous remercions grandement pour votre contribution à notre questionnaire et pour votre temps.\n\nVos données collectées sont situées dans le dossier \"results\".", "fr": "Nous vous remercions grandement pour votre contribution à notre questionnaire et pour votre temps.",
"sp": "Agradecemos enormemente su contribución a nuestro cuestionario y su tiempo.\n\nSus datos recopilados se encuentran en la carpeta \"results\"." "sp": "Agradecemos enormemente su contribución a nuestro cuestionario y su tiempo."
} }
} }
} }