Sfoglia il codice sorgente

add previous_song.py script + add more info when expecting to burn next cd in gui

Noah Vogt 1 anno fa
parent
commit
6d329f1d6f
8 ha cambiato i file con 94 aggiunte e 43 eliminazioni
  1. 4 1
      README.md
  2. 3 8
      force_song.py
  3. 1 1
      input/__init__.py
  4. 1 1
      input/validate_config.py
  5. 6 28
      next_song.py
  6. 31 0
      previous_song.py
  7. 2 0
      utils/__init__.py
  8. 46 4
      utils/scripts.py

+ 4 - 1
README.md

@@ -352,6 +352,9 @@ To transition to the new song, it sends another hotkey defined by the following
 OBS_TRANSITION_HOTKEY = ["ctrl", "shift", "f12"]
 ```
 
+### previous_song.py
+
+Same as `next_song.py`, but in the other direction. Meaning it will switch to the OBS scene for the previous song.
 
 ### force_song.py
 
@@ -365,7 +368,7 @@ to switch to the scene with song 4.
 
 These are some issues and possible changes that will be addressed or at least considered by our future development efforts:
 
-- add more documentation, especially explaining the slide generation, but also the `PROMPT_INPUT`
+- add more documentation, especially explaining the slide generation, but also the `PROMPT_INPUT` and the cd burning scripts
 - add tests
 - use smarter multi slide splitter algorithm: either by pattern recognition like line matching or rhymes of the last word or by incorporating some sort of sub-song-structures in the body.
 - add warnings that indicate potential problems with rclone syncing

+ 3 - 8
force_song.py

@@ -19,13 +19,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from sys import argv
 
-
 from utils import (
     error_msg,
     make_sure_file_exists,
     switch_to_song,
 )
-from input import validate_songchooser_config
+from input import validate_obs_song_scene_switcher_config
 import config as const
 
 
@@ -45,12 +44,8 @@ def exit_if_force_int_is_illegal():
         error_msg("force integer cannot be smaller than 1")
 
 
-def main() -> None:
-    validate_songchooser_config()
+if __name__ == "__main__":
+    validate_obs_song_scene_switcher_config()
     make_sure_file_exists(const.NEXTSONG_CACHE_FILE)
     exit_if_force_int_is_illegal()
     switch_to_song(get_force_int())
-
-
-if __name__ == "__main__":
-    main()

+ 1 - 1
input/__init__.py

@@ -28,7 +28,7 @@ from .parse_argv import (
 )
 from .validate_config import (
     validate_ssync_config,
-    validate_songchooser_config,
+    validate_obs_song_scene_switcher_config,
     validate_cd_record_config,
 )
 from .slide_selection_iterator import slide_selection_iterator

+ 1 - 1
input/validate_config.py

@@ -35,7 +35,7 @@ def validate_ssync_config() -> None:
     general_config_validator(needed_constants)
 
 
-def validate_songchooser_config() -> None:
+def validate_obs_song_scene_switcher_config() -> None:
     needed_constants: dict = {
         "NEXTSONG_CACHE_FILE": const.NEXTSONG_CACHE_FILE,
         "OBS_MIN_SUBDIRS": const.OBS_MIN_SUBDIRS,

+ 6 - 28
next_song.py

@@ -17,37 +17,15 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
-from re import match
-
 from utils import (
-    get_yyyy_mm_dd_date,
-    switch_to_song,
+    SongDirection,
+    cycle_to_song_direction,
     make_sure_file_exists,
 )
-from input import get_cachefile_content, validate_songchooser_config
+from input import validate_obs_song_scene_switcher_config
 import config as const
 
-
-def cycle_to_next_song() -> None:
-    cachefile_content = get_cachefile_content(const.NEXTSONG_CACHE_FILE)
-    if (
-        not (
-            len(cachefile_content) == 2
-            and match(r"[0-9]{4}-[0-9]{2}-[0-9]{2}$", cachefile_content[0])
-            and match(r"^[0-9]+$", cachefile_content[1])
-        )
-        or cachefile_content[0].strip() != get_yyyy_mm_dd_date()
-    ):
-        switch_to_song(1)
-    else:
-        switch_to_song(int(cachefile_content[1]) + 1)
-
-
-def main() -> None:
-    validate_songchooser_config()
-    make_sure_file_exists(const.NEXTSONG_CACHE_FILE)
-    cycle_to_next_song()
-
-
 if __name__ == "__main__":
-    main()
+    validate_obs_song_scene_switcher_config()
+    make_sure_file_exists(const.NEXTSONG_CACHE_FILE)
+    cycle_to_song_direction(SongDirection.NEXT)

+ 31 - 0
previous_song.py

@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+
+"""
+Copyright © 2023 Noah Vogt <noah@noahvogt.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from utils import (
+    SongDirection,
+    cycle_to_song_direction,
+    make_sure_file_exists,
+)
+from input import validate_obs_song_scene_switcher_config
+import config as const
+
+if __name__ == "__main__":
+    validate_obs_song_scene_switcher_config()
+    make_sure_file_exists(const.NEXTSONG_CACHE_FILE)
+    cycle_to_song_direction(SongDirection.PREVIOUS)

+ 2 - 0
utils/__init__.py

@@ -32,4 +32,6 @@ from .scripts import (
     is_valid_cd_record_checkfile,
     burn_cds_of_day,
     mark_end_of_recording,
+    cycle_to_song_direction,
+    SongDirection,
 )

+ 46 - 4
utils/scripts.py

@@ -21,6 +21,7 @@ from subprocess import Popen
 from shlex import split
 from time import sleep
 from re import match
+from enum import Enum
 
 from pyautogui import keyDown, keyUp
 from PyQt5.QtWidgets import (  # pylint: disable=no-name-in-module
@@ -43,6 +44,7 @@ from input import (
     RadioButtonDialog,
     InfoMsgBox,
     SheetAndPreviewChooser,
+    get_cachefile_content,
 )
 from os_agnostic import get_cd_drives, eject_drive
 import config as const
@@ -93,9 +95,35 @@ def get_burn_cmd(cd_drive: str, yyyy_mm_dd, padded_zfill_num: str) -> str:
     )
 
 
+class SongDirection(Enum):
+    PREVIOUS = "previous"
+    NEXT = "next"
+
+
+def cycle_to_song_direction(song_direction: SongDirection):
+    cachefile_content = get_cachefile_content(const.NEXTSONG_CACHE_FILE)
+    if song_direction == SongDirection.PREVIOUS:
+        step = -1
+    else:
+        step = 1
+    if (
+        not (
+            len(cachefile_content) == 2
+            and match(r"[0-9]{4}-[0-9]{2}-[0-9]{2}$", cachefile_content[0])
+            and match(r"^[0-9]+$", cachefile_content[1])
+        )
+        or cachefile_content[0].strip() != get_yyyy_mm_dd_date()
+    ):
+        switch_to_song(1)
+    else:
+        switch_to_song(int(cachefile_content[1]) + step)
+
+
 def switch_to_song(song_number: int) -> None:
     if song_number > const.OBS_MIN_SUBDIRS:
         song_number = 1
+    if song_number < 1:
+        song_number = const.OBS_MIN_SUBDIRS
     log("sending hotkey to switch to scene {}".format(song_number), "cyan")
     scene_switch_hotkey = list(const.OBS_SWITCH_TO_SCENE_HOTKEY_PREFIX)
     scene_switch_hotkey.append("f{}".format(song_number))
@@ -248,10 +276,14 @@ def burn_cds_of_day(yyyy_mm_dd: str) -> None:
                 if not dialog.chosen_sheets:
                     sys.exit(0)
                 log(f"Burning CD's from sheets: {dialog.chosen_sheets}")
-                for sheet in dialog.chosen_sheets:
+                num_of_chosen_sheets = len(dialog.chosen_sheets)
+                for num, sheet in enumerate(dialog.chosen_sheets):
                     del app  # pyright: ignore
+                    last_cd_to_burn = num == num_of_chosen_sheets
                     burn_and_eject_cd(
-                        yyyy_mm_dd, get_padded_cd_num_from_sheet_filename(sheet)
+                        yyyy_mm_dd,
+                        get_padded_cd_num_from_sheet_filename(sheet),
+                        last_cd_to_burn,
                     )
 
     except (FileNotFoundError, PermissionError, IOError):
@@ -289,7 +321,9 @@ def get_padded_cd_num_from_sheet_filename(filename: str) -> str:
     return filename[6:13]
 
 
-def burn_and_eject_cd(yyyy_mm_dd: str, padded_cd_num: str) -> None:
+def burn_and_eject_cd(
+    yyyy_mm_dd: str, padded_cd_num: str, expect_next_cd=False
+) -> None:
     cd_drives = get_cd_drives()
     if not cd_drives:
         InfoMsgBox(
@@ -303,8 +337,16 @@ def burn_and_eject_cd(yyyy_mm_dd: str, padded_cd_num: str) -> None:
     burn_success = CDBurnerGUI(
         drive, yyyy_mm_dd, padded_cd_num
     ).burning_successful()
+    if expect_next_cd:
+        extra_success_msg = "Please put the next CD into the drive slot before clicking the button."
+    else:
+        extra_success_msg = ""
     if burn_success:
-        InfoMsgBox(QMessageBox.Info, "Info", "Successfully burned CD.")
+        InfoMsgBox(
+            QMessageBox.Info,
+            "Info",
+            "Successfully burned CD." + extra_success_msg,
+        )
     else:
         InfoMsgBox(QMessageBox.Critical, "Error", "Error: Failed to burn CD.")