2020-10-03 02:45:45 +00:00
|
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
# Copyright (c) 2020, The Monero Project.
|
|
|
|
# Copyright (c) 2020, dsc@xmr.pm
|
|
|
|
|
|
|
|
import json
|
|
|
|
import asyncio
|
2020-12-22 18:03:48 +00:00
|
|
|
from typing import List, Set
|
|
|
|
from datetime import datetime
|
2020-10-03 02:45:45 +00:00
|
|
|
|
|
|
|
from quart import Quart
|
|
|
|
from quart_session import Session
|
|
|
|
import aioredis
|
|
|
|
|
2021-04-05 17:49:02 +00:00
|
|
|
from wowlet_backend.utils import current_worker_thread_is_primary, print_banner
|
2020-10-03 02:45:45 +00:00
|
|
|
import settings
|
|
|
|
|
2020-12-22 18:03:48 +00:00
|
|
|
now = datetime.now()
|
|
|
|
app: Quart = None
|
2020-10-03 02:45:45 +00:00
|
|
|
cache = None
|
2020-12-22 18:03:48 +00:00
|
|
|
user_agents: List[str] = None
|
|
|
|
connected_websockets: Set[asyncio.Queue] = set()
|
|
|
|
_is_primary_worker_thread = False
|
|
|
|
|
|
|
|
|
|
|
|
async def _setup_nodes(app: Quart):
|
2020-12-29 20:33:32 +00:00
|
|
|
global cache
|
|
|
|
with open('data/nodes.json', 'r') as f:
|
|
|
|
nodes = json.loads(f.read()).get(settings.COIN_SYMBOL)
|
2021-04-06 23:24:46 +00:00
|
|
|
await cache.set('nodes', json.dumps(nodes).encode())
|
2020-12-22 18:03:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def _setup_user_agents(app: Quart):
|
|
|
|
global user_agents
|
|
|
|
with open('data/user_agents.txt', 'r') as f:
|
|
|
|
user_agents = [l.strip() for l in f.readlines() if l.strip()]
|
2020-10-03 02:45:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def _setup_cache(app: Quart):
|
|
|
|
global cache
|
2020-12-22 18:03:48 +00:00
|
|
|
# Each coin has it's own Redis DB index; `redis-cli -n $INDEX`
|
|
|
|
db = {"xmr": 0, "wow": 1, "aeon": 2, "trtl": 3, "msr": 4, "xhv": 5, "loki": 6}[settings.COIN_SYMBOL]
|
2020-10-03 02:45:45 +00:00
|
|
|
data = {
|
2020-12-22 18:03:48 +00:00
|
|
|
"address": settings.REDIS_ADDRESS,
|
|
|
|
"db": db,
|
|
|
|
"password": settings.REDIS_PASSWORD if settings.REDIS_PASSWORD else None
|
2020-10-03 02:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cache = await aioredis.create_redis_pool(**data)
|
|
|
|
app.config['SESSION_TYPE'] = 'redis'
|
|
|
|
app.config['SESSION_REDIS'] = cache
|
|
|
|
Session(app)
|
|
|
|
|
|
|
|
|
2020-12-22 18:03:48 +00:00
|
|
|
async def _setup_tasks(app: Quart):
|
|
|
|
"""Schedules a series of tasks at an interval."""
|
|
|
|
if not _is_primary_worker_thread:
|
|
|
|
return
|
|
|
|
|
2021-04-05 17:49:02 +00:00
|
|
|
from wowlet_backend.tasks import (
|
2020-12-22 18:03:48 +00:00
|
|
|
BlockheightTask, HistoricalPriceTask, FundingProposalsTask,
|
|
|
|
CryptoRatesTask, FiatRatesTask, RedditTask, RPCNodeCheckTask,
|
2021-04-05 19:03:35 +00:00
|
|
|
XmrigTask, SuchWowTask)
|
2020-12-22 18:03:48 +00:00
|
|
|
|
|
|
|
asyncio.create_task(BlockheightTask().start())
|
|
|
|
asyncio.create_task(HistoricalPriceTask().start())
|
|
|
|
asyncio.create_task(CryptoRatesTask().start())
|
|
|
|
asyncio.create_task(FiatRatesTask().start())
|
|
|
|
asyncio.create_task(RedditTask().start())
|
|
|
|
asyncio.create_task(RPCNodeCheckTask().start())
|
|
|
|
asyncio.create_task(XmrigTask().start())
|
2021-04-05 19:03:35 +00:00
|
|
|
asyncio.create_task(SuchWowTask().start())
|
2020-12-22 18:03:48 +00:00
|
|
|
|
|
|
|
if settings.COIN_SYMBOL in ["xmr", "wow"]:
|
|
|
|
asyncio.create_task(FundingProposalsTask().start())
|
|
|
|
|
|
|
|
|
|
|
|
def _setup_logging():
|
|
|
|
from logging import Formatter
|
|
|
|
from logging.config import dictConfig
|
|
|
|
from quart.logging import default_handler
|
|
|
|
default_handler.setFormatter(Formatter('[%(asctime)s] %(levelname)s in %(funcName)s(): %(message)s (%(pathname)s)'))
|
|
|
|
|
|
|
|
dictConfig({
|
|
|
|
'version': 1,
|
|
|
|
'loggers': {
|
|
|
|
'quart.app': {
|
|
|
|
'level': 'DEBUG' if settings.DEBUG else 'INFO',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
|
2020-10-03 02:45:45 +00:00
|
|
|
def create_app():
|
|
|
|
global app
|
2020-12-22 18:03:48 +00:00
|
|
|
|
|
|
|
_setup_logging()
|
2020-10-03 02:45:45 +00:00
|
|
|
app = Quart(__name__)
|
|
|
|
|
|
|
|
@app.before_serving
|
|
|
|
async def startup():
|
2020-12-22 18:03:48 +00:00
|
|
|
global _is_primary_worker_thread
|
|
|
|
_is_primary_worker_thread = current_worker_thread_is_primary()
|
|
|
|
|
|
|
|
if _is_primary_worker_thread:
|
|
|
|
print_banner()
|
|
|
|
|
2020-10-03 02:45:45 +00:00
|
|
|
await _setup_cache(app)
|
2020-12-22 18:03:48 +00:00
|
|
|
await _setup_nodes(app)
|
|
|
|
await _setup_user_agents(app)
|
|
|
|
await _setup_tasks(app)
|
|
|
|
|
2021-04-05 17:49:02 +00:00
|
|
|
import wowlet_backend.routes
|
2020-10-03 02:45:45 +00:00
|
|
|
|
|
|
|
return app
|