Skip to content

Commit

Permalink
Merge pull request #690 from Drakkar-Software/dev
Browse files Browse the repository at this point in the history
master merge
  • Loading branch information
GuillaumeDSM authored Sep 7, 2022
2 parents bd46b52 + 54926f4 commit 3c2f99e
Show file tree
Hide file tree
Showing 17 changed files with 165 additions and 39 deletions.
2 changes: 1 addition & 1 deletion Services/Interfaces/web_interface/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def register_notifier(notification_key, notifier):

# Override system configuration content types
flask_util.init_content_types()
server_instance.json_encoder = flask_util.Jsonifier
server_instance.json = flask_util.FloatDecimalJSONProvider(server_instance)

# Make WebInterface visible to imports
from tentacles.Services.Interfaces.web_interface.web import WebInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def _handle_package_operation(update_type):
elif update_type == "reset_packages":
packages_operation_result = models.reset_packages()

if packages_operation_result is not None:
if packages_operation_result:
return util.get_rest_reply(flask.jsonify(packages_operation_result))
else:
action = update_type.split("_")[0]
Expand Down Expand Up @@ -100,6 +100,17 @@ def _handle_tentacles_pages_post(update_type):
return _handle_module_operation(update_type)


@advanced_controllers.advanced.route('/install_official_tentacle_packages<use_beta_tentacles>', methods=['POST'])
@login.login_required_when_activated
def install_official_tentacle_packages(use_beta_tentacles):
bundle_url = models.get_official_tentacles_url(use_beta_tentacles == "True")
packages_operation_result = models.install_packages(path_or_url=bundle_url)
if packages_operation_result:
return util.get_rest_reply(flask.jsonify(packages_operation_result))
else:
return util.get_rest_reply(f'Impossible to install tentacles, check the logs for more information.', 500)


@advanced_controllers.advanced.route("/tentacle_packages")
@advanced_controllers.advanced.route('/tentacle_packages', methods=['GET', 'POST'])
@login.active_login_required
Expand Down
16 changes: 6 additions & 10 deletions Services/Interfaces/web_interface/flask_util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,18 @@

from tentacles.Services.Interfaces.web_interface.flask_util import template_filters
from tentacles.Services.Interfaces.web_interface.flask_util.template_filters import (
is_dict,
is_list,
is_bool,
register_template_filters,
)

from tentacles.Services.Interfaces.web_interface.flask_util import jsonifier
from tentacles.Services.Interfaces.web_interface.flask_util.jsonifier import (
Jsonifier,
from tentacles.Services.Interfaces.web_interface.flask_util import json_provider
from tentacles.Services.Interfaces.web_interface.flask_util.json_provider import (
FloatDecimalJSONProvider,
)

__all__ = [
"init_content_types",
"context_processor_register",
"send_and_remove_file",
"is_dict",
"is_list",
"is_bool",
"Jsonifier",
"register_template_filters",
"FloatDecimalJSONProvider",
]
4 changes: 2 additions & 2 deletions Services/Interfaces/web_interface/flask_util/file_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
import tentacles.Services.Interfaces.web_interface.models as models


def send_and_remove_file(file_path, attachment_filename):
def send_and_remove_file(file_path, download_name):
try:
return flask.send_file(file_path, as_attachment=True, attachment_filename=attachment_filename, cache_timeout=0)
return flask.send_file(file_path, as_attachment=True, download_name=download_name, max_age=0)
finally:
# cleanup temp_file
def remove_file(file_path):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
# License along with this library.

import decimal
import flask.json
import flask.json.provider


class Jsonifier(flask.json.JSONEncoder):
class FloatDecimalJSONProvider(flask.json.provider.DefaultJSONProvider):

def default(self, obj):
def dumps(self, obj, **kwargs):
if isinstance(obj, decimal.Decimal):
# Convert decimal instances to strings.
# Convert decimal instances to float.
return float(obj)
return super().default(obj)
return super().dumps(obj, **kwargs)
21 changes: 11 additions & 10 deletions Services/Interfaces/web_interface/flask_util/template_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@
import tentacles.Services.Interfaces.web_interface as web_interface


@web_interface.server_instance.template_filter()
def is_dict(value):
return isinstance(value, dict)
def register_template_filters():
# should only be called after app configuration

@web_interface.server_instance.template_filter()
def is_dict(value):
return isinstance(value, dict)

@web_interface.server_instance.template_filter()
def is_list(value):
return isinstance(value, list)
@web_interface.server_instance.template_filter()
def is_list(value):
return isinstance(value, list)


@web_interface.server_instance.template_filter()
def is_bool(value):
return isinstance(value, bool)
@web_interface.server_instance.template_filter()
def is_bool(value):
return isinstance(value, bool)
2 changes: 2 additions & 0 deletions Services/Interfaces/web_interface/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
)
from tentacles.Services.Interfaces.web_interface.models.tentacles import (
get_tentacles_packages,
get_official_tentacles_url,
call_tentacle_manager,
install_packages,
update_packages,
Expand Down Expand Up @@ -298,6 +299,7 @@
"get_current_run_params",
"get_optimizer_status",
"get_tentacles_packages",
"get_official_tentacles_url",
"call_tentacle_manager",
"install_packages",
"update_packages",
Expand Down
10 changes: 8 additions & 2 deletions Services/Interfaces/web_interface/models/tentacles.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ def _add_version_to_tentacles_package_path(path_or_url, version):
return f"{path_or_url}/{version.replace('.', tentacles_manager_constants.ARTIFACT_VERSION_DOT_REPLACEMENT)}"


def get_official_tentacles_url(use_beta_tentacles) -> str:
return configuration_manager.get_default_tentacles_url(
version=octobot_constants.BETA_TENTACLE_PACKAGE_NAME if use_beta_tentacles else None
)


def install_packages(path_or_url=None, version=None, authenticator=None):
message = "Tentacles installed"
message = "Tentacles installed. Restart your OctoBot to load the new tentacles."
success = True
if path_or_url and version:
path_or_url = _add_version_to_tentacles_package_path(path_or_url, version)
Expand Down Expand Up @@ -93,7 +99,7 @@ def reset_packages():
def update_modules(modules):
success = True
for url in [
configuration_manager.get_default_tentacles_url(),
get_official_tentacles_url(False),
# tentacles_manager_api.get_compiled_tentacles_url(
# octobot_constants.DEFAULT_COMPILED_TENTACLES_URL,
# octobot_constants.TENTACLES_REQUIRED_VERSION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ function register_and_install_package(){

function disable_packages_operations(should_lock=true){
const disabled_attr = 'disabled';
$("#update_tentacles_packages").prop(disabled_attr, should_lock);
$("#install_tentacles_packages").prop(disabled_attr, should_lock);
$("#install_tentacles_packages, #update_tentacles_packages, #install-beta-tentacles, #install-regular-tentacles").prop(disabled_attr, should_lock);
$("#reset_tentacles_packages").prop(disabled_attr, should_lock);
const register_and_install_package_input = $("#register_and_install_package_input");
register_and_install_package_input.prop(disabled_attr, should_lock);
Expand Down Expand Up @@ -143,10 +142,7 @@ function get_selected_modules(){
}

function handle_tentacles_buttons(){
$("#install_tentacles_packages").click(function(){
perform_packages_operation($(this));
});
$("#update_tentacles_packages").click(function(){
$("#install_tentacles_packages, #update_tentacles_packages, #install-beta-tentacles, #install-regular-tentacles").click(function(){
perform_packages_operation($(this));
});
$("#reset_tentacles_packages").click(function(){
Expand Down
2 changes: 1 addition & 1 deletion Services/Interfaces/web_interface/templates/about.html
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ <h2>Support the OctoBot project</h2>
</div>
<br>

<div class="card">
<div class="card" id="beta-program">
<div class="card-header"><h2>OctoBot Beta tester program</h2></div>
<div class="card-body">
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ <h2>
<h5>Logged in as {{ current_logged_in_email }}</h5>
<a class="btn btn-sm btn-outline-warning waves-effect mt-4" href="{{ url_for('community_logout') }}">Logout</a>
{% else %}
<h5>Login and access your OctoBot community account.</h5>
<h5>
Login and access your
{% if is_in_stating_community_env() %}
<span class="badge badge-light">
Beta
</span>
{% endif %}
Astrolab account.
</h5>
<form method=post name="community-login">
<div class="my-4">
{{ form.csrf_token }}
Expand Down
38 changes: 38 additions & 0 deletions Services/Interfaces/web_interface/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@
<h5 class="d-none d-sm-inline"><span class="d-none d-md-inline"><i class="far fa-bell"></i> Good news ! </span>OctoBot version <span update-url="{{ url_for('api.upgrade_version') }}" id="upgradeVersion"></span> is available.</h5><button route="{{ url_for('commands', cmd='update') }}" type="button" class="btn btn-warning waves-effect">Upgrade now <i class="fas fa-cloud-download-alt"></i></button>
</div>
<span id="exchange-specific-data">
{% if is_in_stating_community_env() %}
<div class="card mt-2 mt-md-4">
<div class="card-header"><h2>
Welcome to the OctoBot beta environment
</h2>
</div>
<div class="card-body card-text">
<div class="alert alert-info">
When the beta environment is enabled, you will be connected to the "in development"
version of Astrolab (<a href="{{OCTOBOT_COMMUNITY_URL}}">{{OCTOBOT_COMMUNITY_URL}})</a>. The beta Astrolab has its own accounts and products.
Please login using your beta account.
</div>
<div>
<div>
Beta tentacles with early access features might be available.
</div>
<div>
<button class="btn btn-primary waves-effect" id="install-beta-tentacles"
update-url="{{url_for('advanced.install_official_tentacle_packages', use_beta_tentacles=True)}}">
Install / Update beta tentacles
</button>
<button class="btn btn-outline-primary waves-effect" id="install-regular-tentacles"
update-url="{{url_for('advanced.install_official_tentacle_packages', use_beta_tentacles=False)}}">
Reinstall regular tentacles
</button>
</div>
<div class='progress' id='packages_action_progess_bar' style='display: none;'>
<div class='progress-bar progress-bar-striped progress-bar-animated' role='progressbar' aria-valuenow='100' aria-valuemin='0' aria-valuemax='100' style='width: 100%;'></div>
</div>
</div>
</div>
<div class="card-footer">
You can disable the beta environment and go back to the regular one at anytime from the
<a href="{{ url_for('about', _anchor='beta-program') }}"> about tab</a>.
</div>
</div>
{% endif %}
<div class="card mt-2 mt-md-4">
<div class="card-header"><h2>
Profitability
Expand Down Expand Up @@ -87,4 +124,5 @@ <h5 class="modal-title" id="tutorialModalTitle">Welcome to OctoBot !</h5>
<script src="{{ url_for('static', filename='js/common/custom_elements.js', u=LAST_UPDATED_STATIC_FILES) }}"></script>
<script src="{{ url_for('static', filename='js/common/candlesticks.js', u=LAST_UPDATED_STATIC_FILES) }}"></script>
<script src="{{ url_for('static', filename='js/components/dashboard.js', u=LAST_UPDATED_STATIC_FILES) }}"></script>
<script src="{{ url_for('static', filename='js/components/tentacles_configuration.js', u=LAST_UPDATED_STATIC_FILES) }}"></script>
{% endblock additional_scripts %}
2 changes: 2 additions & 0 deletions Services/Interfaces/web_interface/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import tentacles.Services.Interfaces.web_interface.security as security
import tentacles.Services.Interfaces.web_interface.websockets as websockets
import tentacles.Services.Interfaces.web_interface.plugins as web_interface_plugins
import tentacles.Services.Interfaces.web_interface.flask_util as flask_util
import tentacles.Services.Interfaces.web_interface as web_interface_root
import tentacles.Services.Services_bases as Service_bases

Expand Down Expand Up @@ -149,6 +150,7 @@ def init_flask_plugins(self, server_instance):
Compress(server_instance)

if not WebInterface.IS_FLASK_APP_CONFIGURED:
flask_util.register_template_filters()
# register session secret key
server_instance.secret_key = self.session_secret_key
self._handle_login(server_instance)
Expand Down
1 change: 1 addition & 0 deletions Trading/Exchange/coinex/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .coinex_exchange import Coinex
58 changes: 58 additions & 0 deletions Trading/Exchange/coinex/coinex_exchange.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Drakkar-Software OctoBot-Tentacles
# Copyright (c) Drakkar-Software, All rights reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3.0 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library.
import ccxt.async_support as ccxt
import copy
import math

import ccxt

import octobot_trading.errors
import octobot_trading.enums as trading_enums
import octobot_trading.exchanges as exchanges

import octobot_commons.logging as logging

import octobot_trading.api as trading_api

import octobot_services.interfaces as interfaces

class Coinex(exchanges.SpotCCXTExchange):
DESCRIPTION = ""
MAX_PAGINATION_LIMIT: int = 100

@classmethod
def get_name(cls):
return 'coinex'

@classmethod
def is_supporting_exchange(cls, exchange_candidate_name) -> bool:
return cls.get_name() == exchange_candidate_name


async def get_open_orders(self, symbol=None, since=None, limit=None, **kwargs) -> list:
return await super().get_open_orders(symbol=symbol,
since=since,
limit=self._fix_limit(limit),
**kwargs)

async def get_closed_orders(self, symbol=None, since=None, limit=None, **kwargs) -> list:
return await super().get_closed_orders(symbol=symbol,
since=since,
limit=self._fix_limit(limit),
**kwargs)

def _fix_limit(self, limit: int) -> int:
return min(self.MAX_PAGINATION_LIMIT, limit)
6 changes: 6 additions & 0 deletions Trading/Exchange/coinex/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"version": "1.2.0",
"origin_package": "OctoBot-Default-Tentacles",
"tentacles": ["Coinex"],
"tentacles-requirements": []
}
1 change: 1 addition & 0 deletions Trading/Exchange/coinex/resources/coinex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coinex is a basic SpotExchange adaptation for coinex exchange.

0 comments on commit 3c2f99e

Please sign in to comment.