From 9ce6503fce8e0d8b07c6e68ffd1c76930daecdba Mon Sep 17 00:00:00 2001 From: Josh Levin Date: Mon, 16 May 2022 21:10:59 -0400 Subject: [PATCH 01/16] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e94d7f3..031705f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "redownload" version = "0.1.0" description = "" -authors = ["Josh Levin (Morpheus636) "] +authors = ["Josh Levin "] [tool.poetry.dependencies] python = "^3.10, <3.11" From f21b569743481beedb9ed87537dc483a7545ba48 Mon Sep 17 00:00:00 2001 From: Josh Levin Date: Mon, 16 May 2022 21:57:05 -0400 Subject: [PATCH 02/16] Update code_analysis_pull.yml --- .github/workflows/code_analysis_pull.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code_analysis_pull.yml b/.github/workflows/code_analysis_pull.yml index 1d33c59..a4378a1 100644 --- a/.github/workflows/code_analysis_pull.yml +++ b/.github/workflows/code_analysis_pull.yml @@ -30,7 +30,7 @@ jobs: run: poetry run isort - name: Black (Code Formatter) - run: poetry run black src/ tests/ + run: find . -type f -name "*.py" | xargs poetry run black - name: Check for changes id: changes From f87ddc07bef627335a4e3cebc8bb60d1edc0d75a Mon Sep 17 00:00:00 2001 From: Josh Levin Date: Mon, 16 May 2022 21:57:22 -0400 Subject: [PATCH 03/16] Update code_analysis_push.yml --- .github/workflows/code_analysis_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code_analysis_push.yml b/.github/workflows/code_analysis_push.yml index cd66826..7c73035 100644 --- a/.github/workflows/code_analysis_push.yml +++ b/.github/workflows/code_analysis_push.yml @@ -29,7 +29,7 @@ jobs: run: poetry run isort - name: Black (Code Formatter) - run: poetry run black src/ tests/ + run: find . -type f -name "*.py" | xargs poetry run black - name: Check for changes id: changes From 051908e5c398077c033a7f7bff549146fe707f53 Mon Sep 17 00:00:00 2001 From: Josh Levin Date: Tue, 17 May 2022 17:24:38 -0400 Subject: [PATCH 04/16] (#32) Created config.py --- poetry.lock | 38 +++++++++----------------- pyproject.toml | 1 + src/redownload/config.py | 58 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 src/redownload/config.py diff --git a/poetry.lock b/poetry.lock index 30c44a8..1a17e8a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -57,7 +57,6 @@ mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -121,7 +120,7 @@ python-versions = "*" [[package]] name = "filelock" -version = "3.6.0" +version = "3.7.0" description = "A platform independent file lock." category = "dev" optional = false @@ -365,7 +364,7 @@ hook_testing = ["pytest (>=2.7.3)", "execnet (>=1.5.0)", "psutil"] [[package]] name = "pyinstaller-hooks-contrib" -version = "2022.4" +version = "2022.5" description = "Community maintained hooks for PyInstaller" category = "dev" optional = false @@ -373,7 +372,7 @@ python-versions = ">=3.7" [[package]] name = "pyparsing" -version = "3.0.8" +version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "dev" optional = false @@ -415,7 +414,7 @@ python-versions = "*" name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -477,14 +476,6 @@ category = "dev" optional = false python-versions = ">=3.7" -[[package]] -name = "typing-extensions" -version = "4.2.0" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "dev" -optional = false -python-versions = ">=3.7" - [[package]] name = "urllib3" version = "1.26.9" @@ -518,8 +509,8 @@ testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", [metadata] lock-version = "1.1" -python-versions = "^3.9, <3.11" -content-hash = "6cf471f38fbe3b6e4cfd3ed350a5308a6fb9fee3ca7462ca297e4eeb0024e8b7" +python-versions = "^3.10, <3.11" +content-hash = "0ab46ffd9de727bd1c3380c77a3111eea4dab36297b95d54ebabc7351862ebd4" [metadata.files] altgraph = [ @@ -578,7 +569,6 @@ charset-normalizer = [ click = [ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, - ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -589,8 +579,8 @@ distlib = [ {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"}, ] filelock = [ - {file = "filelock-3.6.0-py3-none-any.whl", hash = "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0"}, - {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, + {file = "filelock-3.7.0-py3-none-any.whl", hash = "sha256:c7b5fdb219b398a5b28c8e4c1893ef5f98ece6a38c6ab2c22e26ec161556fed6"}, + {file = "filelock-3.7.0.tar.gz", hash = "sha256:b795f1b42a61bbf8ec7113c341dad679d772567b936fbd1bf43c9a238e673e20"}, ] flake8 = [ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, @@ -688,12 +678,12 @@ pyinstaller = [ {file = "pyinstaller-4.10.tar.gz", hash = "sha256:7749c868d2e2dc84df7d6f65437226183c8a366f3a99bb2737785625c3a3cca1"}, ] pyinstaller-hooks-contrib = [ - {file = "pyinstaller-hooks-contrib-2022.4.tar.gz", hash = "sha256:b7f7da20e5b83c22219a21b8f849525e5f735197975313208f4e07ff9549cdaf"}, - {file = "pyinstaller_hooks_contrib-2022.4-py2.py3-none-any.whl", hash = "sha256:b57a90bb8520d6e1dbbaaae416875e28fa5a3b74d2e40e330d02d1ccadacc38c"}, + {file = "pyinstaller-hooks-contrib-2022.5.tar.gz", hash = "sha256:90a05207ceea2f8c166f12c3add46e24c0ed6a78234e5f99320f8683d56e0dec"}, + {file = "pyinstaller_hooks_contrib-2022.5-py2.py3-none-any.whl", hash = "sha256:d0ff4c13eda0104db6eb43c60641c19cdf2bc2d6a2a1f0855d26629c3dacc8b7"}, ] pyparsing = [ - {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, - {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -762,10 +752,6 @@ tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -typing-extensions = [ - {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, - {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, -] urllib3 = [ {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, diff --git a/pyproject.toml b/pyproject.toml index 031705f..29416f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ python = "^3.10, <3.11" beautifulsoup4 = "^4.10.0" requests = "^2.27.1" certifi = "^2021.10.8" +PyYAML = "^6.0" [tool.poetry.dev-dependencies] flake8 = "^3.9.2" diff --git a/src/redownload/config.py b/src/redownload/config.py new file mode 100644 index 0000000..00e8a66 --- /dev/null +++ b/src/redownload/config.py @@ -0,0 +1,58 @@ +import os +import platform + +import yaml + + +# Set the IS_UNIX constant to true or false based on the platform +if platform.system() == "linux" or platform.system() == "darwin": + IS_UNIX = True +else: + IS_UNIX = False + import winreg + +# Set the LOCATION constant +if not IS_UNIX: + LOCATION = os.path.join(os.getenv("APPDATA"), "redownload", "config.yml") +elif IS_UNIX: + LOCATION = os.path.join(os.getenv("HOME"), ".config", "redownload", "config.yml") + + +def create_default() -> None: + """Create a config file at the correct location with the default values + + :return: None + """ + # Figure out where the default output dir should be + if not IS_UNIX: + # Get the location of the Downloads folder from the registry + # Yes this is long, windows is stupid. There's nothing I can do about it. Blame Microsoft. + # https://stackoverflow.com/a/48706260/13800487 + sub_key = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + downloads_guid = "{374DE290-123F-4565-9164-39C4925E467B}" + with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key: + downloads_location = winreg.QueryValueEx(key, downloads_guid)[0] + # Actually set the output dir + output_dir = os.path.join(downloads_location, "redownloads") + elif IS_UNIX: + output_dir = os.path.join(os.getenv("HOME"), "Downloads", "redownloads") + + default_config = {"output_dir": output_dir, "track_formats": [".flac", ".mp3"]} + + with open(LOCATION, "w") as stream: + yaml.safe_dump(default_config, stream) + + +def load() -> dict: + """Load the config file from LOCATION and return it as a dict. + + :return: Config dict + """ + if not os.path.exists(LOCATION): + create_default() + with open(LOCATION, "r") as stream: + loaded_config = yaml.safe_load(stream) + return loaded_config + + +config = load() From 50cb89fce699e5106fda54adc259263f41d46b8d Mon Sep 17 00:00:00 2001 From: Josh Levin Date: Tue, 17 May 2022 17:45:26 -0400 Subject: [PATCH 05/16] (#32) CLI now uses config --- src/redownload/__init__.py | 6 ++++-- src/redownload/config.py | 12 ++++++++---- src/redownload_cli.py | 20 ++++++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/redownload/__init__.py b/src/redownload/__init__.py index c6dd077..ea6350f 100644 --- a/src/redownload/__init__.py +++ b/src/redownload/__init__.py @@ -1,9 +1,11 @@ import urllib.parse -from . import downloads, exceptions, version, web_parsing +from . import config, downloads, exceptions, version, web_parsing -def redownload(link, filetypes, output_dir): +def redownload( + link, filetypes=config.config["track_formats"], output_dir=config.config["output_dir"] +): parsed_link = urllib.parse.urlparse(link) if parsed_link.hostname == "archive.org": final_page = web_parsing.html_from_url(link) diff --git a/src/redownload/config.py b/src/redownload/config.py index 00e8a66..7840c04 100644 --- a/src/redownload/config.py +++ b/src/redownload/config.py @@ -5,7 +5,7 @@ # Set the IS_UNIX constant to true or false based on the platform -if platform.system() == "linux" or platform.system() == "darwin": +if platform.system() == "Linux" or platform.system() == "Darwin": IS_UNIX = True else: IS_UNIX = False @@ -13,9 +13,11 @@ # Set the LOCATION constant if not IS_UNIX: - LOCATION = os.path.join(os.getenv("APPDATA"), "redownload", "config.yml") + CONFIG_DIR = os.path.join(os.getenv("APPDATA"), "redownload") + LOCATION = os.path.join(CONFIG_DIR, "config.yml") elif IS_UNIX: - LOCATION = os.path.join(os.getenv("HOME"), ".config", "redownload", "config.yml") + CONFIG_DIR = os.path.join(os.getenv("HOME"), ".config", "redownload") + LOCATION = os.path.join(CONFIG_DIR, "config.yml") def create_default() -> None: @@ -39,7 +41,9 @@ def create_default() -> None: default_config = {"output_dir": output_dir, "track_formats": [".flac", ".mp3"]} - with open(LOCATION, "w") as stream: + # Save the default config to the file + os.makedirs(CONFIG_DIR, exist_ok=True) + with open(LOCATION, "w+") as stream: yaml.safe_dump(default_config, stream) diff --git a/src/redownload_cli.py b/src/redownload_cli.py index 650f9db..a871989 100644 --- a/src/redownload_cli.py +++ b/src/redownload_cli.py @@ -5,6 +5,9 @@ import redownload +config = redownload.config.config + + def main(): parser = argparse.ArgumentParser() parser.add_argument( @@ -22,19 +25,24 @@ def main(): if args.version: print(f"Build Version: {redownload.version.build_version}") sys.exit() + # Non-Interactive Mode elif args.url is not None: if args.output_dir is not None: output_dir = args.output_dir - else: - output_dir = os.path.join(os.getcwd(), "redownloads") + else: # Use the default output dir + output_dir = None + # Interactive Mode else: url = input("Enter the Relisten or Archive.org URL to download the tracks from: ") output_dir = input( - "Enter the path to save the tracks to (ENTER for default [./redownlaods]): " + f"Enter the path to save the tracks to (ENTER for default [{config['output_dir']}]): " ) - if not output_dir: - output_dir = os.path.join(os.getcwd(), "redownloads") - redownload.redownload(url, [".flac", ".mp3"], output_dir) + if not output_dir: # Use the default output dir + output_dir = None + if output_dir: + redownload.redownload(url, output_dir=output_dir) + else: + redownload.redownload(url) if __name__ == "__main__": From f6ebfcf7f6e6b6082024619ef07ff7132b421a77 Mon Sep 17 00:00:00 2001 From: CodeShady <46631279+CodeShady@users.noreply.github.com> Date: Tue, 17 May 2022 19:21:36 -0400 Subject: [PATCH 06/16] Update usage.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added fancy icons to make the usage.md look more professional, and clean. - Added small help section for "Apple can’t check app for malicious software". - Fixed various grammar mistakes. --- docs/usage.md | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 831abdf..b835b81 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -4,27 +4,37 @@ Instructions for downloading it and using it are as follows: - Go to the [Releases](https://github.com/Morpheus636/redownload/releases) page in this repository. - Select the most recent stable release (or alpha/beta, but you may have problems with them). - Download the file starting with `redownload-cli` for your operating system. -## Linux +## Linux Linux - Open a terminal - `cd` into the directory containing the `redownload-cli-linux` file -- run `chmod +x ./redownload-cli-linux` -- you can now run the file with `./redownload-cli-linux `. This will download all the .mp3's and .flac's +- Run `chmod +x ./redownload-cli-linux` +- You can now run the file with `./redownload-cli-linux `. This will download all the .mp3's and .flac's to `./redownloads/` -- if you need more options, you can run `./redownload-cli-linux --help` and it will print the help to the console. +- If you need more options, you can run `./redownload-cli-linux --help` and it will print the help to the console. -## MacOS +## MacOS MacOS - Open a terminal - `cd` into the directory containing the `redownload-cli-mac` file. -- run `chmod +x ./redownload-cli-mac` -- you can now run the file with `./redownload-cli-mac `. This will download all the .mp3's and .flac's +- Run `chmod +x ./redownload-cli-mac` +- You can now run the file with `./redownload-cli-mac `. This will download all the .mp3's and .flac's to `./redownloads/` -- if you need more options, you can run `./redownload-cli-linux --help` and it will print the help to the console. +- If you need more options, you can run `./redownload-cli-linux --help` and it will print the help to the console. -## Windows +### Error Icon If you get "Apple can’t check app for malicious software" error, +By default, MacOS prevents apps from running if your system can't check if the software is malicious or not. +**This github repository is not malicious**, so it's safe to say we can override this and run the software anyway. + +- Immediately after you get the popup, go to **System Preferences** > **Security and Privacy** +- Near the bottom of the page, next to where it says "redownload-cli-mac was blocked from use because it is not from an identified developer", click the button that says - "**Open Anyway**" +- **Run the app again**. (`./redownload-cli-mac ...`) +- A confirmation popup will appear. **Click "Open" in the new popup**. + +## Windows Windows - Open cmd.exe - `cd` into the directory containing the `redownload-cli-windows.exe` file. -- run the file with `redownload-cli-windows Help! +If you need help or clarification, join me on [Discord](https://discord.morpheus636.com) or, you can open a [GitHub Issue](https://github.com/Morpheus636/redownload/issues). From 1b4fe42768b632030dbf8bbf8dd26e534e043b66 Mon Sep 17 00:00:00 2001 From: CodeShady <46631279+CodeShady@users.noreply.github.com> Date: Tue, 17 May 2022 21:33:19 -0400 Subject: [PATCH 07/16] Update usage.md Added credit to Flaticon.com --- docs/usage.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index b835b81..6484857 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -38,3 +38,5 @@ to a subdirectory of your working directory called `redownloads` ## Help! Help! If you need help or clarification, join me on [Discord](https://discord.morpheus636.com) or, you can open a [GitHub Issue](https://github.com/Morpheus636/redownload/issues). + +Uicons by Flaticon From d1f1f16d4efd8cb71b5ea455fcd7ee102ed717b3 Mon Sep 17 00:00:00 2001 From: CodeShady <46631279+CodeShady@users.noreply.github.com> Date: Tue, 17 May 2022 21:54:12 -0400 Subject: [PATCH 08/16] Update README.md Added fancy cover image. --- docs/README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 632ca18..f2c1872 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,10 @@ + + # Redownload -A python based utility for downloading mp3 files from relisten. + + + +A python based utility for downloading mp3 files from [Relisten](https://relisten.net). ## Features - Download music from Relisten and Archive.org automatically @@ -21,4 +26,8 @@ To ask a question or get support, you can join my [Discord Server](https://disco [Forums](https://forums.morpheus636.com) ## Contributing -To contribute to this project, view the Contribution Docs found in [CONTRIBUTING.md](CONTRIBUTING.md) \ No newline at end of file +To contribute to this project, view the Contribution Docs found in [CONTRIBUTING.md](CONTRIBUTING.md) + +--- + +Custom Badges by markdown-badges From da377781a5052c36c35d6cb9dde6a0647a42a3c8 Mon Sep 17 00:00:00 2001 From: CodeShady <46631279+CodeShady@users.noreply.github.com> Date: Tue, 17 May 2022 21:56:14 -0400 Subject: [PATCH 09/16] Add files via upload --- logo.png | Bin 0 -> 57372 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 logo.png diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..da016a83ed213857b7b8edb65f2d3490004a33d6 GIT binary patch literal 57372 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 wR{8~#S%S?9xf}EnOR!mq^!* Date: Tue, 17 May 2022 22:26:20 -0400 Subject: [PATCH 10/16] Delete logo.png --- logo.png | Bin 57372 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 logo.png diff --git a/logo.png b/logo.png deleted file mode 100644 index da016a83ed213857b7b8edb65f2d3490004a33d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57372 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 wR{8~#S%S?9xf}EnOR!mq^!* Date: Tue, 17 May 2022 22:27:19 -0400 Subject: [PATCH 11/16] Update README.md --- docs/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index f2c1872..d924853 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,3 @@ - - # Redownload @@ -30,4 +28,4 @@ To contribute to this project, view the Contribution Docs found in [CONTRIBUTING --- -Custom Badges by markdown-badges +### Custom Badges by markdown-badges From db960fcdd6240349ddc79e6126ec58de95bd69c6 Mon Sep 17 00:00:00 2001 From: CodeShady <46631279+CodeShady@users.noreply.github.com> Date: Tue, 17 May 2022 22:27:46 -0400 Subject: [PATCH 12/16] Update usage.md --- docs/usage.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 6484857..df5eda5 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -39,4 +39,6 @@ to a subdirectory of your working directory called `redownloads` ## Help! Help! If you need help or clarification, join me on [Discord](https://discord.morpheus636.com) or, you can open a [GitHub Issue](https://github.com/Morpheus636/redownload/issues). -Uicons by Flaticon +--- + +### Uicons by Flaticon From 16e624291b754bfd6883a85e16020fb08ecbe497 Mon Sep 17 00:00:00 2001 From: CodeShady <46631279+CodeShady@users.noreply.github.com> Date: Wed, 18 May 2022 15:50:54 -0400 Subject: [PATCH 13/16] Fixed "credit" section --- docs/usage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index df5eda5..6b696df 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -39,6 +39,6 @@ to a subdirectory of your working directory called `redownloads` ## Help! Help! If you need help or clarification, join me on [Discord](https://discord.morpheus636.com) or, you can open a [GitHub Issue](https://github.com/Morpheus636/redownload/issues). ---- -### Uicons by Flaticon +## Credits +Uicons by Flaticon From 3dffb934546c0d8e996b3f2d278ce6e134268b66 Mon Sep 17 00:00:00 2001 From: CodeShady <46631279+CodeShady@users.noreply.github.com> Date: Wed, 18 May 2022 15:51:52 -0400 Subject: [PATCH 14/16] Fixed "credits" section --- docs/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index d924853..7b3710f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,6 +26,5 @@ To ask a question or get support, you can join my [Discord Server](https://disco ## Contributing To contribute to this project, view the Contribution Docs found in [CONTRIBUTING.md](CONTRIBUTING.md) ---- - -### Custom Badges by markdown-badges +## Credits +Custom Badges by markdown-badges From 82f6a193bfab9488535fcd0b3281f33a89c5e119 Mon Sep 17 00:00:00 2001 From: Josh Levin Date: Tue, 14 Jun 2022 18:48:28 -0400 Subject: [PATCH 15/16] (#32) Created optional location arg --- src/redownload/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/redownload/config.py b/src/redownload/config.py index 7840c04..22fd9ea 100644 --- a/src/redownload/config.py +++ b/src/redownload/config.py @@ -20,7 +20,7 @@ LOCATION = os.path.join(CONFIG_DIR, "config.yml") -def create_default() -> None: +def create_default(location=LOCATION) -> None: """Create a config file at the correct location with the default values :return: None @@ -43,7 +43,7 @@ def create_default() -> None: # Save the default config to the file os.makedirs(CONFIG_DIR, exist_ok=True) - with open(LOCATION, "w+") as stream: + with open(location, "w+") as stream: yaml.safe_dump(default_config, stream) From ebfdc54725c88e909e526d680946877ba631eb6b Mon Sep 17 00:00:00 2001 From: Josh Levin Date: Sun, 26 Jun 2022 17:59:31 -0400 Subject: [PATCH 16/16] (#32) created funcs for modifying config --- src/redownload/config.py | 50 +++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/redownload/config.py b/src/redownload/config.py index 22fd9ea..87003a6 100644 --- a/src/redownload/config.py +++ b/src/redownload/config.py @@ -1,5 +1,6 @@ import os import platform +import typing import yaml @@ -19,10 +20,26 @@ CONFIG_DIR = os.path.join(os.getenv("HOME"), ".config", "redownload") LOCATION = os.path.join(CONFIG_DIR, "config.yml") +# Define the empty config variable to be populated by load() +config = dict() + + +def dump(config_dict: dict, location=LOCATION) -> None: + """Dumps config dict to location using YAML syntax. + + :param config_dict: The dictionary to dump. + :param location: The location of the config file. Optional, defaults to LOCATION + :return: None + """ + os.makedirs(os.path.dirname(location), exist_ok=True) + with open(location, "w+") as stream: + yaml.safe_dump(config_dict, stream) + def create_default(location=LOCATION) -> None: """Create a config file at the correct location with the default values + :param location: The location of the config file. Optional, defaults to LOCATION :return: None """ # Figure out where the default output dir should be @@ -42,21 +59,42 @@ def create_default(location=LOCATION) -> None: default_config = {"output_dir": output_dir, "track_formats": [".flac", ".mp3"]} # Save the default config to the file - os.makedirs(CONFIG_DIR, exist_ok=True) - with open(location, "w+") as stream: - yaml.safe_dump(default_config, stream) + dump(default_config, location=location) + + +def set_key(key: str, value: typing.Any, location=LOCATION, ignore_invalid: bool = False) -> None: + """Sets specified key to equal specified in the config dict, and writes the changes + to the config file + + :param key: The key to set. + :param value: The value to set the key to. + :param location: The location of the config file. Optional, defaults to LOCATION + :param ignore_invalid: If true, the function will add a key to the config file if it doesn't already exist. + Otherwise, will raise a KeyError. Optional, defaults to False. + :return None: + """ + global config + if key not in config.keys() and ignore_invalid is False: + raise KeyError("The config key specified does not exist.") + else: + config[key] = value + dump(config, location=location) -def load() -> dict: +def load(location=LOCATION) -> dict: """Load the config file from LOCATION and return it as a dict. + :param location: The location of the config file. Optional, defaults to LOCATION :return: Config dict """ + global config if not os.path.exists(LOCATION): create_default() - with open(LOCATION, "r") as stream: + with open(location, "r") as stream: loaded_config = yaml.safe_load(stream) + config = loaded_config return loaded_config -config = load() +# Load config +load()