import os import subprocess import re import shutil import time from ..utils.print_markdown import print_markdown def create_tunnel(tunnel_method='ngrok', server_host='localhost', server_port=10001): print_markdown(f"Exposing server to the internet...") if tunnel_method == "bore": try: output = subprocess.check_output('command -v bore', shell=True) except subprocess.CalledProcessError: print("The bore-cli command is not available. Please run 'cargo install bore-cli'.") print("For more information, see https://github.com/ekzhang/bore") exit(1) time.sleep(6) # output = subprocess.check_output(f'bore local {server_port} --to bore.pub', shell=True) process = subprocess.Popen(f'bore local {server_port} --to bore.pub', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) while True: line = process.stdout.readline() print(line) if not line: break if "listening at bore.pub:" in line: remote_port = re.search('bore.pub:([0-9]*)', line).group(1) print_markdown(f"Your server is being hosted at the following URL: bore.pub:{remote_port}") break elif tunnel_method == "localtunnel": if subprocess.call('command -v lt', shell=True): print("The 'lt' command is not available.") print("Please ensure you have Node.js installed, then run 'npm install -g localtunnel'.") print("For more information, see https://github.com/localtunnel/localtunnel") exit(1) else: process = subprocess.Popen(f'npx localtunnel --port {server_port}', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) found_url = False url_pattern = re.compile(r'your url is: https://[a-zA-Z0-9.-]+') while True: line = process.stdout.readline() if not line: break # Break out of the loop if no more output match = url_pattern.search(line) if match: found_url = True remote_url = match.group(0).replace('your url is: ', '') print(f"\nYour server is being hosted at the following URL: {remote_url}") break # Exit the loop once the URL is found if not found_url: print("Failed to extract the localtunnel URL. Please check localtunnel's output for details.") elif tunnel_method == "ngrok": # Check if ngrok is installed is_installed = subprocess.check_output('command -v ngrok', shell=True).decode().strip() if not is_installed: print("The ngrok command is not available.") print("Please install ngrok using the instructions at https://ngrok.com/docs/getting-started/") exit(1) # If ngrok is installed, start it on the specified port # process = subprocess.Popen(f'ngrok http {server_port} --log=stdout', shell=True, stdout=subprocess.PIPE) process = subprocess.Popen(f'ngrok http {server_port} --scheme http,https --log=stdout', shell=True, stdout=subprocess.PIPE) # Initially, no URL is found found_url = False # Regular expression to match the ngrok URL url_pattern = re.compile(r'https://[a-zA-Z0-9-]+\.ngrok(-free)?\.app') # Read the output line by line while True: line = process.stdout.readline().decode('utf-8') if not line: break # Break out of the loop if no more output match = url_pattern.search(line) if match: found_url = True remote_url = match.group(0) print(f"\nYour server is being hosted at the following URL: {remote_url}") break # Exit the loop once the URL is found if not found_url: print("Failed to extract the ngrok tunnel URL. Please check ngrok's output for details.")