TonieToolbox 0.1.5__py3-none-any.whl → 0.1.7__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.
- TonieToolbox/__init__.py +1 -1
- TonieToolbox/__main__.py +26 -4
- TonieToolbox/dependency_manager.py +55 -17
- TonieToolbox/version_handler.py +156 -25
- {tonietoolbox-0.1.5.dist-info → tonietoolbox-0.1.7.dist-info}/METADATA +1 -1
- {tonietoolbox-0.1.5.dist-info → tonietoolbox-0.1.7.dist-info}/RECORD +10 -10
- {tonietoolbox-0.1.5.dist-info → tonietoolbox-0.1.7.dist-info}/WHEEL +0 -0
- {tonietoolbox-0.1.5.dist-info → tonietoolbox-0.1.7.dist-info}/entry_points.txt +0 -0
- {tonietoolbox-0.1.5.dist-info → tonietoolbox-0.1.7.dist-info}/licenses/LICENSE.md +0 -0
- {tonietoolbox-0.1.5.dist-info → tonietoolbox-0.1.7.dist-info}/top_level.txt +0 -0
TonieToolbox/__init__.py
CHANGED
TonieToolbox/__main__.py
CHANGED
@@ -15,7 +15,7 @@ from .tonie_analysis import check_tonie_file, split_to_opus_files
|
|
15
15
|
from .dependency_manager import get_ffmpeg_binary, get_opus_binary
|
16
16
|
from .logger import setup_logging, get_logger
|
17
17
|
from .filename_generator import guess_output_filename
|
18
|
-
from .version_handler import check_for_updates
|
18
|
+
from .version_handler import check_for_updates, clear_version_cache
|
19
19
|
|
20
20
|
def main():
|
21
21
|
"""Entry point for the TonieToolbox application."""
|
@@ -45,8 +45,15 @@ def main():
|
|
45
45
|
help='Compare input file with another .taf file for debugging')
|
46
46
|
parser.add_argument('--detailed-compare', action='store_true',
|
47
47
|
help='Show detailed OGG page differences when comparing files')
|
48
|
-
|
48
|
+
|
49
|
+
# Version check options
|
50
|
+
version_group = parser.add_argument_group('Version Check Options')
|
51
|
+
version_group.add_argument('--skip-update-check', action='store_true',
|
49
52
|
help='Skip checking for updates')
|
53
|
+
version_group.add_argument('--force-refresh-cache', action='store_true',
|
54
|
+
help='Force refresh of update information from PyPI')
|
55
|
+
version_group.add_argument('--clear-version-cache', action='store_true',
|
56
|
+
help='Clear cached version information')
|
50
57
|
|
51
58
|
log_group = parser.add_argument_group('Logging Options')
|
52
59
|
log_level_group = log_group.add_mutually_exclusive_group()
|
@@ -70,10 +77,25 @@ def main():
|
|
70
77
|
|
71
78
|
setup_logging(log_level)
|
72
79
|
logger = get_logger('main')
|
73
|
-
logger.debug("Starting TonieToolbox with log level: %s", logging.getLevelName(log_level))
|
80
|
+
logger.debug("Starting TonieToolbox v%s with log level: %s", __version__, logging.getLevelName(log_level))
|
81
|
+
|
82
|
+
# Handle version cache operations
|
83
|
+
if args.clear_version_cache:
|
84
|
+
if clear_version_cache():
|
85
|
+
logger.info("Version cache cleared successfully")
|
86
|
+
else:
|
87
|
+
logger.info("No version cache to clear or error clearing cache")
|
74
88
|
|
89
|
+
# Check for updates
|
75
90
|
if not args.skip_update_check:
|
76
|
-
|
91
|
+
logger.debug("Checking for updates (force_refresh=%s)", args.force_refresh_cache)
|
92
|
+
is_latest, latest_version, message, update_confirmed = check_for_updates(
|
93
|
+
quiet=args.silent or args.quiet,
|
94
|
+
force_refresh=args.force_refresh_cache
|
95
|
+
)
|
96
|
+
|
97
|
+
if not is_latest and not update_confirmed and not (args.silent or args.quiet):
|
98
|
+
logger.info("Update available but user chose to continue without updating.")
|
77
99
|
|
78
100
|
ffmpeg_binary = args.ffmpeg
|
79
101
|
if ffmpeg_binary is None:
|
@@ -309,14 +309,65 @@ def ensure_dependency(dependency_name, auto_download=False):
|
|
309
309
|
logger.info("Found %s in PATH: %s", dependency_name, path_binary)
|
310
310
|
return path_binary
|
311
311
|
|
312
|
+
# Set up paths to check for previously downloaded versions
|
313
|
+
user_data_dir = get_user_data_dir()
|
314
|
+
dependency_info = DEPENDENCIES[dependency_name].get(system, {})
|
315
|
+
extract_dir_name = dependency_info.get('extract_dir', dependency_name)
|
316
|
+
binary_path = dependency_info.get('bin_path', bin_name)
|
317
|
+
extract_dir = os.path.join(user_data_dir, extract_dir_name)
|
318
|
+
|
319
|
+
# Check if we already downloaded and extracted it previously
|
320
|
+
logger.debug("Checking for previously downloaded %s in %s", dependency_name, extract_dir)
|
321
|
+
if os.path.exists(extract_dir):
|
322
|
+
existing_binary = find_binary_in_extracted_dir(extract_dir, binary_path)
|
323
|
+
if existing_binary and os.path.exists(existing_binary):
|
324
|
+
# Verify that the binary works
|
325
|
+
logger.info("Found previously downloaded %s: %s", dependency_name, existing_binary)
|
326
|
+
try:
|
327
|
+
if os.access(existing_binary, os.X_OK) or system == 'windows':
|
328
|
+
if system in ['linux', 'darwin']:
|
329
|
+
logger.debug("Ensuring executable permissions on %s", existing_binary)
|
330
|
+
os.chmod(existing_binary, 0o755)
|
331
|
+
|
332
|
+
# Quick check to verify binary works
|
333
|
+
if dependency_name == 'opusenc':
|
334
|
+
cmd = [existing_binary, '--version']
|
335
|
+
try:
|
336
|
+
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=5)
|
337
|
+
if result.returncode == 0:
|
338
|
+
logger.info("Using previously downloaded %s: %s", dependency_name, existing_binary)
|
339
|
+
return existing_binary
|
340
|
+
except:
|
341
|
+
# If --version fails, try without arguments
|
342
|
+
try:
|
343
|
+
result = subprocess.run([existing_binary], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=5)
|
344
|
+
if result.returncode == 0:
|
345
|
+
logger.info("Using previously downloaded %s: %s", dependency_name, existing_binary)
|
346
|
+
return existing_binary
|
347
|
+
except:
|
348
|
+
pass
|
349
|
+
else:
|
350
|
+
cmd = [existing_binary, '-version']
|
351
|
+
try:
|
352
|
+
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=5)
|
353
|
+
if result.returncode == 0:
|
354
|
+
logger.info("Using previously downloaded %s: %s", dependency_name, existing_binary)
|
355
|
+
return existing_binary
|
356
|
+
except:
|
357
|
+
pass
|
358
|
+
|
359
|
+
logger.warning("Previously downloaded %s exists but failed verification", dependency_name)
|
360
|
+
except Exception as e:
|
361
|
+
logger.warning("Error verifying downloaded binary: %s", e)
|
362
|
+
|
312
363
|
# If auto_download is not enabled, don't try to install or download
|
313
364
|
if not auto_download:
|
314
365
|
logger.warning("%s not found in PATH and auto-download is disabled. Use --auto-download to enable automatic installation.", dependency_name)
|
315
366
|
return None
|
316
367
|
|
317
368
|
# If not in PATH, check if we should install via package manager
|
318
|
-
if 'package' in
|
319
|
-
package_name =
|
369
|
+
if 'package' in dependency_info:
|
370
|
+
package_name = dependency_info['package']
|
320
371
|
logger.info("%s not found. Attempting to install %s package...", dependency_name, package_name)
|
321
372
|
if install_package(package_name):
|
322
373
|
path_binary = check_binary_in_path(bin_name)
|
@@ -325,27 +376,14 @@ def ensure_dependency(dependency_name, auto_download=False):
|
|
325
376
|
return path_binary
|
326
377
|
|
327
378
|
# If not installable via package manager or installation failed, try downloading
|
328
|
-
if 'url' not in
|
379
|
+
if 'url' not in dependency_info:
|
329
380
|
logger.error("Cannot download %s for %s", dependency_name, system)
|
330
381
|
return None
|
331
382
|
|
332
|
-
# Set up paths
|
333
|
-
user_data_dir = get_user_data_dir()
|
334
|
-
dependency_info = DEPENDENCIES[dependency_name][system]
|
383
|
+
# Set up download paths
|
335
384
|
download_url = dependency_info['url']
|
336
|
-
extract_dir_name = dependency_info['extract_dir']
|
337
|
-
binary_path = dependency_info['bin_path']
|
338
|
-
|
339
|
-
extract_dir = os.path.join(user_data_dir, extract_dir_name)
|
340
|
-
logger.debug("Using extract directory: %s", extract_dir)
|
341
385
|
os.makedirs(extract_dir, exist_ok=True)
|
342
386
|
|
343
|
-
# Check if we already downloaded and extracted it
|
344
|
-
existing_binary = find_binary_in_extracted_dir(extract_dir, binary_path)
|
345
|
-
if existing_binary and os.path.exists(existing_binary):
|
346
|
-
logger.info("Using existing %s: %s", dependency_name, existing_binary)
|
347
|
-
return existing_binary
|
348
|
-
|
349
387
|
# Download and extract
|
350
388
|
archive_ext = '.zip' if download_url.endswith('zip') else '.tar.xz'
|
351
389
|
archive_path = os.path.join(user_data_dir, f"{dependency_name}{archive_ext}")
|
TonieToolbox/version_handler.py
CHANGED
@@ -12,45 +12,70 @@ from urllib.error import URLError
|
|
12
12
|
from . import __version__
|
13
13
|
from .logger import get_logger
|
14
14
|
|
15
|
+
# Cache filename for version information
|
15
16
|
CACHE_DIR = os.path.join(os.path.expanduser("~"), ".tonietoolbox")
|
16
17
|
CACHE_FILE = os.path.join(CACHE_DIR, "version_cache.json")
|
17
18
|
CACHE_EXPIRY = 86400 # 24 hours in seconds
|
18
19
|
|
19
20
|
|
20
|
-
def get_pypi_version():
|
21
|
+
def get_pypi_version(force_refresh=False):
|
21
22
|
"""
|
22
23
|
Get the latest version of TonieToolbox from PyPI.
|
23
24
|
|
25
|
+
Args:
|
26
|
+
force_refresh: If True, ignore the cache and fetch directly from PyPI
|
27
|
+
|
24
28
|
Returns:
|
25
29
|
tuple: (latest_version, None) on success, (current_version, error_message) on failure
|
26
30
|
"""
|
27
31
|
logger = get_logger("version_handler")
|
32
|
+
logger.debug("Checking for latest version (force_refresh=%s)", force_refresh)
|
33
|
+
logger.debug("Current version: %s", __version__)
|
28
34
|
|
29
35
|
try:
|
30
|
-
if
|
36
|
+
# Check if we have a recent cache and should use it
|
37
|
+
if not force_refresh and os.path.exists(CACHE_FILE):
|
31
38
|
try:
|
32
39
|
with open(CACHE_FILE, "r") as f:
|
33
40
|
cache_data = json.load(f)
|
34
41
|
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
cached_version = cache_data.get("version")
|
43
|
+
cache_timestamp = cache_data.get("timestamp", 0)
|
44
|
+
cache_age = time.time() - cache_timestamp
|
45
|
+
|
46
|
+
logger.debug("Cache info: version=%s, age=%d seconds (expires after %d)",
|
47
|
+
cached_version, cache_age, CACHE_EXPIRY)
|
48
|
+
|
49
|
+
if cache_age < CACHE_EXPIRY:
|
50
|
+
logger.debug("Using cached version info: %s", cached_version)
|
51
|
+
return cached_version, None
|
52
|
+
else:
|
53
|
+
logger.debug("Cache expired (%d seconds old), refreshing from PyPI", cache_age)
|
38
54
|
except (json.JSONDecodeError, KeyError) as e:
|
39
55
|
logger.debug("Cache file corrupt, will fetch from PyPI: %s", e)
|
56
|
+
else:
|
57
|
+
if force_refresh:
|
58
|
+
logger.debug("Forced refresh requested, bypassing cache")
|
59
|
+
else:
|
60
|
+
logger.debug("No cache found, fetching from PyPI")
|
40
61
|
|
62
|
+
# Fetch from PyPI
|
41
63
|
logger.debug("Fetching latest version from PyPI")
|
42
64
|
with request.urlopen("https://pypi.org/pypi/TonieToolbox/json", timeout=2) as response:
|
43
65
|
pypi_data = json.loads(response.read().decode("utf-8"))
|
44
66
|
latest_version = pypi_data["info"]["version"]
|
45
67
|
|
68
|
+
# Update cache
|
46
69
|
if not os.path.exists(CACHE_DIR):
|
47
70
|
os.makedirs(CACHE_DIR, exist_ok=True)
|
48
71
|
|
49
72
|
with open(CACHE_FILE, "w") as f:
|
50
|
-
|
73
|
+
cache_data = {
|
51
74
|
"version": latest_version,
|
52
75
|
"timestamp": time.time()
|
53
|
-
}
|
76
|
+
}
|
77
|
+
json.dump(cache_data, f)
|
78
|
+
logger.debug("Updated cache: %s", cache_data)
|
54
79
|
|
55
80
|
logger.debug("Latest version from PyPI: %s", latest_version)
|
56
81
|
return latest_version, None
|
@@ -74,43 +99,67 @@ def compare_versions(v1, v2):
|
|
74
99
|
Returns:
|
75
100
|
int: -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2
|
76
101
|
"""
|
77
|
-
|
78
|
-
|
102
|
+
logger = get_logger("version_handler")
|
103
|
+
logger.debug("Comparing versions: '%s' vs '%s'", v1, v2)
|
79
104
|
|
80
|
-
|
81
|
-
|
82
|
-
|
105
|
+
try:
|
106
|
+
v1_parts = [int(x) for x in v1.split('.')]
|
107
|
+
v2_parts = [int(x) for x in v2.split('.')]
|
108
|
+
|
109
|
+
logger.debug("Version parts: %s vs %s", v1_parts, v2_parts)
|
83
110
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
return 1
|
111
|
+
for i in range(max(len(v1_parts), len(v2_parts))):
|
112
|
+
v1_part = v1_parts[i] if i < len(v1_parts) else 0
|
113
|
+
v2_part = v2_parts[i] if i < len(v2_parts) else 0
|
88
114
|
|
89
|
-
|
115
|
+
logger.debug("Comparing part %d: %d vs %d", i, v1_part, v2_part)
|
116
|
+
|
117
|
+
if v1_part < v2_part:
|
118
|
+
logger.debug("Result: '%s' is OLDER than '%s'", v1, v2)
|
119
|
+
return -1
|
120
|
+
elif v1_part > v2_part:
|
121
|
+
logger.debug("Result: '%s' is NEWER than '%s'", v1, v2)
|
122
|
+
return 1
|
123
|
+
|
124
|
+
logger.debug("Result: versions are EQUAL")
|
125
|
+
return 0
|
126
|
+
except Exception as e:
|
127
|
+
logger.debug("Error comparing versions '%s' and '%s': %s", v1, v2, e)
|
128
|
+
# On error, assume versions are equal
|
129
|
+
return 0
|
90
130
|
|
91
131
|
|
92
|
-
def check_for_updates(quiet=False):
|
132
|
+
def check_for_updates(quiet=False, force_refresh=False):
|
93
133
|
"""
|
94
134
|
Check if the current version of TonieToolbox is the latest.
|
95
135
|
|
96
136
|
Args:
|
97
|
-
quiet: If True, will not log any information messages
|
137
|
+
quiet: If True, will not log any information messages and skip user confirmation
|
138
|
+
force_refresh: If True, bypass cache and check PyPI directly
|
98
139
|
|
99
140
|
Returns:
|
100
|
-
tuple: (is_latest, latest_version, message)
|
141
|
+
tuple: (is_latest, latest_version, message, update_confirmed)
|
101
142
|
is_latest: boolean indicating if the current version is the latest
|
102
143
|
latest_version: string with the latest version
|
103
144
|
message: string message about the update status or error
|
145
|
+
update_confirmed: boolean indicating if the user confirmed the update
|
104
146
|
"""
|
105
147
|
logger = get_logger("version_handler")
|
106
148
|
current_version = __version__
|
149
|
+
update_confirmed = False
|
107
150
|
|
108
|
-
|
151
|
+
logger.debug("Starting update check (quiet=%s, force_refresh=%s)",
|
152
|
+
quiet, force_refresh)
|
153
|
+
latest_version, error = get_pypi_version(force_refresh)
|
109
154
|
|
110
155
|
if error:
|
111
|
-
|
156
|
+
logger.debug("Error occurred during update check: %s", error)
|
157
|
+
return True, current_version, error, update_confirmed
|
112
158
|
|
113
|
-
|
159
|
+
compare_result = compare_versions(current_version, latest_version)
|
160
|
+
is_latest = compare_result >= 0 # current >= latest
|
161
|
+
|
162
|
+
logger.debug("Version comparison result: %d (is_latest=%s)", compare_result, is_latest)
|
114
163
|
|
115
164
|
if is_latest:
|
116
165
|
message = f"You are using the latest version of TonieToolbox ({current_version})"
|
@@ -120,6 +169,88 @@ def check_for_updates(quiet=False):
|
|
120
169
|
message = f"Update available! Current version: {current_version}, Latest version: {latest_version}"
|
121
170
|
if not quiet:
|
122
171
|
logger.info(message)
|
123
|
-
|
172
|
+
|
173
|
+
# Show confirmation prompt if not in quiet mode
|
174
|
+
try:
|
175
|
+
response = input(f"Do you want to upgrade to TonieToolbox {latest_version}? [y/N]: ").lower().strip()
|
176
|
+
update_confirmed = response == 'y' or response == 'yes'
|
177
|
+
|
178
|
+
if update_confirmed:
|
179
|
+
logger.info("Update confirmed. Attempting to install update...")
|
180
|
+
if install_update():
|
181
|
+
logger.info(f"Successfully updated to TonieToolbox {latest_version}")
|
182
|
+
import sys
|
183
|
+
logger.info("Exiting program. Please restart TonieToolbox to use the new version.")
|
184
|
+
sys.exit(0)
|
185
|
+
else:
|
186
|
+
logger.error("Failed to install update automatically")
|
187
|
+
logger.error("Please update manually using: pip install --upgrade TonieToolbox")
|
188
|
+
import sys
|
189
|
+
sys.exit(1)
|
190
|
+
else:
|
191
|
+
logger.info("Update skipped by user.")
|
192
|
+
except (EOFError, KeyboardInterrupt):
|
193
|
+
logger.debug("User input interrupted")
|
194
|
+
update_confirmed = False
|
195
|
+
|
196
|
+
return is_latest, latest_version, message, update_confirmed
|
197
|
+
|
198
|
+
|
199
|
+
def install_update():
|
200
|
+
"""
|
201
|
+
Try to install the update using pip, pip3, or pipx.
|
124
202
|
|
125
|
-
|
203
|
+
Returns:
|
204
|
+
bool: True if the update was successfully installed, False otherwise
|
205
|
+
"""
|
206
|
+
logger = get_logger("version_handler")
|
207
|
+
import subprocess
|
208
|
+
import sys
|
209
|
+
|
210
|
+
package_name = "TonieToolbox"
|
211
|
+
commands = [
|
212
|
+
[sys.executable, "-m", "pip", "install", "--upgrade", package_name],
|
213
|
+
["pip", "install", "--upgrade", package_name],
|
214
|
+
["pip3", "install", "--upgrade", package_name],
|
215
|
+
["pipx", "upgrade", package_name]
|
216
|
+
]
|
217
|
+
|
218
|
+
for cmd in commands:
|
219
|
+
try:
|
220
|
+
logger.info(f"Attempting to install update using: {' '.join(cmd)}")
|
221
|
+
result = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
222
|
+
|
223
|
+
if result.returncode == 0:
|
224
|
+
logger.debug("Update command succeeded")
|
225
|
+
logger.debug(f"Output: {result.stdout}")
|
226
|
+
return True
|
227
|
+
else:
|
228
|
+
logger.debug(f"Command failed with returncode {result.returncode}")
|
229
|
+
logger.debug(f"stdout: {result.stdout}")
|
230
|
+
logger.debug(f"stderr: {result.stderr}")
|
231
|
+
except Exception as e:
|
232
|
+
logger.debug(f"Exception while running {cmd[0]}: {str(e)}")
|
233
|
+
|
234
|
+
return False
|
235
|
+
|
236
|
+
|
237
|
+
def clear_version_cache():
|
238
|
+
"""
|
239
|
+
Clear the version cache file to force a refresh on next check.
|
240
|
+
|
241
|
+
Returns:
|
242
|
+
bool: True if cache was cleared, False otherwise
|
243
|
+
"""
|
244
|
+
logger = get_logger("version_handler")
|
245
|
+
|
246
|
+
try:
|
247
|
+
if os.path.exists(CACHE_FILE):
|
248
|
+
logger.debug("Removing version cache file: %s", CACHE_FILE)
|
249
|
+
os.remove(CACHE_FILE)
|
250
|
+
return True
|
251
|
+
else:
|
252
|
+
logger.debug("No cache file to remove")
|
253
|
+
return False
|
254
|
+
except Exception as e:
|
255
|
+
logger.debug("Error clearing cache: %s", e)
|
256
|
+
return False
|
@@ -1,8 +1,8 @@
|
|
1
|
-
TonieToolbox/__init__.py,sha256=
|
2
|
-
TonieToolbox/__main__.py,sha256=
|
1
|
+
TonieToolbox/__init__.py,sha256=H7iZa88oEbyIf0RTuwe8HaIbX7hDamX8WW6fQubcijs,96
|
2
|
+
TonieToolbox/__main__.py,sha256=eEsfnwLsgI6ynwR4uxo4CKptuOJDpGp6lYWSRwJSY3M,8520
|
3
3
|
TonieToolbox/audio_conversion.py,sha256=10PayO1VQDGee2bcO6JD8zRSFoJRJhO2pBeba5k15vk,7998
|
4
4
|
TonieToolbox/constants.py,sha256=QQWQpnCI65GByLlXLOkt2n8nALLu4m6BWp0zuhI3M04,2021
|
5
|
-
TonieToolbox/dependency_manager.py,sha256=
|
5
|
+
TonieToolbox/dependency_manager.py,sha256=LHH8PlKp12_TkFFk2dyg6CRURh3-oCOiDff1AIEUbKU,17397
|
6
6
|
TonieToolbox/filename_generator.py,sha256=RqQHyGTKakuWR01yMSnFVMU_HfLw3rqFxKhXNIHdTlg,3441
|
7
7
|
TonieToolbox/logger.py,sha256=Up9fBVkOZwkY61_645bX4tienCpyVSkap-FeTV0v730,1441
|
8
8
|
TonieToolbox/ogg_page.py,sha256=-ViaIRBgh5ayfwmyplL8QmmRr5P36X8W0DdHkSFUYUU,21948
|
@@ -11,10 +11,10 @@ TonieToolbox/tonie_analysis.py,sha256=4eOzxHL_g0TJFhuexNHcZXivxZ7eb5xfb9-efUZ02W
|
|
11
11
|
TonieToolbox/tonie_file.py,sha256=nIS4qhpBKIyPvTU39yYljRidpY6cz78halXlz3HJy9w,15294
|
12
12
|
TonieToolbox/tonie_header.proto,sha256=WaWfwO4VrwGtscK2ujfDRKtpeBpaVPoZhI8iMmR-C0U,202
|
13
13
|
TonieToolbox/tonie_header_pb2.py,sha256=s5bp4ULTEekgq6T61z9fDkRavyPM-3eREs20f_Pxxe8,3665
|
14
|
-
TonieToolbox/version_handler.py,sha256=
|
15
|
-
tonietoolbox-0.1.
|
16
|
-
tonietoolbox-0.1.
|
17
|
-
tonietoolbox-0.1.
|
18
|
-
tonietoolbox-0.1.
|
19
|
-
tonietoolbox-0.1.
|
20
|
-
tonietoolbox-0.1.
|
14
|
+
TonieToolbox/version_handler.py,sha256=7Zx-pgzAUhz6jMplvNal1wHyxidodVxaNcAV0EMph5k,9778
|
15
|
+
tonietoolbox-0.1.7.dist-info/licenses/LICENSE.md,sha256=rGoga9ZAgNco9fBapVFpWf6ri7HOBp1KRnt1uIruXMk,35190
|
16
|
+
tonietoolbox-0.1.7.dist-info/METADATA,sha256=7kF7ZRqq_GWhRUrw-z6XlxdfG6kY_nTOtlIUfVFk0DU,8971
|
17
|
+
tonietoolbox-0.1.7.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
18
|
+
tonietoolbox-0.1.7.dist-info/entry_points.txt,sha256=oqpeyBxel7aScg35Xr4gZKnf486S5KW9okqeBwyJxxc,60
|
19
|
+
tonietoolbox-0.1.7.dist-info/top_level.txt,sha256=Wkkm-2p7I3ENfS7ZbYtYUB2g-xwHrXVlERHfonsOPuE,13
|
20
|
+
tonietoolbox-0.1.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|