T-581 AI生成打开图片文件夹
This commit is contained in:
+232
-1
@@ -17,7 +17,7 @@ from app import accounts, ai, appconfig, db, image_paths, prompts, update_check
|
||||
if gui.QT_IMPORT_ERROR is not None:
|
||||
raise unittest.SkipTest("PySide6 未安装")
|
||||
|
||||
from PySide6.QtCore import QItemSelectionModel, QRect
|
||||
from PySide6.QtCore import QItemSelectionModel, QModelIndex, QRect
|
||||
from PySide6.QtGui import QImage, QKeyEvent, QTextCursor
|
||||
from PySide6.QtWidgets import QApplication, QComboBox, QLineEdit, QPlainTextEdit, QProgressBar, QTableView
|
||||
|
||||
@@ -39,6 +39,7 @@ from app.gui import (
|
||||
TAB_TITLES,
|
||||
WriteBackWorker,
|
||||
)
|
||||
from app.gui import file_manager
|
||||
from app.gui.tabs.generate import CoverGalleryDialog, OriginalImageDialog
|
||||
from app.gui.main_window import _fit_and_center_window
|
||||
|
||||
@@ -1810,6 +1811,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
self.assertEqual("开始生成", tab.generate_button.text())
|
||||
self.assertEqual("停止", tab.stop_generate_button.text())
|
||||
self.assertEqual("重置生成结果", tab.reset_generate_button.text())
|
||||
self.assertEqual("打开图片文件夹", tab.open_image_dir_button.text())
|
||||
self.assertEqual("openImageDirButton", tab.open_image_dir_button.objectName())
|
||||
self.assertIn("当前批次文件夹", tab.open_image_dir_button.toolTip())
|
||||
self.assertEqual(
|
||||
["只生成标题", "只生成封面", "生成标题和封面"],
|
||||
[tab.generate_mode_combo.itemText(index) for index in range(tab.generate_mode_combo.count())],
|
||||
@@ -1975,6 +1979,233 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_generate_tab_opens_current_row_image_directory(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
accounts.create_account("主店", "alias-a", debug_port=9222, config=cfg)
|
||||
accounts.create_account("副店", "alias-b", debug_port=9223, config=cfg)
|
||||
batch_id = db.create_batch(["input.xlsx"], path=cfg["db_path"])
|
||||
db.insert_tasks(
|
||||
batch_id,
|
||||
[
|
||||
{
|
||||
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
|
||||
"source_sheet": "商品",
|
||||
"source_row": 2,
|
||||
"account_name": "Excel主店",
|
||||
"alias": "alias-a",
|
||||
"item_id": "51100639510",
|
||||
},
|
||||
{
|
||||
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
|
||||
"source_sheet": "商品",
|
||||
"source_row": 3,
|
||||
"account_name": "Excel副店",
|
||||
"alias": "alias-b",
|
||||
"item_id": "51100639511",
|
||||
},
|
||||
],
|
||||
path=cfg["db_path"],
|
||||
)
|
||||
tasks = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])
|
||||
first_dir = os.path.join(temp_dir, "legacy-a")
|
||||
second_dir = os.path.join(temp_dir, "legacy-b")
|
||||
first_cover = self.write_test_image(os.path.join(first_dir, "old.jpg"))
|
||||
second_cover = self.write_test_image(os.path.join(second_dir, "new.jpg"))
|
||||
db.set_collected(tasks[0].id, "旧标题A", first_cover, path=cfg["db_path"])
|
||||
db.set_collected(tasks[1].id, "旧标题B", "missing-old.jpg", path=cfg["db_path"])
|
||||
db.set_generated(tasks[1].id, "新标题B", second_cover, path=cfg["db_path"])
|
||||
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
selection = tab.task_table.selectionModel()
|
||||
selection.select(tab.model.index(0, 0), QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
||||
selection.select(tab.model.index(1, 0), QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
||||
tab.task_table.setCurrentIndex(tab.model.index(1, 0))
|
||||
|
||||
with mock.patch(
|
||||
"app.gui.tabs.generate.file_manager.open_in_file_manager",
|
||||
return_value=second_dir,
|
||||
) as open_dir:
|
||||
tab.open_image_directory()
|
||||
|
||||
open_dir.assert_called_once_with(os.path.abspath(second_dir))
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_generate_tab_open_image_directory_falls_back_to_canonical_account_dir(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
account = accounts.create_account("主店", "alias-a", debug_port=9222, config=cfg)
|
||||
batch_id = db.create_batch(["input.xlsx"], path=cfg["db_path"])
|
||||
db.insert_tasks(
|
||||
batch_id,
|
||||
[
|
||||
{
|
||||
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
|
||||
"source_sheet": "商品",
|
||||
"source_row": 2,
|
||||
"account_name": "Excel主店",
|
||||
"alias": "alias-a",
|
||||
"item_id": "51100639510",
|
||||
},
|
||||
],
|
||||
path=cfg["db_path"],
|
||||
)
|
||||
task = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])[0]
|
||||
canonical_dir = os.path.dirname(
|
||||
image_paths.task_image_path(cfg["image_dir"], task, account=account, suffix="new")
|
||||
)
|
||||
os.makedirs(canonical_dir, exist_ok=True)
|
||||
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.task_table.selectRow(0)
|
||||
tab.task_table.setCurrentIndex(tab.model.index(0, 0))
|
||||
|
||||
with mock.patch(
|
||||
"app.gui.tabs.generate.file_manager.open_in_file_manager",
|
||||
return_value=canonical_dir,
|
||||
) as open_dir:
|
||||
tab.open_image_directory()
|
||||
|
||||
open_dir.assert_called_once_with(os.path.abspath(canonical_dir))
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_generate_tab_opens_batch_or_root_directory_without_selected_row(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
db.init_db(cfg["db_path"])
|
||||
batch_id = db.create_batch(["input.xlsx"], path=cfg["db_path"])
|
||||
image_root = os.path.abspath(cfg["image_dir"])
|
||||
batch_dir = os.path.join(image_root, batch_id)
|
||||
os.makedirs(batch_dir, exist_ok=True)
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.batch_filter.setCurrentIndex(tab.batch_filter.findData(batch_id))
|
||||
tab.task_table.clearSelection()
|
||||
tab.task_table.setCurrentIndex(QModelIndex())
|
||||
|
||||
with mock.patch(
|
||||
"app.gui.tabs.generate.file_manager.open_in_file_manager",
|
||||
return_value=batch_dir,
|
||||
) as open_dir:
|
||||
tab.open_image_directory()
|
||||
|
||||
open_dir.assert_called_once_with(os.path.abspath(batch_dir))
|
||||
|
||||
tab.batch_filter.setCurrentIndex(tab.batch_filter.findData(None))
|
||||
tab.task_table.clearSelection()
|
||||
tab.task_table.setCurrentIndex(QModelIndex())
|
||||
with mock.patch(
|
||||
"app.gui.tabs.generate.file_manager.open_in_file_manager",
|
||||
return_value=image_root,
|
||||
) as open_dir:
|
||||
tab.open_image_directory()
|
||||
|
||||
open_dir.assert_called_once_with(image_root)
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_generate_tab_open_image_directory_warns_without_creating_missing_dir(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
db.init_db(cfg["db_path"])
|
||||
batch_id = db.create_batch(["input.xlsx"], path=cfg["db_path"])
|
||||
batch_dir = os.path.join(os.path.abspath(cfg["image_dir"]), batch_id)
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.batch_filter.setCurrentIndex(tab.batch_filter.findData(batch_id))
|
||||
tab.task_table.clearSelection()
|
||||
tab.task_table.setCurrentIndex(QModelIndex())
|
||||
|
||||
with mock.patch("app.gui.tabs.generate.QMessageBox.warning") as warning, mock.patch(
|
||||
"app.gui.tabs.generate.file_manager.open_in_file_manager"
|
||||
) as open_dir:
|
||||
tab.open_image_directory()
|
||||
|
||||
warning.assert_called_once()
|
||||
self.assertIn("该批次还没有图片", warning.call_args[0][2])
|
||||
open_dir.assert_not_called()
|
||||
self.assertFalse(os.path.exists(batch_dir))
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_generate_tab_open_image_directory_warns_when_selected_account_unmatched(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
db.init_db(cfg["db_path"])
|
||||
batch_id = db.create_batch(["input.xlsx"], path=cfg["db_path"])
|
||||
db.insert_tasks(
|
||||
batch_id,
|
||||
[
|
||||
{
|
||||
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
|
||||
"source_sheet": "商品",
|
||||
"source_row": 2,
|
||||
"account_name": "Excel主店",
|
||||
"alias": "missing-alias",
|
||||
"item_id": "51100639510",
|
||||
},
|
||||
],
|
||||
path=cfg["db_path"],
|
||||
)
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.task_table.selectRow(0)
|
||||
tab.task_table.setCurrentIndex(tab.model.index(0, 0))
|
||||
|
||||
with mock.patch("app.gui.tabs.generate.QMessageBox.warning") as warning, mock.patch(
|
||||
"app.gui.tabs.generate.file_manager.open_in_file_manager"
|
||||
) as open_dir:
|
||||
tab.open_image_directory()
|
||||
|
||||
warning.assert_called_once()
|
||||
self.assertIn("选中任务没有匹配账号", warning.call_args[0][2])
|
||||
open_dir.assert_not_called()
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_open_in_file_manager_uses_platform_file_manager(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
target = os.path.join(temp_dir, "images")
|
||||
os.makedirs(target)
|
||||
|
||||
with mock.patch("app.gui.file_manager.sys.platform", "win32"), mock.patch(
|
||||
"app.gui.file_manager.os.startfile",
|
||||
create=True,
|
||||
) as startfile:
|
||||
self.assertEqual(os.path.abspath(target), file_manager.open_in_file_manager(target))
|
||||
startfile.assert_called_once_with(os.path.abspath(target))
|
||||
|
||||
with mock.patch("app.gui.file_manager.sys.platform", "darwin"), mock.patch(
|
||||
"app.gui.file_manager.subprocess.Popen"
|
||||
) as popen:
|
||||
self.assertEqual(os.path.abspath(target), file_manager.open_in_file_manager(target))
|
||||
popen.assert_called_once_with(
|
||||
["open", os.path.abspath(target)],
|
||||
stdout=file_manager.subprocess.DEVNULL,
|
||||
stderr=file_manager.subprocess.DEVNULL,
|
||||
shell=False,
|
||||
)
|
||||
|
||||
with mock.patch("app.gui.file_manager.sys.platform", "linux"), mock.patch(
|
||||
"app.gui.file_manager.subprocess.Popen"
|
||||
) as popen:
|
||||
self.assertEqual(os.path.abspath(target), file_manager.open_in_file_manager(target))
|
||||
popen.assert_called_once_with(
|
||||
["xdg-open", os.path.abspath(target)],
|
||||
stdout=file_manager.subprocess.DEVNULL,
|
||||
stderr=file_manager.subprocess.DEVNULL,
|
||||
shell=False,
|
||||
)
|
||||
|
||||
with self.assertRaises(FileNotFoundError):
|
||||
file_manager.open_in_file_manager(os.path.join(temp_dir, "missing"))
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_generate_elapsed_timer_tracks_title_then_cover(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
tab = GenerateTab(config=self.make_config(temp_dir))
|
||||
|
||||
Reference in New Issue
Block a user