From 3d667389c75348e1355c990892a771ca6d0e9658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6hning?= <1497707+bohning@users.noreply.github.com> Date: Mon, 11 Nov 2024 18:28:36 +0100 Subject: [PATCH 1/7] Implement format version support. --- src/usdb_syncer/download_options.py | 2 + src/usdb_syncer/gui/forms/SettingsDialog.ui | 99 ++++++++++++--------- src/usdb_syncer/gui/settings_dialog.py | 5 ++ src/usdb_syncer/json_export.py | 6 +- src/usdb_syncer/resource_dl.py | 4 +- src/usdb_syncer/settings.py | 32 +++++-- src/usdb_syncer/song_loader.py | 34 ++++++- src/usdb_syncer/song_txt/__init__.py | 1 + src/usdb_syncer/song_txt/headers.py | 27 +++++- src/usdb_syncer/utils.py | 2 +- tests/unit/song_txt/test_notes_parser.py | 9 +- 11 files changed, 166 insertions(+), 55 deletions(-) diff --git a/src/usdb_syncer/download_options.py b/src/usdb_syncer/download_options.py index 76cabbd9..2c1f33e4 100644 --- a/src/usdb_syncer/download_options.py +++ b/src/usdb_syncer/download_options.py @@ -12,6 +12,7 @@ class TxtOptions: encoding: settings.Encoding newline: settings.Newline + format_version: settings.FormatVersion fix_linebreaks: settings.FixLinebreaks fix_first_words_capitalization: bool fix_spaces: settings.FixSpaces @@ -100,6 +101,7 @@ def _txt_options() -> TxtOptions | None: return TxtOptions( encoding=settings.get_encoding(), newline=settings.get_newline(), + format_version=settings.get_version(), fix_linebreaks=settings.get_fix_linebreaks(), fix_first_words_capitalization=settings.get_fix_first_words_capitalization(), fix_spaces=settings.get_fix_spaces(), diff --git a/src/usdb_syncer/gui/forms/SettingsDialog.ui b/src/usdb_syncer/gui/forms/SettingsDialog.ui index 711bd083..6697b57a 100644 --- a/src/usdb_syncer/gui/forms/SettingsDialog.ui +++ b/src/usdb_syncer/gui/forms/SettingsDialog.ui @@ -7,7 +7,7 @@ 0 0 640 - 649 + 677 @@ -28,7 +28,7 @@ 20 - + @@ -76,17 +76,20 @@ true - - + + + + + - Line endings: + Encoding: - - + + - Fix capitalization: + Line endings: @@ -103,72 +106,88 @@ - - - - + + + + + 1 + 0 + + + + <html><head/><body><p>USDX and variants can handle both line ending types, but if you want to edit the song file manually, your editor of choice may required a certain line ending. UNIX users (MacOS, Linux) should generally use LF (line feed). On Windows, some text editors may require CRLF (carriage return, line feed). USDB currently requires CRLF line endings.</p></body></html> - - + + - Fix spaces: + Version: - - - <html><head/><body><p>If this setting is enabled, the linebreak timings will be recalculated, either according to USDX or to YASS rules.</p></body></html> - - + - + + + + + + + Optional song file fixes + + + Fix linebreaks: - - + + - <html><head/><body><p>If this setting is enabled, all inter-word spaces will be shifted to either after or before a word.</p></body></html> + <html><head/><body><p>If this setting is enabled, the linebreak timings will be recalculated, either according to USDX or to YASS rules.</p></body></html> - - - - - 1 - 0 - - - - <html><head/><body><p>USDX and variants can handle both line ending types, but if you want to edit the song file manually, your editor of choice may required a certain line ending. UNIX users (MacOS, Linux) should generally use LF (line feed). On Windows, some text editors may require CRLF (carriage return, line feed). USDB currently requires CRLF line endings.</p></body></html> + + + + Fix capitalization: - - - + + + + + + + - Encoding: + Fix spaces: + + + + + + + <html><head/><body><p>If this setting is enabled, all inter-word spaces will be shifted to either after or before a word.</p></body></html> - + Fix quotation marks: - + diff --git a/src/usdb_syncer/gui/settings_dialog.py b/src/usdb_syncer/gui/settings_dialog.py index 079caac8..9e35f33f 100644 --- a/src/usdb_syncer/gui/settings_dialog.py +++ b/src/usdb_syncer/gui/settings_dialog.py @@ -117,6 +117,7 @@ def _populate_comboboxes(self) -> None: combobox_settings = ( (self.comboBox_encoding, settings.Encoding), (self.comboBox_line_endings, settings.Newline), + (self.comboBox_format_version, settings.FormatVersion), (self.comboBox_fix_linebreaks, settings.FixLinebreaks), (self.comboBox_fix_spaces, settings.FixSpaces), (self.comboBox_cover_max_size, settings.CoverMaxSize), @@ -148,6 +149,9 @@ def _load_settings(self) -> None: self.comboBox_line_endings.setCurrentIndex( self.comboBox_line_endings.findData(settings.get_newline()) ) + self.comboBox_format_version.setCurrentIndex( + self.comboBox_format_version.findData(settings.get_version()) + ) self.comboBox_fix_linebreaks.setCurrentIndex( self.comboBox_fix_linebreaks.findData(settings.get_fix_linebreaks()) ) @@ -244,6 +248,7 @@ def _save_settings(self) -> bool: settings.set_txt(self.groupBox_songfile.isChecked()) settings.set_encoding(self.comboBox_encoding.currentData()) settings.set_newline(self.comboBox_line_endings.currentData()) + settings.set_version(self.comboBox_format_version.currentData()) settings.set_fix_linebreaks(self.comboBox_fix_linebreaks.currentData()) settings.set_fix_first_words_capitalization( self.checkBox_fix_first_words_capitalization.isChecked() diff --git a/src/usdb_syncer/json_export.py b/src/usdb_syncer/json_export.py index f917e211..31e7548b 100644 --- a/src/usdb_syncer/json_export.py +++ b/src/usdb_syncer/json_export.py @@ -13,7 +13,7 @@ from usdb_syncer import SongId from usdb_syncer.logger import logger from usdb_syncer.usdb_song import UsdbSong -from usdb_syncer.utils import url_from_resource +from usdb_syncer.utils import video_url_from_resource JSON_EXPORT_VERSION = 1 @@ -62,12 +62,12 @@ def from_usdb_song(cls, song: UsdbSong) -> SongExportData | None: meta.meta_tags.cover.to_str("co") if meta.meta_tags.cover else None ), audio_url=( - url_from_resource(meta.meta_tags.audio) + video_url_from_resource(meta.meta_tags.audio) if meta.meta_tags.audio else None ), video_url=( - url_from_resource(meta.meta_tags.video) + video_url_from_resource(meta.meta_tags.video) if meta.meta_tags.video else None ), diff --git a/src/usdb_syncer/resource_dl.py b/src/usdb_syncer/resource_dl.py index 6a0ef6b5..4937bdcc 100644 --- a/src/usdb_syncer/resource_dl.py +++ b/src/usdb_syncer/resource_dl.py @@ -17,7 +17,7 @@ from usdb_syncer.meta_tags import ImageMetaTags from usdb_syncer.settings import Browser, CoverMaxSize from usdb_syncer.usdb_scraper import SongDetails -from usdb_syncer.utils import url_from_resource +from usdb_syncer.utils import video_url_from_resource IMAGE_DOWNLOAD_HEADERS = { "User-Agent": ( @@ -134,7 +134,7 @@ def _ytdl_options(format_: str, _browser: Browser, target_stem: Path) -> YtdlOpt def _download_resource(options: YtdlOptions, resource: str, logger: Log) -> str | None: - if (url := url_from_resource(resource)) is None: + if (url := video_url_from_resource(resource)) is None: logger.debug(f"invalid audio/video resource: {resource}") return None diff --git a/src/usdb_syncer/settings.py b/src/usdb_syncer/settings.py index a8375d54..cc716718 100644 --- a/src/usdb_syncer/settings.py +++ b/src/usdb_syncer/settings.py @@ -71,10 +71,11 @@ class SettingKey(Enum): TXT = "downloads/txt" ENCODING = "downloads/encoding" NEWLINE = "downloads/newline" + FORMAT_VERSION = "downloads/format_version" FIX_LINEBREAKS = "fixes/linebreaks" - FIX_FIRST_WORDS_CAPITALIZATION = "fixes/firstwordscapitalization" + FIX_FIRST_WORDS_CAPITALIZATION = "fixes/first_words_capitalization" FIX_SPACES = "fixes/spaces" - FIX_QUOTATION_MARKS = "fixes/quotationmarks" + FIX_QUOTATION_MARKS = "fixes/quotation_marks" AUDIO = "downloads/audio" AUDIO_FORMAT = "downloads/audio_format" AUDIO_BITRATE = "downloads/audio_bitrate" @@ -146,6 +147,17 @@ def default() -> Newline: return Newline.LF +class FormatVersion(Enum): + """Supported format versions for song txts.""" + + V1_0_0 = "1.0.0" + V1_1_0 = "1.1.0" + V1_2_0 = "1.2.0" + + def __str__(self) -> str: + return str(self.value) + + class FixLinebreaks(Enum): """Supported variants for fixing linebreak timings.""" @@ -624,6 +636,14 @@ def set_audio_embed_artwork(value: bool) -> None: set_setting(SettingKey.AUDIO_EMBED_ARTWORK, value) +def get_encoding() -> Encoding: + return get_setting(SettingKey.ENCODING, Encoding.UTF_8) + + +def set_encoding(value: Encoding) -> None: + set_setting(SettingKey.ENCODING, value) + + def get_newline() -> Newline: return get_setting(SettingKey.NEWLINE, Newline.default()) @@ -632,12 +652,12 @@ def set_newline(value: Newline) -> None: set_setting(SettingKey.NEWLINE, value) -def get_encoding() -> Encoding: - return get_setting(SettingKey.ENCODING, Encoding.UTF_8) +def get_version() -> FormatVersion: + return get_setting(SettingKey.FORMAT_VERSION, FormatVersion.V1_0_0) -def set_encoding(value: Encoding) -> None: - set_setting(SettingKey.ENCODING, value) +def set_version(value: FormatVersion) -> None: + set_setting(SettingKey.FORMAT_VERSION, value) def get_txt() -> bool: diff --git a/src/usdb_syncer/song_loader.py b/src/usdb_syncer/song_loader.py index 96468715..00180635 100644 --- a/src/usdb_syncer/song_loader.py +++ b/src/usdb_syncer/song_loader.py @@ -39,10 +39,12 @@ from usdb_syncer.constants import ISO_639_2B_LANGUAGE_CODES from usdb_syncer.custom_data import CustomData from usdb_syncer.logger import Log, logger, song_logger +from usdb_syncer.settings import FormatVersion from usdb_syncer.song_txt import SongTxt from usdb_syncer.sync_meta import ResourceFile, SyncMeta from usdb_syncer.usdb_scraper import SongDetails from usdb_syncer.usdb_song import DownloadStatus, UsdbSong +from usdb_syncer.utils import video_url_from_resource class DownloadManager: @@ -518,14 +520,44 @@ def _maybe_write_txt(ctx: _Context) -> None: def _write_headers(ctx: _Context) -> None: + version = FormatVersion.V1_0_0 + if ctx.options and ctx.options.txt_options: + version = ctx.options.txt_options.format_version + if path := ctx.out.audio.path(ctx.locations, temp=True): - ctx.txt.headers.mp3 = path.name + match version: + case FormatVersion.V1_0_0: + ctx.txt.headers.mp3 = path.name + case FormatVersion.V1_1_0: + # write both #MP3 and #AUDIO for compatibility + ctx.txt.headers.mp3 = path.name + ctx.txt.headers.audio = path.name + case FormatVersion.V1_2_0: + ctx.txt.headers.audio = path.name + if resource := ctx.txt.meta_tags.audio: + ctx.txt.headers.audiourl = video_url_from_resource(resource) + elif resource := ctx.txt.meta_tags.video: + ctx.txt.headers.audiourl = video_url_from_resource(resource) if path := ctx.out.video.path(ctx.locations, temp=True): ctx.txt.headers.video = path.name + if version == FormatVersion.V1_2_0 and (resource := ctx.txt.meta_tags.video): + ctx.txt.headers.videourl = video_url_from_resource(resource) if path := ctx.out.cover.path(ctx.locations, temp=True): ctx.txt.headers.cover = path.name + if ( + version == FormatVersion.V1_2_0 + and ctx.txt.meta_tags.cover + and (url := ctx.txt.meta_tags.cover.source_url(ctx.logger)) + ): + ctx.txt.headers.coverurl = url if path := ctx.out.background.path(ctx.locations, temp=True): ctx.txt.headers.background = path.name + if ( + version == FormatVersion.V1_2_0 + and ctx.txt.meta_tags.background + and (url := ctx.txt.meta_tags.background.source_url(ctx.logger)) + ): + ctx.txt.headers.backgroundurl = url def _maybe_write_audio_tags(ctx: _Context) -> None: diff --git a/src/usdb_syncer/song_txt/__init__.py b/src/usdb_syncer/song_txt/__init__.py index 4261c2fe..63c5f8b5 100644 --- a/src/usdb_syncer/song_txt/__init__.py +++ b/src/usdb_syncer/song_txt/__init__.py @@ -86,6 +86,7 @@ def sanitize(self, txt_options: download_options.TxtOptions | None) -> None: """Sanitize USDB issues and prepare for local usage.""" self.headers.reset_file_location_headers() if txt_options: + self.headers.set_version(txt_options.format_version) self.fix(txt_options) def fix(self, txt_options: download_options.TxtOptions) -> None: diff --git a/src/usdb_syncer/song_txt/headers.py b/src/usdb_syncer/song_txt/headers.py index bf226cfa..3fa4c644 100644 --- a/src/usdb_syncer/song_txt/headers.py +++ b/src/usdb_syncer/song_txt/headers.py @@ -8,6 +8,7 @@ from usdb_syncer import errors from usdb_syncer.logger import Log +from usdb_syncer.settings import FormatVersion from usdb_syncer.song_txt.auxiliaries import BeatsPerMinute, replace_false_apostrophes from usdb_syncer.song_txt.language_translations import LANGUAGE_TRANSLATIONS @@ -21,6 +22,7 @@ class Headers: artist: str bpm: BeatsPerMinute gap: int = 0 + version: str | None = None language: str | None = None edition: str | None = None genre: str | None = None @@ -28,9 +30,16 @@ class Headers: year: str | None = None creator: str | None = None mp3: str | None = None + audio: str | None = None + audiourl: str | None = None + vocals: str | None = None + instrumental: str | None = None cover: str | None = None + coverurl: str | None = None background: str | None = None + backgroundurl: str | None = None video: str | None = None + videourl: str | None = None videogap: float | None = None start: float | None = None end: int | None = None @@ -71,14 +80,20 @@ def parse(cls, lines: list[str], logger: Log) -> Headers: ) return cls(**kwargs) + def set_version(self, version: FormatVersion) -> None: + self.version = version.value + def reset_file_location_headers(self) -> None: """Clear all tags with local file locations.""" - self.mp3 = self.video = self.cover = self.background = None + self.mp3 = self.audio = self.vocals = self.instrumental = self.video = ( + self.cover + ) = self.background = None def __str__(self) -> str: out = "\n".join( f"#{key.upper()}:{val}" for key in ( + "version", "title", "artist", "language", @@ -87,9 +102,16 @@ def __str__(self) -> str: "year", "creator", "mp3", + "audio", + "audiourl", + "vocals", + "instrumental", "cover", + "coverurl", "background", + "backgroundurl", "video", + "videourl", "videogap", "resolution", "start", @@ -170,6 +192,9 @@ def _set_header_value(kwargs: dict[str, Any], header: str, value: str) -> None: "year", "creator", "mp3", + "audio", + "vocals", + "instrumental", "cover", "background", "relative", diff --git a/src/usdb_syncer/utils.py b/src/usdb_syncer/utils.py index 37bef2df..c735d669 100644 --- a/src/usdb_syncer/utils.py +++ b/src/usdb_syncer/utils.py @@ -34,7 +34,7 @@ def _root() -> Path: return Path(__file__).parent.parent.parent.absolute() -def url_from_resource(resource: str) -> str | None: +def video_url_from_resource(resource: str) -> str | None: if "://" in resource: return resource if "/" in resource: diff --git a/tests/unit/song_txt/test_notes_parser.py b/tests/unit/song_txt/test_notes_parser.py index 869b3e05..f20e5efb 100644 --- a/tests/unit/song_txt/test_notes_parser.py +++ b/tests/unit/song_txt/test_notes_parser.py @@ -5,7 +5,13 @@ from usdb_syncer.download_options import TxtOptions from usdb_syncer.logger import logger -from usdb_syncer.settings import Encoding, FixLinebreaks, FixSpaces, Newline +from usdb_syncer.settings import ( + Encoding, + FixLinebreaks, + FixSpaces, + FormatVersion, + Newline, +) from usdb_syncer.song_txt import SongTxt @@ -41,6 +47,7 @@ def test_notes_parser_fixes(resource_dir: str) -> None: TxtOptions( encoding=Encoding.UTF_8, newline=Newline.CRLF, + format_version=FormatVersion.V1_0_0, fix_linebreaks=FixLinebreaks.USDX_STYLE, fix_first_words_capitalization=True, fix_spaces=FixSpaces.AFTER, From 90d24b5c58ffa37a849eed9bbd3bd0854db75e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6hning?= <1497707+bohning@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:33:02 +0100 Subject: [PATCH 2/7] Refactor _write_header() to reduce complexity. --- src/usdb_syncer/song_loader.py | 85 +++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/src/usdb_syncer/song_loader.py b/src/usdb_syncer/song_loader.py index 00180635..2224f448 100644 --- a/src/usdb_syncer/song_loader.py +++ b/src/usdb_syncer/song_loader.py @@ -520,44 +520,63 @@ def _maybe_write_txt(ctx: _Context) -> None: def _write_headers(ctx: _Context) -> None: - version = FormatVersion.V1_0_0 - if ctx.options and ctx.options.txt_options: - version = ctx.options.txt_options.format_version + version = ( + ctx.options.txt_options.format_version + if ctx.options and ctx.options.txt_options + else FormatVersion.V1_0_0 + ) if path := ctx.out.audio.path(ctx.locations, temp=True): - match version: - case FormatVersion.V1_0_0: - ctx.txt.headers.mp3 = path.name - case FormatVersion.V1_1_0: - # write both #MP3 and #AUDIO for compatibility - ctx.txt.headers.mp3 = path.name - ctx.txt.headers.audio = path.name - case FormatVersion.V1_2_0: - ctx.txt.headers.audio = path.name - if resource := ctx.txt.meta_tags.audio: - ctx.txt.headers.audiourl = video_url_from_resource(resource) - elif resource := ctx.txt.meta_tags.video: - ctx.txt.headers.audiourl = video_url_from_resource(resource) + _set_audio_headers(ctx, version, path) + if path := ctx.out.video.path(ctx.locations, temp=True): - ctx.txt.headers.video = path.name - if version == FormatVersion.V1_2_0 and (resource := ctx.txt.meta_tags.video): - ctx.txt.headers.videourl = video_url_from_resource(resource) + _set_video_headers(ctx, version, path) + if path := ctx.out.cover.path(ctx.locations, temp=True): - ctx.txt.headers.cover = path.name - if ( - version == FormatVersion.V1_2_0 - and ctx.txt.meta_tags.cover - and (url := ctx.txt.meta_tags.cover.source_url(ctx.logger)) - ): - ctx.txt.headers.coverurl = url + _set_cover_headers(ctx, version, path) + if path := ctx.out.background.path(ctx.locations, temp=True): - ctx.txt.headers.background = path.name - if ( - version == FormatVersion.V1_2_0 - and ctx.txt.meta_tags.background - and (url := ctx.txt.meta_tags.background.source_url(ctx.logger)) - ): - ctx.txt.headers.backgroundurl = url + _set_background_headers(ctx, version, path) + + +def _set_audio_headers(ctx: _Context, version: FormatVersion, path: Path) -> None: + match version: + case FormatVersion.V1_0_0: + ctx.txt.headers.mp3 = path.name + case FormatVersion.V1_1_0: + # write both #MP3 and #AUDIO to maximize compatibility + ctx.txt.headers.mp3 = path.name + ctx.txt.headers.audio = path.name + case FormatVersion.V1_2_0: + ctx.txt.headers.audio = path.name + if resource := ctx.txt.meta_tags.audio or ctx.txt.meta_tags.video: + ctx.txt.headers.audiourl = video_url_from_resource(resource) + + +def _set_video_headers(ctx: _Context, version: FormatVersion, path: Path) -> None: + ctx.txt.headers.video = path.name + if version == FormatVersion.V1_2_0 and (resource := ctx.txt.meta_tags.video): + ctx.txt.headers.videourl = video_url_from_resource(resource) + + +def _set_cover_headers(ctx: _Context, version: FormatVersion, path: Path) -> None: + ctx.txt.headers.cover = path.name + if ( + version == FormatVersion.V1_2_0 + and ctx.txt.meta_tags.cover + and (url := ctx.txt.meta_tags.cover.source_url(ctx.logger)) + ): + ctx.txt.headers.coverurl = url + + +def _set_background_headers(ctx: _Context, version: FormatVersion, path: Path) -> None: + ctx.txt.headers.background = path.name + if ( + version == FormatVersion.V1_2_0 + and ctx.txt.meta_tags.background + and (url := ctx.txt.meta_tags.background.source_url(ctx.logger)) + ): + ctx.txt.headers.backgroundurl = url def _maybe_write_audio_tags(ctx: _Context) -> None: From 6dd83c45918bdeac5861695f649394815c2a0bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6hning?= <1497707+bohning@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:45:23 +0100 Subject: [PATCH 3/7] Add format version feature to changelog. --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 281178e4..cfadc7ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ # Changes +## Features + +- The UltraStar format version can now be specified in the settings (see https://usdx.eu/format/). + + + +# Changes + ## Fixes - Switch from browser_cookie3 to rookiepy in order to retrieve browser cookies on From a5586c9778742a2c98612173f9d05c45dd74bd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6hning?= <1497707+bohning@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:49:59 +0100 Subject: [PATCH 4/7] Fix typo in tooltip. Co-authored-by: RumovZ --- src/usdb_syncer/gui/forms/SettingsDialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usdb_syncer/gui/forms/SettingsDialog.ui b/src/usdb_syncer/gui/forms/SettingsDialog.ui index 6697b57a..797d26e1 100644 --- a/src/usdb_syncer/gui/forms/SettingsDialog.ui +++ b/src/usdb_syncer/gui/forms/SettingsDialog.ui @@ -115,7 +115,7 @@ - <html><head/><body><p>USDX and variants can handle both line ending types, but if you want to edit the song file manually, your editor of choice may required a certain line ending. UNIX users (MacOS, Linux) should generally use LF (line feed). On Windows, some text editors may require CRLF (carriage return, line feed). USDB currently requires CRLF line endings.</p></body></html> + <html><head/><body><p>USDX and variants can handle both line ending types, but if you want to edit the song file manually, your editor of choice may require a certain line ending. UNIX users (MacOS, Linux) should generally use LF (line feed). On Windows, some text editors may require CRLF (carriage return, line feed). USDB currently requires CRLF line endings.</p></body></html> From 51de4b05f387beced78bf052f5fa683d1f1b17c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6hning?= <1497707+bohning@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:54:48 +0100 Subject: [PATCH 5/7] Assert exhaustive matching. --- src/usdb_syncer/song_loader.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/usdb_syncer/song_loader.py b/src/usdb_syncer/song_loader.py index 2224f448..3891a9cd 100644 --- a/src/usdb_syncer/song_loader.py +++ b/src/usdb_syncer/song_loader.py @@ -10,7 +10,7 @@ import traceback from itertools import islice from pathlib import Path -from typing import Iterable, Iterator +from typing import Iterable, Iterator, assert_never import attrs import mutagen.mp4 @@ -551,6 +551,8 @@ def _set_audio_headers(ctx: _Context, version: FormatVersion, path: Path) -> Non ctx.txt.headers.audio = path.name if resource := ctx.txt.meta_tags.audio or ctx.txt.meta_tags.video: ctx.txt.headers.audiourl = video_url_from_resource(resource) + case _ as unreachable: + assert_never(unreachable) def _set_video_headers(ctx: _Context, version: FormatVersion, path: Path) -> None: From d850b4c24043ed2c03c472dbd6667806ea2682d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6hning?= <1497707+bohning@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:57:55 +0100 Subject: [PATCH 6/7] Undo changes to settings key to avoid losing existing settings. --- src/usdb_syncer/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usdb_syncer/settings.py b/src/usdb_syncer/settings.py index cc716718..88609230 100644 --- a/src/usdb_syncer/settings.py +++ b/src/usdb_syncer/settings.py @@ -73,7 +73,7 @@ class SettingKey(Enum): NEWLINE = "downloads/newline" FORMAT_VERSION = "downloads/format_version" FIX_LINEBREAKS = "fixes/linebreaks" - FIX_FIRST_WORDS_CAPITALIZATION = "fixes/first_words_capitalization" + FIX_FIRST_WORDS_CAPITALIZATION = "fixes/firstwordscapitalization" FIX_SPACES = "fixes/spaces" FIX_QUOTATION_MARKS = "fixes/quotation_marks" AUDIO = "downloads/audio" From 8206da680ba7cd1493415f3296815cd6b0f59f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6hning?= <1497707+bohning@users.noreply.github.com> Date: Tue, 12 Nov 2024 20:04:32 +0100 Subject: [PATCH 7/7] Update SettingsDialog.ui Add tooltip to explain the differences in the different format versions. --- src/usdb_syncer/gui/forms/SettingsDialog.ui | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/usdb_syncer/gui/forms/SettingsDialog.ui b/src/usdb_syncer/gui/forms/SettingsDialog.ui index 797d26e1..a7e18d32 100644 --- a/src/usdb_syncer/gui/forms/SettingsDialog.ui +++ b/src/usdb_syncer/gui/forms/SettingsDialog.ui @@ -127,7 +127,11 @@ - + + + <html><head/><body><p><span style=" font-weight:700;">V1.0.0</span></p><p>Choose this version for highest compatibility. This uses #MP3 to specifiy the audio file.</p><p><span style=" font-weight:700;">V1.1.0</span></p><p>This version switches from #MP3 to #AUDIO to underline that other audio formats than mp3 are supported. For compatibility, the Syncer adds both #MP3 and #AUDIO to the text file, which should cause no issues when loading the song.</p><p><span style=" font-weight:700;">V1.2.0</span></p><p>This version introduces new tags #AUDIOURL, #COVERURL, #BACKGROUNDURL and #VIDEOURL to specify URLs for the respective sources. The syncer will fill these tags with the contents of the respective metatags, if available.</p></body></html> + +