moneropro/app/charts/asynchronous.py

499 lines
20 KiB
Python
Raw Normal View History

2022-09-17 03:04:08 +00:00
import aiohttp
import asyncio
import json
from .synchronous import data_prep_posts, data_prep_comments, update_rank, update_dominance
2022-09-17 03:04:08 +00:00
import datetime
from datetime import date, timedelta
from .models import Coin, Social, P2Pool
import requests
from django.conf import settings
import pandas as pd
BASE_DIR = settings.BASE_DIR
DATA_FILE = settings.DATA_FILE
2022-09-17 03:04:08 +00:00
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get block data from xmrchain
####################################################################################
2022-09-17 03:04:08 +00:00
async def get_block_data(session, block: str):
url = "https://localmonero.co/blocks/api/get_block_data/" + block
2022-09-17 03:04:08 +00:00
async with session.get(url) as res:
data = await res.read()
data = json.loads(data)
data["provider"] = "localmonero"
2022-09-17 03:04:08 +00:00
if res.status < 299:
data["success"] = True
2022-09-17 03:04:08 +00:00
else:
data["success"] = False
2022-09-17 03:04:08 +00:00
return data
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get network data from xmrchain
####################################################################################
2022-09-17 03:04:08 +00:00
async def get_network_data(session, block: str):
url = "https://xmrchain.net/api/networkinfo"
2022-09-17 03:04:08 +00:00
async with session.get(url) as res:
data = await res.read()
data = json.loads(data)
data["provider"] = "xmrchain"
2022-09-17 03:04:08 +00:00
if res.status < 299:
data["success"] = True
2022-09-17 03:04:08 +00:00
else:
data["success"] = False
2022-09-17 03:04:08 +00:00
return data
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get coinmarketcap data for price USD and BTC
####################################################################################
2022-09-17 03:04:08 +00:00
async def get_coinmarketcap_data(session, symbol: str, convert: str):
with open(BASE_DIR / "settings.json") as file:
2022-09-17 03:04:08 +00:00
data = json.load(file)
file.close()
url = data["metrics_provider"][0]["price_url_old"] + symbol
parameters = {
"convert": convert,
}
headers = {
"Accepts": "application/json",
data["metrics_provider"][0]["api_key_name"]: data["metrics_provider"][0][
"api_key_value"
],
}
2022-09-17 03:04:08 +00:00
async with session.get(url, headers=headers, params=parameters) as res:
data = await res.read()
data = json.loads(data)
data["provider"] = "coinmarketcap"
2022-09-17 03:04:08 +00:00
if res.status < 299:
try:
if data["data"][symbol.upper()]["cmc_rank"]:
data["success"] = True
2022-09-17 03:04:08 +00:00
else:
data["success"] = False
except Exception:
data["success"] = False
2022-09-17 03:04:08 +00:00
else:
data["success"] = False
2022-09-17 03:04:08 +00:00
return data
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get coinmetrics data for any coin inside URL
####################################################################################
2022-09-17 03:04:08 +00:00
async def get_coin_data(session, symbol, url):
update = True
count = 0
while update:
2022-09-17 03:04:08 +00:00
async with session.get(url) as res:
data = await res.read()
data = json.loads(data)
data_aux = data["data"]
2022-09-17 03:04:08 +00:00
for item in data_aux:
day, hour = str(item["time"]).split("T")
day = datetime.datetime.strptime(day, "%Y-%m-%d")
day = datetime.datetime.strftime(day, "%Y-%m-%d")
2022-09-17 03:04:08 +00:00
try:
coin = Coin.objects.filter(name=symbol).get(date=day)
except Exception:
2022-09-17 03:04:08 +00:00
coin = Coin()
try:
coin.name = symbol
coin.date = day
try:
coin.priceusd = float(item["PriceUSD"])
except Exception:
2022-09-17 03:04:08 +00:00
coin.priceusd = 0
try:
coin.pricebtc = float(item["PriceBTC"])
except Exception:
2022-09-17 03:04:08 +00:00
coin.pricebtc = 0
try:
coin.inflation = float(item["IssContPctAnn"])
coin.stocktoflow = (100 / coin.inflation) ** 1.65
except Exception:
2022-09-17 03:04:08 +00:00
coin.inflation = 0
coin.stocktoflow = 0
try:
coin.supply = float(item["SplyCur"])
except Exception:
2022-09-17 03:04:08 +00:00
coin.supply = 0
try:
coin.fee = float(item["FeeTotNtv"])
except Exception:
2022-09-17 03:04:08 +00:00
coin.fee = 0
try:
coin.revenue = float(item["RevNtv"])
except Exception:
2022-09-17 03:04:08 +00:00
coin.revenue = 0
try:
coin.hashrate = float(item["HashRate"])
except Exception:
2022-09-17 03:04:08 +00:00
coin.hashrate = 0
try:
coin.transactions = float(item["TxCnt"])
except Exception:
2022-09-17 03:04:08 +00:00
coin.transactions = 0
coin.save()
count += 1
except Exception:
2022-09-17 03:04:08 +00:00
pass
try:
url = data["next_page_url"]
2022-09-17 03:04:08 +00:00
update = True
except Exception:
2022-09-17 03:04:08 +00:00
update = False
break
return count
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get social metrics from reddit
####################################################################################
2022-09-17 03:04:08 +00:00
async def get_social_data(session, symbol):
yesterday = datetime.datetime.strftime(date.today() - timedelta(1), "%Y-%m-%d")
2022-09-23 20:38:20 +00:00
try:
social = Social.objects.filter(name=symbol).get(date=yesterday)
except Exception:
url = "https://www.reddit.com/r/" + symbol + "/about.json"
2022-09-17 03:04:08 +00:00
async with session.get(
url, headers={"User-agent": "Checking new social data"}
) as res:
2022-09-17 03:04:08 +00:00
data = await res.read()
data = json.loads(data)
data = data["data"]
2022-09-23 20:38:20 +00:00
2022-09-17 03:04:08 +00:00
social = Social()
social.name = symbol
2022-09-23 20:38:20 +00:00
social.date = yesterday
social.subscriberCount = data["subscribers"]
2022-09-17 03:04:08 +00:00
timestamp1 = int(
datetime.datetime.timestamp(
datetime.datetime.strptime(yesterday, "%Y-%m-%d")
)
)
2022-09-23 20:38:20 +00:00
timestamp2 = int(timestamp1 - 7200)
limit = 1000
2022-09-17 03:04:08 +00:00
filters = []
data = data_prep_posts(symbol, timestamp2, timestamp1, filters, limit)
social.postsPerHour = len(data) / 2
2022-09-17 03:04:08 +00:00
data = data_prep_comments(symbol, timestamp2, timestamp1, filters, limit)
social.commentsPerHour = len(data) / 2
2022-09-17 03:04:08 +00:00
social.save()
return True
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get whole xmr data calling coinmarketcap and xmrchain
####################################################################################
2022-09-17 03:04:08 +00:00
async def update_xmr_data(yesterday, coin):
# TODO: Why is this all commented out?
name = coin.name # noqa: F841
# Coin.objects.filter(name=coin.name).filter(date=yesterday).delete()
2022-09-19 02:12:23 +00:00
url = "https://localmonero.co/blocks/api/get_stats"
2022-09-17 03:04:08 +00:00
response = requests.get(url)
data = json.loads(response.text)
height = int(data["height"]) # noqa: F841
difficulty = int(data["difficulty"]) # noqa: F841
hashrate = int(data["hashrate"]) # noqa: F841
supply = int(data["total_emission"]) # noqa: F841
blocksize = 0 # noqa: F841
2022-09-17 03:04:08 +00:00
actions = []
my_timeout = aiohttp.ClientTimeout(total=10, sock_connect=10, sock_read=10)
client_args = dict(trust_env=True, timeout=my_timeout)
async with aiohttp.ClientSession(**client_args) as session:
# for count in range(1, 1400):
2023-10-08 21:39:47 +00:00
# block = str(height - count)
# actions.append(asyncio.ensure_future(get_block_data(session, block)))
actions.append(
asyncio.ensure_future(get_coinmarketcap_data(session, "xmr", "USD"))
)
actions.append(
asyncio.ensure_future(get_coinmarketcap_data(session, "xmr", "BTC"))
)
2022-09-17 03:04:08 +00:00
try:
responses = await asyncio.gather(*actions, return_exceptions=True)
except asyncio.exceptions.TimeoutError:
print("Timeout!")
2022-09-17 03:04:08 +00:00
errors = 0
success = 0 # noqa: F841
txs = 0 # noqa: F841
revenue = 0 # noqa: F841
fees = 0 # noqa: F841
priceusd = 0 # noqa: F841
2022-09-17 03:04:08 +00:00
pricebtc = 0
for response in responses:
if response:
try:
2023-10-08 21:39:47 +00:00
# if response['provider'] == 'localmonero':
# date_aux = response['block_header']['timestamp']
# if date_aux == yesterday:
# try:
# blocksize += int(response['block_header']['size'])
# for tx in response['block_header']['txs']:
# if tx['coinbase']:
# revenue += int(tx['xmr_outputs'])
# else:
# txs += 1
# fees += int(tx['tx_fee'])
# revenue += int(tx['tx_fee'])
# success += 1
# except:
# errors += 1
2022-09-17 03:04:08 +00:00
if response["provider"] == "coinmarketcap":
2022-09-17 03:04:08 +00:00
try:
# priceusd = float(response['data']['XMR']['quote']['USD']['price'])
update_rank(response)
2022-09-17 03:04:08 +00:00
update_dominance(response)
except Exception:
2022-09-17 03:04:08 +00:00
try:
pricebtc = float( # noqa: F841
response["data"]["XMR"]["quote"]["BTC"]["price"]
)
except Exception:
2022-09-17 03:04:08 +00:00
errors += 1
except Exception:
2022-09-17 03:04:08 +00:00
errors += 1
else:
errors += 1
2023-10-09 03:44:48 +00:00
# blocksize = blocksize/success
# revenue = float(revenue)/10**12
# fees = float(fees)/10**12
# inflation = 100*365*(revenue)/float(coin.supply)
# stocktoflow = (100/inflation)**1.65
2023-10-09 03:44:48 +00:00
# supply = coin.supply + revenue
2022-09-17 03:04:08 +00:00
# try:
2023-10-09 03:44:48 +00:00
# coin = Coin.objects.filter(name='xmr').get(date=yesterday)
# coin.name = name
# coin.date = datetime.datetime.strptime(yesterday, '%Y-%m-%d')
# coin.date = datetime.datetime.strftime(coin.date, '%Y-%m-%d')
# #coin.blocksize = blocksize
# #coin.transactions = txs
# #coin.revenue = revenue
# #coin.fee = fees
# #coin.inflation = inflation
# #coin.hashrate = hashrate
# #coin.difficulty = difficulty
# #coin.stocktoflow = stocktoflow
# coin.priceusd = priceusd
# coin.pricebtc = pricebtc
# #coin.supply = supply
# coin.save()
2022-09-30 11:38:49 +00:00
2023-10-09 03:44:48 +00:00
# # print('Success: ' + str(success))
# # print('Errors: ' + str(errors))
# # print('Name: ' + coin.name)
# # print('Date: ' + str(coin.date))
# # print('Blocksize: ' + str(coin.blocksize))
# # print('Transactions: ' + str(coin.transactions))
# # print('Revenue: ' + str(coin.revenue))
# # print('Fees: ' + str(coin.fee))
# # print('Inflation: ' + str(coin.inflation))
# # print('Hashrate: ' + str(coin.hashrate))
# # print('Stocktoflow: ' + str(coin.stocktoflow))
# # print('Priceusd: ' + str(coin.priceusd))
# # print('Pricebtc: ' + str(coin.pricebtc))
# # print('Supply: ' + str(coin.supply))
# except:
# return False
2022-09-17 03:04:08 +00:00
return True
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get social and coins data
####################################################################################
2022-09-17 03:04:08 +00:00
async def update_others_data(date):
with open(BASE_DIR / "settings.json") as file:
2022-09-17 03:04:08 +00:00
data = json.load(file)
file.close()
url_btc = data["metrics_provider"][0]["metrics_url_new"] + "btc/" + date
url_dash = data["metrics_provider"][0]["metrics_url_new"] + "dash/" + date
url_grin = data["metrics_provider"][0]["metrics_url_new"] + "grin/" + date
url_zec = data["metrics_provider"][0]["metrics_url_new"] + "zec/" + date
2022-09-17 03:04:08 +00:00
actions = []
my_timeout = aiohttp.ClientTimeout(total=10, sock_connect=10, sock_read=10)
client_args = dict(trust_env=True, timeout=my_timeout)
async with aiohttp.ClientSession(**client_args) as session:
2022-09-17 03:04:08 +00:00
# reddit data
# actions.append(asyncio.ensure_future(get_social_data(session, 'Monero')))
# actions.append(asyncio.ensure_future(get_social_data(session, 'Bitcoin')))
# actions.append(asyncio.ensure_future(get_social_data(session, 'Cryptocurrency')))
2022-09-17 03:04:08 +00:00
# coinmetrics data
actions.append(asyncio.ensure_future(get_coin_data(session, "btc", url_btc)))
actions.append(asyncio.ensure_future(get_coin_data(session, "dash", url_dash)))
actions.append(asyncio.ensure_future(get_coin_data(session, "grin", url_grin)))
actions.append(asyncio.ensure_future(get_coin_data(session, "zec", url_zec)))
2022-09-17 03:04:08 +00:00
actions.append(asyncio.ensure_future(get_p2pool_data(session, mini=False)))
actions.append(asyncio.ensure_future(get_p2pool_data(session, mini=True)))
try:
await asyncio.gather(*actions, return_exceptions=True)
except asyncio.exceptions.TimeoutError:
print("Timeout!")
2022-09-23 20:38:20 +00:00
return True
2022-09-23 20:38:20 +00:00
####################################################################################
# Asynchronous get social and coins data
####################################################################################
2022-09-23 20:38:20 +00:00
async def update_social_data(symbol):
actions = []
my_timeout = aiohttp.ClientTimeout(total=10, sock_connect=10, sock_read=10)
client_args = dict(trust_env=True, timeout=my_timeout)
2022-09-23 20:38:20 +00:00
2024-11-12 00:19:52 +00:00
async with aiohttp.ClientSession(**client_args) as session:
2022-09-23 20:38:20 +00:00
# reddit data
actions.append(asyncio.ensure_future(get_social_data(session, "Monero")))
actions.append(asyncio.ensure_future(get_social_data(session, "Bitcoin")))
actions.append(
asyncio.ensure_future(get_social_data(session, "Cryptocurrency"))
)
2024-11-12 00:19:52 +00:00
2022-09-23 20:38:20 +00:00
try:
await asyncio.gather(*actions, return_exceptions=True)
except asyncio.exceptions.TimeoutError:
print("Timeout!")
2022-09-23 20:38:20 +00:00
2022-09-17 03:04:08 +00:00
return True
2022-09-17 03:04:08 +00:00
####################################################################################
# Asynchronous get p2pool and p2poolmini data and then save to .ods
####################################################################################
2022-09-17 03:04:08 +00:00
async def get_p2pool_data(session, mini):
today = date.today()
yesterday = date.today() - timedelta(1)
try:
p2pool_stat = P2Pool.objects.filter(mini=mini).get(date=today)
if p2pool_stat.percentage > 0:
update = False
2022-09-17 03:04:08 +00:00
else:
p2pool_stat.delete()
try:
coin = Coin.objects.filter(name="xmr").get(date=yesterday)
2022-09-17 03:04:08 +00:00
if coin.hashrate > 0:
update = True
else:
update = False
except Exception:
update = False
except Exception:
2022-09-17 03:04:08 +00:00
try:
coin = Coin.objects.filter(name="xmr").get(date=yesterday)
2022-09-17 03:04:08 +00:00
if coin.hashrate > 0:
update = True
else:
update = False
except Exception:
update = False
2022-09-17 03:04:08 +00:00
if update:
p2pool_stat = P2Pool()
p2pool_stat.date = today
if not (mini):
async with session.get("https://p2pool.io/api/pool/stats") as res:
2022-09-17 03:04:08 +00:00
data = await res.read()
data = json.loads(data)
p2pool_stat.hashrate = data["pool_statistics"]["hashRate"]
p2pool_stat.percentage = (
100 * data["pool_statistics"]["hashRate"] / coin.hashrate
)
p2pool_stat.miners = data["pool_statistics"]["miners"]
p2pool_stat.totalhashes = data["pool_statistics"]["totalHashes"]
p2pool_stat.totalblocksfound = data["pool_statistics"][
"totalBlocksFound"
]
2022-09-17 03:04:08 +00:00
p2pool_stat.mini = False
p2pool_stat.save()
print("p2pool saved!")
df = pd.read_excel(DATA_FILE, sheet_name="p2pool", engine="odf")
start_row, end_row = 2, 9999
start_col, end_col = 0, 2
values_mat = df.iloc[start_row:end_row, start_col:end_col].to_numpy()
2022-09-17 03:04:08 +00:00
k = len(values_mat)
date_aux = datetime.datetime.strptime(values_mat[k - 1][0], "%Y-%m-%d")
date_aux2 = datetime.datetime.strftime(date.today(), "%Y-%m-%d")
date_aux2 = datetime.datetime.strptime(date_aux2, "%Y-%m-%d")
2022-09-17 03:04:08 +00:00
if date_aux < date_aux2:
values_mat[k][5] = p2pool_stat.totalblocksfound
values_mat[k][4] = p2pool_stat.totalhashes
values_mat[k][3] = p2pool_stat.percentage
values_mat[k][2] = p2pool_stat.hashrate
values_mat[k][1] = p2pool_stat.miners
values_mat[k][0] = datetime.datetime.strftime(p2pool_stat.date, "%Y-%m-%d")
df.iloc[start_row:end_row, start_col:end_col] = values_mat
df.to_excel(DATA_FILE, sheet_name="p2pool", index=False)
print("spreadsheet updated")
else:
print("spreadsheet already with the latest data")
2022-09-17 03:04:08 +00:00
return data
else:
async with session.get("https://p2pool.io/mini/api/pool/stats") as res:
2022-09-17 03:04:08 +00:00
data = await res.read()
data = json.loads(data)
p2pool_stat.hashrate = data["pool_statistics"]["hashRate"]
p2pool_stat.percentage = (
100 * data["pool_statistics"]["hashRate"] / coin.hashrate
)
p2pool_stat.miners = data["pool_statistics"]["miners"]
p2pool_stat.totalhashes = data["pool_statistics"]["totalHashes"]
p2pool_stat.totalblocksfound = data["pool_statistics"][
"totalBlocksFound"
]
2022-09-17 03:04:08 +00:00
p2pool_stat.mini = True
p2pool_stat.save()
print("p2pool_mini saved!")
df = pd.read_excel(DATA_FILE, sheet_name="p2poolmini", engine="odf")
start_row, end_row = 2, 9999
start_col, end_col = 0, 2
values_mat = df.iloc[start_row:end_row, start_col:end_col].to_numpy()
2022-09-17 03:04:08 +00:00
k = len(values_mat)
date_aux = datetime.datetime.strptime(values_mat[k - 1][0], "%Y-%m-%d")
date_aux2 = datetime.datetime.strftime(date.today(), "%Y-%m-%d")
date_aux2 = datetime.datetime.strptime(date_aux2, "%Y-%m-%d")
2022-09-17 03:04:08 +00:00
if date_aux < date_aux2:
values_mat[k][5] = p2pool_stat.totalblocksfound
values_mat[k][4] = p2pool_stat.totalhashes
values_mat[k][3] = p2pool_stat.percentage
values_mat[k][2] = p2pool_stat.hashrate
values_mat[k][1] = p2pool_stat.miners
values_mat[k][0] = datetime.datetime.strftime(p2pool_stat.date, "%Y-%m-%d")
df.iloc[start_row:end_row, start_col:end_col] = values_mat
df.to_excel(DATA_FILE, sheet_name="p2poolmini", index=False)
print("spreadsheet updated")
2024-11-12 00:19:52 +00:00
else:
print("spreadsheet already with the latest data")
2022-09-17 03:04:08 +00:00
return data
2024-11-12 00:19:52 +00:00
else:
2022-09-17 03:04:08 +00:00
return False
return True