supervertaler 1.9.146__py3-none-any.whl → 1.9.147__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Supervertaler.py +157 -9
- {supervertaler-1.9.146.dist-info → supervertaler-1.9.147.dist-info}/METADATA +17 -3
- {supervertaler-1.9.146.dist-info → supervertaler-1.9.147.dist-info}/RECORD +7 -7
- {supervertaler-1.9.146.dist-info → supervertaler-1.9.147.dist-info}/WHEEL +0 -0
- {supervertaler-1.9.146.dist-info → supervertaler-1.9.147.dist-info}/entry_points.txt +0 -0
- {supervertaler-1.9.146.dist-info → supervertaler-1.9.147.dist-info}/licenses/LICENSE +0 -0
- {supervertaler-1.9.146.dist-info → supervertaler-1.9.147.dist-info}/top_level.txt +0 -0
Supervertaler.py
CHANGED
|
@@ -34,7 +34,7 @@ License: MIT
|
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
36
|
# Version Information.
|
|
37
|
-
__version__ = "1.9.
|
|
37
|
+
__version__ = "1.9.147"
|
|
38
38
|
__phase__ = "0.9"
|
|
39
39
|
__release_date__ = "2026-01-20"
|
|
40
40
|
__edition__ = "Qt"
|
|
@@ -65,18 +65,158 @@ def get_user_data_path() -> Path:
|
|
|
65
65
|
"""
|
|
66
66
|
Get the path to user data directory.
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
This function returns a PERSISTENT location for user data that survives
|
|
69
|
+
pip upgrades and reinstalls. The location varies by context:
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
1. FROZEN BUILDS (Windows EXE): 'user_data' folder next to the EXE
|
|
72
|
+
- This allows the EXE to be portable (copy folder = copy everything)
|
|
73
|
+
- Path: C:/SomeFolder/Supervertaler/user_data/
|
|
74
|
+
|
|
75
|
+
2. PIP INSTALLS: Platform-specific user data directory
|
|
76
|
+
- Windows: %LOCALAPPDATA%/Supervertaler/ (e.g., C:/Users/John/AppData/Local/Supervertaler/)
|
|
77
|
+
- macOS: ~/Library/Application Support/Supervertaler/
|
|
78
|
+
- Linux: ~/.local/share/Supervertaler/ (XDG_DATA_HOME)
|
|
79
|
+
- This location persists across pip upgrades!
|
|
80
|
+
|
|
81
|
+
3. DEVELOPMENT MODE: 'user_data' or 'user_data_private' next to script
|
|
82
|
+
- Developers can use ENABLE_PRIVATE_FEATURES to use user_data_private/
|
|
83
|
+
|
|
84
|
+
The key insight: pip installs wipe site-packages on upgrade, so we MUST
|
|
85
|
+
store user data outside the package directory for pip users.
|
|
72
86
|
"""
|
|
73
87
|
if getattr(sys, 'frozen', False):
|
|
74
|
-
#
|
|
88
|
+
# =====================================================================
|
|
89
|
+
# FROZEN BUILD (EXE): Keep data next to executable for portability
|
|
90
|
+
# =====================================================================
|
|
91
|
+
# Users can copy the entire folder to a USB drive and it works.
|
|
92
|
+
# The build script copies user_data/ next to Supervertaler.exe
|
|
75
93
|
return Path(sys.executable).parent / "user_data"
|
|
94
|
+
|
|
95
|
+
# Check if we're running from site-packages (pip install)
|
|
96
|
+
script_path = Path(__file__).resolve()
|
|
97
|
+
is_pip_install = "site-packages" in str(script_path)
|
|
98
|
+
|
|
99
|
+
if is_pip_install:
|
|
100
|
+
# =================================================================
|
|
101
|
+
# PIP INSTALL: Use platform-specific persistent location
|
|
102
|
+
# =================================================================
|
|
103
|
+
# This survives pip upgrades because it's OUTSIDE site-packages!
|
|
104
|
+
try:
|
|
105
|
+
from platformdirs import user_data_dir
|
|
106
|
+
return Path(user_data_dir("Supervertaler", "MichaelBeijer"))
|
|
107
|
+
except ImportError:
|
|
108
|
+
# Fallback if platformdirs not available (shouldn't happen)
|
|
109
|
+
if sys.platform == 'win32':
|
|
110
|
+
base = Path(os.environ.get('LOCALAPPDATA', os.path.expanduser('~')))
|
|
111
|
+
return base / "Supervertaler"
|
|
112
|
+
elif sys.platform == 'darwin':
|
|
113
|
+
return Path.home() / "Library" / "Application Support" / "Supervertaler"
|
|
114
|
+
else:
|
|
115
|
+
# Linux/BSD - follow XDG spec
|
|
116
|
+
xdg_data = os.environ.get('XDG_DATA_HOME', os.path.expanduser('~/.local/share'))
|
|
117
|
+
return Path(xdg_data) / "Supervertaler"
|
|
76
118
|
else:
|
|
77
|
-
#
|
|
119
|
+
# =================================================================
|
|
120
|
+
# DEVELOPMENT MODE: Use folder next to script
|
|
121
|
+
# =================================================================
|
|
78
122
|
return Path(__file__).parent / "user_data"
|
|
79
123
|
|
|
124
|
+
|
|
125
|
+
def migrate_user_data_if_needed(new_path: Path) -> bool:
|
|
126
|
+
"""
|
|
127
|
+
Migrate user data from old location (inside site-packages) to new location.
|
|
128
|
+
|
|
129
|
+
This handles the transition for existing pip users whose data was stored
|
|
130
|
+
inside the package directory (which gets wiped on upgrade).
|
|
131
|
+
|
|
132
|
+
Returns True if migration was performed, False otherwise.
|
|
133
|
+
"""
|
|
134
|
+
import shutil
|
|
135
|
+
|
|
136
|
+
# Only migrate for pip installs (frozen builds keep data next to EXE)
|
|
137
|
+
if getattr(sys, 'frozen', False):
|
|
138
|
+
return False
|
|
139
|
+
|
|
140
|
+
# Check if we're in a pip install
|
|
141
|
+
script_path = Path(__file__).resolve()
|
|
142
|
+
if "site-packages" not in str(script_path):
|
|
143
|
+
return False # Development mode, no migration needed
|
|
144
|
+
|
|
145
|
+
# Old location: user_data folder inside the package in site-packages
|
|
146
|
+
old_path = script_path.parent / "user_data"
|
|
147
|
+
|
|
148
|
+
# If old location doesn't exist or is empty, no migration needed
|
|
149
|
+
if not old_path.exists():
|
|
150
|
+
return False
|
|
151
|
+
|
|
152
|
+
# Check if old location has actual content (not just empty dirs)
|
|
153
|
+
old_has_content = False
|
|
154
|
+
for item in old_path.rglob('*'):
|
|
155
|
+
if item.is_file():
|
|
156
|
+
old_has_content = True
|
|
157
|
+
break
|
|
158
|
+
|
|
159
|
+
if not old_has_content:
|
|
160
|
+
return False
|
|
161
|
+
|
|
162
|
+
# If new location already has content, don't overwrite (user may have set up fresh)
|
|
163
|
+
new_has_content = False
|
|
164
|
+
if new_path.exists():
|
|
165
|
+
for item in new_path.rglob('*'):
|
|
166
|
+
if item.is_file():
|
|
167
|
+
new_has_content = True
|
|
168
|
+
break
|
|
169
|
+
|
|
170
|
+
if new_has_content:
|
|
171
|
+
# Both have content - log but don't migrate (user may have set up manually)
|
|
172
|
+
print(f"[Migration] Both old and new data locations have content:")
|
|
173
|
+
print(f" Old: {old_path}")
|
|
174
|
+
print(f" New: {new_path}")
|
|
175
|
+
print(f"[Migration] Keeping new location. Old data preserved in site-packages.")
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
# Perform migration
|
|
179
|
+
print(f"[Migration] Migrating user data from old location...")
|
|
180
|
+
print(f" From: {old_path}")
|
|
181
|
+
print(f" To: {new_path}")
|
|
182
|
+
|
|
183
|
+
try:
|
|
184
|
+
# Ensure new path parent exists
|
|
185
|
+
new_path.parent.mkdir(parents=True, exist_ok=True)
|
|
186
|
+
|
|
187
|
+
# Copy entire directory tree (use copy, not move, for safety)
|
|
188
|
+
if new_path.exists():
|
|
189
|
+
# Merge into existing empty directory
|
|
190
|
+
for item in old_path.iterdir():
|
|
191
|
+
dest = new_path / item.name
|
|
192
|
+
if item.is_dir():
|
|
193
|
+
shutil.copytree(item, dest, dirs_exist_ok=True)
|
|
194
|
+
else:
|
|
195
|
+
shutil.copy2(item, dest)
|
|
196
|
+
else:
|
|
197
|
+
shutil.copytree(old_path, new_path)
|
|
198
|
+
|
|
199
|
+
print(f"[Migration] ✅ Successfully migrated user data!")
|
|
200
|
+
print(f"[Migration] Your API keys, TMs, glossaries, and prompts are now in:")
|
|
201
|
+
print(f" {new_path}")
|
|
202
|
+
|
|
203
|
+
# Leave a marker file in the old location so users know what happened
|
|
204
|
+
marker = old_path / "_MIGRATED_TO_NEW_LOCATION.txt"
|
|
205
|
+
marker.write_text(
|
|
206
|
+
f"Your Supervertaler data has been migrated to a persistent location:\n"
|
|
207
|
+
f"{new_path}\n\n"
|
|
208
|
+
f"This location survives pip upgrades.\n"
|
|
209
|
+
f"You can safely delete this old folder.\n"
|
|
210
|
+
f"Migration date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
return True
|
|
214
|
+
|
|
215
|
+
except Exception as e:
|
|
216
|
+
print(f"[Migration] ⚠️ Error during migration: {e}")
|
|
217
|
+
print(f"[Migration] Your data is still in: {old_path}")
|
|
218
|
+
return False
|
|
219
|
+
|
|
80
220
|
import threading
|
|
81
221
|
import time # For delays in Superlookup
|
|
82
222
|
import re
|
|
@@ -5167,17 +5307,25 @@ class SupervertalerQt(QMainWindow):
|
|
|
5167
5307
|
# ============================================================================
|
|
5168
5308
|
# USER DATA PATH INITIALIZATION
|
|
5169
5309
|
# ============================================================================
|
|
5170
|
-
#
|
|
5171
|
-
#
|
|
5310
|
+
# User data is stored in a PERSISTENT location that survives pip upgrades:
|
|
5311
|
+
# - Windows: %LOCALAPPDATA%\Supervertaler\
|
|
5312
|
+
# - macOS: ~/Library/Application Support/Supervertaler/
|
|
5313
|
+
# - Linux: ~/.local/share/Supervertaler/
|
|
5314
|
+
# - EXE: user_data/ folder next to executable (portable mode)
|
|
5315
|
+
# - Dev: user_data_private/ or user_data/ next to script
|
|
5172
5316
|
from modules.database_manager import DatabaseManager
|
|
5173
5317
|
|
|
5174
5318
|
if ENABLE_PRIVATE_FEATURES:
|
|
5175
5319
|
# Developer mode: use private folder (git-ignored)
|
|
5176
5320
|
self.user_data_path = Path(__file__).parent / "user_data_private"
|
|
5177
5321
|
else:
|
|
5178
|
-
# Normal mode: use the helper function
|
|
5322
|
+
# Normal mode: use the helper function (handles pip vs EXE vs dev)
|
|
5179
5323
|
self.user_data_path = get_user_data_path()
|
|
5180
5324
|
|
|
5325
|
+
# Migrate old data from site-packages to new persistent location (pip users)
|
|
5326
|
+
# This is a one-time migration for users upgrading from older versions
|
|
5327
|
+
migrate_user_data_if_needed(self.user_data_path)
|
|
5328
|
+
|
|
5181
5329
|
# Ensure user_data directory exists (creates empty folder if missing)
|
|
5182
5330
|
self.user_data_path.mkdir(parents=True, exist_ok=True)
|
|
5183
5331
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: supervertaler
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.147
|
|
4
4
|
Summary: Professional AI-powered translation workbench with multi-LLM support, glossary system, TM, spellcheck, voice commands, and PyQt6 interface. Batteries included (core).
|
|
5
5
|
Home-page: https://supervertaler.com
|
|
6
6
|
Author: Michael Beijer
|
|
@@ -46,6 +46,7 @@ Requires-Dist: chardet>=5.0.0
|
|
|
46
46
|
Requires-Dist: pyyaml>=6.0.0
|
|
47
47
|
Requires-Dist: markdown>=3.4.0
|
|
48
48
|
Requires-Dist: pyspellchecker>=0.7.0
|
|
49
|
+
Requires-Dist: platformdirs>=4.0.0
|
|
49
50
|
Requires-Dist: sounddevice>=0.4.6
|
|
50
51
|
Requires-Dist: numpy>=1.24.0
|
|
51
52
|
Requires-Dist: PyMuPDF>=1.23.0
|
|
@@ -71,7 +72,7 @@ Dynamic: home-page
|
|
|
71
72
|
Dynamic: license-file
|
|
72
73
|
Dynamic: requires-python
|
|
73
74
|
|
|
74
|
-
# 🚀 Supervertaler v1.9.
|
|
75
|
+
# 🚀 Supervertaler v1.9.147
|
|
75
76
|
|
|
76
77
|
[](https://pypi.org/project/Supervertaler/)
|
|
77
78
|
[](https://www.python.org/downloads/)
|
|
@@ -79,7 +80,20 @@ Dynamic: requires-python
|
|
|
79
80
|
|
|
80
81
|
AI-enhanced CAT tool with multi-LLM support (GPT-4, Claude, Gemini, Ollama), innovative Superlookup concordance system offering access to multiple terminology sources (TMs, glossaries, web resources, etc.), and seamless CAT tool integration (memoQ, Trados, CafeTran, Phrase).
|
|
81
82
|
|
|
82
|
-
**Current Version:** v1.9.
|
|
83
|
+
**Current Version:** v1.9.147 (January 21, 2026)
|
|
84
|
+
|
|
85
|
+
### NEW in v1.9.147 - 📁 Persistent User Data Location
|
|
86
|
+
|
|
87
|
+
**No More Data Loss on Upgrade!** User data (API keys, TMs, glossaries, prompts, settings) is now stored in a persistent location that survives `pip install --upgrade`:
|
|
88
|
+
|
|
89
|
+
| Platform | User Data Location |
|
|
90
|
+
|----------|-------------------|
|
|
91
|
+
| **Windows** | `%LOCALAPPDATA%\MichaelBeijer\Supervertaler\` |
|
|
92
|
+
| **macOS** | `~/Library/Application Support/Supervertaler/` |
|
|
93
|
+
| **Linux** | `~/.local/share/Supervertaler/` |
|
|
94
|
+
| **Windows EXE** | `user_data\` next to executable (portable) |
|
|
95
|
+
|
|
96
|
+
Existing data is automatically migrated on first run after upgrade.
|
|
83
97
|
|
|
84
98
|
### FIXED in v1.9.146 - 🔑 Gemini/Google API Key Alias
|
|
85
99
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Supervertaler.py,sha256=
|
|
1
|
+
Supervertaler.py,sha256=0Vkn41czCn0bkCEQ-Vpd1Ee3ifsLUjeJT5QY3wYPNkg,2159745
|
|
2
2
|
modules/__init__.py,sha256=G58XleS-EJ2sX4Kehm-3N2m618_W2Es0Kg8CW_eBG7g,327
|
|
3
3
|
modules/ai_actions.py,sha256=i5MJcM-7Y6CAvKUwxmxrVHeoZAVtAP7aRDdWM5KLkO0,33877
|
|
4
4
|
modules/ai_attachment_manager.py,sha256=mA5ISI22qN9mH3DQFF4gOTciDyBt5xVR7sHTkgkTIlw,11361
|
|
@@ -77,9 +77,9 @@ modules/unified_prompt_manager_qt.py,sha256=kpR-Tk1xmVyJGHnZdHm6NbGQPTZ1jB8t4tI_
|
|
|
77
77
|
modules/voice_commands.py,sha256=iBb-gjWxRMLhFH7-InSRjYJz1EIDBNA2Pog8V7TtJaY,38516
|
|
78
78
|
modules/voice_dictation.py,sha256=QmitXfkG-vRt5hIQATjphHdhXfqmwhzcQcbXB6aRzIg,16386
|
|
79
79
|
modules/voice_dictation_lite.py,sha256=jorY0BmWE-8VczbtGrWwt1zbnOctMoSlWOsQrcufBcc,9423
|
|
80
|
-
supervertaler-1.9.
|
|
81
|
-
supervertaler-1.9.
|
|
82
|
-
supervertaler-1.9.
|
|
83
|
-
supervertaler-1.9.
|
|
84
|
-
supervertaler-1.9.
|
|
85
|
-
supervertaler-1.9.
|
|
80
|
+
supervertaler-1.9.147.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
|
|
81
|
+
supervertaler-1.9.147.dist-info/METADATA,sha256=cqvLJ6GY6wgzZOqBQynIOMb7CiCaS46UQJbaI0qorSY,44450
|
|
82
|
+
supervertaler-1.9.147.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
83
|
+
supervertaler-1.9.147.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
|
|
84
|
+
supervertaler-1.9.147.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
|
|
85
|
+
supervertaler-1.9.147.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|