ソースを参照

add next_slide script

Noah Vogt 2 年 前
コミット
687ddbe35c
3 ファイル変更120 行追加1 行削除
  1. 1 0
      README.md
  2. 1 1
      input/validate_ssync_config.py
  3. 118 0
      next_slide.py

+ 1 - 0
README.md

@@ -312,6 +312,7 @@ These are some issues and possible changes that will be addressed or at least co
 - add more documentation, especially explaining the slide generation, but also dependencies and deployment
 - 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 docs for extra scripts
 
 ## Licensing
 

+ 1 - 1
input/validate_ssync_config.py

@@ -28,7 +28,7 @@ def validate_ssync_config():
         "SSYNC_CACHEFILE_NAMING": const.SSYNC_CACHEFILE_NAMING,
         "SSYNC_CACHE_DIR": const.SSYNC_CACHE_DIR,
         "OBS_SLIDES_DIR": const.OBS_SLIDES_DIR,
-        "OBS_TARGET_SUBDIR": const.OBS_SUBDIR_NAMING,
+        "OBS_SUBDIR_NAMING": const.OBS_SUBDIR_NAMING,
         "OBS_MIN_SUBDIRS": const.OBS_MIN_SUBDIRS,
     }
     for key in needed_constants:

+ 118 - 0
next_slide.py

@@ -0,0 +1,118 @@
+#!/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 datetime import date
+from re import match
+from os import path
+
+from pyautogui import hotkey
+
+from utils import log, error_msg
+import config as const
+
+
+def calculate_date() -> str:
+    return date.strftime(date.today(), "%Y-%m-%d")
+
+
+def get_cachefile_content() -> list:
+    try:
+        with open(
+            const.NEXTSONG_CACHE_FILE, mode="r", encoding="utf8"
+        ) as cachefile_reader:
+            cachefile_content = cachefile_reader.readlines()
+    except (FileNotFoundError, PermissionError, IOError) as error:
+        error_msg(
+            "Failed to access cachefile in '{}'. Reason: {}".format(
+                const.NEXTSONG_CACHE_FILE, error
+            )
+        )
+    return cachefile_content
+
+
+def cycle_to_next_slide() -> None:
+    cachefile_content = get_cachefile_content()
+    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() != calculate_date()
+    ):
+        switch_to_slide(1)
+    else:
+        switch_to_slide(int(cachefile_content[1]) + 1)
+
+
+def switch_to_slide(slide: int) -> None:
+    if slide > const.OBS_MIN_SUBDIRS:
+        slide = 1
+    log("sending hotkey Ctr + Shift + F{}".format(slide))
+    hotkey("ctrl", "shift", "f{}".format(slide))
+    create_cachfile_for_slide(slide)
+
+
+def create_cachfile_for_slide(slide) -> None:
+    log("writing slide {} cachefile...".format(slide))
+    try:
+        with open(
+            const.NEXTSONG_CACHE_FILE, mode="w", encoding="utf8"
+        ) as file_writer:
+            file_writer.write(calculate_date() + "\n")
+            file_writer.write(str(slide) + "\n")
+    except (FileNotFoundError, PermissionError, IOError) as error:
+        error_msg(
+            "Failed to write to cachefile '{}'. Reason: {}".format(
+                const.NEXTSONG_CACHE_FILE, error
+            )
+        )
+
+
+def validate_config() -> None:
+    if const.NEXTSONG_CACHE_FILE == "":
+        error_msg("needed config entry 'NEXTSONG_CACHE_FILE' is empty")
+    if const.OBS_MIN_SUBDIRS == "":
+        error_msg("needed config entry 'OBS_MIN_SUBDIRS' is empty")
+    log("configuration initialised")
+
+
+def make_sure_cachefile_exists() -> None:
+    if not path.isfile(const.NEXTSONG_CACHE_FILE):
+        try:
+            with open(
+                const.NEXTSONG_CACHE_FILE, mode="w+", encoding="utf8"
+            ) as file_creator:
+                file_creator.write("")
+        except (FileNotFoundError, PermissionError, IOError) as error:
+            error_msg(
+                "Failed to create cachefile in '{}'. Reason: {}".format(
+                    const.NEXTSONG_CACHE_FILE, error
+                )
+            )
+
+
+def main() -> None:
+    validate_config()
+    make_sure_cachefile_exists()
+    cycle_to_next_slide()
+
+
+if __name__ == "__main__":
+    main()