Fix: Handle missing IPv4/IPv6 URIs and improve UI/UX

This commit is contained in:
Whispering Wind
2025-02-22 13:22:01 +03:30
committed by GitHub
parent 87b2d125fb
commit 54aa154465
2 changed files with 45 additions and 29 deletions

View File

@ -134,8 +134,10 @@ async def get_template_context(username, user_agent):
ipv4_uri, ipv6_uri = get_uris(username)
sub_link = f"https://{DOMAIN}:{PORT}/sub/normal/{username}"
ipv4_qrcode = generate_qrcode_base64(ipv4_uri)
ipv6_qrcode = generate_qrcode_base64(ipv6_uri)
# Generate QR codes only if URIs are available
ipv4_qrcode = generate_qrcode_base64(ipv4_uri) if ipv4_uri else None
ipv6_qrcode = generate_qrcode_base64(ipv6_uri) if ipv6_uri else None
sublink_qrcode = generate_qrcode_base64(sub_link)
@ -185,7 +187,7 @@ def get_user_info(username):
def get_user_uri(username, user_agent):
"""
The original function, but it's only used when the request doesn't accept HTML.
Returns the URI for the user, adapting the output based on the User-Agent.
"""
try:
user_info = get_user_info(username)
@ -204,27 +206,21 @@ def get_user_uri(username, user_agent):
expiration_timestamp = 0
# Get URI
command = [
'python3',
'/etc/hysteria/core/cli.py',
'show-user-uri',
'-u', username,
'-a'
]
safe_command = [shlex.quote(arg) for arg in command]
output = subprocess.check_output(safe_command).decode().strip()
output = re.sub(r'IPv4:\s*', '', output)
output = re.sub(r'IPv6:\s*', '', output)
ipv4_uri, ipv6_uri = get_uris(username)
# Choose the appropriate URI based on availability. Prioritize IPv6 if available.
output_uri = ipv6_uri if ipv6_uri else (ipv4_uri if ipv4_uri else "No URI available")
if "v2ray" in user_agent and "ng" in user_agent:
match = re.search(r'pinSHA256=sha256/([^&]+)', output)
match = re.search(r'pinSHA256=sha256/([^&]+)', output_uri)
if match:
base64_pin = match.group(1)
try:
decoded_pin = base64.b64decode(base64_pin)
hex_pin = ':'.join(['{:02X}'.format(byte) for byte in decoded_pin])
output = output.replace(f'pinSHA256=sha256/{base64_pin}', f'pinSHA256={hex_pin}')
output_uri = output_uri.replace(f'pinSHA256=sha256/{base64_pin}', f'pinSHA256={hex_pin}')
except Exception as e:
print(f"Error processing pinSHA256: {e}")
@ -233,7 +229,7 @@ def get_user_uri(username, user_agent):
)
profile_lines = f"//profile-title: {username}-Hysteria2 🚀\n//profile-update-interval: 1\n"
output = profile_lines + subscription_info + output
output = profile_lines + subscription_info + output_uri
return output
except subprocess.CalledProcessError:
@ -245,7 +241,7 @@ def get_user_uri(username, user_agent):
def get_uris(username):
"""
Gets the IPv4 and IPv6 URIs for a user.
Gets the IPv4 and IPv6 URIs for a user, handling cases where one or both might be missing.
"""
try:
command = [
@ -257,10 +253,16 @@ def get_uris(username):
]
safe_command = [shlex.quote(arg) for arg in command]
output = subprocess.check_output(safe_command).decode().strip()
ipv4_uri = re.search(r'IPv4:\s*(.*)', output).group(1).strip()
ipv6_uri = re.search(r'IPv6:\s*(.*)', output).group(1).strip()
# Use regex to find IPv4 and IPv6 URIs, handling cases where they might not exist.
ipv4_match = re.search(r'IPv4:\s*(.*)', output)
ipv6_match = re.search(r'IPv6:\s*(.*)', output)
ipv4_uri = ipv4_match.group(1).strip() if ipv4_match else None
ipv6_uri = ipv6_match.group(1).strip() if ipv6_match else None
return ipv4_uri, ipv6_uri
except subprocess.CalledProcessError as e:
print(f"Error executing show-user-uri command: {e}")
raise
@ -284,4 +286,4 @@ if __name__ == '__main__':
ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
ssl_context.set_ciphers('AES256+EECDH:AES256+EDH')
web.run_app(app, port=PORT, ssl_context=ssl_context)
web.run_app(app, port=PORT, ssl_context=ssl_context)

View File

@ -145,6 +145,12 @@
.card-text.dark-mode{
color: #f8f9fa;
}
.uri-unavailable {
color: #777;
text-align: center;
margin: 10px auto;
}
</style>
</head>
<body>
@ -174,7 +180,7 @@
<div class="col-md-4">
<div class="card">
<div class="card-header">
<i class="fas fa-chart-bar"></i> Upload + Download / Total
<i class="fas fa-chart-bar"></i> Used / Total
</div>
<div class="card-body">
<p class="card-text" data-toggle="tooltip" data-placement="top" title="Total Data Usage: {{ usage_raw }}">
@ -211,15 +217,23 @@
</div>
<div class="col-md-4">
<h5>IPv4 URI</h5>
<img src="{{ ipv4_qrcode }}" alt="IPv4 QR Code" class="qrcode">
<button class="btn btn-primary" onclick="copyToClipboard('{{ ipv4_uri }}')"><i class="fas fa-copy"></i> Copy</button>
<a href="{{ ipv4_uri }}" class="btn btn-info" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt"></i> Open Link</a>
{% if ipv4_qrcode %}
<img src="{{ ipv4_qrcode }}" alt="IPv4 QR Code" class="qrcode">
<button class="btn btn-primary" onclick="copyToClipboard('{{ ipv4_uri }}')"><i class="fas fa-copy"></i> Copy</button>
<a href="{{ ipv4_uri }}" class="btn btn-info" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt"></i> Open Link</a>
{% else %}
<p class="uri-unavailable">IPv4 URI not available</p>
{% endif %}
</div>
<div class="col-md-4">
<h5>IPv6 URI</h5>
<img src="{{ ipv6_qrcode }}" alt="IPv6 QR Code" class="qrcode">
<button class="btn btn-primary" onclick="copyToClipboard('{{ ipv6_uri }}')"><i class="fas fa-copy"></i> Copy</button>
<a href="{{ ipv6_uri }}" class="btn btn-info" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt"></i> Open Link</a>
{% if ipv6_qrcode %}
<img src="{{ ipv6_qrcode }}" alt="IPv6 QR Code" class="qrcode">
<button class="btn btn-primary" onclick="copyToClipboard('{{ ipv6_uri }}')"><i class="fas fa-copy"></i> Copy</button>
<a href="{{ ipv6_uri }}" class="btn btn-info" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt"></i> Open Link</a>
{% else %}
<p class="uri-unavailable">IPv6 URI not available</p>
{% endif %}
</div>
</div>
</div>
@ -306,4 +320,4 @@
showLoadingIndicator();
</script>
</body>
</html>
</html>