NitroExpose 2.1__py3-none-any.whl → 2.2__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.

Potentially problematic release.


This version of NitroExpose might be problematic. Click here for more details.

nitroexpose/cli.py CHANGED
@@ -10,8 +10,11 @@ import requests
10
10
  import signal
11
11
  import socket
12
12
  import importlib.metadata
13
+ import random
14
+ import string
15
+ import threading
13
16
 
14
- # cli.py
17
+ # cli.py (Main File)
15
18
  # 𝗠𝗮𝗻𝗮𝗴𝗲𝗱 𝗕𝘆 @Nactire
16
19
 
17
20
  def print_green(text):
@@ -73,6 +76,18 @@ def is_port_listening(port):
73
76
  except Exception:
74
77
  return False
75
78
 
79
+ def get_system_architecture():
80
+ try:
81
+ result = subprocess.check_output("uname -m", shell=True, text=True).strip()
82
+ return result
83
+ except Exception:
84
+ return None
85
+
86
+ def generate_random_process_name():
87
+ letters = ''.join(random.choices(string.ascii_lowercase, k=5))
88
+ numbers = ''.join(random.choices(string.digits, k=5))
89
+ return letters + numbers
90
+
76
91
  def restricted_input(prompt, allowed_pattern):
77
92
  def handle_sigint(signum, frame):
78
93
  print("\n\n")
@@ -220,12 +235,158 @@ def remove_domain(domain):
220
235
  print_green(f"\n{domain_type} Removed Successfully.\n")
221
236
  sys.exit(0)
222
237
 
238
+ def freehost_mode():
239
+ if os.geteuid() != 0:
240
+ print_red("\nPlease Use Root Environment.\n")
241
+ sys.exit(1)
242
+
243
+ if not is_installed("expect -v"):
244
+ print_green("Installing Expect ...")
245
+ run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
246
+ run_command("sudo apt install -y expect")
247
+
248
+ if not is_installed("expect -v"):
249
+ print_red("Expect installing Error.")
250
+ sys.exit(1)
251
+ print_green("Expect installed.")
252
+
253
+ if not is_installed("cloudflared --version"):
254
+ print_green("Installing CloudServer ...")
255
+
256
+ arch = get_system_architecture()
257
+
258
+ if arch in ["x86_64", "aarch64"]:
259
+ install_cmds = [
260
+ "wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64",
261
+ "chmod +x cloudflared-linux-amd64",
262
+ "sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared"
263
+ ]
264
+ elif arch in ["armv7l", "armhf"]:
265
+ install_cmds = [
266
+ "wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm",
267
+ "chmod +x cloudflared-linux-arm",
268
+ "sudo mv cloudflared-linux-arm /usr/local/bin/cloudflared"
269
+ ]
270
+ else:
271
+ print_red("Unsupported architecture.")
272
+ sys.exit(1)
273
+
274
+ for cmd in install_cmds:
275
+ run_command(cmd)
276
+
277
+ if is_installed("cloudflared --version"):
278
+ print_green("CloudServer installed.")
279
+ else:
280
+ print_red("CloudServer installing Error.")
281
+ sys.exit(1)
282
+ else:
283
+ print_green("CloudServer installed.")
284
+
285
+ print("\n")
286
+
287
+ print_turquoise("┌─╼ Enter Port To Expose")
288
+ port = restricted_input("\033[38;2;0;255;234m└────╼ ❯❯❯ \033[0m", r"[0-9]+")
289
+
290
+ print("\n")
291
+
292
+ if not is_port_listening(port):
293
+ print_red("Port Not Listening, Operation Failed.")
294
+ sys.exit(1)
295
+
296
+ process_name = generate_random_process_name()
297
+
298
+ expect_script = f"""#!/usr/bin/expect -f
299
+ set timeout 20
300
+ spawn supercore cloudflared tunnel --url http://localhost:{port}
301
+ expect "└────╼ ❯❯❯"
302
+ send "{process_name}\\r"
303
+ expect eof
304
+ """
305
+
306
+ script_path = f"/tmp/cloudflared_tunnel_{port}.exp"
307
+ with open(script_path, "w") as f:
308
+ f.write(expect_script)
309
+
310
+ os.chmod(script_path, 0o755)
311
+
312
+ try:
313
+ process = subprocess.Popen(
314
+ [script_path],
315
+ stdout=subprocess.PIPE,
316
+ stderr=subprocess.STDOUT,
317
+ text=True,
318
+ bufsize=1
319
+ )
320
+
321
+ output_lines = []
322
+ url_found = False
323
+ extracted_url = None
324
+
325
+ print_yellow("Connecting to CloudServer...")
326
+
327
+ start_time = time.time()
328
+ while time.time() - start_time < 15:
329
+ line = process.stdout.readline()
330
+ if line:
331
+ output_lines.append(line)
332
+ url_pattern = r'https://[a-z0-9\-]+\.trycloudflare\.com'
333
+ match = re.search(url_pattern, line)
334
+ if match:
335
+ extracted_url = match.group(0)
336
+ url_found = True
337
+ break
338
+
339
+ if process.poll() is not None:
340
+ break
341
+
342
+ time.sleep(0.1)
343
+
344
+ if not url_found:
345
+ remaining = process.stdout.read()
346
+ if remaining:
347
+ output_lines.append(remaining)
348
+ full_output = ''.join(output_lines)
349
+ url_pattern = r'https://[a-z0-9\-]+\.trycloudflare\.com'
350
+ match = re.search(url_pattern, full_output)
351
+ if match:
352
+ extracted_url = match.group(0)
353
+ url_found = True
354
+
355
+ process.wait()
356
+
357
+ if url_found and extracted_url:
358
+ print("\n")
359
+ print_green(f"Exposed Successfully On Free Subdomain.\n")
360
+ print_green(f"Exposed On: {extracted_url}\n")
361
+ print_green(f"Port: {port}\n")
362
+ print_green(f"SSL Installed Using Google Trust Services\n")
363
+ print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -")
364
+ print_yellow(f"If You Like NitroExpose, Please Support Us by:\n")
365
+ print_yellow(f" * Join Our Telegram Channel: https://t.me/NacDevs")
366
+ print_yellow(f" * Please Star Our Project: https://github.com/yuvrajmodz/NitroExpose")
367
+ print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n")
368
+ sys.exit(0)
369
+ else:
370
+ print_red("Server is Busy, Try Again Later.")
371
+ os.remove(script_path)
372
+ sys.exit(1)
373
+
374
+ except Exception as e:
375
+ print_red("Server is Busy, Try Again Later.")
376
+ if os.path.exists(script_path):
377
+ os.remove(script_path)
378
+ sys.exit(1)
379
+
223
380
  def main():
224
381
  if len(sys.argv) == 2 and sys.argv[1] in ["-v", "--v"]:
225
382
  version = get_version()
226
383
  print_green(f"V{version}")
227
384
  sys.exit(0)
228
385
 
386
+ if len(sys.argv) == 2 and sys.argv[1] == "--freehost":
387
+ freehost_mode()
388
+ return
389
+
229
390
  if len(sys.argv) == 3 and sys.argv[1] == "remove":
230
391
  domain = sys.argv[2]
231
392
  remove_domain(domain)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NitroExpose
3
- Version: 2.1
3
+ Version: 2.2
4
4
  Summary: Advanced CLI To Expose Port To Your Domain.
5
5
  Home-page: https://github.com/yuvrajmodz/NitroExpose
6
6
  Author: @NacDevs
@@ -12,6 +12,7 @@ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: requests
15
+ Requires-Dist: supercore
15
16
  Dynamic: author
16
17
  Dynamic: author-email
17
18
  Dynamic: classifier
@@ -25,7 +26,7 @@ Dynamic: summary
25
26
 
26
27
  ## NitroExpose
27
28
 
28
- **Letest Version:** 2.1
29
+ **Letest Version:** 2.2
29
30
  **Developer:** @Nactire
30
31
  **Git Repo:** [NitroExpose](https://github.com/yuvrajmodz/NitroExpose)
31
32
 
@@ -35,6 +36,8 @@ Dynamic: summary
35
36
  **NitroExpose** is an advanced CLI tool that allows you to **instantly expose any local port to your custom domain,**
36
37
  **automatic SSL installation** Powered by Let's Encrypt.
37
38
 
39
+ If You Don't Have Domain, No Problem We Also Provide Free Subdomain To Host Your Local Port Service On Subdomain With Https.
40
+
38
41
  It provides a **one-command deployment system** for developers who want to run their local apps (Flask, FastAPI, Node.js, etc.) directly on a live domain without manually configuring NGINX or DNS records.
39
42
 
40
43
 
@@ -82,7 +85,7 @@ Step 3 – **Enter Your Domain Or Subdomain**
82
85
  └────╼ ❯❯❯ myproject.example.com
83
86
  ```
84
87
 
85
- Step 4 – **Enter the Local Port to Expose**
88
+ Step 4 – **Enter Your Local Port to Expose**
86
89
  ```bash
87
90
  ┌─╼ Enter Port To Expose
88
91
  └────╼ ❯❯❯ 8000
@@ -90,6 +93,22 @@ Step 4 – **Enter the Local Port to Expose**
90
93
 
91
94
  ✨ **Now it Will Take 8 to 9 Seconds For Verification And Then Boom! Your Local Port Successfully Exposed To Your Public Domain/Subdomain**.
92
95
 
96
+ ## 🌐 Host On Free Subdomain (Cloudflared).
97
+
98
+ Step 1 – **Launch NitroExpose With FreeHost**
99
+ ```bash
100
+ NitroExpose --freehost
101
+ ```
102
+
103
+ Step 2 – **Enter Your Local Port To Expose On Subdomain**
104
+ ```bash
105
+ ┌─╼ Enter Port To Expose
106
+ └────╼ ❯❯❯ 8001
107
+ ```
108
+
109
+ ✨ **Now it Will Take 8 to 9 Seconds To Connect CloudServer And Then Your Service Successfully Exposed To Our Subdomain With 24/7.**
110
+
111
+
93
112
  ## 🎯 To Remove Domain/Subdomain
94
113
 
95
114
  ```bash
@@ -0,0 +1,8 @@
1
+ nitroexpose/__init__.py,sha256=jzli5z-wSkAiPccBUXLYoXWqtFxcoSs4cfupy9yjmFM,161
2
+ nitroexpose/cli.py,sha256=C3lkvEryTstXDww37MSM-p3QBIfx254gecQrb5tuwxU,18026
3
+ nitroexpose-2.2.dist-info/licenses/LICENSE,sha256=i_D1gc46cD__O4L8jy8izzueLV1F5ut89qyA6EOynaQ,255
4
+ nitroexpose-2.2.dist-info/METADATA,sha256=yjIc-n2WUapbjBz8GnPaFxMOwWN5pHmn-62Pno0G-To,3255
5
+ nitroexpose-2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
+ nitroexpose-2.2.dist-info/entry_points.txt,sha256=xmBtMDqH7wn0ZT8MtQYWLsEIZNvVqAi-F9nUrxVoq8w,53
7
+ nitroexpose-2.2.dist-info/top_level.txt,sha256=plDtsFeO3ei4PeJvvK2DjGFjFxZ4lnKSHHH4xeC8ei8,12
8
+ nitroexpose-2.2.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- nitroexpose/__init__.py,sha256=jzli5z-wSkAiPccBUXLYoXWqtFxcoSs4cfupy9yjmFM,161
2
- nitroexpose/cli.py,sha256=x87jSmHHxk6YBNEsNB3XY8kFTZko1JOf53G75N_bBN0,12449
3
- nitroexpose-2.1.dist-info/licenses/LICENSE,sha256=i_D1gc46cD__O4L8jy8izzueLV1F5ut89qyA6EOynaQ,255
4
- nitroexpose-2.1.dist-info/METADATA,sha256=eaT6pGardvEks4MZnRbFBP0vp5sMWqwbXBR4MKM14bQ,2692
5
- nitroexpose-2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
- nitroexpose-2.1.dist-info/entry_points.txt,sha256=xmBtMDqH7wn0ZT8MtQYWLsEIZNvVqAi-F9nUrxVoq8w,53
7
- nitroexpose-2.1.dist-info/top_level.txt,sha256=plDtsFeO3ei4PeJvvK2DjGFjFxZ4lnKSHHH4xeC8ei8,12
8
- nitroexpose-2.1.dist-info/RECORD,,