Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Spotbit as a Specter Plugin #1

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions spotbit-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
__pycache__
.pytest_cache
*.pyc
.env
*.egg-info
.DS_Store
node_modules
btcd-conn.json
elmd-conn.json
prevent_mining
5 changes: 5 additions & 0 deletions spotbit-plugin/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
recursive-include src/ahv15/specterext/spotbit/templates *
recursive-include src/ahv15/specterext/spotbit/static *
recursive-include src/ahv15/specterext/spotbit/*/LC_MESSAGES *.mo
recursive-include src/ahv15/specterext/spotbit/translations/*/LC_MESSAGES *.po
include requirements.txt
53 changes: 53 additions & 0 deletions spotbit-plugin/available_exchanges_currencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import ccxt as ccxt
from bs4 import BeautifulSoup
import requests
r = requests.get("https://github.com/ccxt/ccxt/tree/master/python/ccxt")
soup = BeautifulSoup(r.content, 'html5lib')
links = soup.findAll('a', attrs={'class': 'js-navigation-open Link--primary'})
objects = {}
for i in range(6, len(links)):
try:
objects[links[i].text[0:-3]
] = eval("ccxt." + links[i].text[0:-3] + "()")
except:
print(links[i].text[0:-3] + " is not available.")
continue
exchanges = objects.keys()
currencies = ['USD', 'EUR', 'CAD', 'GBP', 'AUD', 'SEK', 'BRL', 'CZK', 'INR']
possibilities = {}


def get_supported_pair_for(currency, exchange):
result = ''
exchange.load_markets()
market_ids_found = []
for market in exchange.markets_by_id.keys():
if ((market[:len('BTC')].upper() == 'BTC' or market[:len('XBT')].upper() == 'XBT' or market[:len('XXBTZCAD')].upper() == 'XXBTZCAD') and market[-len(currency):].upper() == currency.upper() and (len(market) == (3 + len(currency)) or (len(market) == (4 + len(currency)) and (market[3] == '/' or market[3] == '-' or market[3] == '_')))):
market_ids_found.append(market)
if market_ids_found:
market_id = market_ids_found[0]
market = exchange.markets_by_id[exchange.market_id(market_id)]
if market:
result = market['symbol']
return result


for exchange in exchanges:
if objects[exchange].has['fetchOHLCV']:
try:
ticker = get_supported_pair_for('USD', objects[exchange])
except:
print(exchange + " is not available.")
continue
for currency in currencies:
ticker = get_supported_pair_for(currency, objects[exchange])
if ticker == '' or ticker == 'BTC/USDT': # incorrect id to ticker mapping USD to USDT
continue
if (currency in possibilities.keys()):
possibilities[currency].append([exchange, ticker])
else:
possibilities[currency] = [[exchange, ticker]]

for curr in possibilities.keys():
for exchange in possibilities[curr]:
print(f"{curr}: exchange: {exchange[0]}")
5 changes: 5 additions & 0 deletions spotbit-plugin/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build-system]
requires = [
"cryptoadvance.specter==1.8.1"
]
build-backend = "setuptools.build_meta"
11 changes: 11 additions & 0 deletions spotbit-plugin/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[pytest]
norecursedirs = tests/bitcoin* tests/elements* tests/xtestdata_testextensions
log_format = [%(levelname)8s] %(message)s %(name)s (%(filename)s:%(lineno)s)
addopts = --bitcoind-version v22.0.0 --elementsd-version v0.21.0.2
markers =
slow: mark test as slow.
elm: mark test as elementsd dependent
#log_cli = 1

filterwarnings =
ignore::DeprecationWarning:bitbox02[.*]
2 changes: 2 additions & 0 deletions spotbit-plugin/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cryptoadvance.specter>=1.12.0
ccxt>=1.74.49
25 changes: 25 additions & 0 deletions spotbit-plugin/setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[metadata]
name = ahv15_spotbit
version = 0.0.1
author = ahv15
author_email = [email protected]
description = A small example package
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/ahv15/specterext-spotbit
project_urls =
Bug Tracker = https://github.com/ahv15/specterext-spotbit/issues
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent

[options]
include_package_data=true
package_dir =
= src
packages = find_namespace:
python_requires = >=3.6

[options.packages.find]
where = src
4 changes: 4 additions & 0 deletions spotbit-plugin/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from setuptools import setup

if __name__ == "__main__":
setup()
Empty file.
41 changes: 41 additions & 0 deletions spotbit-plugin/src/ahv15/specterext/spotbit/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from cryptoadvance.specter.cli import entry_point
from cryptoadvance.specter.cli.cli_server import server
import logging
import click

logger = logging.getLogger(__name__)

@click.group()
def cli():
pass

@cli.command()
@click.pass_context
@click.option(
"--host",
default="127.0.0.1",
help="if you specify --host 0.0.0.0 then Spotbit will be available in your local LAN.",
)
@click.option(
"--ssl/--no-ssl",
is_flag=True,
default=False,
help="By default SSL encryption will not be used. Use -ssl to create a self-signed certificate for SSL encryption.",
)
@click.option("--debug/--no-debug", default=None)
@click.option("--filelog/--no-filelog", default=True)
@click.option(
"--config",
default=None,
help="A class which sets reasonable default values.",
)
def start(ctx, host, ssl, debug, filelog, config):
if config == None:
config = "ahv15.specterext.spotbit.config.AppProductionConfig"
ctx.invoke(server, host=host, ssl=ssl, debug=debug, filelog=filelog, port=8080, config=config)

entry_point.add_command(start)

if __name__ == "__main__":
entry_point()

27 changes: 27 additions & 0 deletions spotbit-plugin/src/ahv15/specterext/spotbit/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
Here Configuration of your Extension (and maybe your Application) takes place
"""
import os
from cryptoadvance.specter.config import ProductionConfig as SpecterProductionConfig


class BaseConfig:
''' This is a extension-based Config which is used as Base '''
SPOTBIT_SOMEKEY = "some value"

class ProductionConfig(BaseConfig):
''' This is a extension-based Config for Production '''
pass


class AppProductionConfig(SpecterProductionConfig):
''' The AppProductionConfig class can be used to user this extension as application
'''
# Where should the User endup if he hits the root of that domain?
ROOT_URL_REDIRECT = "/spc/ext/spotbit"
# I guess this is the only extension which should be available?
EXTENSION_LIST = [
"ahv15.specterext.spotbit.service"
]
# You probably also want a different folder here
SPECTER_DATA_FOLDER=os.path.expanduser("~/.spotbit")
84 changes: 84 additions & 0 deletions spotbit-plugin/src/ahv15/specterext/spotbit/controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from flask import redirect, render_template, request, url_for
from flask import current_app as app

from cryptoadvance.specter.specter import Specter
from .service import SpotbitService

from datetime import datetime


spotbit_endpoint = SpotbitService.blueprint


def ext() -> SpotbitService:
''' convenience for getting the extension-object'''
return app.specter.ext["spotbit"]


def specter() -> Specter:
''' convenience for getting the specter-object'''
return app.specter


@spotbit_endpoint.route("/")
def index():
service = ext()
status_info = service.status_info()
return render_template(
"spotbit/index.jinja", status=status_info
)


@spotbit_endpoint.route("/", methods=["POST"])
def index_post():
service = ext()
info = request.form.get('pair', "None")
print("Test")
print(info)
if (info == ""):
service.remove_db()
else:
service.remove_exchange(info.strip('][').split(', '))
status_info = service.status_info()
return render_template(
"spotbit/index.jinja", status=status_info
)


@spotbit_endpoint.route("/hist/<currency>/<exchange>/<date_start>/<date_end>")
def historical_exchange_rate(currency, exchange, date_start, date_end):
service = ext()
return (service.historical_exchange_rate(currency, exchange, date_start, date_end))


@spotbit_endpoint.route("/now/<currency>/<exchange>")
def current_exchange_rate(currency, exchange):
service = ext()
return (service.current_exchange_rate(currency, exchange))


@spotbit_endpoint.route("/settings", methods=["GET"])
def settings_get():
return render_template(
"spotbit/settings.jinja",
)


@spotbit_endpoint.route("/settings", methods=["POST"])
def settings_post():
exchange = request.form.get('exchange', "None")
currency1 = request.form.get('currency1', "None")
currency2 = request.form.get('currency2', "None")
currency3 = request.form.get('currency3', "None")
currency4 = request.form.get('currency4', "None")
currency5 = request.form.get('currency5', "None")
currency6 = request.form.get('currency6', "None")
currency7 = request.form.get('currency7', "None")
currency8 = request.form.get('currency8', "None")
currency9 = request.form.get('currency9', "None")
start_date = request.form.get('start_date', "None")
frequencies = request.form.get('frequencies', "1m")
service = ext()
service.init_table([exchange.lower()], [currency1, currency2, currency3, currency4, currency5, currency6,
currency7, currency8, currency9], frequencies, start_date)
return redirect(url_for(f"{ SpotbitService.get_blueprint_name()}.settings_get"))
Loading