Open-AutoTools 0.0.1__py3-none-any.whl

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.
@@ -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,31 @@
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
31
+
@@ -0,0 +1,16 @@
1
+ autotools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ autotools/cli.py,sha256=a510Nq8u3xUA_AGkkEDZSvnZ7DN28wKbpoyShlhU10k,2485
3
+ autotools/autocaps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ autotools/autocaps/core.py,sha256=NnOacVp0kMoq__KHWi5UMcApSuq6Iyo5bFxN40dRw7U,253
5
+ autotools/autocorrect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ autotools/autocorrect/core.py,sha256=S0Sp1wAfuv2k9J9pvvuSJ4vpD_rNn08kcG-jMiXMxlw,1168
7
+ autotools/autotranslate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ autotools/autotranslate/core.py,sha256=qh_0marZKojHCMSuqJbeRZT5CyDwOxknWIygB-rkSXU,1159
9
+ autotools/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ autotools/downloader/core.py,sha256=Meyq0ABpHGziaFYXNYVfoewfZAONc-3stvPOzEzaBm0,6988
11
+ Open_AutoTools-0.0.1.dist-info/LICENSE,sha256=SpbSRxNWos2l0-geleCa6d0L9G_bOsZRkY4rB9OduJ0,1069
12
+ Open_AutoTools-0.0.1.dist-info/METADATA,sha256=PSTWsQQkC-lJVfHg1cZMpHICrUG6eJulQAJHm_OF_K4,925
13
+ Open_AutoTools-0.0.1.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
14
+ Open_AutoTools-0.0.1.dist-info/entry_points.txt,sha256=xpRGvz30QlP0wB7R64UdNzgwOVH7yQMkgtQX7GwwqOk,214
15
+ Open_AutoTools-0.0.1.dist-info/top_level.txt,sha256=x5ZRvdQw7DQnVmR0YDqVSAuuS94KTHDmk6uIeW7YOPw,10
16
+ Open_AutoTools-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (74.1.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,6 @@
1
+ [console_scripts]
2
+ autocaps = autotools.cli:autocaps
3
+ autocorrect = autotools.cli:autocorrect
4
+ autodownload = autotools.cli:autodownload
5
+ autotools = autotools.cli:autotools
6
+ autotranslate = autotools.cli:autotranslate
@@ -0,0 +1 @@
1
+ autotools
autotools/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,7 @@
1
+ import pyperclip
2
+
3
+ # AUTOCAPS CORE FUNCTION DEFINITION
4
+ def autocaps_transform(text):
5
+ transformed_text = text.upper() # TRANSFORM TEXT TO UPPERCASE
6
+ pyperclip.copy(transformed_text) # COPY TRANSFORMED TEXT TO CLIPBOARD
7
+ return transformed_text
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
autotools/cli.py ADDED
@@ -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}")