From 4fdd1495ad474e797860692ab1a93c03125e2e92 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Sun, 9 Jun 2024 19:32:58 +0800 Subject: [PATCH 01/18] Installed playsound package and implimented function to call audio file. --- app/app.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/app.py b/app/app.py index d060138..87fcec5 100644 --- a/app/app.py +++ b/app/app.py @@ -8,6 +8,7 @@ from flask import Flask, render_template, request, send_file, redirect import html import glob +from playsound import playsound # Initialise flask app app = Flask(__name__, static_url_path='/static', static_folder='static') @@ -17,6 +18,10 @@ cancel_search_flag: bool = False +def playsound_notification(audio_file): + if audio_file is not None: + playsound(audio_file) + @app.context_processor def utility_processor(): """ From 73646aff2e7ae88028dfc27e51c15531239614a4 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Sun, 9 Jun 2024 19:35:01 +0800 Subject: [PATCH 02/18] Added docstring for playsound_notification function. --- app/app.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/app.py b/app/app.py index 87fcec5..80b7566 100644 --- a/app/app.py +++ b/app/app.py @@ -19,6 +19,10 @@ def playsound_notification(audio_file): + """ + Play a notification sound. Requires the playsound package to be installed. + :args: audio_file: Path to the audio_file in the app/static/audio folder + """ if audio_file is not None: playsound(audio_file) From be44b154ea91793d5b21e7b51da8838d9907e181 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Sun, 9 Jun 2024 22:16:33 +0800 Subject: [PATCH 03/18] Modified function to include users absolutepath to audiofiles. --- app/app.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/app.py b/app/app.py index 80b7566..60ecbf1 100644 --- a/app/app.py +++ b/app/app.py @@ -23,8 +23,14 @@ def playsound_notification(audio_file): Play a notification sound. Requires the playsound package to be installed. :args: audio_file: Path to the audio_file in the app/static/audio folder """ + file_path = os.getcwd() + file_name = audio_file + file_path = os.path.join(file_path, file_name) + print(file_path) if audio_file is not None: - playsound(audio_file) + playsound(file_path) + + @app.context_processor def utility_processor(): From c8ff026b654e5b7664c93ae03f079f70211fb5b8 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Sun, 9 Jun 2024 22:55:39 +0800 Subject: [PATCH 04/18] Added notification sounds to send_to_ide(). --- app/app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/app.py b/app/app.py index 60ecbf1..ed2cea5 100644 --- a/app/app.py +++ b/app/app.py @@ -30,7 +30,7 @@ def playsound_notification(audio_file): if audio_file is not None: playsound(file_path) - +playsound_notification("static/audio/capture_success_tone.wav") @app.context_processor def utility_processor(): @@ -152,8 +152,10 @@ def send_to_ide(): code = request.get_json().get("code_snippet") unescaped_code = html.unescape(code) if utils.send_code_snippet_to_ide(filename, unescaped_code): + playsound_notification("static/audio/capture_success_tone.wav") return "success" else: + playsound_notification("static/audio/capture_fail_tone.wav") return "fail" From a5e2f4e3e681b89f0a7270e5ffe52ee8738496e0 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Sun, 9 Jun 2024 23:08:24 +0800 Subject: [PATCH 05/18] Moved playsound_notification() to utils.py. Added notification sound to extract_code_at_timestamp(). --- app/app.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/app/app.py b/app/app.py index ed2cea5..f23c2bd 100644 --- a/app/app.py +++ b/app/app.py @@ -8,7 +8,6 @@ from flask import Flask, render_template, request, send_file, redirect import html import glob -from playsound import playsound # Initialise flask app app = Flask(__name__, static_url_path='/static', static_folder='static') @@ -18,19 +17,9 @@ cancel_search_flag: bool = False -def playsound_notification(audio_file): - """ - Play a notification sound. Requires the playsound package to be installed. - :args: audio_file: Path to the audio_file in the app/static/audio folder - """ - file_path = os.getcwd() - file_name = audio_file - file_path = os.path.join(file_path, file_name) - print(file_path) - if audio_file is not None: - playsound(file_path) -playsound_notification("static/audio/capture_success_tone.wav") + +utils.playsound_notification("static/audio/capture_success_tone.wav") @app.context_processor def utility_processor(): @@ -152,10 +141,10 @@ def send_to_ide(): code = request.get_json().get("code_snippet") unescaped_code = html.unescape(code) if utils.send_code_snippet_to_ide(filename, unescaped_code): - playsound_notification("static/audio/capture_success_tone.wav") + utils.playsound_notification("static/audio/capture_success_tone.wav") return "success" else: - playsound_notification("static/audio/capture_fail_tone.wav") + utils.playsound_notification("static/audio/capture_fail_tone.wav") return "fail" From d7fc1b1b41eacc4b3e9266a4cb99565b144c9ccd Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Sun, 9 Jun 2024 23:11:11 +0800 Subject: [PATCH 06/18] Added playsound_notifications to extract_code_at_timestamp. --- app/extract_text.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/extract_text.py b/app/extract_text.py index d3b864a..76c8af0 100644 --- a/app/extract_text.py +++ b/app/extract_text.py @@ -28,10 +28,12 @@ def extract_code_at_timestamp(filename: str, timestamp: float) -> str: """ frame = ExtractText.extract_frame_at_timestamp(filename, timestamp) if frame is not None: + utils.playsound_notification("static/audio/capture_success_tone.wav") extracted_text = pytesseract.image_to_string(frame) logging.info(f"Successfully extracted code from frame @ {timestamp}s in file {filename}") return ExtractText.format_raw_ocr_string(extracted_text) else: + utils.playsound_notification("static/audio/capture_fail_tone.wav") logging.error(f"Unable to extract code from frame @ {timestamp}s in file {filename}") return "ERROR" From e7fd5609080310c9c29b5600bb5a72ddfffde314 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Sun, 9 Jun 2024 23:33:27 +0800 Subject: [PATCH 07/18] Moved the notification function to utils. --- app/utils.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/utils.py b/app/utils.py index 76a8506..201213d 100644 --- a/app/utils.py +++ b/app/utils.py @@ -13,6 +13,19 @@ from pytube import YouTube from pytube.exceptions import RegexMatchError from configparser import ConfigParser +from playsound import playsound + +def playsound_notification(audio_file): + """ + Play a notification sound. Requires the playsound package to be installed. + :args: audio_file: Path to the audio_file in the app/static/audio folder + """ + file_path = os.getcwd() + file_name = audio_file + file_path = os.path.join(file_path, file_name) + print(file_path) + if audio_file is not None: + playsound(file_path) def config(section: str = None, option: str = None) -> Union[ConfigParser, str]: From 995639783a66d362a4394146ee01cf4917b61453 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Mon, 10 Jun 2024 00:08:36 +0800 Subject: [PATCH 08/18] Moved notification sound to adjust for loading delay between sound and result. Updated requirements to include playsound version. --- app/extract_text.py | 3 ++- requirements.txt | 3 +++ tests/test_utils.py | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/extract_text.py b/app/extract_text.py index 76c8af0..4d4e4d9 100644 --- a/app/extract_text.py +++ b/app/extract_text.py @@ -26,9 +26,9 @@ def extract_code_at_timestamp(filename: str, timestamp: float) -> str: :param timestamp: Time stamp of the frame to extract :return: Formatted code as a string """ + utils.playsound_notification("static/audio/capture_tone.wav") frame = ExtractText.extract_frame_at_timestamp(filename, timestamp) if frame is not None: - utils.playsound_notification("static/audio/capture_success_tone.wav") extracted_text = pytesseract.image_to_string(frame) logging.info(f"Successfully extracted code from frame @ {timestamp}s in file {filename}") return ExtractText.format_raw_ocr_string(extracted_text) @@ -52,6 +52,7 @@ def format_raw_ocr_string(extracted_text: str) -> str: formatted_text = formatted_text.replace("```", "") if config("Formatting", "remove_language_name"): formatted_text = formatted_text.replace(language, "", 1) + utils.playsound_notification("static/audio/capture_success_tone.wav") return formatted_text @staticmethod diff --git a/requirements.txt b/requirements.txt index 232a124..5938f11 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,7 @@ openai==0.28.1 opencv-python==4.8.1.78 packaging==23.2 Pillow==10.1.0 +playsound==1.2.2 pydantic==2.4.2 pydantic_core==2.10.1 pytesseract==0.3.10 @@ -29,3 +30,5 @@ Werkzeug==3.0.1 pytest==7.4.3 pytest-cov==4.1.0 pytest-mock==3.12.0 + +playsound~=1.3.0 \ No newline at end of file diff --git a/tests/test_utils.py b/tests/test_utils.py index 16dc7d7..a01c218 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -12,7 +12,6 @@ from app import utils - def load_dummy_user_data(): """ Dummy data for testing various functions in utils.py From 11c9cb1b373d4d3f1661bc418317aca7e6a38a23 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Mon, 10 Jun 2024 00:09:48 +0800 Subject: [PATCH 09/18] Removed hard coded test notification on startup. fixes #20. --- app/app.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/app.py b/app/app.py index f23c2bd..767603d 100644 --- a/app/app.py +++ b/app/app.py @@ -17,10 +17,6 @@ cancel_search_flag: bool = False - - -utils.playsound_notification("static/audio/capture_success_tone.wav") - @app.context_processor def utility_processor(): """ From 9cc8206aa3238566a15b7149d4c1e3a14e9ddec2 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Mon, 10 Jun 2024 00:12:53 +0800 Subject: [PATCH 10/18] Removed playsound version 1.3.0 from requirments due to using a previous version. --- requirements.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 5938f11..06f3d8f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,6 +29,4 @@ typing_extensions==4.8.0 Werkzeug==3.0.1 pytest==7.4.3 pytest-cov==4.1.0 -pytest-mock==3.12.0 - -playsound~=1.3.0 \ No newline at end of file +pytest-mock==3.12.0 \ No newline at end of file From b2cc6883ae3222b41e110ced16f7a46668f7bdc6 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Mon, 10 Jun 2024 00:15:05 +0800 Subject: [PATCH 11/18] Applied fix for flake-8 linting fix error. --- app/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/utils.py b/app/utils.py index 201213d..abd59ad 100644 --- a/app/utils.py +++ b/app/utils.py @@ -15,6 +15,7 @@ from configparser import ConfigParser from playsound import playsound + def playsound_notification(audio_file): """ Play a notification sound. Requires the playsound package to be installed. From 303a0c132a8dd6f4956b36cd432e5ef36e96fa6d Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Mon, 10 Jun 2024 00:54:13 +0800 Subject: [PATCH 12/18] Final linting fix for build error. --- tests/test_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_utils.py b/tests/test_utils.py index a01c218..16dc7d7 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -12,6 +12,7 @@ from app import utils + def load_dummy_user_data(): """ Dummy data for testing various functions in utils.py From bc943870f94dbdb8b7221a9781c1860152653626 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Tue, 11 Jun 2024 20:22:13 +0800 Subject: [PATCH 13/18] Refactored project folder into file_path string construction for soundplay_notifications and modified associated function calls. --- app/app.py | 4 ++-- app/extract_text.py | 6 +++--- app/utils.py | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/app.py b/app/app.py index 767603d..849abc7 100644 --- a/app/app.py +++ b/app/app.py @@ -137,10 +137,10 @@ def send_to_ide(): code = request.get_json().get("code_snippet") unescaped_code = html.unescape(code) if utils.send_code_snippet_to_ide(filename, unescaped_code): - utils.playsound_notification("static/audio/capture_success_tone.wav") + utils.playsound_notification("capture_success_tone.wav") return "success" else: - utils.playsound_notification("static/audio/capture_fail_tone.wav") + utils.playsound_notification("capture_fail_tone.wav") return "fail" diff --git a/app/extract_text.py b/app/extract_text.py index 4d4e4d9..f7202a1 100644 --- a/app/extract_text.py +++ b/app/extract_text.py @@ -26,14 +26,14 @@ def extract_code_at_timestamp(filename: str, timestamp: float) -> str: :param timestamp: Time stamp of the frame to extract :return: Formatted code as a string """ - utils.playsound_notification("static/audio/capture_tone.wav") + utils.playsound_notification("capture_tone.wav") frame = ExtractText.extract_frame_at_timestamp(filename, timestamp) if frame is not None: extracted_text = pytesseract.image_to_string(frame) logging.info(f"Successfully extracted code from frame @ {timestamp}s in file {filename}") return ExtractText.format_raw_ocr_string(extracted_text) else: - utils.playsound_notification("static/audio/capture_fail_tone.wav") + utils.playsound_notification("capture_fail_tone.wav") logging.error(f"Unable to extract code from frame @ {timestamp}s in file {filename}") return "ERROR" @@ -52,7 +52,7 @@ def format_raw_ocr_string(extracted_text: str) -> str: formatted_text = formatted_text.replace("```", "") if config("Formatting", "remove_language_name"): formatted_text = formatted_text.replace(language, "", 1) - utils.playsound_notification("static/audio/capture_success_tone.wav") + utils.playsound_notification("capture_success_tone.wav") return formatted_text @staticmethod diff --git a/app/utils.py b/app/utils.py index abd59ad..0ea4a4a 100644 --- a/app/utils.py +++ b/app/utils.py @@ -22,6 +22,7 @@ def playsound_notification(audio_file): :args: audio_file: Path to the audio_file in the app/static/audio folder """ file_path = os.getcwd() + file_path += "//static/audio/" file_name = audio_file file_path = os.path.join(file_path, file_name) print(file_path) From 8ad816619ce8d86d0b2bcd9c20406be87acd92be Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Tue, 11 Jun 2024 22:56:02 +0800 Subject: [PATCH 14/18] Added mp3 files to be played when calling soundplay_noticiation. --- app/app.py | 4 ++-- app/extract_text.py | 4 ++-- app/static/audio/capture.mp3 | Bin 0 -> 12480 bytes app/static/audio/error.mp3 | Bin 0 -> 40124 bytes app/static/audio/success.mp3 | Bin 0 -> 49319 bytes 5 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 app/static/audio/capture.mp3 create mode 100644 app/static/audio/error.mp3 create mode 100644 app/static/audio/success.mp3 diff --git a/app/app.py b/app/app.py index bcc0348..650e5c6 100644 --- a/app/app.py +++ b/app/app.py @@ -137,10 +137,10 @@ def send_to_ide(): code = request.get_json().get("code_snippet") unescaped_code = html.unescape(code) if utils.send_code_snippet_to_ide(filename, unescaped_code): - utils.playsound_notification("capture_success_tone.wav") + utils.playsound_notification("success.mp3") return "success" else: - utils.playsound_notification("capture_fail_tone.wav") + utils.playsound_notification("error.mp3") return "fail" diff --git a/app/extract_text.py b/app/extract_text.py index f7202a1..02aaf4c 100644 --- a/app/extract_text.py +++ b/app/extract_text.py @@ -26,7 +26,7 @@ def extract_code_at_timestamp(filename: str, timestamp: float) -> str: :param timestamp: Time stamp of the frame to extract :return: Formatted code as a string """ - utils.playsound_notification("capture_tone.wav") + utils.playsound_notification("capture.mp3") frame = ExtractText.extract_frame_at_timestamp(filename, timestamp) if frame is not None: extracted_text = pytesseract.image_to_string(frame) @@ -52,7 +52,7 @@ def format_raw_ocr_string(extracted_text: str) -> str: formatted_text = formatted_text.replace("```", "") if config("Formatting", "remove_language_name"): formatted_text = formatted_text.replace(language, "", 1) - utils.playsound_notification("capture_success_tone.wav") + utils.playsound_notification("success.mp3") return formatted_text @staticmethod diff --git a/app/static/audio/capture.mp3 b/app/static/audio/capture.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..52aa2a0ed4092e009899e3a904d8d733a5e80af9 GIT binary patch literal 12480 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 literal 0 HcmV?d00001 diff --git a/app/static/audio/error.mp3 b/app/static/audio/error.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6a86ef02e546ffdbf2371a9a35af8352032c6dd8 GIT binary patch literal 40124 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 literal 0 HcmV?d00001 diff --git a/app/static/audio/success.mp3 b/app/static/audio/success.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..a0f2e2d83666a0d1b9faef56ff307709d3a4205c GIT binary patch literal 49319 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

*jx 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 Date: Wed, 12 Jun 2024 00:44:52 +0800 Subject: [PATCH 15/18] Added tests to verify audio file pathing is constructed correctly and verify audio file exists at location. --- tests/test_utils.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 82106dc..93b67bf 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -119,25 +119,25 @@ def test_hash_string(): def test_get_output_path(mocker): project_root = str(utils.PROJ_ROOT) default_path = utils.directory_append_slash(os.path.join(project_root, 'out')) - + test_output_paths = { "output_path": default_path, } - + assert os.name in ['nt', 'posix'] - + # Windows if os.name == 'nt': test_output_paths["c:\\users\\program files\\app"] = "c:\\users\\program files\\app\\" test_output_paths["videos\\my_videos\\"] = "videos\\my_videos\\" - + # Linux or macOS (Note: GitHub Runner is using ubuntu) else: assert os.name == 'posix' users_dir = 'home' if 'home' in os.path.expanduser("~") else 'Users' test_output_paths[f"/{users_dir}/program_files/app"] = f"/{users_dir}/program_files/app/" test_output_paths["videos/my_videos/"] = "videos/my_videos/" - + for paths in test_output_paths: mocker.patch("app.utils.config", return_value=paths) assert utils.get_output_path() == test_output_paths[paths] @@ -156,3 +156,24 @@ def test_file_already_exists_false(mocker): def test_file_already_exists_no_user_data(mocker): mocker.patch("app.utils.read_user_data", return_value=None) assert not utils.file_already_exists("4aj3sdl5a4k2sjd091u091j") + +def test_audio_file_exists_in_audio_file_directory(): + file_path = os.getcwd() + file_path += "//static/audio/" + edit_path = file_path.replace('tests', 'app') + + audio_file = 'success.mp3' + file_path = os.path.join(edit_path, audio_file) + + assert os.path.exists(file_path) + + +def test_audio_file_does_not_exist_in_audio_file_directory(): + file_path = os.getcwd() + file_path += "//static/audio/" + edit_path = file_path.replace('tests', 'app') + + audio_file = 'non_existent_file.mp3' + file_path = os.path.join(edit_path, audio_file) + + assert not os.path.exists(file_path) From b9c7bf71d43e65b83453ffc46c85a9d9c0affca9 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Wed, 12 Jun 2024 00:52:31 +0800 Subject: [PATCH 16/18] Build errors / linting fixes. --- app/utils.py | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/app/utils.py b/app/utils.py index 437a7de..3ebc433 100644 --- a/app/utils.py +++ b/app/utils.py @@ -8,7 +8,7 @@ import time import cv2 from json import JSONDecodeError -from typing import Union, Optional, Any, List, Dict +from typing import Union, Optional, Any, List import openai import pytesseract from pytube import YouTube @@ -30,10 +30,12 @@ def playsound_notification(audio_file): if audio_file is not None: playsound(file_path) + FILE_PATH = Path(__file__).resolve() # Absolute Path of utils.py APP_DIR = FILE_PATH.parent PROJ_ROOT = APP_DIR.parent + def config(section: str = None, option: str = None) -> Union[ConfigParser, str]: """ Loads config variables from file and returns either specified variable or parser object. If attempting to @@ -43,7 +45,6 @@ def config(section: str = None, option: str = None) -> Union[ConfigParser, str]: :param option: [Optional] Key/option of value to retrieve :return: Return string or ConfigParser object """ - if (section is None) != (option is None): raise SyntaxError("section AND option parameters OR no parameters must be passed to function config()") parser = ConfigParser() @@ -128,14 +129,11 @@ def directory_append_slash(directory: str) -> str: :param directory: The directory path to which a trailing slash will be appended, if missing. :return: The directory path with a trailing slash appended, if necessary. """ - # Check if directory already have trailing slash if directory.endswith(('/', '\\')): return directory - # Append trailing slash - directory += '\\' if os.name == 'nt' else '/' - + directory += '\\' if os.name == 'nt' else '/' return directory @@ -145,18 +143,14 @@ def get_vid_save_path() -> str: :return: file path as string """ vid_download_path = config("UserSettings", "video_save_path") - # Set default output path for video download path if vid_download_path == "output_path": default_path = PROJ_ROOT / 'out' / 'videos' if not default_path.exists(): default_path.mkdir(parents=True, exist_ok=True) - default_path = str(default_path) return directory_append_slash(default_path) - vid_download_path = str(Path(vid_download_path)) - return directory_append_slash(vid_download_path) @@ -167,16 +161,12 @@ def get_output_path() -> str: """ output_path = config("UserSettings", "capture_output_path") # Set default output path for code files - if output_path == "output_path": default_path = PROJ_ROOT / 'out' if not default_path.exists(): default_path.mkdir(parents=True, exist_ok=True) - default_path = str(default_path) - return directory_append_slash(default_path) - output_path = str(Path(output_path)) return directory_append_slash(output_path) @@ -326,7 +316,6 @@ def add_video_to_user_data(filename: str, video_title: str, video_hash: str, you user_data = read_user_data() if user_data is None: return - video_path = str(Path(get_vid_save_path(), f'{filename}').resolve()) video_capture = cv2.VideoCapture(video_path) if not video_capture.isOpened(): @@ -341,7 +330,6 @@ def add_video_to_user_data(filename: str, video_title: str, video_hash: str, you return thumbnail = str(int(time.time())) + ".png" # Check if img dir exists if not create - static_dir = APP_DIR / 'static' img_dir = static_dir / 'img' if not img_dir.exists(): @@ -495,7 +483,6 @@ def delete_video_from_userdata(filename: str) -> None: if current_video["filename"] == filename: all_videos.remove(current_video) break - with (APP_DIR / 'data' / 'userdata.json').open('w') as json_data: json.dump(user_data, json_data, indent=4) @@ -516,7 +503,6 @@ def update_configuration(new_values_dict) -> None: if isinstance(value, bool) or isinstance(value, int): value = str(value) config_file.set(section, key, value) - # save the file with (APP_DIR / 'config.ini').open('w') as config_file_save: config_file.write(config_file_save) From 9e42fad73d810da452e92144db59f8228e5286f2 Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Wed, 12 Jun 2024 00:55:03 +0800 Subject: [PATCH 17/18] Linting fixes. --- tests/test_utils.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 93b67bf..b6b8612 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -157,14 +157,13 @@ def test_file_already_exists_no_user_data(mocker): mocker.patch("app.utils.read_user_data", return_value=None) assert not utils.file_already_exists("4aj3sdl5a4k2sjd091u091j") + def test_audio_file_exists_in_audio_file_directory(): file_path = os.getcwd() file_path += "//static/audio/" edit_path = file_path.replace('tests', 'app') - audio_file = 'success.mp3' file_path = os.path.join(edit_path, audio_file) - assert os.path.exists(file_path) @@ -172,8 +171,6 @@ def test_audio_file_does_not_exist_in_audio_file_directory(): file_path = os.getcwd() file_path += "//static/audio/" edit_path = file_path.replace('tests', 'app') - audio_file = 'non_existent_file.mp3' file_path = os.path.join(edit_path, audio_file) - assert not os.path.exists(file_path) From 1771df25dbc494a6e53e596b87597855a86cddfb Mon Sep 17 00:00:00 2001 From: Rumsie-Grimshaw Date: Wed, 12 Jun 2024 00:57:38 +0800 Subject: [PATCH 18/18] final linting fix --- app/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/utils.py b/app/utils.py index 3ebc433..3d050a3 100644 --- a/app/utils.py +++ b/app/utils.py @@ -334,7 +334,6 @@ def add_video_to_user_data(filename: str, video_title: str, video_hash: str, you img_dir = static_dir / 'img' if not img_dir.exists(): img_dir.mkdir(parents=True, exist_ok=True) - cv2.imwrite(str(img_dir / f'{thumbnail}'), frame) new_video = { "video_hash": video_hash,