slide_selection_iterator.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. """
  2. Copyright © 2022 Noah Vogt <noah@noahvogt.com>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. """
  14. import os
  15. from utils import (
  16. log,
  17. create_min_obs_subdirs,
  18. error_msg,
  19. expand_dir,
  20. )
  21. from input import parse_metadata, generate_final_prompt
  22. from slides import SlideStyle
  23. import config as const
  24. import slidegen
  25. def slide_selection_iterator(
  26. disable_async_enabled: bool, slide_style: SlideStyle
  27. ) -> None:
  28. iterator_prompt = "Exit now? [y/N]: "
  29. structure_prompt = (
  30. "Choose song structure (leave blank for full song)"
  31. + " eg. [1,R,2,R] / [1-4]: "
  32. )
  33. rclone_local_dir = expand_dir(const.RCLONE_LOCAL_DIR)
  34. song_counter = 0
  35. while True:
  36. song_counter += 1
  37. input_prompt_prefix = "[{}{}] ".format(
  38. const.OBS_SUBDIR_NAMING, song_counter
  39. )
  40. prompt_answer = str(input(input_prompt_prefix + iterator_prompt))
  41. if prompt_answer.lower() == "y":
  42. create_min_obs_subdirs()
  43. break
  44. os.system(
  45. "cd {} && fzf {} > {}".format(
  46. rclone_local_dir,
  47. const.FZF_ARGS,
  48. os.path.join(
  49. const.SSYNC_CACHE_DIR, const.SSYNC_CHOSEN_FILE_NAMING
  50. ),
  51. )
  52. )
  53. chosen_song_file = read_chosen_song_file()
  54. if len(chosen_song_file) == 0:
  55. log("no slides chosen, skipping...")
  56. else:
  57. src_dir = os.path.join(rclone_local_dir, chosen_song_file)
  58. dest_dir = create_and_get_dest_dir(
  59. expand_dir(const.OBS_SLIDES_DIR), song_counter
  60. )
  61. full_song_structure = get_structure_for_prompt(
  62. slide_style, src_dir, dest_dir
  63. )
  64. log(
  65. "full song structure of '{}':\n{}".format(
  66. chosen_song_file,
  67. full_song_structure,
  68. ),
  69. color="magenta",
  70. )
  71. structure_prompt_answer = input(
  72. input_prompt_prefix + structure_prompt
  73. ).strip()
  74. log(
  75. "generating slides '{}' to '{}{}'...".format(
  76. chosen_song_file, const.OBS_SUBDIR_NAMING, song_counter
  77. )
  78. )
  79. generate_slides_for_selected_song(
  80. slide_style,
  81. src_dir,
  82. dest_dir,
  83. generate_final_prompt(
  84. structure_prompt_answer, full_song_structure
  85. ),
  86. disable_async_enabled,
  87. )
  88. remove_chosenfile()
  89. def generate_slides_for_selected_song(
  90. classic_slide_style: SlideStyle,
  91. src_dir: str,
  92. dest_dir: str,
  93. calculated_prompt: str | list[str],
  94. disable_async_enabled: bool,
  95. ) -> None:
  96. executing_slidegen_instance = slidegen.Slidegen(
  97. classic_slide_style,
  98. src_dir,
  99. dest_dir,
  100. calculated_prompt,
  101. )
  102. executing_slidegen_instance.execute(disable_async_enabled)
  103. def get_structure_for_prompt(classic_slide_style, src_dir, dest_dir):
  104. dummy_slidegen_instance = slidegen.Slidegen(
  105. classic_slide_style,
  106. src_dir,
  107. dest_dir,
  108. "",
  109. )
  110. parse_metadata(dummy_slidegen_instance)
  111. full_song_structure = dummy_slidegen_instance.metadata["structure"]
  112. return full_song_structure
  113. def get_file_list_inside(rclone_local_dir):
  114. file_list_str = ""
  115. try:
  116. for file in os.listdir(rclone_local_dir):
  117. file_list_str += file + "\n"
  118. except (FileNotFoundError, PermissionError, IOError) as error:
  119. error_msg(
  120. "Failed to access items in '{}'. Reason: {}".format(
  121. rclone_local_dir, error
  122. )
  123. )
  124. file_list_str = file_list_str[:-1]
  125. file_list_str = file_list_str.replace("\n", "\\n")
  126. return file_list_str
  127. def remove_chosenfile() -> None:
  128. try:
  129. if os.path.isfile(
  130. os.path.join(const.SSYNC_CACHE_DIR, const.SSYNC_CHOSEN_FILE_NAMING)
  131. ):
  132. os.remove(
  133. os.path.join(
  134. const.SSYNC_CACHE_DIR, const.SSYNC_CHOSEN_FILE_NAMING
  135. ),
  136. )
  137. except (FileNotFoundError, PermissionError, IOError) as error:
  138. error_msg("Failed to remove chosenfile. Reason: {}".format(error))
  139. def create_and_get_dest_dir(obs_slides_dir, index) -> str:
  140. dest_dir = os.path.join(
  141. obs_slides_dir,
  142. const.OBS_SUBDIR_NAMING + str(index),
  143. )
  144. os.mkdir(dest_dir)
  145. return dest_dir
  146. def read_chosen_song_file() -> str:
  147. with open(
  148. os.path.join(const.SSYNC_CACHE_DIR, const.SSYNC_CHOSEN_FILE_NAMING),
  149. encoding="utf-8-sig",
  150. mode="r",
  151. ) as tempfile_file_opener:
  152. chosen_song_file = tempfile_file_opener.read()[:-1].strip()
  153. return chosen_song_file