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.
- Open_AutoTools-0.0.3rc1.dist-info/METADATA +307 -0
- Open_AutoTools-0.0.3rc1.dist-info/RECORD +31 -0
- {Open_AutoTools-0.0.2.post1.dist-info → Open_AutoTools-0.0.3rc1.dist-info}/entry_points.txt +2 -1
- autotools/autocaps/tests/__init__.py +1 -0
- autotools/autocaps/tests/test_autocaps_core.py +45 -0
- autotools/autocaps/tests/test_autocaps_integration.py +46 -0
- autotools/autoip/core.py +133 -40
- autotools/autoip/tests/__init__.py +1 -0
- autotools/autoip/tests/test_autoip_core.py +72 -0
- autotools/autoip/tests/test_autoip_integration.py +92 -0
- autotools/autolower/tests/__init__.py +1 -0
- autotools/autolower/tests/test_autolower_core.py +45 -0
- autotools/autolower/tests/test_autolower_integration.py +46 -0
- autotools/autospell/__init__.py +3 -0
- autotools/autospell/core.py +222 -0
- autotools/autotranslate/core.py +13 -1
- autotools/cli.py +431 -47
- Open_AutoTools-0.0.2.post1.dist-info/METADATA +0 -37
- Open_AutoTools-0.0.2.post1.dist-info/RECORD +0 -20
- {Open_AutoTools-0.0.2.post1.dist-info → Open_AutoTools-0.0.3rc1.dist-info}/LICENSE +0 -0
- {Open_AutoTools-0.0.2.post1.dist-info → Open_AutoTools-0.0.3rc1.dist-info}/WHEEL +0 -0
- {Open_AutoTools-0.0.2.post1.dist-info → Open_AutoTools-0.0.3rc1.dist-info}/top_level.txt +0 -0
- /autotools/{downloader → autodownload}/__init__.py +0 -0
- /autotools/{downloader → autodownload}/core.py +0 -0
- /autotools/{password → autopassword}/__init__.py +0 -0
- /autotools/{password → autopassword}/core.py +0 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: Open-AutoTools
|
|
3
|
+
Version: 0.0.3rc1
|
|
4
|
+
Summary: A suite of automated tools accessible via CLI with a simple `autotools` command
|
|
5
|
+
Home-page: https://github.com/BabylooPro/Open-AutoTools
|
|
6
|
+
Author: BabylooPro
|
|
7
|
+
Author-email: maxremy.dev@gmail.com
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/BabylooPro/Open-AutoTools/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.6
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: Brotli==1.1.0
|
|
16
|
+
Requires-Dist: certifi==2024.2.2
|
|
17
|
+
Requires-Dist: charset-normalizer==3.3.2
|
|
18
|
+
Requires-Dist: click==8.1.3
|
|
19
|
+
Requires-Dist: cryptography==42.0.2
|
|
20
|
+
Requires-Dist: idna==3.6
|
|
21
|
+
Requires-Dist: importlib-metadata>=7.0.1
|
|
22
|
+
Requires-Dist: joblib==1.3.2
|
|
23
|
+
Requires-Dist: Levenshtein==0.25.0
|
|
24
|
+
Requires-Dist: mutagen==1.47.0
|
|
25
|
+
Requires-Dist: packaging>=23.0
|
|
26
|
+
Requires-Dist: platformdirs==4.2.0
|
|
27
|
+
Requires-Dist: pycryptodomex==3.20.0
|
|
28
|
+
Requires-Dist: pyperclip==1.8.2
|
|
29
|
+
Requires-Dist: python-Levenshtein==0.25.0
|
|
30
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
31
|
+
Requires-Dist: rapidfuzz==3.6.1
|
|
32
|
+
Requires-Dist: regex==2023.12.25
|
|
33
|
+
Requires-Dist: requests>=2.32.2
|
|
34
|
+
Requires-Dist: textblob==0.18.0.post0
|
|
35
|
+
Requires-Dist: tomli==2.0.1
|
|
36
|
+
Requires-Dist: tqdm==4.66.2
|
|
37
|
+
Requires-Dist: urllib3==2.2.1
|
|
38
|
+
Requires-Dist: websockets==13.0.1
|
|
39
|
+
Requires-Dist: yapf==0.40.2
|
|
40
|
+
Requires-Dist: yt-dlp>=2024.3.10
|
|
41
|
+
Requires-Dist: zipp==3.17.0
|
|
42
|
+
Requires-Dist: translate==3.6.1
|
|
43
|
+
Requires-Dist: langdetect==1.0.9
|
|
44
|
+
Requires-Dist: deep-translator==1.11.4
|
|
45
|
+
Requires-Dist: netifaces>=0.11.0
|
|
46
|
+
Requires-Dist: speedtest-cli>=2.1.3
|
|
47
|
+
Requires-Dist: psutil>=5.9.0
|
|
48
|
+
Requires-Dist: setuptools>=40.8.0
|
|
49
|
+
Requires-Dist: language-tool-python>=2.7.1
|
|
50
|
+
Requires-Dist: spacy>=3.7.2
|
|
51
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
52
|
+
Provides-Extra: test
|
|
53
|
+
Requires-Dist: pytest>=7.4.0; extra == "test"
|
|
54
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "test"
|
|
55
|
+
Dynamic: author
|
|
56
|
+
Dynamic: author-email
|
|
57
|
+
Dynamic: classifier
|
|
58
|
+
Dynamic: description
|
|
59
|
+
Dynamic: description-content-type
|
|
60
|
+
Dynamic: home-page
|
|
61
|
+
Dynamic: project-url
|
|
62
|
+
Dynamic: provides-extra
|
|
63
|
+
Dynamic: requires-dist
|
|
64
|
+
Dynamic: requires-python
|
|
65
|
+
Dynamic: summary
|
|
66
|
+
|
|
67
|
+
# Open-AutoTools
|
|
68
|
+
|
|
69
|
+
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. It is designed to be used as a set of CLI commands, making its features directly accessible from the user's terminal.
|
|
70
|
+
|
|
71
|
+
https://github.com/BabylooPro/Open-AutoTools/assets/35376790/d57f2b9d-55f8-4368-bb40-c0010eb9d49a
|
|
72
|
+
|
|
73
|
+
## How to install to use directly
|
|
74
|
+
|
|
75
|
+
To install Open-AutoTools, use the following command in your terminal: `pip install open-autotools`
|
|
76
|
+
|
|
77
|
+
This command installs all the necessary tools to integrate Open-AutoTools into your workflow.
|
|
78
|
+
|
|
79
|
+
You can also find the package on PyPI at: https://pypi.org/project/Open-AutoTools/
|
|
80
|
+
|
|
81
|
+
## How to develop more features
|
|
82
|
+
|
|
83
|
+
Open-AutoTools is developed using Python 3.11.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Create a virtual environment
|
|
87
|
+
python -m venv venv
|
|
88
|
+
|
|
89
|
+
# Activate virtual environment
|
|
90
|
+
source venv/bin/activate # On macOS/Linux
|
|
91
|
+
venv\Scripts\activate # On Windows
|
|
92
|
+
|
|
93
|
+
# Install project dependencies
|
|
94
|
+
pip install -r requirements.txt
|
|
95
|
+
|
|
96
|
+
# For development, install in editable mode
|
|
97
|
+
pip install -e .
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Key Features
|
|
101
|
+
|
|
102
|
+
### AutoCaps
|
|
103
|
+
|
|
104
|
+
- **Description:** Converts any text entered by the user to uppercase.
|
|
105
|
+
- **Usage:**
|
|
106
|
+
```
|
|
107
|
+
~ ❯ autocaps "Your text here."
|
|
108
|
+
```
|
|
109
|
+
- **Output:**
|
|
110
|
+
```
|
|
111
|
+
YOUR TEXT HERE.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### AutoLower
|
|
115
|
+
|
|
116
|
+
- **Description:** Converts any text entered by the user to lowercase.
|
|
117
|
+
- **Usage:**
|
|
118
|
+
```
|
|
119
|
+
~ ❯ autolower "Your text here."
|
|
120
|
+
```
|
|
121
|
+
- **Output:**
|
|
122
|
+
```
|
|
123
|
+
your text here.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### AutoPassword
|
|
127
|
+
|
|
128
|
+
- **Description:** Generates secure random passwords and encryption keys with customizable options.
|
|
129
|
+
- **Usage:**
|
|
130
|
+
```
|
|
131
|
+
~ ❯ autopassword --length 16
|
|
132
|
+
~ ❯ autopassword --no-special --length 8
|
|
133
|
+
~ ❯ autopassword --gen-key
|
|
134
|
+
~ ❯ autopassword --password-key "your-password" --analyze
|
|
135
|
+
```
|
|
136
|
+
- **Options:**
|
|
137
|
+
- `--length, -l`: Set password length (default: 12)
|
|
138
|
+
- `--no-uppercase`: Exclude uppercase letters
|
|
139
|
+
- `--no-numbers`: Exclude numbers
|
|
140
|
+
- `--no-special`: Exclude special characters
|
|
141
|
+
- `--min-special`: Minimum number of special characters (default: 1)
|
|
142
|
+
- `--min-numbers`: Minimum number of numbers (default: 1)
|
|
143
|
+
- `--gen-key`: Generate a random encryption key
|
|
144
|
+
- `--password-key`: Generate an encryption key from a password
|
|
145
|
+
- `--analyze`: Show password strength analysis
|
|
146
|
+
|
|
147
|
+
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.
|
|
148
|
+
|
|
149
|
+
### AutoTranslate
|
|
150
|
+
|
|
151
|
+
- **Description:** Translates text between languages with automatic source language detection.
|
|
152
|
+
- **Usage:**
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
~ ❯ autotranslate "Bonjour le monde" --to en
|
|
156
|
+
Hello world
|
|
157
|
+
|
|
158
|
+
~ ❯ autotranslate "Hello world" --to fr --copy
|
|
159
|
+
Bonjour le monde
|
|
160
|
+
// Result also copied to clipboard
|
|
161
|
+
|
|
162
|
+
~ ❯ autotranslate "こんにちは" --to en --detect
|
|
163
|
+
[Detected: ja] Hello
|
|
164
|
+
|
|
165
|
+
~ ❯ autotranslate --list-languages
|
|
166
|
+
// Shows all supported languages
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- **Options:**
|
|
170
|
+
- `--to`: Target language code (default: en)
|
|
171
|
+
- `--from`: Source language code (default: auto-detect)
|
|
172
|
+
- `--copy`: Copy translation to clipboard
|
|
173
|
+
- `--detect`: Show detected source language
|
|
174
|
+
- `--list-languages`: Show all supported language codes and names
|
|
175
|
+
|
|
176
|
+
### AutoSpell (unreleased)
|
|
177
|
+
|
|
178
|
+
- **Description:** Checks and corrects spelling in text with multi-language support.
|
|
179
|
+
- **Usage:**
|
|
180
|
+
```
|
|
181
|
+
~ ❯ autospell "Your text with misspellings"
|
|
182
|
+
~ ❯ autospell --lang fr "Votre texte avec des fautes"
|
|
183
|
+
~ ❯ autospell --file document.txt
|
|
184
|
+
```
|
|
185
|
+
- **Options:**
|
|
186
|
+
- `--lang`: Language code (default: en)
|
|
187
|
+
- `--file`: Input from file
|
|
188
|
+
- `--copy`: Copy corrected text to clipboard
|
|
189
|
+
- `--suggest`: Show alternative suggestions
|
|
190
|
+
- `--interactive`: Interactive correction mode
|
|
191
|
+
|
|
192
|
+
### AutoDownload
|
|
193
|
+
|
|
194
|
+
- **Description:** Downloads videos from YouTube and files from other sources.
|
|
195
|
+
- **Usage:**
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Download YouTube video in MP4 format
|
|
199
|
+
~ ❯ autodownload https://youtube.com/watch?v=example
|
|
200
|
+
|
|
201
|
+
# Download with specific format and quality
|
|
202
|
+
~ ❯ autodownload https://youtube.com/watch?v=example --format mp3
|
|
203
|
+
~ ❯ autodownload https://youtube.com/watch?v=example --quality 1080p
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
- **Options:**
|
|
207
|
+
|
|
208
|
+
- `--format`: Choose output format (mp4 or mp3)
|
|
209
|
+
- `--quality`: Select video quality (best, 1440p, 1080p, 720p, 480p, 360p, 240p)
|
|
210
|
+
|
|
211
|
+
- **Features:**
|
|
212
|
+
|
|
213
|
+
- Automatic bot detection bypass
|
|
214
|
+
- Browser cookie integration
|
|
215
|
+
- Progress tracking
|
|
216
|
+
- Multiple quality options
|
|
217
|
+
- MP3 audio extraction
|
|
218
|
+
- Downloads to user's Downloads folder
|
|
219
|
+
- Supports both YouTube and general file downloads
|
|
220
|
+
|
|
221
|
+
- **Setup Requirements:**
|
|
222
|
+
|
|
223
|
+
- Chrome browser installed and configured:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# First time setup:
|
|
227
|
+
1. Open Chrome and sign in to YouTube
|
|
228
|
+
2. Make sure you're logged into your Google account
|
|
229
|
+
3. Accept YouTube's terms of service in browser
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
- **Troubleshooting:**
|
|
233
|
+
|
|
234
|
+
- If downloads fail with "Sign in to confirm you're not a bot":
|
|
235
|
+
|
|
236
|
+
1. Open YouTube in Chrome
|
|
237
|
+
2. Sign in if not already
|
|
238
|
+
3. Solve any CAPTCHA if prompted
|
|
239
|
+
4. Try download again
|
|
240
|
+
|
|
241
|
+
- If you get cookie errors:
|
|
242
|
+
1. Clear Chrome cookies
|
|
243
|
+
2. Sign in to YouTube again
|
|
244
|
+
3. Wait a few minutes before downloading
|
|
245
|
+
|
|
246
|
+
- **Technical Requirements:**
|
|
247
|
+
- Chrome browser (for cookie and session handling)
|
|
248
|
+
- Active YouTube/Google account
|
|
249
|
+
- Internet connection
|
|
250
|
+
- Sufficient storage space
|
|
251
|
+
- yt-dlp library (automatically installed)
|
|
252
|
+
|
|
253
|
+
> **Note:** The tool uses your Chrome browser's cookies to authenticate with YouTube. This is required to bypass YouTube's bot detection and download restrictions.
|
|
254
|
+
|
|
255
|
+
### AutoIP
|
|
256
|
+
|
|
257
|
+
- **Description:** Displays network information including IP addresses, connectivity tests, speed tests, and more.
|
|
258
|
+
- **Usage:**
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Display IP addresses
|
|
262
|
+
~ ❯ autoip
|
|
263
|
+
|
|
264
|
+
# Run speed test
|
|
265
|
+
~ ❯ autoip --speed
|
|
266
|
+
|
|
267
|
+
# Test connectivity
|
|
268
|
+
~ ❯ autoip --test
|
|
269
|
+
|
|
270
|
+
# Show location info
|
|
271
|
+
~ ❯ autoip --location
|
|
272
|
+
|
|
273
|
+
# Monitor network traffic
|
|
274
|
+
~ ❯ autoip --monitor
|
|
275
|
+
|
|
276
|
+
# Check common ports
|
|
277
|
+
~ ❯ autoip --ports
|
|
278
|
+
|
|
279
|
+
# Show DNS servers
|
|
280
|
+
~ ❯ autoip --dns
|
|
281
|
+
|
|
282
|
+
# Hide IP display and only show tests
|
|
283
|
+
~ ❯ autoip --no-ip --test --speed
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
- **Options:**
|
|
287
|
+
|
|
288
|
+
- `--test, -t`: Run connectivity tests to popular services
|
|
289
|
+
- `--speed, -s`: Run internet speed test
|
|
290
|
+
- `--monitor, -m`: Monitor real-time network traffic
|
|
291
|
+
- `--ports, -p`: Check status of common ports
|
|
292
|
+
- `--dns, -d`: Show DNS server configuration
|
|
293
|
+
- `--location, -l`: Show IP geolocation information
|
|
294
|
+
- `--no-ip, -n`: Hide IP addresses display
|
|
295
|
+
|
|
296
|
+
- **Features:**
|
|
297
|
+
- Local and public IP detection (IPv4 & IPv6)
|
|
298
|
+
- Internet speed testing
|
|
299
|
+
- Network connectivity checks
|
|
300
|
+
- Real-time traffic monitoring
|
|
301
|
+
- Port scanning
|
|
302
|
+
- DNS server information
|
|
303
|
+
- IP geolocation
|
|
304
|
+
|
|
305
|
+
## License
|
|
306
|
+
|
|
307
|
+
This project is licensed under the MIT License. For more details, see the [LICENSE](LICENSE) file.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
autotools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
autotools/cli.py,sha256=YJ_0Dq7t97SPkmmRSvqFuBkOVsh2UcnNcS8wdNSoESg,24389
|
|
3
|
+
autotools/autocaps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
autotools/autocaps/core.py,sha256=NnOacVp0kMoq__KHWi5UMcApSuq6Iyo5bFxN40dRw7U,253
|
|
5
|
+
autotools/autocaps/tests/__init__.py,sha256=CckydfM7SZdXtW3pLgAeRdrC60sovNx_v59nyFvslFo,23
|
|
6
|
+
autotools/autocaps/tests/test_autocaps_core.py,sha256=fzpci_sK7L1fSf_IJ1paJ__bmnHwC9OUOD7ftd3w07c,1672
|
|
7
|
+
autotools/autocaps/tests/test_autocaps_integration.py,sha256=Qe2hzVEvzf0-INp14oTTrHi0RiRDCE2fxo9abVNcd_E,1435
|
|
8
|
+
autotools/autodownload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
autotools/autodownload/core.py,sha256=xmQSEEi3UYPkbbwsL-H4vGKcpqLCkwhIYlZxDWrIEpI,8266
|
|
10
|
+
autotools/autoip/__init__.py,sha256=T_5hz9G4reFPXDucdzRoMFPYlAKwTPt9TejOpkRPgn0,23
|
|
11
|
+
autotools/autoip/core.py,sha256=Q3dzLstZQruwYkSbCSlKQNmKVGCyNpo1DGst5VFtHLU,10123
|
|
12
|
+
autotools/autoip/tests/__init__.py,sha256=CckydfM7SZdXtW3pLgAeRdrC60sovNx_v59nyFvslFo,23
|
|
13
|
+
autotools/autoip/tests/test_autoip_core.py,sha256=Q8865qqhopcGBzS4mIlDlEzxu-mTIbZxpgJyzIyuQXc,2153
|
|
14
|
+
autotools/autoip/tests/test_autoip_integration.py,sha256=-vS2gnY8ZfT-tfY2FRbUtTzY0lcIBtVZHbPbWsKyueo,2746
|
|
15
|
+
autotools/autolower/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
autotools/autolower/core.py,sha256=vjM2ognA3tDCbv10a9vta9WPuAiqTPjOXZ1JHL_b-nk,260
|
|
17
|
+
autotools/autolower/tests/__init__.py,sha256=CckydfM7SZdXtW3pLgAeRdrC60sovNx_v59nyFvslFo,23
|
|
18
|
+
autotools/autolower/tests/test_autolower_core.py,sha256=ChkS3qZgXz75iLfC9EXVH_kMd-sjaxpRKFjaxKoBnxo,1694
|
|
19
|
+
autotools/autolower/tests/test_autolower_integration.py,sha256=M2yN1Ym7kGulys62-IwKq-uWn7CFvI3sCnoo-e3CTaA,1446
|
|
20
|
+
autotools/autopassword/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
21
|
+
autotools/autopassword/core.py,sha256=GQrd-QGWpgxuq6Nf28URcTZRku8Gji1NfpbecXAsIF0,3146
|
|
22
|
+
autotools/autospell/__init__.py,sha256=jkpkiE7pksBgllXKfkNpYYvqtlm8vN0h4kXnQOqcb_U,60
|
|
23
|
+
autotools/autospell/core.py,sha256=WPvi9Xs6uF3dte_g2I9oHfTjCV1-NasrJElLP9bbC8U,8103
|
|
24
|
+
autotools/autotranslate/__init__.py,sha256=6BxuZqhyQhfsZ5x7DkB1BAEpC08GT_5l5bl0AY_eLpU,64
|
|
25
|
+
autotools/autotranslate/core.py,sha256=H2f90IWr_jNGiJD3XAv-20i5sRGM-VDYWrYt65EDEkI,1836
|
|
26
|
+
Open_AutoTools-0.0.3rc1.dist-info/LICENSE,sha256=SpbSRxNWos2l0-geleCa6d0L9G_bOsZRkY4rB9OduJ0,1069
|
|
27
|
+
Open_AutoTools-0.0.3rc1.dist-info/METADATA,sha256=Vvbj28d0I4k0RdUeBE6v2lxmkvr5UxV89nznLpU9bVs,9120
|
|
28
|
+
Open_AutoTools-0.0.3rc1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
29
|
+
Open_AutoTools-0.0.3rc1.dist-info/entry_points.txt,sha256=QLIsUk6vHo0wAYDk1K74kIuYunJMwWe2xbwQhJXLoKo,312
|
|
30
|
+
Open_AutoTools-0.0.3rc1.dist-info/top_level.txt,sha256=x5ZRvdQw7DQnVmR0YDqVSAuuS94KTHDmk6uIeW7YOPw,10
|
|
31
|
+
Open_AutoTools-0.0.3rc1.dist-info/RECORD,,
|
|
@@ -4,5 +4,6 @@ autodownload = autotools.cli:autodownload
|
|
|
4
4
|
autoip = autotools.cli:autoip
|
|
5
5
|
autolower = autotools.cli:autolower
|
|
6
6
|
autopassword = autotools.cli:autopassword
|
|
7
|
-
|
|
7
|
+
autospell = autotools.cli:autospell
|
|
8
|
+
autotools = autotools.cli:cli
|
|
8
9
|
autotranslate = autotools.cli:autotranslate
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# INIT FILE FOR TESTS
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from autotools.autocaps.core import autocaps_transform
|
|
3
|
+
|
|
4
|
+
# UNIT TESTS
|
|
5
|
+
|
|
6
|
+
# TEST FOR BASIC STRING TRANSFORMATION
|
|
7
|
+
def test_autocaps_transform_basic():
|
|
8
|
+
"""TEST BASIC STRING TRANSFORMATION"""
|
|
9
|
+
assert autocaps_transform("hello") == "HELLO"
|
|
10
|
+
assert autocaps_transform("Hello World") == "HELLO WORLD"
|
|
11
|
+
assert autocaps_transform("123") == "123"
|
|
12
|
+
|
|
13
|
+
# TEST FOR EMPTY STRING
|
|
14
|
+
def test_autocaps_transform_empty():
|
|
15
|
+
"""TEST EMPTY STRING"""
|
|
16
|
+
assert autocaps_transform("") == ""
|
|
17
|
+
|
|
18
|
+
# TEST FOR SPECIAL CHARACTERS
|
|
19
|
+
def test_autocaps_transform_special_chars():
|
|
20
|
+
"""TEST STRING WITH SPECIAL CHARACTERS"""
|
|
21
|
+
assert autocaps_transform("hello@world.com") == "HELLO@WORLD.COM"
|
|
22
|
+
assert autocaps_transform("hello-world!") == "HELLO-WORLD!"
|
|
23
|
+
|
|
24
|
+
# TEST FOR MIXED CASE STRING
|
|
25
|
+
def test_autocaps_transform_mixed_case():
|
|
26
|
+
"""TEST MIXED CASE STRING"""
|
|
27
|
+
assert autocaps_transform("HeLLo WoRLD") == "HELLO WORLD"
|
|
28
|
+
|
|
29
|
+
# TEST FOR WHITESPACE
|
|
30
|
+
def test_autocaps_transform_whitespace():
|
|
31
|
+
"""TEST STRING WITH WHITESPACE"""
|
|
32
|
+
assert autocaps_transform(" hello world ") == " HELLO WORLD "
|
|
33
|
+
assert autocaps_transform("\thello\nworld") == "\tHELLO\nWORLD"
|
|
34
|
+
|
|
35
|
+
# TEST FOR NUMBERS
|
|
36
|
+
def test_autocaps_transform_numbers():
|
|
37
|
+
"""TEST STRING WITH NUMBERS"""
|
|
38
|
+
assert autocaps_transform("hello123world") == "HELLO123WORLD"
|
|
39
|
+
assert autocaps_transform("123hello456world789") == "123HELLO456WORLD789"
|
|
40
|
+
|
|
41
|
+
# TEST FOR UNICODE CHARACTERS
|
|
42
|
+
def test_autocaps_transform_unicode():
|
|
43
|
+
"""TEST UNICODE CHARACTERS"""
|
|
44
|
+
assert autocaps_transform("héllo wörld") == "HÉLLO WÖRLD"
|
|
45
|
+
assert autocaps_transform("こんにちは") == "こんにちは" # JAPANESE SHOULD REMAIN UNCHANGED
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from click.testing import CliRunner
|
|
3
|
+
from autotools.cli import autocaps
|
|
4
|
+
|
|
5
|
+
# INTEGRATION TESTS
|
|
6
|
+
|
|
7
|
+
# TEST FOR BASIC CLI FUNCTIONALITY
|
|
8
|
+
def test_autocaps_cli_basic():
|
|
9
|
+
"""TEST BASIC CLI FUNCTIONALITY"""
|
|
10
|
+
runner = CliRunner()
|
|
11
|
+
result = runner.invoke(autocaps, ["hello world"])
|
|
12
|
+
assert result.exit_code == 0
|
|
13
|
+
assert "HELLO WORLD" in result.output
|
|
14
|
+
|
|
15
|
+
# TEST FOR EMPTY INPUT
|
|
16
|
+
def test_autocaps_cli_empty():
|
|
17
|
+
"""TEST CLI WITH EMPTY INPUT"""
|
|
18
|
+
runner = CliRunner()
|
|
19
|
+
result = runner.invoke(autocaps, [""])
|
|
20
|
+
assert result.exit_code == 0
|
|
21
|
+
assert "" in result.output
|
|
22
|
+
|
|
23
|
+
# TEST FOR SPECIAL CHARACTERS
|
|
24
|
+
def test_autocaps_cli_special_chars():
|
|
25
|
+
"""TEST CLI WITH SPECIAL CHARACTERS"""
|
|
26
|
+
runner = CliRunner()
|
|
27
|
+
result = runner.invoke(autocaps, ["hello@world.com"])
|
|
28
|
+
assert result.exit_code == 0
|
|
29
|
+
assert "HELLO@WORLD.COM" in result.output
|
|
30
|
+
|
|
31
|
+
# TEST FOR UNICODE CHARACTERS
|
|
32
|
+
def test_autocaps_cli_unicode():
|
|
33
|
+
"""TEST CLI WITH UNICODE CHARACTERS"""
|
|
34
|
+
runner = CliRunner()
|
|
35
|
+
result = runner.invoke(autocaps, ["héllo wörld"])
|
|
36
|
+
assert result.exit_code == 0
|
|
37
|
+
assert "HÉLLO WÖRLD" in result.output
|
|
38
|
+
|
|
39
|
+
# TEST FOR MULTIPLE ARGUMENTS
|
|
40
|
+
def test_autocaps_cli_multiple_args():
|
|
41
|
+
"""TEST CLI WITH MULTIPLE ARGUMENTS"""
|
|
42
|
+
runner = CliRunner()
|
|
43
|
+
result = runner.invoke(autocaps, ["hello", "world"])
|
|
44
|
+
assert result.exit_code == 0
|
|
45
|
+
# SHOULD ONLY PROCESS FIRST ARGUMENT
|
|
46
|
+
assert "HELLO" in result.output
|
autotools/autoip/core.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import socket
|
|
2
2
|
import requests
|
|
3
|
+
import json
|
|
4
|
+
import ipaddress
|
|
3
5
|
import netifaces
|
|
4
6
|
import time
|
|
5
7
|
import speedtest
|
|
@@ -125,94 +127,185 @@ def run_speedtest():
|
|
|
125
127
|
print(f"\nSpeed test failed: {str(e)}")
|
|
126
128
|
return False
|
|
127
129
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
# GET PUBLIC IP ADDRESS USING IPIFY API
|
|
131
|
+
def get_public_ip():
|
|
132
|
+
"""GET PUBLIC IP ADDRESS USING IPIFY API"""
|
|
133
|
+
try:
|
|
134
|
+
response = requests.get('https://api.ipify.org')
|
|
135
|
+
return response.text
|
|
136
|
+
except requests.RequestException:
|
|
137
|
+
# FALLBACK TO ANOTHER SERVICE IF IPIFY FAILS
|
|
138
|
+
try:
|
|
139
|
+
response = requests.get('https://api.ipapi.com/api/check')
|
|
140
|
+
return response.json()['ip']
|
|
141
|
+
except:
|
|
142
|
+
return None
|
|
143
|
+
|
|
144
|
+
# GET LOCAL IP ADDRESS
|
|
145
|
+
def get_local_ip():
|
|
146
|
+
"""GET LOCAL IP ADDRESS"""
|
|
147
|
+
try:
|
|
148
|
+
# GET DEFAULT INTERFACE
|
|
149
|
+
gateways = netifaces.gateways()
|
|
150
|
+
default_interface = gateways['default'][netifaces.AF_INET][1]
|
|
151
|
+
|
|
152
|
+
# GET IP FROM DEFAULT INTERFACE
|
|
153
|
+
addrs = netifaces.ifaddresses(default_interface)
|
|
154
|
+
return addrs[netifaces.AF_INET][0]['addr']
|
|
155
|
+
except:
|
|
156
|
+
# FALLBACK METHOD
|
|
157
|
+
try:
|
|
158
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
159
|
+
s.connect(("8.8.8.8", 80))
|
|
160
|
+
ip = s.getsockname()[0]
|
|
161
|
+
s.close()
|
|
162
|
+
return ip
|
|
163
|
+
except:
|
|
164
|
+
return None
|
|
165
|
+
|
|
166
|
+
# GET IP INFORMATION USING IPAPI.CO
|
|
167
|
+
def get_ip_info(ip=None):
|
|
168
|
+
"""GET IP INFORMATION USING IPAPI.CO
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
ip (str, optional): IP address to get info for. If None, uses current IP.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
dict: Dictionary containing IP information
|
|
175
|
+
|
|
176
|
+
Raises:
|
|
177
|
+
ValueError: If IP is invalid or private
|
|
178
|
+
"""
|
|
179
|
+
if ip:
|
|
180
|
+
# VALIDATE IP
|
|
181
|
+
try:
|
|
182
|
+
ip_obj = ipaddress.ip_address(ip)
|
|
183
|
+
if ip_obj.is_private:
|
|
184
|
+
raise ValueError("Cannot get info for private IP addresses")
|
|
185
|
+
except ValueError as e:
|
|
186
|
+
raise ValueError(f"Invalid IP address: {str(e)}")
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
# USE IPAPI.CO FOR IP INFO
|
|
190
|
+
url = f'https://ipapi.co/{ip}/json' if ip else 'https://ipapi.co/json'
|
|
191
|
+
response = requests.get(url)
|
|
192
|
+
data = response.json()
|
|
193
|
+
|
|
194
|
+
if 'error' in data:
|
|
195
|
+
raise ValueError(f"Error getting IP info: {data['error']}")
|
|
196
|
+
|
|
197
|
+
return data
|
|
198
|
+
except requests.RequestException as e:
|
|
199
|
+
raise ValueError(f"Error connecting to IP info service: {str(e)}")
|
|
200
|
+
|
|
201
|
+
# MAIN FUNCTION TO RUN IP TOOLS
|
|
202
|
+
def run(test=False, speed=False, monitor=False, interval=1, ports=False, dns=False, location=False, no_ip=False):
|
|
203
|
+
"""MAIN FUNCTION TO RUN IP TOOLS
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
test (bool): Run connectivity tests
|
|
207
|
+
speed (bool): Run speed test
|
|
208
|
+
monitor (bool): Monitor network traffic
|
|
209
|
+
interval (int): Monitoring interval in seconds
|
|
210
|
+
ports (bool): Check common ports status
|
|
211
|
+
dns (bool): Show DNS servers
|
|
212
|
+
location (bool): Show IP location info
|
|
213
|
+
no_ip (bool): Hide IP addresses
|
|
214
|
+
"""
|
|
215
|
+
output = []
|
|
133
216
|
|
|
134
|
-
#
|
|
217
|
+
# GET IP ADDRESSES IF NOT HIDDEN
|
|
135
218
|
if not no_ip:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
219
|
+
local_ips = get_local_ips()
|
|
220
|
+
public_ips = get_public_ips()
|
|
221
|
+
|
|
222
|
+
output.append("\nLocal IPs:")
|
|
223
|
+
if local_ips['ipv4']:
|
|
224
|
+
for ip in local_ips['ipv4']:
|
|
225
|
+
output.append(f"IPv4: {ip}")
|
|
140
226
|
else:
|
|
141
|
-
|
|
227
|
+
output.append("IPv4: Not available")
|
|
142
228
|
|
|
143
|
-
if
|
|
144
|
-
for ip in
|
|
145
|
-
|
|
229
|
+
if local_ips['ipv6']:
|
|
230
|
+
for ip in local_ips['ipv6']:
|
|
231
|
+
output.append(f"IPv6: {ip}")
|
|
146
232
|
else:
|
|
147
|
-
|
|
233
|
+
output.append("IPv6: Not available")
|
|
148
234
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
235
|
+
output.append("\nPublic IPs:")
|
|
236
|
+
output.append(f"IPv4: {public_ips['ipv4'] or 'Not available'}")
|
|
237
|
+
output.append(f"IPv6: {public_ips['ipv6'] or 'Not available'}")
|
|
152
238
|
|
|
153
239
|
# RUN CONNECTIVITY TESTS IF REQUESTED
|
|
154
240
|
if test:
|
|
155
|
-
|
|
241
|
+
output.append("\nConnectivity Tests:")
|
|
156
242
|
results = test_connectivity()
|
|
157
243
|
for name, success, latency in results:
|
|
158
244
|
status = f"✓ {latency}ms" if success else "✗ Failed"
|
|
159
|
-
|
|
245
|
+
output.append(f"{name:<15} {status}")
|
|
160
246
|
|
|
161
247
|
# RUN SPEED TEST IF REQUESTED
|
|
162
248
|
if speed:
|
|
163
|
-
|
|
249
|
+
output.append("\nRunning speed test...")
|
|
250
|
+
if run_speedtest():
|
|
251
|
+
output.append("Speed test completed successfully")
|
|
252
|
+
else:
|
|
253
|
+
output.append("Speed test failed")
|
|
164
254
|
|
|
165
255
|
# DISPLAY LOCATION INFO IF REQUESTED
|
|
166
256
|
if location:
|
|
167
257
|
try:
|
|
168
|
-
loc =
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
except:
|
|
175
|
-
|
|
258
|
+
loc = get_ip_info()
|
|
259
|
+
output.append("\nLocation Info:")
|
|
260
|
+
output.append(f"City: {loc.get('city', 'Unknown')}")
|
|
261
|
+
output.append(f"Region: {loc.get('region', 'Unknown')}")
|
|
262
|
+
output.append(f"Country: {loc.get('country', 'Unknown')}")
|
|
263
|
+
output.append(f"ISP: {loc.get('org', 'Unknown')}")
|
|
264
|
+
except Exception as e:
|
|
265
|
+
output.append(f"\nLocation lookup failed: {str(e)}")
|
|
176
266
|
|
|
177
267
|
# DISPLAY DNS SERVERS IF REQUESTED
|
|
178
268
|
if dns:
|
|
179
|
-
|
|
269
|
+
output.append("\nDNS Servers:")
|
|
180
270
|
try:
|
|
181
271
|
with open('/etc/resolv.conf', 'r') as f:
|
|
182
272
|
for line in f:
|
|
183
273
|
if 'nameserver' in line:
|
|
184
|
-
|
|
274
|
+
output.append(f"DNS: {line.split()[1]}")
|
|
185
275
|
except:
|
|
186
|
-
|
|
276
|
+
output.append("Could not read DNS configuration")
|
|
187
277
|
|
|
188
278
|
# CHECK COMMON PORTS IF REQUESTED
|
|
189
279
|
if ports:
|
|
190
280
|
common_ports = [80, 443, 22, 21, 25, 3306]
|
|
191
|
-
|
|
281
|
+
output.append("\nCommon Ports Status (localhost):")
|
|
192
282
|
for port in common_ports:
|
|
193
283
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
194
284
|
result = sock.connect_ex(('127.0.0.1', port))
|
|
195
285
|
status = "Open" if result == 0 else "Closed"
|
|
196
|
-
|
|
286
|
+
output.append(f"Port {port}: {status}")
|
|
197
287
|
sock.close()
|
|
198
288
|
|
|
199
289
|
# MONITOR NETWORK TRAFFIC IF REQUESTED
|
|
200
290
|
if monitor:
|
|
201
|
-
|
|
291
|
+
output.append("\nNetwork Monitor (Press Ctrl+C to stop):")
|
|
202
292
|
try:
|
|
203
293
|
prev_bytes_sent = psutil.net_io_counters().bytes_sent
|
|
204
294
|
prev_bytes_recv = psutil.net_io_counters().bytes_recv
|
|
205
295
|
while True:
|
|
206
|
-
time.sleep(
|
|
296
|
+
time.sleep(interval)
|
|
207
297
|
bytes_sent = psutil.net_io_counters().bytes_sent
|
|
208
298
|
bytes_recv = psutil.net_io_counters().bytes_recv
|
|
209
299
|
|
|
210
|
-
|
|
211
|
-
|
|
300
|
+
# CALCULATE UPLOAD AND DOWNLOAD SPEEDS
|
|
301
|
+
upload_speed = (bytes_sent - prev_bytes_sent) / (1024 * interval)
|
|
302
|
+
download_speed = (bytes_recv - prev_bytes_recv) / (1024 * interval)
|
|
212
303
|
|
|
213
|
-
|
|
304
|
+
output.append(f"\rUp: {upload_speed:.2f} KB/s | Down: {download_speed:.2f} KB/s")
|
|
214
305
|
|
|
215
306
|
prev_bytes_sent = bytes_sent
|
|
216
307
|
prev_bytes_recv = bytes_recv
|
|
217
308
|
except KeyboardInterrupt:
|
|
218
|
-
|
|
309
|
+
output.append("\nMonitoring stopped")
|
|
310
|
+
|
|
311
|
+
return "\n".join(output)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# INIT FILE FOR TESTS
|