See social network users cryptocurrency addresses and balances. Powered by transparent blockchains.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.6 KiB

# /path/to/
from jinja2 import Environment, FileSystemLoader
from datetime import datetime, timedelta
from urllib.parse import unquote
from sanic.response import redirect
from sanic.response import text
from sanic.response import html
from sanic import Sanic
from sanic.exceptions import SanicException
from sanic.handlers import ErrorHandler
from bs4 import BeautifulSoup
from random import randrange
import os, os.path
import random
import json
import re
import utils
base_dir = os.path.abspath(os.path.dirname(__name__))
static_dir = os.path.join(base_dir, 'static')
templates_dir = os.path.join(base_dir, 'templates')
data_dir = os.path.join(base_dir, 'data')
env = Environment(loader=FileSystemLoader(templates_dir), autoescape=True)
app = Sanic(__name__)
app.static('/static', static_dir)
app.config.DEBUG = int(os.environ["ISYC_DEBUG"]) > 0
class CustomErrorHandler(ErrorHandler):
def default(self, request, exception):
''' handles errors that have no error handlers assigned '''
self.log(request, exception)
template = env.get_template("error.html")
return html(template.render(status_code=500))
app.error_handler = CustomErrorHandler()
f = open('data.json')
data = json.load(f)['quotes']
#filename = ""
@app.route("/", name="index")
@app.route("/index", name="index")
async def index(request):
template = env.get_template('index.html')
errorHTML = ""
err = False
quote = random.choice(data)['text']
args = request.args
ranking = await utils.get_rankings(5)
return html(template.render(quote=quote, ranking=ranking))
@app.route("/about", name="about")
async def about(request):
template = env.get_template('about.html')
return html(template.render())
@app.get("/u/<username>", name="getaddr")
async def user(request, username=None):
template = env.get_template('user.html')
args = request.args
quote = data[randrange(0,len(data)-1)]['text']
invalid = re.compile("[^A-Za-z0-9_\-\.]")
username = re.sub(r"(?:(?:/)?\bu)?/|@|\s", "", username)
if invalid.findall(username):
return html(template.render(quote=quote, addresses={"btc":-1,"eth":-1,"nano":-1}, totals={"btc":-1,"eth":-1,"nano":-1}, user=username))
prices, dt = await utils.get_price()
if dt <
await utils.update_price()
addresses = await utils.get_user_data(username)
totals = {
"btc": 0.0,
"eth": 0.0,
"nano": 0.0
if addresses["btc"] == -2:
return html(template.render(quote=quote, addresses={"btc":-2,"eth":-2,"nano":-2}, totals={"btc":-2,"eth":-2,"nano":-2}, user=username))
# add up totals and format the balances
# btc has 8 digits precision
# eth has 18 digits precision but more than 12 digits may show wrong digits
# nano has 30 digits precision but more than 12 digits may show wrong digits
for currency, digits in (("btc", 8), ("eth", 12), ("nano", 12)):
if addresses[currency] != -1:
# convert sqlalchemy's rows to lists
addresses[currency] = [list(a) for a in addresses[currency]]
for i, addr in enumerate(addresses[currency]):
totals[currency] += float(addr[2])
addresses[currency][i][2] = f"{float(addr[2]):,.{digits}f}".rstrip("0").rstrip(".")
total_float = sum(totals[currency]*float(prices[currency]) for currency in ("btc", "eth", "nano"))
total_usd = f"{total_float:,.2f}"
totals = {currency: [totals[currency], f"{totals[currency]:,.{digits}f}".rstrip("0").rstrip(".")] for currency, digits in (("btc", 8), ("eth", 12), ("nano", 12))}
return html(template.render(quote=quote, addresses=addresses,
totals=totals, total_usd=total_usd,
@app.route("/ranking", name="ranking")
async def ranking(request):
template = env.get_template('ranking.html')
errorHTML = ""
err = False
quote = random.choice(data)['text']
args = request.args
ranking = await utils.get_rankings(50)
tot_addr_count, tot_user_count = await utils.get_global_stats()
return html(template.render(quote=quote, ranking=ranking, tot_addr_count=tot_addr_count, tot_user_count=tot_user_count))
async def error(request, exception):
template = env.get_template("error.html")
return html(template.render(status_code=exception.status_code))