Parcourir la source

add SlideStyle dataclass for better abstraction + optimize slide_selection_iterater.py

Noah Vogt il y a 2 ans
Parent
commit
688a26954b

+ 61 - 41
input/slide_selection_iterator.py

@@ -23,7 +23,6 @@ from utils import (
     error_msg,
     expand_dir,
 )
-from slides import ClassicSongTemplate, ClassicStartSlide, ClassicSongSlide
 from input import parse_metadata, generate_final_prompt
 
 import config as const
@@ -37,34 +36,23 @@ def slide_selection_iterator(ssync):
         "Choose song structure (leave blank for full song)"
         + " eg. [1,R,2,R] / [1-4]: "
     )
-    file_list_str = ""
     rclone_local_dir = expand_dir(const.RCLONE_LOCAL_DIR)
-    obs_slides_dir = expand_dir(const.OBS_SLIDES_DIR)
-    try:
-        for file in os.listdir(rclone_local_dir):
-            file_list_str += file + "\n"
-    except (FileNotFoundError, PermissionError, IOError) as error:
-        error_msg(
-            "Failed to access items in '{}'. Reason: {}".format(
-                rclone_local_dir, error
-            )
-        )
-    file_list_str = file_list_str[:-1]
-    const.SSYNC_CHOSEN_FILE_NAMING = ".chosen-tempfile"
 
-    index = 0
+    song_counter = 0
     while True:
-        index += 1
-        input_song_prompt = "[{}{}] ".format(const.OBS_SUBDIR_NAMING, index)
-        prompt_answer = str(input(input_song_prompt + iterator_prompt))
+        song_counter += 1
+        input_prompt_prefix = "[{}{}] ".format(
+            const.OBS_SUBDIR_NAMING, song_counter
+        )
+        prompt_answer = str(input(input_prompt_prefix + iterator_prompt))
         if prompt_answer.lower() == "y":
             create_min_obs_subdirs()
             break
 
-        file_list_str = file_list_str.replace("\n", "\\n")
         os.system(
             'printf "{}" | fzf > {}'.format(
-                file_list_str, const.SSYNC_CHOSEN_FILE_NAMING
+                get_file_list_inside(rclone_local_dir),
+                const.SSYNC_CHOSEN_FILE_NAMING,
             )
         )
 
@@ -74,18 +62,13 @@ def slide_selection_iterator(ssync):
             log("no slides chosen, skipping...")
         else:
             src_dir = os.path.join(rclone_local_dir, chosen_song_file)
-            dest_dir = create_and_get_dest_dir(obs_slides_dir, index)
+            dest_dir = create_and_get_dest_dir(
+                expand_dir(const.OBS_SLIDES_DIR), song_counter
+            )
 
-            dummy_slidegen_instance = slidegen.Slidegen(
-                ClassicSongTemplate,
-                ClassicStartSlide,
-                ClassicSongSlide,
-                src_dir,
-                dest_dir,
-                "",
+            full_song_structure = get_structure_for_prompt(
+                ssync.slide_style, src_dir, dest_dir
             )
-            parse_metadata(dummy_slidegen_instance)
-            full_song_structure = dummy_slidegen_instance.metadata["structure"]
             log(
                 "full song structure of '{}':\n{}".format(
                     chosen_song_file,
@@ -95,31 +78,68 @@ def slide_selection_iterator(ssync):
             )
 
             structure_prompt_answer = input(
-                input_song_prompt + structure_prompt
+                input_prompt_prefix + structure_prompt
             ).strip()
-            calculated_prompt = generate_final_prompt(
-                structure_prompt_answer, full_song_structure
-            )
 
             log(
                 "generating slides '{}' to '{}{}'...".format(
-                    chosen_song_file, const.OBS_SUBDIR_NAMING, index
+                    chosen_song_file, const.OBS_SUBDIR_NAMING, song_counter
                 )
             )
 
-            executing_slidegen_instance = slidegen.Slidegen(
-                ClassicSongTemplate,
-                ClassicStartSlide,
-                ClassicSongSlide,
+            generate_slides_for_selected_song(
+                ssync.slide_style,
                 src_dir,
                 dest_dir,
-                calculated_prompt,
+                generate_final_prompt(
+                    structure_prompt_answer, full_song_structure
+                ),
+                ssync,
             )
-            executing_slidegen_instance.execute(ssync.disable_async)
 
     remove_chosenfile()
 
 
+def generate_slides_for_selected_song(
+    classic_slide_style, src_dir, dest_dir, calculated_prompt, ssync
+) -> None:
+    executing_slidegen_instance = slidegen.Slidegen(
+        classic_slide_style,
+        src_dir,
+        dest_dir,
+        calculated_prompt,
+    )
+    executing_slidegen_instance.execute(ssync.disable_async)
+
+
+def get_structure_for_prompt(classic_slide_style, src_dir, dest_dir):
+    dummy_slidegen_instance = slidegen.Slidegen(
+        classic_slide_style,
+        src_dir,
+        dest_dir,
+        "",
+    )
+    parse_metadata(dummy_slidegen_instance)
+    full_song_structure = dummy_slidegen_instance.metadata["structure"]
+    return full_song_structure
+
+
+def get_file_list_inside(rclone_local_dir):
+    file_list_str = ""
+    try:
+        for file in os.listdir(rclone_local_dir):
+            file_list_str += file + "\n"
+    except (FileNotFoundError, PermissionError, IOError) as error:
+        error_msg(
+            "Failed to access items in '{}'. Reason: {}".format(
+                rclone_local_dir, error
+            )
+        )
+    file_list_str = file_list_str[:-1]
+    file_list_str = file_list_str.replace("\n", "\\n")
+    return file_list_str
+
+
 def remove_chosenfile() -> None:
     try:
         if os.path.isfile(const.SSYNC_CHOSEN_FILE_NAMING):

+ 11 - 15
slidegen.py

@@ -25,6 +25,7 @@ from slides import (
     ClassicSongTemplate,
     ClassicStartSlide,
     ClassicSongSlide,
+    SlideStyle,
     generate_slides,
     generate_song_template,
     count_number_of_slides_to_be_generated,
@@ -41,12 +42,10 @@ from input import (
 class Slidegen:
     def __init__(
         self,
-        song_template_form,
-        start_slide_form,
-        song_slide_form,
-        song_file_path,
-        output_dir,
-        chosen_structure,
+        slide_style: SlideStyle,
+        song_file_path: str,
+        output_dir: str,
+        chosen_structure: str | list,
     ) -> None:
         self.metadata: dict = {"": ""}
         self.songtext: dict = {"": ""}
@@ -54,10 +53,7 @@ class Slidegen:
         self.song_file_content: list = []
         self.output_dir: str = output_dir
         self.chosen_structure = chosen_structure
-        self.generated_slides: list = []
-        self.song_template_form = song_template_form
-        self.start_slide_form = start_slide_form
-        self.song_slide_form = song_slide_form
+        self.slide_style: SlideStyle = slide_style
 
     def execute(self, disable_async=False) -> None:
         self.parse_file()
@@ -85,12 +81,12 @@ class Slidegen:
 def main() -> None:
     colorama.init()
 
-    slidegen: Slidegen = Slidegen(
-        ClassicSongTemplate,
-        ClassicStartSlide,
-        ClassicSongSlide,
-        *parse_argv_as_tuple()
+    classic_slide_style = SlideStyle(
+        ClassicSongTemplate,  # pyright: ignore [reportGeneralTypeIssues]
+        ClassicStartSlide,  # pyright: ignore [reportGeneralTypeIssues]
+        ClassicSongSlide,  # pyright: ignore [reportGeneralTypeIssues]
     )
+    slidegen = Slidegen(classic_slide_style, *parse_argv_as_tuple())
     slidegen.execute()
 
 

+ 2 - 0
slides/__init__.py

@@ -19,6 +19,8 @@ from .song_template import SongTemplate
 from .start_slide import StartSlide
 from .song_slide import SongSlide
 
+from .slide_style import SlideStyle
+
 from .classic_song_template import ClassicSongTemplate
 from .classic_start_slide import ClassicStartSlide
 from .classic_song_slide import ClassicSongSlide

+ 1 - 0
slides/classic_song_slide.py

@@ -22,6 +22,7 @@ from wand.color import Color
 
 import config as const
 
+from utils import get_empty_image
 from .song_slide import SongSlide
 
 

+ 3 - 4
slides/engine/generate_slides.py

@@ -32,7 +32,6 @@ def generate_slides(
     slidegen, slide_count, template_img, zfill_length, disable_async: bool
 ) -> None:
     log("generating song slides...")
-    # unique_structures: list = list(set(chosen_structure))
 
     current_slide_index: int = 0
 
@@ -102,7 +101,7 @@ def generate_slides(
                 Thread(
                     target=generate_song_slide,
                     args=(
-                        slidegen.song_slide_form,
+                        slidegen.slide_style.song_slide_form,
                         template_img,
                         structure_element_value,
                         slidegen,
@@ -125,7 +124,7 @@ def generate_slides(
 
 
 def generate_start_slide(slidegen, template_img, zfill_length, disable_async):
-    first_slide = slidegen.start_slide_form()
+    first_slide = slidegen.slide_style.start_slide_form()
     start_slide_img = first_slide.get_slide(
         template_img,
         slidegen.metadata["book"],
@@ -162,7 +161,7 @@ def generate_song_slide(
     disable_async,
 ):
     song_slide_img = song_slide.get_slide(
-        self=slidegen.song_slide_form(),
+        self=slidegen.slide_style.song_slide_form(),
         template_img=template_img,
         slide_text=structure_element_value,
         song_structure=slidegen.chosen_structure,

+ 1 - 1
slides/engine/song_template.py

@@ -23,6 +23,6 @@ from utils import (
 
 
 def generate_song_template(slidegen) -> Image:
-    song_template = slidegen.song_template_form()
+    song_template = slidegen.slide_style.song_template_form()
     log("generating template...")
     return song_template.get_template(slidegen.metadata["title"])

+ 26 - 0
slides/slide_style.py

@@ -0,0 +1,26 @@
+"""
+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 dataclasses import dataclass
+from . import SongTemplate, StartSlide, SongSlide
+
+
+@dataclass
+class SlideStyle:
+    song_template_form: SongTemplate
+    start_slide_form: StartSlide
+    song_slide_form: SongSlide

+ 14 - 2
ssync.py

@@ -20,6 +20,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 import colorama
 
 from utils import clear_obs_slides_dir
+from slides import (
+    SlideStyle,
+    ClassicSongSlide,
+    ClassicSongTemplate,
+    ClassicStartSlide,
+)
 from input import (
     validate_ssync_config,
     slide_selection_iterator,
@@ -29,10 +35,11 @@ from sync import sync_slide_repo, save_new_checkfile, syncing_needed
 
 
 class Ssync:
-    def __init__(self, offline, sequential):
+    def __init__(self, offline: bool, sequential: bool, slide_style) -> None:
         validate_ssync_config()
         self.offline_flag_enabled = offline
         self.disable_async = sequential
+        self.slide_style = slide_style
 
     def execute(self):
         if syncing_needed(self):
@@ -45,7 +52,12 @@ class Ssync:
 def main() -> None:
     colorama.init()
 
-    ssync: Ssync = Ssync(*parse_ssync_args_as_tuple())
+    classic_slide_style = SlideStyle(
+        ClassicSongTemplate,  # pyright: ignore [reportGeneralTypeIssues]
+        ClassicStartSlide,  # pyright: ignore [reportGeneralTypeIssues]
+        ClassicSongSlide,  # pyright: ignore [reportGeneralTypeIssues]
+    )
+    ssync = Ssync(*parse_ssync_args_as_tuple(), slide_style=classic_slide_style)
     ssync.execute()