Skip to content

Commit

Permalink
Release v.0.7 version - see readme.md for changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Gazoo101 committed Mar 9, 2023
1 parent 4fefda7 commit fce5e04
Show file tree
Hide file tree
Showing 19 changed files with 712 additions and 49 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

## [0.7]
### Added
- Github version check to inform users when a new release occurs.
- Multiple previously CLI-only settings now exposed in GUI (note they're not all currently functional)
- Support for getting artist and song name/title from mp3 tags, as opposed to from filename
- Icon for the application

### Changed
- Changed GUI to give more space to 'folders to process' list and encapsulate settings in tabbed pages.
- NUSAutoLyrixAligner made more tolerant to missing paths/files to allow for use of previously cached output.
- Fixed broken local filename lyric fetcher
- Application exit procedure from generating an exception when application closes in a 'normal' fashion

### Removed


## [0.5]
### Added
Expand Down
3 changes: 2 additions & 1 deletion freeze-lyricmanager.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
REM Builds LyricManager GUI. Read commentary in setup.py.
python freeze-small.py build
call C:\Python\Environments\LyricManagerP311\Scripts\activate.bat
python freeze-small.py build
7 changes: 4 additions & 3 deletions freeze-small.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,16 @@
# *Substantially* reduces the size of the created frozen package.
"zip_include_packages": ["PySide6"],
"include_files": [
("resources/lyric_manager_v3.ui", "resources/lyric_manager_v3.ui")
("resources/lyric_manager_v4.ui", "resources/lyric_manager_v4.ui"),
("resources/lyric_manager.ico", "resources/lyric_manager.ico")
]
}
}

executables = [Executable(
"lyric_manager_gui.py",
base=base
#icon="resources/nameofanicon.ico"
base=base,
icon="resources/lyric_manager.ico"
)]

setup(
Expand Down
107 changes: 99 additions & 8 deletions lyric_manager_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,36 @@
import os
import sys
import logging
import webbrowser
from enum import Enum
from pathlib import Path
from typing import Optional, List

# 3rd Party
from PySide6 import QtCore, QtWidgets, QtGui
from PySide6.QtWidgets import QMainWindow, QListWidget, QPlainTextEdit, QListWidgetItem, QAbstractItemView, QSplitter
from PySide6.QtWidgets import QRadioButton, QTableWidget, QTableWidgetItem, QProgressBar, QPushButton, QCheckBox
from PySide6.QtWidgets import QMessageBox, QMenuBar
from PySide6.QtWidgets import QMessageBox, QMenuBar, QComboBox
from PySide6.QtUiTools import QUiLoader
from PySide6.QtCore import QFile, QDir, qDebug, QSettings
from PySide6.QtGui import QAction
from PySide6.QtGui import QAction, QIcon

# 1st Party
from src.developer_options import DeveloperOptions

from src.components.audio_artist_and_song_name_source import AudioArtistAndSongNameSource
from src.components.github_repository_version_check import GithubRepositoryVersionCheck

from src.gui import GuiWorker
from src.gui import LoggingHandlerSignal
from src.gui import ProgressItemGeneratorGUI
from src.gui import QListWidgetDragAndDrop

from src.gui import ComboBoxEnum

from src.lyric_manager_base import LyricManagerBase
from src.lyric_processing_config import Settings
from src.lyric_processing_config import FileCopyMode
from src.lyric_processing_config import AlignedLyricsOutputMode
from src.lyric.dataclasses_and_types import LyricFetcherType
from src.lyric.dataclasses_and_types import LyricAlignerType
from src.lyric.dataclasses_and_types import LyricAlignTask
Expand Down Expand Up @@ -128,7 +135,7 @@ def __init__(self, parent: Optional[QtCore.QObject] = ...) -> None:
# For more complicated things, this might not work as easily...
#self.test_config = Config() # no - undo...

self._setup_ui("./resources/lyric_manager_v3.ui")
self._setup_ui("./resources/lyric_manager_v4.ui")
self._load_ui_settings()

self.widget_main_window.setWindowTitle(f"LyricManager v. {DeveloperOptions.version}")
Expand All @@ -153,6 +160,12 @@ def __init__(self, parent: Optional[QtCore.QObject] = ...) -> None:
if DeveloperOptions.automatically_start_processing():
self.start_processing()

def _create_combo_box_enum(self, widget_name: str, enum_value: Enum, settings_name: str) -> ComboBoxEnum:
q_widget: QComboBox = self.widget_main_window.findChild(QComboBox, widget_name)
if q_widget:
return ComboBoxEnum(q_widget, type(enum_value), enum_value, settings_name, self.q_settings)

return None

def _setup_ui(self, path_to_ui_file : str):
""" Loads a Qt .ui interface via the path provided, and sets up static/dynamic widget behavior.
Expand All @@ -170,6 +183,11 @@ def _setup_ui(self, path_to_ui_file : str):

self.widget_main_window : QMainWindow = QUiLoader().load(path_to_ui_file)

# Set icon
# https://stackoverflow.com/questions/17034330/how-to-include-resource-file-in-cx-freeze-binary
icon = QIcon("./resources/lyric_manager.ico")
self.widget_main_window.setWindowIcon(icon)

self.widget_songs_processed: QTableWidget = self.widget_main_window.findChild(QTableWidget, "tableWidget_songs_processed")

self.widget_log: QPlainTextEdit = self.widget_main_window.findChild(QPlainTextEdit, "plainTextEdit_log")
Expand Down Expand Up @@ -202,6 +220,15 @@ def _setup_ui(self, path_to_ui_file : str):
### Dynamic GUI Behavior
self.widget_local_data_sources = self._setup_widget_local_data_sources()

# We obtain the default values for our enum-based ComboBoxes form a default Settings object
settings = Settings()

self.widget_artist_song_name_source = \
self._create_combo_box_enum("comboBox_artist_song_name_source", settings.data.input.artist_song_name_source, "Processing/artist_song_name_source")
self.widget_file_copy_mode = \
self._create_combo_box_enum("comboBox_file_copy_mode", settings.data.output.aligned_lyrics_file_copy_mode, "Processing/file_copy_mode")
self.widget_aligned_lyrics_output_mode = \
self._create_combo_box_enum("comboBox_aligned_lyrics_output_mode", settings.data.output.aligned_lyrics_output_mode, "Processing/aligned_lyrics_output_mode")

# Set 'Delete' key to remove executable entries if the widget is active
QtGui.QShortcut(QtGui.QKeySequence("Delete"), self.widget_local_data_sources, self.widget_local_data_sources.remove_selected_items, context=QtCore.Qt.WidgetShortcut)
Expand Down Expand Up @@ -292,6 +319,10 @@ def _save_ui_settings(self):
self._set_checkbox_settings_value("Processing/RecursivelyParseFolders", "checkBox_recursively_parse_folders_to_process")
self._set_checkbox_settings_value("Processing/OverwriteExisting", "checkBox_overwrite_existing_generated_files")

self.widget_artist_song_name_source.save_setting()
self.widget_file_copy_mode.save_setting()
self.widget_aligned_lyrics_output_mode.save_setting()


def start_processing(self):
""" Starts LyricManager's lyric fetching and alignment.
Expand Down Expand Up @@ -319,6 +350,8 @@ def start_processing(self):
settings.data.output.path_to_working_directory = self.path_to_working_directory
settings.data.output.path_to_reports = self.path_to_reports

#settings.data.output.aligned_lyrics_file_copy_mode = FileCopyMode.Disabled

# These still need to be set
# settings.data.output.aligned_lyrics_file_copy_mode = None
# settings.data.output.aligned_lyrics_output_mode = None
Expand Down Expand Up @@ -589,11 +622,67 @@ def sl_menu_bar_trigger(self, q_action: QAction):
"https://github.com/Gazoo101/lyric-manager\n"
"\n"
"Awesome Testers:\n"
"Robert Santoro"
"Robert Santoro\n"
"Ryan-Kaye Simmons\n"
"Rolf 'shargo' Karlsson"
)
)


def show_dialog_message_box_if_new_version_has_been_released(self):
""" Presents the user with a dialogue box if there's a new release of LyricManager that the user has yet to be informed of.
To keep user-pestering to a bare minimum, we keep track of which latest version of LyricManager we're aware of.
Only if the user has yet to be informed of a new release do we provide them with a dialogue about this.
"""
latest_known_release = self.q_settings.value("LatestKnownRelease", DeveloperOptions.version)
newer_release = GithubRepositoryVersionCheck.get_newer_version_if_available(latest_known_release)

# If the latest release is already 'known', even if potentially newer, we don't inform the user
if newer_release is None:
return

message_box = QMessageBox()
message_box.setIcon(QMessageBox.Icon.Information)
message_box.setWindowTitle('New version available!')

# Setting the width of a QMessageBox is an uphill struggle. Apparently a spacer can do the trick, but we manage
# with setting the CSS in the QMessageBox
#width = "130"
#message_box.setStyleSheet("QLabel{width: "+width+"px; min-width: "+width+"px; max-width: "+width+"px;}")

message_box.setText((
"Detected newer release of LyricManager!\n"
"\n"
f"Your version: {DeveloperOptions.version}\n"
f"New version: {newer_release}"
"\n"
"Would you like to visit Github to download this new release?"
))
message_box.setStandardButtons(QMessageBox.StandardButton.Yes|QMessageBox.StandardButton.No|QMessageBox.StandardButton.Ignore)
message_box.setDefaultButton(QMessageBox.StandardButton.Yes)

button_yes = message_box.button(QMessageBox.StandardButton.Yes)
button_yes.setText('Yes')

button_ignore = message_box.button(QMessageBox.StandardButton.Ignore)
button_ignore.setText("No, and don't remind me about this release again.")

button_no = message_box.button(QMessageBox.StandardButton.No)
button_no.setText('Maybe later')
message_box.exec()

if message_box.clickedButton() == button_yes:
webbrowser.open("https://github.com/Gazoo101/lyric-manager/releases")
self.q_settings.setValue("LatestKnownRelease", newer_release)
elif message_box.clickedButton() == button_no:
pass # 'No', which is 'Maybe' just closes the Dialog.
elif message_box.clickedButton() == button_ignore:
self.q_settings.setValue("LatestKnownRelease", newer_release)



def main():
try:
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts) # Suppresses a Qt Error
Expand All @@ -603,14 +692,16 @@ def main():

application.execution_mode()

application.show_dialog_message_box_if_new_version_has_been_released()

return_value = qt_application.exec()
sys.exit(return_value)

except BaseException as e:
logging.critical(sys.exc_info())
logging.exception(f"Uncaught Exception: {e}")
raise e

#sys.exit(qt_application.exec())
sys.exit(return_value)

if __name__ == '__main__':
main()
Binary file added resources/lyric_manager.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion resources/lyric_manager_v3.ui
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@
</column>
<column>
<property name="text">
<string>Progress</string>
<string>% of lyrics aligned</string>
</property>
</column>
<column>
Expand Down
Loading

0 comments on commit fce5e04

Please sign in to comment.