325 lines
13 KiB
Python
325 lines
13 KiB
Python
|
|
import json
|
||
|
|
import shutil
|
||
|
|
import os
|
||
|
|
import threading
|
||
|
|
from app.views.ViewsBase import *
|
||
|
|
from django.shortcuts import render
|
||
|
|
from app.utils.OSSystem import OSSystem
|
||
|
|
from app.utils.GlobalUtils import g_filepath_settings_json, GlobalUtils
|
||
|
|
from framework.settings import PROJECT_VERSION, PROJECT_FLAG, PROJECT_UA, PROJECT_BUILT, PROJECT_ADMIN_START_TIMESTAMP
|
||
|
|
|
||
|
|
def f_readSettings(lang):
|
||
|
|
try:
|
||
|
|
for encoding in ["utf-8", "gbk"]:
|
||
|
|
try:
|
||
|
|
with open(g_filepath_settings_json, 'r', encoding=encoding) as f:
|
||
|
|
data = json.load(f)
|
||
|
|
# 从 languages 字典中直接获取对应语言的 oem 配置
|
||
|
|
languages = data.get("languages", {})
|
||
|
|
return languages.get(lang, {}).get("oem", {})
|
||
|
|
except Exception as e:
|
||
|
|
g_logger.error("f_readSettings() error: %s" % str(e))
|
||
|
|
return {}
|
||
|
|
except:
|
||
|
|
return {}
|
||
|
|
|
||
|
|
def f_writeSettings(lang, settings_data):
|
||
|
|
for encoding in ["utf-8", "gbk"]:
|
||
|
|
try:
|
||
|
|
with open(g_filepath_settings_json, 'r', encoding=encoding) as f:
|
||
|
|
data = json.load(f)
|
||
|
|
|
||
|
|
# 更新 languages 字典中对应语言的 oem 配置
|
||
|
|
languages = data.get("languages", {})
|
||
|
|
if lang in languages:
|
||
|
|
languages[lang]["oem"] = settings_data
|
||
|
|
|
||
|
|
with open(g_filepath_settings_json, 'w', encoding=encoding) as f:
|
||
|
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
||
|
|
return True
|
||
|
|
except Exception as e:
|
||
|
|
g_logger.error("f_writeSettings() error: %s"%str(e))
|
||
|
|
continue
|
||
|
|
|
||
|
|
def config(request):
|
||
|
|
lang = f_parseRequestLang(request)
|
||
|
|
branding = f_readSettings(lang)
|
||
|
|
cfg = g_config.to_dict()
|
||
|
|
context = {
|
||
|
|
"config": cfg,
|
||
|
|
"branding": branding
|
||
|
|
}
|
||
|
|
return render(request, 'app/system/config.html', context)
|
||
|
|
|
||
|
|
|
||
|
|
def _config_api_payload():
|
||
|
|
data = g_config.to_dict()
|
||
|
|
# 前端习惯 0/1 开关
|
||
|
|
for k in (
|
||
|
|
"autoAddStreamProxy", "isEnableLoginCaptcha", "logDebug", "isEnableUpdatePopup",
|
||
|
|
"telemetryEnabled", "updateCheckEnabled",
|
||
|
|
"isEnableMediaProxyRtmp", "autoStartMedia", "analysisSharedInference",
|
||
|
|
"recordingEnabled",
|
||
|
|
):
|
||
|
|
if k in data:
|
||
|
|
data[k] = 1 if _bool_web(data.get(k)) else 0
|
||
|
|
sip = data.get("sipServer") or {}
|
||
|
|
if "autoInviteAfterRecCateLog" in sip:
|
||
|
|
sip["autoInviteAfterRecCateLog"] = 1 if _bool_web(sip.get("autoInviteAfterRecCateLog")) else 0
|
||
|
|
data["sipServer"] = sip
|
||
|
|
return data
|
||
|
|
|
||
|
|
|
||
|
|
def _bool_web(v):
|
||
|
|
return v is True or v == 1 or str(v).strip().lower() in ("1", "true", "yes")
|
||
|
|
|
||
|
|
|
||
|
|
def api_openConfig(request):
|
||
|
|
ret = False
|
||
|
|
msg = LANG_VIEWS_T(request, "msg_unknown_error")
|
||
|
|
|
||
|
|
if request.method == 'GET':
|
||
|
|
# 加载配置:同时返回基础配置 + OEM 品牌信息
|
||
|
|
__check_ret, __check_msg = f_checkRequestSafe(request)
|
||
|
|
if __check_ret:
|
||
|
|
try:
|
||
|
|
lang = f_parseRequestLang(request)
|
||
|
|
branding = f_readSettings(lang)
|
||
|
|
data = _config_api_payload()
|
||
|
|
ret = True
|
||
|
|
msg = LANG_VIEWS_T(request, "msg_success")
|
||
|
|
res = {
|
||
|
|
"code": 1000,
|
||
|
|
"msg": msg,
|
||
|
|
"data": data,
|
||
|
|
"config": data,
|
||
|
|
"branding": branding
|
||
|
|
}
|
||
|
|
g_logger.info("SystemView.openConfig(GET) ok")
|
||
|
|
return f_responseJson(res)
|
||
|
|
except Exception as e:
|
||
|
|
msg = str(e)
|
||
|
|
else:
|
||
|
|
msg = __check_msg
|
||
|
|
|
||
|
|
elif request.method == 'POST':
|
||
|
|
__check_ret, __check_msg = f_checkRequestSafe(request)
|
||
|
|
if __check_ret:
|
||
|
|
params = f_parsePostParams(request)
|
||
|
|
g_logger.info("SystemView.openConfig() requested")
|
||
|
|
|
||
|
|
try:
|
||
|
|
before = g_config.to_dict(include_secrets=True)
|
||
|
|
g_config.save_from_web(params)
|
||
|
|
notes = GlobalUtils.apply_runtime_config(before)
|
||
|
|
|
||
|
|
ret = True
|
||
|
|
msg = LANG_VIEWS_T(request, "syscfg_save_success")
|
||
|
|
hint_parts = []
|
||
|
|
if "adminPort" in notes:
|
||
|
|
hint_parts.append(LANG_VIEWS_T(request, "syscfg_hint_admin_port"))
|
||
|
|
if "logDebug" in notes:
|
||
|
|
hint_parts.append(LANG_VIEWS_T(request, "syscfg_hint_log_debug"))
|
||
|
|
if "zlm" in notes:
|
||
|
|
hint_parts.append(LANG_VIEWS_T(request, "syscfg_hint_zlm"))
|
||
|
|
if hint_parts:
|
||
|
|
msg = msg + " " + " ".join(hint_parts)
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
msg = str(e)
|
||
|
|
else:
|
||
|
|
msg = __check_msg
|
||
|
|
else:
|
||
|
|
msg = LANG_VIEWS_T(request, "msg_method_not_supported")
|
||
|
|
|
||
|
|
res = {
|
||
|
|
"code": 1000 if ret else 0,
|
||
|
|
"msg": msg
|
||
|
|
}
|
||
|
|
g_logger.info("SystemView.openConfig() res: %s" % str(res))
|
||
|
|
return f_responseJson(res)
|
||
|
|
|
||
|
|
def api_openSaveSettings(request):
|
||
|
|
ret = False
|
||
|
|
msg = LANG_VIEWS_T(request, "msg_unknown_error")
|
||
|
|
|
||
|
|
if request.method == 'POST':
|
||
|
|
__check_ret, __check_msg = f_checkRequestSafe(request)
|
||
|
|
if __check_ret:
|
||
|
|
params = f_parsePostParams(request)
|
||
|
|
g_logger.info("SystemView.openSaveSettings() params: %s" % str(params))
|
||
|
|
|
||
|
|
try:
|
||
|
|
lang = f_parseRequestLang(request)
|
||
|
|
|
||
|
|
branding_name = str(params.get("name", "")).strip()
|
||
|
|
branding_welcome = str(params.get("welcome", "")).strip()
|
||
|
|
branding_logo_url = str(params.get("logo_url", "")).strip()
|
||
|
|
branding_bottom_name = str(params.get("bottom_name", "")).strip()
|
||
|
|
branding_author = str(params.get("author", "")).strip()
|
||
|
|
branding_author_link = str(params.get("author_link", "")).strip()
|
||
|
|
branding_check_version_download_url = str(params.get("check_version_download_url", "")).strip()
|
||
|
|
branding_is_show_author = params.get("is_show_author", False)
|
||
|
|
if isinstance(branding_is_show_author, str):
|
||
|
|
branding_is_show_author = branding_is_show_author.lower() in ['true', '1', 'yes']
|
||
|
|
|
||
|
|
settings_data = {
|
||
|
|
"name": branding_name,
|
||
|
|
"welcome": branding_welcome,
|
||
|
|
"logo_url": branding_logo_url,
|
||
|
|
"bottom_name": branding_bottom_name,
|
||
|
|
"is_show_author": branding_is_show_author,
|
||
|
|
"author": branding_author,
|
||
|
|
"author_link": branding_author_link,
|
||
|
|
"check_version_download_url": branding_check_version_download_url
|
||
|
|
}
|
||
|
|
|
||
|
|
f_writeSettings(lang, settings_data)
|
||
|
|
ret = True
|
||
|
|
msg = LANG_VIEWS_T(request, "syscfg_save_oem_success")
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
msg = str(e)
|
||
|
|
else:
|
||
|
|
msg = __check_msg
|
||
|
|
else:
|
||
|
|
msg = LANG_VIEWS_T(request, "msg_method_not_supported")
|
||
|
|
|
||
|
|
res = {
|
||
|
|
"code": 1000 if ret else 0,
|
||
|
|
"msg": msg
|
||
|
|
}
|
||
|
|
g_logger.info("SystemView.openSaveSettings() res: %s" % str(res))
|
||
|
|
return f_responseJson(res)
|
||
|
|
|
||
|
|
def api_openExportLogs(request):
|
||
|
|
# 导出日志
|
||
|
|
ret = False
|
||
|
|
msg = LANG_VIEWS_T(request, "msg_unknown_error")
|
||
|
|
info = {
|
||
|
|
|
||
|
|
}
|
||
|
|
request_ip = f_parseRequestIp(request)
|
||
|
|
lang = f_parseRequestLang(request)
|
||
|
|
|
||
|
|
export_dir = None
|
||
|
|
if request.method == 'POST':
|
||
|
|
__check_ret, __check_msg = f_checkRequestSafe(request)
|
||
|
|
if __check_ret:
|
||
|
|
try:
|
||
|
|
params = f_parsePostParams(request)
|
||
|
|
g_logger.info("SystemView.openExportLogs() params:%s" % str(params))
|
||
|
|
|
||
|
|
g_gb28181SipServer.log_status()
|
||
|
|
run_errors = []
|
||
|
|
|
||
|
|
# 导出外层文件夹
|
||
|
|
export_dirname = "logs%s-%s-%s" % (PROJECT_VERSION, PROJECT_FLAG, datetime.now().strftime("%Y%m%d%H%M%S"))
|
||
|
|
export_dir = os.path.join(g_config.storageTempDir, export_dirname)
|
||
|
|
export_filename = "%s.xclogs" % export_dirname
|
||
|
|
export_filepath = os.path.join(g_config.storageTempDir, export_filename)
|
||
|
|
|
||
|
|
if not os.path.exists(export_dir):
|
||
|
|
os.makedirs(export_dir)
|
||
|
|
|
||
|
|
osSystem = OSSystem()
|
||
|
|
|
||
|
|
|
||
|
|
try:
|
||
|
|
# 压缩log文件夹->log.tar
|
||
|
|
log_dir = os.path.join(BASE_DIR, "log")
|
||
|
|
if os.path.exists(log_dir):
|
||
|
|
log_tar_filepath = os.path.join(export_dir, "log")
|
||
|
|
shutil.make_archive(log_tar_filepath, 'tar', log_dir)
|
||
|
|
except Exception as e:
|
||
|
|
run_errors.append("export log error:%s" % str(e))
|
||
|
|
|
||
|
|
# 写入config.json, settings.json
|
||
|
|
if os.path.exists(g_filepath_config_json):
|
||
|
|
dst = os.path.join(export_dir, "config.json")
|
||
|
|
shutil.copyfile(g_filepath_config_json, dst)
|
||
|
|
|
||
|
|
if os.path.exists(g_filepath_settings_json):
|
||
|
|
dst = os.path.join(export_dir, "settings.json")
|
||
|
|
shutil.copyfile(g_filepath_settings_json, dst)
|
||
|
|
|
||
|
|
|
||
|
|
if os.path.exists(g_config.mediaStartConfigPath):
|
||
|
|
dst = os.path.join(export_dir, "config.ini")
|
||
|
|
shutil.copyfile(g_config.mediaStartConfigPath, dst)
|
||
|
|
|
||
|
|
allowed_hosts_src = os.path.join(BASE_DIR, ".allowed_hosts")
|
||
|
|
if os.path.exists(allowed_hosts_src):
|
||
|
|
allowed_hosts_dst = os.path.join(export_dir, ".allowed_hosts")
|
||
|
|
shutil.copyfile(allowed_hosts_src, allowed_hosts_dst)
|
||
|
|
|
||
|
|
|
||
|
|
# 写入env.txt
|
||
|
|
export_filepath_env = os.path.join(export_dir, "env.txt")
|
||
|
|
env_f = open(export_filepath_env, 'w', encoding="utf-8")
|
||
|
|
env_f.write("name=%s\n" % PROJECT_UA)
|
||
|
|
env_f.write("built=%s\n" % PROJECT_BUILT)
|
||
|
|
env_f.write("version=%s\n" % PROJECT_VERSION)
|
||
|
|
env_f.write("flag=%s\n" % PROJECT_FLAG)
|
||
|
|
env_f.write("log_filename=%s\n" % export_filename)
|
||
|
|
env_f.write("app_start_date=%s\n" % datetime.fromtimestamp(PROJECT_ADMIN_START_TIMESTAMP).strftime('%Y-%m-%d %H:%M'))
|
||
|
|
env_f.write("current_date=%s\n" % datetime.now().strftime('%Y-%m-%d %H:%M'))
|
||
|
|
env_f.write("system=%s\n" % osSystem.getSystemName())
|
||
|
|
env_f.write("machine=%s\n" % osSystem.getMachineNode())
|
||
|
|
env_f.write("uname_a=%s\n" % osSystem.getMachineUnameA())
|
||
|
|
env_f.write("zlm.threadsLoad=%s\n" % str(g_zlm.getThreadsLoad()))
|
||
|
|
env_f.write("cpu=%s\n" % osSystem.getMachineCpu())
|
||
|
|
env_f.write("nvidia=%s\n" % osSystem.getMachineNvidia())
|
||
|
|
env_f.write("ascend=%s\n" % osSystem.getMachineAscend())
|
||
|
|
env_f.write("rknpu=%s\n" % osSystem.getMachineRknpu())
|
||
|
|
env_f.write("os=%s\n" % str(osSystem.getOSInfo()))
|
||
|
|
env_f.write("os_release=%s\n" % osSystem.getMachineOsRelease())
|
||
|
|
env_f.write("lscpu=%s\n" % osSystem.getMachineLsCpu())
|
||
|
|
env_f.close()
|
||
|
|
|
||
|
|
# 写入online.txt
|
||
|
|
export_filepath_online = os.path.join(export_dir, "online.txt")
|
||
|
|
online_f = open(export_filepath_online, 'w', encoding="utf-8")
|
||
|
|
run_info = {}
|
||
|
|
for k, v in run_info.items():
|
||
|
|
online_f.write("%s=%s\n" % (str(k), str(v)))
|
||
|
|
|
||
|
|
online_f.write("av_log=%s\n" % str(g_database.select("select * from av_log order by id desc limit 100")))
|
||
|
|
online_f.write("run_errors=%s\n" % str(run_errors))
|
||
|
|
online_f.close()
|
||
|
|
|
||
|
|
# 压缩导出文件夹
|
||
|
|
shutil.make_archive(export_filepath.replace(".xclogs", ""), 'tar', export_dir)
|
||
|
|
# 重命名为 .xclogs
|
||
|
|
tar_filepath = export_filepath.replace(".xclogs", ".tar")
|
||
|
|
if os.path.exists(tar_filepath):
|
||
|
|
shutil.move(tar_filepath, export_filepath)
|
||
|
|
|
||
|
|
from app.views.StorageView import issue_download_file_id
|
||
|
|
info["download_file_id"] = issue_download_file_id(export_filename)
|
||
|
|
info["download_filename"] = export_filename
|
||
|
|
ret = True
|
||
|
|
msg = LANG_VIEWS_T(request, "syscfg_export_log_success")
|
||
|
|
except Exception as e:
|
||
|
|
msg = str(e)
|
||
|
|
else:
|
||
|
|
msg = __check_msg
|
||
|
|
else:
|
||
|
|
msg = LANG_VIEWS_T(request, "msg_method_not_supported")
|
||
|
|
|
||
|
|
g_logger.info("export_dir=%s" % str(export_dir))
|
||
|
|
if export_dir:
|
||
|
|
try:
|
||
|
|
if os.path.exists(export_dir):
|
||
|
|
shutil.rmtree(export_dir)
|
||
|
|
except Exception as e:
|
||
|
|
g_logger.error("e=%s" % str(e))
|
||
|
|
|
||
|
|
res = {
|
||
|
|
"code": 1000 if ret else 0,
|
||
|
|
"msg": msg,
|
||
|
|
"info": info
|
||
|
|
}
|
||
|
|
g_logger.info("SystemView.openExportLogs() res:%s" % str(res))
|
||
|
|
return f_responseJson(res)
|