Open-AutoTools 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- open_autotools-0.0.1/LICENSE +21 -0
- open_autotools-0.0.1/Open_AutoTools.egg-info/PKG-INFO +30 -0
- open_autotools-0.0.1/Open_AutoTools.egg-info/SOURCES.txt +19 -0
- open_autotools-0.0.1/Open_AutoTools.egg-info/dependency_links.txt +1 -0
- open_autotools-0.0.1/Open_AutoTools.egg-info/entry_points.txt +6 -0
- open_autotools-0.0.1/Open_AutoTools.egg-info/requires.txt +26 -0
- open_autotools-0.0.1/Open_AutoTools.egg-info/top_level.txt +1 -0
- open_autotools-0.0.1/PKG-INFO +30 -0
- open_autotools-0.0.1/README.md +65 -0
- open_autotools-0.0.1/autotools/__init__.py +0 -0
- open_autotools-0.0.1/autotools/autocaps/__init__.py +0 -0
- open_autotools-0.0.1/autotools/autocaps/core.py +7 -0
- open_autotools-0.0.1/autotools/autocorrect/__init__.py +0 -0
- open_autotools-0.0.1/autotools/autocorrect/core.py +34 -0
- open_autotools-0.0.1/autotools/autotranslate/__init__.py +0 -0
- open_autotools-0.0.1/autotools/autotranslate/core.py +39 -0
- open_autotools-0.0.1/autotools/cli.py +66 -0
- open_autotools-0.0.1/autotools/downloader/__init__.py +0 -0
- open_autotools-0.0.1/autotools/downloader/core.py +189 -0
- open_autotools-0.0.1/setup.cfg +4 -0
- open_autotools-0.0.1/setup.py +22 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 MAX REMY DEV
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: Open-AutoTools
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
License-File: LICENSE
|
|
5
|
+
Requires-Dist: Brotli==1.1.0
|
|
6
|
+
Requires-Dist: certifi==2024.2.2
|
|
7
|
+
Requires-Dist: charset-normalizer==3.3.2
|
|
8
|
+
Requires-Dist: click==8.1.7
|
|
9
|
+
Requires-Dist: idna==3.6
|
|
10
|
+
Requires-Dist: importlib-metadata==7.0.1
|
|
11
|
+
Requires-Dist: joblib==1.3.2
|
|
12
|
+
Requires-Dist: Levenshtein==0.25.0
|
|
13
|
+
Requires-Dist: mutagen==1.47.0
|
|
14
|
+
Requires-Dist: nltk==3.8.1
|
|
15
|
+
Requires-Dist: platformdirs==4.2.0
|
|
16
|
+
Requires-Dist: pycryptodomex==3.20.0
|
|
17
|
+
Requires-Dist: pyperclip==1.9.0
|
|
18
|
+
Requires-Dist: python-dotenv==1.0.1
|
|
19
|
+
Requires-Dist: python-Levenshtein==0.25.0
|
|
20
|
+
Requires-Dist: rapidfuzz==3.6.1
|
|
21
|
+
Requires-Dist: regex==2023.12.25
|
|
22
|
+
Requires-Dist: requests==2.32.3
|
|
23
|
+
Requires-Dist: textblob==0.18.0.post0
|
|
24
|
+
Requires-Dist: tomli==2.0.1
|
|
25
|
+
Requires-Dist: tqdm==4.66.2
|
|
26
|
+
Requires-Dist: urllib3==2.2.1
|
|
27
|
+
Requires-Dist: websockets==13.0.1
|
|
28
|
+
Requires-Dist: yapf==0.40.2
|
|
29
|
+
Requires-Dist: yt-dlp==2024.8.6
|
|
30
|
+
Requires-Dist: zipp==3.17.0
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
Open_AutoTools.egg-info/PKG-INFO
|
|
5
|
+
Open_AutoTools.egg-info/SOURCES.txt
|
|
6
|
+
Open_AutoTools.egg-info/dependency_links.txt
|
|
7
|
+
Open_AutoTools.egg-info/entry_points.txt
|
|
8
|
+
Open_AutoTools.egg-info/requires.txt
|
|
9
|
+
Open_AutoTools.egg-info/top_level.txt
|
|
10
|
+
autotools/__init__.py
|
|
11
|
+
autotools/cli.py
|
|
12
|
+
autotools/autocaps/__init__.py
|
|
13
|
+
autotools/autocaps/core.py
|
|
14
|
+
autotools/autocorrect/__init__.py
|
|
15
|
+
autotools/autocorrect/core.py
|
|
16
|
+
autotools/autotranslate/__init__.py
|
|
17
|
+
autotools/autotranslate/core.py
|
|
18
|
+
autotools/downloader/__init__.py
|
|
19
|
+
autotools/downloader/core.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Brotli==1.1.0
|
|
2
|
+
certifi==2024.2.2
|
|
3
|
+
charset-normalizer==3.3.2
|
|
4
|
+
click==8.1.7
|
|
5
|
+
idna==3.6
|
|
6
|
+
importlib-metadata==7.0.1
|
|
7
|
+
joblib==1.3.2
|
|
8
|
+
Levenshtein==0.25.0
|
|
9
|
+
mutagen==1.47.0
|
|
10
|
+
nltk==3.8.1
|
|
11
|
+
platformdirs==4.2.0
|
|
12
|
+
pycryptodomex==3.20.0
|
|
13
|
+
pyperclip==1.9.0
|
|
14
|
+
python-dotenv==1.0.1
|
|
15
|
+
python-Levenshtein==0.25.0
|
|
16
|
+
rapidfuzz==3.6.1
|
|
17
|
+
regex==2023.12.25
|
|
18
|
+
requests==2.32.3
|
|
19
|
+
textblob==0.18.0.post0
|
|
20
|
+
tomli==2.0.1
|
|
21
|
+
tqdm==4.66.2
|
|
22
|
+
urllib3==2.2.1
|
|
23
|
+
websockets==13.0.1
|
|
24
|
+
yapf==0.40.2
|
|
25
|
+
yt-dlp==2024.8.6
|
|
26
|
+
zipp==3.17.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
autotools
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: Open-AutoTools
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
License-File: LICENSE
|
|
5
|
+
Requires-Dist: Brotli==1.1.0
|
|
6
|
+
Requires-Dist: certifi==2024.2.2
|
|
7
|
+
Requires-Dist: charset-normalizer==3.3.2
|
|
8
|
+
Requires-Dist: click==8.1.7
|
|
9
|
+
Requires-Dist: idna==3.6
|
|
10
|
+
Requires-Dist: importlib-metadata==7.0.1
|
|
11
|
+
Requires-Dist: joblib==1.3.2
|
|
12
|
+
Requires-Dist: Levenshtein==0.25.0
|
|
13
|
+
Requires-Dist: mutagen==1.47.0
|
|
14
|
+
Requires-Dist: nltk==3.8.1
|
|
15
|
+
Requires-Dist: platformdirs==4.2.0
|
|
16
|
+
Requires-Dist: pycryptodomex==3.20.0
|
|
17
|
+
Requires-Dist: pyperclip==1.9.0
|
|
18
|
+
Requires-Dist: python-dotenv==1.0.1
|
|
19
|
+
Requires-Dist: python-Levenshtein==0.25.0
|
|
20
|
+
Requires-Dist: rapidfuzz==3.6.1
|
|
21
|
+
Requires-Dist: regex==2023.12.25
|
|
22
|
+
Requires-Dist: requests==2.32.3
|
|
23
|
+
Requires-Dist: textblob==0.18.0.post0
|
|
24
|
+
Requires-Dist: tomli==2.0.1
|
|
25
|
+
Requires-Dist: tqdm==4.66.2
|
|
26
|
+
Requires-Dist: urllib3==2.2.1
|
|
27
|
+
Requires-Dist: websockets==13.0.1
|
|
28
|
+
Requires-Dist: yapf==0.40.2
|
|
29
|
+
Requires-Dist: yt-dlp==2024.8.6
|
|
30
|
+
Requires-Dist: zipp==3.17.0
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Open-AutoTools - ***WORK IN PROGRESS (WIP)***
|
|
2
|
+
Open-AutoTools is an innovative project developed in Python, specifically designed to offer a suite of automated tools directly accessible via the terminal. This project aims to simplify and automate daily tasks for developers and terminal users, such as converting text to uppercase, automatically correcting text errors, and real-time text translation.
|
|
3
|
+
|
|
4
|
+
https://github.com/BabylooPro/Open-AutoTools/assets/35376790/d57f2b9d-55f8-4368-bb40-c0010eb9d49a
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
To install Open-AutoTools, use the following command in your terminal: ``pip install open-autotools``
|
|
8
|
+
|
|
9
|
+
This command installs all the necessary tools to integrate Open-AutoTools into your workflow.
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
### AutoCaps
|
|
14
|
+
- **Description:** Converts any text entered by the user to uppercase.
|
|
15
|
+
- **Usage:**
|
|
16
|
+
```
|
|
17
|
+
~ ❯ autocaps "Your text here."
|
|
18
|
+
```
|
|
19
|
+
- **Output:**
|
|
20
|
+
```
|
|
21
|
+
YOUR TEXT HERE.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### AutoCorrect
|
|
25
|
+
- **Description:** Automatically corrects mistakes in any text.
|
|
26
|
+
- **Usage:**
|
|
27
|
+
```
|
|
28
|
+
~ ❯ autocorrect "Your text with mistakes here."
|
|
29
|
+
```
|
|
30
|
+
- **Output:**
|
|
31
|
+
```
|
|
32
|
+
Your text without mistakes here.
|
|
33
|
+
```
|
|
34
|
+
(Note: The exact output for AutoCorrect will vary depending on the mistakes in the input text and the correction applied.)
|
|
35
|
+
|
|
36
|
+
### AutoTranslate
|
|
37
|
+
- **Description:** Translates text from one language to another in real-time, offering users a convenient solution to overcome the language barrier.
|
|
38
|
+
- **Usage:**
|
|
39
|
+
```
|
|
40
|
+
~ ❯ autotranslate "Bonjour le monde" --from fr --to en
|
|
41
|
+
```
|
|
42
|
+
- **Output:**
|
|
43
|
+
```
|
|
44
|
+
Hello world
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
These examples demonstrate how the terminal will display the results after executing each command, providing a straightforward way for users to understand the immediate effects of these commands.
|
|
48
|
+
|
|
49
|
+
## General Usage
|
|
50
|
+
Open-AutoTools is designed to be used as a set of CLI commands, making its features directly accessible from the user's terminal.
|
|
51
|
+
|
|
52
|
+
## Technologies, Frameworks, Libraries, and APIs
|
|
53
|
+
- **Programming Language:** Python (3.8 or higher)
|
|
54
|
+
- **Frameworks and Libraries:** Click
|
|
55
|
+
- **APIs:** Text correction API (multi-language), Text translation API (multi-language)
|
|
56
|
+
|
|
57
|
+
## Contributing
|
|
58
|
+
This project is a work in progress, and we welcome any contributions that can help improve Open-AutoTools. If you're interested in contributing, please check the project's issues or submit a pull request.
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
This project is licensed under the MIT License. For more details, see the [LICENSE](LICENSE) file.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
For more information and updates, please follow the project's GitHub repository.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import os
|
|
3
|
+
import pyperclip
|
|
4
|
+
|
|
5
|
+
# AUTOCORRECT FUNCTION DEFINITION
|
|
6
|
+
def autocorrect_text(text, language="en"):
|
|
7
|
+
# API CALL TO REWRITER API
|
|
8
|
+
url = "https://rewriter-paraphraser-text-changer-multi-language.p.rapidapi.com/rewrite"
|
|
9
|
+
|
|
10
|
+
# PAYLOAD AND HEADERS FOR API CALL
|
|
11
|
+
payload = {
|
|
12
|
+
"language": language,
|
|
13
|
+
"strength": 3, # STRENGTH OF REWRITING (STRENGTH 3 IS RECOMMENDED FOR BETTER RESULTS)
|
|
14
|
+
"text": text
|
|
15
|
+
}
|
|
16
|
+
headers = {
|
|
17
|
+
"content-type": "application/json",
|
|
18
|
+
"X-RapidAPI-Key": os.getenv('RAPIDAPI_API_KEY'), # API KEY FROM ENVIRONMENT VARIABLE
|
|
19
|
+
"X-RapidAPI-Host": "rewriter-paraphraser-text-changer-multi-language.p.rapidapi.com"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# RESPONSE FROM API CALL
|
|
23
|
+
response = requests.post(url, json=payload, headers=headers)
|
|
24
|
+
|
|
25
|
+
# RETURN REWRITTEN TEXT IF SUCCESSFUL ELSE RETURN ERROR MESSAGE
|
|
26
|
+
if response.status_code == 200:
|
|
27
|
+
corrected_text = response.json()['rewrite']
|
|
28
|
+
|
|
29
|
+
# COPY CORRECTED TEXT TO CLIPBOARD
|
|
30
|
+
pyperclip.copy(corrected_text)
|
|
31
|
+
|
|
32
|
+
return corrected_text
|
|
33
|
+
else:
|
|
34
|
+
return "ERROR: CORRECTION FAILED - " + response.text + str(response.status_code)
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import os
|
|
3
|
+
import pyperclip
|
|
4
|
+
|
|
5
|
+
# PARAMETERS API
|
|
6
|
+
BASE_URL = "https://google-translate113.p.rapidapi.com/api/v1/translator/{}"
|
|
7
|
+
HEADERS = {
|
|
8
|
+
"X-RapidAPI-Key": os.getenv('RAPIDAPI_API_KEY'),
|
|
9
|
+
"X-RapidAPI-Host": "google-translate113.p.rapidapi.com"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# FUNCTION TO GET SUPPORTED LANGUAGES
|
|
14
|
+
def autotranslate_supported_languages():
|
|
15
|
+
endpoint = "support-languages"
|
|
16
|
+
full_url = BASE_URL.format(endpoint)
|
|
17
|
+
response = requests.get(full_url, headers=HEADERS)
|
|
18
|
+
languages = response.json()
|
|
19
|
+
|
|
20
|
+
language_codes = [lang['code'] for lang in languages]
|
|
21
|
+
return language_codes
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# FUNCTION TO TRANSLATE TEXT AND COPY TO CLIPBOARD
|
|
25
|
+
def autotranslate_text(text, language_target):
|
|
26
|
+
endpoint = "text"
|
|
27
|
+
full_url = BASE_URL.format(endpoint)
|
|
28
|
+
payload = {"from": "auto", "to": language_target, "text": text}
|
|
29
|
+
specific_headers = {
|
|
30
|
+
**HEADERS, "content-type": "application/x-www-form-urlencoded"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
response = requests.post(full_url, data=payload, headers=specific_headers)
|
|
34
|
+
translated_text = response.json()['trans']
|
|
35
|
+
|
|
36
|
+
# COPY TRANSLATED TEXT TO CLIPBOARD
|
|
37
|
+
pyperclip.copy(translated_text)
|
|
38
|
+
|
|
39
|
+
return translated_text
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from dotenv import load_dotenv
|
|
2
|
+
load_dotenv() # LOAD ENVIRONMENT VARIABLES BEFORE IMPORTING OTHER MODULES BECAUSE CERTAIN MODULES DEPEND ON ENVIRONMENT VARIABLES
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import click
|
|
6
|
+
from autotools.autotranslate.core import autotranslate_text, autotranslate_supported_languages
|
|
7
|
+
from autotools.autocorrect.core import autocorrect_text
|
|
8
|
+
from autotools.autocaps.core import autocaps_transform
|
|
9
|
+
from autotools.downloader.core import download_youtube_video, download_file
|
|
10
|
+
|
|
11
|
+
# CLI FUNCTION DEFINITION
|
|
12
|
+
@click.group()
|
|
13
|
+
def cli():
|
|
14
|
+
"""Autotools is a set of tools for text capitalization, correction and translation."""
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
# AUTOTOOLS COMMAND LINE INTERFACE FUNCTION DEFINITION FOR SHOW HELP MESSAGE
|
|
18
|
+
@cli.command()
|
|
19
|
+
def autotools():
|
|
20
|
+
return
|
|
21
|
+
|
|
22
|
+
# AUTOCAPS COMMAND LINE INTERFACE FUNCTION DEFINITION
|
|
23
|
+
@cli.command()
|
|
24
|
+
@click.argument('text')
|
|
25
|
+
def autocaps(text):
|
|
26
|
+
result = autocaps_transform(text)
|
|
27
|
+
click.echo(result)
|
|
28
|
+
|
|
29
|
+
# AUTOCORRECT COMMAND LINE INTERFACE FUNCTION DEFINITION
|
|
30
|
+
@cli.command()
|
|
31
|
+
@click.argument('text')
|
|
32
|
+
def autocorrect(text):
|
|
33
|
+
result = autocorrect_text(text)
|
|
34
|
+
click.echo(result)
|
|
35
|
+
|
|
36
|
+
# AUTOTRANSLATE COMMAND LINE INTERFACE FUNCTION DEFINITION
|
|
37
|
+
VALID_LANGUAGES = autotranslate_supported_languages() # VALID LANGUAGES FOR TRANSLATION
|
|
38
|
+
@cli.command()
|
|
39
|
+
@click.argument('text')
|
|
40
|
+
#@click.option('--from', 'language_origin', required=True, help="Language of the source text")
|
|
41
|
+
@click.option('--to', 'language_target', required=True, help="Target language for translation")
|
|
42
|
+
def autotranslate(text, language_target):
|
|
43
|
+
if language_target not in VALID_LANGUAGES:
|
|
44
|
+
click.secho(f"Language code '{
|
|
45
|
+
language_target}' is not supported.", fg='red')
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
# CALL TO AUTOTRANSLATE FUNCTION
|
|
49
|
+
result = autotranslate_text(
|
|
50
|
+
text, language_target=language_target)
|
|
51
|
+
click.secho(result)
|
|
52
|
+
|
|
53
|
+
# AUTODOWNLOAD COMMAND LINE INTERFACE FUNCTION DEFINITION
|
|
54
|
+
@cli.command()
|
|
55
|
+
@click.argument('url')
|
|
56
|
+
@click.option('--format', type=click.Choice(['mp4', 'mp3'], case_sensitive=False), default='mp4', help='Output file format (mp4 or mp3)')
|
|
57
|
+
@click.option('--quality', type=click.Choice(['best', '1440p', '1080p', '720p', '480p', '360p', '240p'], case_sensitive=False), default='best', help='"Video quality (mp4 only)"')
|
|
58
|
+
def autodownload(url, format, quality):
|
|
59
|
+
if "youtube.com" in url or "youtu.be" in url:
|
|
60
|
+
download_youtube_video(url, format, quality)
|
|
61
|
+
else:
|
|
62
|
+
download_file(url)
|
|
63
|
+
|
|
64
|
+
# MAIN FUNCTION TO RUN CLI
|
|
65
|
+
if __name__ == '__main__':
|
|
66
|
+
cli()
|
|
File without changes
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from urllib.parse import urlsplit
|
|
5
|
+
from tqdm import tqdm
|
|
6
|
+
import yt_dlp
|
|
7
|
+
import platform
|
|
8
|
+
import subprocess
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# FUNCTION TO GET DEFAULT DOWNLOAD DIRECTORY
|
|
12
|
+
def get_default_download_dir():
|
|
13
|
+
return Path(os.getenv('USERPROFILE') if os.name == 'nt' else Path.home()) / 'Downloads'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# FUNCTION TO GET FILENAME FROM URL WITH DEFAULT AND EXTENSION HANDLING
|
|
17
|
+
def get_filename_from_url(url):
|
|
18
|
+
filename = os.path.basename(urlsplit(url).path)
|
|
19
|
+
if not filename: # IF NO FILENAME IN URL
|
|
20
|
+
return "downloaded_file"
|
|
21
|
+
if not Path(filename).suffix: # IF NO EXTENSION IN FILENAME
|
|
22
|
+
return f"{filename}.bin"
|
|
23
|
+
return filename
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# FUNCTION TO OPEN DOWNLOAD DIRECTORY AFTER DOWNLOAD IS COMPLETE
|
|
27
|
+
def open_download_folder(path):
|
|
28
|
+
try:
|
|
29
|
+
if platform.system() == 'Darwin': # macOS
|
|
30
|
+
subprocess.run(['open', '--', path], check=True)
|
|
31
|
+
elif platform.system() == 'Windows': # Windows
|
|
32
|
+
subprocess.run(['explorer', str(path)], check=True)
|
|
33
|
+
elif platform.system() == 'Linux': # Linux
|
|
34
|
+
subprocess.run(['xdg-open', str(path)], check=True)
|
|
35
|
+
except Exception as e:
|
|
36
|
+
print(f"Could not open the folder: {e}")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# FUNCTION TO VALIDATE YOUTUBE URL FORMAT
|
|
40
|
+
def validate_youtube_url(url):
|
|
41
|
+
try:
|
|
42
|
+
# USE YT-DLP TO CHECK IF THE URL IS VALID
|
|
43
|
+
with yt_dlp.YoutubeDL({'quiet': True, 'no_warnings': True}) as ydl:
|
|
44
|
+
ydl.extract_info(url, download=False)
|
|
45
|
+
return True
|
|
46
|
+
except yt_dlp.utils.DownloadError as e:
|
|
47
|
+
print(f"Invalid YouTube URL: {e}")
|
|
48
|
+
return False
|
|
49
|
+
except Exception as e:
|
|
50
|
+
print(f"Unexpected error during URL validation: {e}")
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# FUNCTION TO DOWNLOAD FILES WITH REQUESTS, INCLUDING ERROR HANDLING AND PROGRESS BAR
|
|
55
|
+
def download_file(url):
|
|
56
|
+
download_dir = get_default_download_dir()
|
|
57
|
+
filename = get_filename_from_url(url)
|
|
58
|
+
dest_file = download_dir / filename
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
with requests.get(url, stream=True) as response:
|
|
62
|
+
response.raise_for_status()
|
|
63
|
+
|
|
64
|
+
total_size = int(response.headers.get('content-length', 0))
|
|
65
|
+
block_size = 1024 # 1KB
|
|
66
|
+
|
|
67
|
+
with tqdm(total=total_size if total_size else None, unit='iB', unit_scale=True, desc=f"Downloading {filename}", leave=True) as tqdm_bar:
|
|
68
|
+
with open(dest_file, 'wb') as file:
|
|
69
|
+
for chunk in response.iter_content(chunk_size=block_size):
|
|
70
|
+
if chunk:
|
|
71
|
+
file.write(chunk)
|
|
72
|
+
tqdm_bar.update(len(chunk))
|
|
73
|
+
|
|
74
|
+
# AUTOMATICALLY OPEN DOWNLOAD FOLDER AFTER FILE DOWNLOAD IS COMPLETE
|
|
75
|
+
open_download_folder(download_dir)
|
|
76
|
+
except requests.exceptions.RequestException as e:
|
|
77
|
+
print(f"Error during file download: {e}")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# FUNCTION TO DOWNLOAD YOUTUBE VIDEOS WITH YT-DLP AND SPECIFIED FORMAT AND QUALITY
|
|
81
|
+
def download_youtube_video(url, file_format='mp4', quality='best'):
|
|
82
|
+
# First, validate the YouTube URL
|
|
83
|
+
if not validate_youtube_url(url):
|
|
84
|
+
print(f"Aborting download: Invalid URL {url}")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
download_dir = get_default_download_dir()
|
|
88
|
+
|
|
89
|
+
video_formats = {
|
|
90
|
+
'1440p': 'bestvideo[height<=1440]+bestaudio/best[height<=1440]',
|
|
91
|
+
'1080p': 'bestvideo[height<=1080]+bestaudio/best[height<=1080]',
|
|
92
|
+
'720p': 'bestvideo[height<=720]+bestaudio/best[height<=720]',
|
|
93
|
+
'480p': 'bestvideo[height<=480]+bestaudio/best[height<=480]',
|
|
94
|
+
'360p': 'bestvideo[height<=360]+bestaudio/best[height<=360]',
|
|
95
|
+
'240p': 'bestvideo[height<=240]+bestaudio/best[height<=240]',
|
|
96
|
+
'best': 'bestvideo+bestaudio/best'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
selected_format = video_formats.get(quality, video_formats['best'])
|
|
100
|
+
|
|
101
|
+
ydl_opts = {
|
|
102
|
+
'format': selected_format if file_format == 'mp4' else 'bestaudio',
|
|
103
|
+
'outtmpl': str(download_dir / '%(title)s.%(ext)s'),
|
|
104
|
+
'progress_hooks': [tqdm_progress_hook],
|
|
105
|
+
'quiet': True, # SUPPRESS MOST OF YT-DLP OUTPUT EXCEPT PROGRESS
|
|
106
|
+
'no_warnings': True, # HIDE WARNINGS
|
|
107
|
+
'merge_output_format': 'mp4' # AUTOMATICALLY REMUX TO MP4 IF NEEDED
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if file_format == 'mp3':
|
|
111
|
+
ydl_opts['postprocessors'] = [{
|
|
112
|
+
'key': 'FFmpegExtractAudio',
|
|
113
|
+
'preferredcodec': 'mp3',
|
|
114
|
+
'preferredquality': '192'
|
|
115
|
+
}]
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
119
|
+
ydl.download([url])
|
|
120
|
+
# AUTOMATICALLY OPEN DOWNLOAD FOLDER AFTER YOUTUBE DOWNLOAD IS COMPLETE
|
|
121
|
+
open_download_folder(download_dir)
|
|
122
|
+
except yt_dlp.utils.DownloadError as e:
|
|
123
|
+
print(f"Error during YouTube download: {e}")
|
|
124
|
+
except Exception as e:
|
|
125
|
+
print(f"Unexpected error: {e}")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# FUNCTION TO LIST AVAILABLE FORMATS FOR A YOUTUBE VIDEO
|
|
129
|
+
def list_available_formats(url):
|
|
130
|
+
try:
|
|
131
|
+
with yt_dlp.YoutubeDL({'quiet': True}) as ydl:
|
|
132
|
+
info_dict = ydl.extract_info(url, download=False)
|
|
133
|
+
formats = info_dict.get('formats', None)
|
|
134
|
+
if formats:
|
|
135
|
+
for f in formats:
|
|
136
|
+
print(f"Format: {f['format_id']}, Resolution: {f.get('resolution')}, Extension: {f['ext']}")
|
|
137
|
+
except yt_dlp.utils.DownloadError as e:
|
|
138
|
+
print(f"Error fetching formats: {e}")
|
|
139
|
+
except Exception as e:
|
|
140
|
+
print(f"Unexpected error: {e}")
|
|
141
|
+
|
|
142
|
+
pbar = None # GLOBAL VARIABLE TO STORE PROGRESS BAR
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# FUNCTION TO UPDATE PROGRESS BAR
|
|
146
|
+
def tqdm_progress_hook(d):
|
|
147
|
+
global pbar
|
|
148
|
+
|
|
149
|
+
if d['status'] == 'downloading':
|
|
150
|
+
total = d.get('total_bytes', 0)
|
|
151
|
+
downloaded = d.get('downloaded_bytes', 0)
|
|
152
|
+
|
|
153
|
+
if pbar is None:
|
|
154
|
+
pbar = tqdm(total=total, unit='B', unit_scale=True, desc="YouTube Download", leave=True)
|
|
155
|
+
|
|
156
|
+
pbar.n = downloaded
|
|
157
|
+
pbar.refresh()
|
|
158
|
+
|
|
159
|
+
elif d['status'] == 'finished' and pbar:
|
|
160
|
+
pbar.n = pbar.total
|
|
161
|
+
pbar.close()
|
|
162
|
+
print("Download completed")
|
|
163
|
+
pbar = None
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# FUNCTION TO DOWNLOAD FILE WITH SPECIFIC HANDLING AND FOLDER OPENING
|
|
167
|
+
def download_file_with_tqdm(url):
|
|
168
|
+
download_dir = get_default_download_dir()
|
|
169
|
+
filename = get_filename_from_url(url)
|
|
170
|
+
dest_file = download_dir / filename
|
|
171
|
+
|
|
172
|
+
try:
|
|
173
|
+
with requests.get(url, stream=True) as response:
|
|
174
|
+
response.raise_for_status()
|
|
175
|
+
|
|
176
|
+
total_size = int(response.headers.get('content-length', 0))
|
|
177
|
+
block_size = 1024 # 1KB
|
|
178
|
+
|
|
179
|
+
with tqdm(total=total_size if total_size else None, unit='iB', unit_scale=True, desc=f"Downloading {filename}", leave=True) as tqdm_bar:
|
|
180
|
+
with open(dest_file, 'wb') as file:
|
|
181
|
+
for chunk in response.iter_content(chunk_size=block_size):
|
|
182
|
+
if chunk:
|
|
183
|
+
file.write(chunk)
|
|
184
|
+
tqdm_bar.update(len(chunk))
|
|
185
|
+
|
|
186
|
+
# AUTOMATICALLY OPEN DOWNLOAD FOLDER AFTER FILE DOWNLOAD IS COMPLETE
|
|
187
|
+
open_download_folder(download_dir)
|
|
188
|
+
except requests.exceptions.RequestException as e:
|
|
189
|
+
print(f"Error during file download: {e}")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
# READING REQUIREMENTS FROM FILE
|
|
4
|
+
with open('requirements.txt') as f:
|
|
5
|
+
required = [line for line in f.read().splitlines() if "git+" not in line] # ignore git+ links in requirements if "pip freeze > requirements.txt" generates them
|
|
6
|
+
|
|
7
|
+
# SETUP CONFIGURATION FOR PACKAGE DISTRIBUTION
|
|
8
|
+
setup(
|
|
9
|
+
name='Open-AutoTools',
|
|
10
|
+
version='0.0.1',
|
|
11
|
+
packages=find_packages(),
|
|
12
|
+
include_package_data=True,
|
|
13
|
+
install_requires=required,
|
|
14
|
+
entry_points='''
|
|
15
|
+
[console_scripts]
|
|
16
|
+
autotools=autotools.cli:autotools
|
|
17
|
+
autocaps=autotools.cli:autocaps
|
|
18
|
+
autocorrect=autotools.cli:autocorrect
|
|
19
|
+
autotranslate=autotools.cli:autotranslate
|
|
20
|
+
autodownload=autotools.cli:autodownload
|
|
21
|
+
''',
|
|
22
|
+
)
|