from flask import Flask, make_response, redirect, request, jsonify, render_template, send_from_directory import os import dotenv import requests import datetime import json import render import payments import threading import account app = Flask(__name__) dotenv.load_dotenv() # Exchange cache exchange = { 'timestamp': 0, 'rate': 0 } #Assets routes @app.route('/assets/') def send_report(path): return send_from_directory('templates/assets', path) @app.route('/sitemap') @app.route('/sitemap.xml') def sitemap(): # Remove all .html from sitemap with open('templates/sitemap.xml') as file: sitemap = file.read() sitemap = sitemap.replace('.html', '') return make_response(sitemap, 200, {'Content-Type': 'application/xml'}) @app.route('/favicon.png') def faviconPNG(): return send_from_directory('templates/assets/img', 'favicon.png') @app.route('/https.js') @app.route('/handshake.js') @app.route('/redirect.js') def handshake(): # return request.path return send_from_directory('templates/', request.path.split('/')[-1]) @app.route('/.well-known/wallets/') def wallet(path): return send_from_directory('templates/.well-known/wallets', path, mimetype='text/plain') # Special routes @app.route('/email') def email(): return redirect('mailto:hns@hns.au') @app.route('/pins') def pins(): global exchange year = datetime.datetime.now().year # Get current exchange rate if not in cache if exchange['timestamp'] < datetime.datetime.now().timestamp() - 3600: response = requests.get('https://api.coingecko.com/api/v3/simple/price?ids=handshake&vs_currencies=usd') exchange['rate'] = response.json()['handshake']['usd'] exchange['timestamp'] = datetime.datetime.now().timestamp() hns_45 = 45 / exchange['rate'] hns_30 = 30 / exchange['rate'] # Round to the nearest 5 HNS and add commas hns_45 = int(hns_45 / 5) * 5 hns_30 = int(hns_30 / 5) * 5 hns_45 = "{:,}".format(hns_45) hns_30 = "{:,}".format(hns_30) return render_template('pins.html', year=year, hns_45=hns_45, hns_30=hns_30) @app.route('/pins/') def pins_redirect(path): global exchange if not os.path.isfile('templates/pins/'+path + ".html"): return render_template('404.html'), 404 year = datetime.datetime.now().year # Get current exchange rate if not in cache if exchange['timestamp'] < datetime.datetime.now().timestamp() - 3600: response = requests.get('https://api.coingecko.com/api/v3/simple/price?ids=handshake&vs_currencies=usd') exchange['rate'] = response.json()['handshake']['usd'] exchange['timestamp'] = datetime.datetime.now().timestamp() hns_45 = 45 / exchange['rate'] hns_30 = 30 / exchange['rate'] # Round to the nearest 5 HNS and add commas hns_45 = int(hns_45 / 5) * 5 hns_30 = int(hns_30 / 5) * 5 hns_45 = "{:,}".format(hns_45) hns_30 = "{:,}".format(hns_30) return render_template('pins/'+path + ".html", year=year, hns_45=hns_45, hns_30=hns_30) @app.route('/pins/order/') def pins_order(path): if not os.path.isfile('templates/pins/'+path + ".html"): return render_template('404.html'), 404 # Get cookies cookies = request.cookies if 'cart' in cookies: cart = cookies['cart'] else: cart = '[]' cart = json.loads(cart) item = { 'name': path, 'quantity': 1 } for i in range(len(cart)): if cart[i]['name'] == path: cart[i]['quantity'] += 1 item = None break if item: cart.append(item) cart = json.dumps(cart) response = make_response(redirect('/cart')) response.set_cookie('cart', cart) return response @app.route('/pins/update/', methods=['POST']) def pins_update(path): # Get cookies cookies = request.cookies if 'cart' in cookies: cart = cookies['cart'] else: cart = '[]' cart = json.loads(cart) data = request.json for i in range(len(cart)): if cart[i]['name'] == path: cart[i]['quantity'] = data['quantity'] break # Remove any item with less than 1 quantity cart = [item for item in cart if int(item['quantity']) > 0] cart = json.dumps(cart) response = make_response(jsonify({'status': 'ok'})) response.set_cookie('cart', cart) return response @app.route('/cart') def cart(): year = datetime.datetime.now().year # Get cookies cookies = request.cookies if 'cart' in cookies: cart = cookies['cart'] else: cart = '[]' promo_message = '' if 'promo' in cookies: promo = cookies['promo'] else: promo = '' cart = json.loads(cart) cartHtml = render.cart(cart) if promo != '': promo = payments.getPromo(promo) if not promo: promo_message = 'Invalid promo code' promo = '' else: promo_message = f'Promo code {promo["id"]} applied' total_usd = render.total_usd(cart,promo) total_hns = render.total_hns(cart,promo) promoCode = '' if promo: promoCode = promo["id"] else: total_usd = render.total_usd(cart, False) total_hns = render.total_hns(cart, False) promoCode = '' return render_template('cart.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns,promo=promoCode, promo_message=promo_message) @app.route('/cart/promo', methods=['POST']) def cart_promo(): data = request.form response = make_response(redirect('/cart')) response.set_cookie('promo', data['promo']) return response @app.route('/payment') def payment(): year = datetime.datetime.now().year # Get cookies cookies = request.cookies if 'cart' in cookies: cart = cookies['cart'] else: cart = '[]' if cart == '[]': return redirect('/cart') cart = json.loads(cart) cartHtml = render.cart_total(cart) if 'promo' in cookies: promo = cookies['promo'] promo = payments.getPromo(promo) total_usd = render.total_usd(cart,promo) total_hns = render.total_hns(cart,promo) else: promo = '' total_usd = render.total_usd(cart, False) total_hns = render.total_hns(cart, False) return render_template('payment.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns) @app.route('/payment', methods=['POST']) def payment_post(): # Get cookies cookies = request.cookies if 'cart' in cookies: cart = cookies['cart'] else: cart = '[]' if cart == '[]': return redirect('/cart') cart = json.loads(cart) if 'promo' in cookies: promo = cookies['promo'] promo = payments.getPromo(promo) total_usd = render.total_usd(cart,promo) total_hns = render.total_hns(cart,promo) else: promo = False total_usd = render.total_usd(cart, False) total_hns = render.total_hns(cart, False) data = request.form if 'email' in data: email = data['email'] else: email = '' if 'mobile' in data: mobile = data['mobile'] else: mobile = '' if 'address' in data: address = data['address'] else: address = '' if 'country' in data: country = data['country'] else: country = '' if 'name' in data: name = data['name'] else: name = '' cartHtml = render.cart_total(cart) if email == '' or address == '' or name == '' or country == '' or mobile == '': return render_template('payment.html', error='Please fill all fields', email=email, address=address, name=name, mobile=mobile, country=country, cart=cartHtml, total_usd=total_usd, total_hns=total_hns) # All good, check out payment = payments.generate_payment(name, email, mobile,address,country, cart, render.total_hns(cart, promo,True), promo) if payment == False: return render_template('payment.html', error='There was an error processing your payment', email=email, address=address, name=name, cart=cartHtml, total_usd=total_usd, total_hns=total_hns) finalPrice = payment['ID'] HNSaddress = payment['HNSaddress'] qr = f"QR Code" # Center the QR code qr = f"
{qr}
" responce = make_response(render_template('payment_info.html',cart=cartHtml, total_hns=finalPrice,address=HNSaddress, year=datetime.datetime.now().year, qr=qr)) responce.set_cookie('cart', '[]') return responce # Promo routes @app.route('/promo') def promo(): year = datetime.datetime.now().year # Check user is logged in token = request.cookies.get('token') if not token: return redirect('/login') if not account.token(token): return redirect('/login') promos = payments.getPromos() promos = render.promoList(promos) return render_template('promo.html', year=year, promos=promos) @app.route('/promo', methods=['POST']) def promo_post(): data = request.form token = request.cookies.get('token') if not token: return redirect('/login') if not account.token(token): return redirect('/login') id = data['code'] constant = data['constant'] percent = data['percent'] uses = data['uses'] payments.addPromo(id, constant, percent, uses) return redirect('/promo') @app.route('/promo/delete/') def promo_delete(path): token = request.cookies.get('token') if not token: return redirect('/login') if not account.token(token): return redirect('/login') payments.deletePromo(path) return redirect('/promo') @app.route('/login', methods=['POST']) def login(): data = request.form token = account.login(data['email'], data['password']) if token: response = make_response(redirect('/promo')) response.set_cookie('token', token) return response return redirect('/login') # Main routes @app.route('/') def index(): year = datetime.datetime.now().year return render_template('index.html',year=year) @app.route('/') def catch_all(path): year = datetime.datetime.now().year # If file exists, load it if os.path.isfile('templates/' + path): return render_template(path, year=year) # Try with .html if os.path.isfile('templates/' + path + '.html'): return render_template(path + '.html', year=year) if os.path.isfile('templates/' + path.strip('/') + '.html'): return render_template(path.strip('/') + '.html', year=year) return render_template('404.html'), 404 # 404 catch all @app.errorhandler(404) def not_found(e): return render_template('404.html'), 404 def repeat_check_payments(auto=False): # Run check_payments function payments.check_payments() # Schedule the function to run again after 10 seconds if not auto: threading.Timer(10, repeat_check_payments).start() def check_payments(): print('Checking payments', flush=True) payments.check_payments() if __name__ == '__main__': app.run(debug=True, port=5000, host='0.0.0.0')