diff --git a/.gitignore b/.gitignore index e8f045b1..4cd33da8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ __pycache__ .idea logs .venv -.vscode \ No newline at end of file +.vscode +.pytest_cache \ No newline at end of file diff --git a/appmanage/api/service/db.py b/appmanage/api/service/db.py index c7072f7d..f09c4b3d 100644 --- a/appmanage/api/service/db.py +++ b/appmanage/api/service/db.py @@ -1,9 +1,8 @@ -from fastapi import FastAPI -from pydantic import BaseModel +import sqlite3 + from api.exception.command_exception import CommandException from api.utils import const -from api.model.user import User -import sqlite3 + def dict_factory(cursor, row): d = {} diff --git a/appmanage/api/service/manage.py b/appmanage/api/service/manage.py index b02504c5..22311421 100644 --- a/appmanage/api/service/manage.py +++ b/appmanage/api/service/manage.py @@ -1,33 +1,19 @@ -from ast import Constant -import os -import io -import sys -import platform -import shutil -import time -import subprocess import requests import json -import datetime -import socket import re -from threading import Thread + +from redis import Redis +from rq import Queue +from rq.registry import StartedJobRegistry, FinishedJobRegistry, DeferredJobRegistry, FailedJobRegistry, ScheduledJobRegistry, CanceledJobRegistry + from api.utils import shell_execute, docker, const from api.model.app import App from api.service import db -from api.model.response import Response from api.model.config import Config from api.model.status_reason import StatusReason from api.utils.log import myLogger -from redis import Redis -from rq import Queue, Worker, Connection -from rq.registry import StartedJobRegistry, FinishedJobRegistry, DeferredJobRegistry, FailedJobRegistry, ScheduledJobRegistry, CanceledJobRegistry from api.exception.command_exception import CommandException -from apscheduler.schedulers.background import BackgroundScheduler -from apscheduler.triggers.date import DateTrigger -from apscheduler.triggers.cron import CronTrigger -from apscheduler.triggers.interval import IntervalTrigger -from apscheduler.events import EVENT_SCHEDULER_PAUSED, EVENT_SCHEDULER_RESUMED,EVENT_SCHEDULER_STARTED,EVENT_SCHEDULER_SHUTDOWN + # 指定 Redis 容器的主机名和端口 redis_conn = Redis(host='websoft9-redis', port=6379) @@ -141,16 +127,18 @@ def AppStoreUpdate(): myLogger.info_logger("You click update appstore, but not need to update") # 获取 update info -def get_update_list(): +def get_update_list(url: str=None): local_path = '/data/apps/websoft9/version.json' - local_version = "0" + artifact_url = const.ARTIFACT_URL + if url: + artifact_url = url try: op = shell_execute.execute_command_output_all("cat " + local_path)['result'] local_version = json.loads(op)['VERSION'] except: local_version = "0.0.0" - version_cmd = "wget -O version.json " + const.ARTIFACT_URL + "/version.json && cat version.json" + version_cmd = f"wget -O version.json {artifact_url}/version.json && cat version.json" latest = shell_execute.execute_command_output_all(version_cmd)['result'] version = json.loads(latest)['VERSION'] ret = {} @@ -161,8 +149,8 @@ def get_update_list(): if compared_version(local_version, version) == -1: ret['update'] = True - cmd = "wget -O CHANGELOG.md " + const.ARTIFACT_URL + "/CHANGELOG.md && head -n 20 CHANGELOG.md " - change_log_contents = shell_execute.execute_command_output_all(cmd)['result'] + cmd = f"wget -O CHANGELOG.md {artifact_url}/CHANGELOG.md && head -n 20 CHANGELOG.md" + change_log_contents = shell_execute.execute_command_output(cmd) change_log = change_log_contents.split('## ')[1].split('\n') date = change_log[0].split()[-1] for change in change_log[1:]: diff --git a/appmanage/api/utils/docker.py b/appmanage/api/utils/docker.py index bca2b28a..cbce18b2 100644 --- a/appmanage/api/utils/docker.py +++ b/appmanage/api/utils/docker.py @@ -1,9 +1,6 @@ -import os, io, sys, platform, shutil, time, json, datetime, psutil -import re, docker, requests -from api.utils import shell_execute -from dotenv import load_dotenv, find_dotenv -import dotenv -from pathlib import Path +import json, psutil +import re + from api.utils.log import myLogger from api.utils import shell_execute, const from api.exception.command_exception import CommandException diff --git a/appmanage/api/utils/files.py b/appmanage/api/utils/files.py index 53eed1e7..25044b06 100644 --- a/appmanage/api/utils/files.py +++ b/appmanage/api/utils/files.py @@ -3,7 +3,6 @@ from api.utils.helper import Singleton # This class is add/modify/list/delete item to item=value(键值对) model settings file -__all__ = ['settings'] class SettingsFile(object): diff --git a/appmanage/api/utils/shell_execute.py b/appmanage/api/utils/shell_execute.py index 7aa7a2ee..889544e5 100644 --- a/appmanage/api/utils/shell_execute.py +++ b/appmanage/api/utils/shell_execute.py @@ -1,5 +1,6 @@ #!/usr/bin/python3 -import os, io, sys, platform, shutil, time, subprocess, json, datetime +import subprocess + from api.utils.log import myLogger from api.exception.command_exception import CommandException from api.utils import const @@ -26,11 +27,11 @@ def execute_command_output_all(cmd_str): if process.returncode == 0 and 'Fail' not in process.stdout and 'fail' not in process.stdout and 'Error' not in process.stdout and 'error' not in process.stdout: - return {"code": "0", "result": process.stdout,} + return {"code": "0", "result": process.stdout} else: myLogger.info_logger("Failed to execute cmd, output failed result") myLogger.info_logger(process) - raise CommandException(const.ERROR_SERVER_COMMAND,"Docker returns the original error", process.stderr) + raise CommandException(const.ERROR_SERVER_COMMAND, "Docker returns the original error", process.stderr) diff --git a/appmanage/api/v1/api.py b/appmanage/api/v1/api.py index c8430e37..ce9ad256 100644 --- a/appmanage/api/v1/api.py +++ b/appmanage/api/v1/api.py @@ -1,6 +1,6 @@ from fastapi import APIRouter -from api.v1.routers import health, apps +from .routers import health, apps def get_api(): diff --git a/appmanage/api/v1/routers/apps.py b/appmanage/api/v1/routers/apps.py index 61f377b5..61eedcee 100644 --- a/appmanage/api/v1/routers/apps.py +++ b/appmanage/api/v1/routers/apps.py @@ -1,15 +1,12 @@ -from typing import Optional, List +from typing import Optional -from fastapi import APIRouter, status, Depends, Query, Request -from pydantic import BaseModel, Field +from fastapi import APIRouter, Query, Request from starlette.responses import JSONResponse -import os, io, sys, platform, shutil, time, subprocess, json, datetime -from api.model.app import App from api.model.response import Response from api.service import manage, db -from api.utils import shell_execute, const from api.utils.log import myLogger +from api.utils import const from api.exception.command_exception import CommandException from api.settings.settings import settings diff --git a/appmanage/main.py b/appmanage/main.py index 33000e6b..79eae111 100644 --- a/appmanage/main.py +++ b/appmanage/main.py @@ -13,7 +13,6 @@ from fastapi.openapi.docs import ( import api.v1.api as api_router_v1 from api.utils.log import myLogger -from api.utils import shell_execute from api.settings.settings import settings diff --git a/appmanage/requirements.txt b/appmanage/requirements.txt index 267299d0..d1d8c062 100644 --- a/appmanage/requirements.txt +++ b/appmanage/requirements.txt @@ -5,4 +5,6 @@ apscheduler docker psutil gunicorn -python-dotenv \ No newline at end of file +python-dotenv +pytest +httpx \ No newline at end of file diff --git a/appmanage/test_main.py b/appmanage/test_main.py new file mode 100644 index 00000000..a484758c --- /dev/null +++ b/appmanage/test_main.py @@ -0,0 +1,16 @@ +from unittest.mock import patch + +from fastapi.testclient import TestClient + + +from .main import app + +client = TestClient(app) + +# current not used, because the project layout is not right. + +@patch("api.v1.routers.apps.manage") +def test_app_update_list(manage): + manage.get_update_list.return_value = {'date': '', 'content': ''} + response = client.get("/AppUpdateList") + assert response.status_code == 200