import re
from flask import Blueprint, render_template, request, redirect, url_for, abort
from flask_login import current_user
from jinja2 import Markup
from names.pygments import ZoneLexer
from names.types import User
from pygments import highlight
from pygments.formatters import HtmlFormatter
from srht.flask import loginrequired
from srht.oauth import UserType
from srht.validation import Validation
# TODO: Make OpenSRS integration optional
from names.opensrs import DomainStatus, lookup_domain, get_price, check_transfer
from names.opensrs import name_suggest
web = Blueprint("names.web", __name__)
# https://stackoverflow.com/a/26987741
name_re = re.compile(r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$')
@web.route("/")
def index():
if current_user:
return render_template("dashboard.html")
else:
return render_template("index.html")
@web.route("/create")
@loginrequired
def create_GET():
# TODO: Redirect to user contact info
return render_template("create.html")
@web.route("/create", methods=["POST"])
@loginrequired
def create_POST():
valid = Validation(request)
domain = valid.require("domain_name", friendly_name="Domain name")
valid.expect(not domain or name_re.match(domain),
"This must be a valid RFC-1034 (+errata) domain name. " +
"For IDNs, use punycode.", field="domain_name")
if not valid.ok:
return render_template("create.html", **valid.kwargs), 400
return redirect(url_for(".create_domain_GET", domain=domain))
@web.route("/create/<domain>")
@loginrequired
def create_domain_GET(domain):
status = lookup_domain(domain)
# TODO: Check if user has payment info on file
if status == DomainStatus.available:
market_price = get_price(domain)
# Factor in our Stripe fees, so we don't lose money
our_price = int(market_price + (market_price * 0.029) + 30)
return render_template("create-domain.html",
DomainStatus=DomainStatus, status=status, domain=domain,
our_price=our_price, market_price=market_price)
else:
transferable, transfer_email = check_transfer(domain)
# Note: this could be merged into lookup_domain and save us an API call
suggestions = name_suggest(domain)
return render_template("create-domain.html",
DomainStatus=DomainStatus, status=status, domain=domain,
transferable=transferable,
transfer_email=transfer_email,
suggestions=suggestions)
@web.route("/create/<domain>", methods=["POST"])
@loginrequired
def create_domain_POST(domain):
valid = Validation(request)
permitted_users = [
UserType.active_paying,
UserType.active_free,
UserType.admin,
]
if "purchase" in valid:
if current_user.user_type not in permitted_users:
return render_template("need-paid-account.html")
# TODO: Check for contacts
return render_template("purchase-domain.html")
elif "transfer" in valid:
if current_user.user_type not in permitted_users:
return render_template("need-paid-account.html")
# TODO: Check for contacts
return render_template("transfer-domain.html")
elif "configure" in valid:
# TODO: Configure domain
pass
else:
abort(400)
@web.route("/mockup")
def mockup():
with open("/home/sircmpwn/sr.ht.zone") as f:
zone = f.read()
formatter = HtmlFormatter()
lexer = ZoneLexer()
style = formatter.get_style_defs('.highlight')
html = f"<style>{style}</style>" + highlight(zone, lexer, formatter)
return render_template("mockup.html", view="zone", zone=Markup(html))