diff --git a/README.md b/README.md index 63bf823..77a0fb3 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Back-end websocket server for Feather wallet. - Monero - Wownero -See also the environment variables `FEATHER_COIN_NAME`, `FEATHER_COIN_SYMBOL`, etc. in `settings.py`. +See also the environment variables `WOWLET_COIN_NAME`, `WOWLET_COIN_SYMBOL`, etc. in `settings.py`. ## Tasks @@ -26,7 +26,7 @@ When Feather wallet starts up, it will connect to this websocket server and receive the information listed above which is necessary for normal operation. -See `fapi.tasks.*` for the various tasks. +See `wowlet_backend.tasks.*` for the various tasks. ## Development @@ -37,7 +37,7 @@ virtualenv -p /usr/bin/python3 venv source venv/bin/activate pip install -r requirements.txt -export FEATHER_DEBUG=true +export WOWLET_DEBUG=true python run.py ``` diff --git a/asgi.py b/asgi.py index 50bfc10..4d49d01 100644 --- a/asgi.py +++ b/asgi.py @@ -2,5 +2,5 @@ # Copyright (c) 2020, The Monero Project. # Copyright (c) 2020, dsc@xmr.pm -from fapi.factory import create_app +from wowlet_backend_backend.factory import create_app app = create_app() diff --git a/docker-compose.yml b/docker-compose.yml index 76e7e8f..57ecb1c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,12 +16,12 @@ services: context: . dockerfile: Dockerfile environment: - - FEATHER_DEBUG=false - - FEATHER_PORT=1337 - - FEATHER_REDIS_ADDRESS=redis://redis - - FEATHER_TOR_SOCKS_PROXY=socks5://tor-node:9050 - - FEATHER_COIN_NAME=monero - - FEATHER_COIN_SYMBOL=xmr - - FEATHER_COIN_MODE=mainnet + - WOWLET_DEBUG=false + - WOWLET_PORT=1337 + - WOWLET_REDIS_ADDRESS=redis://redis + - WOWLET_TOR_SOCKS_PROXY=socks5://tor-node:9050 + - WOWLET_COIN_NAME=monero + - WOWLET_COIN_SYMBOL=xmr + - WOWLET_COIN_MODE=mainnet ports: - "1337:1337" diff --git a/run.py b/run.py index 2c40153..3c89440 100644 --- a/run.py +++ b/run.py @@ -2,7 +2,7 @@ # Copyright (c) 2020, The Monero Project. # Copyright (c) 2020, dsc@xmr.pm -from fapi.factory import create_app +from wowlet_backend.factory import create_app import settings app = create_app() diff --git a/settings.py_example b/settings.py_example index 50765c1..799084e 100644 --- a/settings.py_example +++ b/settings.py_example @@ -10,19 +10,19 @@ def bool_env(val): return val is True or (isinstance(val, str) and (val.lower() == 'true' or val == '1')) -DEBUG = bool_env(os.environ.get("FEATHER_DEBUG", False)) -HOST = os.environ.get("FEATHER_HOST", "127.0.0.1") -PORT = int(os.environ.get("FEATHER_PORT", 1337)) +DEBUG = bool_env(os.environ.get("WOWLET_DEBUG", False)) +HOST = os.environ.get("WOWLET_HOST", "127.0.0.1") +PORT = int(os.environ.get("WOWLET_PORT", 1337)) -REDIS_ADDRESS = os.environ.get("FEATHER_REDIS_ADDRESS", "redis://localhost") -REDIS_PASSWORD = os.environ.get("FEATHER_REDIS_PASSWORD") +REDIS_ADDRESS = os.environ.get("WOWLET_REDIS_ADDRESS", "redis://localhost") +REDIS_PASSWORD = os.environ.get("WOWLET_REDIS_PASSWORD") -COIN_NAME = os.environ.get("FEATHER_COIN_NAME", "monero").lower() # as per coingecko -COIN_SYMBOL = os.environ.get("FEATHER_COIN_SYMBOL", "xmr").lower() # as per coingecko -COIN_GENESIS_DATE = os.environ.get("FEATHER_COIN_GENESIS_DATE", "20140418") -COIN_MODE = os.environ.get("FEATHER_COIN_MODE", "mainnet").lower() +COIN_NAME = os.environ.get("WOWLET_COIN_NAME", "monero").lower() # as per coingecko +COIN_SYMBOL = os.environ.get("WOWLET_COIN_SYMBOL", "xmr").lower() # as per coingecko +COIN_GENESIS_DATE = os.environ.get("WOWLET_COIN_GENESIS_DATE", "20140418") +COIN_MODE = os.environ.get("WOWLET_COIN_MODE", "mainnet").lower() -TOR_SOCKS_PROXY = os.environ.get("FEATHER_TOR_SOCKS_PROXY", "socks5://127.0.0.1:9050") +TOR_SOCKS_PROXY = os.environ.get("WOWLET_TOR_SOCKS_PROXY", "socks5://127.0.0.1:9050") # while fetching USD price from coingecko, also include these extra coins: CRYPTO_RATES_COINS_EXTRA = { diff --git a/fapi/__init__.py b/wowlet_backend/__init__.py similarity index 100% rename from fapi/__init__.py rename to wowlet_backend/__init__.py diff --git a/fapi/factory.py b/wowlet_backend/factory.py similarity index 93% rename from fapi/factory.py rename to wowlet_backend/factory.py index 115d820..12ffdb0 100644 --- a/fapi/factory.py +++ b/wowlet_backend/factory.py @@ -11,7 +11,7 @@ from quart import Quart from quart_session import Session import aioredis -from fapi.utils import current_worker_thread_is_primary, print_banner +from wowlet_backend.utils import current_worker_thread_is_primary, print_banner import settings now = datetime.now() @@ -56,7 +56,7 @@ async def _setup_tasks(app: Quart): if not _is_primary_worker_thread: return - from fapi.tasks import ( + from wowlet_backend.tasks import ( BlockheightTask, HistoricalPriceTask, FundingProposalsTask, CryptoRatesTask, FiatRatesTask, RedditTask, RPCNodeCheckTask, XmrigTask, XmrToTask) @@ -72,9 +72,6 @@ async def _setup_tasks(app: Quart): if settings.COIN_SYMBOL in ["xmr", "wow"]: asyncio.create_task(FundingProposalsTask().start()) - if settings.COIN_SYMBOL == "xmr": - asyncio.create_task(XmrToTask().start()) - def _setup_logging(): from logging import Formatter @@ -111,6 +108,6 @@ def create_app(): await _setup_user_agents(app) await _setup_tasks(app) - import fapi.routes + import wowlet_backend.routes return app diff --git a/fapi/routes.py b/wowlet_backend/routes.py similarity index 91% rename from fapi/routes.py rename to wowlet_backend/routes.py index 26464e0..f9a9f92 100644 --- a/fapi/routes.py +++ b/wowlet_backend/routes.py @@ -7,9 +7,9 @@ import json from quart import websocket, jsonify -from fapi.factory import app -from fapi.wsparse import WebsocketParse -from fapi.utils import collect_websocket, feather_data +from wowlet_backend.factory import app +from wowlet_backend.wsparse import WebsocketParse +from wowlet_backend.utils import collect_websocket, feather_data @app.route("/") diff --git a/fapi/tasks/__init__.py b/wowlet_backend/tasks/__init__.py similarity index 87% rename from fapi/tasks/__init__.py rename to wowlet_backend/tasks/__init__.py index e9de64d..ff70e9e 100644 --- a/fapi/tasks/__init__.py +++ b/wowlet_backend/tasks/__init__.py @@ -39,7 +39,7 @@ class FeatherTask: self._running = False async def start(self, *args, **kwargs): - from fapi.factory import app, connected_websockets + from wowlet_backend.factory import app, connected_websockets if not self._active: # invalid task return @@ -124,7 +124,7 @@ class FeatherTask: raise NotImplementedError() async def cache_json_get(self, key: str, path="."): - from fapi.factory import app, cache + from wowlet_backend.factory import app, cache try: data = await cache.execute('JSON.GET', key, path) @@ -134,7 +134,7 @@ class FeatherTask: app.logger.error(f"Redis error: {ex}") async def cache_get(self, key: str) -> dict: - from fapi.factory import app, cache + from wowlet_backend.factory import app, cache try: data = await cache.get(key) @@ -145,7 +145,7 @@ class FeatherTask: app.logger.error(f"Redis GET error with key '{key}': {ex}") async def cache_set(self, key, val: Union[dict, int], expiry: int = 0) -> bool: - from fapi.factory import app, cache + from wowlet_backend.factory import app, cache try: data = json.dumps(val) if isinstance(expiry, int) and expiry > 0: @@ -157,12 +157,12 @@ class FeatherTask: app.logger.error(f"Redis SET error with key '{key}': {ex}") -from fapi.tasks.proposals import FundingProposalsTask -from fapi.tasks.historical_prices import HistoricalPriceTask -from fapi.tasks.blockheight import BlockheightTask -from fapi.tasks.rates_fiat import FiatRatesTask -from fapi.tasks.rates_crypto import CryptoRatesTask -from fapi.tasks.reddit import RedditTask -from fapi.tasks.rpc_nodes import RPCNodeCheckTask -from fapi.tasks.xmrig import XmrigTask -from fapi.tasks.xmrto import XmrToTask +from wowlet_backend.tasks.proposals import FundingProposalsTask +from wowlet_backend.tasks.historical_prices import HistoricalPriceTask +from wowlet_backend.tasks.blockheight import BlockheightTask +from wowlet_backend.tasks.rates_fiat import FiatRatesTask +from wowlet_backend.tasks.rates_crypto import CryptoRatesTask +from wowlet_backend.tasks.reddit import RedditTask +from wowlet_backend.tasks.rpc_nodes import RPCNodeCheckTask +from wowlet_backend.tasks.xmrig import XmrigTask +from wowlet_backend.tasks.xmrto import XmrToTask diff --git a/fapi/tasks/blockheight.py b/wowlet_backend/tasks/blockheight.py similarity index 97% rename from fapi/tasks/blockheight.py rename to wowlet_backend/tasks/blockheight.py index 4e8c669..f0798aa 100644 --- a/fapi/tasks/blockheight.py +++ b/wowlet_backend/tasks/blockheight.py @@ -8,8 +8,8 @@ from collections import Counter from functools import partial import settings -from fapi.utils import httpget, popularity_contest -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget, popularity_contest +from wowlet_backend.tasks import FeatherTask class BlockheightTask(FeatherTask): @@ -81,7 +81,7 @@ class BlockheightTask(FeatherTask): } async def task(self) -> Union[dict, None]: - from fapi.factory import app + from wowlet_backend.factory import app coin_network_types = ["mainnet", "stagenet", "testnet"] data = {t: 0 for t in coin_network_types} diff --git a/fapi/tasks/historical_prices.py b/wowlet_backend/tasks/historical_prices.py similarity index 96% rename from fapi/tasks/historical_prices.py rename to wowlet_backend/tasks/historical_prices.py index 47201ce..fdd6061 100644 --- a/fapi/tasks/historical_prices.py +++ b/wowlet_backend/tasks/historical_prices.py @@ -11,8 +11,8 @@ from datetime import datetime import aiofiles import settings -from fapi.utils import httpget -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import FeatherTask class HistoricalPriceTask(FeatherTask): @@ -91,7 +91,7 @@ class HistoricalPriceTask(FeatherTask): """This function is called when a Feather wallet client asks for (a range of) historical fiat information. It returns the data filtered by the parameters.""" - from fapi.factory import cache + from wowlet_backend.factory import cache blob = await cache.get("historical_fiat") blob = json.loads(blob) diff --git a/fapi/tasks/proposals.py b/wowlet_backend/tasks/proposals.py similarity index 96% rename from fapi/tasks/proposals.py rename to wowlet_backend/tasks/proposals.py index bdffbfe..1bd30ae 100644 --- a/fapi/tasks/proposals.py +++ b/wowlet_backend/tasks/proposals.py @@ -6,14 +6,14 @@ from bs4 import BeautifulSoup from typing import List import settings -from fapi.utils import httpget -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import FeatherTask class FundingProposalsTask(FeatherTask): """Fetch funding proposals made by the community.""" def __init__(self, interval: int = 600): - from fapi.factory import app + from wowlet_backend.factory import app super(FundingProposalsTask, self).__init__(interval) self._cache_key = "funding_proposals" @@ -58,7 +58,7 @@ class FundingProposalsTask(FeatherTask): # - API does not allow filtering # - API sometimes breaks; https://hackerone.com/reports/934231 # we'll web scrape instead - from fapi.factory import app + from wowlet_backend.factory import app content = await httpget(f"{self._http_endpoint}/funding-required/", json=False) soup = BeautifulSoup(content, "html.parser") diff --git a/fapi/tasks/rates_crypto.py b/wowlet_backend/tasks/rates_crypto.py similarity index 93% rename from fapi/tasks/rates_crypto.py rename to wowlet_backend/tasks/rates_crypto.py index 047083d..3c0cb44 100644 --- a/fapi/tasks/rates_crypto.py +++ b/wowlet_backend/tasks/rates_crypto.py @@ -5,8 +5,8 @@ from typing import List, Union import settings -from fapi.utils import httpget -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import FeatherTask class CryptoRatesTask(FeatherTask): @@ -22,7 +22,7 @@ class CryptoRatesTask(FeatherTask): async def task(self) -> Union[List[dict], None]: """Fetch USD prices for various coins""" - from fapi.factory import app + from wowlet_backend.factory import app url = f"{self._http_api_gecko}/coins/markets?vs_currency=usd" rates = await httpget(url, json=True) diff --git a/fapi/tasks/rates_fiat.py b/wowlet_backend/tasks/rates_fiat.py similarity index 87% rename from fapi/tasks/rates_fiat.py rename to wowlet_backend/tasks/rates_fiat.py index aad593f..99e3926 100644 --- a/fapi/tasks/rates_fiat.py +++ b/wowlet_backend/tasks/rates_fiat.py @@ -2,8 +2,8 @@ # Copyright (c) 2020, The Monero Project. # Copyright (c) 2020, dsc@xmr.pm -from fapi.utils import httpget -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import FeatherTask class FiatRatesTask(FeatherTask): diff --git a/fapi/tasks/reddit.py b/wowlet_backend/tasks/reddit.py similarity index 91% rename from fapi/tasks/reddit.py rename to wowlet_backend/tasks/reddit.py index 1728a3c..992f505 100644 --- a/fapi/tasks/reddit.py +++ b/wowlet_backend/tasks/reddit.py @@ -4,13 +4,13 @@ import html import settings -from fapi.utils import httpget -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import FeatherTask class RedditTask(FeatherTask): def __init__(self, interval: int = 900): - from fapi.factory import app + from wowlet_backend.factory import app super(RedditTask, self).__init__(interval) self._cache_key = "reddit" @@ -36,7 +36,7 @@ class RedditTask(FeatherTask): self._http_endpoint = self._http_endpoint[:-1] async def task(self): - from fapi.factory import app + from wowlet_backend.factory import app url = f"{self._http_endpoint}/new.json?limit=15" try: diff --git a/fapi/tasks/rpc_nodes.py b/wowlet_backend/tasks/rpc_nodes.py similarity index 95% rename from fapi/tasks/rpc_nodes.py rename to wowlet_backend/tasks/rpc_nodes.py index 77dc058..889122a 100644 --- a/fapi/tasks/rpc_nodes.py +++ b/wowlet_backend/tasks/rpc_nodes.py @@ -6,8 +6,8 @@ import json from typing import List import settings -from fapi.utils import httpget, popularity_contest -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget, popularity_contest +from wowlet_backend.tasks import FeatherTask class RPCNodeCheckTask(FeatherTask): @@ -24,7 +24,7 @@ class RPCNodeCheckTask(FeatherTask): async def task(self) -> List[dict]: """Check RPC nodes status""" - from fapi.factory import app, cache + from wowlet_backend.factory import app, cache try: heights = json.loads(await cache.get("blockheights")) diff --git a/fapi/tasks/xmrig.py b/wowlet_backend/tasks/xmrig.py similarity index 95% rename from fapi/tasks/xmrig.py rename to wowlet_backend/tasks/xmrig.py index d79cf7c..a5533af 100644 --- a/fapi/tasks/xmrig.py +++ b/wowlet_backend/tasks/xmrig.py @@ -5,8 +5,8 @@ from dateutil.parser import parse import settings -from fapi.utils import httpget -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import FeatherTask class XmrigTask(FeatherTask): diff --git a/fapi/tasks/xmrto.py b/wowlet_backend/tasks/xmrto.py similarity index 90% rename from fapi/tasks/xmrto.py rename to wowlet_backend/tasks/xmrto.py index 7463b9d..bb4e280 100644 --- a/fapi/tasks/xmrto.py +++ b/wowlet_backend/tasks/xmrto.py @@ -3,8 +3,8 @@ # Copyright (c) 2020, dsc@xmr.pm import settings -from fapi.utils import httpget -from fapi.tasks import FeatherTask +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import FeatherTask class XmrToTask(FeatherTask): diff --git a/fapi/utils.py b/wowlet_backend/utils.py similarity index 95% rename from fapi/utils.py rename to wowlet_backend/utils.py index 73eac73..5234169 100644 --- a/fapi/utils.py +++ b/wowlet_backend/utils.py @@ -35,7 +35,7 @@ def print_banner(): def collect_websocket(func): @wraps(func) async def wrapper(*args, **kwargs): - from fapi.factory import connected_websockets + from wowlet_backend.factory import connected_websockets queue = asyncio.Queue() connected_websockets.add(queue) try: @@ -63,14 +63,14 @@ async def httpget(url: str, json=True, timeout: int = 5, socks5: str = None, rai def random_agent(): - from fapi.factory import user_agents + from wowlet_backend.factory import user_agents return random.choice(user_agents) async def feather_data(): """A collection of data collected by `FeatherTask`, for Feather wallet clients.""" - from fapi.factory import cache, now + from wowlet_backend.factory import cache, now data = await cache.get("data") if data: data = json.loads(data) @@ -110,7 +110,7 @@ def current_worker_thread_is_primary() -> bool: current instance is responsible for the recurring Feather tasks. """ - from fapi.factory import app + from wowlet_backend.factory import app current_pid = os.getpid() parent_pid = os.getppid() diff --git a/fapi/wsparse.py b/wowlet_backend/wsparse.py similarity index 90% rename from fapi/wsparse.py rename to wowlet_backend/wsparse.py index 3ee0335..2f160e2 100644 --- a/fapi/wsparse.py +++ b/wowlet_backend/wsparse.py @@ -21,5 +21,5 @@ class WebsocketParse: year = data.get('year') month = data.get('month') - from fapi.tasks.historical_prices import HistoricalPriceTask + from wowlet_backend.tasks.historical_prices import HistoricalPriceTask return await HistoricalPriceTask.get(year, month)