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

fix: 修复接口文档异常,增加服务启动端口检测 #47

Merged
merged 1 commit into from
Oct 17, 2024
Merged
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
32 changes: 23 additions & 9 deletions common/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# filename : utils
# author : ly_13
# date : 6/2/2023
import datetime
import logging
import re
from collections import OrderedDict
Expand Down Expand Up @@ -119,30 +120,43 @@ def get_query_post_pks(request):


class PrintLogFormat(object):
def __init__(self, base_str=''):
def __init__(self, base_str='', title_width=80, body_width=60, logger_enable=True):
self.base_str = base_str
self.logger_enable = logger_enable
self.title_width = title_width
self.body_width = body_width
self.bold_error = make_style(opts=('bold',), fg='magenta')
self._info = make_style(fg='green')
self._error = make_style(fg='red')
self._warning = make_style(fg='yellow')
self._debug = make_style(fg='blue')

def __print(self, title, body):
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"{now} {title}" if self.title_width < 1 else '{0: <{title_width}}'.format(f"{now} {title}",
title_width=self.title_width),
body if self.body_width < 1 else '{0: >{body_width}}'.format(body, body_width=self.body_width))

def info(self, msg, *args, **kwargs):
logger.info(f"{self.base_str} {msg}", *args, **kwargs)
if self.logger_enable:
logger.info(f"{self.base_str} {msg}", *args, **kwargs)
if logger.isEnabledFor(logging.INFO):
print('{0: <50}'.format(self.bold_error(self.base_str)), '{0: >60}'.format(self._info(msg)))
self.__print(self.bold_error(self.base_str), self._info(msg))

def error(self, msg, *args, **kwargs):
logger.error(f"{self.base_str} {msg}", *args, **kwargs)
if self.logger_enable:
logger.error(f"{self.base_str} {msg}", *args, **kwargs)
if logger.isEnabledFor(logging.ERROR):
print('{0: <50}'.format(self.bold_error(self.base_str)), '{0: >60}'.format(self._error(msg)))
self.__print(self.bold_error(self.base_str), self._error(msg))

def debug(self, msg, *args, **kwargs):
logger.debug(f"{self.base_str} {msg}", *args, **kwargs)
if self.logger_enable:
logger.debug(f"{self.base_str} {msg}", *args, **kwargs)
if logger.isEnabledFor(logging.DEBUG):
print('{0: <50}'.format(self.bold_error(self.base_str)), '{0: >60}'.format(self._debug(msg)))
self.__print(self.bold_error(self.base_str), self._debug(msg))

def warning(self, msg, *args, **kwargs):
logger.warning(f"{self.base_str} {msg}", *args, **kwargs)
if self.logger_enable:
logger.warning(f"{self.base_str} {msg}", *args, **kwargs)
if logger.isEnabledFor(logging.WARNING):
print('{0: <50}'.format(self.bold_error(self.base_str)), '{0: >60}'.format(self._warning(msg)))
self.__print(self.bold_error(self.base_str), self._warning(msg))
37 changes: 25 additions & 12 deletions common/management/commands/services/hands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
import sys
import time

import psutil
from django.conf import settings
from django.core import management
from django.db.utils import OperationalError

from common.core.utils import PrintLogFormat
from common.utils.file import download_file

HTTP_HOST = settings.HTTP_BIND_HOST or '127.0.0.1'
Expand All @@ -19,38 +21,48 @@
LOG_DIR = os.path.join(BASE_DIR, 'logs')
TMP_DIR = os.path.join(LOG_DIR, 'tmp')

logger = PrintLogFormat(f"xAdmin API Server", title_width=30, body_width=0)


def check_port_is_used(port):
for proc in psutil.process_iter():
for con in proc.connections():
if con.status == 'LISTEN' and con.laddr.port == port:
logger.error(f"Check LISTEN PORT {port} failed, Address already in use")
sys.exit(10)


def check_database_connection():
for i in range(60):
print(f"Check database connection: {i}")
logger.info(f"Check database connection: {i}")
try:
management.call_command('check', '--database', 'default')
print("Database connect success")
logger.info("Database connect success")
return
except OperationalError:
print('Database not setup, retry')
logger.warning('Database not setup, retry')
except Exception as exc:
print('Unexpect error occur: {}'.format(str(exc)))
logger.warning('Unexpect error occur: {}'.format(str(exc)))
time.sleep(1)
print("Connection database failed, exit")
logger.error("Connection database failed, exit")
sys.exit(10)


def perform_db_migrate():
print("Check database structure change ...")
print("Migrate model change to database ...")
logger.info("Check database structure change ...")
logger.info("Migrate model change to database ...")
try:
management.call_command('migrate')
except Exception as e:
print(f'Perform migrate failed, {e} exit')
logger.error(f'Perform migrate failed, {e} exit')
sys.exit(11)


def collect_static():
print("Collect static files")
logger.info("Collect static files")
try:
management.call_command('collectstatic', '--no-input', '-c', verbosity=0, interactive=False)
print("Collect static files done")
logger.info("Collect static files done")
except:
pass

Expand All @@ -61,7 +73,7 @@ def compile_i18n_file():
# return
os.chdir(os.path.join(BASE_DIR))
management.call_command('compilemessages', verbosity=0)
print("Compile i18n files done")
logger.info("Compile i18n files done")


def download_ip_db(force=False):
Expand All @@ -74,7 +86,7 @@ def download_ip_db(force=False):
path = os.path.join(db_base_dir, *p)
if not force and os.path.isfile(path) and os.path.getsize(path) > 1000:
continue
print("Download ip db: {}".format(path))
logger.info("Download ip db: {}".format(path))
download_file(src, path)


Expand All @@ -89,6 +101,7 @@ def prepare():
check_database_connection()
collect_static()
compile_i18n_file()
check_port_is_used(HTTP_PORT)
perform_db_migrate()
expire_caches()
download_ip_db()
27 changes: 14 additions & 13 deletions common/swagger/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,22 @@ def map_serializer_field(self, auto_schema, direction):
attrs: List = self.target.attrs

obj = {}
for attr in attrs:
if not source_model or not field_mapping:
obj[attr] = build_basic_type(OpenApiTypes.STR)
else:
field = get_model_field(source_model, 'id' if attr == 'pk' else attr)
if field is None:
if isinstance(attrs, (list, set)):
for attr in attrs:
if not source_model or not field_mapping:
obj[attr] = build_basic_type(OpenApiTypes.STR)
else:
try:
field_class, field_kwargs = ms.build_standard_field(attr, field)
obj[attr] = auto_schema._map_serializer_field(field_class(**field_kwargs), direction)
except Exception as e:
logger.warning(f"get filed {attr} {field} auto schema error: {e}")
if 'label' not in attrs:
obj["label"] = build_basic_type(OpenApiTypes.STR)
field = get_model_field(source_model, 'id' if attr == 'pk' else attr)
if field is None:
obj[attr] = build_basic_type(OpenApiTypes.STR)
else:
try:
field_class, field_kwargs = ms.build_standard_field(attr, field)
obj[attr] = auto_schema._map_serializer_field(field_class(**field_kwargs), direction)
except Exception as e:
logger.warning(f"get filed {attr} {field} auto schema error: {e}")
if 'label' not in attrs:
obj["label"] = build_basic_type(OpenApiTypes.STR)
return build_object_type(obj)


Expand Down
6 changes: 5 additions & 1 deletion common/utils/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import threading
import time

import redis
from django.core.cache import cache
from redis.client import PubSub

Expand All @@ -13,6 +14,7 @@

def get_redis_client(db=0):
client = cache.client.get_client()
assert isinstance(client, redis.Redis)
return client


Expand Down Expand Up @@ -45,6 +47,7 @@ def __init__(self, pb: RedisPubSub, sub: PubSub):
self.ch = pb.ch
self.sub = sub
self.unsubscribed = False
logger.info("Subscribed to channel: {}".format(sub))

def _handle_msg(self, _next, error, complete):
"""
Expand Down Expand Up @@ -103,10 +106,11 @@ def keep_handle_msg(self, _next, error, complete):

def unsubscribe(self):
self.unsubscribed = True
logger.info("Unsubscribed from channel: {}".format(self.sub))
try:
self.sub.close()
except Exception as e:
logger.debug('Unsubscribe msg error: {}'.format(e))
logger.warning('Unsubscribe msg error: {}'.format(e))

def retry(self, _next, error, complete):
logger.info('Retry subscribe channel: {}'.format(self.ch))
Expand Down
6 changes: 3 additions & 3 deletions locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-16 12:28+0800\n"
"POT-Creation-Date: 2024-10-17 14:34+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -24,7 +24,7 @@ msgid ""
msgstr ""

#: common/core/auth.py:23 common/core/filter.py:202 common/core/filter.py:210
#: common/core/permission.py:110
#: common/core/permission.py:111
msgid "Unauthorized authentication"
msgstr ""

Expand Down Expand Up @@ -119,7 +119,7 @@ msgstr ""
msgid "Operation successful. Batch deleted {} data"
msgstr ""

#: common/core/permission.py:108
#: common/core/permission.py:109
msgid "Permission denied"
msgstr ""

Expand Down
6 changes: 3 additions & 3 deletions locale/zh/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-16 12:28+0800\n"
"POT-Creation-Date: 2024-10-17 14:34+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -23,7 +23,7 @@ msgid ""
msgstr "任务监控系统不可用,请联系管理员"

#: common/core/auth.py:23 common/core/filter.py:202 common/core/filter.py:210
#: common/core/permission.py:110
#: common/core/permission.py:111
msgid "Unauthorized authentication"
msgstr "未授权"

Expand Down Expand Up @@ -118,7 +118,7 @@ msgstr "操作失败,主键列表不存在"
msgid "Operation successful. Batch deleted {} data"
msgstr "操作成功,批量删除 {} 条数据"

#: common/core/permission.py:108
#: common/core/permission.py:109
msgid "Permission denied"
msgstr "权限拒绝"

Expand Down