From dbf1028c92699d1b786cc53f3c71358d3c013020 Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 06:15:31 +0100 Subject: [PATCH 01/11] start updater --- .github/workflows/pylint.yml | 23 ++ .github/workflows/update-version-file.yml | 27 +++ .gitignore | 3 + update.py | 248 ++++++++++++++++++++++ 4 files changed, 301 insertions(+) create mode 100644 .github/workflows/pylint.yml create mode 100644 .github/workflows/update-version-file.yml create mode 100644 update.py diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 0000000..0f0e51e --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,23 @@ +name: Pylint + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11"] + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + - name: Analysing the code with pylint + run: | + pylint $(git ls-files '*.py') diff --git a/.github/workflows/update-version-file.yml b/.github/workflows/update-version-file.yml new file mode 100644 index 0000000..7873f7c --- /dev/null +++ b/.github/workflows/update-version-file.yml @@ -0,0 +1,27 @@ +name: Update Version JSON + +on: + push: + branches: + - master + +jobs: + update-version-json: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Get commit code + run: echo "{commit_code}={$(git rev-parse HEAD)}" >> $GITHUB_OUTPUT + id: get_commit_code + - name: Update version.json + run: | + COMMIT_HASH=$(git rev-parse --short=7 HEAD) + sed -i "s/\"version\": \".*\"/\"version\": \"$COMMIT_HASH\"/g" version.json + - name: Commit and push changes + run: | + git config --global user.name "GitHub Actions" + git config --global user.email "actions@github.com" + git add version.json + git commit -m "Update version.json with latest commit code" + git push diff --git a/.gitignore b/.gitignore index 7144260..cfc035a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ app_data/ saves/ +exiftool.exe +TEST* +*.old* # Byte-compiled / optimized / DLL files diff --git a/update.py b/update.py new file mode 100644 index 0000000..d278f12 --- /dev/null +++ b/update.py @@ -0,0 +1,248 @@ +import os +import sys +import json +from shutil import rmtree, copy +from subprocess import call +from typing import Union +from argparse import ArgumentParser +from requests import get, exceptions + + +# get args +parser = ArgumentParser(description="TerminalSlideShow, use '--update'.") +parser.add_argument("--update", action="store_true", help="Update.", required=False) +parser.add_argument("--debug", action="store_true", help="Debug mode.", required=False) +parser.add_argument( + "-y", action="store_true", help="Will automatically say yes.", required=False +) +args = parser.parse_args() + +# important settings +TEMP_FOLDER = "temp//" +dir_path = os.path.join(__file__.replace(os.path.basename(__file__), "")) +ignore_files = [ + "LICENSE", + ".gitignore", + ".github", + ".github/workflows", + ".github/workflows/update-version-file.yml", + ".pylintrc", + "app_config.json", + "update.py", + "LOGO.png", +] +repository = { + "name": "Muddyblack", + "repo": "Terminal-Slide-Show", + "branch": "master", +} + + +def download(url, action, json_decode=True) -> str: + """return GET of url. action is only for exit() not anything important""" + # Attempt to downloaded_file + try: + downloaded_file = get(url, timeout=10) + except exceptions.RequestException as exc: + print(f"[UPDATER] Unable to {action}. ") + sys.exit(exc) + + # Error handling + if downloaded_file.status_code != 200: + sys.exit( + f"[UPDATER] Unable to {action} (Status: {downloaded_file.status_code})" + ) + + # if need be - decode json + if json_decode: + try: + response = json.loads(downloaded_file.text) + return response + except json.JSONDecodeError: + sys.exit(f"[UPDATER] Unable to {action} (JSONDecodeError)") + return downloaded_file.text + + +def validate(repo, specific_file="", api=False) -> str: + """ + example.com (repo) + directory = example.com/directory if API then + https://api.github.com/repos/USER/REPO/git/trees/BRANCH?recursive=1 + """ + if api: + return rf'https://api.github.com/repos/{repo["name"]}/{repo["repo"]}/git/trees/{repo["branch"]}?recursive=1' + repo_link = rf'https://raw.githubusercontent.com/{repo["name"]}/{repo["repo"]}/{repo["branch"]}' + return ( + f"{repo_link}{specific_file}" + if repo_link[-1] == "/" + else f"{repo_link}/{specific_file}" + ) + + +def api_to_list(data) -> list: + """GitHub API file paths to dictionary""" + stripped, files = [], [] + + # strip unnecessary data + for file_path in data["tree"]: + if file_path["path"] not in ignore_files: + stripped.append(file_path) + + # convert useful file paths to list + for _, value in enumerate(stripped): + files.append(value["path"]) + + return sorted(files) + + +def create_dir(dir_name: str) -> str: + """Create directory""" + path = dir_path + dir_name + + # check if folder exists, if so deleted L + if os.path.isdir(path): + delete_dir(dir_name) + + os.mkdir(path) + print(f"Directory created: {path}") + + return path + + +def delete_dir(dir_name: str) -> None: + """Delete directory""" + path = dir_path + dir_name + rmtree(path) + print(f"Directory deleted: {path}") + + +def user_permissions() -> Union[str, bool]: + """Ask user if Yes or No""" + if not args.y: + rights = input( + "Automatic installer will download and update your program files. If you have the appropriate file, and download rights please continue by entering 'Y'. [y/N] " + ) + if rights.lower() not in ["y", "yes"]: + print("Exiting script...") + sys.exit(1) + return rights + return args.y + + +def debug(statement) -> None: + """send debug info if --debug""" + if args.debug: + print(statement) + + +def download_online_files(path) -> list: + """download files from the internet superhighway""" + files = [] + for file in online_files: + files.append(file) + print(f"Attempting to download {file}.") + try: + downloaded_text = download( + validate(repository, file), f"downloading {file}", False + ) + with open(rf"{path}/{file}", "wb") as temp_file: + temp_file.write( + downloaded_text.encode(sys.stdout.encoding, errors="replace") + ) + except Exception as exc: # skipcq + debug(exc) + print( + f"Failed to download {file}.\nError occurred whilst downloading files.\n" + "Before reporting this as an issue on github please run --debug and report the result." + ) + delete_dir("temp") + sys.exit(1) + print(f"Successfully downloaded {file}.") + return files + + +def delete_files(): + """Delete files""" + for file in online_files: + try: + os.remove(dir_path + file) + except FileNotFoundError: + continue + + +def move_temp_files(): + """move files from /temp to working directory""" + for file in online_files: + copy(dir_path + TEMP_FOLDER + file, dir_path) + + +def pip_install(): + """runs: pip install -r requirements.txt""" + try: + call("pip install -r requirements.txt", shell=True) + except Exception as exc: # skipcq + debug(exc) + print( + "Pip was unable to automatically update your modules." + "\nPlease manually update your modules by using: 'pip install -r requirements.txt'." + ) + return + print("Updated pip modules.") + + +if __name__ == "__main__": + # Force users to use --update + if not args.update: + print(f"Use 'py {os.path.basename(__file__)} --update'") + sys.exit(0) + + # Check latest version + print("Checking latest version online.") + check_version = download( + validate(repository, "version.json"), "check latest version" + ) + print( + f"Found a version online! Attempting to update to {check_version['version']}." + ) + debug(check_version) + + # Get online files + print("Finding list of online files.") + online_files = api_to_list( + download(validate(repository, api=True), "check file directory") + ) + print("Found list of online files.") + debug(online_files) + + # Check for user permissions + user_perm = user_permissions() + debug(user_perm) + + # Create directory + temp_path = create_dir("temp") + + # Download all files to local device + print("Attempting to download files.") + download_online_files(temp_path) + print("Successfully downloaded files") + + # Delete local files + print("Deleting local files.") + delete_files() + print("Deleted local files.") + + # Move files in temp to main directory + print("Moving downloaded files to local directory.") + move_temp_files() + print("Moved downloaded files to local directory.") + + # Delete downloaded/temp folder + print("Deleting temp folder.") + delete_dir("temp") + print("Deleted temp folder.") + + # Updating pip + print("Updating pip modules.") + pip_install() + + # Finishing message + print(f"Successfully updated your script to {check_version['version']}.") From 70c0d1641ca06094ea788d84da9607f5dd9bfc7b Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 06:23:56 +0100 Subject: [PATCH 02/11] req for pylint --- .github/workflows/pylint.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 0f0e51e..2af3a2a 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -17,6 +17,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip + pip install -r requirements.txt pip install pylint - name: Analysing the code with pylint run: | From 210678ca30094c631e081d762afe0d76d226306d Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 06:32:08 +0100 Subject: [PATCH 03/11] pylint --- update.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/update.py b/update.py index d278f12..c643078 100644 --- a/update.py +++ b/update.py @@ -1,3 +1,5 @@ +""" Update script for TerminalSlideShow """ +# pylint: disable=all import os import sys import json From e5befbd87c706aa52cfa320df01ebc5ebffcead7 Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 08:28:31 +0100 Subject: [PATCH 04/11] added unittest-workflow --- .github/workflows/run_unittests.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/run_unittests.yml diff --git a/.github/workflows/run_unittests.yml b/.github/workflows/run_unittests.yml new file mode 100644 index 0000000..7ae9e4f --- /dev/null +++ b/.github/workflows/run_unittests.yml @@ -0,0 +1,25 @@ +name: Run Unit Tests +on: [push] +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11"] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Install exiftool + run: | + sudo apt-get update + sudo apt-get install -y libimage-exiftool-perl + - name: Run tests + run: | + python -m unittest discover unittests \ No newline at end of file From b996a8121ac38438bc39cbc5924335ad1f0038ef Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 21:19:08 +0100 Subject: [PATCH 05/11] try fix pylint error --- MetaDataEditor/unittests/test_custom_widgets.py | 4 +--- MetaDataEditor/unittests/test_image_metadata_handler.py | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/MetaDataEditor/unittests/test_custom_widgets.py b/MetaDataEditor/unittests/test_custom_widgets.py index ee404ad..ccd5a4e 100644 --- a/MetaDataEditor/unittests/test_custom_widgets.py +++ b/MetaDataEditor/unittests/test_custom_widgets.py @@ -1,6 +1,4 @@ -# pylint: disable=C -# pylint: disable=unused-import -# pylint: disable=pointless-string-statement +# pylint: disable=all import __init__ import unittest from PyQt5.QtWidgets import QApplication diff --git a/MetaDataEditor/unittests/test_image_metadata_handler.py b/MetaDataEditor/unittests/test_image_metadata_handler.py index 8362d46..7e7e309 100644 --- a/MetaDataEditor/unittests/test_image_metadata_handler.py +++ b/MetaDataEditor/unittests/test_image_metadata_handler.py @@ -1,5 +1,4 @@ -# pylint: disable=C -# pylint: disable=unused-import +# pylint: disable=all import __init__ import unittest from unittest.mock import patch, MagicMock From 744ad1d29cdb9c60e9a2c0fa1f638bc58771bc81 Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 21:32:53 +0100 Subject: [PATCH 06/11] change pylintrc --- .pylintrc | Bin 132 -> 44096 bytes MetaDataEditor/unittests/__init__.py | 1 + 2 files changed, 1 insertion(+) diff --git a/.pylintrc b/.pylintrc index b0b06bcf742b9230e2d48deefc03cbf94c27a81e..dd6dcb74b847d4f6c317c9f2f8a1f79f3620f1dd 100644 GIT binary patch literal 44096 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 F3INS7EDQhu diff --git a/MetaDataEditor/unittests/__init__.py b/MetaDataEditor/unittests/__init__.py index b4cebcf..51ddf04 100644 --- a/MetaDataEditor/unittests/__init__.py +++ b/MetaDataEditor/unittests/__init__.py @@ -1,3 +1,4 @@ +# pylint: disable=all import os import sys From 5eafe5f9d057b53fffc2f55c87f379c020498bf5 Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 21:39:43 +0100 Subject: [PATCH 07/11] test --- .github/workflows/pylint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 2af3a2a..6905e59 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -19,6 +19,6 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt pip install pylint - - name: Analysing the code with pylint + - name: Run pylint run: | - pylint $(git ls-files '*.py') + pylint **/*.py From b452b6e243a91dd76a5656dc07f1d4aab1be76f1 Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 21:43:03 +0100 Subject: [PATCH 08/11] fix utf8 --- .pylintrc | Bin 44096 -> 21413 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/.pylintrc b/.pylintrc index dd6dcb74b847d4f6c317c9f2f8a1f79f3620f1dd..c43a4ed3ee629ff6a574ed7d375910d0d679689a 100644 GIT binary patch literal 21413 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 Date: Wed, 10 Jan 2024 21:55:01 +0100 Subject: [PATCH 09/11] update pylint stuff --- .pylintrc | 3 ++- MetaDataEditor/custom_widgets.py | 13 ++++++++++--- unittests/test_drive_change_detector.py | 3 +-- unittests/test_drive_connector.py | 4 +--- unittests/test_drive_downloader.py | 4 ++-- unittests/test_show_file_checker.py | 4 ++-- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/.pylintrc b/.pylintrc index c43a4ed..30c2b6f 100644 --- a/.pylintrc +++ b/.pylintrc @@ -430,7 +430,8 @@ disable=raw-checker-failed, deprecated-pragma, use-symbolic-message-instead, use-implicit-booleaness-not-comparison-to-string, - use-implicit-booleaness-not-comparison-to-zero + use-implicit-booleaness-not-comparison-to-zero, + broad-except # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/MetaDataEditor/custom_widgets.py b/MetaDataEditor/custom_widgets.py index 963b6a2..6eecc33 100644 --- a/MetaDataEditor/custom_widgets.py +++ b/MetaDataEditor/custom_widgets.py @@ -15,6 +15,7 @@ class TagTextEdit(QTextEdit): Custom QTextEdit that allows tabbing between widgets """ + # pylint: disable=invalid-name def keyPressEvent(self, event): """Overwrite the keyPressEvent to allow tabbing between widgets""" if event.key() == Qt.Key_Tab and not event.modifiers(): @@ -22,6 +23,7 @@ def keyPressEvent(self, event): else: super().keyPressEvent(event) + # pylint: enable=invalid-name def event(self, event): """Overwrite the event to allow tabbing between widgets""" if ( @@ -35,11 +37,14 @@ def event(self, event): return True return super().event(event) + # pylint: disable=invalid-name def focusInEvent(self, event): """Overwrite the focusInEvent to select all text""" super().focusInEvent(event) self.selectAll() + # pylint: enable=invalid-name + class TagWidget(QWidget): """ @@ -89,15 +94,17 @@ def clear_fields(self): try: self.tag_name_edit.clear() self.tag_value_edit.clear() - except: + except AttributeError: pass def remove_self(self): """Removes itself from the parent layout""" try: self.deleteLater() - except: - pass + except RuntimeError as e: + print(f"RuntimeError: {e}") + except Exception as e: + print(f"An unexpected error occurred: {e}") def get_values(self): """Returns the values of the tag_name_edit and tag_value_edit""" diff --git a/unittests/test_drive_change_detector.py b/unittests/test_drive_change_detector.py index 80b948b..e54335a 100644 --- a/unittests/test_drive_change_detector.py +++ b/unittests/test_drive_change_detector.py @@ -1,5 +1,4 @@ -# pylint: disable=C -# pylint: disable=unused-import +# pylint: disable=all import setup import json import unittest diff --git a/unittests/test_drive_connector.py b/unittests/test_drive_connector.py index be04d76..b10d7d0 100644 --- a/unittests/test_drive_connector.py +++ b/unittests/test_drive_connector.py @@ -1,7 +1,5 @@ """ Unit tests for drive_connector.py """ -# pylint: disable=C -# pylint: disable=unused-import - +# pylint: disable=all import setup import unittest from unittest.mock import patch, MagicMock diff --git a/unittests/test_drive_downloader.py b/unittests/test_drive_downloader.py index 9e095c7..56d3409 100644 --- a/unittests/test_drive_downloader.py +++ b/unittests/test_drive_downloader.py @@ -1,5 +1,5 @@ -# pylint: disable=C -# pylint: disable=unused-import +# pylint: disable=all + import setup import os import unittest diff --git a/unittests/test_show_file_checker.py b/unittests/test_show_file_checker.py index 1d80dff..9fbcf69 100644 --- a/unittests/test_show_file_checker.py +++ b/unittests/test_show_file_checker.py @@ -1,5 +1,5 @@ -# pylint: disable=C -# pylint: disable=unused-import +# pylint: disable=all + import setup import logging from datetime import datetime From 0c09b445617c05314e367b9c557778cbead425d0 Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 22:05:21 +0100 Subject: [PATCH 10/11] elimnating pylint --- MetaDataEditor/app.py | 15 +++++++++------ MetaDataEditor/custom_widgets.py | 2 +- drive_downloader.py | 3 +-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/MetaDataEditor/app.py b/MetaDataEditor/app.py index 5e230f5..11d3dfa 100644 --- a/MetaDataEditor/app.py +++ b/MetaDataEditor/app.py @@ -38,8 +38,8 @@ def load_styles(self, file): """Loads the styles from stylefiles to the application""" - with open(file, "r", encoding="utf-8") as file: - style = file.read() + with open(file, "r", encoding="utf-8") as style_file: + style = style_file.read() self.setStyleSheet(style) @@ -201,8 +201,8 @@ def load_image(self): self.tag_widgets.append(tag_widget) self.scroll_layout.addWidget(tag_widget) - except: - pass + except Exception as error: + logging.warning(error) def save_image(self): """Opens a file dialog to select a location to save the image with metadata""" @@ -223,8 +223,8 @@ def save_image(self): try: tag_name, tag_value = tag_widget.get_values() metadata_dict[tag_name] = tag_value - except: - pass + except AttributeError as error: + logging.warning(error) write_metadata(self.image_path, file_dialog[0], metadata_dict) def display_image(self, image_path): @@ -241,6 +241,7 @@ def display_image(self, image_path): self.image_label.setPixmap(pixmap) self.image_path = image_path + # pylint: disable=invalid-name def resizeEvent(self, event): """Resizes the image when the window is resized""" if ( @@ -253,6 +254,8 @@ def resizeEvent(self, event): self.image_label.setPixmap(pixmap) super().resizeEvent(event) # Call the parent class's resizeEvent method + # pylint: enable=invalid-name + if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) diff --git a/MetaDataEditor/custom_widgets.py b/MetaDataEditor/custom_widgets.py index 6eecc33..6ac3f40 100644 --- a/MetaDataEditor/custom_widgets.py +++ b/MetaDataEditor/custom_widgets.py @@ -52,7 +52,7 @@ class TagWidget(QWidget): """ def __init__(self, tag_name="", tag_value="", text_field_height=50, parent=None): - super(TagWidget, self).__init__(parent) + super().__init__(parent) self.text_field_height = text_field_height diff --git a/drive_downloader.py b/drive_downloader.py index 392bed7..1842e45 100644 --- a/drive_downloader.py +++ b/drive_downloader.py @@ -7,9 +7,8 @@ from googleapiclient.http import MediaIoBaseDownload from googleapiclient.errors import HttpError -# pylint: disable=broad-except - +# pylint: disable=too-many-arguments def download_file(service, file_item, target_directory="./temp"): """Download an item from Google Drive. (file or entire folder)""" file_name = file_item["name"] From 2e8e359fed78091b2399ede678ffd6016e93ea7d Mon Sep 17 00:00:00 2001 From: Muddyblack Date: Wed, 10 Jan 2024 22:07:22 +0100 Subject: [PATCH 11/11] fix pylnt --- MetaDataEditor/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/MetaDataEditor/app.py b/MetaDataEditor/app.py index 11d3dfa..69aadd1 100644 --- a/MetaDataEditor/app.py +++ b/MetaDataEditor/app.py @@ -43,6 +43,7 @@ def load_styles(self, file): self.setStyleSheet(style) +# pylint: disable=too-many-instance-attributes class ImageEditorGUI(QWidget): """ Main GUI Window for editing images MetaData