mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-11-29 00:23:07 +00:00
refactor: move ui deployment to it's own file
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional, Tuple
|
||||
|
||||
import requests
|
||||
from typing import Any, Dict
|
||||
|
||||
from freqtrade.constants import USERPATH_STRATEGIES
|
||||
from freqtrade.enums import RunMode
|
||||
@@ -101,80 +99,14 @@ def start_new_strategy(args: Dict[str, Any]) -> None:
|
||||
raise ConfigurationError("`new-strategy` requires --strategy to be set.")
|
||||
|
||||
|
||||
def clean_ui_subdir(directory: Path):
|
||||
if directory.is_dir():
|
||||
logger.info("Removing UI directory content.")
|
||||
|
||||
for p in reversed(list(directory.glob("**/*"))): # iterate contents from leaves to root
|
||||
if p.name in (".gitkeep", "fallback_file.html"):
|
||||
continue
|
||||
if p.is_file():
|
||||
p.unlink()
|
||||
elif p.is_dir():
|
||||
p.rmdir()
|
||||
|
||||
|
||||
def read_ui_version(dest_folder: Path) -> Optional[str]:
|
||||
file = dest_folder / ".uiversion"
|
||||
if not file.is_file():
|
||||
return None
|
||||
|
||||
with file.open("r") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def download_and_install_ui(dest_folder: Path, dl_url: str, version: str):
|
||||
from io import BytesIO
|
||||
from zipfile import ZipFile
|
||||
|
||||
logger.info(f"Downloading {dl_url}")
|
||||
resp = requests.get(dl_url, timeout=req_timeout).content
|
||||
dest_folder.mkdir(parents=True, exist_ok=True)
|
||||
with ZipFile(BytesIO(resp)) as zf:
|
||||
for fn in zf.filelist:
|
||||
with zf.open(fn) as x:
|
||||
destfile = dest_folder / fn.filename
|
||||
if fn.is_dir():
|
||||
destfile.mkdir(exist_ok=True)
|
||||
else:
|
||||
destfile.write_bytes(x.read())
|
||||
with (dest_folder / ".uiversion").open("w") as f:
|
||||
f.write(version)
|
||||
|
||||
|
||||
def get_ui_download_url(version: Optional[str] = None) -> Tuple[str, str]:
|
||||
base_url = "https://api.github.com/repos/freqtrade/frequi/"
|
||||
# Get base UI Repo path
|
||||
|
||||
resp = requests.get(f"{base_url}releases", timeout=req_timeout)
|
||||
resp.raise_for_status()
|
||||
r = resp.json()
|
||||
|
||||
if version:
|
||||
tmp = [x for x in r if x["name"] == version]
|
||||
if tmp:
|
||||
latest_version = tmp[0]["name"]
|
||||
assets = tmp[0].get("assets", [])
|
||||
else:
|
||||
raise ValueError("UI-Version not found.")
|
||||
else:
|
||||
latest_version = r[0]["name"]
|
||||
assets = r[0].get("assets", [])
|
||||
dl_url = ""
|
||||
if assets and len(assets) > 0:
|
||||
dl_url = assets[0]["browser_download_url"]
|
||||
|
||||
# URL not found - try assets url
|
||||
if not dl_url:
|
||||
assets = r[0]["assets_url"]
|
||||
resp = requests.get(assets, timeout=req_timeout)
|
||||
r = resp.json()
|
||||
dl_url = r[0]["browser_download_url"]
|
||||
|
||||
return dl_url, latest_version
|
||||
|
||||
|
||||
def start_install_ui(args: Dict[str, Any]) -> None:
|
||||
from freqtrade.commands.deploy_ui import (
|
||||
clean_ui_subdir,
|
||||
download_and_install_ui,
|
||||
get_ui_download_url,
|
||||
read_ui_version,
|
||||
)
|
||||
|
||||
dest_folder = Path(__file__).parents[1] / "rpc/api_server/ui/installed/"
|
||||
# First make sure the assets are removed.
|
||||
dl_url, latest_version = get_ui_download_url(args.get("ui_version"))
|
||||
|
||||
84
freqtrade/commands/deploy_ui.py
Normal file
84
freqtrade/commands/deploy_ui.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Timeout for requests
|
||||
req_timeout = 30
|
||||
|
||||
|
||||
def clean_ui_subdir(directory: Path):
|
||||
if directory.is_dir():
|
||||
logger.info("Removing UI directory content.")
|
||||
|
||||
for p in reversed(list(directory.glob("**/*"))): # iterate contents from leaves to root
|
||||
if p.name in (".gitkeep", "fallback_file.html"):
|
||||
continue
|
||||
if p.is_file():
|
||||
p.unlink()
|
||||
elif p.is_dir():
|
||||
p.rmdir()
|
||||
|
||||
|
||||
def read_ui_version(dest_folder: Path) -> Optional[str]:
|
||||
file = dest_folder / ".uiversion"
|
||||
if not file.is_file():
|
||||
return None
|
||||
|
||||
with file.open("r") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def download_and_install_ui(dest_folder: Path, dl_url: str, version: str):
|
||||
from io import BytesIO
|
||||
from zipfile import ZipFile
|
||||
|
||||
logger.info(f"Downloading {dl_url}")
|
||||
resp = requests.get(dl_url, timeout=req_timeout).content
|
||||
dest_folder.mkdir(parents=True, exist_ok=True)
|
||||
with ZipFile(BytesIO(resp)) as zf:
|
||||
for fn in zf.filelist:
|
||||
with zf.open(fn) as x:
|
||||
destfile = dest_folder / fn.filename
|
||||
if fn.is_dir():
|
||||
destfile.mkdir(exist_ok=True)
|
||||
else:
|
||||
destfile.write_bytes(x.read())
|
||||
with (dest_folder / ".uiversion").open("w") as f:
|
||||
f.write(version)
|
||||
|
||||
|
||||
def get_ui_download_url(version: Optional[str] = None) -> Tuple[str, str]:
|
||||
base_url = "https://api.github.com/repos/freqtrade/frequi/"
|
||||
# Get base UI Repo path
|
||||
|
||||
resp = requests.get(f"{base_url}releases", timeout=req_timeout)
|
||||
resp.raise_for_status()
|
||||
r = resp.json()
|
||||
|
||||
if version:
|
||||
tmp = [x for x in r if x["name"] == version]
|
||||
if tmp:
|
||||
latest_version = tmp[0]["name"]
|
||||
assets = tmp[0].get("assets", [])
|
||||
else:
|
||||
raise ValueError("UI-Version not found.")
|
||||
else:
|
||||
latest_version = r[0]["name"]
|
||||
assets = r[0].get("assets", [])
|
||||
dl_url = ""
|
||||
if assets and len(assets) > 0:
|
||||
dl_url = assets[0]["browser_download_url"]
|
||||
|
||||
# URL not found - try assets url
|
||||
if not dl_url:
|
||||
assets = r[0]["assets_url"]
|
||||
resp = requests.get(assets, timeout=req_timeout)
|
||||
r = resp.json()
|
||||
dl_url = r[0]["browser_download_url"]
|
||||
|
||||
return dl_url, latest_version
|
||||
@@ -31,7 +31,7 @@ from freqtrade.commands import (
|
||||
start_webserver,
|
||||
)
|
||||
from freqtrade.commands.db_commands import start_convert_db
|
||||
from freqtrade.commands.deploy_commands import (
|
||||
from freqtrade.commands.deploy_ui import (
|
||||
clean_ui_subdir,
|
||||
download_and_install_ui,
|
||||
get_ui_download_url,
|
||||
@@ -612,13 +612,13 @@ def test_start_new_strategy_no_arg(mocker, caplog):
|
||||
|
||||
|
||||
def test_start_install_ui(mocker):
|
||||
clean_mock = mocker.patch("freqtrade.commands.deploy_commands.clean_ui_subdir")
|
||||
clean_mock = mocker.patch("freqtrade.commands.deploy_ui.clean_ui_subdir")
|
||||
get_url_mock = mocker.patch(
|
||||
"freqtrade.commands.deploy_commands.get_ui_download_url",
|
||||
"freqtrade.commands.deploy_ui.get_ui_download_url",
|
||||
return_value=("https://example.com/whatever", "0.0.1"),
|
||||
)
|
||||
download_mock = mocker.patch("freqtrade.commands.deploy_commands.download_and_install_ui")
|
||||
mocker.patch("freqtrade.commands.deploy_commands.read_ui_version", return_value=None)
|
||||
download_mock = mocker.patch("freqtrade.commands.deploy_ui.download_and_install_ui")
|
||||
mocker.patch("freqtrade.commands.deploy_ui.read_ui_version", return_value=None)
|
||||
args = [
|
||||
"install-ui",
|
||||
]
|
||||
@@ -642,13 +642,13 @@ def test_start_install_ui(mocker):
|
||||
|
||||
|
||||
def test_clean_ui_subdir(mocker, tmp_path, caplog):
|
||||
mocker.patch("freqtrade.commands.deploy_commands.Path.is_dir", side_effect=[True, True])
|
||||
mocker.patch("freqtrade.commands.deploy_commands.Path.is_file", side_effect=[False, True])
|
||||
rd_mock = mocker.patch("freqtrade.commands.deploy_commands.Path.rmdir")
|
||||
ul_mock = mocker.patch("freqtrade.commands.deploy_commands.Path.unlink")
|
||||
mocker.patch("freqtrade.commands.deploy_ui.Path.is_dir", side_effect=[True, True])
|
||||
mocker.patch("freqtrade.commands.deploy_ui.Path.is_file", side_effect=[False, True])
|
||||
rd_mock = mocker.patch("freqtrade.commands.deploy_ui.Path.rmdir")
|
||||
ul_mock = mocker.patch("freqtrade.commands.deploy_ui.Path.unlink")
|
||||
|
||||
mocker.patch(
|
||||
"freqtrade.commands.deploy_commands.Path.glob",
|
||||
"freqtrade.commands.deploy_ui.Path.glob",
|
||||
return_value=[Path("test1"), Path("test2"), Path(".gitkeep")],
|
||||
)
|
||||
folder = tmp_path / "uitests"
|
||||
@@ -668,10 +668,10 @@ def test_download_and_install_ui(mocker, tmp_path):
|
||||
file_like_object.seek(0)
|
||||
requests_mock.content = file_like_object.read()
|
||||
|
||||
mocker.patch("requests.get", return_value=requests_mock)
|
||||
mocker.patch("freqtrade.commands.deploy_ui.requests.get", return_value=requests_mock)
|
||||
|
||||
mocker.patch("freqtrade.commands.deploy_commands.Path.is_dir", side_effect=[True, False])
|
||||
wb_mock = mocker.patch("freqtrade.commands.deploy_commands.Path.write_bytes")
|
||||
mocker.patch("freqtrade.commands.deploy_ui.Path.is_dir", side_effect=[True, False])
|
||||
wb_mock = mocker.patch("freqtrade.commands.deploy_ui.Path.write_bytes")
|
||||
|
||||
folder = tmp_path / "uitests_dl"
|
||||
folder.mkdir(exist_ok=True)
|
||||
@@ -693,9 +693,7 @@ def test_get_ui_download_url(mocker):
|
||||
[{"browser_download_url": "http://download.zip"}],
|
||||
]
|
||||
)
|
||||
get_mock = mocker.patch(
|
||||
"freqtrade.commands.deploy_commands.requests.get", return_value=response
|
||||
)
|
||||
get_mock = mocker.patch("freqtrade.commands.deploy_ui.requests.get", return_value=response)
|
||||
x, last_version = get_ui_download_url()
|
||||
assert get_mock.call_count == 2
|
||||
assert last_version == "0.0.1"
|
||||
@@ -718,9 +716,7 @@ def test_get_ui_download_url_direct(mocker):
|
||||
},
|
||||
]
|
||||
)
|
||||
get_mock = mocker.patch(
|
||||
"freqtrade.commands.deploy_commands.requests.get", return_value=response
|
||||
)
|
||||
get_mock = mocker.patch("freqtrade.commands.deploy_ui.requests.get", return_value=response)
|
||||
x, last_version = get_ui_download_url()
|
||||
assert get_mock.call_count == 1
|
||||
assert last_version == "0.0.2"
|
||||
|
||||
Reference in New Issue
Block a user