Open-AutoTools 0.0.2.post1__py3-none-any.whl → 0.0.3rc1__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.
autotools/cli.py CHANGED
@@ -1,10 +1,17 @@
1
1
  import os
2
2
  import click
3
3
  import base64
4
+ import json as json_module
5
+ from importlib.metadata import version as get_version, PackageNotFoundError
6
+ from packaging.version import parse as parse_version
4
7
  from autotools.autocaps.core import autocaps_transform
5
8
  from autotools.autolower.core import autolower_transform
6
- from autotools.downloader.core import download_youtube_video, download_file
7
- from autotools.password.core import (
9
+ from autotools.autodownload.core import (
10
+ download_youtube_video,
11
+ download_file,
12
+ validate_youtube_url
13
+ )
14
+ from autotools.autopassword.core import (
8
15
  generate_password,
9
16
  generate_encryption_key,
10
17
  analyze_password_strength
@@ -12,56 +19,246 @@ from autotools.password.core import (
12
19
  from translate import Translator
13
20
  from autotools.autotranslate.core import translate_text, get_supported_languages
14
21
  import yt_dlp
15
- from autotools import downloader, autolower, autocaps, autoip
22
+ from autotools import autodownload, autolower, autocaps, autoip
16
23
  import argparse
24
+ from autotools.autospell.core import SpellChecker
25
+ from urllib.parse import urlparse
26
+ import requests
27
+ from datetime import datetime
28
+ import pytest
29
+ import sys
30
+ import subprocess
31
+ from dotenv import load_dotenv
32
+
33
+ # LOAD ENVIRONMENT VARIABLES FROM .ENV FILE
34
+ load_dotenv()
35
+
36
+ # VERSION CALLBACK
37
+ def print_version(ctx, param, value):
38
+ """PRINT VERSION AND CHECK FOR UPDATES"""
39
+
40
+ # EXIT IF VERSION IS NOT REQUESTED
41
+ if not value or ctx.resilient_parsing:
42
+ return
43
+
44
+ # GET CURRENT VERSION
45
+ try:
46
+ pkg_version = get_version('Open-AutoTools')
47
+ click.echo(f"Open-AutoTools version {pkg_version}")
48
+
49
+ try:
50
+ # CHECK IF PACKAGE IS FROM TESTPYPI
51
+ is_testpypi = False
52
+ try:
53
+ import pkg_resources
54
+ dist = pkg_resources.get_distribution('Open-AutoTools')
55
+ is_testpypi = 'test.pypi.org' in dist.location
56
+ except:
57
+ pass
58
+
59
+ # DETERMINE PYPI URL BASED ON SOURCE
60
+ pypi_url = "https://test.pypi.org/pypi/Open-AutoTools/json" if is_testpypi else "https://pypi.org/pypi/Open-AutoTools/json"
61
+
62
+ # CHECK LATEST VERSION FROM PYPI
63
+ response = requests.get(pypi_url)
64
+ if response.status_code == 200:
65
+ data = response.json()
66
+ latest_version = data["info"]["version"]
67
+ # GET RELEASE DATE
68
+ releases = data["releases"]
69
+ if latest_version in releases and releases[latest_version]:
70
+ try:
71
+ upload_time = releases[latest_version][0]["upload_time"]
72
+ # TRY DIFFERENT DATE FORMATS
73
+ try:
74
+ published_date = datetime.strptime(upload_time, "%Y-%m-%dT%H:%M:%S")
75
+ except ValueError:
76
+ try:
77
+ published_date = datetime.strptime(upload_time, "%Y-%m-%dT%H:%M:%S.%fZ")
78
+ except ValueError:
79
+ published_date = datetime.strptime(upload_time, "%Y-%m-%d %H:%M:%S")
80
+ formatted_date = published_date.strftime("%d %B %Y at %H:%M:%S")
81
+ click.echo(f"Released: {formatted_date}")
82
+ except Exception:
83
+ # IF DATE PARSING FAILS, SKIP SHOWING THE DATE
84
+ pass
85
+
86
+ # PARSE VERSIONS FOR COMPARISON
87
+ current_parsed = parse_version(pkg_version)
88
+ latest_parsed = parse_version(latest_version)
89
+
90
+ # COMPARE VERSIONS AND PRINT UPDATE MESSAGE IF NEEDED
91
+ if latest_parsed > current_parsed:
92
+ update_cmd = "pip install --upgrade -i https://test.pypi.org/simple/ Open-AutoTools" if is_testpypi else "pip install --upgrade Open-AutoTools"
93
+ click.echo(click.style(f"\nUpdate available: v{latest_version}", fg='red', bold=True))
94
+ click.echo(click.style(f"Run '{update_cmd}' to update", fg='red'))
95
+ except Exception as e:
96
+ click.echo(f"Error checking updates: {str(e)}")
97
+ except PackageNotFoundError:
98
+ click.echo("Open-AutoTools version information not available")
99
+ ctx.exit()
17
100
 
18
101
  # CLI FUNCTION DEFINITION
19
102
  @click.group()
103
+ @click.option('--version', '--v', is_flag=True, callback=print_version,
104
+ expose_value=False, is_eager=True, help='Show version and check for updates')
105
+ @click.option('--help', '-h', is_flag=True, callback=lambda ctx, param, value:
106
+ None if not value else (click.echo(ctx.get_help() + '\n' +
107
+ (check_for_updates() or '')) or ctx.exit()),
108
+ is_eager=True, expose_value=False, help='Show this message and exit.')
20
109
  def cli():
21
- """Autotools is a set of tools for text capitalization and file downloading."""
110
+ """A suite of automated tools for various tasks.
111
+
112
+ Run 'autotools COMMAND --help' for more information on each command."""
22
113
  pass
23
114
 
24
115
  # AUTOTOOLS COMMAND LINE INTERFACE FUNCTION DEFINITION FOR SHOW HELP MESSAGE
25
116
  @cli.command()
26
117
  def autotools():
27
- return
118
+ """Display available commands and tool information."""
119
+ # SHOW COMMANDS LIST WITH BETTER FORMATTING
120
+ ctx = click.get_current_context()
121
+ commands = cli.list_commands(ctx)
122
+
123
+ click.echo(click.style("\nOpen-AutoTools Commands:", fg='blue', bold=True))
124
+ for cmd in sorted(commands):
125
+ if cmd != 'autotools':
126
+ cmd_obj = cli.get_command(ctx, cmd)
127
+ help_text = cmd_obj.help or cmd_obj.short_help or ''
128
+ click.echo(f"\n{click.style(cmd, fg='green', bold=True)}")
129
+ click.echo(f" {help_text}")
130
+
131
+ # GET OPTIONS FOR EACH COMMAND
132
+ if hasattr(cmd_obj, 'params'):
133
+ click.echo(click.style("\n Options:", fg='yellow'))
134
+ for param in cmd_obj.params:
135
+ if isinstance(param, click.Option):
136
+ opts = '/'.join(param.opts)
137
+ help_text = param.help or ''
138
+ click.echo(f" {click.style(opts, fg='yellow')}")
139
+ click.echo(f" {help_text}")
140
+
141
+ # SHOW USAGE EXAMPLES
142
+ click.echo(click.style("\nUsage Examples:", fg='blue', bold=True))
143
+ click.echo(" autotools --help Show this help message")
144
+ click.echo(" autotools --version Show version information")
145
+ click.echo(" autotools COMMAND Run a specific command")
146
+ click.echo(" autotools COMMAND --help Show help for a specific command")
147
+
148
+ # CHECK FOR UPDATES
149
+ update_msg = check_for_updates()
150
+ if update_msg:
151
+ click.echo(click.style("\nUpdate Available:", fg='red', bold=True))
152
+ click.echo(update_msg)
153
+
154
+ def check_for_updates():
155
+ """CHECK IF AN UPDATE IS AVAILABLE AND RETURN UPDATE MESSAGE IF NEEDED"""
156
+
157
+ # GET CURRENT VERSION
158
+ try:
159
+ current_version = get_version('Open-AutoTools')
160
+
161
+ # CHECK IF PACKAGE IS FROM TESTPYPI
162
+ is_testpypi = False
163
+ try:
164
+ # ATTEMPT TO GET PACKAGE METADATA
165
+ import pkg_resources
166
+ dist = pkg_resources.get_distribution('Open-AutoTools')
167
+ is_testpypi = 'test.pypi.org' in dist.location
168
+ except:
169
+ pass
170
+
171
+ # DETERMINE PYPI URL BASED ON SOURCE
172
+ pypi_url = "https://test.pypi.org/pypi/Open-AutoTools/json" if is_testpypi else "https://pypi.org/pypi/Open-AutoTools/json"
173
+
174
+ # CHECK FOR UPDATES FROM PYPI
175
+ response = requests.get(pypi_url)
176
+
177
+ # CHECK IF RESPONSE IS SUCCESSFUL
178
+ if response.status_code == 200:
179
+ data = response.json()
180
+ latest_version = data["info"]["version"]
181
+
182
+ # PARSE VERSIONS FOR COMPARISON
183
+ current_parsed = parse_version(current_version)
184
+ latest_parsed = parse_version(latest_version)
185
+
186
+ # PRINT UPDATE MESSAGE IF NEEDED
187
+ if latest_parsed > current_parsed:
188
+ update_cmd = "pip install --upgrade -i https://test.pypi.org/simple/ Open-AutoTools" if is_testpypi else "pip install --upgrade Open-AutoTools"
189
+ return (
190
+ click.style(f"\nUpdate available: v{latest_version}", fg='red', bold=True) + "\n" +
191
+ click.style(f"Run '{update_cmd}' to update", fg='red')
192
+ )
193
+ except Exception as e:
194
+ # FOR DEBUGGING, LOG ERROR
195
+ print(f"Error checking updates: {str(e)}")
196
+ pass
197
+ return None
28
198
 
29
199
  # AUTOCAPS COMMAND LINE INTERFACE FUNCTION DEFINITION
30
200
  @cli.command()
31
- @click.argument('text')
201
+ @click.argument('text', nargs=-1)
32
202
  def autocaps(text):
33
- result = autocaps_transform(text)
203
+ """Convert text to UPPERCASE."""
204
+ result = autocaps_transform(" ".join(text))
34
205
  click.echo(result)
206
+
207
+ # UPDATE CHECK AT THE END
208
+ update_msg = check_for_updates()
209
+ if update_msg:
210
+ click.echo(update_msg)
35
211
 
36
212
  # AUTOLOWER CASE COMMAND LINE INTERFACE FUNCTION DEFINITION
37
213
  @cli.command()
38
- @click.argument('text')
214
+ @click.argument('text', nargs=-1)
39
215
  def autolower(text):
40
- result = autolower_transform(text)
216
+ """Convert text to lowercase."""
217
+ result = autolower_transform(" ".join(text))
41
218
  click.echo(result)
219
+
220
+ # UPDATE CHECK AT THE END
221
+ update_msg = check_for_updates()
222
+ if update_msg:
223
+ click.echo(update_msg)
42
224
 
43
225
  # AUTODOWNLOAD COMMAND LINE INTERFACE FUNCTION DEFINITION
44
226
  @cli.command()
45
227
  @click.argument('url')
46
- @click.option('--format', type=click.Choice(['mp4', 'mp3'], case_sensitive=False), default='mp4', help='Output file format (mp4 or mp3)')
47
- @click.option('--quality', type=click.Choice(['best', '1440p', '1080p', '720p', '480p', '360p', '240p'], case_sensitive=False), default='best', help='"Video quality (mp4 only)"')
228
+ @click.option('--format', '-f', type=click.Choice(['mp4', 'mp3'], case_sensitive=False),
229
+ default='mp4', help='Output file format')
230
+ @click.option('--quality', '-q', type=click.Choice(['best', '1440p', '1080p', '720p', '480p', '360p', '240p'],
231
+ case_sensitive=False), default='best', help='Video quality (mp4 only)')
48
232
  def autodownload(url, format, quality):
233
+ """Download videos from YouTube or files from any URL.
234
+
235
+ Supports YouTube video download with quality selection and format conversion (mp4/mp3).
236
+ For non-YouTube URLs, downloads the file directly."""
49
237
  if "youtube.com" in url or "youtu.be" in url:
238
+ # VALIDATE YOUTUBE URL FIRST
239
+ if not validate_youtube_url(url):
240
+ click.echo("Invalid YouTube URL", err=True)
241
+ sys.exit(1)
50
242
  download_youtube_video(url, format, quality)
51
243
  else:
52
244
  download_file(url)
245
+
246
+ # UPDATE CHECK AT THE END
247
+ update_msg = check_for_updates()
248
+ if update_msg:
249
+ click.echo(update_msg)
53
250
 
54
251
  # AUTOPASSWORD COMMAND LINE INTERFACE FUNCTION DEFINITION
55
252
  @cli.command()
56
253
  @click.option('--length', '-l', default=12, help='Password length (default: 12)')
57
- @click.option('--no-uppercase', is_flag=True, help='Exclude uppercase letters')
58
- @click.option('--no-numbers', is_flag=True, help='Exclude numbers')
59
- @click.option('--no-special', is_flag=True, help='Exclude special characters')
60
- @click.option('--min-special', default=1, help='Minimum number of special characters')
61
- @click.option('--min-numbers', default=1, help='Minimum number of numbers')
62
- @click.option('--analyze', is_flag=True, help='Analyze password strength')
63
- @click.option('--gen-key', is_flag=True, help='Generate encryption key')
64
- @click.option('--password-key', help='Generate key from password')
254
+ @click.option('--no-uppercase', '-u', is_flag=True, help='Exclude uppercase letters')
255
+ @click.option('--no-numbers', '-n', is_flag=True, help='Exclude numbers')
256
+ @click.option('--no-special', '-s', is_flag=True, help='Exclude special characters')
257
+ @click.option('--min-special', '-m', default=1, help='Minimum number of special characters')
258
+ @click.option('--min-numbers', '-d', default=1, help='Minimum number of numbers')
259
+ @click.option('--analyze', '-a', is_flag=True, help='Analyze password strength')
260
+ @click.option('--gen-key', '-g', is_flag=True, help='Generate encryption key')
261
+ @click.option('--password-key', '-p', help='Generate key from password')
65
262
  def autopassword(length, no_uppercase, no_numbers, no_special,
66
263
  min_special, min_numbers, analyze, gen_key, password_key):
67
264
  """Generate secure passwords and encryption keys."""
@@ -114,6 +311,11 @@ def autopassword(length, no_uppercase, no_numbers, no_special,
114
311
  # SHOW PASSWORD
115
312
  click.echo(f"Generated Password: {password}")
116
313
  show_analysis(password, "Password ")
314
+
315
+ # UPDATE CHECK AT THE END
316
+ update_msg = check_for_updates()
317
+ if update_msg:
318
+ click.echo(update_msg)
117
319
 
118
320
  # TRANSLATE COMMAND LINE INTERFACE FUNCTION DEFINITION
119
321
  @cli.command()
@@ -123,10 +325,14 @@ def autopassword(length, no_uppercase, no_numbers, no_special,
123
325
  @click.option('--list-languages', is_flag=True, help='List all supported languages')
124
326
  @click.option('--copy', is_flag=True, help='Copy translation to clipboard')
125
327
  @click.option('--detect', is_flag=True, help='Show detected source language')
328
+ @click.option('--output', '-o', type=click.Path(), help='Save translation to file')
126
329
  def autotranslate(text: str, to: str, from_lang: str, list_languages: bool,
127
- copy: bool, detect: bool):
128
- """TRANSLATE TEXT TO SPECIFIED LANGUAGE (AUTO-DETECTS SOURCE LANGUAGE)"""
330
+ copy: bool, detect: bool, output: str):
331
+ """Translate text to specified language.
129
332
 
333
+ Supports automatic language detection, multiple target languages,
334
+ clipboard operations and file output. Use --list-languages to see
335
+ all supported language codes."""
130
336
  # LIST ALL SUPPORTED LANGUAGES
131
337
  if list_languages:
132
338
  click.echo("\nSupported Languages:")
@@ -140,44 +346,222 @@ def autotranslate(text: str, to: str, from_lang: str, list_languages: bool,
140
346
  return
141
347
 
142
348
  result = translate_text(text, to_lang=to, from_lang=from_lang,
143
- copy=copy, detect_lang=detect)
349
+ copy=copy, detect_lang=detect, output=output)
144
350
  click.echo(result)
351
+
352
+ # UPDATE CHECK AT THE END
353
+ update_msg = check_for_updates()
354
+ if update_msg:
355
+ click.echo(update_msg)
145
356
 
146
357
  # AUTOIP COMMAND LINE INTERFACE FUNCTION DEFINITION
147
358
  @cli.command()
148
359
  @click.option('--test', '-t', is_flag=True, help='Run connectivity tests')
149
360
  @click.option('--speed', '-s', is_flag=True, help='Run internet speed test')
150
361
  @click.option('--monitor', '-m', is_flag=True, help='Monitor network traffic')
362
+ @click.option('--interval', '-i', default=1, help='Monitoring interval in seconds')
151
363
  @click.option('--ports', '-p', is_flag=True, help='Check common ports status')
152
364
  @click.option('--dns', '-d', is_flag=True, help='Show DNS servers')
153
365
  @click.option('--location', '-l', is_flag=True, help='Show IP location info')
154
- @click.option('--no-ip', '-n', is_flag=True, help='Hide IP addresses display')
155
- def autoip(test, speed, monitor, ports, dns, location, no_ip):
156
- """DISPLAY LOCAL AND PUBLIC IP ADDRESSES"""
157
- from autotools import autoip
158
- autoip.run(test, speed, monitor, ports, dns, location, no_ip)
366
+ @click.option('--no-ip', '-n', is_flag=True, help='Hide IP addresses')
367
+ def autoip(test, speed, monitor, interval, ports, dns, location, no_ip):
368
+ """Display network information and diagnostics.
369
+
370
+ Shows local and public IP addresses, runs network diagnostics,
371
+ performs speed tests, monitors traffic with custom intervals,
372
+ checks ports, displays DNS information and provides geolocation data."""
373
+ from autotools.autoip.core import run
374
+ output = run(test=test, speed=speed, monitor=monitor, interval=interval,
375
+ ports=ports, dns=dns, location=location, no_ip=no_ip)
376
+ click.echo(output)
377
+
378
+ # UPDATE CHECK AT THE END
379
+ update_msg = check_for_updates()
380
+ if update_msg:
381
+ click.echo(update_msg)
159
382
 
160
- # MAIN FUNCTION TO RUN CLI
161
- if __name__ == '__main__':
162
- cli()
383
+ # AUTOSPELL COMMAND LINE INTERFACE FUNCTION DEFINITION
384
+ @cli.command()
385
+ @click.argument('texts', nargs=-1)
386
+ @click.option('--lang', '-l', default='auto', help='Language code (auto for detection)')
387
+ @click.option('--fix', '-f', is_flag=True, help='Auto-fix text and copy to clipboard')
388
+ @click.option('--copy', '-c', is_flag=True, help='Copy result to clipboard')
389
+ @click.option('--list-languages', is_flag=True, help='List supported languages')
390
+ @click.option('--json', '-j', is_flag=True, help='Output results as JSON')
391
+ @click.option('--ignore', '-i', multiple=True,
392
+ type=click.Choice(['spelling', 'grammar', 'style', 'punctuation']),
393
+ help='Error types to ignore')
394
+ @click.option('--interactive', '-n', is_flag=True,
395
+ help='Interactive mode - confirm each correction')
396
+ @click.option('--output', '-o', type=click.Path(),
397
+ help='Save corrections to file')
398
+ def autospell(texts: tuple, lang: str, fix: bool, copy: bool, list_languages: bool,
399
+ json: bool, ignore: tuple, interactive: bool, output: str):
400
+ """Check and fix text for spelling, grammar, style, and punctuation errors.
401
+
402
+ Provides comprehensive text analysis with support for multiple languages,
403
+ interactive corrections, and various output formats (text/JSON).
404
+ Can ignore specific error types: spelling, grammar, style, or punctuation."""
405
+ checker = SpellChecker()
406
+
407
+ # LIST ALL SUPPORTED LANGUAGES
408
+ if list_languages:
409
+ languages = checker.get_supported_languages()
410
+ if json:
411
+ result = {'languages': languages}
412
+ click.echo(json_module.dumps(result, indent=2))
413
+ else:
414
+ click.echo("\nSupported Languages:")
415
+ for lang in languages:
416
+ click.echo(f"{lang['code']:<8} {lang['name']}")
417
+ return
418
+
419
+ # CHECK AND FIX SPELLING/GRAMMAR IN TEXT
420
+ for text in texts:
421
+ if not text:
422
+ click.echo("Error: Please provide text to check")
423
+ continue
424
+
425
+ # FIX SPELLING/GRAMMAR IN TEXT
426
+ if fix:
427
+ # CORRECT TEXT WITH SPELL CHECKER
428
+ corrected = checker.fix_text(text, lang, copy_to_clipboard=True,
429
+ ignore=ignore, interactive=interactive)
430
+ result = {'corrected_text': corrected} # RESULT TO RETURN
431
+
432
+ # OUTPUT RESULTS AS JSON
433
+ if json:
434
+ click.echo(json_module.dumps(result, indent=2))
435
+ else:
436
+ # LANGUAGE INFORMATION
437
+ check_result = checker.check_text(text, lang)
438
+ lang_info = check_result['language']
439
+ click.echo(f"\nLanguage detected: {lang_info['name']} ({lang_info['code']})")
440
+ click.echo(f"Confidence: {lang_info['confidence']:.2%}")
441
+ click.echo("\nCorrected text (copied to clipboard):")
442
+ click.echo(corrected)
443
+
444
+ # SAVE CORRECTIONS TO FILE
445
+ if output:
446
+ with open(output, 'w', encoding='utf-8') as f:
447
+ if json:
448
+ json_module.dump(result, f, indent=2)
449
+ else:
450
+ f.write(corrected)
451
+ else:
452
+ # CHECK SPELLING/GRAMMAR IN TEXT
453
+ check_result = checker.check_text(text, lang)
454
+
455
+ # OUTPUT RESULTS AS JSON
456
+ if json:
457
+ click.echo(json_module.dumps(check_result, indent=2))
458
+ else:
459
+ lang_info = check_result['language']
460
+ click.echo(f"\nLanguage detected: {lang_info['name']} ({lang_info['code']})")
461
+ click.echo(f"Confidence: {lang_info['confidence']:.2%}")
462
+ click.echo(f"Total errors found: {check_result['statistics']['total_errors']}")
463
+
464
+ # CORRECTIONS SUGGESTED
465
+ if check_result['corrections']:
466
+ click.echo("\nCorrections suggested:")
467
+ for i, corr in enumerate(check_result['corrections'], 1):
468
+ click.echo(f"\n{i}. [{corr['severity'].upper()}] {corr['message']}")
469
+ click.echo(f" Context: {corr['context']}")
470
+ if corr['replacements']:
471
+ click.echo(f" Suggestions: {', '.join(corr['replacements'][:3])}")
472
+
473
+ # SAVE CHECK RESULT TO FILE
474
+ if output:
475
+ with open(output, 'w', encoding='utf-8') as f:
476
+ if json:
477
+ json_module.dump(check_result, f, indent=2)
478
+ else:
479
+ # WRITE A HUMAN-READABLE REPORT
480
+ f.write(f"Language: {lang_info['name']} ({lang_info['code']})\n")
481
+ f.write(f"Confidence: {lang_info['confidence']:.2%}\n")
482
+ f.write(f"Total errors: {check_result['statistics']['total_errors']}\n\n")
483
+
484
+ # CORRECTIONS SUGGESTED
485
+ if check_result['corrections']:
486
+ f.write("Corrections suggested:\n")
487
+ for i, corr in enumerate(check_result['corrections'], 1):
488
+ f.write(f"\n{i}. [{corr['severity'].upper()}] {corr['message']}\n")
489
+ f.write(f" Context: {corr['context']}\n")
490
+ if corr['replacements']:
491
+ f.write(f" Suggestions: {', '.join(corr['replacements'][:3])}\n")
492
+
493
+ # UPDATE CHECK AT THE END
494
+ update_msg = check_for_updates()
495
+ if update_msg:
496
+ click.echo(update_msg)
163
497
 
164
- def download_video(url):
498
+ # TEST COMMAND LINE INTERFACE FUNCTION DEFINITION
499
+ @cli.command()
500
+ @click.option('--unit', '-u', is_flag=True, help='Run only unit tests')
501
+ @click.option('--integration', '-i', is_flag=True, help='Run only integration tests')
502
+ @click.option('--no-cov', is_flag=True, help='Disable coverage report')
503
+ @click.option('--html', is_flag=True, help='Generate HTML coverage report')
504
+ @click.option('--module', '-m', help='Test specific module (e.g., autocaps, autolower)')
505
+ def test(unit, integration, no_cov, html, module):
506
+ """Run test suite with various options."""
507
+ # CHECK IF PYTEST IS INSTALLED
165
508
  try:
166
- # CONFIGURE YT-DLP WITH COOKIES AND HEADERS
167
- yt_opts = {
168
- 'cookiefile': '~/cookies.txt',
169
- 'headers': {
170
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
171
- }
172
- }
173
- with yt_dlp.YoutubeDL(yt_opts) as ydl:
174
- ydl.download([url])
175
- return True
509
+ import pytest
510
+ import pytest_cov
511
+ except ImportError:
512
+ click.echo(click.style("\n❌ pytest and/or pytest-cov not found. Installing...", fg='yellow', bold=True))
513
+ try:
514
+ subprocess.run(['pip', 'install', 'pytest', 'pytest-cov'], check=True)
515
+ click.echo(click.style("✅ Successfully installed pytest and pytest-cov", fg='green', bold=True))
516
+ except subprocess.CalledProcessError as e:
517
+ click.echo(click.style(f"\n❌ Failed to install dependencies: {str(e)}", fg='red', bold=True))
518
+ sys.exit(1)
519
+
520
+ cmd = ['python', '-m', 'pytest', '-v'] # BASE COMMAND
521
+
522
+ # COVERAGE OPTIONS
523
+ if not no_cov:
524
+ cmd.extend(['--cov=autotools'])
525
+ if html:
526
+ cmd.extend(['--cov-report=html'])
527
+ else:
528
+ cmd.extend(['--cov-report=term-missing'])
529
+
530
+ # TEST SELECTION
531
+ test_path = 'autotools'
532
+ if module:
533
+ if unit and not integration:
534
+ cmd.append(f'autotools/{module}/tests/test_{module}_core.py')
535
+ elif integration and not unit:
536
+ cmd.append(f'autotools/{module}/tests/test_{module}_integration.py')
537
+ else:
538
+ cmd.append(f'autotools/{module}/tests')
539
+
540
+ # SHOW COMMAND BEING RUN
541
+ click.echo(click.style("\nRunning tests with command:", fg='blue', bold=True))
542
+ click.echo(" ".join(cmd))
543
+ click.echo()
544
+
545
+ # RUN TESTS
546
+ try:
547
+ result = subprocess.run(cmd, check=True)
548
+ if result.returncode == 0:
549
+ click.echo(click.style("\n✅ All tests passed!", fg='green', bold=True))
550
+ else:
551
+ click.echo(click.style("\n❌ Some tests failed!", fg='red', bold=True))
552
+ sys.exit(1)
553
+ except subprocess.CalledProcessError as e:
554
+ click.echo(click.style(f"\n❌ Tests failed with return code {e.returncode}", fg='red', bold=True))
555
+ sys.exit(1)
176
556
  except Exception as e:
177
- print(f"ERROR: {str(e)}")
178
- return False
557
+ click.echo(click.style(f"\n❌ Error running tests: {str(e)}", fg='red', bold=True))
558
+ sys.exit(1)
559
+
560
+ # UPDATE CHECK AT THE END
561
+ update_msg = check_for_updates()
562
+ if update_msg:
563
+ click.echo(update_msg)
179
564
 
180
- # REMOVE OR COMMENT OUT THE NEW ARGPARSE-BASED MAIN FUNCTION
181
- # def main():
182
- # parser = argparse.ArgumentParser()
183
- # ...
565
+ # MAIN FUNCTION TO RUN CLI
566
+ if __name__ == '__main__':
567
+ cli()
@@ -1,37 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: Open-AutoTools
3
- Version: 0.0.2.post1
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.3
9
- Requires-Dist: cryptography==42.0.2
10
- Requires-Dist: idna==3.6
11
- Requires-Dist: importlib-metadata==7.0.1
12
- Requires-Dist: joblib==1.3.2
13
- Requires-Dist: Levenshtein==0.25.0
14
- Requires-Dist: mutagen==1.47.0
15
- Requires-Dist: platformdirs==4.2.0
16
- Requires-Dist: pycryptodomex==3.20.0
17
- Requires-Dist: pyperclip==1.8.2
18
- Requires-Dist: python-Levenshtein==0.25.0
19
- Requires-Dist: rapidfuzz==3.6.1
20
- Requires-Dist: regex==2023.12.25
21
- Requires-Dist: requests>=2.32.2
22
- Requires-Dist: textblob==0.18.0.post0
23
- Requires-Dist: tomli==2.0.1
24
- Requires-Dist: tqdm==4.66.2
25
- Requires-Dist: urllib3==2.2.1
26
- Requires-Dist: websockets==13.0.1
27
- Requires-Dist: yapf==0.40.2
28
- Requires-Dist: yt-dlp>=2024.3.10
29
- Requires-Dist: zipp==3.17.0
30
- Requires-Dist: translate==3.6.1
31
- Requires-Dist: langdetect==1.0.9
32
- Requires-Dist: deep-translator==1.11.4
33
- Requires-Dist: netifaces>=0.11.0
34
- Requires-Dist: speedtest-cli>=2.1.3
35
- Requires-Dist: psutil>=5.9.0
36
- Requires-Dist: setuptools>=40.8.0
37
- Dynamic: requires-dist
@@ -1,20 +0,0 @@
1
- autotools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- autotools/cli.py,sha256=VWQgHF0WuAD9XGtqaF48EHF5pczrg7VCq-w_wylV9Tc,7167
3
- autotools/autocaps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- autotools/autocaps/core.py,sha256=NnOacVp0kMoq__KHWi5UMcApSuq6Iyo5bFxN40dRw7U,253
5
- autotools/autoip/__init__.py,sha256=T_5hz9G4reFPXDucdzRoMFPYlAKwTPt9TejOpkRPgn0,23
6
- autotools/autoip/core.py,sha256=_Gy8QyDIUaQmfBF6CIP3Ju3_KYbZhs2mst9Vm0sPQUI,6940
7
- autotools/autolower/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- autotools/autolower/core.py,sha256=vjM2ognA3tDCbv10a9vta9WPuAiqTPjOXZ1JHL_b-nk,260
9
- autotools/autotranslate/__init__.py,sha256=6BxuZqhyQhfsZ5x7DkB1BAEpC08GT_5l5bl0AY_eLpU,64
10
- autotools/autotranslate/core.py,sha256=-QdWBIF-eNbuN5qhf45BlOzaOkckwhaF4IMG3OOeRcw,1383
11
- autotools/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- autotools/downloader/core.py,sha256=xmQSEEi3UYPkbbwsL-H4vGKcpqLCkwhIYlZxDWrIEpI,8266
13
- autotools/password/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
14
- autotools/password/core.py,sha256=GQrd-QGWpgxuq6Nf28URcTZRku8Gji1NfpbecXAsIF0,3146
15
- Open_AutoTools-0.0.2.post1.dist-info/LICENSE,sha256=SpbSRxNWos2l0-geleCa6d0L9G_bOsZRkY4rB9OduJ0,1069
16
- Open_AutoTools-0.0.2.post1.dist-info/METADATA,sha256=U8eB5odvQPlYUs044z2s3EMNS9wSYT4CofxyclBTn-s,1163
17
- Open_AutoTools-0.0.2.post1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
18
- Open_AutoTools-0.0.2.post1.dist-info/entry_points.txt,sha256=NVN0wuAVjff3e4_MyceS5o22V_l7_0R_wT2adgvWAlY,282
19
- Open_AutoTools-0.0.2.post1.dist-info/top_level.txt,sha256=x5ZRvdQw7DQnVmR0YDqVSAuuS94KTHDmk6uIeW7YOPw,10
20
- Open_AutoTools-0.0.2.post1.dist-info/RECORD,,
File without changes
File without changes
File without changes
File without changes