2023-11-08 20:56:03 +11:00
|
|
|
from flask import Flask, make_response, redirect, render_template_string, request, jsonify, render_template, send_from_directory
|
2023-11-08 22:51:39 +11:00
|
|
|
from bs4 import BeautifulSoup
|
2023-11-09 12:51:35 +11:00
|
|
|
import os
|
|
|
|
import dotenv
|
|
|
|
|
|
|
|
main_domain = "cities.hnshosting.au"
|
|
|
|
if os.getenv('MAIN_DOMAIN') != None:
|
|
|
|
main_domain = os.getenv('MAIN_DOMAIN')
|
2023-11-08 20:56:03 +11:00
|
|
|
|
2023-11-15 18:03:43 +11:00
|
|
|
def render(data,db_object):
|
2023-11-17 13:06:38 +11:00
|
|
|
if data == False:
|
2023-11-09 12:51:35 +11:00
|
|
|
return redirect("https://" + main_domain + '/claim?domain=' + request.host.split('.')[0])
|
2023-11-08 22:32:00 +11:00
|
|
|
|
2023-11-15 18:03:43 +11:00
|
|
|
# Render as HTML
|
|
|
|
html = ""
|
2023-11-16 13:05:46 +11:00
|
|
|
ssl = "<script src='https://nathan.woodburn/https.js'></script>"
|
|
|
|
if ("localhost" in request.host or "127.0.0.1" in request.host):
|
|
|
|
ssl = ""
|
|
|
|
|
2023-11-08 22:51:39 +11:00
|
|
|
try:
|
|
|
|
soup = BeautifulSoup(data, 'html.parser')
|
|
|
|
for script in soup.find_all('script'):
|
|
|
|
script.extract()
|
2023-11-08 23:25:01 +11:00
|
|
|
|
2023-11-16 13:05:46 +11:00
|
|
|
# Inject SSL
|
|
|
|
soup.append(BeautifulSoup(ssl, 'html.parser'))
|
|
|
|
|
2023-11-15 18:03:43 +11:00
|
|
|
html = str(soup)
|
|
|
|
except Exception as e:
|
|
|
|
return "<h1>Invalid HTML</h1><br>" + str(e)
|
|
|
|
|
|
|
|
try:
|
|
|
|
avatar = db_object['avatar']
|
|
|
|
hnschat = db_object['hnschat']
|
|
|
|
location = db_object['location']
|
2023-11-16 12:52:12 +11:00
|
|
|
email = db_object['email']
|
2023-11-15 18:03:43 +11:00
|
|
|
hns = db_object['HNS']
|
|
|
|
btc = db_object['BTC']
|
|
|
|
eth = db_object['ETH']
|
2023-11-15 18:28:40 +11:00
|
|
|
bg_colour = db_object['bg_colour']
|
|
|
|
fg_colour = db_object['fg_colour']
|
|
|
|
text_colour = db_object['text_colour']
|
2023-11-15 22:08:49 +11:00
|
|
|
if (rgb_to_hex(generate_foreground_color(text_colour)) == "#000000"):
|
2023-11-15 18:24:11 +11:00
|
|
|
hns_icon = "assets/img/HNSW.png"
|
2023-11-15 22:08:49 +11:00
|
|
|
btc_icon = "assets/img/BTCW.png"
|
|
|
|
eth_icon = "assets/img/ETHW.png"
|
|
|
|
location_icon = "assets/img/mapw.png"
|
2023-11-16 12:52:12 +11:00
|
|
|
email_icon = "assets/img/emailw.png"
|
2023-11-15 18:24:11 +11:00
|
|
|
else:
|
|
|
|
hns_icon = "assets/img/HNS.png"
|
2023-11-15 22:08:49 +11:00
|
|
|
btc_icon = "assets/img/BTC.png"
|
|
|
|
eth_icon = "assets/img/ETH.png"
|
|
|
|
location_icon = "assets/img/map.png"
|
2023-11-16 12:52:12 +11:00
|
|
|
email_icon = "assets/img/email.png"
|
2023-11-15 22:08:49 +11:00
|
|
|
|
|
|
|
if hns != "":
|
|
|
|
hns = "<img src='" + hns_icon + "' width='20px' height='20px' style='margin-right: 5px;'>" + hns
|
|
|
|
if btc != "":
|
|
|
|
btc = "<img src='" + btc_icon + "' width='20px' height='25px' style='margin-right: 5px;'>" + btc
|
|
|
|
if eth != "":
|
|
|
|
eth = "<img src='" + eth_icon + "' width='20px' height='30px' style='margin-right: 5px;'>" + eth
|
2023-11-18 14:44:06 +11:00
|
|
|
|
|
|
|
hide_addresses = False
|
|
|
|
if hns == "" and btc == "" and eth == "":
|
|
|
|
hide_addresses = True
|
|
|
|
|
2023-11-15 22:08:49 +11:00
|
|
|
if hnschat != "":
|
2023-11-16 12:52:12 +11:00
|
|
|
hnschat = "<a href='https://hns.chat/#message:"+hnschat+"' target='_blank'><img src='"+hns_icon+"' width='20px' height='20px' style='margin-right: 5px;'>" + hnschat + "</a>"
|
2023-11-15 22:08:49 +11:00
|
|
|
if location != "":
|
|
|
|
location = "<img src='"+location_icon+"' width='20px' height='30px' style='margin-right: 5px;'>" + location
|
2023-11-16 12:52:12 +11:00
|
|
|
if email != "":
|
|
|
|
email = "<a href='mailto:"+email+"'><img src='"+email_icon+"' width='30px' height='20px' style='margin-right: 5px;margin-left:-10px;'>" + email + "</a>"
|
|
|
|
|
2023-11-18 13:21:38 +11:00
|
|
|
if avatar != "":
|
|
|
|
avatar = "<img src='"+avatar+"' width='200vw' height='200vw' style='border-radius: 50%;margin-right: 5px;'>"
|
|
|
|
else:
|
2023-11-18 13:30:03 +11:00
|
|
|
avatar = "<h1 style='color:"+fg_colour+";'>" + request.host.split(':')[0] + "/</h1>"
|
2023-11-15 22:08:49 +11:00
|
|
|
|
2023-11-18 14:44:06 +11:00
|
|
|
template = "Standard"
|
|
|
|
|
2023-11-18 13:21:38 +11:00
|
|
|
if 'template' in db_object:
|
|
|
|
if db_object['template'] != "":
|
2023-11-18 14:44:06 +11:00
|
|
|
template = db_object['template']
|
2023-11-08 22:51:39 +11:00
|
|
|
|
2023-11-18 14:44:06 +11:00
|
|
|
if hide_addresses:
|
|
|
|
return render_template_string(get_template_without_address(template),bg_colour=bg_colour,text_colour=text_colour,
|
|
|
|
fg_colour=fg_colour, avatar=avatar,main_domain=main_domain,
|
|
|
|
hnschat=hnschat,email=email,location=location, hns_icon=hns_icon,
|
|
|
|
hns=hns,btc=btc,eth=eth, data=html)
|
|
|
|
else:
|
|
|
|
return render_template(get_template_file(template),bg_colour=bg_colour,text_colour=text_colour,
|
|
|
|
fg_colour=fg_colour, avatar=avatar,main_domain=main_domain,
|
|
|
|
hnschat=hnschat,email=email,location=location, hns_icon=hns_icon,
|
|
|
|
hns=hns,btc=btc,eth=eth, data=html)
|
2023-11-15 18:03:43 +11:00
|
|
|
|
2023-11-18 14:44:06 +11:00
|
|
|
except Exception as e:
|
|
|
|
return "<h1>Nothing here yet</h1>" + "<script>console.log('" + str(e).replace('\'','') + "');</script>"
|
2023-11-16 13:05:46 +11:00
|
|
|
|
2023-11-15 18:03:43 +11:00
|
|
|
|
|
|
|
|
2023-11-18 14:44:06 +11:00
|
|
|
def get_template_without_address(template):
|
|
|
|
file = "templates/" +get_template_file(template)
|
|
|
|
with open(file) as f:
|
|
|
|
data = f.read()
|
|
|
|
|
|
|
|
# Read template
|
|
|
|
soup = BeautifulSoup(data, 'html.parser')
|
|
|
|
# Remove addresses div
|
|
|
|
try:
|
|
|
|
addresses = soup.find(id="addresses")
|
|
|
|
addresses.decompose()
|
|
|
|
finally:
|
|
|
|
# Return template without addresses
|
|
|
|
return str(soup)
|
|
|
|
|
|
|
|
|
2023-11-15 18:03:43 +11:00
|
|
|
def calculate_contrast_ratio(color1, color2):
|
|
|
|
def calculate_luminance(color):
|
|
|
|
def adjust_color_value(value):
|
|
|
|
value /= 255.0
|
|
|
|
if value <= 0.03928:
|
|
|
|
return value / 12.92
|
|
|
|
return ((value + 0.055) / 1.055) ** 2.4
|
|
|
|
|
|
|
|
r, g, b = color
|
|
|
|
r = adjust_color_value(r)
|
|
|
|
g = adjust_color_value(g)
|
|
|
|
b = adjust_color_value(b)
|
|
|
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b
|
|
|
|
|
|
|
|
luminance1 = calculate_luminance(color1)
|
|
|
|
luminance2 = calculate_luminance(color2)
|
|
|
|
|
|
|
|
brighter = max(luminance1, luminance2)
|
|
|
|
darker = min(luminance1, luminance2)
|
|
|
|
|
|
|
|
contrast_ratio = (brighter + 0.05) / (darker + 0.05)
|
|
|
|
return contrast_ratio
|
|
|
|
|
|
|
|
def generate_foreground_color(background_color):
|
2023-11-15 18:24:11 +11:00
|
|
|
# Convert to RGB tuple
|
|
|
|
background_color=background_color.lstrip('#')
|
|
|
|
background_color = tuple(int(background_color[i:i+2], 16) for i in (0, 2, 4))
|
2023-11-15 18:03:43 +11:00
|
|
|
|
2023-11-15 18:24:11 +11:00
|
|
|
contrast_color = (255, 255, 255) # White
|
2023-11-15 18:03:43 +11:00
|
|
|
ratio = calculate_contrast_ratio(background_color, contrast_color)
|
|
|
|
|
|
|
|
if ratio < 4.5:
|
|
|
|
return (0, 0, 0) # Black
|
|
|
|
else:
|
|
|
|
return contrast_color
|
|
|
|
|
|
|
|
def rgb_to_hex(rgb_color):
|
|
|
|
return "#{:02x}{:02x}{:02x}".format(*rgb_color)
|
2023-11-18 13:21:38 +11:00
|
|
|
|
2023-11-18 14:44:06 +11:00
|
|
|
def get_template_file(template):
|
2023-11-18 13:21:38 +11:00
|
|
|
if template == "Original":
|
|
|
|
return "city-old.html"
|
|
|
|
|
|
|
|
return "city.html"
|