Spaces:
Running
Running
rogerxavier
commited on
Commit
•
b9d0462
1
Parent(s):
7d4961d
Upload 6 files
Browse files- api.py +65 -0
- config.json +5 -0
- config.py +59 -0
- requirements.txt +6 -0
- taskMap.py +47 -0
- utils.py +246 -0
api.py
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import uvicorn
|
3 |
+
from fastapi import FastAPI
|
4 |
+
from utils import *
|
5 |
+
from typing import *
|
6 |
+
from config import *
|
7 |
+
from apscheduler.schedulers.background import BackgroundScheduler#定时任务
|
8 |
+
|
9 |
+
scheduler = BackgroundScheduler()#这个不要用缓存的
|
10 |
+
|
11 |
+
|
12 |
+
def load_config():
|
13 |
+
return get_variables()
|
14 |
+
|
15 |
+
class configData():
|
16 |
+
def update(self):
|
17 |
+
self.data = load_config()
|
18 |
+
print(self.data)
|
19 |
+
return self.data
|
20 |
+
|
21 |
+
|
22 |
+
configData = configData()#复用实例
|
23 |
+
app = FastAPI()
|
24 |
+
|
25 |
+
def periodic_function():
|
26 |
+
data = configData.update()
|
27 |
+
print(f'定时执行的操作时间:{datetime.now()}')
|
28 |
+
print("是否允许定时任务",data['allow_scheduler'])
|
29 |
+
run_asp_task()#执行asp任务进行发送
|
30 |
+
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
+
#启动app时候的定时任务 - 每天根据manga_abs_dir路径是否有jpg文件来判断是否运行
|
35 |
+
@app.on_event("startup")
|
36 |
+
async def app_start():
|
37 |
+
#scheduler.add_job(periodic_function, 'interval', seconds=55)
|
38 |
+
scheduler.add_job(periodic_function, 'interval', seconds=18000)#间隔5小时执行一次
|
39 |
+
scheduler.start()
|
40 |
+
|
41 |
+
|
42 |
+
|
43 |
+
# 返回当前目录及其子目录下的所有信息
|
44 |
+
@app.get("/listFiles")
|
45 |
+
def list_files_func():
|
46 |
+
result = list_files()
|
47 |
+
return result
|
48 |
+
|
49 |
+
# 返回一个章节并删除
|
50 |
+
@app.get("/random_chapter")
|
51 |
+
def random_chapter_handler():
|
52 |
+
result = random_chapter()
|
53 |
+
return result
|
54 |
+
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
#两个blocks放到不同的地方,一个管理manga素材上传,一个管理任务处理
|
59 |
+
app = gr.mount_gradio_app(app, mangaManager, path="/gr")
|
60 |
+
#下面这个暂不更新->没想到太大作用
|
61 |
+
app = gr.mount_gradio_app(app, taskManager, path="/taskManager")
|
62 |
+
|
63 |
+
if __name__ == '__main__':
|
64 |
+
|
65 |
+
uvicorn.run(app, host='0.0.0.0', port=7860)
|
config.json
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"manga_dir": "manga_all",
|
3 |
+
"mask_dir": "mask",
|
4 |
+
"allow_scheduler": true
|
5 |
+
}
|
config.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import os
|
3 |
+
from datetime import datetime
|
4 |
+
|
5 |
+
|
6 |
+
import cachetools#缓存模块
|
7 |
+
#将config中导入的内容作为函数返回的结果加入缓存,通过定时更新缓存来更新config
|
8 |
+
ROTATE = 1 #TTLCache(maxsize = 1, ttl = ROTATE) 表示缓存的生存时间为ttl秒。 最大容量为maxsize个条目。
|
9 |
+
@cachetools.cached(cachetools.TTLCache(maxsize = 1, ttl = ROTATE))
|
10 |
+
def get_variables():
|
11 |
+
# 获取当前脚本的根目录路径
|
12 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
13 |
+
current_config_json = os.path.join(current_dir, "config.json")
|
14 |
+
|
15 |
+
def get_config_data()->json:
|
16 |
+
with open(current_config_json,'r')as f:
|
17 |
+
data = json.load(f)
|
18 |
+
return data
|
19 |
+
data = get_config_data()
|
20 |
+
#是否允许定时任务执行->方便开关任务
|
21 |
+
allow_scheduler = data['allow_scheduler']
|
22 |
+
#设置manga保存路径
|
23 |
+
manga_dir = data['manga_dir']
|
24 |
+
#设置mask保存路径
|
25 |
+
mask_dir = data['mask_dir']
|
26 |
+
#获取manga绝对路径
|
27 |
+
manga_abs_dir = os.path.join(current_dir, manga_dir)
|
28 |
+
#获取mask绝对路径
|
29 |
+
mask_abs_dir = os.path.join(current_dir, mask_dir)
|
30 |
+
#可以选择的两项,包括manga绝对路径和mask绝对路径
|
31 |
+
default_values = [manga_abs_dir, mask_abs_dir]
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
#需要执行任务的bili 容器space的url
|
36 |
+
# bili_space = ['https://rogerxavier-moviepy-with-manga-test.hf.space'
|
37 |
+
# ,'https://rogerxavier-moviepy-with-manga-bili-2.hf.space'
|
38 |
+
# ]
|
39 |
+
|
40 |
+
#不能加下划线,因为后面拼接的时候加了一个 且必须https
|
41 |
+
bili_spaces = ['https://rogerxavier-moviepy-with-manga-test.hf.space'
|
42 |
+
]
|
43 |
+
|
44 |
+
return {
|
45 |
+
"allow_scheduler": allow_scheduler,
|
46 |
+
"manga_dir": manga_dir,
|
47 |
+
"mask_dir": mask_dir,
|
48 |
+
"manga_abs_dir": manga_abs_dir,
|
49 |
+
"mask_abs_dir": mask_abs_dir,
|
50 |
+
"default_values": default_values,
|
51 |
+
"bili_spaces": bili_spaces,
|
52 |
+
"current_config_json":current_config_json,
|
53 |
+
"current_dir":current_dir
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
from utils import * #写在这里防止循环引用的时候utils中导入manga_abs_dir出错
|
59 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
fastapi==0.111.0
|
2 |
+
uvicorn[standard]==0.17.*
|
3 |
+
apscheduler
|
4 |
+
gradio==4.36.0
|
5 |
+
Pillow==8.3.1
|
6 |
+
cachetools==4.2.4
|
taskMap.py
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from task import _0上传遮罩, _1批量顺序上传原始图片到服务器manga, _2发送任务请求一次执行全部流程, \
|
2 |
+
_3检测output_video效果
|
3 |
+
|
4 |
+
bili_meta_data = {
|
5 |
+
"act_reserve_create": 0,
|
6 |
+
"copyright": 1, # 2是转载
|
7 |
+
"source": "",
|
8 |
+
"desc": '點精心设计乳猪份巷',
|
9 |
+
"desc_format_id": 0,
|
10 |
+
"dynamic": "",
|
11 |
+
"interactive": 0,
|
12 |
+
"no_reprint": 1,
|
13 |
+
"open_elec": 0,
|
14 |
+
"origin_state": 0,
|
15 |
+
"subtitles": {
|
16 |
+
"lan": "",
|
17 |
+
"open": 0
|
18 |
+
},
|
19 |
+
"tag": "动漫解说,漫画, 标动画,动漫杂谈,恋爱,吐槽,漫画推荐",
|
20 |
+
"tid": 210,
|
21 |
+
"title": '鬼畜英雄13',
|
22 |
+
"up_close_danmaku": False,
|
23 |
+
"up_close_reply": False,
|
24 |
+
"up_selection_reply": False,
|
25 |
+
"dtime": 0
|
26 |
+
}
|
27 |
+
defaultBaseUrl = 'https://rogerxavier-moviepy-with-manga-test.hf.space'#比如https否则method not allowed
|
28 |
+
# 函数映射简化执行输入
|
29 |
+
# 定义任务函数映射字典
|
30 |
+
task_functions = {
|
31 |
+
"0": _0上传遮罩.upload_mask_to_space,
|
32 |
+
"1": _1批量顺序上传原始图片到服务器manga.upload_manga_to_space,
|
33 |
+
"2": _2发送任务请求一次执行全部流程.task_submit_to_space,
|
34 |
+
"3": _3检测output_video效果.download_output_video
|
35 |
+
}
|
36 |
+
|
37 |
+
# 定义函数名称和参数的元组列表,可以用**的写法将dict传递参数字典给函数
|
38 |
+
tasks_params = {
|
39 |
+
"0": {"baseUrl": defaultBaseUrl, "mask_path": 'mask'},
|
40 |
+
"1": {"baseUrl": defaultBaseUrl, "manga_path": 'manga'},
|
41 |
+
"2": {"baseUrl": defaultBaseUrl,
|
42 |
+
"task_list": ["0filterImage", "1removeMask", "2magiDialogCut", "3mergeDialogToVideo"],
|
43 |
+
"bili_meta": bili_meta_data, "allow_submit": False
|
44 |
+
},
|
45 |
+
"3": {"baseUrl": defaultBaseUrl, "save_path": "output_video.mp4"}
|
46 |
+
}
|
47 |
+
|
utils.py
ADDED
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import os
|
3 |
+
import random
|
4 |
+
from zipfile import ZipFile
|
5 |
+
import zipfile
|
6 |
+
import gradio as gr
|
7 |
+
from config import *
|
8 |
+
import shutil
|
9 |
+
from PIL import Image#上传保存遮罩和比较遮罩width height能否和章节图片匹配的时候用
|
10 |
+
from taskMap import *
|
11 |
+
|
12 |
+
|
13 |
+
def load_config():
|
14 |
+
return get_variables()
|
15 |
+
|
16 |
+
class configData():
|
17 |
+
def __init__(self):
|
18 |
+
self.data = load_config()
|
19 |
+
def update(self):
|
20 |
+
self.data = load_config()
|
21 |
+
print(self.data)
|
22 |
+
|
23 |
+
configData = configData()#复用实例
|
24 |
+
|
25 |
+
|
26 |
+
# 解压缩函数
|
27 |
+
def unzip_file(file_path, extract_path):
|
28 |
+
with zipfile.ZipFile(file_path, 'r') as zip_ref:
|
29 |
+
zip_ref.extractall(extract_path)
|
30 |
+
|
31 |
+
# 上传并解压缩函数
|
32 |
+
#upload_and_unzip(file:"文件",extract_path:"解压路径")->"void 成功提示":
|
33 |
+
def upload_and_unzip(file_obj, extract_path):
|
34 |
+
print("执行上传解压函数")
|
35 |
+
##这样写如果新的多,那么替换为多的一方,如果新的少,也只会替换已经存在的部分--->符合预期想法
|
36 |
+
with ZipFile(file_obj.name) as zfile:
|
37 |
+
zfile.extractall(extract_path)
|
38 |
+
return "File uploaded and extracted successfully to "+extract_path
|
39 |
+
|
40 |
+
#构造函数获取当前目录file list信息-不放config进行返回是为了避免引入旧值
|
41 |
+
def update_file_info(root_dir):
|
42 |
+
info = {}
|
43 |
+
for root, dirs, files in os.walk(root_dir):
|
44 |
+
info[root] = {
|
45 |
+
"directories": dirs,
|
46 |
+
"files": files
|
47 |
+
}
|
48 |
+
for dir_name in dirs:
|
49 |
+
update_file_info(os.path.join(root, dir_name))
|
50 |
+
return info
|
51 |
+
|
52 |
+
def random_chapter():
|
53 |
+
# for root, info in configData.data['file_info'].items():
|
54 |
+
#手动更新避免引入旧值-成功
|
55 |
+
file_info = update_file_info(configData.data['current_dir'])
|
56 |
+
configData.data['file_info'] = file_info
|
57 |
+
for root, info in configData.data['file_info'].items():
|
58 |
+
if root.startswith(configData.data['manga_abs_dir']):
|
59 |
+
for directory in info["directories"]:
|
60 |
+
if any(file.endswith('.jpg') or file.endswith('.png') for file in os.listdir(os.path.join(root, directory))):
|
61 |
+
chapter_path = os.path.join(root, directory)
|
62 |
+
# 删除章节目录
|
63 |
+
print("章节目录是:",chapter_path)
|
64 |
+
|
65 |
+
#获取标题
|
66 |
+
# 将路径转换为标题
|
67 |
+
folders = chapter_path.split(os.sep)
|
68 |
+
if len(folders) >= 2:
|
69 |
+
chapter_title = " ".join([folders[-2], folders[-1]]) # 获取倒数第二个和倒数第一个目录名作为标题
|
70 |
+
else:
|
71 |
+
chapter_title = chapter_path # 如果目录层级不足2层,直接使用路径作为标题
|
72 |
+
|
73 |
+
# 获取标题
|
74 |
+
return chapter_title,chapter_path#返回章节标题和章节目录给任务-1批量顺序上传原始图片到服务器manga.
|
75 |
+
|
76 |
+
return None,None
|
77 |
+
|
78 |
+
def list_files():
|
79 |
+
return configData.data['file_info']
|
80 |
+
|
81 |
+
|
82 |
+
def save_mask(mask_file, output_dir):
|
83 |
+
#上传遮罩保存到mask下面,名称随意
|
84 |
+
# 检查遮罩文件是否存在
|
85 |
+
# 构造保存文件的路径-保证linux和windows都能转义
|
86 |
+
save_path = os.path.join(output_dir, '0.jpg')
|
87 |
+
# 创建目录(如果目录不存在)
|
88 |
+
os.makedirs(output_dir, exist_ok=True)
|
89 |
+
|
90 |
+
# 使用with open方式保存文件
|
91 |
+
mask_file_img = mask_file #这个是Image.open后的对象
|
92 |
+
mask_file_img.save(save_path)
|
93 |
+
return "文件保存成功到:" + str(save_path)
|
94 |
+
|
95 |
+
|
96 |
+
def update_config_json(newConfig:str):
|
97 |
+
newConfig = json.loads(newConfig) #转换str为dict
|
98 |
+
with open(configData.data['current_config_json'], "w") as file:
|
99 |
+
file.write(json.dumps(newConfig, indent=4, ensure_ascii=False)) # 指定indent参数来保持JSON格式
|
100 |
+
#返回新的json文件内容
|
101 |
+
with open(configData.data['current_config_json'], "r") as f:
|
102 |
+
content =f.read() # 读取文件内容
|
103 |
+
return content
|
104 |
+
|
105 |
+
|
106 |
+
def is_asp_task_valid()->bool:
|
107 |
+
# 启动状态检测 ->
|
108 |
+
# 1config允许定时任务 2 mask目录下齐备 3 manga_all目录下有可用素材 4 mask的width height和素材匹配
|
109 |
+
# 5应当将config写入文件而不是py随时可以修改,以防ck账号被封等情况下不发送->同时删除不可用账号 -全部space中账号反馈不可用的时候停止定时任务
|
110 |
+
# 6应该避免任务扎堆进行,对ocr space造成负担
|
111 |
+
if configData.data['allow_scheduler'] == False:
|
112 |
+
print("当前配置不允许定时任务,停止定时任务")
|
113 |
+
return False
|
114 |
+
chapter_title ,cur_chapter= random_chapter()
|
115 |
+
if cur_chapter == None:
|
116 |
+
print("当前没有可用章节了,停止定时任务")
|
117 |
+
return False
|
118 |
+
mask_file_path = os.path.join(configData.data['mask_dir'], '0.jpg')
|
119 |
+
if not os.path.exists(mask_file_path):
|
120 |
+
print("遮罩文件不存在,停止定��任务")
|
121 |
+
return False
|
122 |
+
# 读取遮罩图片长宽比较当前章节下面图片的长宽
|
123 |
+
mask_image = Image.open(mask_file_path)
|
124 |
+
random_chapter_image_name = random.choice(os.listdir(cur_chapter))
|
125 |
+
random_chapter_image_path = os.path.join(cur_chapter, random_chapter_image_name)
|
126 |
+
random_chapter_image = Image.open(random_chapter_image_path)
|
127 |
+
if mask_image.size != random_chapter_image.size:
|
128 |
+
print("遮罩大小和章节随机一个图片的大小不匹配,停止定时任务")
|
129 |
+
return False
|
130 |
+
return True
|
131 |
+
|
132 |
+
#定时任务流程函数集合 ->返回None说明非正常执行情况
|
133 |
+
def run_asp_task():
|
134 |
+
if not is_asp_task_valid():
|
135 |
+
return None
|
136 |
+
#遍历bili_spaces中的space url并执行日常任务
|
137 |
+
for space_url in configData.data["bili_spaces"]:
|
138 |
+
process_task_list("0 1 2",space_url)
|
139 |
+
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
|
145 |
+
|
146 |
+
#实现gradio接受上传压缩文件,解压到manga_all目录下面
|
147 |
+
with gr.Blocks() as mangaManager:
|
148 |
+
#上传文件选择列表
|
149 |
+
file_selected = gr.File(label="待上传压缩章节",file_types=['.zip', '.tar', '.gz'])
|
150 |
+
#上传zip的解压保存路径或mask的地址(必选) 根据需要选择
|
151 |
+
output_dir_gr = gr.Dropdown(label="上传zip的解压保存路径或mask的地址(必选)", choices=configData.data['default_values'])
|
152 |
+
#压缩包上传按钮
|
153 |
+
file_upload_btn = gr.Button("开始上传")
|
154 |
+
#获取到返回的结果-可以是上传的,可以是查看files信息,也可以是别的
|
155 |
+
someResult = gr.Textbox(label="获取按钮返回信息", type="text")
|
156 |
+
# 设置按钮点击事件(调用上传解压函数,将压缩包内容解压到指定目录 默认是manga_all下面)
|
157 |
+
file_upload_btn.click(fn=upload_and_unzip, inputs=[file_selected, output_dir_gr],outputs=someResult)
|
158 |
+
|
159 |
+
#设置按钮查看json类型的listFiles信息
|
160 |
+
|
161 |
+
filesInfoBtn = gr.Button("查看files信息")
|
162 |
+
filesInfoBtn.click(fn=list_files,outputs=someResult)
|
163 |
+
|
164 |
+
#设置mask上传遮罩按钮保存遮罩到mask目录-因为直接重启space利用docker上传会触发定时任务,也许造成不好结果
|
165 |
+
# mask_selected = gr.inputs.Image(label="待上传遮罩", type='pil')
|
166 |
+
mask_selected = gr.components.Image(label="待上传遮罩", type='pil')#代替inputs的新写法
|
167 |
+
markUploadBtn = gr.Button("上传遮罩mask")
|
168 |
+
markUploadBtn.click(fn=save_mask,inputs=[mask_selected, output_dir_gr],outputs=someResult)
|
169 |
+
|
170 |
+
#设置按钮关联新config输入进行更新操作
|
171 |
+
config_update_text = gr.Textbox(placeholder="输入新的JSON数据")#str类型
|
172 |
+
config_update_btn = gr.Button("更新config.json数据")
|
173 |
+
config_update_btn.click(fn=update_config_json, inputs=[config_update_text], outputs=someResult)
|
174 |
+
|
175 |
+
|
176 |
+
# 定义一个函数来处理输入的步骤转list然后执行,返回执行结果->taskResult/None
|
177 |
+
# gradio输入0 1 2 3就行,会自动转"0 1 2 3"然后给process_task_list处理
|
178 |
+
def process_task_list(input_task_str:str = None,baseUrl:str =None):
|
179 |
+
if not is_asp_task_valid():
|
180 |
+
print("任务基本条件不符合")
|
181 |
+
return None
|
182 |
+
if baseUrl is None:
|
183 |
+
print("baseUrl不存在")
|
184 |
+
return None
|
185 |
+
if input_task_str is None:
|
186 |
+
print("input_task_str不存在")
|
187 |
+
return None
|
188 |
+
chapter_title,cur_chapter_path = random_chapter()
|
189 |
+
task_results = {}#保存任务执行结果
|
190 |
+
#临时变量记录是否上传了章节-上传了需要删除,而且只能在for循环任务结束后删除
|
191 |
+
manga_has_uploaded = False
|
192 |
+
|
193 |
+
|
194 |
+
print(input_task_str)# "a b c" - >['a', 'b', 'c']
|
195 |
+
task_list = input_task_str.split(' ')
|
196 |
+
for task in task_list:
|
197 |
+
if task in task_functions:
|
198 |
+
task_func = task_functions[task]#func
|
199 |
+
task_param = tasks_params[task]#dict
|
200 |
+
if "baseUrl" in task_param:
|
201 |
+
task_param["baseUrl"] = baseUrl
|
202 |
+
if "mask_path" in task_param:
|
203 |
+
#使用后遮罩不删,否则维护成本太高
|
204 |
+
task_param["mask_path"] = configData.data['mask_abs_dir']
|
205 |
+
if "manga_path" in task_param:
|
206 |
+
task_param["manga_path"] = cur_chapter_path#上传一个章节作为本次素材,保存到space的manga下面
|
207 |
+
print("上传了章节:",cur_chapter_path,"下面提交后删除")
|
208 |
+
manga_has_uploaded = True
|
209 |
+
#执行了这个任务就要删除该章节
|
210 |
+
|
211 |
+
if "bili_meta" in task_param:
|
212 |
+
bili_meta_data["title"] = chapter_title
|
213 |
+
task_param["bili_meta"] = bili_meta_data
|
214 |
+
result = task_func(**task_param)#执行对应函数获取结果
|
215 |
+
task_results[task] = "success" if result is None else result#保存对应函数执行结果
|
216 |
+
else:
|
217 |
+
print("该执行流程函数不存在")
|
218 |
+
return None#立即推出循环结束函数
|
219 |
+
if manga_has_uploaded is True:
|
220 |
+
#如果上传章节任务得到了执行,那么删除
|
221 |
+
shutil.rmtree(cur_chapter_path) # 递归地删除指定路径的目录及其所有内容,包括文件和子目录 #删除应该在返回的时候删
|
222 |
+
|
223 |
+
|
224 |
+
|
225 |
+
return task_results
|
226 |
+
|
227 |
+
# 创建一个输入块,接受str+空格类型的输入,比如设置默认值3只查看结果output.mp4
|
228 |
+
|
229 |
+
# 将按钮添加到任务管理器中
|
230 |
+
with gr.Blocks() as taskManager:
|
231 |
+
# 任务需要 1:查看指定space的output video状态 2: 手动修改执行流程->比如上传后是发送还是查看output效果
|
232 |
+
# 3:可以添加按钮跳转路由
|
233 |
+
task_list_text = gr.components.Textbox(type="text", label="输入任务列表元素,用空格分隔(一般用来执首尾比如查看output状态)", lines=5)
|
234 |
+
baseSpaceUrl = gr.components.Textbox(type="text", label="指定手动任务的执行容器地址", lines=3)
|
235 |
+
# 获取到返回的结果-可以是上传的,可以是查看files信息,也可以是别的
|
236 |
+
someResult = gr.components.Textbox(label="获取按钮返回信息", type="text")
|
237 |
+
# 创建一个按钮块来触发处理函数
|
238 |
+
taskBtn = gr.Button("处理列表")
|
239 |
+
taskBtn.click(fn=process_task_list,inputs=[task_list_text, baseSpaceUrl],outputs=someResult)
|
240 |
+
new_text = gr.components.Textbox(placeholder="敬请期待") # str类型
|
241 |
+
|
242 |
+
|
243 |
+
|
244 |
+
|
245 |
+
|
246 |
+
|