Skip to content
This repository has been archived by the owner on Sep 12, 2023. It is now read-only.

Commit

Permalink
[*] Update settings and about dialogs
Browse files Browse the repository at this point in the history
  • Loading branch information
IceflowRE committed Dec 13, 2020
1 parent d5aed54 commit 36dba77
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 51 deletions.
7 changes: 7 additions & 0 deletions gui/about_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,13 @@
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="update_now">
<property name="text">
<string>Update now</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
Expand Down
31 changes: 19 additions & 12 deletions gui/settings_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@
<property name="spacing">
<number>7</number>
</property>
<item row="0" column="1">
<widget class="QCheckBox" name="start_minimized">
<item row="1" column="1">
<widget class="QCheckBox" name="start_with_system">
<property name="text">
<string/>
</property>
Expand All @@ -96,14 +96,7 @@
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="start_minimized_l">
<property name="text">
<string>Start minimized</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<spacer name="vertical_spacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -116,13 +109,27 @@
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="start_with_system">
<item row="0" column="1">
<widget class="QCheckBox" name="start_minimized">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="start_minimized_l">
<property name="text">
<string>Start minimized</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="create_start_menu_entry">
<property name="text">
<string>Create Start Menu Entry</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
Expand Down
35 changes: 27 additions & 8 deletions mp3monitoring/gui/dialog/about.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from PySide2.QtCore import Qt, QSize
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QDialog
from mp3monitoring.gui.dialog import show

from mp3monitoring import static_data
from mp3monitoring.gui import pkg_data
from mp3monitoring.gui.ui.about_dialog import Ui_AboutDialog
from mp3monitoring.gui.updater import UpdateCheckThread
from mp3monitoring.gui.updater import UpdateCheckThread, UpdateAppThread


class AboutDialog(QDialog, Ui_AboutDialog):
Expand All @@ -21,21 +22,39 @@ def __init__(self, parent):
self.website.setText(f"<a href=\"{static_data.PROJECT_URL}\">Github</a>")

# set logo
self.logo.setPixmap(QIcon(str(pkg_data.LOGO_ICON)).pixmap(QSize(250, 250)))
self.logo.setPixmap(QIcon(str(pkg_data.LOGO)).pixmap(QSize(250, 250)))

self._update_app_runner = UpdateAppThread()
self._update_app_runner.finished.connect(self.update_app_check)
self.update_now.clicked.connect(self.update_app)
self.update_now.hide()

self.update_status.setPixmap(QIcon(str(pkg_data.WAIT_SYMBOL)).pixmap(QSize(self.update_info.height() * 0.8, self.update_info.height() * 0.8)))
self._update_check = UpdateCheckThread()
self._update_check.finished.connect(self.change_update_check)
self._update_check.start()
self._update_check_runner = UpdateCheckThread()
self._update_check_runner.finished.connect(self.change_update_check)
self._update_check_runner.start()

def update_app(self):
self.update_now.setDisabled(True)
self._update_app_runner.start()

def update_app_check(self):
if not self._update_app_runner.succeed:
show.information_dialog("Failed to update", self._update_app_runner.err_msg)
return
self.update_info.setText("Restart to finish the update.")
show.information_dialog("Update succeed", "Restart the app to finish the update.")

def change_update_check(self):
if not self._update_check.check_succeed:
if not self._update_check_runner.check_succeed:
self.update_status.setPixmap(QIcon(str(pkg_data.ERROR_SYMBOL)).pixmap(QSize(self.update_info.height() * 0.8, self.update_info.height() * 0.8)))
self.update_info.setText(self._update_check.err_msg)
self.update_info.setText(self._update_check_runner.err_msg)
return
if self._update_check.update_available:
if self._update_check_runner.update_available:
self.update_status.setPixmap(QIcon(str(pkg_data.WARNING_SYMBOL)).pixmap(QSize(self.update_info.height() * 0.8, self.update_info.height() * 0.8)))
self.update_info.setText("An Update is available.")
self.update_now.show()
else:
self.update_status.setPixmap(QIcon(str(pkg_data.OK_SYMBOL)).pixmap(QSize(self.update_info.height() * 0.8, self.update_info.height() * 0.8)))
self.update_info.setText("MP3 Monitoring is up to date.")
self.update_now.hide()
43 changes: 17 additions & 26 deletions mp3monitoring/gui/dialog/settings.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import platform
from pathlib import Path

from PySide2.QtCore import Qt
from PySide2.QtWidgets import QDialog

from mp3monitoring import tools
from mp3monitoring.core.manager import Manager
from mp3monitoring.core.settings import Settings, save_config
from mp3monitoring.gui.dialog import show
Expand All @@ -18,47 +18,38 @@ def __init__(self, settings: Settings, manager: Manager, parent):
self._settings: Settings = settings

self.setupUi(self)
self.setWindowFlags(self.windowFlags() & ~(Qt.WindowContextHelpButtonHint | Qt.MSWindowsFixedSizeDialogHint))
self.setWindowFlags(self.windowFlags() & (~Qt.WindowContextHelpButtonHint | Qt.MSWindowsFixedSizeDialogHint))

self.start_minimized.setChecked(self._settings.start_minimized)
self.start_with_system.setChecked(self._settings.start_with_system)

if platform.system() != "Windows":
self.start_with_system.hide()
self.start_with_system_l.hide()
self.create_start_menu_entry.hide()

self.create_start_menu_entry.clicked.connect(self.add_start_menu_entry)

self.button_box.accepted.connect(self.apply)
self.button_box.rejected.connect(self.cancel)

def add_start_menu_entry(self):
success, err = tools.create_start_menu_entry()
if success:
show.information_dialog("Success", "Start menu entry successful created.")
else:
show.information_dialog("Could not create a start menu entry", err)

def apply(self):
settings_changed = False

if platform.system() == "Windows" and self._settings.start_with_system != self.start_with_system.isChecked():
startup_dir = Path.home() / "AppData" / "Roaming" / "Microsoft" / "Windows" / "Start Menu" / "Programs" / "Startup"
startup_file = startup_dir.joinpath("MP3 Monitoring GUI.bat")
if self.start_with_system.isChecked():
if not startup_dir.is_dir():
show.information_dialog("Settings change failed", "Could not find startup directory.\nPlease report this error.")
else:
try:
with startup_file.open(mode='w', encoding='utf-8') as writer:
writer.writelines(["@echo off\n", "mp3monitoring-gui"])
except PermissionError:
show.information_dialog("Settings change failed", "Could not create startup item.")
else:
self._settings.start_with_system = True
settings_changed = True
success, err = tools.edit_startup_link(self.start_with_system.isChecked())
if success:
self._settings.start_with_system = self.start_with_system.isChecked()
settings_changed = True
else:
try:
startup_file.unlink()
except FileNotFoundError:
self._settings.start_with_system = False
settings_changed = True
except PermissionError:
show.information_dialog("Settings change failed", "Could not find startup directory.\nPlease report this error.")
else:
self._settings.start_with_system = False
settings_changed = True
show.information_dialog("Settings change failed", err)

if self._settings.start_minimized != self.start_minimized.isChecked():
self._settings.start_minimized = self.start_minimized.isChecked()
Expand Down
4 changes: 2 additions & 2 deletions mp3monitoring/gui/dialog/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def settings_dialog(settings, manager, parent=None):
def question_dialog(win_title, msg):
msg_box = QMessageBox()
msg_box.setIcon(QMessageBox.Question)
msg_box.setWindowIcon(QIcon(str(pkg_data.LOGO_ICON)))
msg_box.setWindowIcon(QIcon(str(pkg_data.LOGO)))

msg_box.setText(msg)
msg_box.setWindowTitle(win_title)
Expand All @@ -35,7 +35,7 @@ def question_dialog(win_title, msg):
def information_dialog(win_title, msg):
msg_box = QMessageBox()
msg_box.setIcon(QMessageBox.Information)
msg_box.setWindowIcon(QIcon(str(pkg_data.LOGO_ICON)))
msg_box.setWindowIcon(QIcon(str(pkg_data.LOGO)))

msg_box.setText(msg)
msg_box.setWindowTitle(win_title)
Expand Down
20 changes: 20 additions & 0 deletions mp3monitoring/gui/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Things needed for checking for updates.
"""
import json
import subprocess
import sys

import certifi
import urllib3
Expand Down Expand Up @@ -37,6 +39,14 @@ def check_for_app_updates() -> bool:
return get_newest_app_version() > Version(static_data.VERSION)


def update() -> (bool, str):
try:
subprocess.run([sys.executable, '-m', 'pip', 'install', '--upgrade', 'mp3monitoring==2.0.0.dev4'], stdout=sys.stdout, stderr=sys.stderr, check=True)
except subprocess.CalledProcessError as ex:
return False, ex.stdout
return True, ""


class UpdateCheckThread(QThread):
def __init__(self):
super().__init__()
Expand All @@ -51,3 +61,13 @@ def run(self):
except Exception:
self.check_succeed = False
self.err_msg = "Update check failed."


class UpdateAppThread(QThread):
def __init__(self):
super().__init__()
self.succeed: bool = False
self.err_msg: str = ""

def run(self):
self.succeed, self.err_msg = update()
4 changes: 2 additions & 2 deletions mp3monitoring/gui/window/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, app: QApplication, settings: Settings, manager: Manager):
self._settings: Settings = settings
self._manager: Manager = manager

self.setWindowIcon(QIcon(str(pkg_data.LOGO_ICON)))
self.setWindowIcon(QIcon(str(pkg_data.LOGO)))
self.tray_icon: QSystemTrayIcon = self.create_tray_icon()

self.overlay: ShutdownOverlay = ShutdownOverlay(self)
Expand Down Expand Up @@ -93,7 +93,7 @@ def exit(self):
self._stop_thread.start()

def create_tray_icon(self):
tray_icon = QSystemTrayIcon(QIcon(str(pkg_data.LOGO_ICON)))
tray_icon = QSystemTrayIcon(QIcon(str(pkg_data.LOGO)))
tray_icon.activated.connect(self.tray_icon_clicked)

menu = QMenu(self)
Expand Down
53 changes: 53 additions & 0 deletions mp3monitoring/tools.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import sys
from pathlib import Path

import pylnk3
from mutagen import mp3

from mp3monitoring.gui import pkg_data


def is_mp3(file_path: Path):
"""
Expand All @@ -15,3 +19,52 @@ def is_mp3(file_path: Path):
except FileNotFoundError:
pass
return False


def create_start_menu_entry():
start_menu_dir = Path.home() / "AppData" / "Roaming" / "Microsoft" / "Windows" / "Start Menu" / "Programs"
start_menu_entry = start_menu_dir / "MP3 Monitoring.lnk"

if not start_menu_dir.is_dir():
return False, "Could not find start menu directory.\nPlease report this error."
exe = Path(sys.executable).parent / "Scripts" / "mp3monitoring-gui.exe"
if not exe.is_file():
return False, "Could not find the executable path.\nPlease report this error."

try:
pylnk3.for_file(str(exe.absolute()), lnk_name=str(start_menu_entry), icon_file=str(pkg_data.LOGO_ICO))
except Exception as ex:
return False, str(ex)
return True, ""


def edit_startup_link(create: bool = True) -> (bool, str):
"""
:param create: Create or remove the link.
:return: Success and error message.
"""
startup_dir = Path.home() / "AppData" / "Roaming" / "Microsoft" / "Windows" / "Start Menu" / "Programs" / "Startup"
startup_file = startup_dir / "MP3 Monitoring.lnk"

if not create:
try:
startup_file.unlink()
except FileNotFoundError:
return True, ""
except PermissionError:
return False, "Could not remove the Startup entry, due to permission error."
return True, ""

startup_dir.mkdir(exist_ok=True)
if create and not startup_dir.is_dir():
return False, "Could not find startup directory.\nPlease report this error."
exe = Path(sys.executable).parent / "Scripts" / "mp3monitoring-gui.exe"
if create and not exe.is_file():
return False, "Could not find the executable path.\nPlease report this error."

try:
pylnk3.for_file(str(exe.absolute()), lnk_name=str(startup_file), icon_file=str(pkg_data.LOGO_ICO))
except Exception as ex:
return False, str(ex)
return True, ""
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
extras_require={
'gui': [
'pyside2>=5.15.1',
'pylnk3>=0.4.2',
'urllib3[secure]>=1.25.10',
],
'dev': [
Expand All @@ -62,7 +63,7 @@
include_package_data=True,
package_data={
"mp3monitoring": [
'gui/pkg_data/icon.svg',
'gui/pkg_data/*',
'gui/pkg_data/symbols/*',
],
},
Expand Down

0 comments on commit 36dba77

Please sign in to comment.