Skip to content

Releases: MerciHanrim/FileNexusSuite

File Nexus Suite v1.1.2

Choose a tag to compare

@MerciHanrim MerciHanrim released this 14 May 04:47
v1.1.2
58567cf

v1.1.2 โ€” Text Merger MD ์ถœ๋ ฅ ํ˜•์‹ ์ถ”๊ฐ€ / Text Merger MD Output Format

Full Changelog: v1.1.1...v1.1.2


โœจ Added

  • Text Merger โ€” MD ์ถœ๋ ฅ ํ˜•์‹ ์ถ”๊ฐ€ / Text Merger โ€” MD output format added
    • ์ €์žฅ ์„ค์ • ์˜์—ญ์— ์ถœ๋ ฅ ํ˜•์‹: TXT / MD ๋ผ๋””์˜ค๋ฒ„ํŠผ์ด ์ถ”๊ฐ€๋จ. MD ์„ ํƒ ์‹œ ํŒŒ์ผ ๊ตฌ๋ถ„์„ ์ด ## ํŒŒ์ผ๋ช… ํ—ค๋” + --- ๋งˆํฌ๋‹ค์šด ์–‘์‹์œผ๋กœ ์ž๋™ ์ „ํ™˜๋˜๊ณ , ๊ธฐ๋ณธ ํŒŒ์ผ๋ช…๋„ merged.md๋กœ ๋ณ€๊ฒฝ๋จ. ์„ ํƒํ•œ ํ˜•์‹์€ ์„ค์ •์œผ๋กœ ์ €์žฅ๋จ / Output Format: TXT / MD radio buttons added to the save settings area. When MD is selected, file separators switch to ## filename header + --- Markdown form and the default filename becomes merged.md. The selected format is saved with other settings.

๐Ÿ“ Notes for Existing Users

  • ๊ธฐ์กด v1.1.1 ์‚ฌ์šฉ์ž๋Š” ์•ˆ์ „ํ•˜๊ฒŒ v1.1.2๋กœ ์ด์ „ ๊ฐ€๋Šฅ. ์„ค์ • ๋ฐ์ดํ„ฐ(FileNexusSuite.json)์™€ ์ถœ๋ ฅ ํŒŒ์ผ(Output/)์€ ๊ทธ๋Œ€๋กœ ๋ณด์กด๋ฉ๋‹ˆ๋‹ค / Existing v1.1.1 users can safely upgrade to v1.1.2. Settings (FileNexusSuite.json) and output files (Output/) are preserved.
  • ๊ธฐ์กด ์„ค์ • ํŒŒ์ผ์— ์ถœ๋ ฅ ํ˜•์‹ ํ•ญ๋ชฉ์ด ์—†๋Š” ๊ฒฝ์šฐ TXT๋กœ ๊ธฐ๋ณธ ๋ณต์›๋ฉ๋‹ˆ๋‹ค / If the output format entry is absent from an existing settings file, TXT is used as the default.

๐Ÿ” Release Signing

  • Release commit [PLACEHOLDER] โ€” SSH ์„œ๋ช… (Ed25519), GitHub Verified ๋ฑƒ์ง€ / SSH-signed (Ed25519), GitHub Verified
  • ํƒœ๊ทธ v1.1.2 SSH ์„œ๋ช…, GitHub Verified ๋ฑƒ์ง€ / Tag v1.1.2 SSH-signed, GitHub Verified
  • GitHub Actions CI windows-latest + Python 3.10 ํ™˜๊ฒฝ์—์„œ ์ž๋™ ํ†ต๊ณผ / GitHub Actions CI passed on windows-latest + Python 3.10

Tag: v1.1.2
Released: 2026-05-14
Build: FileNexusSuite_v1.1.2_win64.zip ([PLACEHOLDER] MB)

๊นŠ์€ ๊ธฐ์ˆ  ๋ณ€ํ™” ์ด๋ ฅ์€ CHANGELOG.md ์ฐธ์กฐ / For detailed technical changes, see CHANGELOG.md

๐ŸŒผ

File Nexus Suite v1.1.1

Choose a tag to compare

@MerciHanrim MerciHanrim released this 13 May 07:15
v1.1.1
4e0cb99

v1.1.1 โ€” ๋„์›€๋ง ๋‹ค๊ตญ์–ด + ๋ณธ์ฒด i18n ์ •๋ฆฌ / Help Localization + Main Module i18n Cleanup

Full Changelog: v1.1.0...v1.1.1


๐Ÿ› Bug Fixes

  • Text Converter โ€” Book Info ํŒจ๋„ ๋ ˆ์ด์•„์›ƒ fix / Text Converter โ€” Book Info panel layout fix
    • Debug Log ํŒจ๋„์„ ํŽผ์ณค์„ ๋•Œ ์šฐ์ธก Book Info ํŒจ๋„์˜ Title / Author / Language / Chapter Split ์ž…๋ ฅ ํ•„๋“œ ๋ผ๋ฒจ์ด ์ž…๋ ฅ ๋ฐ•์Šค์— ๊ฐ€๋ ค์ง€๋˜ ๊ฒฐํ•จ์ด ์ˆ˜์ •๋จ. v1.1.0๋ถ€ํ„ฐ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ / The labels of Title / Author / Language / Chapter Split fields in the Book Info panel were hidden under the input boxes when Debug Log was expanded โ€” fixed. Issue had been present since v1.1.0

โœจ Changed

  • ๋„์›€๋ง ์‹œ์Šคํ…œ์ด OS ์–ธ์–ด ์„ค์ •์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ 5๊ฐœ ์–ธ์–ด๋กœ ํ‘œ์‹œ / Help system now displays in 5 languages following OS language setting

    • v1.1.0์—์„œ ๋ณธ์ฒด UI ๋ฌธ์ž์—ด์— ์ ์šฉ๋˜์—ˆ๋˜ Qt Linguist ๋‹ค๊ตญ์–ด ๋Ÿฐํƒ€์ž„ ์›Œํฌํ”Œ๋กœ๊ฐ€ ๋„์›€๋ง ์ฝ˜ํ…์ธ ๊นŒ์ง€ ์ผ๊ด€๋˜๊ฒŒ ํ™•์žฅ๋จ. ๋„์›€๋ง ํ…์ŠคํŠธ๊ฐ€ OS ์–ธ์–ด ์ž๋™ ๊ฐ์ง€ ๋˜๋Š” Settings โ†’ Language์—์„œ ์„ ํƒํ•œ ์–ธ์–ด๋กœ ํ‘œ์‹œ๋จ / The Qt Linguist runtime workflow used for main UI strings in v1.1.0 now extends to help content. Help text displays in the OS-detected language or the user-selected language from Settings โ†’ Language
  • ๋ณธ์ฒด์— ๋‚จ์•„์žˆ๋˜ ํ•œ๊ตญ์–ด ํ•˜๋“œ์ฝ”๋“œ 6๊ณณ ์ •๋ฆฌ / Six remaining Korean-hardcoded sites in the main module cleaned up

    • v1.0.x ์‹œ์ ˆ ๋‹จ์ผ ํ•œ๊ตญ์–ด ์ฝ”๋“œ์˜ ์ž”์žฌ๋กœ ๋ณธ์ฒด์— ๋‚จ์•„์žˆ๋˜ 6๊ณณ(๋„์›€๋ง ๋ฒ„ํŠผ ํˆดํŒ, ์‹œ์ž‘ ๋กœ๊ทธ ๋ฉ”์‹œ์ง€, EPUB ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ '์ €์ž: ' ๋ผ๋ฒจ, ์„ค์ •์ฐฝ ์‚ฌ์ด๋“œ๋ฐ” 4๊ฐœ ๋ผ๋ฒจ)์ด 5๊ฐœ ์ง€์› ์–ธ์–ด๋กœ ์ •์ƒ ํ‘œ์‹œ๋˜๋„๋ก ์ •๋ฆฌ๋จ / Six leftover Korean-hardcoded sites (help button tooltip, startup log message, EPUB metadata 'Author: ' label, four Settings sidebar labels) now display in all 5 supported languages

๐Ÿ“ Notes for Existing Users

  • ๊ธฐ์กด v1.1.0 ์‚ฌ์šฉ์ž๋Š” ์•ˆ์ „ํ•˜๊ฒŒ v1.1.1๋กœ ์ด์ „ ๊ฐ€๋Šฅ. ์„ค์ • ๋ฐ์ดํ„ฐ(FileNexusSuite.json)์™€ ์ถœ๋ ฅ ํŒŒ์ผ(Output/)์€ ๊ทธ๋Œ€๋กœ ๋ณด์กด๋ฉ๋‹ˆ๋‹ค / Existing v1.1.0 users can safely upgrade to v1.1.1. Settings (FileNexusSuite.json) and output files (Output/) are preserved
  • ๋ณธ ๋ฆด๋ฆฌ์ฆˆ ์ ์šฉ ํ›„ Settings โ†’ Language์—์„œ ์–ธ์–ด ๋ณ€๊ฒฝ ์‹œ ๋„์›€๋ง ํ…์ŠคํŠธ๋„ ํ•จ๊ป˜ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค / After this release, changing language from Settings โ†’ Language will also update the help text in real time

๐Ÿ” Release Signing

  • Release commit [PLACEHOLDER] โ€” SSH ์„œ๋ช… (Ed25519), GitHub Verified ๋ฑƒ์ง€ / SSH-signed (Ed25519), GitHub Verified
  • ํƒœ๊ทธ v1.1.1 SSH ์„œ๋ช…, GitHub Verified ๋ฑƒ์ง€ / Tag v1.1.1 SSH-signed, GitHub Verified
  • GitHub Actions CI windows-latest + Python 3.10 ํ™˜๊ฒฝ์—์„œ ์ž๋™ ํ†ต๊ณผ / GitHub Actions CI passed on windows-latest + Python 3.10

Tag: v1.1.1
Released: [PLACEHOLDER โ€” YYYY-MM-DD]
Build: FileNexusSuite_v1.1.1_win64.zip ([PLACEHOLDER] MB)

๊นŠ์€ ๊ธฐ์ˆ  ๋ณ€ํ™” ์ด๋ ฅ์€ CHANGELOG.md ์ฐธ์กฐ / For detailed technical changes, see CHANGELOG.md

๐ŸŒผ

File Nexus Suite v1.1.0

Choose a tag to compare

@MerciHanrim MerciHanrim released this 11 May 16:36
v1.1.0
debff54

v1.1.0 โ€” ๋ชจ๋“ˆํ™”์™€ ๋””์ž์ธ ํด๋ฆฌ์‹ฑ: Qt Linguist ๋ฒˆ์—ญ ์‹œ์Šคํ…œ ์ „ํ™˜ + ํ—ฌํผ/ํ…Œ๋งˆ ๋ชจ๋“ˆ ๋ถ„๋ฆฌ + ์‚ฌ์ด๋“œ๋ฐ”ยท์ง„ํ–‰๋ฅ  ํ†ค ํ†ตํ•ฉ / Modularization and Design Polishing: Qt Linguist Translation System Migration + Helper/Theme Module Extraction + Sidebar & Progress Tone Unification

v1.1.0์€ v1.0.11์˜ ์ฝ”๋“œ ๋ณธ์งˆ ๊ฐ•ํ™” ๋‹ค์Œ ์ž๋ฆฌ์—์„œ, ๋ชจ๋“ˆํ™”์™€ ๋””์ž์ธ ํด๋ฆฌ์‹ฑ์ด ๋ชจ์ด๋Š” ์ž๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋ณธ ๋ฆด๋ฆฌ์ฆˆ๋Š” ์„ธ ๋ฌถ์Œ(ํ—ฌํผ ํ•จ์ˆ˜์™€ ํ…Œ๋งˆ ์‹œ์Šคํ…œ์˜ ๋ชจ๋“ˆ ๋ถ„๋ฆฌ, Qt Linguist ๋ฒˆ์—ญ ์‹œ์Šคํ…œ ์ „ํ™˜, ์‚ฌ์ด๋“œ๋ฐ” ์นด๋“œ์™€ Batch Renamer ์ง„ํ–‰๋ฅ  ๋‹ค์ด์–ผ๋กœ๊ทธ์˜ ๋””์ž์ธ ํ†ค ํ†ตํ•ฉ)์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋ณธ์ฒด ๋ชจ๋“ˆ์€ ํ—ฌํผ์™€ ํ…Œ๋งˆ ์‹œ์Šคํ…œ ๋ถ„๋ฆฌ๋ฅผ ํ†ตํ•ด ์•ฝ 15,662์ค„์—์„œ 13,274์ค„๋กœ ์ถ•์†Œ๋˜์—ˆ์œผ๋ฉฐ, ๋ฒˆ์—ญ ์‹œ์Šคํ…œ์€ ์ธ๋ผ์ธ Python ๋”•์…”๋„ˆ๋ฆฌ์—์„œ Qt Linguist .ts/.qm ๋Ÿฐํƒ€์ž„ ์–‘์‹์œผ๋กœ ์ „ํ™˜๋˜์–ด ๋ฐ์ดํ„ฐ ๊ณ„์ธต์ด Python ์†Œ์Šค ์™ธ๋ถ€๋กœ ์ด์ „๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ์‹คํ–‰ ์‹œ ์šด์˜์ฒด์ œ์˜ ์–ธ์–ด ์„ค์ •์—์„œ UI ์–ธ์–ด๊ฐ€ ์ž๋™ ๊ฐ์ง€๋ฉ๋‹ˆ๋‹ค.

v1.1.0 follows v1.0.11's code essence deepening by gathering modularization and design polishing artifacts. This release bundles three threads (helper utilities and theme system extracted into sibling modules, Qt Linguist translation system migration, design tone unification across sidebar cards and Batch Renamer progress dialog). The main module shrinks from roughly 15,662 to 13,274 lines through helper and theme system extraction; the translation system migrates from an inline Python dictionary to Qt Linguist .ts/.qm runtime files, moving the data layer outside the Python source. The UI language is auto-detected from the OS settings on first launch.


โœจ ์ฃผ์š” ๋ณ€๊ฒฝ / Major Changes

  • Qt Linguist ๋ฒˆ์—ญ ์‹œ์Šคํ…œ ์ „ํ™˜ / Qt Linguist translation system migration

    • ๊ธฐ์กด FileNexusSuite.py ๋‚ด๋ถ€ ์ธ๋ผ์ธ TRANSLATIONS ๋”•์…”๋„ˆ๋ฆฌ๊ฐ€ Qt Linguist .ts (์†Œ์Šค) + .qm (๋Ÿฐํƒ€์ž„) ์–‘์‹์œผ๋กœ ์ปดํŒŒ์ผ๋จ. ์†Œ์Šค ํŒŒ์ผ์€ translations_ts/ ์•„๋ž˜, ๋Ÿฐํƒ€์ž„ ํŒŒ์ผ์€ translations/ ์•„๋ž˜, 5๊ฐœ ์–ธ์–ด (ko/en/ja/zh_cn/zh_tw) ร— 25๊ฐœ ์ปจํ…์ŠคํŠธ ร— 503๊ฐœ ๋ฒˆ์—ญ / Inline TRANSLATIONS dict migrated to Qt Linguist .ts (source) + .qm (runtime) files. Source files under translations_ts/, runtime files under translations/, 5 languages ร— 25 contexts ร— 503 translations
    • ๋ชจ๋“  UI ๋ฌธ์ž์—ด์ด ๊ธฐ์กด _t(key) ์–‘์‹์—์„œ self.tr(key)๋กœ ์ „ํ™˜๋˜์–ด ๋Ÿฐํƒ€์ž„์— QTranslator๋ฅผ ํ†ตํ•ด ํ•ด์„๋จ / All UI strings migrated from _t(key) to self.tr(key), resolved at runtime through QTranslator
    • OS ์–ธ์–ด ์ž๋™ ๊ฐ์ง€ โ€” ์ฒซ ์‹คํ–‰ ์‹œ ์šด์˜์ฒด์ œ ์–ธ์–ด ์„ค์ •์— ๊ธฐ๋ฐ˜ํ•ด UI ์–ธ์–ด๊ฐ€ ์ž๋™ ์„ ํƒ๋˜๋ฉฐ, ์„ค์ •์—์„œ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ / OS language auto-detection on first launch; changeable in Settings
    • scripts/update_translations.bat์™€ scripts/add_ts_contexts.py ํ—ฌํผ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ lupdate/lrelease ์‚ฌ์ดํด์„ ์ž๋™ํ™”. ๋ฒˆ์—ญ ํ˜‘์—…์€ .ts ํŒŒ์ผ์„ Qt Linguist๋กœ ์ง์ ‘ ํŽธ์ง‘ํ•˜๋ฉฐ, UI ๋ณ€๊ฒฝ ํ›„ .qm ๋Ÿฐํƒ€์ž„ ํŒŒ์ผ์„ ์žฌ์ƒ์„ฑ / Helper scripts automate the lupdate/lrelease cycle; translators edit .ts files directly in Qt Linguist, with .qm files regenerated after UI changes
  • ํ—ฌํผ ํ•จ์ˆ˜ ๋ฐ ํ…Œ๋งˆ ์‹œ์Šคํ…œ ๋ชจ๋“ˆ ๋ถ„๋ฆฌ / Helper utilities and theme system extracted into sibling modules

    • fns_utils.py ์‹ ๊ทœ โ€” 17๊ฐœ์˜ ์ˆœ์ˆ˜ Python ํ—ฌํผ ํ•จ์ˆ˜๊ฐ€ ๋ณธ์ฒด ๋ชจ๋“ˆ์—์„œ ๋ถ„๋ฆฌ๋จ. ์ˆซ์ž/์ž์—ฐ ์ •๋ ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ (_pad, extract_number, _get_leading_num, extract_number_auto, auto_width_for_group, detect_common_prefix, natural_sort_key, _SKIP_FILES), Tag Editor ํ•ต์‹ฌ ๋กœ์ง (remove_tag_from_name, _build_tag_str, add_tag_to_name, depad_name, apply_renames), HTML escape/unescape ์œ ํ‹ธ๋ฆฌํ‹ฐ (_de, _h2t, _strip_xml_illegal, _ex) / New fns_utils.py โ€” 17 pure-Python helpers extracted from the main module
    • fns_theme.py ์‹ ๊ทœ โ€” 9๊ฐœ ํ…Œ๋งˆ ํŒ”๋ ˆํŠธ ๋”•์…”๋„ˆ๋ฆฌ (THEMES, ํ…Œ๋งˆ๋ณ„ 18๊ฐœ ํ‚ค), 5๊ฐœ ํ…Œ๋งˆ ํ—ฌํผ (_hex_rgba, _combo_arrow_url, _detect_system_theme, _resolve_theme, make_style), ๊ทธ๋ฆฌ๊ณ  _apply_card_shadow ์œ„์ ฏ ํ—ฌํผ๊ฐ€ ๋ถ„๋ฆฌ๋จ. _apply_card_shadow์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” _apply_card_shadow(widget)์—์„œ _apply_card_shadow(widget, border_color)๋กœ ๋ณ€๊ฒฝ๋˜์–ด BORDER global ์˜์กด์„ ๋ช…์‹œ์  ์ธ์ž๋กœ ํ’€๊ณ  ๋ชจ๋“ˆ์„ ์ž๊ธฐ-์™„๊ฒฐ๋กœ ์œ ์ง€ / New fns_theme.py โ€” 9-theme palette dict, 5 theme helpers, and _apply_card_shadow widget helper extracted; signature change breaks the BORDER global dependency
    • ๋‘ ๋ชจ๋“ˆ ๋ชจ๋‘ PySide6 ์™ธ ์™ธ๋ถ€ ์˜์กด์ด ์—†์œผ๋ฉฐ ๋ณธ์ฒด ๋Ÿฐํƒ€์ž„ ์ƒํƒœ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ. ๋ณธ์ฒด ๋ชจ๋“ˆ์€ ๋‘ ๋ถ„๋ฆฌ๋ฅผ ํ†ตํ•ด ์•ฝ 532์ค„ ๊ฐ์†Œ (15,662 โ†’ 15,130) / Both modules are independent of FNS runtime state; main module shrinks by roughly 532 lines through these two extractions
  • ํŒŒ์ผ ๋ชฉ๋ก ์œ„์ ฏ์˜ ๊ฐ€์ƒํ™” base ํด๋ž˜์Šค ํ†ตํ•ฉ / File-list widget virtualization unification

    • ๊ฑฐ์˜ ๋™์ผํ•œ QTreeWidget ํŒจํ„ด์„ ๊ณต์œ ํ•˜๋˜ 5๊ฐœ ์œ„์ ฏ (MergeFileTree, BulkFixerFileList, TextConverterFileList, Tag Editor์˜ _file_list์™€ _tree)์ด 3๊ฐœ์˜ ์‹ ๊ทœ base ํด๋ž˜์Šค๋กœ ํ†ตํ•ฉ / Five widgets sharing a near-identical QTreeWidget pattern unified under three new base classes
    • FileListModel(QAbstractTableModel) โ€” ๋ฒ”์šฉ ํ‰๋ฉด ๋ชฉ๋ก ๋ชจ๋ธ (์„œ๋ธŒํด๋ž˜์Šค ์ œ๊ณต COLUMNS ๊ธฐ๋ฐ˜ ๋ Œ๋”๋ง, PATH_ROLE = UserRole+4, sort()/sort_key()); FileListBase(QTableView) โ€” ๊ณตํ†ต ๊ณ„์•ฝ (COLUMNS, COLUMN_WIDTHS, SELECTION_MODE ๋“ฑ 6๊ฐœ ํด๋ž˜์Šค ์†์„ฑ + ๊ณตํ†ต ๋ฉ”์„œ๋“œ); DragDropMixin โ€” drag-drop ๋™์ž‘์ด ํ•„์š”ํ•œ 3๊ฐœ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์œ„ํ•œ mixin / FileListModel, FileListBase, DragDropMixin โ€” base classes consolidating shared model/view/drag-drop logic
    • ๊ฒฐ๊ณผ: v1.0.11์—์„œ Batch Renamer ๋ฏธ๋ฆฌ๋ณด๊ธฐ์—๋งŒ ์ ์šฉ๋˜์—ˆ๋˜ QAbstractTableModel ๊ธฐ๋ฐ˜ ๊ฐ€์ƒํ™” ๋ Œ๋”๋ง์ด ๋‹ค์„ฏ ์œ„์ ฏ ๋ชจ๋‘์— ์ ์šฉ๋˜์–ด, ํฐ ํŒŒ์ผ ๋ชฉ๋ก๋„ ์–ด๋А ํƒญ์—์„œ๋“  ํ™”๋ฉด์— ๋ณด์ด๋Š” ํ–‰๋งŒ ๋ Œ๋”๋ง๋จ. ์•ฝ 350์ค„์˜ ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ 270์ค„์˜ ๊ณต์œ  base๋กœ ๋Œ€์ฒด / QAbstractTableModel virtualization (previously only on Batch Renamer preview) now applies uniformly to all five widgets; roughly 350 lines of duplicated subclass code replaced by 270 lines of shared base
  • ์‚ฌ์ด๋“œ๋ฐ” ์นด๋“œ์˜ ์‹œ๊ฐ์  ๋ถ„๋ฆฌ๊ฐ ๊ฐ•ํ™” / Sidebar card visual separation strengthened

    • ์šฐ์ธก ์‚ฌ์ด๋“œ๋ฐ” ์นด๋“œ๋“ค (Batch Renamer์˜ Number Reset / Start Number / Digits / Prefix-Suffix ๋“ฑ)์ด ์ •๋ณด ๋ฐ€๋„๋Š” ์œ ์ง€ํ•˜๋ฉด์„œ ์‚ด์ง ๋–  ์žˆ๋Š” ํ˜•ํƒœ๋กœ ์‹œ๊ฐ์ ์œผ๋กœ ๊ทธ๋ฃนํ•‘๋จ / Cards in the right-hand sidebar feel slightly elevated and visually grouped while preserving information density
    • ์„ธ ๊ฐ€์ง€ ํ˜‘์กฐ ๋ณ€๊ฒฝ: (1) ์‹ ๊ทœ _apply_card_shadow(widget) ํ—ฌํผ๊ฐ€ ๋ชจ๋“  QGroupBox์— ๋ถ€๋“œ๋Ÿฌ์šด QGraphicsDropShadowEffect ์ ์šฉ (blur radius 18, Y offset 3, BORDER์—์„œ alpha 0.5๋กœ derive); (2) ๊ธ€๋กœ๋ฒŒ QGroupBox ๋ฃฐ์— margin-bottom:6px์™€ ๊ฐ•ํ™”๋œ padding ์ถ”๊ฐ€; (3) QGroupBox::title ์ƒ‰์ด MUTED์—์„œ ACCENT๋กœ ๋ณ€๊ฒฝ๋˜์–ด ์นด๋“œ ํ—ค๋”๊ฐ€ ์„น์…˜ ๋งˆ์ปค์ฒ˜๋Ÿผ ์ฝํž˜ / Three coordinated changes: subtle QGraphicsDropShadowEffect on every QGroupBox, stronger margin/padding on the global QGroupBox rule, and QGroupBox::title color shifted from MUTED to ACCENT
    • AppSuite._apply_card_shadows()๊ฐ€ __init__๊ณผ apply_theme()์—์„œ ํ˜ธ์ถœ๋˜์–ด ๋ผ์ดํŠธ/๋‹คํฌ ํ…Œ๋งˆ ๋ณ€๊ฒฝ ์‹œ ๊ทธ๋ฆผ์ž ์ƒ‰์ด BORDER๋ฅผ ๋”ฐ๋ผ ๊ฐฑ์‹  / Shadow color tracks BORDER across light/dark theme switches
  • Batch Renamer ์ง„ํ–‰๋ฅ  ๋‹ค์ด์–ผ๋กœ๊ทธ FNS ํ†ค ๋งค์น˜ / Batch Renamer progress dialog tone-matched with FNS theme

    • Batch Renamer์˜ ingest worker์™€ rename worker๊ฐ€ ์‚ฌ์šฉํ•˜๋˜ Qt ๊ธฐ๋ณธ QProgressDialog๋ฅผ ์‹ ๊ทœ _build_progress_dlg ํ—ฌํผ๋กœ ๋นŒ๋“œํ•œ FNS ํ†ค ๋ชจ๋‹ฌ ์ง„ํ–‰๋ฅ  ๋‹ค์ด์–ผ๋กœ๊ทธ๋กœ ๊ต์ฒด. ๊ธฐ์กด _confirm / _build_dlg ์ƒ‰์ƒ ํŒ”๋ ˆํŠธ ๊ณ„์Šน (SURFACE ๋ฐฐ๊ฒฝ, ACCENT ์ง„ํ–‰ ๋ฐ” chunk, BORDER ์™ธ๊ณฝ์„ , _btn_style(False) ์ทจ์†Œ ๋ฒ„ํŠผ) / Qt's default QProgressDialog replaced with an FNS-toned modal dialog inheriting the _confirm/_build_dlg palette
    • ๊ธฐ์กด ๋™์ž‘ ๋ชจ๋‘ ๋ณด์กด: ๋ชจ๋‹ฌ (Qt.WindowModal), 400 ms ์ตœ์†Œ ํ‘œ์‹œ ์ง€์—ฐ (QTimer.singleShot(400, ...) + ์™„๋ฃŒ ํ”Œ๋ž˜๊ทธ๋กœ ์งง์€ ์ž‘์—…์˜ ๊นœ๋นก์ž„ ๋ฐฉ์ง€), ์™„๋ฃŒ ์‹œ ์ž๋™ ๋‹ซํž˜, ์ทจ์†Œ ์ „ํŒŒ (worker.request_cancel()). QProgressDialog ์‹ฌ๋ณผ์€ QtWidgets ์ž„ํฌํŠธ์—์„œ ์ œ๊ฑฐ / All prior behaviors preserved: modal, 400 ms minimum-duration delay, auto-close on completion, cancel propagation

๐Ÿ“ฆ ์ถ”๊ฐ€ / Added

  • _ElideLabel(QLabel) ํ—ฌํผ ์œ„์ ฏ / _ElideLabel(QLabel) helper widget
    • ๋„ˆ๋น„๊ฐ€ ๋‚ด์šฉ๋ณด๋‹ค ์ข์œผ๋ฉด ํ…์ŠคํŠธ๋ฅผ '...'๋กœ ์šฐ์ธก ์ ˆ์‚ญํ•˜๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋ผ๋ฒจ. ์ „์ฒด ํ…์ŠคํŠธ๋Š” _full_text์— ๋ณด๊ด€๋˜๊ณ  resizeEvent์—์„œ ์ ˆ์‚ญ์ด ์žฌ์ ์šฉ๋˜์–ด ๋ถ€๋ชจ ๋„ˆ๋น„ ๋ณ€ํ™”์— ๋”ฐ๋ผ ์ ˆ์‚ญ ์œ„์น˜๊ฐ€ ๋™์ ์œผ๋กœ ๊ฐฑ์‹ ๋จ / Right-elides text with '...' when narrower than content; full text stored in _full_text and re-applied on resizeEvent
    • ๊ฐ€๋กœ QSizePolicy๊ฐ€ Ignored๋กœ ์„ค์ •๋˜์–ด ๊ธด ๋ฌธ์ž์—ด์ด ๋ถ€๋ชจ์˜ ์ตœ์†Œ ๋„ˆ๋น„๋ฅผ ํ‚ค์šฐ๋Š” ์ผ์ด ์—†์Œ. ์ „์ฒด ํ…์ŠคํŠธ๋Š” ๋ชจ๋“  setText() ํ˜ธ์ถœ์—์„œ ํˆดํŒ์œผ๋กœ ๋…ธ์ถœ๋จ / Horizontal QSizePolicy.Ignored so long strings never inflate the parent's minimum width; full text exposed via tooltip
    • ํ˜„์žฌ๋Š” Text Merger์˜ ์„ ํƒ ์š”์•ฝ ๋ผ๋ฒจ์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ๊ฐ€์šฉ ๋„ˆ๋น„๋ณด๋‹ค ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์ƒํƒœ ๋ผ๋ฒจ์— ์ ์šฉ ๊ฐ€๋Šฅ / Currently used by Text Merger's selection summary label; available for any future status label

๐Ÿ› ์ˆ˜์ • / Fixed

  • Text Merger ์„ ํƒ ๋ผ๋ฒจ ๋ ˆ์ด์•„์›ƒ ๊นจ์ง (๋‹ค์ค‘ ํŒŒ์ผ ์„ ํƒ ์‹œ) / Text Merger selection-label layout breakage with multiple files selected

    • ํ•˜๋‹จ ์„ ํƒ ์š”์•ฝ ๋ผ๋ฒจ (_lbl_selection)์ด ์ด๋™/์‚ญ์ œ ๋ฒ„ํŠผ๊ณผ ๊ฐ™์€ ๊ฐ€๋กœ ํ–‰์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์–ด, ๋‹ค์ˆ˜์˜ ํŒŒ์ผ์ด ์„ ํƒ๋˜๋ฉด ๋ผ๋ฒจ์˜ ๊ธธ์ด๊ฐ€ ์ขŒ์ธก ํŒจ๋„์˜ ์ตœ์†Œ ๋„ˆ๋น„๋ฅผ ํ‚ค์›Œ ์šฐ์ธก(์ €์žฅ ์„ค์ •) ํŒจ๋„์„ ํ™”๋ฉด ๋ฐ–์œผ๋กœ ๋ฐ€์–ด๋‚ด๊ณ  ์ด๋™/์‚ญ์ œ ๋ฒ„ํŠผ ํ…์ŠคํŠธ๋„ ์ž˜๋ฆฌ๋Š” ํ˜„์ƒ / The bottom selection summary label shared a horizontal row with the move/delete buttons; with many files selected, the label's intrinsic width inflated the left panel's minimum size and pushed the right panel off-screen
    • ์ˆ˜์ •: (1) ๋ผ๋ฒจ์„ bot_btn_row ์•„๋ž˜์˜ ๋ณ„๋„ ์„ธ๋กœ ํ–‰์œผ๋กœ ์ด๋™, (2) _ElideLabel ํ—ฌํผ(์œ„ Added ์ฐธ๊ณ )๋กœ ๊ฐ์‹ธ ๊ฐ€๋กœ minimumSize๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋„ˆ๋น„๊ฐ€ ์ข์„ ๋•Œ ์šฐ์ธก ์ ˆ์‚ญ. ์ „์ฒด ์„ ํƒ ํ…์ŠคํŠธ๋Š” ํˆดํŒ์œผ๋กœ ๊ทธ๋Œ€๋กœ ํ™•์ธ ๊ฐ€๋Šฅ / Fixed by moving the label to its own row and wrapping it in _ElideLabel; full selection text remains accessible via the tooltip
    • v1.0.11๋ถ€ํ„ฐ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ์ด๋ฉฐ, v1.1.0 base ํด๋ž˜์Šค ํ†ตํ•ฉ์˜ ํšŒ๊ท€๊ฐ€ ์•„๋‹˜์ด ํ™•์ธ๋จ / Issue had been present since v1.0.11; not a regression of the v1.1.0 base-class refactor
  • PyInstaller ๋นŒ๋“œ์˜ ๋ฒˆ์—ญ ํŒŒ์ผ ๋ˆ„๋ฝ / Translation files missing in PyInstaller frozen build

    • ๋นŒ๋“œ๋œ ์‹คํ–‰ํŒŒ์ผ์ด ํ•œ๊ตญ์–ด Windows ํ™˜๊ฒฝ์—์„œ๋„ ์˜์–ด๋งŒ ํ‘œ์‹œ๋˜๊ณ  ์„ค์ • > Language ๋ฉ”๋‰ด์— ๋‹ค๋ฅธ 4๊ฐœ ์–ธ์–ด๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋˜ ํ˜„์ƒ. ๋‘ ์›์ธ: (1) build_pyinstaller.py์— --add-data ํ”Œ๋ž˜๊ทธ๊ฐ€ ์—†์–ด translations/*.qm ํŒŒ์ผ์ด frozen ๋นŒ๋“œ์— ๋ฒˆ๋“ค๋ง๋˜์ง€ ์•Š์Œ, (2) _resource_dir()์ด os.path.dirname(sys.executable)์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ PyInstaller 6.x onedir ๋ชจ๋“œ์˜ contents directory (_internal/)๋ฅผ ์ฐพ์ง€ ๋ชปํ•จ / Built executable silently fell back to English on all platforms because --add-data was missing from the build script and _resource_dir() did not resolve to PyInstaller 6.x's _internal/ contents directory
    • ์ˆ˜์ •: (1) build_pyinstaller.py์— --add-data "translations;translations" ์ถ”๊ฐ€, (2) _resource_dir()์ด getattr(sys, '_MEIPASS', os.path.dirname(sys.executable))์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋ณ€๊ฒฝ. 5๊ฐœ ์–ธ์–ด ๋ชจ๋‘ frozen ๋นŒ๋“œ์—์„œ ์ •์ƒ ๋…ธ์ถœ / Fixed by adding --add-data to the PyInstaller command and updating _resource_dir() to use sys._MEIPASS; all five languages restored in the frozen build

๐Ÿงช ํ…Œ์ŠคํŠธ ์ž๋™ํ™” / Test Automation

  • 594 โ†’ 513 passing (-81), 0 failures / 0 errors / 5 intentional skips (ํ•œ๋ฆผ ๋กœ์ปฌ + Git ํด๋” ์ด์ค‘ ๊ฒ€์ฆ). Qt Linguist ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์—์„œ TRANSLATIONS ๋”•์…”๋„ˆ๋ฆฌ literal์— ๋Œ€ํ•œ source-grep ํ…Œ์ŠคํŠธ๊ฐ€ ๋ชจ๋‘ ์ œ๊ฑฐ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ (๋”•์…”๋„ˆ๋ฆฌ๊ฐ€ Python ์†Œ์Šค์— ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š์Œ) / 594 โ†’ 513 passing (-81), Hanrim local + Git folder dual verification. Net reduction reflects removal of source-grep tests against the TRANSLATIONS dict literal (no longer in Python source after Qt Linguist migration)
  • Qt Linguist ๋Ÿฐํƒ€์ž„์šฉ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ ๋งˆ๋ฌด๋ฆฌ โ€” ๋™๋“ฑํ•œ ์ปค๋ฒ„๋ฆฌ์ง€๊ฐ€ TestV105RegressionModule (self.tr() ํ˜ธ์ถœ ๊ธฐ๋ฐ˜ ๋Ÿฐํƒ€์ž„ ๋ฒˆ์—ญ...
Read more

File Nexus Suite v1.0.11

Choose a tag to compare

@MerciHanrim MerciHanrim released this 08 May 07:02
v1.0.11
3ca7987

v1.0.11 โ€” ์ฝ”๋“œ ๋ณธ์งˆ ๊ฐ•ํ™”: Batch Renamer ๋Œ€์šฉ๋Ÿ‰ ์‘๋‹ต์„ฑ ์žฌ์ž‘์„ฑ + ์˜๋ฌธ ๊ธฐ๋ณธ ์ „ํ™˜ + 12๊ฐœ ์ธ๋ผ์ธ UI i18n migration / Code Essence Deepening: Batch Renamer Scalability Rewrite + English-First Transition + 12 Inline UI i18n Migration

v1.0.11์€ v1.0.10์˜ MIT ์ „ํ™˜๊ณผ OSS ๊ฒฐ์˜ ์‹œ์ž‘์  ๋‹ค์Œ ์ž๋ฆฌ์—์„œ, ์ฝ”๋“œ ๋ณธ์งˆ์„ OSS-facing ์–‘์‹์œผ๋กœ ๋” ๊นŠ๊ฒŒ ๋‹ค์ง€๋Š” ํŠธ๋ž™์ž…๋‹ˆ๋‹ค. ๋ณธ ๋ฆด๋ฆฌ์ฆˆ๋Š” ์„ธ ํŠธ๋ž™(Batch Renamer ๋Œ€์šฉ๋Ÿ‰ ์‘๋‹ต์„ฑ ์žฌ์ž‘์„ฑ, ๋ฉ”์ธ ์ฝ”๋“œ + ๋ถ€์† ๋ฌธ์„œ ์˜๋ฌธ ๊ธฐ๋ณธ ์ „ํ™˜, 12๊ฐœ ์ธ๋ผ์ธ UI ๋ฌธ์ž์—ด TRANSLATIONS ์ด์ „)์˜ ๋ฌถ์Œ์ž…๋‹ˆ๋‹ค. 154,895 ํŒŒ์ผ / 2,714 ํด๋” / 86.8 GB ๊ทœ๋ชจ ๋ฐ์ดํ„ฐ์…‹์—์„œ ๋ฐœ์ƒํ•˜๋˜ ์ˆ˜์‹ญ ์ดˆ~์ˆ˜๋ถ„ ๋ฉˆ์ถค ํ˜„์ƒ์ด ํ’€๋ ธ์œผ๋ฉฐ โ€” 103,716 ํŒŒ์ผ / 1,767 ํด๋” / 32.7 GB์—์„œ โœ“ ๊ฒ€์ฆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

v1.0.11 follows v1.0.10's decisive turning point: OSS opening by deepening the code itself for OSS-facing posture. This release bundles three tracks (Batch Renamer scalability rewrite, English-first transition for main code + supporting documents, 12 inline UI strings migrated to TRANSLATIONS). The tens-of-seconds to minutes freeze observed at 154,895 files / 2,714 folders / 86.8 GB has been resolved โ€” verified at 103,716 files / 1,767 folders / 32.7 GB.


โœจ ์ฃผ์š” ๋ณ€๊ฒฝ / Major Changes

  • Batch Renamer ๋Œ€์šฉ๋Ÿ‰ ์‘๋‹ต์„ฑ ์žฌ์ž‘์„ฑ / Batch Renamer scalability rewrite

    • ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํ…Œ์ด๋ธ”์„ ๊ฐ€์ƒํ™”๋œ QTableView + QAbstractTableModel (์‹ ๊ทœ BatchPreviewModel + BatchRowHeightDelegate)๋กœ ์ „ํ™˜ โ€” ๊ธฐ์กด QTableWidget์ด ํ™”๋ฉด ๊ฐฑ์‹ ๋งˆ๋‹ค ์ƒ์„ฑํ•˜๋˜ ์•ฝ 47๋งŒ ๊ฐœ์˜ QTableWidgetItem ๋ถ€๋‹ด ์ œ๊ฑฐ. _f_refresh / _p_refresh๋Š” ์…€๋ณ„ ์œ„์ ฏ ๊ตฌ์„ฑ ๋กœ์ง์ด data(index, role)๋กœ ์ด๋™ํ•˜๋ฉด์„œ 23 / 21์ค„์—์„œ 4์ค„๋กœ ์ถ•์†Œ / Preview table converted to virtualized QTableView + QAbstractTableModel (new BatchPreviewModel + BatchRowHeightDelegate) โ€” eliminates ~470,000 QTableWidgetItem allocations per render. _f_refresh / _p_refresh shrink from 23/21 lines to 4 lines as per-cell widget construction moves into data(index, role)
    • _f_ingest / _p_ingest์™€ _f_do_rename / _p_do_rename์€ BatchIngestWorker(QThread)์™€ BatchRenameWorker(QThread)๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์‹คํ–‰, ์ทจ์†Œ ๊ฐ€๋Šฅํ•œ ๋ชจ๋‹ฌ QProgressDialog(ํด๋”๋ณ„ ์ง„ํ–‰๋ฅ ) ๋ฐฉ์‹. rename worker ์•ˆ์—์„œ๋Š” ๊นŠ์ด ์šฐ์„  ํด๋” ์ˆœํšŒ์™€ WinError 5 ์ผ๊ด„ ์žฌ์‹œ๋„ ๋กœ์ง์„ ๊ทธ๋Œ€๋กœ ๋ณด์กด / Ingest and rename now run on BatchIngestWorker(QThread) / BatchRenameWorker(QThread) with a modal QProgressDialog (cancel + per-folder progress); the rename worker preserves the depth-first folder traversal and the WinError 5 bulk-retry loop
    • ํด๋” / ํŒŒ์ผ ํƒญ์ด 'f' / 'p' kind ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋™์ผ model / worker ํด๋ž˜์Šค๋ฅผ ๊ณต์œ  / Both folder + file tabs share the same model / worker classes via a 'f' / 'p' kind parameter
    • 5๊ฐœ ์–ธ์–ด์— i18n ํ‚ค 3๊ฐœ ์ถ”๊ฐ€ (dlg_cancel, batch_ingest_progress, batch_rename_progress). ๋‘ worker ๋‹ค์ด์–ผ๋กœ๊ทธ์˜ QProgressDialog ์ฐฝ ์ œ๋ชฉ๋„ Qt ๊ธฐ๋ณธ๊ฐ’ (python, sys.argv[0] ์œ ๋ž˜)์—์„œ FileNexusSuite๋กœ ์žฌ์ •์˜ / 3 new i18n keys ร— 5 languages. Window title also overridden from Qt's default (python, from sys.argv[0]) to FileNexusSuite
  • ๋ฉ”์ธ ์ฝ”๋“œ + ๋ถ€์† ๋ฌธ์„œ ์˜๋ฌธ ๊ธฐ๋ณธ ์ „ํ™˜ / English-first transition for main codebase + supporting documents

    • FileNexusSuite.py ํ•œ๊ตญ์–ด ์ฃผ์„/docstring/๋””๋ฒ„๊ทธ ๋กœ๊ทธ 1,133์ค„์„ ์˜๋ฌธ ์ „ํ™˜ (์‚ฌ์šฉ์ž ๋…ธ์ถœ UI ๋ฌธ์ž์—ด, ์–ธ์–ด ๋ถ„๊ธฐ ๊ฐ€์ด๋“œ ์ฝ˜ํ…์ธ , ์‚ฌ์ „ ํ‚ค/๊ฐ’์€ ํ•œ๊ตญ์–ด ๋ณด์กด). ์•ˆ์ „์„ฑ์„ ์œ„ํ•ด ๋‘ commit ๋ถ„๋ฆฌ: Step 1+2 (506์ค„, f54bc81)์™€ Step 3 final (627์ค„, 177598b) / 1,133 lines of Korean comments/docstrings/debug logs translated to English (user-facing UI strings, language-branched guides, dictionary keys/values preserved). Split into two commits for safety
    • test_file_nexus.py๋„ ๋™์ผ ์–‘์‹์œผ๋กœ 277๊ฐœ ๋งคํ•‘ (F1 L1โ€“L3500: 90, F2 L3501โ€“L4100: 120, F3 L4101โ€“L4590: 67). 459 ๋ณดํ˜ธ ๋ผ์ธ(SAMPLE_KO_* ์ž…๋ ฅ ๋ณ€์ˆ˜, assertEqual ๊ธฐ๋Œ€๊ฐ’, ํ•œ๊ตญ์–ด ์ธ์šฉ 9๊ฑด ๋“ฑ)์€ ์–ธ์–ด ์ค‘๋ฆฝ ๋™์ž‘ ๊ฒ€์ฆ ์ฝ”๋“œ๋ผ ๋ณด์กด / test_file_nexus.py: 277 mappings across 3 chunks. 459 protected lines preserved (SAMPLE_KO_* test inputs, assertEqual expected outputs, 9 Korean evidentiary citations)
    • STORY.md ํ•œ/์˜ ์ด์ค‘์–ธ์–ด ์–‘์‹ (c469f6b), README.txt ์˜๋ฌธ ๊ธฐ๋ณธ + ๋‹ค๊ตญ์–ด ๋ผ๋ฒจ (3922250), ๋นŒ๋“œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์˜๋ฌธ ์ „ํ™˜ (7ca4f734) / STORY.md bilingual, README.txt English-first multilingual, build metadata translated
  • 12๊ฐœ ์ธ๋ผ์ธ UI ๋ฌธ์ž์—ด TRANSLATIONS ์ด์ „ / 12 inline UI strings migrated to TRANSLATIONS

    • 14๊ฐœ ์‹ ๊ทœ ๋ฒˆ์—ญ ํ‚ค ร— 5๊ฐœ ์–ธ์–ด = 70๊ฐœ ํ•ญ๋ชฉ ์ถ”๊ฐ€ (crash_* ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋‹ค์ด์–ผ๋กœ๊ทธ / already_running_* ์ค‘๋ณต ์‹คํ–‰ / rename_skip_* Batch Renamer ์Šคํ‚ต / lib_required_msg Bulk Fixer ImportError ร— 4 / dlg_info ๋‹ค์ด์–ผ๋กœ๊ทธ ํ—ค๋” fallback / help_* ๋„์›€๋ง ์ฐฝ) / 14 new translation keys ร— 5 languages = 70 entries
    • dead code ์ œ๊ฑฐ: SHORTCUT_DEFS์˜ 'label' ํ•„๋“œ (๋ณ„๋„ _sc_label_keys ๋งต์ด i18n ํ‚ค ๋ณด์œ , ํ•œ ๋ฒˆ๋„ ์ฝํžˆ์ง€ ์•Š๋˜ ์ฝ”๋“œ), _CARD_CFG์˜ 'label' ํ•„๋“œ (ํ•œ ์ž๋ฆฌ๋งŒ ์‚ฌ์šฉ โ†’ _theme_label() ํ˜ธ์ถœ๋กœ ๋Œ€์ฒด) / Dead code cleaned: SHORTCUT_DEFS['label'] and _CARD_CFG['label']
    • TRANSLATIONS ๋ฐ”๊นฅ ํ•œ๊ตญ์–ด ๋ฌธ์ž์—ด 191 โ†’ 142 (-49). ๋‚จ์€ 142๊ฑด์€ ์˜๋„๋œ ๋ถ€๋ถ„ (122๊ฑด if lang == 'ko' ๋ถ„๊ธฐ ์•ˆ ๊ฐ€์ด๋“œ ์ฝ˜ํ…์ธ , 7๊ฑด ํฐํŠธ/์ €์ž‘๊ถŒ/์–ธ์–ด๋ช…, 4๊ฑด _section_icons ํ˜ธํ™˜์„ฑ lookup, 9๊ฑด ๊ธฐํƒ€) / Korean string literals outside TRANSLATIONS reduced 191 โ†’ 142

๐Ÿ“ฆ ์ถ”๊ฐ€ / Added

  • Batch Renamer ๊ทธ๋ฃน ํ—ค๋” + ์ƒˆ ์ด๋ฆ„ ์ปฌ๋Ÿผ ํˆดํŒ / Batch Renamer tooltips on group header and new-name column
    • ๊ธฐ์กด์—” ์›๋ณธ ํŒŒ์ผ๋ช… ์ปฌ๋Ÿผ์—๋งŒ setToolTip(full_path) ๋ฐ•ํ˜€ ์žˆ์—ˆ์–ด โ€” ๊ทธ๋ฃน ํ—ค๋”(๐Ÿ“‚ parent_folder)์™€ ์ƒˆ ์ด๋ฆ„ ์ปฌ๋Ÿผ์€ ํˆดํŒ โŒ๋ผ ๊ธด ํ•œ๊ตญ์–ด ์ฑ… ์ œ๋ชฉ์ด๋‚˜ ์ฑ•ํ„ฐ ์ด๋ฆ„์ด ์ปฌ๋Ÿผ ๋„ˆ๋น„๋กœ ์ž˜๋ ธ์„ ๋•Œ ํ•œ๋ˆˆ์— ์ •์ฐฐ โŒ / Previously only original-name column had setToolTip(full_path) โ€” group header and new-name column had no tooltips
    • _f_refresh / _p_refresh ์–‘์ชฝ์—์„œ ์„ธ ์ž๋ฆฌ(๊ทธ๋ฃน ํ—ค๋” / ์›๋ณธ ์ปฌ๋Ÿผ / ์ƒˆ ์ด๋ฆ„ ์ปฌ๋Ÿผ)์— ์ผ๊ด€ ์ ์šฉ / Now applied symmetrically across both panels at three sites
    • ์›๋ณธ๊ณผ ์ƒˆ ์ด๋ฆ„ ํ‘œ์‹œ ์‚ฌ์ด์˜ ๋Œ€์นญ์„ฑ ๋ณต์› / Restores symmetry between original and new-name display

๐Ÿ› ์ˆ˜์ • / Fixed

  • Batch Renamer (file mode) ๊ทธ๋ฃน๋ณ„ ์ž๋ฆฟ์ˆ˜ / per-group digit width

    • _p_calc_preview๊ฐ€ ๊ฐ€์žฅ ํฐ ๊ทธ๋ฃน์˜ ํŒŒ์ผ ์ˆ˜์—์„œ ๊ณ„์‚ฐํ•œ ๋‹จ์ผ auto_d ๊ฐ’์„ ๋ชจ๋“  ๊ทธ๋ฃน์— ์ „์—ญ ์ ์šฉ โ†’ 9-ํŒŒ์ผ ๊ทธ๋ฃน์ด 100+ ํŒŒ์ผ ๊ทธ๋ฃน๊ณผ ๊ฐ™์€ 3์ž๋ฆฌ๋กœ ๋ Œ๋”๋ง๋˜๋˜ ๋ฌธ์ œ. ์ด์ œ ๊ฐ ๊ทธ๋ฃน์ด ์ž์‹ ์˜ ํŒŒ์ผ ์ˆ˜์— ๋งž์ถฐ ์ž๋ฆฟ์ˆ˜ ๊ณ„์‚ฐ (grp_max_num = start + len(files) - 1) / Each group now computes its own digit width based on its own file count
  • Batch Renamer ingest ํ†ตํ•ฉ empty-folder ๋‹ค์ด์–ผ๋กœ๊ทธ / consolidated empty-folder dialog

    • ๋น„์–ด์žˆ๋Š” ํด๋” ์—ฌ๋Ÿฌ ๊ฐœ ๋“œ๋ž˜๊ทธ ์‹œ ํด๋”๋งˆ๋‹ค ๋ชจ๋‹ฌ _dlg_info๊ฐ€ ๋–  ํŒ์—… ํญ์ฃผ๋กœ ~21+ ํด๋”์—์„œ ์•ฑ ๊ฐ•์ œ ์ข…๋ฃŒ ์œ„ํ—˜. ์ด์ œ ๋นˆ ํด๋” ๋ชฉ๋ก์„ ๋ชจ์•„ ๋‹จ์ผ ํ†ตํ•ฉ ๋‹ค์ด์–ผ๋กœ๊ทธ (โ‰ค10๊ฐœ: ์ „์ฒด ํ‘œ์‹œ, >10๊ฐœ: ์ฒ˜์Œ 10๊ฐœ + ... (+N)) / Skipped folders consolidated into a single dialog (โ‰ค10 paths shown, >10 truncated with ... (+N))
  • ์ค‘๊ตญ์–ด ์‚ฌ์ „์˜ i18n ์ผ๊ด€์„ฑ / i18n consistency in Chinese dictionaries

    • zh_tw์— simplified ๋ˆ„์ถœ 2๊ฑด (tag_drop2, merge_sel_one), zh_cn์— merge_sel_one ํ‚ค ๋ˆ„๋ฝ. simplified ์‚ฌ์šฉ์ž๊ฐ€ _t์˜ zh_cn โ†’ zh_tw fallback path๋ฅผ silentํ•˜๊ฒŒ ํƒ€๊ณ  traditional ๊ฐ’์„ ๋ฐ›๋˜ ์šฐ์—ฐํ•œ ์‹œ๊ฐ ์ผ์น˜ ํ˜„์ƒ. ์–‘์ชฝ ์‚ฌ์ „์ด ๊ฐ์ž์˜ ์Šคํฌ๋ฆฝํŠธ๋กœ ํ‚ค๋ฅผ ๊ฐ–๋„๋ก ์ •์ • / Both dictionaries now carry the keys in their respective scripts
  • legacy %APPDATA% config fallback ์ œ๊ฑฐ / Dropped legacy %APPDATA% config fallback in _show_already_running_popup

    • pre-v1.0.x try-block ์ž”์žฌ โ€” ~/AppData/Roaming/FileNexusSuite/FileNexusSuite.json์„ ๋จผ์ € ์‹œ๋„ ํ›„ __file__ ์ƒ๋Œ€ ๊ฒฝ๋กœ fallback. ๋‘ ๋ถ„๊ธฐ ๋ชจ๋‘ dead since v1.0.x onward (_CONFIG_PATH = _app_dir() / "FileNexusSuite.json"๋งŒ ์‚ฌ์šฉ). 14์ค„ โ†’ 10์ค„ / 14-line probe-and-fallback reduced to 10 lines (-4 lines, single source of truth)

๐Ÿ”„ ๋ณ€๊ฒฝ / Changed

  • Batch Renamer ingest: O(1) ์ค‘๋ณต ๊ฒ€์‚ฌ / O(1) duplicate-path check
    • ๊ธฐ์กด ๊ทธ๋ฃน๋“ค์— ๋Œ€ํ•œ O(Nยฒ) any() ์„ ํ˜• ๊ฒ€์‚ฌ๋ฅผ set ์กฐํšŒ๋กœ ๊ต์ฒด. ํด๋” ingest (_f_ingest)์™€ ํŒŒ์ผ ingest (_p_ingest, os.walk ์žฌ๊ท€ path ํฌํ•จ) ์–‘์ชฝ์— ๋Œ€์นญ ์ ์šฉ. ~2,700 ํด๋” ์ผ๊ด„ ๋“œ๋ž˜๊ทธ ์‹œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ CPU ์‹œ๊ฐ„ ~170ms ์ ˆ์•ฝ / set lookup replacing O(Nยฒ) any() linear scan, saves ~170 ms on 2,700 folders dragged

๐Ÿงช ํ…Œ์ŠคํŠธ ์ž๋™ํ™” / Test Automation

  • 535 โ†’ 594 passing (+59), 61 classes (+3), 0 failures / 0 errors / 5 skipped (ํ•œ๋ฆผ ๋กœ์ปฌ + Git ํด๋” ์ด์ค‘ ๊ฒ€์ฆ) / 535 โ†’ 594 passing (+59), 61 classes (+3), zero failures/errors, 5 intentional skips (Hanrim local + Git folder dual verification)
  • TestBatchRenamerDigitWidth (+20) โ€” _p_calc_preview์˜ ๊ทธ๋ฃน๋ณ„ digit width ๋กœ์ง ์ˆœํ•จ์ˆ˜ ์ถ”์ถœ (auto/nopad/pad2/pad3 ๋ชจ๋“œ ร— ๊ฒฝ๊ณ„ ํŒŒ์ผ ์ˆ˜ ร— ์‹œ์ž‘๊ฐ’ + per-group independence) / Pure-function extraction of per-group digit-width logic
  • TestBatchRenamerEmptyFolderDialog (+5 โ†’ -5 skipped) โ€” ํ†ตํ•ฉ empty-folder dialog์˜ ํ†ตํ•ฉ ๊ฒ€์ฆ. async BatchIngestWorker๊ฐ€ _BarePanel ์–‘์‹์—์„œ๋Š” QObject๊ฐ€ โŒ๋ผ skip ์–‘์‹. ํ†ตํ•ฉ ๋™์ž‘ ์ž์ฒด๋Š” _run_ingest_worker.on_done() ์•ˆ์—์„œ ๋ณด์กด๋จ / Integration test of consolidated empty-folder dialog (5 skipped due to async worker requirement)
  • TestBatchRenamerScenarioB (+5) โ€” ์‹œ๋‚˜๋ฆฌ์˜ค B์˜ source-grep ๊ฒ€์ฆ. 4 ์‹ ๊ทœ ํด๋ž˜์Šค (BatchPreviewModel / BatchRowHeightDelegate / BatchIngestWorker / BatchRenameWorker) + PySide6 imports + QTableView() ๊ต์ฒด + worker kind ๊ฒ€์ฆ + model ๊ณต๊ฐœ API / Source-grep checks for scenario B classes (PySide6 not required)
  • _run_fix ์˜๋ฌธ sibling ํ…Œ์ŠคํŠธ (+29) โ€” 6 ํด๋ž˜์Šค ร— ์˜๋ฌธ ์ž๋งค ํ…Œ์ŠคํŠธ, _SENT_END = '.!?โ€ฆใ€‚๏ผ๏ผŸโ€ฅใ€ใ€๏ผ‰)}>]"\''์˜ ์–ธ์–ด ์ค‘๋ฆฝ ๋™์ž‘์„ ์˜๋ฌธ ์ž…๋ ฅ์œผ๋กœ ๊ฒ€์ฆ. 12 SAMPLE_EN_* fixtures (CC0 1.0) ์ถ”๊ฐ€ / 29 English sibling tests across 6 classes
  • 8 unclosed file handle ์ œ๊ฑฐ โ€” open(path, encoding='utf-8').read() ์•ˆํ‹ฐํŒจํ„ด์„ with open(...) as _f ์–‘์‹์œผ๋กœ ์ •์ •. ResourceWarning 8 โ†’ 0 / 8 unclosed file handles closed (ResourceWarnings 8 โ†’ 0)

๐Ÿ“ ํŒŒ์ผ ๋ณ€๊ฒฝ / File Changes

ํŒŒ์ผ / File ๋ณ€๊ฒฝ / Change
FileNexusSuite.py 14,915 โ†’ 15,347 ์ค„ (+432) โ€” ์‹œ๋‚˜๋ฆฌ์˜ค B refactor + i18n migration + python ์ œ๋ชฉ ์ •์ • / Scenario B refactor + i18n migration + python title fix
test_file_nexus.py 4,798 โ†’ 5,008 ์ค„ (+210) โ€” ์ž๋™ํ™” ํ…Œ์ŠคํŠธ +59๊ฑด / +59 automated tests
LICENSE ๋ณ€๊ฒฝ โŒ (v1.0.10 ๊ทธ๋Œ€๋กœ ๋ณด์กด) / Unchanged
version_info.txt 4๊ณณ ๊ฐฑ์‹  (filevers / prodvers / FileVersion / ProductVersion) / Version (4 locations) updated
README.md / README_KO.md version ๋ฑƒ์ง€ (1.0.10 โ†’ 1.0.11) + tests ๋ฑƒ์ง€ (589 โ†’ 594 passing) / version + tests badges updated
README.txt v1.0.11 ๊ฐฑ์‹  / v1.0.11 updated
SECURITY.md Supported Versions ๊ฐฑ์‹  (1.0.10 โ†’ 1.0.11) / Supported Versions updated
CHANGELOG.md / CHANGELOG_KO.md v1.0.11 ์„น์…˜ ์ถ”๊ฐ€ (์‹œ๋‚˜๋ฆฌ์˜ค B + python ์ œ๋ชฉ ์ •์ • ํก์ˆ˜) / v1.0.11 section added

๐Ÿ” ๋ฆด๋ฆฌ์ฆˆ ์„œ๋ช… / Release Signing

  • ๋‹จ์ผ Release ์ปค๋ฐ‹ + SSH ์„œ๋ช… (Ed25519, fingerprint SHA256:4H2f7lrFfI4u0YP0dpp6N9BQH2f74iKjjMRHu7lyjKI) / Single Release commit + SSH signature
  • ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ / Commit message: Release v1.0.11: Batch Renamer scalability + English-first transition + 12 inline UI i18n
  • Commit hash: 3ca7987
  • ํƒœ๊ทธ v1.0.11 SSH ์„œ๋ช…, GitHub Verified ๋ฑƒ์ง€ / Tag v1.0.11 SSH-signed, GitHub Verified badge
  • GitHub Actions CI windows-latest + Python 3.10 ํ™˜๊ฒฝ์—์„œ ์ž๋™ ํ†ต๊ณผ / GitHub Actions CI passed on windows-latest + Python 3.10

โš  ์•Œ๋ ค์ง„ ์ด์Šˆ / Known Issues

  • ๋ณธ ๋ฆด๋ฆฌ์ฆˆ์—์„œ ์‹ ๊ทœ ์•Œ๋ ค์ง„ ์ด์Šˆ โŒ โ€” v1.0.10์˜ *`test_file_nexus.py...
Read more

File Nexus Suite v1.0.10

Choose a tag to compare

@MerciHanrim MerciHanrim released this 25 Apr 15:43
v1.0.10
382eb9a

v1.0.10 โ€” MIT ์ „ํ™˜๊ณผ OSS ๊ฒฐ์˜ ์‹œ์ž‘์ : ๋ผ์ด์„ ์Šค ์ „ํ™˜ + LGPL ํ˜ธํ™˜์„ฑ ๋ช…์‹œํ™” + SignPath OSS Sponsorship ์‹ ์ฒญ / The Start of the OSS Turn: License Transition + LGPL Compatibility Documentation + SignPath OSS Sponsorship Application

v1.0.10์€ v1.0.5 ~ v1.0.9์˜ 5๊ฐœ ๋ฆด๋ฆฌ์ฆˆ๋กœ ๋ˆ„์ ๋œ v1.0.x ์‹œ๋ฆฌ์ฆˆ ์ธํ”„๋ผ๋ฅผ OSS ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ ๊ฐœ๋ฐฉํ•˜๋Š” ๊ฒฐ์ •์  ์ „ํ™˜์ ์ž…๋‹ˆ๋‹ค. ๋ณธ ๋ฆด๋ฆฌ์ฆˆ๋Š” ์„ธ ํŠธ๋ž™(๋ผ์ด์„ ์Šค ์ „ํ™˜ Freeware โ†’ MIT, LGPL ํ˜ธํ™˜์„ฑ ๋ช…์‹œ์  ๋ฌธ์„œํ™”, SignPath OSS Sponsorship ์‹ ์ฒญ ํŠธ๋ž™)์˜ ๋ฌถ์Œ์ด๋ฉฐ, ์ฝ”๋“œ ๋ณ€๊ฒฝ๋Ÿ‰์€ v1.0.5~v1.0.9 ์–ด๋–ค ๋ฆด๋ฆฌ์ฆˆ๋ณด๋‹ค๋„ ์ ์Šต๋‹ˆ๋‹ค(FileNexusSuite.py ๋ผ์ธ ์ˆ˜ ๋ณ€ํ™” 0, ํ…์ŠคํŠธ ๋‚ด์šฉ๋งŒ ๋ณ€๊ฒฝ). ๊ทธ๋Ÿฌ๋‚˜ ์˜๋ฏธ ๋ณ€ํ™”๋Š” ๊ฐ€์žฅ ํฝ๋‹ˆ๋‹ค โ€” ์‚ฌ์šฉ์ž๊ฐ€ ๋ณธ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋ฐ›์•„ ์“ธ ๋•Œ์˜ ๊ถŒ๋ฆฌ๊ฐ€ ๊ธˆ์ง€์—์„œ ํ—ˆ์šฉ์œผ๋กœ ์ •ํ™•ํžˆ ์ •๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

v1.0.10 marks the decisive turning point where the v1.0.x series infrastructure โ€” accumulated across five releases (v1.0.5 ~ v1.0.9) โ€” is opened to the OSS community. This release bundles three tracks (license transition Freeware โ†’ MIT, explicit LGPL compatibility documentation, SignPath OSS Sponsorship application track). Code changes are smaller than any v1.0.5~v1.0.9 release (FileNexusSuite.py line count delta 0, text-only changes). Yet the semantic change is the largest: the rights users gain when they receive this software have been flipped from prohibited to permitted in the exact opposite direction.


โœจ ์ฃผ์š” ๋ณ€๊ฒฝ / Major Changes

  • ๋ผ์ด์„ ์Šค ์ „ํ™˜: Freeware (์†Œ์Šค ๊ณต๊ฐœ) โ†’ MIT License / License transition: Freeware (source available) โ†’ MIT License

    • ์‚ฌ์šฉยท์ˆ˜์ •ยท์žฌ๋ฐฐํฌยทํŒ๋งค๊ฐ€ ๋ชจ๋‘ ์ž์œ ๋กญ๊ฒŒ ํ—ˆ์šฉ (์ €์ž‘๊ถŒ ๊ณ ์ง€ ์œ ์ง€ ์กฐ๊ฑด). ์ด์ „ ๋ฒ„์ „์˜ "๋ฌด๋‹จ ์žฌ๋ฐฐํฌยท์žฌ๊ฐ€๊ณตยทํŒ๋งค ๊ธˆ์ง€" ๋ฌธ๊ตฌ๊ฐ€ ์ •ํ™•ํžˆ ์ •๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ์ „ํ™˜ / All of use, modify, redistribute, and sell are now freely permitted (provided that the copyright notice is retained). The previous "unauthorized redistribution, repackaging, or resale prohibited" clause is reversed in the exact opposite direction
    • ์‚ฌ์šฉ์ž๋Š” ๋ณธ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ forkํ•˜์—ฌ ์ž์‹ ์˜ ํ”„๋กœ์ ํŠธ๋กœ ๋ฐœ์ „์‹œํ‚ค๊ฑฐ๋‚˜, ์ˆ˜์ •๋ณธ์„ ๋ฐฐํฌํ•˜๊ฑฐ๋‚˜, ์ƒ์—…์  ์ œํ’ˆ์— ํ†ตํ•ฉ ๊ฐ€๋Šฅ / Users may fork this software to develop into their own projects, distribute modified versions, or integrate into commercial products
    • ํ•œ๋ฆผ์ด *"๊ฐœ์ธ ์ž‘์—… ๋„๊ตฌ๋กœ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ, ๊ฐ™์€ ์ž‘์—…์„ ํ•˜๋Š” ๋‹ค๋ฅธ ๋ถ„๋“ค์—๊ฒŒ๋„ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ"*์ด๋ผ๋Š” ๊ฒฐ๋กœ v1.0.x ์‹œ๋ฆฌ์ฆˆ ๋ˆ„์ ์˜ ๊ฒฐ๊ณผ๋ฅผ OSS ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ ๊ฐœ๋ฐฉ / Released by Hanrim with the spirit "originally built as a personal tool, in the hope it may help others with similar workflows"
  • MIT ์„ ํƒ์˜ ๊ฒฐ / Why MIT specifically

    • ๊ฐ„๊ฒฐ์„ฑ: 21์ค„ ํ‘œ์ค€ ํ…์ŠคํŠธ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›€ / Conciseness: 21-line standard text easy for users to read and understand
    • ํ˜ธํ™˜์„ฑ: GPL์„ ๋น„๋กฏํ•œ ๊ฑฐ์˜ ๋ชจ๋“  OSS ๋ผ์ด์„ ์Šค์™€ ํ˜ธํ™˜ โ€” fork ์‹œ ๋ผ์ด์„ ์Šค ์ถฉ๋Œ 0 / Compatibility: Compatible with virtually all OSS licenses including GPL โ€” zero license conflicts when forked
    • ์ƒ์—… ํ™œ์šฉ ๋ช…์‹œ์  ํ—ˆ์šฉ: "GPL ์ „์—ผ์„ฑ" ๊ฐ™์€ ์˜๋ฌด ๋ฐœ์ƒ 0 / Commercial use explicitly permitted: zero obligations like "GPL contagion"
    • OSS ์—…๊ณ„ ํ‘œ์ค€: GitHub Top ํ”„๋กœ์ ํŠธ์˜ 50% ์ด์ƒ์ด MIT ์‚ฌ์šฉ / OSS industry standard: 50%+ of GitHub Top projects use MIT
  • Copyright ยฉ 2026 Hanrim. All rights reserved. โ†’ Copyright ยฉ 2026 Hanrim โ€” "All rights reserved" ํ‘œ๊ธฐ 6๊ณณ ์ผ๊ด„ ์ •๋ฆฌ. 1910๋…„ ๋ถ€์—๋…ธ์Šค์•„์ด๋ ˆ์Šค ํ˜‘์•ฝ ์ž”์žฌ๋กœ ํ˜„๋Œ€ ์ €์ž‘๊ถŒ๋ฒ•์— ๋ฒ•์  ์˜๋ฏธ ์—†์Œ + MIT ๋ผ์ด์„ ์Šค ์˜๋ฏธ์™€ ๊ฒฐ ์ผ๊ด€์„ฑ / "All rights reserved" notation cleaned across 6 locations. Vestige from the 1910 Buenos Aires Convention with no legal meaning in modern copyright law + consistency with MIT license semantics


๐Ÿ“ฆ ์ถ”๊ฐ€ / Added

  • LGPL ํ˜ธํ™˜์„ฑ ๋ช…์‹œ์  ๋ฌธ์„œํ™” / Explicit LGPL compatibility documentation

    • _build_license_html()์˜ PySide6 (LGPL-3.0) / chardet (LGPL-2.1) note ํ•„๋“œ์— LGPL replacement ์•ˆ๋‚ด 1๋ฌธ์žฅ์”ฉ ์ถ”๊ฐ€ / One-sentence LGPL replacement note added to PySide6 (LGPL-3.0) / chardet (LGPL-2.1) note fields in _build_license_html()
    • ์•ˆ๋‚ด ๋ฌธ์žฅ: "File Nexus Suite is built with PyInstaller. Users may replace this LGPL library by rebuilding from source โ€” see the GitHub repository for build instructions."
    • PyInstaller --onedir ๋นŒ๋“œ ๋ชจ๋“œ์˜ _internal/ ํด๋” ๋ถ„๋ฆฌ ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ LGPL ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ต์ฒด ๊ฐ€๋Šฅํ•จ์„ ๋ช…์‹œ. LGPL ยง3 ์˜๋ฌด๋ฅผ ์•”๋ฌต์  ์ถฉ์กฑ(GitHub source ๊ณต๊ฐœ)์—์„œ ๋ช…์‹œ์  ์ถฉ์กฑ์œผ๋กœ ๊ฐ•ํ™”ํ•˜์—ฌ ํšŒ์ƒ‰์ง€๋Œ€ ์˜๊ตฌ ์ฐจ๋‹จ / Explicitly states that users can directly replace LGPL libraries thanks to PyInstaller --onedir mode's _internal/ folder separation. Strengthens LGPL ยง3 obligation from implicit fulfillment (GitHub source publication) to explicit documentation, permanently closing the gray zone
  • README.txt _internal ํด๋” ๋ณดํ˜ธ ์•ˆ๋‚ด / README.txt _internal folder protection note

    • PyInstaller --onedir ๋นŒ๋“œ ๋ชจ๋“œ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ _internal/ ํด๋”๋ฅผ *"ํ•„์š” ์—†์–ด ๋ณด์ด๋Š” ๋ฐ์ดํ„ฐ"*๋กœ ์˜คํ•ดํ•˜์—ฌ ์‚ญ์ œํ•  ์œ„ํ—˜์„ ํ•œ/์˜ ์–‘์ชฝ ์•ˆ๋‚ด๋กœ ์ฐจ๋‹จ / Mitigates the risk of users mistaking _internal/ for "seemingly unnecessary data" and deleting it, with both Korean and English notices
    • README.txt๊ฐ€ *"ํฌ์žฅ์ง€ ์•ˆ๋‚ด ๋ผ๋ฒจ"*์—์„œ ์ง„์งœ ์ •์ฒด์„ฑ์ธ *"_internal ๋ณดํ˜ธ ์žฅ์น˜"*๋กœ ์˜๋„-์‚ฐ์ถœ๋ฌผ ์ •ํ•ฉ์„ ๊ฐ–์ถค / README.txt achieves intent-artifact alignment, transitioning from "package label" to its true identity as "_internal protection device"
  • README "์ดํƒ€์‹ฌ" ํ•œ ์ค„ / README "altruism" line

    • README.md / README_EN.md ๋ผ์ด์„ ์Šค ์„น์…˜ + _build_license_html() ๋ณธ ํ”„๋กœ์ ํŠธ ํ•ญ๋ชฉ note์— ์ผ๊ด€ ์ถ”๊ฐ€. "๊ฐœ์ธ ์ž‘์—… ๋„๊ตฌ๋กœ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ, ๊ฐ™์€ ์ž‘์—…์„ ํ•˜๋Š” ๋‹ค๋ฅธ ๋ถ„๋“ค์—๊ฒŒ๋„ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ๋ฉฐ MIT ๋ผ์ด์„ ์Šค๋กœ ๊ณต๊ฐœํ•ฉ๋‹ˆ๋‹ค." / Added consistently to README.md / README_EN.md license section + _build_license_html() project entry note. "Originally built as a personal tool, now released under MIT in the hope it may help others with similar workflows."
    • GitHub README์™€ ์•ฑ ๋‚ด ๋ผ์ด์„ ์Šค ํŽ˜์ด์ง€๊ฐ€ ๊ฐ™์€ ๊ฒฐ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌ / GitHub README and in-app license page deliver the same message to users

๐Ÿ”„ ๋ณ€๊ฒฝ / Changed

  • 5์–ธ์–ด license_summary ํ‚ค ์˜๋ฏธ ์ •๋ฐ˜๋Œ€ ์žฌ์ž‘์„ฑ / 5-language license_summary key reworded with opposite semantics

    • en/ko/ja/zh_cn/zh_tw ๋ชจ๋‘ "๋ฌด๋‹จ ์žฌ๋ฐฐํฌยท์žฌ๊ฐ€๊ณตยทํŒ๋งค ๊ธˆ์ง€" โ†’ *"์‚ฌ์šฉยท์ˆ˜์ •ยท์žฌ๋ฐฐํฌยทํŒ๋งค ๋ชจ๋‘ ํ—ˆ์šฉ"*์œผ๋กœ ์ •ํ™•ํžˆ ์ •๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ. zh_cn์€ v1.0.9 ยง5.1.G fallback chain์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋„๋ก 5์–ธ์–ด ์ง์ ‘ ์ •์˜ ์œ ์ง€ (๋ผ์ด์„ ์Šค ํ•ต์‹ฌ ํ‚ค์ด๋ฏ€๋กœ zh_tw ์–ดํœ˜ ์ฐจ์ด ๋ณด์กด) / All five languages reworded from "unauthorized redistribution, repackaging, or resale prohibited" โ†’ "use, modify, redistribute, and sell all permitted". zh_cn maintains direct 5-language definition unaffected by v1.0.9 ยง5.1.G fallback chain (license-critical key, preserves zh_tw vocabulary distinction)
  • _build_license_html() ๋ณธ ํ”„๋กœ์ ํŠธ ํ•ญ๋ชฉ ์ „๋ฉด ์žฌ์ž‘์„ฑ / _build_license_html() project entry fully reworded

    • Freeware โ€” Free for Personal & Commercial Use โ†’ MIT License / Title field updated
    • note ํ•„๋“œ: "๋ฌด๋‹จ ์žฌ๋ฐฐํฌยท์žฌ๊ฐ€๊ณตยทํŒ๋งค ๊ธˆ์ง€" ๋‹จ๋ฝ โ†’ "MIT ๋ผ์ด์„ ์Šค / ์ €์ž‘๊ถŒ ๊ณ ์ง€ ์œ ์ง€ ์‹œ ๋ชจ๋“  ๊ถŒ๋ฆฌ ํ—ˆ์šฉ" ๋‹จ๋ฝ. "์ดํƒ€์‹ฌ" ํ•œ ์ค„ ์‹ ๊ทœ ์ถ”๊ฐ€, AI ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฒฐ ๋ณด์กด / note field reworded; "altruism" line newly added, AI pair programming context preserved
  • README ๋ฑƒ์ง€ ์‹œ๊ฐ ์ฒด๊ณ„ ์žฌ์ •๋ฆฝ / README badge visual system refined

    • *"v1.0.10์ด v1.0.x ์‹œ๋ฆฌ์ฆˆ์—์„œ OSS ๋„์ฐฉ์ "*์ด๋ผ๋Š” ๊ฒฐ์„ ์ƒ‰์˜ ํ๋ฆ„์œผ๋กœ ํ‘œํ˜„ / Expresses the narrative "v1.0.10 as the OSS arrival point of v1.0.x series" through color flow
    • ์‹œ์ž‘์  (#7B6FA3 ๋ณด๋ผ): version 1.0.10 / Starting point (#7B6FA3 purple): version 1.0.10
    • OSS ํ™œ๊ธฐ (#97CA00 ์ง™์€ OSS ์ดˆ๋ก): tests 535 passing / license MIT โ† v1.0.10 ์‹ ๊ทœ ์ž๋ฆฌ / OSS vitality (#97CA00 deep OSS green): tests 535 passing / license MIT โ† new placement in v1.0.10
    • ์ •์ฒด์„ฑ (#CC785C Anthropic ๊ตฌ๋ฆฟ๋น›): AI pair Claude / Download CTA / Identity (#CC785C Anthropic copper): AI pair Claude / Download CTA
    • ๋ธŒ๋žœ๋“œ ์ธ์šฉ (์™ธ๋ถ€ ํ‘œ์ค€ ๊ทธ๋Œ€๋กœ): python / PySide6 / platform / CI badge / Brand citations (external standards as-is): python / PySide6 / platform / CI badge
  • LICENSE ํŒŒ์ผ ํ˜•์‹ ์ „ํ™˜ / LICENSE file format transition

    • ์ž์ฒด ์ž‘์„ฑ Freeware ํ˜•์‹ โ†’ MIT ํ‘œ์ค€ 21์ค„ ํ…์ŠคํŠธ๋กœ ์ „ํ™˜. GitHub Licensee gem์ด ์ •ํ™•ํžˆ "MIT License" ์ž๋™ ํƒ์ง€ / Custom Freeware format โ†’ 21-line MIT standard text. GitHub Licensee gem now correctly auto-detects "MIT License"
    • ํ•œ๊ตญ์–ด ์•ˆ๋‚ด + Test Data Exception (CC0) ๋ถ€๋ก ๋ณด์กด. third-party libraries ๋ชฉ๋ก์€ LICENSE์—์„œ ์ œ๊ฑฐ (_build_license_html() + README๊ฐ€ ๋‹จ์ผ ์ง„์‹ค ์›์ฒœ ์ฑ…์ž„) / Korean notice + Test Data Exception (CC0) appendix preserved. Third-party libraries list removed from LICENSE (_build_license_html() + README take single source of truth responsibility)

โœ… ๊ฒ€์ฆ / Verified

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ผ์ด์„ ์Šค ํ˜ธํ™˜์„ฑ ๋ฌด๊ฒฐ ์ ๊ฒ€ / Library license compatibility integrity audit

    • 7์ข… ์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (Python/PySide6/chardet/python-docx/pdfplumber/openpyxl/python-hwpx) ๋ชจ๋‘ MIT ํ˜ธํ™˜ ํ™•์ธ / All 7 dependencies (Python/PySide6/chardet/python-docx/pdfplumber/openpyxl/python-hwpx) confirmed MIT-compatible
    • LGPL 2์ข…(PySide6/chardet)์˜ ยง3 ์˜๋ฌด๊ฐ€ (๊ฐ€) GitHub source ๊ณต๊ฐœ + (๋‹ค) ๋ช…์‹œ์  ์•ˆ๋‚ด ์ถ”๊ฐ€์˜ ์ด์ค‘ ๋ณด์žฅ์œผ๋กœ ํšŒ์ƒ‰์ง€๋Œ€ ์˜๊ตฌ ์ฐจ๋‹จ / LGPL libraries' ยง3 obligation permanently closed via dual guarantee: (๊ฐ€) GitHub source publication + (๋‹ค) explicit replacement note
  • ๊ฐœ์ธ ์ž์‚ฐ ๋ถ„๋ฆฌ ์ ๊ฒ€ / Personal asset separation audit

    • LICENSE / _build_license_html() / README / RELEASE_NOTE ๋ชจ๋“  OSS-facing ์‚ฐ์ถœ๋ฌผ์—์„œ ํ•œ๋ฆผ ๊ฐœ์ธ ์ž์‚ฐ(๋ธ”๋กœ๊ทธ, ๋ณธ๋ช… ๋“ฑ) ์ผ์ ˆ ๋ฏธํฌํ•จ ํ™•์ธ. ์ด ๊ฒฐ์€ v1.0.10 ์ดํ›„ ๋ชจ๋“  ๋ฆด๋ฆฌ์ฆˆ์— ์˜๊ตฌ ์ ์šฉ / All OSS-facing artifacts confirmed free of Hanrim's personal assets (blog, full name, etc.). This principle applies permanently from v1.0.10 onward

๐Ÿงช ํ…Œ์ŠคํŠธ ์ž๋™ํ™” / Test Automation

  • 535 passing (v1.0.9์™€ ๋™์ผ), 58๊ฐœ ํด๋ž˜์Šค, ์‹คํŒจยท์˜ค๋ฅ˜ยท์Šคํ‚ต 0 (ํ•œ๋ฆผ ๋กœ์ปฌ + Git ํด๋” ์ด์ค‘ ๊ฒ€์ฆ + GitHub Actions CI ํ†ต๊ณผ) / 535 passing (same as v1.0.9), 58 classes, zero failures/errors/skips (Hanrim local + Git folder dual verification + GitHub Actions CI passed)
  • v1.0.10 ๋ณ€๊ฒฝ ์˜์—ญ(๋ผ์ด์„ ์Šค ํ…์ŠคํŠธ 5์–ธ์–ด + ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ note 2๊ณณ + ํ‘ธํ„ฐ "All rights reserved" ์ œ๊ฑฐ + ๋ฒ„์ „ ๊ฐฑ์‹ )์ด ์ž๋™ ํ…Œ์ŠคํŠธ invariant์™€ ์ถฉ๋Œ 0 / Zero conflicts between v1.0.10 change areas (license text 5 languages + library notes 2 locations + footer "All rights reserved" removal + version update) and test invariants
  • v1.0.4 ์ž‘์—… ์‹œ์ ์— ๋„์ž…๋œ ์ •์ˆ˜ ํŠœํ”Œ ๋น„๊ต ํŒจํ„ด (parts = tuple(int(p) for p in ver.split('.')))์ด 1.0.10 ๊ฐ™์€ ๋‘ ์ž๋ฆฟ์ˆ˜ ํŒจ์น˜ ๋ฒ„์ „์„ ์ž๋™ ๋Œ€์‘ โ€” ๋ชจ๋“  ๋ฒ„์ „ ๋น„๊ต invariant ์ž์—ฐ ํ†ต๊ณผ / Integer tuple comparison pattern introduced in v1.0.4 automatically handles two-digit patch versions like 1.0.10 โ€” all version comparison invariants pass naturally

๐Ÿš€ ํ–ฅํ›„ ํŠธ๋ž™ / Deferred Tracks

  • SignPath OSS Sponsorship ์‹ ์ฒญ / SignPath OSS Sponsorship application
    • v1.0.10 Release publish ์งํ›„ signpath.org์— OSS Sponsorship ์‹ ์ฒญ์„œ ์ œ์ถœ. v1.0.10์ด *"Latest release: first MIT release"*๋กœ ์‹ ์ฒญ์„œ์— ๊ธฐ๋ก๋จ์œผ๋กœ์จ ๊ฒ€ํ†  ์‹ ๋ขฐ๋„ ๊ฐ•ํ™” / OSS Sponsorship application submitted to signpath.org immediately after v1.0.10 publish. v1.0.10 recorded in application as "Latest release: first MIT release" strengthens review credibility
    • ์ž๊ฒฉ ์กฐ๊ฑด 6๊ฐœ ๋ชจ๋‘ ์ถฉ์กฑ: OSI-approved license (MIT) / No malware / Actively maintained / Released / Documented / Verifiable build from source
    • ์Šน์ธ ํ›„ v1.0.11์—...
Read more

File Nexus Suite v1.0.9

Choose a tag to compare

@MerciHanrim MerciHanrim released this 25 Apr 12:53
v1.0.9
a3e61c9

v1.0.9 โ€” v1.0.x ์‹œ๋ฆฌ์ฆˆ ๋งˆ๋ฌด๋ฆฌ: ACDG ์‚ฌํ›„ ์ •๋ฆฌ ๋ฌถ์Œ (ํ‘œ๊ธฐ ์ •์ฑ… ๋™๊ธฐํ™” + ๋นŒ๋“œ ๋„๊ตฌ strict ๋ชจ๋“œ + zh_cn ์‚ฌ์ „ ์ •๋ฆฌ + fallback chain) / End of v1.0.x series: ACDG cleanup bundle (notation policy sync + build strict mode + zh_cn dictionary cleanup + fallback chain)

v1.0.9๋Š” v1.0.5 ~ v1.0.8 ์‚ฌ์ด 4๊ฐœ ๋ฆด๋ฆฌ์ฆˆ๋กœ ๋ฌด๊ฑฐ์›Œ์ง„ v1.0.x ์‹œ๋ฆฌ์ฆˆ๋ฅผ ๋‹ซ๋Š” ์‚ฌํ›„ ์ •๋ฆฌ / ๋ฐ์ดํ„ฐ ์ฒญ์†Œ ์นดํ…Œ๊ณ ๋ฆฌ ๋ฆด๋ฆฌ์ฆˆ์ž…๋‹ˆ๋‹ค. v1.0.8 ์ธ์ˆ˜์ธ๊ณ„ ยง5.1์—์„œ ์ •์˜๋œ ACDG 4๊ฐœ ์ž‘์—…(A: ํ‘œ๊ธฐ ์ •์ฑ… ๋™๊ธฐํ™”, C: ๋นŒ๋“œ ๋„๊ตฌ strict ๋ชจ๋“œ, D: HelpDialog ์ ๊ฒ€, G: zh_cn ์‚ฌ์ „ ์ •๋ฆฌ)์„ ๋ฌถ์–ด ์ง„ํ–‰ํ–ˆ์œผ๋ฉฐ, ๋‹ค์Œ ์‹œ๋ฆฌ์ฆˆ(v1.1.0 โ€” ๊ตฌ์กฐ ๋ฆฌํŒฉํ† ๋ง / ์ƒˆ ๊ธฐ๋Šฅ)์™€ ๊ฒฐ์„ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ยง5.1.D๋Š” ์ ๊ฒ€ ๊ฒฐ๊ณผ ์˜ต์…˜ C ์ ์šฉ ๋ถˆ์š”๋กœ 0์ค„ ์ž‘์—…์œผ๋กœ ๋งˆ๊ฐ๋˜์–ด ์ž ์žฌ ๊ฒฐํ•จ ์—†์Œ์ด ๋ฐ์ดํ„ฐ๋กœ ํ™•์ธ๋๊ณ , ยง5.1.G๋Š” ์ธ์ˆ˜์ธ๊ณ„ ๋ช…์„ธ "188๊ฐœ ํ‚ค"๊ฐ€ ๋ฐ์ดํ„ฐ๋กœ ๊ฒ€์ฆ๋˜์ง€ ์•Š์•„ ํ˜„์‹ค ๋ฐ์ดํ„ฐ 47๊ฐœ โ†’ invariant ๋ณดํ˜ธ 7๊ฐœ ์ œ์™ธ โ†’ 40๊ฐœ๋กœ ์ •์งํ•˜๊ฒŒ ์žฌ์ •์˜ํ•œ ํ›„ fallback chain(zh_cn โ†’ zh_tw โ†’ ko)์„ ํ•จ๊ป˜ ๋„์ž…ํ•˜์—ฌ ์‚ฌ์šฉ์ž ๋™์ž‘ ์˜ํ–ฅ 0์ด ์ •์˜์ƒ ๋ณด์žฅ๋˜๋„๋ก ๊ตฌ์กฐ์ ์œผ๋กœ ํ’€์—ˆ์Šต๋‹ˆ๋‹ค. 1์ฐจ ์ ์šฉ ํ›„ v1.0.5 ํšŒ๊ท€ ํ…Œ์ŠคํŠธ 6๊ฐœ FAIL์ด ๋ฐœ๊ฒฌ๋์œผ๋‚˜ ํšŒ๊ท€ ์ˆ˜์ • ์‚ฌ์ดํด์„ ๊ฑฐ์ณ 535/0/0/0์œผ๋กœ ๊นจ๋—์ด ๋‹ซํ˜”์Šต๋‹ˆ๋‹ค.

v1.0.9 closes the v1.0.x series, which had grown heavy across four releases (v1.0.5 ~ v1.0.8), under the post-cleanup / data hygiene category. It bundles the four ACDG tasks defined in v1.0.8 handover ยง5.1 (A: notation policy sync, C: build strict mode, D: HelpDialog audit, G: zh_cn dictionary cleanup), drawing a clear line from the next series (v1.1.0 โ€” structural refactor / new features). ยง5.1.D was closed as a 0-line task after the audit confirmed Option C didn't apply, with the absence of latent defects established as evidence; ยง5.1.G honestly re-defined the handover spec "188 keys" โ€” which was not verifiable in data โ€” to 47 actual matches โ†’ 40 after excluding 7 invariant-protected keys, while introducing a fallback chain (zh_cn โ†’ zh_tw โ†’ ko) so that user-observable behavior remains unchanged by definition. After initial application, six v1.0.5 regression tests failed, but a regression-fix cycle closed cleanly at 535/0/0/0.


โœจ ์ฃผ์š” ๊ธฐ๋Šฅ / Major Features

  • build_pyinstaller.py --strict ๋ชจ๋“œ ๋„์ž… / build_pyinstaller.py --strict mode introduced

    • ๋ฒ„์ „ ์ผ๊ด€์„ฑ ๊ฒ€์ฆ ๋‹จ๊ณ„๋ฅผ ๋นŒ๋“œ ์ „(step 5)์œผ๋กœ ๋ถ„๋ฆฌ. mismatch ์‹œ strict ๋ชจ๋“œ์—์„œ PyInstaller๊ฐ€ ์‹œ์ž‘๋„ ํ•˜๊ธฐ ์ „์— ์ฆ‰์‹œ abort๋˜์–ด ์ˆ˜์‹ญ ์ดˆ ๋นŒ๋“œ + UPX ์••์ถ• ์‹œ๊ฐ„ ์ ˆ์•ฝ + ๊ธฐ์กด ๋นŒ๋“œ ์‚ฐ์ถœ๋ฌผ ๋ณด์กด / Version consistency check separated to pre-build (step 5). In strict mode on mismatch, build aborts before PyInstaller even starts, saving tens-of-seconds build + UPX compression time and preserving prior dist artifacts
    • ์‹ ๊ทœ ํ•จ์ˆ˜ check_version_consistency(strict) ์ถ”๊ฐ€, step ์‹œํ€€์Šค 7โ†’8๋‹จ๊ณ„๋กœ ์žฌ์ •๋ ฌ / New function check_version_consistency(strict) added, step sequence reorganized 7โ†’8
    • build.bat wrapper์— %* ์ธ์ž ํŒจ์Šค์Šค๋ฃจ ์ถ”๊ฐ€ํ•˜์—ฌ build.bat --strict ์ง์ ‘ ํ˜ธ์ถœ ๊ฐ€๋Šฅ / build.bat wrapper now supports %* argument pass-through for direct build.bat --strict invocation
  • zh_cn ์‚ฌ์ „ fallback chain ๋„์ž… / zh_cn dictionary fallback chain introduced

    • _t() / _rt() ํ•จ์ˆ˜์— zh_cn โ†’ zh_tw โ†’ ko fallback chain ์ถ”๊ฐ€. v1.0.5๋ถ€ํ„ฐ ko ๋‹จ์ผ fallback์ด์—ˆ๋˜ ํ•œ๊ณ„ ๋ณด์™„ / _t() / _rt() now use zh_cn โ†’ zh_tw โ†’ ko chain. Improvement over single ko fallback since v1.0.5
    • zh_cn ์‚ฌ์ „์— ๋ฏธ์ •์˜ ํ‚ค๋Š” zh_tw๋กœ 1์ฐจ fallback๋˜์–ด ์‚ฌ์šฉ์ž ๋™์ž‘ ์˜ํ–ฅ 0์ด ์ •์˜์ƒ ๋ณด์žฅ / Keys missing in zh_cn fall back to zh_tw first, guaranteeing zero user-observable impact by definition
  • zh_cn ์‚ฌ์ „ 40๊ฐœ ํ‚ค ์ •๋ฆฌ / zh_cn dictionary 40-key cleanup

    • zh_cn โ†” zh_tw ๊ฐ’์ด 100% ๋™์ผํ•œ ํ‚ค 47๊ฐœ ์ค‘ invariant ๋ณดํ˜ธ 7๊ฐœ ์ œ์™ธํ•˜๊ณ  40๊ฐœ ์ •๋ฆฌ / 40 keys cleaned among 47 with values identical to zh_tw, excluding 7 invariant-protected keys
    • ์ •๋ฆฌ ๋Œ€์ƒ: ์ด๋ชจ์ง€/์‹ฌ๋ณผ (โ–ถ ๋“ฑ), ์งง์€ ๋‹จ์–ด (ๅ–ๆถˆ/ๅฎŒๆˆ/ๅญ—/่กŒ ๋“ฑ), ์ž๋ฆฟ์ˆ˜ ํ‘œ๊ธฐ (ๆœ€ๅฐ‘2ไฝ/ๅ›บๅฎš3ไฝ ๋“ฑ), ์ž๋ฆฌํ‘œ์‹œ์ž (ไพ‹: jpg, png, gif ๋“ฑ), ํ…Œ๋งˆ๋ช… (ๆทฑ่‰ฒ/่œ‚่œœ/่–ฐ่กฃ่‰ ๋“ฑ), ์ธ์ฝ”๋”ฉ ๋ผ๋ฒจ ์ผ๋ถ€ / Cleaned: emojis/symbols, short words, digit notations, placeholders, theme names, partial encoding labels
    • ๋ณดํ˜ธ๋œ 7๊ฐœ: dlg_yes/dlg_no/dlg_warning (๋‹ค์ด์–ผ๋กœ๊ทธ ๊ณตํ†ต), conv_status_done/conv_sub_epub2txt/conv_sub_txt2epub (๋ณ€ํ™˜ ์ƒํƒœ), rename_cancel (์ทจ์†Œ) / 7 protected: dialog commons, conversion status, cancel โ€” core UI keys retain direct 5-language definition
  • test_zh_cn_fallback_to_zh_tw ์‹ ๊ทœ invariant / test_zh_cn_fallback_to_zh_tw new invariant

    • _t() / _rt() ๋‘ ํ•จ์ˆ˜ ๋ชจ๋‘์— fallback ํŒจํ„ด์ด ์‚ด์•„์žˆ๊ณ  ๊ฒ€์ฆ ๋Œ€์ƒ ํ‚ค๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๊ฒ€์ฆ / Verifies fallback pattern is alive in both _t()/_rt() and that verification target keys exist
    • TEST_MANAGEMENT_POLICY.md ยง3 4๋ฒˆ ์›์น™ ์ ์šฉ. fallback ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ–ฅํ›„ ๋ˆ„๊ตฐ๊ฐ€์˜ ์‹ค์ˆ˜๋กœ ๊นจ์ง€๋ฉด CI์—์„œ ์ฆ‰์‹œ ์ž๋™ ๊ฐ์ง€ / Applies TEST_MANAGEMENT_POLICY.md ยง3 principle #4 โ€” accidental future breakage caught by CI immediately

๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ • / Bug Fixes

  • (์—†์Œ โ€” v1.0.9๋Š” ์‚ฌํ›„ ์ •๋ฆฌ ์นดํ…Œ๊ณ ๋ฆฌ) / (None โ€” v1.0.9 is a post-cleanup category release)
    • ๋ณธ ๋ฆด๋ฆฌ์ฆˆ๋Š” ๊ธฐ๋Šฅ ์ˆ˜์ •์ด ์•„๋‹Œ ์ฝ”๋“œ ์ฒญ๊ฒฐ์„ฑ ๋ฐ ๋„๊ตฌ ๊ฐœ์„ ์ด ํ•ต์‹ฌ / This release focuses on code hygiene and tooling improvement rather than functional fixes

๐Ÿ”„ ๋ณ€๊ฒฝ / Changed

  • README.md / README_EN.md Copyright ๋ฐ ์ œ์ž‘์ž ํ‘œ๊ธฐ ๋™๊ธฐํ™” / README.md / README_EN.md copyright and author notation sync

    • Yongwoo Shin (Hanrim) โ†’ Hanrim ๋‹จ๋… (4๊ณณ). v1.0.8 ยง4.36 ๋งค์ฒด๋ณ„ ํ‘œ๊ธฐ ์ •์ฑ…์— ๋”ฐ๋ฅธ GitHub-facing ์ž๋ฃŒ ๋™๊ธฐํ™” / 4 locations changed to Hanrim alone. GitHub-facing material sync per v1.0.8 ยง4.36 medium-specific notation policy
    • ์™ธ๋ถ€ ๊ฒฉ์‹ ๋งค์ฒด(ํฌํŠธํด๋ฆฌ์˜ค, ๊ธฐํš์„œ)๋Š” ํ’€๋„ค์ž„ Yongwoo Shin (Hanrim) ์œ ์ง€ / Formal external materials (portfolio, planning docs) retain full form
  • test_all_langs_same_key_count ์žฌ์„ค๊ณ„ / test_all_langs_same_key_count redesigned

    • ๋Œ€์นญ ๊ฐ•์ œ(5์–ธ์–ด ๋™์ผ ํ‚ค ์ˆ˜)์—์„œ ๋น„๋Œ€์นญ ํ—ˆ์šฉ์œผ๋กœ ์ „ํ™˜ โ€” zh_cn์€ zh_tw ๋ถ€๋ถ„์ง‘ํ•ฉ ํ—ˆ์šฉ, ko/en/ja/zh_tw๋Š” ๋™์ผ ํ‚ค ์ˆ˜ ๊ฐ•์ œ / Switched from symmetric enforcement (all 5 languages same count) to asymmetric โ€” zh_cn allowed as zh_tw subset, ko/en/ja/zh_tw must match
    • zh_cn fallback ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ ์ •ํ•ฉ์„ฑ ํ™•๋ณด / Aligned with zh_cn fallback mechanism
  • test_all_languages_have_similar_key_count ๊ฐฑ์‹  / test_all_languages_have_similar_key_count updated

    • zh_cn์€ fallback chain ์‚ฌ์šฉ ๋ช…์‹œํ•˜์—ฌ ํ‚ค ์ˆ˜ ๊ฒ€์ฆ์—์„œ ์ œ์™ธ, ๋‹ค๋ฅธ 4์–ธ์–ด๋งŒ โ‰ค5 ์ฐจ์ด ๊ฐ•์ œ / zh_cn excluded from count check (fallback intent), other 4 languages still constrained โ‰ค5 diff
    • v1.0.5 ์‹œ์ ˆ ์˜๋„(์™„๊ฒฐ์„ฑ ๋ณด์žฅ) ์œ ์ง€ํ•˜๋ฉด์„œ ยง5.1.G ์ •ํ•ฉ / Retains v1.0.5-era intent (completeness guarantee) while aligning with ยง5.1.G

โœ… ๊ฒ€์ฆ / Verified

  • HelpDialog ์ ๊ฒ€ โ€” ์˜ต์…˜ C ์ ์šฉ ๋ถˆ์š” ํ™•์ธ / HelpDialog audit โ€” Option C not applicable confirmed
    • v1.0.8 SettingsDialog์˜ ๋ผ๋ฒจ color ์ž”์žฌ ๋ฒ„๊ทธ์™€ ๊ฐ™์€ ๊ตฌ์กฐ์  ๊ฒฐํ•จ์ด ๋‹ค๋ฅธ ๋‹ค์ด์–ผ๋กœ๊ทธ์— ์ž ์žฌํ•  ๊ฐ€๋Šฅ์„ฑ์„ ์ง„๋‹จ / Audited whether the SettingsDialog label-color residue defect from v1.0.8 was latent in other dialogs
    • ํ˜ธ์ถœ ๋ฐฉ์‹ ๋น„๊ต ๊ฒฐ๊ณผ: HelpDialog๋Š” ๋‹จ์ˆœ exec() ๋ชจ๋‹ฌ + ์‹œ๊ทธ๋„ ์—ฐ๊ฒฐ 0๊ฐœ / SettingsDialog๋Š” "์ฐฝ ์œ ์ง€" + ์‹œ๊ทธ๋„ 3๊ฐœ (theme/shortcuts/language) โ€” ๋ณธ์งˆ์ ์œผ๋กœ ๋‹ค๋ฅธ ํŒจํ„ด / Comparison result: HelpDialog uses plain exec() modal + 0 signals; SettingsDialog uses "stays open" + 3 signals โ€” fundamentally different patterns
    • HelpDialog์˜ refresh() ๋ฉ”์„œ๋“œ๋Š” ์˜๋„์ ์œผ๋กœ pass + ์ฃผ์„ "exec() ๋ชจ๋‹ฌ์ด๋ผ ์—ด๋ฆด ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ์ƒ์„ฑ๋จ"์œผ๋กœ ์˜๋„ ๋ช…๋ฌธํ™”. ๋‹ค์ด์–ผ๋กœ๊ทธ๊ฐ€ ์‚ด์•„์žˆ๋Š” ๋™์•ˆ ์™ธ๋ถ€ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ์–ด ๋“ค์–ด์˜ฌ ์‹œ๋‚˜๋ฆฌ์˜ค ์ž์ฒด๊ฐ€ ๊ตฌ์กฐ์ ์œผ๋กœ ์กด์žฌํ•˜์ง€ ์•Š์Œ / HelpDialog.refresh() is intentionally pass with comment "modal exec(), recreated on each open"; the scenario of external state changing while dialog is alive structurally cannot occur
    • ๊ฒฐ๋ก : ์ ๊ฒ€ ์ž์ฒด๊ฐ€ v1.0.9 ยง5.1.D์˜ ์‚ฐ์ถœ๋ฌผ โ€” ์ž ์žฌ ๊ฒฐํ•จ ์—†์Œ์„ ๋ฐ์ดํ„ฐ๋กœ ๋ช…์‹œ. ์ฝ”๋“œ ๋ณ€๊ฒฝ 0์ค„๋กœ ๋งˆ๊ฐ / Conclusion: the audit itself is the ยง5.1.D artifact โ€” absence of latent defects established. Closed as 0-line task

๐Ÿงช ํ…Œ์ŠคํŠธ ์ž๋™ํ™” / Test Automation

  • ์ด 535๊ฐœ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ / 535 tests passing, 58๊ฐœ ํด๋ž˜์Šค / 58 classes, ์‹คํŒจ 0 / ์˜ค๋ฅ˜ 0 / ์Šคํ‚ต 0 / 0 failed / 0 errors / 0 skipped โญ
  • +1 vs v1.0.8 (534 โ†’ 535) โ€” test_zh_cn_fallback_to_zh_tw ์‹ ๊ทœ invariant / test_zh_cn_fallback_to_zh_tw new invariant
  • ํšŒ๊ท€ ๋ฐœ๊ฒฌ โ†’ ์ˆ˜์ • ์‚ฌ์ดํด / Regression-discovery โ†’ fix cycle:
    • ยง5.1.G 1์ฐจ ์ ์šฉ ํ›„ v1.0.5 ํšŒ๊ท€ ํ…Œ์ŠคํŠธ 6๊ฐœ FAIL ๋ฐœ๊ฒฌ โ€” merge_enc_utf8 / merge_enc_utf16 / merge_enc_shiftjis 3๊ฐœ๊ฐ€ invariant ๋ณดํ˜ธ ํ‚ค์˜€์Œ์„ 1์ฐจ ์ง„๋‹จ์—์„œ ๋ˆ„๋ฝ / After initial ยง5.1.G application, 6 v1.0.5 regression tests failed โ€” first diagnosis missed that 3 keys (merge_enc_utf8 / merge_enc_utf16 / merge_enc_shiftjis) were invariant-protected
    • ์ •๋ฆฌ ๋Œ€์ƒ 47โ†’40๊ฐœ๋กœ ์ถ•์†Œ + test_all_languages_have_similar_key_count zh_cn ์˜ˆ์™ธ ๊ฐฑ์‹ ์œผ๋กœ ํšŒ๊ท€ ๋‹ซ์Œ / Resolved by reducing cleanup target 47โ†’40 and updating test_all_languages_have_similar_key_count to except zh_cn
  • ์ด์ค‘ ๊ฒ€์ฆ / Dual verification:
    • ์ž‘์—… ํด๋”: 535/0/0/0 / Work folder: 535/0/0/0
    • Git ํด๋”: 535/0/0/0 / Git folder: 535/0/0/0

๐Ÿ” ๊ฒ€์ฆ ๋ฒ”์œ„ / Verification Scope

  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ / Unit tests: 535 passing (ํ•œ๋ฆผ ๋กœ์ปฌ Windows + Git ํด๋” ์ด์ค‘ ๊ฒ€์ฆ, GitHub Actions CI๋Š” push ํ›„ ์ž๋™ ์žฌํ˜„ ์˜ˆ์ •) / 535 passing (dual verification on Hanrim's local Windows + Git folder; GitHub Actions CI will reproduce automatically after push)
  • ์ˆ˜๋™ QA โ€” ยง5.1.G ์ง์ ‘ ๊ฒ€์ฆ ๊ถŒ์žฅ ์‹œ๋‚˜๋ฆฌ์˜ค / Manual QA โ€” ยง5.1.G recommended scenarios:
    • ์•ฑ ์–ธ์–ด๋ฅผ ็ฎ€ไฝ“ไธญๆ–‡(zh_cn)๋กœ ์ „ํ™˜ ํ›„ ์ •๋ฆฌํ•œ 40๊ฐœ ํ‚ค๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ํ™”๋ฉด ํ™•์ธ (์˜ˆ: ํ…Œ๋งˆ ์„ค์ •์˜ "็™ฝ่‰ฒ/ๆทฑ่‰ฒ", Batch Renamer์˜ "โ–ถ") / Switch app language to ็ฎ€ไฝ“ไธญๆ–‡ and visit screens using cleaned keys (e.g., theme settings "็™ฝ่‰ฒ/ๆทฑ่‰ฒ", Batch Renamer "โ–ถ")
    • fallback chain์œผ๋กœ zh_tw ๊ฐ’๊ณผ ๋™์ผํ•˜๊ฒŒ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ (๊ฐ’ 100% ๋™์ผ์ด๋ผ ์‹œ๊ฐ ์ฐจ์ด 0) / Should display identical to zh_tw values via fallback (100% value match means zero visual difference)
    • zh_tw / ๊ธฐํƒ€ ์–ธ์–ด ํšŒ๊ท€ ํ™•์ธ โ€” ์‚ฌ์ „ ๋ฏธ๋ณ€๊ฒฝ์ด๋ผ ์˜ํ–ฅ ์—†์–ด์•ผ ํ•จ / zh_tw and other languages regression check โ€” should be unaffected (dictionaries unchanged)
  • ๋นŒ๋“œ ๋„๊ตฌ ๊ฒ€์ฆ / Build tooling verification:
    • python build_pyinstaller.py ์ •์ƒ ๋นŒ๋“œ (๊ธฐ์กด ๋™์ž‘ ๋ณด์กด) / python build_pyinstaller.py normal build (existing behavior preserved)
    • python build_pyinstaller.py --strict ํ—ค๋” ํ‘œ์‹œ + ์ •์ƒ ๋นŒ๋“œ / python build_pyinstaller.py --strict header display + normal build
    • ์˜๋„์  mismatch ์‹œ๋‚˜๋ฆฌ์˜ค: README.txt ์ž„์‹œ ๋ณ€๊ฒฝ ํ›„ --strict ์‹คํ–‰ ์‹œ step 5์—์„œ ์ฆ‰์‹œ abort ํ™•์ธ / Intentional mismatch scenario: temporary README.txt change + --strict aborts immediately at step 5
    • build.bat / build.bat --strict wrapper ํ†ต๊ณผ / build.bat / build.bat --strict wrapper verification passed
  • ๋ฒ„์ „ ์ •ํ•ฉ์„ฑ ๊ฒ€์ฆ / Version consistency verification:
    • APP_VERSION ์ƒ์ˆ˜ / version_info.txt 4๊ณณ / README.md / README_EN.md ๋ฑƒ์ง€ / README.txt ๋ชจ๋‘ v1.0.9๋กœ ์ •ํ•ฉ / All aligned to v1.0.9: APP_VERSION constant, version_info.txt (4 locations), README.md/README_EN.md badges, README.txt

๐Ÿ“ฆ ๊ตฌ์กฐ์  ๋ณ€๊ฒฝ / Structural Changes

  • ๋ผ์ธ ์ˆ˜ ๋ณ€๋™ / Line count changes:
    • FileNexusSuite.py: 14,883 โ†’ 14,850์ค„ (-33: zh_cn 40๊ฐœ ํ‚ค ์ œ๊ฑฐ -40 + _t()/_rt() fallback ๋ณด๊ฐ• +6 + APP_VERSION ๊ฐฑ์‹  ๋“ฑ) / -33 lines (zh_cn 40-key removal -40 + _t()/_rt() fallback +6 + APP_VERSION etc.)
    • `test_file_nexus.py...
Read more

File Nexus Suite v1.0.8

Choose a tag to compare

@MerciHanrim MerciHanrim released this 25 Apr 10:26
v1.0.8
59cbbfb

v1.0.8 โ€” ์„ค์ • ๋‹ค์ด์–ผ๋กœ๊ทธ ๋ผ๋ฒจ color ์ž”์žฌ ๋ฒ„๊ทธ ๊ตฌ์กฐ์  ํ•ด๊ฒฐ (ํŽ˜์ด์ง€ lazy ์žฌ์ƒ์„ฑ) / Settings dialog label color residue bug โ€” structural fix via page lazy recreation

v1.0.8์€ v1.0.5๋ถ€ํ„ฐ ๋‹ค์„ฏ ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์‚ด์•„๋‚จ์€ ๋ณธ๊ณผ์ œ๋ฅผ ๋งˆ์นจ๋‚ด ํ•ด๊ฒฐํ•œ ๋ฆด๋ฆฌ์ฆˆ์ž…๋‹ˆ๋‹ค. v1.0.6์—์„œ ์‹œ๋„ํ•œ 4๊ฐ€์ง€ ์ ‘๊ทผ(QTimer ์ง€์—ฐ / unpolish-polish / QApplication ์ „์—ญ ์žฌ์ ์šฉ / findChildren update)์ด ๋ชจ๋‘ ์‹คํŒจํ•œ ํ›„ v1.0.7์—์„œ ์ด์›”๋๋˜ ๋ณธ๊ณผ์ œ๋กœ, ์ด๋ฒˆ์—๋Š” ์‚ฌ์ „ ์กฐ์‚ฌ โ†’ ์ฝ”๋“œ ์ง„๋‹จ โ†’ ์˜ต์…˜ ์žฌํ‰๊ฐ€์˜ ์ •์งํ•œ ํ๋ฆ„์œผ๋กœ ํ’€์–ด๋ƒˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ์ง„๋‹จ ๊ฒฐ๊ณผ ยง11.1์˜ "์˜ํ–ฅ ์œ„์ ฏ 3๊ฐ€์ง€"๊ฐ€ ์‹ค์ œ๋กœ๋Š” 22๊ฐœ ์œ„์ ฏ ๊ฐฑ์‹  ๋ˆ„๋ฝ์˜ ๋น™์‚ฐ ์ผ๊ฐ์ด์—ˆ์Œ์ด ๋“œ๋Ÿฌ๋‚ฌ๊ณ , ์ฒ˜์Œ ๊ถŒ์žฅํ–ˆ๋˜ ์˜ต์…˜ A(Targeted ๊ฐฑ์‹ , 6080์ค„)๋ฅผ ์˜ต์…˜ C(ํŽ˜์ด์ง€ lazy ์žฌ์ƒ์„ฑ, +17์ค„)๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์ •์งํ•œ ์žฌํ‰๊ฐ€๋ฅผ ๊ฑฐ์ณ ์ฝ”๋“œ ๋ณ€๊ฒฝ๋Ÿ‰์„ 1/4๋กœ ์ค„์ด๋ฉด์„œ ๋ˆ„๋ฝ ์žฌ๋ฐœ ์œ„ํ—˜์„ ์˜๊ตฌ ๋ฐฉ์ง€ํ•˜๋Š” ๊ตฌ์กฐ์  ํ•ด๊ฒฐ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์›Œํฌ์–ด๋ผ์šด๋“œ(์„ค์ •์ฐฝ ์žฌ์˜คํ”ˆ)์™€ ๋™์ผํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋‹ค์ด์–ผ๋กœ๊ทธ ๋‚ด๋ถ€์—์„œ ์ž๋™ํ™”ํ•œ ๋ฐฉ์‹์œผ๋กœ, v1.0.6 Phase 2 Completion Record ยง11.3์—์„œ ํ•œ๋ฆผ์ด ์‚ฌ์ „ ํ›„๋ณด๋กœ ์ ์–ด๋‘” "ํŽ˜์ด์ง€ lazy ์ƒ์„ฑ + ์žฌ๋ฐฉ๋ฌธ ์‹œ ์กฐ๊ฑด๋ถ€ ์žฌ์ƒ์„ฑ" ๋ฐฉํ–ฅ๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์ด๋“œ ๊ฒฐํ•จ 2๊ฑด(_ver_lbl ๊ฐฑ์‹  ๋ˆ„๋ฝ, ์ถœ๋ ฅ ํด๋” ๋ฒ„ํŠผ ํ…์ŠคํŠธ ๊ฐฑ์‹  ๋ˆ„๋ฝ)๋„ ๊ฐ™์€ ๊ตฌ์กฐ์  ํ•ด๊ฒฐ๋กœ ๋™์‹œ ํ’€๋ ธ์œผ๋ฉฐ, TEST_MANAGEMENT_POLICY.md ยง3 4๋ฒˆ ์›์น™(์‹ ๊ทœ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž๋™ ์ปค๋ฒ„๋ฆฌ์ง€ ๋ช…์‹œ)์— ๋”ฐ๋ผ TestSettingsDialogStructureInvariant ํด๋ž˜์Šค 3๊ฐœ invariant๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ์˜ต์…˜ C ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ–ฅํ›„ ๋ˆ„๊ตฐ๊ฐ€์˜ ์‹ค์ˆ˜๋กœ ๊นจ์งˆ ์‹œ CI์—์„œ ์ฆ‰์‹œ ์ž๋™ ๊ฐ์ง€๋ฉ๋‹ˆ๋‹ค.

v1.0.8 finally resolves the original target that survived five releases since v1.0.5. After v1.0.6's four attempted approaches (QTimer deferral, unpolish-polish, QApplication global re-apply, findChildren update) all failed and the issue was deferred through v1.0.7, this release tackles it through an honest sequence of preliminary research โ†’ code diagnosis โ†’ option re-evaluation. Code diagnosis revealed that the "3 affected widgets" mentioned in ยง11.1 were merely the visible tip of a 22-widget update omission iceberg, leading to a transparent re-evaluation that swapped the initially recommended Option A (targeted updates, 6080 lines) for Option C (page lazy recreation, +17 lines) โ€” reducing code change to a quarter while permanently preventing recurrence. The mechanism automates the existing workaround (close and reopen the settings dialog) within the dialog itself, aligning precisely with the "page lazy recreation on revisit" approach that Hanrim had pre-listed in v1.0.6 Phase 2 Completion Record ยง11.3. Two side defects (_ver_lbl update omission, output folder button text update omission) were resolved as a byproduct of the structural fix, and following TEST_MANAGEMENT_POLICY.md ยง3 principle #4 (codify automated coverage for new features), TestSettingsDialogStructureInvariant with 3 invariant tests was added โ€” ensuring CI automatically catches any future accidental breakage of the Option C mechanism.


โœจ ์ฃผ์š” ๊ธฐ๋Šฅ / Major Features

  • ์„ค์ • ๋‹ค์ด์–ผ๋กœ๊ทธ ํŽ˜์ด์ง€ lazy ์žฌ์ƒ์„ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋„์ž… / Settings dialog page lazy recreation mechanism

    • ์‹ ๊ทœ ๋ฉ”์„œ๋“œ SettingsDialog._recreate_pages() โ€” ํŽ˜์ด์ง€ 4๊ฐœ destroy + recreate / New method SettingsDialog._recreate_pages() โ€” destroy + recreate 4 pages
    • 7๋‹จ๊ณ„ ์•ˆ์ „ ํ๋ฆ„: ๋‹จ์ถ•ํ‚ค ์บก์ฒ˜ ์•ˆ์ „ ์ข…๋ฃŒ โ†’ ์ถœ๋ ฅ ํด๋” ์ž„์‹œ ์ž…๋ ฅ๊ฐ’ ๋ณด์กด โ†’ ๊ธฐ์กด ํŽ˜์ด์ง€ ์œ„์ ฏ ์ œ๊ฑฐ(removeWidget + deleteLater) โ†’ ์ปจํ…Œ์ด๋„ˆ dict ์ดˆ๊ธฐํ™” โ†’ ์ƒˆ ํŽ˜์ด์ง€ ์ƒ์„ฑ โ†’ ์ž„์‹œ ์ž…๋ ฅ๊ฐ’ ๋ณต์› โ†’ ํ˜„์žฌ ํŽ˜์ด์ง€ ์ „ํ™˜ / 7-step safe flow: stop keyboard capture โ†’ preserve unsaved output folder input โ†’ remove old page widgets (removeWidget + deleteLater) โ†’ clear container dicts โ†’ create new pages โ†’ restore unsaved input โ†’ switch to current page
    • ์›Œํฌ์–ด๋ผ์šด๋“œ(์„ค์ •์ฐฝ ์žฌ์˜คํ”ˆ) ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ๋ช…์‹œ์  ์ž๋™ํ™” โ€” v1.0.6 Phase 2 Completion Record ยง11.3 ๊ถŒ์žฅ ๋ฐฉํ–ฅ๊ณผ ์ผ์น˜ / Explicit automation of the existing workaround โ€” aligns with v1.0.6 Phase 2 Completion Record ยง11.3 recommendation
  • _refresh_theme / _retranslate_dialog ์ฑ…์ž„ ๋ช…ํ™•ํ™” / _refresh_theme / _retranslate_dialog responsibility clarification

    • ๋‹ค์ด์–ผ๋กœ๊ทธ ์™ธ๊ณฝ ์œ„์ ฏ๋งŒ ์ฑ…์ž„์ง€๋„๋ก ๋‹จ์ˆœํ™”. ํŽ˜์ด์ง€ ๋‚ด๋ถ€ ์œ„์ ฏ์˜ stylesheetยทํ…์ŠคํŠธ ๊ฐฑ์‹ ์€ _recreate_pages์— ์ผ๊ด„ ์œ„์ž„ / Simplified to handle only outer dialog widgets; page-internal widget styling/text updates fully delegated to _recreate_pages
    • _refresh_theme: 32์ค„ โ†’ 30์ค„ / 32 lines โ†’ 30 lines
    • _retranslate_dialog: 48์ค„ โ†’ 16์ค„ / 48 lines โ†’ 16 lines
  • TestSettingsDialogStructureInvariant ์‹ ์„ค โ€” ์˜ต์…˜ C ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๊ตฌ์กฐ invariant / TestSettingsDialogStructureInvariant established โ€” Option C mechanism structural invariant

    • test_settings_dialog_has_recreate_pages โ€” _recreate_pages ๋ฉ”์„œ๋“œ ์กด์žฌ ๊ฒ€์ฆ (hasattr + callable) / _recreate_pages method existence verification
    • test_refresh_theme_calls_recreate_pages โ€” _refresh_theme ๋ณธ๋ฌธ์— self._recreate_pages() ํ˜ธ์ถœ ํฌํ•จ ๊ฒ€์ฆ (inspect.getsource ๊ธฐ๋ฐ˜) / _refresh_theme source-level call verification (inspect.getsource)
    • test_retranslate_dialog_simplified โ€” _retranslate_dialog์ด ํŽ˜์ด์ง€ ๋‚ด๋ถ€ attribute 9๊ฐœ(_theme_page_title, _lang_page_title ๋“ฑ)๋ฅผ ์ง์ ‘ ๊ฐฑ์‹ ํ•˜์ง€ ์•Š์Œ ๊ฒ€์ฆ / _retranslate_dialog does not directly touch 9 page-internal attributes (_theme_page_title, _lang_page_title, etc.)
    • TEST_MANAGEMENT_POLICY.md ยง3 4๋ฒˆ ์›์น™(์‹ ๊ทœ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž๋™ ์ปค๋ฒ„๋ฆฌ์ง€ ๋ช…์‹œ) ์ ์šฉ. ์˜ต์…˜ C ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ–ฅํ›„ ๋ˆ„๊ตฐ๊ฐ€์˜ ์‹ค์ˆ˜๋กœ ๊นจ์ง€๋ฉด CI์—์„œ ์ฆ‰์‹œ ์ž๋™ ๊ฐ์ง€ / Applies TEST_MANAGEMENT_POLICY.md ยง3 principle #4 (codify auto-coverage for new features) โ€” accidental future breakage caught by CI immediately
  • ์‚ฌ์ „ ์กฐ์‚ฌ โ†’ ์ฝ”๋“œ ์ง„๋‹จ โ†’ ์˜ต์…˜ ์žฌํ‰๊ฐ€ ํ๋ฆ„ ๋ช…๋ฌธํ™” / Preliminary research โ†’ code diagnosis โ†’ option re-evaluation, codified

    • v1.0.6 ยง11.3์˜ "์‚ฌ์ „ ์กฐ์‚ฌ ํ•„์ˆ˜" ์›์น™์„ ์‹ค์ œ ์ž‘์—… ํ๋ฆ„์œผ๋กœ ์ ์šฉํ•œ ์ฒซ ์‚ฌ๋ก€ / First execution of the "preliminary research mandatory" principle from v1.0.6 ยง11.3 as actual workflow
    • 4๊ฐœ ์ž‘์—… ๋ฌธ์„œ ์‚ฐ์ถœ: ์‚ฌ์ „ ์กฐ์‚ฌ ๋…ธํŠธ / ์ฝ”๋“œ ์ง„๋‹จ ๋ณด๊ณ ์„œ / ์˜ต์…˜ ์žฌํ‰๊ฐ€ ๋ณด๊ณ ์„œ / ์˜ต์…˜ C ์ž‘์—… ์ง€์‹œ์„œ / 4 process documents produced: preliminary research note / code diagnosis report / option re-evaluation report / Option C work instruction
    • ์ด ํ๋ฆ„์ด ์˜ต์…˜ A โ†’ C ๋ณ€๊ฒฝ์˜ ์ •์งํ•œ ๊ทผ๊ฑฐ๊ฐ€ ๋จ (22๊ฐœ ๋ˆ„๋ฝ ๋ฐœ๊ฒฌ ํ›„ ๊ถŒ์žฅ ๋ณ€๊ฒฝ) / This flow provided the honest rationale for switching Option A โ†’ C (after discovering 22 omissions)

๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ • / Bug Fixes

  • ์„ค์ • ๋‹ค์ด์–ผ๋กœ๊ทธ ๋ผ๋ฒจ/ํ”„๋ ˆ์ž„ color ์ž”์žฌ ๋ฒ„๊ทธ (v1.0.5๋ถ€ํ„ฐ ์กด์žฌ, ๋ณธ๊ณผ์ œ) / Settings dialog label/frame color residue (pre-existing since v1.0.5, original target)

    • ํ˜„์ƒ: ๋ผ์ดํŠธ โ†’ ๋‹คํฌ ๋ฐฉํ–ฅ ํ…Œ๋งˆ ์ „ํ™˜ ํ›„ ๋‹ค๋ฅธ ํƒญ ์ด๋™ ์‹œ ์ผ๋ถ€ ์œ„์ ฏ(์–ธ์–ด ํ”„๋ ˆ์ž„ ๋ฐฐ๊ฒฝ, ํƒ€์ดํ‹€ ๋ผ๋ฒจ color, ์ถœ๋ ฅ ํด๋” ์œ„์ ฏ)์ด ์ด์ „ ํ…Œ๋งˆ ๊ฐ’์œผ๋กœ ์ž”์žฌ. ์„ค์ •์ฐฝ ์žฌ์˜คํ”ˆ ์‹œ ์ •์ƒ ๋ณต๊ท€ (์›Œํฌ์–ด๋ผ์šด๋“œ) / Symptom: after light โ†’ dark theme switch and tab navigation, some widgets (language frame background, title label color, output folder widgets) retained previous-theme values. Closing and reopening the settings dialog restored normal display (workaround)
    • ๊ทผ๋ณธ ์›์ธ: ํŽ˜์ด์ง€ 4๊ฐœ์˜ inline stylesheet์— ์ƒ‰์ƒ๊ฐ’์ด f-string์œผ๋กœ ๋ฐ•ํ˜€ ์ƒ์„ฑ ์‹œ์  ํ…Œ๋งˆ๋กœ ์˜๊ตฌ ๊ณ ์ • (v1.0.5๋ถ€ํ„ฐ์˜ ๊ตฌ์กฐ์  ํ•œ๊ณ„). __init__์—์„œ ๋‹จ ํ•œ ๋ฒˆ ์ƒ์„ฑ๋˜์–ด QStackedWidget์— ์ ์ธต๋˜๋ฉฐ ์ ˆ๋Œ€ ์žฌ์ƒ์„ฑ๋˜์ง€ ์•Š์Œ / Root cause: f-string-embedded colors in pages' inline stylesheets froze them at creation-time theme (structural limitation since v1.0.5). Pages were created exactly once in __init__ and stacked into QStackedWidget, never recreated
    • ์ฝ”๋“œ ์ง„๋‹จ์œผ๋กœ ยง11.1์˜ "์˜ํ–ฅ ์œ„์ ฏ 3๊ฐ€์ง€"๊ฐ€ ์‹ค์ œ๋กœ๋Š” 22๊ฐœ ์œ„์ ฏ ๊ฐฑ์‹  ๋ˆ„๋ฝ์˜ ๋น™์‚ฐ ์ผ๊ฐ์ž„์ด ๋“œ๋Ÿฌ๋‚จ โ€” ํŽ˜์ด์ง€ ๋‚ด๋ถ€ ๊ฑฐ์˜ ๋ชจ๋“  inline stylesheet ์œ„์ ฏ์ด ๋™์ผํ•œ ๊ตฌ์กฐ์  ๋ฌธ์ œ / Code diagnosis revealed ยง11.1's "3 affected widgets" were the visible tip of 22-widget update omission iceberg โ€” nearly all page-internal inline-stylesheet widgets shared the same structural defect
    • ์ˆ˜์ •: ์˜ต์…˜ C(ํŽ˜์ด์ง€ lazy ์žฌ์ƒ์„ฑ) โ€” ํ…Œ๋งˆ/์–ธ์–ด ๋ณ€๊ฒฝ ์‹œ ํŽ˜์ด์ง€ 4๊ฐœ๋ฅผ destroy + recreate. ์›Œํฌ์–ด๋ผ์šด๋“œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ์ž๋™ํ™” / Fix: Option C (page lazy recreation) โ€” destroy + recreate all 4 pages on theme/language change. Automation of the existing workaround
    • ์˜ต์…˜ A โ†’ C ์ •์งํ•œ ์žฌํ‰๊ฐ€: ์ฒ˜์Œ ๊ถŒ์žฅํ–ˆ๋˜ ์˜ต์…˜ A(Targeted ๊ฐฑ์‹ , 6080์ค„)๋Š” 22๊ฐœ ์œ„์ ฏ ๋ฐœ๊ฒฌ ํ›„ ๋ˆ„๋ฝ ์žฌ๋ฐœ ์œ„ํ—˜ ์˜๊ตฌ ๋ณด์œ ๋ผ๋Š” ํ•œ๊ณ„๊ฐ€ ๋“œ๋Ÿฌ๋‚จ. ์˜ต์…˜ C(+17์ค„)๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์ฝ”๋“œ ๋ณ€๊ฒฝ๋Ÿ‰ 1/4๋กœ ์ถ•์†Œ + ๊ตฌ์กฐ์  ํ•ด๊ฒฐ / Honest re-evaluation Option A โ†’ C: initially recommended Option A (targeted updates, 6080 lines) revealed permanent recurrence risk after the 22-widget discovery. Switched to Option C (+17 lines) โ€” quarter the code change + structural resolution
  • _ver_lbl ํ…Œ๋งˆ ์ „ํ™˜ ๊ฐฑ์‹  ๋ˆ„๋ฝ (์‚ฌ์ด๋“œ ๊ฒฐํ•จ, v1.0.6 ์ž”์žฌ) / _ver_lbl theme switch update omission (side defect, v1.0.6 residue)

    • ํ˜„์ƒ: ์‚ฌ์ด๋“œ๋ฐ” ํ•˜๋‹จ ๋ฒ„์ „ ๋ผ๋ฒจ์ด ํ…Œ๋งˆ ์ „ํ™˜ ์‹œ ๊ฐฑ์‹ ๋˜์ง€ ์•Š์•„ ์ด์ „ ํ…Œ๋งˆ ์ƒ‰์ƒ์œผ๋กœ ์ž”์žฌ / Symptom: sidebar bottom version label retained previous theme colors after theme switch
    • ๋ฐœ๊ฒฌ ๊ฒฝ๋กœ: v1.0.6 ์ฝ”๋“œ์— # v1.0.6: ํ…Œ๋งˆ ์ „ํ™˜ ์‹œ ๊ฐฑ์‹ ์šฉ self ์ €์žฅ์ด๋ผ ์ฃผ์„ ๋‹ฌ์•„๋†“๊ณ ๋„ _refresh_theme ํ˜ธ์ถœ์ด ๋ˆ„๋ฝ๋œ ๊ฒฐํ•จ์ด ์˜ต์…˜ C ์ž‘์—… ์ค‘ ์ฝ”๋“œ ์ง„๋‹จ ๋‹จ๊ณ„์—์„œ ๋ฐœ๊ฒฌ / Discovery: v1.0.6 source contained the comment # v1.0.6: stored on self for theme switch updates but the actual _refresh_theme call was missing โ€” surfaced during Option C code diagnosis
    • ์ˆ˜์ •: _refresh_theme์— 1์ค„ ์ถ”๊ฐ€ (์™ธ๊ณฝ ์œ„์ ฏ์ด๋ผ _recreate_pages ์ฒ˜๋ฆฌ ๋Œ€์ƒ ์•„๋‹˜) / Fix: 1 line added to _refresh_theme (outer widget, not handled by _recreate_pages)
  • ์ถœ๋ ฅ ํด๋” ๋ฒ„ํŠผ ํ…์ŠคํŠธ ๊ฐฑ์‹  ๋ˆ„๋ฝ (์‚ฌ์ด๋“œ ๊ฒฐํ•จ, v1.0.6 D-2 ์ž”์žฌ) / Output folder button text update omission (side defect, v1.0.6 D-2 residue)

    • ํ˜„์ƒ: ์–ธ์–ด ๋ณ€๊ฒฝ ์‹œ ์ถœ๋ ฅ ํด๋” [์„ ํƒ] / [๊ธฐ๋ณธ๊ฐ’] ๋ฒ„ํŠผ ํ…์ŠคํŠธ๊ฐ€ ์ด์ „ ์–ธ์–ด๋กœ ์ž”์žฌ / Symptom: output folder [Pick] / [Reset] button text retained previous language after language change
    • ๊ทผ๋ณธ ์›์ธ: _retranslate_dialog์ด self._odir_btn / self._odir_reset_btn์„ ์ฐธ์กฐํ•˜์ง€๋งŒ, _page_language์—์„œ๋Š” ๋กœ์ปฌ ๋ณ€์ˆ˜ odir_btn / odir_reset๋กœ๋งŒ ๋งŒ๋“ค์–ด hasattr ๊ฒ€์‚ฌ๋กœ silently fail / Root cause: _retranslate_dialog referenced self._odir_btn / self._odir_reset_btn, but _page_language only created them as local variables odir_btn / odir_reset โ€” the hasattr guard caused silent failure
    • ์ˆ˜์ •: ํŽ˜์ด์ง€ ์žฌ์ƒ์„ฑ์œผ๋กœ ์ž๋™ ํ•ด๊ฒฐ (์˜ต์…˜ C ๋ถ€์ˆ˜ ํšจ๊ณผ) / Fix: automatically resolved by page recreation (Option C byproduct)

๐Ÿ“„ ๋ฌธ์„œ / Documentation

  • CHANGELOG.md v1.0.8 ์„น์…˜ ์‹ ์„ค / CHANGELOG.md v1.0.8 section added
    • Fixed / Changed / Added / Tests / Documentation / File Changes 6๊ฐœ ํ•˜์œ„ ์„น์…˜ / 6 subsections: Fixed / Changed / Added / Tests / Documentation / File Changes
  • FileNexusSuite.py APP_VERSION ์ƒ์ˆ˜ ๊ฐฑ์‹  / FileNexusSuite.py APP_VERSION constant update
    • L76 APP_VERSION = "1.0.7" โ†’ "1.0.8" โ€” f-string์œผ๋กœ ์ฐธ์กฐ๋˜๋Š” ๋„์›€๋ง ์ฐฝ ํƒ€์ดํ‹€ 5๊ฐœ ์–ธ์–ด + ์‚ฌ์ด๋“œ๋ฐ” ๋ฒ„์ „ ๋ผ๋ฒจ์ด ์ž๋™ ์ผ๊ด€ ๊ฐฑ์‹  / All f-string references (5-language help titles + sidebar version label) automatically updated
  • version_info.txt 4๊ณณ ๊ฐฑ์‹  / version_info.txt 4-point update
    • filevers / prodvers ํŠœํ”Œ + FileVersion / ProductVersion ๋ฌธ์ž์—ด ๋ชจ๋‘ v1.0.8 / 1.0.8.0์œผ๋กœ ์ •ํ•ฉ ํ™•๋ณด. PyInstaller ๋นŒ๋“œ ์‹œ Windows .exe ์†์„ฑ ์ฐฝ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ •ํ•ฉ / All aligned to v1.0.8 / 1.0.8.0: filevers/prodvers tuples + FileVersion/ProductVersion strings. PyInstaller .exe properties metadata consistency secured
  • README.md / README_EN.md ๋ฑƒ์ง€ ๋™๊ธฐํ™” / README.md / README_EN.md badge sync
    • version ๋ฑƒ์ง€ 1.0.7 โ†’ 1.0.8, tests ๋ฑƒ์ง€ 531 โ†’ 534 ์–‘์ชฝ ์ผ์น˜ / version badge 1.0.7 โ†’ 1.0.8, tests badge 531 โ†’ 534 โ€” both READMEs synchronized
  • **`RE...
Read more

File Nexus Suite v1.0.7

Choose a tag to compare

@MerciHanrim MerciHanrim released this 22 Apr 07:48
v1.0.7
b40137c

v1.0.7 โ€” ๊ธฐ์ˆ  ๋ถ€์ฑ„ ์ •๋ฆฌ + GitHub Actions CI ๋„์ž… + ํ…Œ์ŠคํŠธ ๊ด€๋ฆฌ ์ •์ฑ… ์ˆ˜๋ฆฝ / Technical debt cleanup + GitHub Actions CI adoption + test management policy establishment

v1.0.7์€ ๊ธฐ๋Šฅ ์ถ”๊ฐ€๊ฐ€ ์•„๋‹Œ ๊ธฐ์ˆ  ๋ถ€์ฑ„ ์ •๋ฆฌ์™€ ์ธํ”„๋ผ ๊ฐ•ํ™”์— ์ง‘์ค‘ํ•œ ๋ฆด๋ฆฌ์ฆˆ์ž…๋‹ˆ๋‹ค. 3๊ฐœ ์‚ฌ์ „ ์ž‘์—… ์„ธ์…˜์„ ํ†ตํ•ด ๋ฒˆ์—ญํ‚ค ๊ณ ์•„ 15๊ฑด์„ ์ œ๊ฑฐํ•˜๊ณ  invariant ํ…Œ์ŠคํŠธ๋ฅผ ํƒญ ๊ธฐ๋ฐ˜ 10๊ฐœ ๋Œ€๋ถ„๋ฅ˜๋กœ ์žฌ๊ตฌ์„ฑํ–ˆ์œผ๋ฉฐ, ๋งค ๋ฆด๋ฆฌ์ฆˆ๋งˆ๋‹ค ์ˆ˜๋™์œผ๋กœ ์ด์›”ํ•ด์˜ค๋˜ ๋ฒ„์ „ ์Šค๋ƒ…์ƒท ๋ฐฉ์‹์˜ ํ•œ๊ณ„๋ฅผ ๋ช…๋ฌธํ™”ํ•œ **TEST_MANAGEMENT_POLICY.md**๋ฅผ ์‹ ์„คํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ณ€ํ™”๋Š” GitHub Actions CI ๋„์ž…์œผ๋กœ, ์ฒซ ์‹คํ–‰๋ถ€ํ„ฐ ๋กœ์ปฌ์—์„œ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š๋˜ ์ˆจ์€ ์ด์Šˆ 2๊ฑด(์œ ๋ น PyPI ํŒจํ‚ค์ง€, Windows ์˜์–ด ๋กœ์ผ€์ผ UnicodeEncodeError)์„ ์ฆ‰์‹œ ๋“œ๋Ÿฌ๋‚ด๋ฉฐ ๊ฐ€์น˜๋ฅผ ์ž…์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. APP_VERSION ์ƒ์ˆ˜์˜ ๋ฒ„์ „-๋…๋ฆฝ ๊ตฌ์กฐ ๊ฒ€์ฆ ์žฌ์„ค๊ณ„, version_info.txt ์ •ํ•ฉ ํ™•๋ณด, README ๋ฑƒ์ง€ ํ™•์žฅ์œผ๋กœ v1.0.7๋ถ€ํ„ฐ ๋ชจ๋“  ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ CI ์ž๋™ ๊ฒ€์ฆ์„ ๊ฑฐ์นœ๋‹ค๋Š” ์ƒˆ๋กœ์šด ๊ธฐ์ค€์„ ์ด ํ™•๋ฆฝ๋์Šต๋‹ˆ๋‹ค.

v1.0.7 is a technical-debt-cleanup release focused on infrastructure reinforcement rather than new features. Through three preparatory sessions, 15 orphan translation keys were removed and invariant tests were restructured into tab-based 10 functional categories, and TEST_MANAGEMENT_POLICY.md โ€” a new permanent reference document โ€” was established to codify the limits of the version-snapshot approach previously migrated by hand each release. The most significant change is the adoption of GitHub Actions CI, which immediately proved its value by surfacing two hidden issues on its very first runs (a phantom PyPI package, and Windows English-locale UnicodeEncodeError) that had gone undetected locally. With the APP_VERSION constant redesigned for version-independent structural verification, version_info.txt alignment secured, and README badges expanded, a new baseline is established: every release from v1.0.7 onward passes CI's automatic verification.


โœจ ์ฃผ์š” ๊ธฐ๋Šฅ / Major Features

  • GitHub Actions CI ๋„์ž… / GitHub Actions CI adoption

    • ๋Ÿฌ๋„ˆ: windows-latest ๋‹จ์ผ โ€” ํ•œ๋ฆผ ๋กœ์ปฌ Windows ํ™˜๊ฒฝ๊ณผ ์ผ์น˜, 531/0/0/0 ์žฌํ˜„ ์ตœ์šฐ์„  / Runner: windows-latest single โ€” matches Hanrim's local Windows, prioritizing 531/0/0/0 reproduction
    • Python 3.10 ๋‹จ์ผ โ€” ํ•œ๋ฆผ ๋กœ์ปฌ Python 3.10.11๊ณผ ์ผ์น˜ / Python 3.10 single โ€” matches local Python 3.10.11
    • pip ์บ์‹œ ์ ์šฉ โ€” 2๋ฒˆ์งธ ์‹คํ–‰๋ถ€ํ„ฐ 12๋ถ„ ๋‚ด ์™„๋ฃŒ / pip cache enabled โ€” subsequent runs complete in 12 minutes
    • ํŠธ๋ฆฌ๊ฑฐ: main push/PR + workflow_dispatch / Triggers: main push/PR + workflow_dispatch
    • ์ปค์Šคํ…€ ๋Ÿฌ๋„ˆ exit code ๊ณ„์•ฝ โ€” ์‹คํŒจ/์˜ค๋ฅ˜ ์‹œ sys.exit(1) ๋ฐ˜ํ™˜์œผ๋กœ CI ๋ฑƒ์ง€ ์ •ํ™•์„ฑ ๋ณด์žฅ / Custom runner exit-code contract โ€” returns sys.exit(1) on failure/error for CI badge accuracy
    • CI ์ฒซ ์‹คํ–‰์—์„œ ์ด๋ฏธ 2๊ฑด์˜ ์ˆจ์€ ์ด์Šˆ ๋ฐœ๊ฒฌ โ€” ํ”„๋กœ์ ํŠธ ์™„์„ฑ๋„์˜ ์‹ค์งˆ์  ํ–ฅ์ƒ / Two hidden issues already surfaced on CI's first runs โ€” real-world improvement in project completeness
  • ์„ธ์…˜ 3 โ€” ๋ฒˆ์—ญํ‚ค ๊ณ ์•„ 15๊ฑด ์ •๋ฆฌ / Session 3 โ€” 15 orphan translation key cleanup

    • ฮฒ ํ”„๋กœํ† ์ฝœ ์ ์šฉ ๊ฐ์‚ฌ: 17๊ฑด ๋ณด๊ณ  โ†’ 2๊ฑด ํ™œ์„ฑ ์‚ฌ์šฉ ํ™•์ธ(conv_sub_txt2epub/conv_sub_epub2txt ๋™์  ๋””์ŠคํŒจ์น˜) โ†’ 15๊ฑด ์ œ๊ฑฐ + 2๊ฑด ๋Œ€ํ‘œ ํ‚ค ํŽธ์ž… / ฮฒ-protocol audit: 17 reported โ†’ 2 confirmed actively used (conv_sub_txt2epub/conv_sub_epub2txt dynamic dispatch) โ†’ 15 removed + 2 absorbed as representative keys
    • ์ œ๊ฑฐ๋œ ํ‚ค 15๊ฐœ: bulk_out_folder, bulk_save_dir, bulk_save_fixed, bulk_save_over, merge_file_list, merge_file_mgmt, p_prefix_ph, sort_header, tag_file_list, tag_preview_title, tf_dlg_overwrite, tf_grp_opt, tf_ph_input, tf_subtitle, tf_title / 15 removed keys
    • ์ด 76์ค„ ์ œ๊ฑฐ (15ํ‚ค ร— 5์–ธ์–ด + ์ฃผ์„ 1์ค„) / Total 76 lines removed (15 keys ร— 5 languages + 1 comment line)
  • ์„ธ์…˜ 3 โ€” invariant ํ…Œ์ŠคํŠธ ํƒญ ๊ธฐ๋ฐ˜ 10๊ฐœ ๋Œ€๋ถ„๋ฅ˜ ์žฌ๊ตฌ์„ฑ / Session 3 โ€” invariant tests restructured into 10 tab-based major categories

    • ์ œ๊ฑฐ๋œ ๊ตฌ ๋ฒ„์ „ ์Šค๋ƒ…์ƒท ํ…Œ์ŠคํŠธ 7๊ฐœ: test_all_langs_have_dlg_keys, test_all_langs_have_sort_header, test_all_langs_have_sc_tab_bulk, test_all_langs_have_new_v010_keys, test_rename_keys_exist, test_all_langs_have_v010_1_keys, test_all_langs_have_v100_keys / 7 removed version-snapshot tests
    • ์‹ ์„ค 9๊ฐœ ํƒญ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ: common_dialog / text_merger / text_converter / tag_editor / batch_renamer / text_fixer / settings / shortcut / misc (๊ธฐ์กด bulk_fixer_keys ํ™•์žฅ ์œ ์ง€) / 9 new tab-based tests
    • test_ko_has_minimum_keys ๊ธฐ์ค€ ์ˆ˜์น˜ ๊ฐฑ์‹  (280 โ†’ 400, ํ˜„ 404๊ฐœ ๊ธฐ์ค€ ์•ˆ์ „ ๋งˆ์ง„) / Minimum key count threshold updated (280 โ†’ 400, safety margin based on current 404)
    • ๊ด€ํ†ต ์ถ•: "์—ญ์‚ฌ๋Š” Git ์ด๋ ฅ๊ณผ CHANGELOG๊ฐ€ ๋‹ด๋‹นํ•˜๊ณ , ํ…Œ์ŠคํŠธ๋Š” ํ˜„์žฌ ์‚ด์•„์žˆ๋Š” ๋ช…์„ธ๋กœ ์œ ์ง€๋œ๋‹ค" / Guiding principle: "History belongs to Git log and CHANGELOG; tests remain living specifications"
  • ์„ธ์…˜ 3 โ€” TEST_MANAGEMENT_POLICY.md ์‹ ์„ค / Session 3 โ€” TEST_MANAGEMENT_POLICY.md established

    • ํ”„๋กœ์ ํŠธ ์˜๊ตฌ ์ฐธ์กฐ ๋ฌธ์„œ (155์ค„, ๋ฃจํŠธ ๋ฐฐ์น˜) / Permanent project reference document (155 lines, placed at repo root)
    • 5๋Œ€ ์›์น™ ๋ช…๋ฌธํ™” + ๋ฐ๋“œ ํŒ์ • ๊ธฐ์ค€ 5๊ฐœ (ํ…Œ์ŠคํŠธ ํŒŒ์ผ invariant ๋“ฑ๋ก ์—ฌ๋ถ€ ์‹ ์„ค ํฌํ•จ) / Codified 5 core principles + 5 dead-code judgment criteria (including new "test-file invariant registration" criterion)
    • ๋Œ€๋ถ„๋ฅ˜ 10๊ฐœ ๋ช…์„ธ + ๊ธˆ์ง€ ์‚ฌํ•ญ (๋ฒ„์ „ ์Šค๋ƒ…์ƒท ๋ฐฉ์‹ invariant ์‹ ๊ทœ ๋„์ž… ๊ธˆ์ง€) / 10 category specifications + prohibitions (ban on new version-snapshot-style invariants)
  • TestAppVersion ๋ฒ„์ „-๋…๋ฆฝ ๊ตฌ์กฐ ๊ฒ€์ฆ ์žฌ์„ค๊ณ„ / TestAppVersion redesigned for version-independent structural verification

    • ๊ธฐ์กด ๊ด€๋ก€: TestV104Regression โ†’ TestV105Regression โ†’ TestV106AppVersion ๋งค ๋ฆด๋ฆฌ์ฆˆ ์ด์›” / Previous pattern: migration at each release
    • ์žฌ์„ค๊ณ„: ์„ธ๋ฏธ๋ฒ„์ „(MAJOR.MINOR.PATCH) ํฌ๋งท ๊ฒ€์ฆ์œผ๋กœ ์ „ํ™˜ โ€” ํ–ฅํ›„ ๋ฒ„์ „ ๊ฐฑ์‹  ์‹œ ํ…Œ์ŠคํŠธ ์ˆ˜์ • ๋ถˆํ•„์š” / Redesign: switched to semver (MAJOR.MINOR.PATCH) format validation โ€” no test updates needed on future version bumps
    • TEST_MANAGEMENT_POLICY.md ยง4.4 "๋ฒ„์ „ ์Šค๋ƒ…์ƒท ๋ฐฉ์‹ invariant ์‹ ๊ทœ ๋„์ž… ๊ธˆ์ง€" ์›์น™์„ ๋ฒˆ์—ญํ‚ค ์™ธ ์ฝ”๋“œ ๋ฒ„์ „ ์Šค๋ƒ…์ƒท์—๋„ ์ ์šฉ / Applied TEST_MANAGEMENT_POLICY.md ยง4.4 "ban on new version-snapshot-style invariants" to code version snapshots as well

๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ • / Bug Fixes

  • APP_VERSION ์ƒ์ˆ˜ ๊ฐฑ์‹  ๋ˆ„๋ฝ / APP_VERSION constant update omission (์„ธ์…˜ 3 ๋ˆ„๋ฝ / session 3 omission)

    • ํ˜„์ƒ: FileNexusSuite.py L76 APP_VERSION = "1.0.6" ๊ทธ๋Œ€๋กœ ๋‚จ์•„ ์•ฑ ํƒ€์ดํ‹€ยท๋„์›€๋ง ์ฐฝ ๋ฒ„์ „ ํ‘œ์‹œ๊ฐ€ v1.0.6์œผ๋กœ ๋ณด์ž„ / Symptom: L76 APP_VERSION = "1.0.6" left unchanged โ€” app title and help window version display showed v1.0.6
    • ๋ฐœ๊ฒฌ: ๋ฆด๋ฆฌ์ฆˆ ์ง์ „ ํ•œ๋ฆผ์˜ findstr /S /I "1\.0\.6" ์ „์ˆ˜ ๊ฒ€์ฆ์œผ๋กœ ๋“œ๋Ÿฌ๋‚จ / Discovered: during Hanrim's pre-release findstr /S /I "1\.0\.6" verification sweep
    • ์ˆ˜์ •: APP_VERSION = "1.0.7" ๊ฐฑ์‹  โ€” f-string์œผ๋กœ ์ฐธ์กฐ๋˜๋Š” ์•ฑ ์ „์—ญ ๋ฒ„์ „ ํ‘œ์‹œ๊ฐ€ ์ž๋™ ์ผ๊ด€ ๊ฐฑ์‹  / Fix: updated to "1.0.7" โ€” all f-string references across the app automatically reflect the new version
  • version_info.txt ๋ฒ„์ „ 4๊ณณ ์ž”์กด / version_info.txt 4-point version residue

    • ํ˜„์ƒ: filevers, prodvers ํŠœํ”Œ + FileVersion, ProductVersion ๋ฌธ์ž์—ด์ด ๋ชจ๋‘ 1.0.6 / Symptom: filevers/prodvers tuples and FileVersion/ProductVersion strings all at 1.0.6
    • ์˜ํ–ฅ: PyInstaller ๋นŒ๋“œ ์‹œ Windows .exe ์†์„ฑ ์ฐฝ์˜ ๋ฒ„์ „ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ v1.0.6์œผ๋กœ ํ‘œ์‹œ๋จ / Impact: PyInstaller builds would show v1.0.6 in Windows .exe file properties
    • ์ˆ˜์ •: 4๊ณณ ๋ชจ๋‘ v1.0.7 / 1.0.7.0์œผ๋กœ ๊ฐฑ์‹  โ€” Copyright ยฉ 2026 Hanrim ํ‘œ๊ธฐ๋Š” ์œ ์ง€ (๋งค์ฒด๋ณ„ ๊ฐ„๊ฒฐ/ํ’€๋„ค์ž„ ๊ตฌ๋ถ„ ์ •์ฑ…) / Fix: all 4 locations updated โ€” Copyright ยฉ 2026 Hanrim preserved (per-medium brevity/full-name policy)
  • CI ์ฒซ ์‹คํ–‰ hotfix โ€” PyPI ์œ ๋ น ํŒจํ‚ค์ง€ / CI first-run hotfix โ€” phantom PyPI package

    • ํ˜„์ƒ: pip install -r requirements.txt ์‹คํ–‰ ์‹œ PySide6-Qt6-Qt6Svg>=6.4.0์—์„œ ERROR: Could not find a version that satisfies the requirement ์‹คํŒจ (CI #1, 39์ดˆ) / Symptom: pip install failed with "No matching distribution found" for PySide6-Qt6-Qt6Svg>=6.4.0 (CI #1, 39s)
    • ์›์ธ: PyPI์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํŒจํ‚ค์ง€. ํ•œ๋ฆผ ๋กœ์ปฌ์—์„œ๋Š” ์ด๋ฏธ ์„ค์น˜๋œ ์ƒํƒœ๋ผ pip install ์‹œ ์กฐ์šฉํžˆ ๋„˜์–ด๊ฐ€ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์Œ / Cause: package does not exist on PyPI. Locally, it was already installed, so pip silently skipped โ€” the issue went undetected
    • ์ˆ˜์ •: requirements.txt์—์„œ ํ•ด๋‹น ์ค„ ์ œ๊ฑฐ. PySide6 ๋ณธ์ฒด๊ฐ€ QtSvg ๋ชจ๋“ˆ์„ ๋‚ด์žฅ / Fix: removed the line from requirements.txt. PySide6 bundles QtSvg natively
    • ์˜์˜: CI ๋„์ž…์˜ ๊ฐ€์น˜๊ฐ€ ์ฒซ ์‹คํ–‰์—์„œ ๋ฐ”๋กœ ์ž…์ฆ๋จ / Significance: CI's value proven on its very first run
  • CI 2๋ฒˆ์งธ ์‹คํ–‰ hotfix โ€” Windows ๋กœ์ผ€์ผ UnicodeEncodeError / CI second-run hotfix โ€” Windows locale UnicodeEncodeError

    • ํ˜„์ƒ: ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ ์‹คํ–‰ ์ค‘ UnicodeEncodeError: 'charmap' codec can't encode character '\ud83d' (CI #2, 1๋ถ„ 10์ดˆ) / Symptom: UnicodeEncodeError: 'charmap' codec can't encode character '\ud83d' during test runner (CI #2, 1m 10s)
    • ์›์ธ: GitHub Actions windows-latest ๊ธฐ๋ณธ ์ฝ˜์†” ์ธ์ฝ”๋”ฉ์ด cp1252 (์˜์–ด ๋กœ์ผ€์ผ)๋ผ ํ•œ๊ธ€ยท์ด๋ชจ์ง€ ์ถœ๋ ฅ ์‹คํŒจ. ํ•œ๋ฆผ ๋กœ์ปฌ์€ cp949 ๋˜๋Š” UTF-8 ๋ชจ๋“œ๋ผ ๋ฌธ์ œ ์—†์Œ / Cause: GitHub Actions windows-latest default console encoding is cp1252 (English locale), failing on Korean/emoji output. Local Windows uses cp949 or UTF-8 mode
    • ์ˆ˜์ •: ์ปค์Šคํ…€ ๋Ÿฌ๋„ˆ ์ง„์ž…๋ถ€์— sys.stdout.reconfigure(encoding='utf-8') ์ถ”๊ฐ€ (Python 3.7+ ํ‘œ์ค€, hasattr ๊ฐ€๋“œ๋กœ ๋ฌดํ•ด) / Fix: added sys.stdout.reconfigure(encoding='utf-8') at runner entry (Python 3.7+ standard, guarded by hasattr)
  • ์˜์กด์„ฑ ์„ ์–ธ ๋ถˆ์ผ์น˜ / Dependency declaration inconsistency

    • requirements.txt์— python-hwpx>=2.9.0 ๋ˆ„๋ฝ โ€” v1.0.6 HWPX ์ž…๋ ฅ ์ง€์› ์˜์กด์„ฑ์ด READMEยท๊ธฐ์ˆ  ์Šคํƒ์—๋งŒ ๋ช…์‹œ๋˜๊ณ  requirements์—์„œ ๋น ์ ธ ์žˆ๋˜ ๋ถˆ์ผ์น˜ ํ•ด์†Œ / python-hwpx>=2.9.0 was missing from requirements.txt โ€” v1.0.6 HWPX input support dependency was only stated in README/tech-stack but missing from requirements; inconsistency now resolved
  • README_EN.md ๋ฑƒ์ง€ ๋™๊ธฐํ™” ๋ˆ„๋ฝ / README_EN.md badge sync omission

    • ์„ธ์…˜ 3์—์„œ ํ•œ๊ตญ์–ด README๋งŒ ๊ฐฑ์‹ ํ•˜๊ณ  ์˜์–ด ๋ฒ„์ „์„ ๋ˆ„๋ฝ / Korean README was updated in session 3, but English version was overlooked
    • ์ˆ˜์ •: version ๋ฑƒ์ง€ 1.0.6 โ†’ 1.0.7, CI ๋ฑƒ์ง€ ์ถ”๊ฐ€, tests ๋ฑƒ์ง€ ์ถ”๊ฐ€, ์„ค์น˜ ๋ช…๋ น์–ด pip install -r requirements.txt๋กœ ๋‹จ์ˆœํ™” / Fix: version badge 1.0.6 โ†’ 1.0.7, CI badge added, tests badge added, install command simplified

๐Ÿ“„ ๋ฌธ์„œ / Documentation

  • TEST_MANAGEMENT_POLICY.md ์‹ ์„ค (155์ค„, ๋ฃจํŠธ ๋ฐฐ์น˜) / New TEST_MANAGEMENT_POLICY.md (155 lines, repo root)
    • ํ…Œ์ŠคํŠธ ๊ด€๋ฆฌ 5๋Œ€ ์›์น™, ๋Œ€๋ถ„๋ฅ˜ 10๊ฐœ ๋ช…์„ธ, ๋ฐ๋“œ ํŒ์ • ๊ธฐ์ค€, ๊ธˆ์ง€ ์‚ฌํ•ญ์„ ๋ช…๋ฌธํ™”ํ•œ ํ”„๋กœ์ ํŠธ ์˜๊ตฌ ์ฐธ์กฐ ๋ฌธ์„œ / Codifies 5 core principles of test management, 10 category specifications, dead-code criteria, and prohibitions โ€” permanent project reference
  • CHANGELOG.md v1.0.7 ์„น์…˜ ํ™•์žฅ / CHANGELOG.md v1.0.7 section expanded
    • Fixed / Removed / Changed / Added / Tests / File Changes / Deferred 7๊ฐœ ํ•˜์œ„ ์„น์…˜ / 7 subsections: Fixed / Removed / Changed / Added / Tests / File Changes / Deferred
  • README.md / README_EN.md ๋ฑƒ์ง€ ํ™•์žฅ / README.md / README_EN.md badge expansion
    • CI ์ƒํƒœ ๋ฑƒ์ง€ + 531 tests passing ๋ฑƒ์ง€ ์ถ”๊ฐ€, ์„ค์น˜ ๋ช…๋ น์–ด ๋‹จ์ผ ์ง„์‹ค ์›์ฒœํ™” (pip install -r requirements.txt) / CI status badge + 531 tests passing badge added; install command centralized

๐Ÿงช ํ…Œ...

Read more

File Nexus Suite v1.0.6

Choose a tag to compare

@MerciHanrim MerciHanrim released this 21 Apr 14:23
v1.0.6
5335461

v1.0.6 โ€” Text Converter ๊ตฌ์กฐ ๋ฆฌํŒฉํ† ๋ง + ๋ถ€๋ถ„ ์†์ƒ ํŒŒ์ผ ๋Œ€์‘ + ์„ค์ • ๋‹ค์ด์–ผ๋กœ๊ทธ ๋ฒˆ์ฒด ์ž”์žฌ ์ˆ˜์ • / Text Converter refactoring + partial corruption handling + Settings dialog Traditional Chinese residue fix

Text Converter ๋ ˆ์ด์•„์›ƒ์„ Bulk Fixer(v1.0.6) ํŒจํ„ด์œผ๋กœ ์žฌ๊ตฌ์„ฑํ•˜์—ฌ ๋“œ๋กญ์กด ๋ถ„๋ฆฌยท5:4 ๋ ˆ์ด์•„์›ƒยทํ•˜๋‹จ ์•ˆ๋‚ด ๋ฐ•์Šค ์ œ๊ฑฐ๋ฅผ ์ ์šฉํ–ˆ๊ณ , ๋ฉ”๋ชจ์žฅ์—์„  ์—ด๋ฆฌ๋Š”๋ฐ Python strict ํด๋ฐฑ์ด ๋ชจ๋‘ ์‹คํŒจํ•˜๋˜ ๋ถ€๋ถ„ ์†์ƒ ์ธ์ฝ”๋”ฉ ํŒŒ์ผ ๋Œ€์‘์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค(Phase 1 + Phase 2-a ํ‹ฐ์–ด๋“œ ์ž๋™ ์ฒ˜๋ฆฌ). Text Merger๋Š” HWPX ์ž…๋ ฅ ์ง€์›๊ณผ A1'' ์ธ์ฝ”๋”ฉ ์ž๋™ ์ถ”์ฒœ ๊ธฐ๋Šฅ์„ ์–ป์—ˆ๊ณ , v1.0.5๋ถ€ํ„ฐ ์กด์žฌํ•˜๋˜ ์„ค์ • ๋‹ค์ด์–ผ๋กœ๊ทธ ๋ฒˆ์ฒด ์ค‘๊ตญ์–ด ์ž”์žฌ ๋ฒ„๊ทธ๋ฅผ ๊ทผ๋ณธ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†์‹ค ์œ„ํ—˜์ด ์žˆ๋˜ toolTip ์˜ค์—ผ ๋ฒ„๊ทธ์™€ ํ—ค๋” ์ •๋ ฌ ๋ฒ„๊ทธ๋„ ํ•จ๊ป˜ ํ•ด๊ฒฐํ–ˆ๊ณ , ๋ถ„ ๋‹จ์œ„ ๊ฑธ๋ฆฌ๋˜ O(Nร—K) ์œ„์น˜ ์ถ”์  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ O(N)์œผ๋กœ ์žฌ์„ค๊ณ„ํ•ด ์ˆ˜๋ฐฑ~์ˆ˜์ฒœ ๋ฐฐ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

Rebuilt the Text Converter layout along the Bulk Fixer (v1.0.6) pattern โ€” drop-zone separation, 5:4 left-right ratio, bottom help-box removal โ€” and added proper handling for partially corrupted encoding files that Notepad opens fine but Python's strict fallback all fail on (Phase 1 + Phase 2-a tiered automatic processing). Text Merger gained HWPX input support and A1'' automatic encoding recommendation, and a pre-existing Settings dialog Traditional Chinese residue bug (from v1.0.5) was rooted out. Also resolved the toolTip contamination bug (with data-loss risk) and header-sort bug, and redesigned the O(Nร—K) position-tracking algorithm to O(N) for hundreds-to-thousands times speedup on previously minute-long operations.


โœจ ์ฃผ์š” ๊ธฐ๋Šฅ / Major Features

  • Phase 2-a โ€” ์ธ์ฝ”๋”ฉ ๋ฆฌํฌํŠธ ๊ธฐ๋Šฅ + ํ‹ฐ์–ด๋“œ ์ž๋™ ์ฒ˜๋ฆฌ / Phase 2-a โ€” encoding report generation + tiered automatic processing

    • Bulk Fixer๊ฐ€ ๋ถ€๋ถ„ ์†์ƒ ํŒŒ์ผ์„ ์„ธ ํ‹ฐ์–ด๋กœ ์ž๋™ ๋ถ„๋ฅ˜ / Bulk Fixer now automatically classifies partially corrupted files into three tiers
    • Tier 1 (์†์ƒ โ‰ค500์ž): ์ฒ˜๋ฆฌ + ๋ฆฌํฌํŠธ ์ƒ์„ฑ / Tier 1 (โ‰ค500 corrupt chars): process + generate report
    • Tier 2 (์†์ƒ 5015000์ž): ์ฒ˜๋ฆฌ + ๊ฒฝ๊ณ  ์ˆ˜์œ„ ๋ฆฌํฌํŠธ / Tier 2 (5015000 corrupt chars): process + elevated-warning report
    • Tier 3 (์†์ƒ 5001์ž+): ์›๋ณธ ๋ณดํ˜ธ ์Šคํ‚ต + ๋ฆฌํฌํŠธ๋งŒ / Tier 3 (5001+ corrupt chars): skip to preserve original + report only
    • ๋ฆฌํฌํŠธ ํŒŒ์ผ๋ช…: {์›๋ณธํŒŒ์ผ๋ช…}.encoding_report.txt (UTF-8 BOM ์—†์Œ) / Report filename: {original}.encoding_report.txt (UTF-8 without BOM)
    • ์‹ค์ธก ๊ธฐ๋ฐ˜ ์ž„๊ณ„๊ฐ’ ๊ฒฐ์ • โ€” make_tier_test_data.py๋กœ ๊ฒฝ๊ณ„๊ฐ’(499/5000/5001) ํ•ฉ์„ฑ ๋ฐ์ดํ„ฐ ํšŒ๊ท€ ๊ฒ€์ฆ / Empirically-chosen thresholds โ€” boundary values (499/5000/5001) validated via synthesized test data in make_tier_test_data.py
    • ์„ค๊ณ„ ์ฒ ํ•™ ๋ถ„๋ฆฌ: Text Fixer(์‚ฌ์šฉ์ž ๋™์˜ ๊ธฐ๋ฐ˜) / Bulk Fixer(์‚ฌํ›„ ํˆฌ๋ช…์„ฑ ๊ธฐ๋ฐ˜) / Philosophy separation: Text Fixer (user-consent based) vs. Bulk Fixer (post-hoc transparency based)
  • #7 Text Converter ๊ตฌ์กฐ ๋ฆฌํŒฉํ† ๋ง / #7 Text Converter structural refactoring

    • ์‹ ๊ทœ ํด๋ž˜์Šค TextConverterDropZone (109์ค„) โ€” BulkFixerDropZone ๋ณต์ œ + mode ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ TXTโ†”EPUB ์ „ํ™˜ ์‹œ ํ…์ŠคํŠธยท์•„์ด์ฝ˜ ์ž๋™ ๊ฐฑ์‹  / New class TextConverterDropZone (109 lines) โ€” cloned from BulkFixerDropZone + mode parameter auto-refreshing text/icon on TXTโ†”EPUB toggle
    • TextConverterFileList ๋‹จ์ˆœํ™” โ€” InternalMove โ†’ DragDrop ๋ชจ๋“œ ์ „ํ™˜, setSectionsClickable(True) ๋ช…์‹œ, startDrag CopyAction ๊ฐ•์ œ / Simplified TextConverterFileList โ€” InternalMove โ†’ DragDrop, explicit setSectionsClickable(True), forced startDrag CopyAction
    • ๋ ˆ์ด์•„์›ƒ 5:4 ์žฌ๊ตฌ์„ฑ โ€” ์™ผ์ชฝ(๋“œ๋กญ์กด+ํŒŒ์ผ๋ชฉ๋ก) ํ™•๋Œ€, ์˜ค๋ฅธ์ชฝ(์˜ต์…˜+์ถœ๋ ฅํด๋”+๋ณ€ํ™˜๋ฒ„ํŠผ+์ง„ํ–‰๋ฐ”+์ƒํƒœ) ์žฌ๋ฐฐ์น˜ / Layout restructured 5:4 โ€” left panel (dropzone + file list) expanded, right panel (options + output folder + convert button + progress + status) rearranged
    • ํ•˜๋‹จ ์•ˆ๋‚ด ๋ฐ•์Šค ์ œ๊ฑฐ (conv_help 5๊ฐœ ์–ธ์–ด ๋ฒˆ์—ญ ํ‚ค ์‚ญ์ œ) / Bottom help-box removed (conv_help translation keys dropped across 5 languages)
    • ํด๋” ๋“œ๋กญ ๋ฏธ์ง€์› โ€” EPUB ์ƒ์„ฑ ์‹œ ์›๋ณธ ํด๋” ๊ตฌ์กฐ ๋ณด์กด ์ด์Šˆ ๋ฐฉ์ง€ (์˜๋„๋œ ์„ค๊ณ„) / Folder drop unsupported โ€” intentional design to avoid EPUB source-folder structure preservation issues
    • ์‹ค๊ธฐ QA 9/9 ์ „์ˆ˜ ํ†ต๊ณผ โ€” ๋“œ๋กญ์กด ์–‘๋ฐฉํ–ฅ / ๋ชจ๋“œ ์ „ํ™˜ / ๋‚ด๋ถ€ ๋“œ๋ž˜๊ทธ / ํ—ค๋” ์ •๋ ฌ / 5:4 / 5๊ฐœ ์–ธ์–ด / ๋ณ€ํ™˜ E2E / toolTip ํšŒ๊ท€ / ํ…Œ๋งˆ ์ „ํ™˜ / IceCream Ebook Reader ์™ธ๋ถ€ ๊ฒ€์ฆ ํฌํ•จ / Manual QA 9/9 passed โ€” dropzone bidirectional / mode toggle / internal drag / header sort / 5:4 / 5 languages / round-trip conversion / toolTip regression / theme switch / with external IceCream Ebook Reader verification
  • Text Merger โ€” HWPX ์ž…๋ ฅ ์ง€์› / Text Merger โ€” HWPX input support

    • python-hwpx 2.9.0 (MIT) ๋„์ž…, .hwpx โ†’ ํ…์ŠคํŠธ ์ถ”์ถœ / Added python-hwpx 2.9.0 (MIT), .hwpx โ†’ text extraction
    • MergeEncodingDelegate์— HWPX ๋ฐฐ์ง€(#9B59B6 ๋ณด๋ผ์ƒ‰) ํ‘œ์‹œ / Purple HWPX badge (#9B59B6) on MergeEncodingDelegate
    • HWP(๊ตฌํ˜•) ๊ฐ์ง€ ์‹œ ํ†ตํ•ฉ ์•ˆ๋‚ด ๋‹ค์ด์–ผ๋กœ๊ทธ โ€” 5๊ฐœ ์–ธ์–ด / HWP (legacy) detection shows a unified informational dialog across 5 languages
    • lxml 5.4.0์œผ๋กœ ์ž๋™ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ ๋ฐœ์ƒ (๊ฒฝ๊ณ ๋งŒ, ๋™์ž‘ ์˜ํ–ฅ ์—†์Œ) / lxml auto-downgraded to 5.4.0 (warning only, no functional impact)
  • Text Merger โ€” A1'' ์ธ์ฝ”๋”ฉ ์ž๋™ ์ถ”์ฒœ / Text Merger โ€” A1'' automatic encoding recommendation

    • ์ƒˆ ํ•จ์ˆ˜ merger_recommend_save_encoding() โ€” ๋ชจ๋“  ํ…์ŠคํŠธ ํŒŒ์ผ์ด ๊ฐ™์€ ๋น„์œ ๋‹ˆ์ฝ”๋“œ ์ธ์ฝ”๋”ฉ + ์‹ ๋ขฐ๋„ โ‰ฅ0.7์ผ ๋•Œ ๊ทธ ์ธ์ฝ”๋”ฉ ์ถ”์ฒœ, ๊ทธ ์™ธ UTF-8 / New function merger_recommend_save_encoding() โ€” recommends the non-Unicode encoding if all files share it with confidence โ‰ฅ0.7, otherwise UTF-8
    • UI: ๋“œ๋กญ๋‹ค์šด ์•„๋ž˜ "๐Ÿ’ก ์ถ”์ฒœ: XXX" ๋ผ๋ฒจ + [์ ์šฉ] ๋ฒ„ํŠผ / UI: "๐Ÿ’ก Recommended: XXX" label + [Apply] button beneath the dropdown
    • ํŒŒ์ผ ์ถ”๊ฐ€/์„ ํƒ์‚ญ์ œ/์ „์ฒด์‚ญ์ œ/์–ธ์–ด์ „ํ™˜ 4์ง€์ ์—์„œ ์ž๋™ ๊ฐฑ์‹  / Auto-refresh at 4 trigger points: add files / delete selected / clear all / language switch
  • Phase 1 โ€” ๋ถ€๋ถ„ ์†์ƒ ํŒŒ์ผ ์•ˆ์ „ ์ฒ˜๋ฆฌ / Phase 1 โ€” safe handling of partially corrupted files

    • ๊ณตํ†ต ํ—ฌํผ safe_read_text_with_report() โ€” strict ํด๋ฐฑ 8๊ฐœ ๋ชจ๋‘ ์‹คํŒจ ์‹œ errors='replace'๋กœ ์ตœ์ข… ์žฌ์‹œ๋„ / Shared helper safe_read_text_with_report() โ€” final retry with errors='replace' when all 8 strict fallbacks fail
    • ๊นจ์ง„ ๋ฐ”์ดํŠธ๋Š” U+FFFD (๏ฟฝ)๋กœ ๋Œ€์ฒด (Python ๊ธฐ๋ณธ๊ฐ’, ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€) / Corrupt bytes replaced with U+FFFD (๏ฟฝ), Python's default and the Unicode standard
    • Text Fixer replace ๋ชจ๋“œ ์‹œ ๊ฒฝ๊ณ  ๋‹ค์ด์–ผ๋กœ๊ทธ tf_warn_partial_enc (5๊ฐœ ์–ธ์–ด) / Text Fixer replace mode shows warning dialog tf_warn_partial_enc in 5 languages
    • Bulk Fixer ๋ฏธ๋ฆฌ๋ณด๊ธฐยท์ผ๊ด„ ๊ต์ •ยทText Fixer ํŒŒ์ผ ๋กœ๋“œ 3๊ณณ ์ ์šฉ / Applied in 3 locations: Bulk Fixer preview, Bulk Fixer worker, Text Fixer file load
  • Phase 2-b โ€” Text Fixer / Bulk Fixer ๋„์›€๋ง ํ™•์žฅ / Phase 2-b โ€” Text Fixer / Bulk Fixer help section expansion

    • Text Fixer ๋„์›€๋ง: "Partially corrupted files note" + ๋‹จ์ผ ํŒŒ์ผ ๊ฒ€ํ†  ๋„๊ตฌ ๋ช…์‹œ + Tier 3 ์ž๋™ ์Šคํ‚ต ์•ˆ๋‚ด / Text Fixer help: "Partially corrupted files note" + single-file review tool explanation + Tier 3 auto-skip notice
    • Bulk Fixer ๋„์›€๋ง: "Automatic corruption tiering note" (Tier 1/2/3 ์ƒ์„ธ) + ๋ฆฌํฌํŠธ ํŒŒ์ผ๋ช… ํ˜•์‹ + Text Fixer ๊ฐœ๋ณ„ ๊ฒ€ํ†  ์œ ๋„ / Bulk Fixer help: "Automatic corruption tiering note" (Tier 1/2/3 details) + report filename format + Text Fixer individual review guidance
    • 5๊ฐœ ์–ธ์–ด ๋ชจ๋‘ ์‹œ๊ฐ ๊ฒ€์ˆ˜ ํ†ต๊ณผ / Visual review passed in all 5 languages

๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ • / Bug Fixes

  • ์„ค์ • ๋‹ค์ด์–ผ๋กœ๊ทธ ๋ฒˆ์ฒด ์ค‘๊ตญ์–ด ์ž”์žฌ / Settings dialog Traditional Chinese residue (v1.0.5๋ถ€ํ„ฐ ์กด์žฌ / pre-existing since v1.0.5)

    • ํ˜„์ƒ: ็น้ซ” โ†’ ํ•œ๊ตญ์–ด ์ „ํ™˜ ์‹œ ๋‹จ์ถ•ํ‚ค ๋ฆฌ์…‹ ๋ฒ„ํŠผ์— ้ ่จญ, ้‡่จญๆ‰€ๆœ‰ๅฟซๆท้ต / ์ถœ๋ ฅ ํด๋” ๋ผ๋ฒจ์— ่ผธๅ‡บ่ณ‡ๆ–™ๅคพ / ๋ฒ„ํŠผ์— ้ธๆ“‡่ณ‡ๆ–™ๅคพ / ้‡่จญ ๋“ฑ ๋ฒˆ์ฒด ์ž”์žฌ / Symptom: after switching ็น้ซ” โ†’ Korean, residue like ้ ่จญ, ้‡่จญๆ‰€ๆœ‰ๅฟซๆท้ต, ่ผธๅ‡บ่ณ‡ๆ–™ๅคพ, ้ธๆ“‡่ณ‡ๆ–™ๅคพ, ้‡่จญ remained
    • ์›์ธ: SettingsDialog._retranslate_dialog๊ฐ€ ์ผ๋ถ€ ์œ„์ ฏ ํ…์ŠคํŠธ ๊ฐฑ์‹ ์„ ๋ˆ„๋ฝ (๋‹จ์ถ•ํ‚ค ๋ฆฌ์…‹ ๋ฒ„ํŠผ 6๊ฐœ + ์ „์ฒด ๋ฆฌ์…‹ + ์ผ๋ฐ˜ ์„ค์ • ์ถœ๋ ฅ ํด๋” ๋ผ๋ฒจยท๋ฒ„ํŠผ + ๋ผ์ด์„ ์Šค ํƒ€์ดํ‹€) / Root cause: SettingsDialog._retranslate_dialog missed text updates for 6 individual reset buttons + reset-all button + output folder label/buttons + license title
    • ์ˆ˜์ • โ€” ์ง€์‹œ์„œ v2 ๊ธฐ๋ฐ˜: _apply_theme_now์— _retranslate_dialog() ํ˜ธ์ถœ ์ถ”๊ฐ€(ยง2.1), ์œ„์ ฏ self ์ €์žฅ 9๊ฐœ ๋ณด์™„(ยง2.2), _retranslate_dialog์— D-1/D-2/D-3 ๋ธ”๋ก ํ™•์žฅ(ยง2.4) / Fix โ€” per Work Instruction v2: added _retranslate_dialog() call to _apply_theme_now (ยง2.1), preserved 9 widget self-references (ยง2.2), expanded _retranslate_dialog with D-1/D-2/D-3 blocks (ยง2.4)
    • AppSuite ๋‚ด ๋ฐ๋“œ ์ฝ”๋“œ 3๊ฐœ ๋ฉ”์„œ๋“œ 74์ค„ ์™„์ „ ์ œ๊ฑฐ(ยง2.5) โ€” _page_language / _on_lang_selected / _retranslate_dialog (SettingsDialog๊ฐ€ ๋ณ„๋„ QDialog๋กœ ๋ถ„๋ฆฌ๋˜๊ธฐ ์ „ ์ž”์žฌ๋œ ๋ณต์ œ๋ณธ) / Removed 3 dead methods (74 lines) in AppSuite (ยง2.5) โ€” remnants from before SettingsDialog was split into a separate QDialog
  • toolTip ์˜ค์—ผ ๋ฐ์ดํ„ฐ ์†์‹ค ๋ฒ„๊ทธ / toolTip contamination data-loss bug (v1.0.4๋ถ€ํ„ฐ ์กด์žฌ / pre-existing since v1.0.4)

    • ํ˜„์ƒ: ์‹ ๋ขฐ๋„ <0.90 ํŒŒ์ผ์˜ ํˆดํŒ์— ์•ˆ๋‚ด๋ฌธ์ด ๋ง๋ถ™์–ด item.toolTip(0) ๊ธฐ๋ฐ˜ ๊ฒฝ๋กœ ์กฐํšŒ ์‹คํŒจ โ†’ ์‚ญ์ œํ•œ ํŒŒ์ผ์ด ๋ณ‘ํ•ฉ ๊ฒฐ๊ณผ์— ํฌํ•จ๋˜๋Š” ๋ฐ์ดํ„ฐ ์†์‹ค / Symptom: low-confidence (<0.90) files had info appended to their toolTip, breaking item.toolTip(0) path lookups โ†’ deleted files included in merge output, causing data loss
    • ์ˆ˜์ •: _PATH_ROLE = Qt.ItemDataRole.UserRole + 4 ์‹ ์„ค, ์ˆœ์ˆ˜ ๊ฒฝ๋กœ ์ €์žฅ / Fix: new _PATH_ROLE = Qt.ItemDataRole.UserRole + 4 storing pure paths
    • 3๊ฐœ ํด๋ž˜์Šค ์ ์šฉ: MergeEncodingDelegate, TextConverterFileList, BulkFixerFileList / Applied to 3 classes: MergeEncodingDelegate, TextConverterFileList, BulkFixerFileList
    • ํ•˜์œ„ ํ˜ธํ™˜ ํด๋ฐฑ ์œ ์ง€: item.data(0, _PATH_ROLE) or item.toolTip(0) / Backward-compat fallback retained: item.data(0, _PATH_ROLE) or item.toolTip(0)
  • ํ—ค๋” ์ •๋ ฌ ๋ฒ„๊ทธ / Header sort bug (v1.0.4๋ถ€ํ„ฐ ์กด์žฌ / pre-existing since v1.0.4)

    • ํ˜„์ƒ: setSortingEnabled(False) + DragDrop ๋ชจ๋“œ ์กฐํ•ฉ์—์„œ ํ—ค๋” ํด๋ฆญ์œผ๋กœ ์ •๋ ฌ์ด ๋™์ž‘ํ•˜์ง€ ์•Š์Œ / Symptom: with setSortingEnabled(False) + DragDrop mode, header-click sorting stopped working
    • ์›์ธ: Qt์˜ ๊ธฐ๋ณธ ๋™์ž‘์œผ๋กœ setSortingEnabled(False) ์‹œ ํ—ค๋” ์„น์…˜ ํด๋ฆญ์ด ๋น„ํ™œ์„ฑํ™”๋จ / Cause: Qt disables header section clicks when setSortingEnabled(False)
    • ์ˆ˜์ •: hdr.setSectionsClickable(True) ๋ช…์‹œ ์ถ”๊ฐ€ (MergeFileTree v1.0.3/1.0.4 ํŒจํ„ด ๋ณต์ œ) / Fix: explicit hdr.setSectionsClickable(True) (pattern cloned from MergeFileTree v1.0.3/1.0.4)
  • alchemy_detect_encoding ํด๋ฐฑ ์‹ ๋ขฐ๋„ 0.0 โ†’ 0.7 / alchemy_detect_encoding fallback confidence 0.0 โ†’ 0.7

    • ํด๋ฐฑ ๋ฃจํ”„ ํ†ต๊ณผ ์‹œ(cp949/shift_jis/gbk/big5) ์‹ ๋ขฐ๋„๋ฅผ 0.7๋กœ ์ƒํ–ฅ / Confidence raised to 0.7 on fallback-loop success (cp949/shift_jis/gbk/big5)
    • utf-8 strict ํด๋ฐฑ๋„ 0.0 โ†’ 0.7 (์ผ๊ด€์„ฑ) / utf-8 strict fallback also raised to 0.7 (consistency)
    • ์งง์€ ํ•œ๊ธ€ CP949 ํŒŒ์ผ์ด "70% CP949" ๋ฐฐ์ง€ + "๐Ÿ’ก ์ถ”์ฒœ: CP949"๋กœ ์ •์ƒ ํ‘œ์‹œ / Short Korean CP949 files now correctly show "70% CP949" badge + "๐Ÿ’ก Recommended: CP949"

โšก ์„ฑ๋Šฅ ๊ฐœ์„  / Performance Improvements

  • O(Nร—K) โ†’ O(N) ์œ„์น˜ ์ถ”์  ์žฌ์„ค๊ณ„ / O(Nร—K) โ†’ O(N) position tracking redesign
    • ๊ธฐ์กด: ํŒŒ์ผ๋‹น ์†์ƒ ๋ฐ”์ดํŠธ K๊ฐœ ์ฐพ๊ธฐ ์œ„ํ•ด N๋ฐ”์ดํŠธ ์ „์ˆ˜ ์ˆœํšŒ โ†’ KํšŒ ๋ฐ˜๋ณต = O(Nร—K) / Before: for each of K corrupt bytes, scanned all N bytes โ†’ O(Nร—K)
    • ์‹ ๊ทœ: codecs.register_error('_fns_track', ...) ๊ธฐ๋ฐ˜ ๋‹จ์ผ ํŒจ์Šค๋กœ ๋””์ฝ”๋”ฉ ์ค‘ ์œ„์น˜ ์ˆ˜์ง‘ โ†’ O(N) / After: single-pass position collecti...
Read more

File Nexus Suite v1.0.5

Choose a tag to compare

@MerciHanrim MerciHanrim released this 18 Apr 17:57
v1.0.5
74883f1

v1.0.5 โ€” Text Merger ์ €์žฅ ์ธ์ฝ”๋”ฉ ๋“œ๋กญ๋‹ค์šด UI ์‚ฌ์šฉ์„ฑ ๊ฐœ์„  / Text Merger save-encoding dropdown UI usability improvements

๋น„ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ 8์ข… ์ €์žฅ ์ธ์ฝ”๋”ฉ ์ค‘ ๋ฌด์—‡์„ ๊ณจ๋ผ์•ผ ํ• ์ง€ ์ง๊ด€์ ์œผ๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก Text Merger ๋“œ๋กญ๋‹ค์šด ๋ผ๋ฒจ์— ์—ฐ๊ด€ ์–ธ์–ด๋ฅผ ๋ณ‘๊ธฐํ•˜๊ณ  ์ฝค๋ณด๋ฐ•์Šค ์•„๋ž˜์— ํ•œ ์ค„ ๋„์›€๋ง์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ํ‚ค์™€ ํ‘œ์‹œ ๋ผ๋ฒจ์„ ๋ถ„๋ฆฌํ•˜๋Š” addItem(display, userData) ๋ฆฌํŒฉํ† ๋ง์„ ํ†ตํ•ด v1.0.4 ์ดํ•˜ ์„ค์ • ํŒŒ์ผ๊ณผ๋„ ์™„์ „ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ ํ›„ QA ์ค‘ ๋ฐœ๊ฒฌ๋œ "์–ธ์–ด ์ „ํ™˜ ์‹œ ์ƒํƒœ ๋ฉ”์‹œ์ง€๊ฐ€ ํ•œ๊ตญ์–ด๋กœ ๋‚จ๋˜ ๊ธฐ์กด ๋ฒ„๊ทธ"๋„ ํ•จ๊ป˜ ํ•ด์†Œํ–ˆ๊ณ , v1.0.2๋ถ€ํ„ฐ ์‹๋ณ„๋๋˜ ๋ฒˆ์—ญ ์‚ฌ์ „ ์ค‘๋ณต ํ‚ค 74๊ฐœ๋ฅผ ์ผ๊ด„ ์ •๋ฆฌํ•˜์—ฌ ๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ํ•ด์†Œํ–ˆ์Šต๋‹ˆ๋‹ค.

Redesigned the Text Merger save-encoding dropdown: each item now carries a language hint (e.g. Shift-JIS (์ผ๋ณธ์–ด)), and a one-line helper ("If unsure, select UTF-8") sits beneath the combobox. Internally, display labels were separated from stable keys using the addItem(display, userData) pattern, preserving full config compatibility with v1.0.4 and earlier. A pre-existing bug where status messages stayed in Korean after language switch โ€” discovered during post-build QA โ€” was also fixed, and 74 duplicate translation keys identified since v1.0.2 were cleaned up as long-standing tech debt.


๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ • (๋นŒ๋“œ ํ›„ QA์—์„œ ๋ฐœ๊ฒฌ) / Bug Fixes (from post-build QA)

  • ์–ธ์–ด ์ „ํ™˜ ์‹œ Text Merger ํ•˜๋‹จ ์ƒํƒœ ๋ฉ”์‹œ์ง€๊ฐ€ ํ•œ๊ตญ์–ด๋กœ ๋‚จ๋˜ ๋ฌธ์ œ / Text Merger status messages stayed in Korean after language switch
    • ํ˜„์ƒ: ํŒŒ์ผ ์ถ”๊ฐ€ ํ›„ ์–ธ์–ด๋ฅผ ์˜์–ด/์ผ๋ณธ์–ด/์ค‘๊ตญ์–ด๋กœ ์ „ํ™˜ํ•ด๋„ 26๊ฐœ ํŒŒ์ผ ์ถ”๊ฐ€๋จ (์ธ์ฝ”๋”ฉ ์ž๋™ ๊ฐ์ง€ ์™„๋ฃŒ)๊ฐ€ ํ•œ๊ตญ์–ด๋กœ ์ž”์กด (v1.0.4 ์ด์ „๋ถ€ํ„ฐ ์กด์žฌํ•œ ๊ธฐ์กด ๋ฒ„๊ทธ)
    • Symptom: After adding files, switching language to English/Japanese/Chinese left 26๊ฐœ ํŒŒ์ผ ์ถ”๊ฐ€๋จ... in Korean (pre-existing bug since before v1.0.4)
    • ์›์ธ: retranslate()๊ฐ€ merge_status_ready ์ƒํƒœ์ผ ๋•Œ๋งŒ _lbl_status๋ฅผ ๊ฐฑ์‹  โ†’ ํŒŒ์ผ ์ถ”๊ฐ€/์‚ญ์ œ/์ €์žฅ ํ›„ ๋ฉ”์‹œ์ง€์—์„œ ๋ฌด๋ฐ˜์‘
    • Root cause: retranslate() only refreshed _lbl_status when it held the merge_status_ready text โ†’ messages after add/del/save never updated
    • ๋ฒ”์œ„: 9์ข… ์ƒํƒœ ๋ฉ”์‹œ์ง€ ์ „๋ถ€ (ready, add, del, clr, reading, save_done, save_err, path_set, path_reset_done) ๋™์ผ ๊ตฌ์กฐ ๋ฒ„๊ทธ
    • Scope: All 9 status messages (ready, add, del, clr, reading, save_done, save_err, path_set, path_reset_done) shared the same defect
    • ์ˆ˜์ •: _retranslate_status() ํ—ฌํผ + _match_status_template() ์ •๊ทœ์‹ ๋งค์นญ ์œ ํ‹ธ ์‹ ์„ค
    • Fix: Added _retranslate_status() helper and _match_status_template() regex-based matching utility
    • ์ •์  ๋ฉ”์‹œ์ง€ 5์ข…(ready/clr/reading/save_err/path_reset_done): ๋‹จ์ˆœ ๋งคํ•‘ ํ›„ ํ˜„์žฌ ์–ธ์–ด๋กœ ์žฌ๋ Œ๋”
    • Static messages (5): simple lookup and re-render in current language
    • ๋ณต์› ๊ฐ€๋Šฅ ๋™์  ๋ฉ”์‹œ์ง€ 2์ข…: ์›๋ณธ ์ •๋ณด๋กœ ์žฌ๊ตฌ์„ฑ โ€” merge_status_add โ†’ len(self.file_list) / merge_path_set โ†’ self.save_dir
    • Recoverable dynamic messages (2): reconstructed from live state โ€” merge_status_add โ†’ file count / merge_path_set โ†’ current save dir
    • ๋ณต์› ๋ถˆ๊ฐ€ ๋ฉ”์‹œ์ง€ 3์ข…(del/save_done/bulk_scanning): ready๋กœ ๋ฆฌ์…‹ + _glog ๋””๋ฒ„๊ทธ ๋กœ๊ทธ๋กœ ์ถ”์ ์„ฑ ํ™•๋ณด
    • Non-recoverable messages (3): reset to ready with _glog debug trace for traceability
    • ์‹ ์šฉ์šฐ๋‹˜์˜ ์‹ค๊ธฐ QA ์ค‘ 3๊ฐœ ์–ธ์–ด(์˜ยท์ผยท์ค‘๊ฐ„) ์Šคํฌ๋ฆฐ์ƒท์œผ๋กœ ํฌ์ฐฉ๋จ โญ
    • Discovered by developer's multilingual QA screenshots (EN / JA / zh_CN) โญ

โœจ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ / New Features

  • ๋“œ๋กญ๋‹ค์šด 8๊ฐœ ์•„์ดํ…œ์— ์—ฐ๊ด€ ์–ธ์–ด ๋ณ‘๊ธฐ / Language hints added to all 8 dropdown items

    • ํ•œ๊ตญ์–ด UI ์˜ˆ: Shift-JIS (์ผ๋ณธ์–ด), EUC-KR (ํ•œ๊ตญ์–ด), CP949 (ํ•œ๊ตญ์–ด Windows), GBK (์ค‘๊ตญ์–ด ๊ฐ„์ฒด), Big5 (์ค‘๊ตญ์–ด ๋ฒˆ์ฒด)
    • Korean UI example: Shift-JIS (์ผ๋ณธ์–ด), EUC-KR (ํ•œ๊ตญ์–ด), CP949 (ํ•œ๊ตญ์–ด Windows), GBK (์ค‘๊ตญ์–ด ๊ฐ„์ฒด), Big5 (์ค‘๊ตญ์–ด ๋ฒˆ์ฒด)
    • 5๊ฐœ ์–ธ์–ด ๋ชจ๋‘ ์ ์šฉ โ€” ์ค‘๊ตญ์–ด ๊ฐ„์ฒด/๋ฒˆ์ฒด UI์—์„œ๋Š” ์ผ๋ณธ์–ด ํ‘œ๊ธฐ๋ฅผ ๆ—ฅๆ–‡์œผ๋กœ ํ†ต์ผ (v1.0.4 tip ๋ฌธ๊ตฌ์™€ ์ผ๊ด€์„ฑ)
    • Applied to all 5 languages โ€” Chinese UIs (simplified/traditional) use ๆ—ฅๆ–‡ for "Japanese" to match v1.0.4 tip wording
    • UTF-8 / UTF-8-BOM / UTF-16์€ ์ˆ˜์‹์–ด ์—†์ด ์œ ์ง€ โ€” ํŠน์ • ์–ธ์–ด์— ์ข…์†๋˜์ง€ ์•Š์Œ
    • UTF-8 / UTF-8-BOM / UTF-16 remain unlabeled โ€” not tied to any specific language
    • ์ฃผ๊ด€ ํ‘œํ˜„((์ถ”์ฒœ), (์ „์šฉ) ๋“ฑ) ๋ฐฐ์ œ, ์‚ฌ์‹ค ๊ธฐ๋ฐ˜ ์ˆ˜์‹์–ด๋งŒ ์‚ฌ์šฉ (์ •์ง์„ฑ ์›์น™)
    • No subjective qualifiers (e.g. "(recommended)", "(only)") โ€” neutral, fact-based hints only (honesty principle)
  • ์ฝค๋ณด๋ฐ•์Šค ์•„๋ž˜ ํ•œ ์ค„ ๋„์›€๋ง ๋ผ๋ฒจ ์ถ”๊ฐ€ / One-line helper added beneath the combobox

    • ์‹ ๊ทœ ๋ฒˆ์—ญ ํ‚ค merge_enc_hint: "ํ™•์‹คํ•˜์ง€ ์•Š์œผ๋ฉด UTF-8์„ ์„ ํƒํ•˜์„ธ์š”" ์™ธ 5๊ฐœ ์–ธ์–ด
    • New translation key merge_enc_hint: "If unsure, select UTF-8" (across 5 languages)
    • MUTED ์ƒ‰์ƒ + font-size:11px๋กœ ๊ธฐ์กด ๋„์›€๋ง ํ†ค๊ณผ ํ†ต์ผ
    • Styled with MUTED color + font-size:11px to match existing helper-text tone
    • ๋น„ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ 5์ดˆ ์•ˆ์— UTF-8์ด ์•ˆ์ „ํ•œ ๊ธฐ๋ณธ๊ฐ’์ž„์„ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„
    • Designed so non-programmers can recognize UTF-8 as the safe default within 5 seconds

๐Ÿ”ง ๋ฆฌํŒฉํ† ๋ง / Refactoring

  • ํ‘œ์‹œ ๋ผ๋ฒจ๊ณผ ๋‚ด๋ถ€ ํ‚ค ๋ถ„๋ฆฌ / Separated display labels from internal keys

    • ์‹ ๊ทœ ํด๋ž˜์Šค ์ƒ์ˆ˜ TextMergerPanel._ENC_ITEMS โ€” [(internal_key, i18n_key), ...] 8-tuple ๋ฆฌ์ŠคํŠธ
    • Added class constant TextMergerPanel._ENC_ITEMS โ€” a list of (internal_key, i18n_key) 8-tuples
    • addItems([...]) โ†’ addItem(display, userData) ํŒจํ„ด์œผ๋กœ ์ „ํ™˜ (userData์— stable ํ‚ค ๋ณด์กด)
    • Switched from addItems([...]) to addItem(display, userData) pattern (keys stored in userData)
    • currentText() โ†’ currentData(), findText() โ†’ findData() ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜
    • Migrated currentText() โ†’ currentData() and findText() โ†’ findData()
    • apply_config()์— ๊ตฌ๋ฒ„์ „ ํด๋ฐฑ ๋‚ด์žฅ: findData() ์‹คํŒจ ์‹œ findText() ์žฌ์‹œ๋„ โ†’ v1.0.4 ์ดํ•˜ ์„ค์ • ํŒŒ์ผ ์ž๋™ ํ˜ธํ™˜
    • Legacy fallback in apply_config(): if findData() misses, retry with findText() โ†’ seamless v1.0.4-and-older config compatibility
    • retranslate()์— ์ฝค๋ณด๋ฐ•์Šค 8๊ฐœ ์•„์ดํ…œ ๋ผ๋ฒจ ๊ฐฑ์‹  ๋ฃจํ”„ + ๋„์›€๋ง ๋ผ๋ฒจ ๊ฐฑ์‹  ์ถ”๊ฐ€
    • retranslate() now iterates all 8 items updating display labels + refreshes the helper label
  • ๋ฒˆ์—ญ ์‚ฌ์ „ ์ค‘๋ณต ํ‚ค 74๊ฐœ ์ผ๊ด„ ์ •๋ฆฌ / Cleaned up 74 duplicate translation keys

    • v1.0.2 ์ธ์ˆ˜์ธ๊ณ„์—์„œ ์‹๋ณ„๋๋˜ zh_cn 188๊ฐœ ํ‚ค ์ค‘๋ณต ์ด์Šˆ์˜ ์‹ค์ธก ํ˜„ํ™ฉ ์žฌ์กฐ์‚ฌ โ†’ 74๊ฐœ ์ค‘๋ณต ๋ผ์ธ ์ž”์กด ํ™•์ธ
    • Re-audited the "188 duplicate zh_cn keys" issue identified since v1.0.2 โ†’ 74 duplicate lines actually remaining
    • ๋ถ„ํฌ: zh_cn 69๊ฐœ + ko/en/zh_tw ๊ฐ 1๊ฐœ + ja 2๊ฐœ = 74๊ฐœ
    • Distribution: zh_cn 69 + ko/en/zh_tw 1 each + ja 2 = 74
    • AST ํŒŒ์‹ฑ์œผ๋กœ ๊ฐ ์ค‘๋ณต ๊ทธ๋ฃน์˜ ๋‘ ๊ฐ’์ด ์™„์ „ํžˆ ์ผ์น˜ํ•จ์„ ๊ฒ€์ฆํ•œ ๋’ค ์•ˆ์ „ ์‚ญ์ œ โ†’ ๋™์ž‘ ์˜ํ–ฅ 0
    • AST-verified that each duplicate pair held identical values before deletion โ†’ zero runtime impact
    • ์ฃผ์š” ํŒจํ„ด: merge_open_explorer๊ฐ€ 5๊ฐœ ์–ธ์–ด ๋ชจ๋‘์—์„œ ์ค‘๋ณต (dict ์žฌ์‚ฝ์ž… ํ”์ ) / bulk_*ยทtf_* ์ ‘๋‘์‚ฌ ํ‚ค๊ฐ€ zh_cn์— ๋Œ€๋Ÿ‰ ์ค‘๋ณต (Bulk FixerยทText Fixer ํ™•์žฅ ์‹œ์ ์˜ ์˜๋„์น˜ ์•Š์€ ์ค‘๋ณต)
    • Main patterns: merge_open_explorer duplicated in all 5 languages (dict-reinsertion artifact) / bulk_* and tf_* prefix keys heavily duplicated in zh_cn (unintended duplication during Bulk Fixer / Text Fixer expansion)
    • ๊ฒฐ๊ณผ: 5๊ฐœ ์–ธ์–ด ๊ฐ dict 390~391 ํ‚ค๋กœ ์Šฌ๋ฆผํ™” (zh_cn 463์ค„ โ†’ 394์ค„)
    • Result: each language dict slimmed to 390~391 keys (zh_cn 463 lines โ†’ 394 lines)

๐Ÿงช ํ…Œ์ŠคํŠธ ์ž๋™ํ™” / Test Automation

  • ์‹ ๊ทœ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ 30๊ฐœ ์ถ”๊ฐ€ / Added 30 new regression tests
    • TestV105Regression: ์†Œ์Šค ๊ฒ€์ฆ 12๊ฐœ (_ENC_ITEMS ์ƒ์ˆ˜, addItem ํŒจํ„ด, ๋„์›€๋ง ๋ผ๋ฒจ, currentData/findData ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜, 45๊ฐœ ๋ฒˆ์—ญ ํ•ญ๋ชฉ, ๆ—ฅๆ–‡ ํ‘œ๊ธฐ ์ผ๊ด€์„ฑ ๋“ฑ)
    • TestV105Regression: 12 source-level checks (_ENC_ITEMS constant, addItem pattern, helper label, currentData/findData migration, 45 translation entries, ๆ—ฅๆ–‡ consistency, etc.)
    • TestV105RegressionModule: ๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ 6๊ฐœ (APP_VERSION, 5๊ฐœ ์–ธ์–ด ์‚ฌ์ „ ์™„๊ฒฐ์„ฑ, ๋ผ๋ฒจ-ํ‚ค ๋งคํ•‘, _ENC_ITEMS ์ˆœ์„œ, ๋„์›€๋ง UTF-8 ์•ˆ๋‚ด ๋“ฑ)
    • TestV105RegressionModule: 6 runtime checks (APP_VERSION, 5-language dict completeness, label-key mapping, _ENC_ITEMS order, UTF-8 guidance in helper, etc.)
    • TestV105TranslationNoDuplicates: ์ค‘๋ณต ์žฌ๋ฐœ ๋ฐฉ์ง€ 2๊ฐœ (AST ๊ธฐ๋ฐ˜ ์ค‘๋ณต 0 ๊ฒ€์ฆ + ์–ธ์–ด๋ณ„ ํ‚ค ๊ฐœ์ˆ˜ ํŽธ์ฐจ โ‰ค5)
    • TestV105TranslationNoDuplicates: 2 no-duplicate-regression tests (AST-based zero duplicates + per-language key-count variance โ‰ค 5)
    • TestV105StatusRetranslate: ์ƒํƒœ ๋ฉ”์‹œ์ง€ ์žฌ๋ฒˆ์—ญ 10๊ฐœ (์ •์ /๋ณต์›๊ฐ€๋Šฅ/๋ณต์›๋ถˆ๊ฐ€/๋ฐฉ์–ด์  ์ฒ˜๋ฆฌ/๋‹จ์œ„ ํ…Œ์ŠคํŠธ)
    • TestV105StatusRetranslate: 10 status-retranslation tests (static / recoverable / non-recoverable / defensive / unit)
  • v1.0.4 ํ…Œ์ŠคํŠธ 2๊ฐœ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ๋ณ€๊ฒฝ์— ๋งž์ถฐ ์—…๋ฐ์ดํŠธ (์˜๋„ ์œ ์ง€) / Updated 2 v1.0.4 tests for the new signature (intent preserved)
    • test_text_merger_combo_has_cjk_encodings: addItems ์ •๊ทœ์‹ โ†’ _ENC_ITEMS ์ƒ์ˆ˜ ๋ธ”๋ก ๊ฒ€์ƒ‰
    • test_text_merger_combo_has_cjk_encodings: addItems regex โ†’ _ENC_ITEMS constant block lookup
    • test_app_version_is_104 โ†’ test_app_version_is_104_or_later: ์ •ํ™• ์ผ์น˜ โ†’ ํŠœํ”Œ ๋น„๊ต(โ‰ฅ (1,0,4))๋กœ ์™„ํ™”
    • test_app_version_is_104 โ†’ test_app_version_is_104_or_later: strict equality โ†’ tuple comparison (โ‰ฅ (1,0,4))

๐Ÿ“Š ๊ฒ€์ฆ ๋ฒ”์œ„ / Verification Scope

  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ / Unit tests: 502 passing (v1.0.4: 472 + v1.0.5: 30) โ€” ์‹คํŒจ 0 / ์˜ค๋ฅ˜ 0 / ์Šคํ‚ต 0 โญ
    • 502 passing / 0 failed / 0 errors / 0 skipped โญ
  • ์‹ค๊ธฐ ๊ฒ€์ฆ / Manual testing:
    • ๋“œ๋กญ๋‹ค์šด ๋ผ๋ฒจ + ๋„์›€๋ง ๋ฌธ๊ตฌ๋ฅผ 5๊ฐœ ์–ธ์–ด ๋ชจ๋“œ์—์„œ ๊ฐ๊ฐ ์Šคํฌ๋ฆฐ์ƒท ๊ฒ€์ฆ / Dropdown labels + helper text verified via screenshots across all 5 language modes
    • ๋นŒ๋“œ ํ›„ ์–ธ์–ด ์ „ํ™˜ ์‹œ ์ƒํƒœ ๋ฉ”์‹œ์ง€ ์žฌ๋ฒˆ์—ญ ํšŒ๊ท€ ๊ฒ€์ฆ (ํŒŒ์ผ ์ถ”๊ฐ€ โ†’ ์˜์–ด ์ „ํ™˜ โ†’ Ready ๋ฆฌ์…‹ + Debug Log์— merge_status_del โ†’ merge_status_ready ๋กœ๊ทธ ํ™•์ธ) / Post-build verification of status message re-translation (add files โ†’ switch to EN โ†’ Ready reset + debug log line confirmed)
    • v1.0.4 ์„ค์ • ํŒŒ์ผ(combo_enc: "Shift-JIS")๋กœ ๊ธฐ๋™ํ•˜์—ฌ findText() ํด๋ฐฑ ์ •์ƒ ๋™์ž‘ ํ™•์ธ / Launched with a v1.0.4 config file (combo_enc: "Shift-JIS") to confirm the findText() fallback works correctly
  • ๊ตฌ์กฐ์  ์•ˆ์ „์„ฑ / Structural safety:
    • addItem(display, userData) ์ „ํ™˜์œผ๋กœ ๋‚ด๋ถ€ ํ‚ค์™€ ํ‘œ์‹œ ๋ผ๋ฒจ ์™„์ „ ๋ถ„๋ฆฌ / Clean separation of internal keys from display labels via addItem(display, userData)
    • currentData() ๊ธฐ๋ฐ˜ ์ €์žฅ โ†’ ๊ธฐ์กด ์„ค์ • ์ €์žฅ ์Šคํ‚ค๋งˆ ํ‚ค(combo_enc) ์ด๋ฆ„ ์œ ์ง€ / currentData()-based save preserves the existing combo_enc config schema key
    • ๋ฒˆ์—ญ ์‚ฌ์ „ ์ค‘๋ณต ์ œ๊ฑฐ๋Š” AST ๊ฐ’ ๋™์ผ์„ฑ ๊ฒ€์ฆ ํ›„์—๋งŒ ์‹คํ–‰ โ†’ ๋™์ž‘ ๋ณ€ํ™” 0 / Duplicate key removal gated on AST-level value-equality check โ†’ zero behavioral change
    • TextMergerPanel ์™ธ ๋‹ค๋ฅธ ํƒญ(Text Converter / Tag Editor / Batch Renamer / Text Fixer / Bulk Fixer) ์˜ํ–ฅ 0 / No impact on other tabs (Text Converter / Tag Editor / Batch Renamer / Text Fixer / Bulk Fixer)

๐Ÿ” ๋ฆด๋ฆฌ์ฆˆ ์„œ๋ช… / Release Signing

  • v1.0.5๋ถ€ํ„ฐ SSH ์„œ๋ช… ๋„์ž… / SSH signing introduced from v1.0.5
    • ์ปค๋ฐ‹ + ํƒœ๊ทธ ๋ชจ๋‘ Ed25519 SSH ํ‚ค๋กœ ์„œ๋ช… โ†’ GitHub Verified ๋ฑƒ์ง€ ํš๋“ / Both commit and tag signed with Ed25519 SSH key โ†’ GitHub Verified badge
    • v1.0.1 ์ดํ›„ Verified ๋ฑƒ์ง€ ๋ณต๊ท€ (v1.0.2~v1.0.4๋Š” ๋น„์„œ๋ช…) / Verified badge returns since v1.0.1 (v1.0.2โ€“v1.0.4 were unsigned)
    • Fingerprint: SHA256:4H2f7lrFfI4u0YP0dpp6N9BQH2f74iKjjMRHu7lyjKI

๐Ÿ’ฌ ๊ฒ€ํ†  / Review

  • Claude Opus 4.7 ๊ธฐ๋ฐ˜ ์ •์  ๋ถ„์„ ...
Read more