Merge branch 'main' of https://gitee.com/wg123/video-gen
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
from sqlalchemy import select, update
|
from sqlalchemy import select, update
|
||||||
@@ -15,42 +14,12 @@ from app.models.user_oauth_account import UserOAuthAccount
|
|||||||
from app.models.pre_test_template import PreTestTemplate
|
from app.models.pre_test_template import PreTestTemplate
|
||||||
from app.utils.id_gen import generate_id
|
from app.utils.id_gen import generate_id
|
||||||
from app.utils.douyinApi import DouyinApi
|
from app.utils.douyinApi import DouyinApi
|
||||||
|
from app.utils.logger import get_logger
|
||||||
|
|
||||||
import os
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
|
|
||||||
LOG_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "logs")
|
logger = get_logger("upload_queue", "upload_queue")
|
||||||
|
|
||||||
os.makedirs(LOG_DIR, exist_ok=True)
|
|
||||||
|
|
||||||
logger = logging.getLogger("upload_queue")
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
|
|
||||||
class DailyRotatingFileHandler(logging.FileHandler):
|
|
||||||
def __init__(self, directory, encoding=None):
|
|
||||||
self.directory = directory
|
|
||||||
filename = self._get_log_filename()
|
|
||||||
super().__init__(filename, encoding=encoding)
|
|
||||||
|
|
||||||
def _get_log_filename(self):
|
|
||||||
return os.path.join(self.directory, f"upload_queue-{datetime.now(timezone.utc).strftime('%Y-%m-%d')}.log")
|
|
||||||
|
|
||||||
def emit(self, record):
|
|
||||||
current_filename = self._get_log_filename()
|
|
||||||
if self.baseFilename != current_filename:
|
|
||||||
self.close()
|
|
||||||
self.baseFilename = current_filename
|
|
||||||
self.stream = self._open()
|
|
||||||
super().emit(record)
|
|
||||||
|
|
||||||
|
|
||||||
if not logger.handlers:
|
|
||||||
handler = DailyRotatingFileHandler(LOG_DIR, encoding="utf-8")
|
|
||||||
handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s", "%Y-%m-%d %H:%M:%S"))
|
|
||||||
logger.addHandler(handler)
|
|
||||||
|
|
||||||
douyin_api = DouyinApi()
|
douyin_api = DouyinApi()
|
||||||
|
|
||||||
#上传素材队列,处理上传素材的任务
|
#上传素材队列,处理上传素材的任务
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from sqlalchemy import select, update
|
from sqlalchemy import select, update
|
||||||
@@ -11,38 +9,9 @@ from app.models.base import async_session
|
|||||||
from app.models.resources_material import ResourcesMaterial
|
from app.models.resources_material import ResourcesMaterial
|
||||||
from app.models.user_oauth import UserOAuth
|
from app.models.user_oauth import UserOAuth
|
||||||
from app.utils.douyinApi import DouyinApi
|
from app.utils.douyinApi import DouyinApi
|
||||||
|
from app.utils.logger import get_logger
|
||||||
|
|
||||||
LOG_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "logs")
|
logger = get_logger("pre_test_result_task", "pre_test_result_task")
|
||||||
os.makedirs(LOG_DIR, exist_ok=True)
|
|
||||||
|
|
||||||
#前测结果和上传素材属于一种任务,放到一起日志里边
|
|
||||||
logger = logging.getLogger("upload_queue")
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
|
|
||||||
class DailyRotatingFileHandler(logging.FileHandler):
|
|
||||||
def __init__(self, directory, encoding=None):
|
|
||||||
self.directory = directory
|
|
||||||
filename = self._get_log_filename()
|
|
||||||
super().__init__(filename, encoding=encoding)
|
|
||||||
|
|
||||||
def _get_log_filename(self):
|
|
||||||
return os.path.join(self.directory, f"pre_test_result_task-{datetime.now(timezone.utc).strftime('%Y-%m-%d')}.log")
|
|
||||||
|
|
||||||
def emit(self, record):
|
|
||||||
current_filename = self._get_log_filename()
|
|
||||||
if self.baseFilename != current_filename:
|
|
||||||
self.close()
|
|
||||||
self.baseFilename = current_filename
|
|
||||||
self.stream = self._open()
|
|
||||||
super().emit(record)
|
|
||||||
|
|
||||||
|
|
||||||
if not logger.handlers:
|
|
||||||
handler = DailyRotatingFileHandler(LOG_DIR, encoding="utf-8")
|
|
||||||
handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s", "%Y-%m-%d %H:%M:%S"))
|
|
||||||
logger.addHandler(handler)
|
|
||||||
|
|
||||||
douyin_api = DouyinApi()
|
douyin_api = DouyinApi()
|
||||||
|
|
||||||
#获取前测结果并更新数据库,计划任务,每2分钟执行一次
|
#获取前测结果并更新数据库,计划任务,每2分钟执行一次
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ from datetime import datetime, timedelta, timezone
|
|||||||
import asyncio
|
import asyncio
|
||||||
import httpx
|
import httpx
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
from logging.handlers import TimedRotatingFileHandler
|
|
||||||
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
@@ -14,37 +11,10 @@ from app.models.user_oauth_app import UserOAuthApp
|
|||||||
from app.models.base import async_session
|
from app.models.base import async_session
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
from app.utils.redis import get_redis
|
from app.utils.redis import get_redis
|
||||||
|
from app.utils.logger import get_logger
|
||||||
|
|
||||||
REDIS_KEY = "douyin:tokens"
|
REDIS_KEY = "douyin:tokens"
|
||||||
|
logger = get_logger("token_refresh", "token_refresh")
|
||||||
LOG_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "logs")
|
|
||||||
|
|
||||||
os.makedirs(LOG_DIR, exist_ok=True)
|
|
||||||
|
|
||||||
logger = logging.getLogger("token_refresh")
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
def get_log_filename():
|
|
||||||
return os.path.join(LOG_DIR, f"token_refresh-{datetime.now().strftime('%Y-%m-%d')}.log")
|
|
||||||
|
|
||||||
class DailyRotatingFileHandler(logging.FileHandler):
|
|
||||||
def __init__(self, directory, encoding=None):
|
|
||||||
self.directory = directory
|
|
||||||
filename = get_log_filename()
|
|
||||||
super().__init__(filename, encoding=encoding)
|
|
||||||
|
|
||||||
def emit(self, record):
|
|
||||||
current_filename = get_log_filename()
|
|
||||||
if self.baseFilename != current_filename:
|
|
||||||
self.close()
|
|
||||||
self.baseFilename = current_filename
|
|
||||||
self.stream = self._open()
|
|
||||||
super().emit(record)
|
|
||||||
|
|
||||||
handler = DailyRotatingFileHandler(LOG_DIR, encoding="utf-8")
|
|
||||||
handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s", "%Y-%m-%d %H:%M:%S"))
|
|
||||||
|
|
||||||
logger.addHandler(handler)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ from app.models.user_oauth import UserOAuth
|
|||||||
from app.models.user_oauth_app import UserOAuthApp
|
from app.models.user_oauth_app import UserOAuthApp
|
||||||
from app.models.base import async_session
|
from app.models.base import async_session
|
||||||
from app.utils.redis import get_redis
|
from app.utils.redis import get_redis
|
||||||
|
from app.utils.logger import get_logger
|
||||||
|
|
||||||
|
logger = get_logger("douyin_request", "douyin_request")
|
||||||
|
|
||||||
|
|
||||||
class DouyinRequest:
|
class DouyinRequest:
|
||||||
@@ -244,8 +247,6 @@ class DouyinRequest:
|
|||||||
await asyncio.sleep(i * 10)
|
await asyncio.sleep(i * 10)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
res = json.dumps(data) if 'data' in locals() else ''
|
|
||||||
|
|
||||||
options_log = {}
|
options_log = {}
|
||||||
if options:
|
if options:
|
||||||
for key, value in options.items():
|
for key, value in options.items():
|
||||||
@@ -254,10 +255,31 @@ class DouyinRequest:
|
|||||||
else:
|
else:
|
||||||
options_log[key] = value
|
options_log[key] = value
|
||||||
|
|
||||||
raise RuntimeError(
|
res = json.dumps(data) if 'data' in locals() else ''
|
||||||
f'DouYin API request failed after 5 retries. '
|
|
||||||
f'url:{url};oauthId:{oauth_id};options:{json.dumps(options_log)};response:{res}'
|
logger.error(
|
||||||
|
f'DouYin API request failed after {request_count} retries. '
|
||||||
|
f'url:{url};method:{method};oauth_id:{oauth_id};options:{json.dumps(options_log)};response:{res}'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if 'data' in locals() and data.get('code', 0) != 0:
|
||||||
|
raise ValueError(f'接口返回错误[code:{data.get("code", "接口编码")}]{data.get("message", "接口返回错误")}')
|
||||||
|
else:
|
||||||
|
raise ValueError('网络错误,稍后重试。')
|
||||||
|
|
||||||
|
# options_log = {}
|
||||||
|
# if options:
|
||||||
|
# for key, value in options.items():
|
||||||
|
# if key == 'files':
|
||||||
|
# options_log[key] = {k: (v[0], 'bytes_content', v[2]) for k, v in value.items()}
|
||||||
|
# else:
|
||||||
|
# options_log[key] = value
|
||||||
|
# raise RuntimeError(
|
||||||
|
# f'DouYin API request failed after 5 retries. '
|
||||||
|
# f'url:{url};oauthId:{oauth_id};options:{json.dumps(options_log)};response:{res}'
|
||||||
|
# )
|
||||||
|
# if code != 0:
|
||||||
|
# raise ValueError(f'response:{res}')
|
||||||
|
|
||||||
# 无token请求
|
# 无token请求
|
||||||
async def request_with_context(
|
async def request_with_context(
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
def get_logger(name: str, log_filename: str) -> logging.Logger:
|
||||||
|
"""
|
||||||
|
创建并配置一个每日滚动的日志记录器
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: 日志记录器名称
|
||||||
|
log_filename: 日志文件名(不含日期和扩展名)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
配置好的日志记录器对象
|
||||||
|
"""
|
||||||
|
logger = logging.getLogger(name)
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
if logger.handlers:
|
||||||
|
return logger
|
||||||
|
|
||||||
|
LOG_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "logs")
|
||||||
|
os.makedirs(LOG_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
class DailyRotatingFileHandler(logging.FileHandler):
|
||||||
|
def __init__(self, directory, filename_prefix, encoding=None):
|
||||||
|
self.directory = directory
|
||||||
|
self.filename_prefix = filename_prefix
|
||||||
|
filename = self._get_log_filename()
|
||||||
|
super().__init__(filename, encoding=encoding)
|
||||||
|
|
||||||
|
def _get_log_filename(self):
|
||||||
|
return os.path.join(self.directory, f"{self.filename_prefix}-{datetime.now().strftime('%Y-%m-%d')}.log")
|
||||||
|
|
||||||
|
def emit(self, record):
|
||||||
|
current_filename = self._get_log_filename()
|
||||||
|
if self.baseFilename != current_filename:
|
||||||
|
self.close()
|
||||||
|
self.baseFilename = current_filename
|
||||||
|
self.stream = self._open()
|
||||||
|
super().emit(record)
|
||||||
|
|
||||||
|
handler = DailyRotatingFileHandler(LOG_DIR, log_filename, encoding="utf-8")
|
||||||
|
handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s", "%Y-%m-%d %H:%M:%S"))
|
||||||
|
|
||||||
|
logger.addHandler(handler)
|
||||||
|
|
||||||
|
return logger
|
||||||
-442
File diff suppressed because one or more lines are too long
-442
File diff suppressed because one or more lines are too long
+106
-106
File diff suppressed because one or more lines are too long
Vendored
+36
-40
@@ -1,41 +1,37 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
||||||
<title>民众智创</title>
|
<title>民众智创</title>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
var cached = localStorage.getItem('siteInfo');
|
var cached = localStorage.getItem('siteInfo');
|
||||||
if (cached) {
|
if (cached) {
|
||||||
try {
|
try {
|
||||||
var info = JSON.parse(cached);
|
var info = JSON.parse(cached);
|
||||||
if (info.siteName) {
|
if (info.siteName) {
|
||||||
document.title = info.siteName;
|
document.title = info.siteName;
|
||||||
}
|
}
|
||||||
if (info.siteLogo) {
|
if (info.siteLogo) {
|
||||||
var link = document.querySelector('link[rel="icon"]');
|
var link = document.querySelector('link[rel="icon"]');
|
||||||
if (link) {
|
if (link) {
|
||||||
link.href = info.siteLogo;
|
link.href = info.siteLogo;
|
||||||
link.type = 'image/png';
|
link.type = 'image/png';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<<<<<<< HEAD
|
<script type="module" crossorigin src="/assets/index-Dm7vTAAt.js"></script>
|
||||||
<script type="module" crossorigin src="/assets/index-D9QoFfGP.js"></script>
|
|
||||||
=======
|
|
||||||
<script type="module" crossorigin src="/assets/index-WjS6rFiW.js"></script>
|
|
||||||
>>>>>>> 3b9e5fab104c33eca7e35adc1c6a4ff8ed9cbd60
|
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-eLRg4pQk.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-eLRg4pQk.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>␍
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1500,7 +1500,7 @@ const GeneratedRecord: React.FC = () => {
|
|||||||
title: '授权账户角色',
|
title: '授权账户角色',
|
||||||
dataIndex: 'accountRole',
|
dataIndex: 'accountRole',
|
||||||
key: 'accountRole',
|
key: 'accountRole',
|
||||||
width: 200,
|
width: 160,
|
||||||
render: (role: string) => {
|
render: (role: string) => {
|
||||||
const roleMap: Record<string, string> = {
|
const roleMap: Record<string, string> = {
|
||||||
ADVERTISER: '客户',
|
ADVERTISER: '客户',
|
||||||
@@ -1548,10 +1548,12 @@ const GeneratedRecord: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
size="small"
|
size="small"
|
||||||
|
scroll={{ x: 'max-content' }}
|
||||||
onRow={(record) => ({
|
onRow={(record) => ({
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const id = String(record.id);
|
const id = String(record.id);
|
||||||
setSelectedOauthItems({ value: id, label: String(record.accountUserid) });
|
setSelectedOauthItems({ value: id, label: String(record.accountUserid) });
|
||||||
|
setOauthSelectOpen(false);
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
|
|||||||
@@ -35,10 +35,9 @@ const resourceTypeConfig: Record<string, { label: string; color: string }> = {
|
|||||||
|
|
||||||
// 状态配置
|
// 状态配置
|
||||||
const statusConfig: Record<string, { label: string; color: string }> = {
|
const statusConfig: Record<string, { label: string; color: string }> = {
|
||||||
'1': { label: '待上传', color: 'orange' },
|
'FAILED': { label: '失败', color: 'error' },
|
||||||
'2': { label: '上传中', color: 'processing' },
|
'PENDING': { label: '处理中', color: 'processing' },
|
||||||
'3': { label: '上传成功', color: 'success' },
|
'SUCCESS': { label: '成功', color: 'success' },
|
||||||
'4': { label: '上传失败', color: 'error' },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interface MaterialResource {
|
interface MaterialResource {
|
||||||
@@ -233,11 +232,10 @@ const MaterialListPage: React.FC = () => {
|
|||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
key: 'status',
|
key: 'status',
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (text: string) => <span style={{ color: '#64748b' }}>{text || '-'}</span>,
|
render: (text: string) => {
|
||||||
// render: (text: string) => {
|
const config = statusConfig[text];
|
||||||
// const config = statusConfig[text];
|
return <Tag color={config?.color}>{config?.label || text || '-'}</Tag>;
|
||||||
// return <Tag color={config?.color}>{config?.label || text}</Tag>;
|
},
|
||||||
// },
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '前测结果',
|
title: '前测结果',
|
||||||
|
|||||||
Reference in New Issue
Block a user