feat: default export dir to <install root>\合并后的图片 when packaged

get_output_dir() now returns <install root>\合并后的图片 (parent of app\) for
frozen builds — next to Launcher.exe, easy to find, not replaced on update.
Falls back to <data_dir>/output if the install root is read-only; dev mode
unchanged. The export panel already uses get_output_dir(), so its default
follows automatically.

- tests/test_file_service.py: +3 (dev, frozen install-root, fallback)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 14:29:09 +08:00
co-authored by Claude Opus 4.8
parent 3c4617a27b
commit 421ae78035
3 changed files with 82 additions and 3 deletions
+51
View File
@@ -52,5 +52,56 @@ class TestGetDataDir(unittest.TestCase):
self.assertEqual(fs.get_data_dir(), fs.get_app_dir())
class TestGetOutputDir(unittest.TestCase):
"""get_output_dir() default location (docs/10-lan-update.md §5)."""
def setUp(self):
import tempfile
self.tmp = Path(tempfile.mkdtemp())
self._env = os.environ.get("CMBOT_DATA_DIR")
self._frozen = getattr(sys, "frozen", None)
os.environ["CMBOT_DATA_DIR"] = str(self.tmp / "data")
if hasattr(sys, "frozen"):
del sys.frozen
self._orig_app_dir = fs.get_app_dir
def tearDown(self):
import shutil
fs.get_app_dir = self._orig_app_dir
if self._env is None:
os.environ.pop("CMBOT_DATA_DIR", None)
else:
os.environ["CMBOT_DATA_DIR"] = self._env
if self._frozen is None:
if hasattr(sys, "frozen"):
del sys.frozen
else:
sys.frozen = self._frozen
shutil.rmtree(str(self.tmp), ignore_errors=True)
def test_dev_uses_data_output(self):
# not frozen -> <data_dir>/output
self.assertEqual(fs.get_output_dir(), Path(os.environ["CMBOT_DATA_DIR"]) / "output")
def test_frozen_uses_install_root(self):
app = self.tmp / "install" / "app"
app.mkdir(parents=True)
fs.get_app_dir = lambda: app
sys.frozen = True
self.assertEqual(fs.get_output_dir(), self.tmp / "install" / "合并后的图片")
def test_frozen_falls_back_when_not_writable(self):
app = self.tmp / "install" / "app"
app.mkdir(parents=True)
fs.get_app_dir = lambda: app
sys.frozen = True
orig = fs._is_dir_writable
fs._is_dir_writable = lambda p: False
try:
self.assertEqual(fs.get_output_dir(), Path(os.environ["CMBOT_DATA_DIR"]) / "output")
finally:
fs._is_dir_writable = orig
if __name__ == "__main__":
unittest.main()