mp3tools 1.2.4__tar.gz → 1.2.7__tar.gz

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.
Files changed (27) hide show
  1. {mp3tools-1.2.4 → mp3tools-1.2.7}/PKG-INFO +6 -22
  2. mp3tools-1.2.7/README.md +35 -0
  3. mp3tools-1.2.7/mp3tools/VERSION +1 -0
  4. mp3tools-1.2.7/mp3tools/cli.py +588 -0
  5. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools.egg-info/PKG-INFO +6 -22
  6. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools.egg-info/SOURCES.txt +2 -1
  7. mp3tools-1.2.7/tests/test_cli.py +158 -0
  8. mp3tools-1.2.4/README.md +0 -51
  9. mp3tools-1.2.4/mp3tools/VERSION +0 -1
  10. mp3tools-1.2.4/mp3tools/cli.py +0 -392
  11. {mp3tools-1.2.4 → mp3tools-1.2.7}/Containerfile +0 -0
  12. {mp3tools-1.2.4 → mp3tools-1.2.7}/HISTORY.md +0 -0
  13. {mp3tools-1.2.4 → mp3tools-1.2.7}/LICENSE +0 -0
  14. {mp3tools-1.2.4 → mp3tools-1.2.7}/MANIFEST.in +0 -0
  15. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools/__init__.py +0 -0
  16. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools/__main__.py +0 -0
  17. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools/base.py +0 -0
  18. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools/mp3tool.py +0 -0
  19. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools.egg-info/dependency_links.txt +0 -0
  20. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools.egg-info/entry_points.txt +0 -0
  21. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools.egg-info/requires.txt +0 -0
  22. {mp3tools-1.2.4 → mp3tools-1.2.7}/mp3tools.egg-info/top_level.txt +0 -0
  23. {mp3tools-1.2.4 → mp3tools-1.2.7}/setup.cfg +0 -0
  24. {mp3tools-1.2.4 → mp3tools-1.2.7}/setup.py +0 -0
  25. {mp3tools-1.2.4 → mp3tools-1.2.7}/tests/__init__.py +0 -0
  26. {mp3tools-1.2.4 → mp3tools-1.2.7}/tests/conftest.py +0 -0
  27. {mp3tools-1.2.4 → mp3tools-1.2.7}/tests/test_base.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mp3tools
3
- Version: 1.2.4
3
+ Version: 1.2.7
4
4
  Summary: Awesome mp3tools created by carsten-engelke
5
5
  Home-page: https://github.com/carsten-engelke/mp3tools/
6
6
  Author: carsten-engelke
@@ -57,26 +57,10 @@ Merge mp3 files and set correct audio length using foobar2000 with an automated
57
57
  pip install mp3tools
58
58
 
59
59
  ## Usage
60
- Command-line-use:
61
60
  ```
62
- mp3tools -> start tools using standard wizard, just follow instructions.
63
-
64
- mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]
65
- [dir] determines the directory in which to perform. Use '.' to select the current directory
66
- [subdir-mode] determines wheter all mp3 files in subfolders should be merged into one file each. ('True' to do so)")
67
- [foobarpath] determines the path to your foobar2000 installation. Please provide in case it differs from 'C:/Program Files (x86)/foobar2000/foobar2000.exe'
68
- [autowaittime] determines whether to automatically close foobar2000 after some seconds. Use -1 to disable and any number to set the waiting time.
69
-
70
- mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]
71
- [group-size] determines the number of files to put into each directory
72
- [dir] determines the directory in which to perform the script. Use '.' to select the current directory
73
- [file-filter] Filter the file list according to this
74
- [copy-mode] If 'True', the files are copied into the created subfolders. If 'False' they are moved (Use with caution).
75
-
76
- mp3tools unpack-subdirs [dir] [subdir-filter] [filter] [copy-mode] [remove-dir]")
77
- [dir] determines the directory in which to perform the script. Use '.' to select the current directory
78
- [subdir-filter] Filter the subdir list according to this. Use '*' to select any subdirectory
79
- [filter] Filter the file list according to this
80
- [copy-mode] If 'True', the files are copied into the parent folder. If 'False' they are moved (Use with caution).
81
- [remove-dir] If 'True', the subdirectories are deleted. If 'False' they are left as they are.
61
+ Usage: mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]
62
+ Usage: mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]
63
+ Usage: mp3tools unpack-subdirs [dir] [subdir-filter] [file-filter] [copy-mode] [removesubdir-mode]
64
+ Usage: mp3tools wait=seconds
65
+ Note: This script depends on a foobar2000 installation! (Get it from: https://www.foobar2000.org/)
82
66
  ```
@@ -0,0 +1,35 @@
1
+ # mp3tools
2
+ Merge mp3 files and set correct audio length using foobar2000 with an automated python script. These scripts can merge all files in one directory or create one file for each subdirectory.
3
+
4
+
5
+ ![merge mp3 files from subdirectories](https://github.com/carsten-engelke/mp3tools/blob/main/mergemp3subdirs.jpg)
6
+ - mp3tools merge-mp3: merging script, works with foobar2000
7
+ - mp3tools pack-subdirs: pack files into grouped subdirectories (good for large audiobooks)
8
+ - mp3tools unpack-subdirs.py: unpack files from grouped subdirectories (undo mp3tools pack-subdirs)
9
+
10
+ ## Version
11
+ 1.2.2 Fixed
12
+
13
+ 1.2.0 Added PI/CI Support thanks to https://github.com/rochacbruno/python-project-template
14
+
15
+ 1.0.0 release version. Ported to vscode.
16
+
17
+ 0.2.0 bug corrected foobar needs to be called from working directory as the command line plugin cannot handle empty spaces in file names or paths given by command line
18
+
19
+ 0.1.0 initial release. Port from windows script to python, introducing automation
20
+
21
+ ## Requirements
22
+ - Python (script was created using python 3.7.0) (https://www.python.org/)
23
+ - foobar2000 (https://www.foobar2000.org/)
24
+
25
+ ## Installation
26
+ pip install mp3tools
27
+
28
+ ## Usage
29
+ ```
30
+ Usage: mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]
31
+ Usage: mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]
32
+ Usage: mp3tools unpack-subdirs [dir] [subdir-filter] [file-filter] [copy-mode] [removesubdir-mode]
33
+ Usage: mp3tools wait=seconds
34
+ Note: This script depends on a foobar2000 installation! (Get it from: https://www.foobar2000.org/)
35
+ ```
@@ -0,0 +1 @@
1
+ 1.2.7
@@ -0,0 +1,588 @@
1
+ # # Merge mp3 files from the current directory or from subfolders (each into one mp3 file)
2
+ # Group files into subfolders. Create groups of a certain size.
3
+ # Ungroup files from subfolders.
4
+ # Carsten Engelke 2023
5
+
6
+ import argparse
7
+ import os
8
+ import subprocess
9
+ import sys
10
+ import time
11
+
12
+ from _thread import start_new_thread
13
+ from pynput.keyboard import Controller, Key # type: ignore
14
+ import math as m
15
+ from shutil import copyfile
16
+
17
+ __all__ = ["main", "mergemp3", "packsubdirs", "unpackdirs"]
18
+
19
+ VERSIONSTR = "1.0.8 (C)opyright Carsten Engelke 2022"
20
+ foobarpath = "C:/Users/carst/scoop/shims/foobar2000.exe"
21
+ mp3tagpath = "C:/Users/carst/scoop/shims/mp3tag.exe"
22
+ workingdir = os.getcwd()
23
+ autowaittime = 5
24
+ groupsize = 15
25
+ filefilter = ".mp3"
26
+ subdirfilter = "subdir-"
27
+ copymode = False
28
+ removesubdirmode = True
29
+ yes = ["yes", "y", "ja", "j", "", "1"]
30
+
31
+
32
+ def mergesubdirs(dir, foobarpath, autowaittime):
33
+ filelist = []
34
+ with os.scandir(dir) as it:
35
+ for subdir in it:
36
+ if not subdir.name.startswith(".") and subdir.is_dir():
37
+ aimfile = mergedir(subdir, True)
38
+ if aimfile != None:
39
+ filelist.append(aimfile)
40
+ callfoobar(foobarpath, dir, filelist, autowaittime)
41
+ print("Merging subdirectories of " + dir + " done.")
42
+
43
+
44
+ def mergedir(dir, copytoparent):
45
+ if copytoparent:
46
+ filestr = os.path.dirname(dir.path) + os.sep + dir.name + ".mp3"
47
+ else:
48
+ filestr = (
49
+ os.path.dirname(dir) + os.sep + os.path.basename(dir) + ".mp3"
50
+ )
51
+ mp3number = " ".join(os.listdir(dir)).count(".mp3")
52
+ mp3now = 0
53
+ if mp3number > 0:
54
+ print(
55
+ "mp3 file found. Merging to: " + filestr + "...0%\r",
56
+ end=" ",
57
+ flush=True,
58
+ )
59
+ if os.path.exists(filestr):
60
+ os.remove(filestr)
61
+ with open(filestr, "ab") as aimfile:
62
+ with os.scandir(dir) as it:
63
+ for f in it:
64
+ if f.name.endswith(".mp3") and f.is_file():
65
+ mp3now += 1
66
+ srcfile = open(f, "rb")
67
+ aimfile.write(srcfile.read())
68
+ return aimfile
69
+ else:
70
+ print("No mp3 in '" + dir.path + "' found.")
71
+ return None
72
+
73
+
74
+ def callfoobar(foobarpath, workdir, filelist, autowaittime):
75
+ # if not in windows skip foobar2000 execution
76
+ if os.name == "nt":
77
+ filenamelist = []
78
+ for f in filelist:
79
+ filenamelist.append(f.name)
80
+ rebuildcmdlist = [foobarpath]
81
+ rebuildcmdlist.append("/runcmd-files=Util/Rebuild")
82
+ rebuildcmdlist.extend(filenamelist)
83
+ fixcmdlist = [foobarpath]
84
+ fixcmdlist.append("/runcmd-files=Util/Fix")
85
+ fixcmdlist.extend(filenamelist)
86
+ minimizecmdlist = [foobarpath]
87
+ minimizecmdlist.append(
88
+ "/runcmd-files=Utilities/Optimize file layout + minimize file size"
89
+ )
90
+ minimizecmdlist.extend(filenamelist)
91
+ os.chdir(workdir)
92
+ if autowaittime >= 0:
93
+ print(
94
+ "Calling foobar2000 for rebuilding the mp3 stream. Automatically ending in:"
95
+ + str(autowaittime * len(filenamelist)),
96
+ end="...",
97
+ flush=True,
98
+ )
99
+ start_new_thread(
100
+ closefoobar, (foobarpath, autowaittime, len(filelist), True)
101
+ )
102
+ else:
103
+ print(
104
+ "Calling foobar2000 for rebuilding the mp3 stream. Please close the foobar window to continue",
105
+ end="...",
106
+ flush=True,
107
+ )
108
+ subprocess.call(rebuildcmdlist)
109
+ print("done")
110
+ if autowaittime >= 0:
111
+ print(
112
+ "Calling foobar2000 for fixing the mp3 metadata length. Automatically ending in:"
113
+ + str(autowaittime * len(filenamelist) / 2),
114
+ end="...",
115
+ flush=True,
116
+ )
117
+ start_new_thread(
118
+ closefoobar,
119
+ (foobarpath, autowaittime / 2, len(filelist), True),
120
+ )
121
+ else:
122
+ print(
123
+ "Calling foobar2000 for fixing the mp3 metadata length. Please close the foobar window to continue",
124
+ end="...",
125
+ flush=True,
126
+ )
127
+ subprocess.call(fixcmdlist)
128
+ print("done")
129
+ if autowaittime >= 0:
130
+ print(
131
+ "Calling foobar2000 for minimizing file. Automatically ending in "
132
+ + str(autowaittime * len(filenamelist) / 3),
133
+ end="...",
134
+ flush=True,
135
+ )
136
+ start_new_thread(
137
+ closefoobar,
138
+ (foobarpath, autowaittime / 3, len(filelist), False),
139
+ )
140
+ else:
141
+ print(
142
+ "Calling foobar2000 for minimizing file. Please close the foobar window to continue",
143
+ end="...",
144
+ flush=True,
145
+ )
146
+ subprocess.call(minimizecmdlist)
147
+ print("done")
148
+ return True
149
+ else:
150
+ print(
151
+ "foobar2000 onyl available in windows - skipping. Use mp3diags manually in linux e.g."
152
+ )
153
+ return False
154
+
155
+
156
+ def closefoobar(foobarpath, sleeptime, filenumber, press):
157
+ closecmdlist = [foobarpath, "/exit"]
158
+ k = Controller()
159
+ if press:
160
+ time.sleep(sleeptime)
161
+ k.press(Key.enter)
162
+ k.release(Key.enter)
163
+ time.sleep(sleeptime * filenumber)
164
+ subprocess.call(closecmdlist)
165
+
166
+
167
+ def mergemp3(dir, mergesub, foobarpath, autowaittime):
168
+
169
+ print(
170
+ "calling mergemp3 [mergesub="
171
+ + str(mergesub)
172
+ + "] [dir="
173
+ + dir
174
+ + "] [foobarpath="
175
+ + foobarpath
176
+ + "] [autowaittime="
177
+ + str(autowaittime)
178
+ + "]"
179
+ )
180
+
181
+ if mergesub:
182
+ mergesubdirs(dir, foobarpath, autowaittime)
183
+ else:
184
+ aimfile = mergedir(dir, False)
185
+ if aimfile != None:
186
+ callfoobar(foobarpath, dir, [aimfile], autowaittime)
187
+ print("Merging mp3s in " + dir + " done.")
188
+
189
+
190
+ def packsubdirs(groupsize, dir, filter, copy):
191
+
192
+ l = []
193
+ with os.scandir(dir) as it:
194
+ for entry in it:
195
+ if entry.name.find(filter) >= 0 and os.path.isfile(entry):
196
+ l.append(entry)
197
+ dirnum = m.ceil(len(l) / groupsize)
198
+ anz = 0
199
+ dirnumactual = 1
200
+ dirname = dir + "/subdir-" + str(dirnumactual)
201
+ try:
202
+ os.makedirs(dirname)
203
+ except:
204
+ print("directory already exists")
205
+ for entry in l:
206
+ if anz >= groupsize:
207
+ anz = 0
208
+ dirnumactual += 1
209
+ dirname = dir + "/subdir-" + str(dirnumactual)
210
+ print("create: " + dirname)
211
+ try:
212
+ os.mkdir(dirname)
213
+ except:
214
+ print("directory already exists")
215
+ if copy:
216
+ copyfile(dir + "/" + entry.name, dirname + "/" + entry.name)
217
+ print("FILE_COPIED: " + entry.name)
218
+ else:
219
+ os.rename(dir + "/" + entry.name, dirname + "/" + entry.name)
220
+ print("FILE_MOVED: " + entry.name)
221
+ anz += 1
222
+
223
+
224
+ def unpackdirs(workdir, subdirfilter, filefilter, copy, remove):
225
+ l = []
226
+ with os.scandir(workdir) as it:
227
+ for entry in it:
228
+ if subdirfilter == "*" and os.path.isdir(entry):
229
+ l.append(entry)
230
+ else:
231
+ if entry.name.find(subdirfilter) >= 0 and os.path.isdir(entry):
232
+ l.append(entry)
233
+
234
+ for subdir in l:
235
+ with os.scandir(subdir) as it:
236
+ for entry in it:
237
+ if entry.name.find(filefilter) >= 0 and os.path.isfile(entry):
238
+ if copy:
239
+ copyfile(
240
+ os.path.join(workdir, subdir.name, entry.name),
241
+ os.path.join(workdir, entry.name),
242
+ )
243
+ print("FILE_COPIED: " + entry.name)
244
+ else:
245
+ os.rename(
246
+ os.path.join(workdir, subdir.name, entry.name),
247
+ os.path.join(workdir, entry.name),
248
+ )
249
+ print("FILE_MOVED: " + entry.name)
250
+ if remove:
251
+ os.removedirs(subdir)
252
+ print("DIR_REMOVED: " + subdir.name)
253
+
254
+
255
+ def selectsubprogram():
256
+ while True:
257
+ choice = input(
258
+ "(M)erge mp3 files, (P)ack subfolders, (U)npack subfolders or (A)bort?"
259
+ )
260
+ if choice == "M" or choice == "m":
261
+ run_command(build_parser().parse_args(["merge-mp3"]))
262
+ return
263
+ if choice == "P" or choice == "p":
264
+ run_command(build_parser().parse_args(["pack-subdirs"]))
265
+ return
266
+ if choice == "U" or choice == "u":
267
+ run_command(build_parser().parse_args(["unpack-subdirs"]))
268
+ return
269
+ if choice == "A" or choice == "a":
270
+ sys.exit(0)
271
+
272
+
273
+ def parse_boolean(value):
274
+ normalized = value.lower()
275
+ if normalized in ("true", "yes", "y", "ja", "j", "1", "on"):
276
+ return True
277
+ if normalized in ("false", "no", "n", "nein", "0", "off", "move"):
278
+ return False
279
+ raise argparse.ArgumentTypeError(
280
+ "expected true/false, yes/no, y/n, ja/nein, 1/0, on/off, or move"
281
+ )
282
+
283
+
284
+ def positive_integer(value):
285
+ try:
286
+ parsed = int(value)
287
+ except ValueError:
288
+ raise argparse.ArgumentTypeError("must be an integer")
289
+ if parsed < 1:
290
+ raise argparse.ArgumentTypeError("must be greater than zero")
291
+ return parsed
292
+
293
+
294
+ def build_parser():
295
+ parser = argparse.ArgumentParser(
296
+ prog="mp3tools",
297
+ description=(
298
+ "Merge MP3 files and organize files into subdirectories.\n"
299
+ "Run without a command to start the interactive wizard."
300
+ ),
301
+ formatter_class=argparse.RawDescriptionHelpFormatter,
302
+ epilog=(
303
+ "For argument details and examples, run one of:\n"
304
+ " mp3tools merge-mp3 --help\n"
305
+ " mp3tools pack-subdirs --help\n"
306
+ " mp3tools unpack-subdirs --help\n"
307
+ " mp3tools wait --help\n"
308
+ "\n"
309
+ "The executable path options may be used before or after a command.\n"
310
+ "Run without a command to use the interactive wizard."
311
+ "\n"
312
+ "Merging and fixing MP3 metadata requires foobar2000 on Windows."
313
+ ),
314
+ )
315
+ parser.add_argument(
316
+ "-V", "--version", action="version", version=VERSIONSTR
317
+ )
318
+ add_executable_arguments(parser)
319
+ commands = parser.add_subparsers(dest="command")
320
+
321
+ merge = commands.add_parser("merge-mp3", help="merge MP3 files")
322
+ add_executable_arguments(merge, suppress_defaults=True)
323
+ merge.add_argument(
324
+ "dir",
325
+ nargs="?",
326
+ metavar="DIR",
327
+ help="directory containing MP3s (default: current directory; '.' also selects it)",
328
+ )
329
+ merge.add_argument(
330
+ "subdir_mode",
331
+ nargs="?",
332
+ metavar="SUBDIR-MODE",
333
+ type=parse_boolean,
334
+ help=(
335
+ "merge each subdirectory into a separate MP3; accepts "
336
+ "true/false, yes/no, y/n, ja/nein, 1/0, on/off (omitted: ask)"
337
+ ),
338
+ )
339
+ merge.add_argument(
340
+ "legacy_foobar_path",
341
+ nargs="?",
342
+ metavar="FOOBAR-PATH",
343
+ help="legacy positional foobar2000 executable path; prefer --foobar-path",
344
+ )
345
+ merge.add_argument(
346
+ "autowaittime",
347
+ nargs="?",
348
+ metavar="SECONDS",
349
+ type=int,
350
+ help="seconds before auto-closing foobar2000; use -1 to disable (default: 5)",
351
+ )
352
+
353
+ pack = commands.add_parser(
354
+ "pack-subdirs", help="group files into subdirectories"
355
+ )
356
+ add_executable_arguments(pack, suppress_defaults=True)
357
+ pack.add_argument(
358
+ "group_size",
359
+ nargs="?",
360
+ metavar="GROUP-SIZE",
361
+ type=positive_integer,
362
+ help="maximum files per subdirectory (default: 15; must be greater than 0)",
363
+ )
364
+ pack.add_argument(
365
+ "dir",
366
+ nargs="?",
367
+ metavar="DIR",
368
+ help="directory containing files (default: current directory; '.' also selects it)",
369
+ )
370
+ pack.add_argument(
371
+ "file_filter",
372
+ nargs="?",
373
+ metavar="FILE-FILTER",
374
+ help="case-sensitive substring selecting files (default: '.mp3')",
375
+ )
376
+ pack.add_argument(
377
+ "copy_mode",
378
+ nargs="?",
379
+ metavar="COPY-MODE",
380
+ type=parse_boolean,
381
+ help=(
382
+ "copy instead of move; accepts true/false, yes/no, y/n, "
383
+ "ja/nein, 1/0, on/off, or 'move' for false "
384
+ "(default: false, move files)"
385
+ ),
386
+ )
387
+
388
+ unpack = commands.add_parser(
389
+ "unpack-subdirs", help="move files out of subdirectories"
390
+ )
391
+ add_executable_arguments(unpack, suppress_defaults=True)
392
+ unpack.add_argument(
393
+ "dir",
394
+ nargs="?",
395
+ metavar="DIR",
396
+ help="directory containing subdirectories (default: current directory; '.' also selects it)",
397
+ )
398
+ unpack.add_argument(
399
+ "subdir_filter",
400
+ nargs="?",
401
+ metavar="SUBDIR-FILTER",
402
+ help="case-sensitive substring selecting subdirectories; '*' selects all (default: 'subdir-')",
403
+ )
404
+ unpack.add_argument(
405
+ "file_filter",
406
+ nargs="?",
407
+ metavar="FILE-FILTER",
408
+ help="case-sensitive substring selecting files (default: '.mp3')",
409
+ )
410
+ unpack.add_argument(
411
+ "copy_mode",
412
+ nargs="?",
413
+ metavar="COPY-MODE",
414
+ type=parse_boolean,
415
+ help=(
416
+ "copy instead of move; accepts true/false, yes/no, y/n, "
417
+ "ja/nein, 1/0, on/off, or 'move' for false "
418
+ "(default: false, move files)"
419
+ ),
420
+ )
421
+ unpack.add_argument(
422
+ "remove_subdirs",
423
+ nargs="?",
424
+ metavar="REMOVE-SUBDIRS",
425
+ type=parse_boolean,
426
+ help=(
427
+ "remove emptied subdirectories; accepts true/false, yes/no, "
428
+ "y/n, ja/nein, 1/0, on/off "
429
+ "(default: true; ignored if files remain)"
430
+ ),
431
+ )
432
+
433
+ wait = commands.add_parser(
434
+ "wait", help="set the foobar2000 wait time, then choose a tool"
435
+ )
436
+ add_executable_arguments(wait, suppress_defaults=True)
437
+ wait.add_argument(
438
+ "seconds",
439
+ nargs="?",
440
+ metavar="SECONDS",
441
+ type=int,
442
+ help="seconds before auto-closing foobar2000; use -1 to disable (default: 5)",
443
+ )
444
+ return parser
445
+
446
+
447
+ def add_executable_arguments(parser, suppress_defaults=False):
448
+ default = argparse.SUPPRESS if suppress_defaults else foobarpath
449
+ parser.add_argument(
450
+ "--foobar-path",
451
+ metavar="PATH",
452
+ default=default,
453
+ help="path to the foobar2000 executable (default: configured path)",
454
+ )
455
+ default = argparse.SUPPRESS if suppress_defaults else mp3tagpath
456
+ parser.add_argument(
457
+ "--mp3tag-path",
458
+ metavar="PATH",
459
+ default=default,
460
+ help="path to the Mp3tag executable (default: configured path)",
461
+ )
462
+
463
+
464
+ def confirm(message):
465
+ print(message)
466
+ return input().lower() in yes
467
+
468
+
469
+ def run_command(args):
470
+ global autowaittime
471
+ global foobarpath
472
+ global mp3tagpath
473
+
474
+ foobarpath = args.foobar_path
475
+ mp3tagpath = args.mp3tag_path
476
+ if args.command == "merge-mp3":
477
+ directory = workingdir if args.dir in (None, ".") else args.dir
478
+ if directory != workingdir and not os.path.isdir(directory):
479
+ choice = input(
480
+ "Specified directory not found: {0} ... will use current "
481
+ "directory instead: {1}...OK? (Y)es or (N)o?".format(
482
+ directory, workingdir
483
+ )
484
+ )
485
+ if choice.lower() in ("n", "no", "nein"):
486
+ return
487
+ directory = workingdir
488
+ mode = args.subdir_mode
489
+ if mode is None:
490
+ while True:
491
+ choice = input(
492
+ " > Merge (S)ubfolders or this (D)irectory or (A)bort?"
493
+ ).lower()
494
+ if choice in ("s", "d"):
495
+ mode = choice == "s"
496
+ break
497
+ if choice == "a":
498
+ return
499
+ path = args.legacy_foobar_path
500
+ if path is None or path == ".":
501
+ path = foobarpath
502
+ wait_time = (
503
+ args.autowaittime
504
+ if args.autowaittime is not None
505
+ else autowaittime
506
+ )
507
+ print("mp3-tools merge-mp3 {0}".format(VERSIONSTR))
508
+ mergemp3(directory, mode, path, wait_time)
509
+ elif args.command == "pack-subdirs":
510
+ group_size = (
511
+ args.group_size if args.group_size is not None else groupsize
512
+ )
513
+ directory = workingdir if args.dir in (None, ".") else args.dir
514
+ filter_value = (
515
+ args.file_filter if args.file_filter is not None else filefilter
516
+ )
517
+ copy = args.copy_mode if args.copy_mode is not None else copymode
518
+ print("pack-subdirs {0}".format(VERSIONSTR))
519
+ print(
520
+ "calling pack-subdirs: [group-size={0}] [dir={1}] "
521
+ "[filter={2}] [copy-mode={3}]".format(
522
+ group_size, directory, filter_value, copy
523
+ )
524
+ )
525
+ if args.group_size is None and not confirm(
526
+ "Pack files according to above settings into subdirectories [y/n]?"
527
+ ):
528
+ return
529
+ packsubdirs(group_size, directory, filter_value, copy)
530
+ elif args.command == "unpack-subdirs":
531
+ directory = workingdir if args.dir in (None, ".") else args.dir
532
+ subdirs = (
533
+ args.subdir_filter
534
+ if args.subdir_filter is not None
535
+ else subdirfilter
536
+ )
537
+ filter_value = (
538
+ args.file_filter if args.file_filter is not None else filefilter
539
+ )
540
+ copy = args.copy_mode if args.copy_mode is not None else copymode
541
+ remove = (
542
+ args.remove_subdirs
543
+ if args.remove_subdirs is not None
544
+ else removesubdirmode
545
+ )
546
+ print("unpack-subdirs {0}".format(VERSIONSTR))
547
+ print(
548
+ "calling unpack-subdirs [dir={0}] [subdir-filter={1}] "
549
+ "[file-filter={2}] [copy-mode={3}] [removesubdir-mode={4}]".format(
550
+ directory, subdirs, filter_value, copy, remove
551
+ )
552
+ )
553
+ if args.dir is None and not confirm(
554
+ "Unpack files according to above settings into subdirectories [y/n]?"
555
+ ):
556
+ return
557
+ unpackdirs(directory, subdirs, filter_value, copy, remove)
558
+ elif args.command == "wait":
559
+ if args.seconds is not None:
560
+ autowaittime = args.seconds
561
+ selectsubprogram()
562
+
563
+
564
+ def main(argv=None):
565
+ """
566
+ The main function executes on commands:
567
+ `python -m mp3tools` and `$ mp3tools `.
568
+
569
+ This is your program's entry point.
570
+ """
571
+ if argv is None:
572
+ argv = sys.argv[1:]
573
+ if not argv:
574
+ selectsubprogram()
575
+ return
576
+
577
+ if len(argv) == 1 and argv[0].startswith("wait="):
578
+ argv = ["wait", argv[0][5:]]
579
+ parser = build_parser()
580
+ args = parser.parse_args(argv)
581
+ if args.command is None:
582
+ parser.print_help()
583
+ else:
584
+ run_command(args)
585
+
586
+
587
+ if __name__ == "__main__":
588
+ main()