mp3tools 1.2.0__tar.gz → 1.2.1__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.
- {mp3tools-1.2.0 → mp3tools-1.2.1}/PKG-INFO +26 -15
- {mp3tools-1.2.0 → mp3tools-1.2.1}/README.md +16 -12
- mp3tools-1.2.1/mp3tools/VERSION +1 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools/cli.py +60 -65
- mp3tools-1.2.1/mp3tools/mp3tool.py +323 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools.egg-info/PKG-INFO +26 -15
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools.egg-info/SOURCES.txt +1 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools.egg-info/requires.txt +0 -1
- mp3tools-1.2.0/mp3tools/VERSION +0 -1
- {mp3tools-1.2.0 → mp3tools-1.2.1}/Containerfile +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/HISTORY.md +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/LICENSE +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/MANIFEST.in +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools/__init__.py +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools/__main__.py +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools/base.py +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools.egg-info/dependency_links.txt +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools.egg-info/entry_points.txt +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/mp3tools.egg-info/top_level.txt +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/setup.cfg +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/setup.py +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/tests/__init__.py +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/tests/conftest.py +0 -0
- {mp3tools-1.2.0 → mp3tools-1.2.1}/tests/test_base.py +0 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mp3tools
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Awesome mp3tools created by carsten-engelke
|
|
5
5
|
Home-page: https://github.com/carsten-engelke/mp3tools/
|
|
6
6
|
Author: carsten-engelke
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: autopep8>=1
|
|
10
|
-
Requires-Dist: natsort>=7
|
|
11
10
|
Requires-Dist: pycodestyle>=2
|
|
12
11
|
Requires-Dist: pynput>=1
|
|
13
12
|
Requires-Dist: six>=1
|
|
@@ -21,17 +20,27 @@ Requires-Dist: pytest-cov; extra == "test"
|
|
|
21
20
|
Requires-Dist: mypy; extra == "test"
|
|
22
21
|
Requires-Dist: gitchangelog; extra == "test"
|
|
23
22
|
Requires-Dist: mkdocs; extra == "test"
|
|
23
|
+
Dynamic: author
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: provides-extra
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: summary
|
|
24
31
|
|
|
25
32
|
# mp3tools
|
|
26
33
|
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.
|
|
27
34
|
|
|
28
35
|
|
|
29
|
-

|
|
30
|
-
- merge-mp3
|
|
31
|
-
- pack-subdirs
|
|
32
|
-
- unpack-subdirs.py: unpack files from grouped subdirectories (undo pack-subdirs
|
|
36
|
+

|
|
37
|
+
- mp3tools merge-mp3: merging script, works with foobar2000
|
|
38
|
+
- mp3tools pack-subdirs: pack files into grouped subdirectories (good for large audiobooks)
|
|
39
|
+
- mp3tools unpack-subdirs.py: unpack files from grouped subdirectories (undo mp3tools pack-subdirs)
|
|
33
40
|
|
|
34
41
|
## Version
|
|
42
|
+
1.2.2 Fixed
|
|
43
|
+
|
|
35
44
|
1.2.0 Added PI/CI Support thanks to https://github.com/rochacbruno/python-project-template
|
|
36
45
|
|
|
37
46
|
1.0.0 release version. Ported to vscode.
|
|
@@ -45,24 +54,26 @@ Merge mp3 files and set correct audio length using foobar2000 with an automated
|
|
|
45
54
|
- foobar2000 (https://www.foobar2000.org/)
|
|
46
55
|
|
|
47
56
|
## Installation
|
|
48
|
-
|
|
49
|
-
- run the script and follow the instructions, alternatively use the following command line
|
|
57
|
+
pip install mp3tools
|
|
50
58
|
|
|
59
|
+
## Usage
|
|
51
60
|
Command-line-use:
|
|
52
61
|
```
|
|
53
|
-
|
|
62
|
+
mp3tools -> start tools using standard wizard, just follow instructions.
|
|
63
|
+
|
|
64
|
+
mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]
|
|
54
65
|
[dir] determines the directory in which to perform. Use '.' to select the current directory
|
|
55
|
-
[
|
|
66
|
+
[subdir-mode] determines wheter all mp3 files in subfolders should be merged into one file each. ('True' to do so)")
|
|
56
67
|
[foobarpath] determines the path to your foobar2000 installation. Please provide in case it differs from 'C:/Program Files (x86)/foobar2000/foobar2000.exe'
|
|
57
|
-
[autowaittime] determines whether to automatically
|
|
68
|
+
[autowaittime] determines whether to automatically close foobar2000 after some seconds. Use -1 to disable and any number to set the waiting time.
|
|
58
69
|
|
|
59
|
-
|
|
70
|
+
mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]
|
|
60
71
|
[group-size] determines the number of files to put into each directory
|
|
61
72
|
[dir] determines the directory in which to perform the script. Use '.' to select the current directory
|
|
62
|
-
[filter] Filter the file list according to this
|
|
73
|
+
[file-filter] Filter the file list according to this
|
|
63
74
|
[copy-mode] If 'True', the files are copied into the created subfolders. If 'False' they are moved (Use with caution).
|
|
64
75
|
|
|
65
|
-
|
|
76
|
+
mp3tools unpack-subdirs [dir] [subdir-filter] [filter] [copy-mode] [remove-dir]")
|
|
66
77
|
[dir] determines the directory in which to perform the script. Use '.' to select the current directory
|
|
67
78
|
[subdir-filter] Filter the subdir list according to this. Use '*' to select any subdirectory
|
|
68
79
|
[filter] Filter the file list according to this
|
|
@@ -2,12 +2,14 @@
|
|
|
2
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
3
|
|
|
4
4
|
|
|
5
|
-

|
|
6
|
-
- merge-mp3
|
|
7
|
-
- pack-subdirs
|
|
8
|
-
- unpack-subdirs.py: unpack files from grouped subdirectories (undo pack-subdirs
|
|
5
|
+

|
|
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
9
|
|
|
10
10
|
## Version
|
|
11
|
+
1.2.2 Fixed
|
|
12
|
+
|
|
11
13
|
1.2.0 Added PI/CI Support thanks to https://github.com/rochacbruno/python-project-template
|
|
12
14
|
|
|
13
15
|
1.0.0 release version. Ported to vscode.
|
|
@@ -21,24 +23,26 @@ Merge mp3 files and set correct audio length using foobar2000 with an automated
|
|
|
21
23
|
- foobar2000 (https://www.foobar2000.org/)
|
|
22
24
|
|
|
23
25
|
## Installation
|
|
24
|
-
|
|
25
|
-
- run the script and follow the instructions, alternatively use the following command line
|
|
26
|
+
pip install mp3tools
|
|
26
27
|
|
|
28
|
+
## Usage
|
|
27
29
|
Command-line-use:
|
|
28
30
|
```
|
|
29
|
-
|
|
31
|
+
mp3tools -> start tools using standard wizard, just follow instructions.
|
|
32
|
+
|
|
33
|
+
mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]
|
|
30
34
|
[dir] determines the directory in which to perform. Use '.' to select the current directory
|
|
31
|
-
[
|
|
35
|
+
[subdir-mode] determines wheter all mp3 files in subfolders should be merged into one file each. ('True' to do so)")
|
|
32
36
|
[foobarpath] determines the path to your foobar2000 installation. Please provide in case it differs from 'C:/Program Files (x86)/foobar2000/foobar2000.exe'
|
|
33
|
-
[autowaittime] determines whether to automatically
|
|
37
|
+
[autowaittime] determines whether to automatically close foobar2000 after some seconds. Use -1 to disable and any number to set the waiting time.
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]
|
|
36
40
|
[group-size] determines the number of files to put into each directory
|
|
37
41
|
[dir] determines the directory in which to perform the script. Use '.' to select the current directory
|
|
38
|
-
[filter] Filter the file list according to this
|
|
42
|
+
[file-filter] Filter the file list according to this
|
|
39
43
|
[copy-mode] If 'True', the files are copied into the created subfolders. If 'False' they are moved (Use with caution).
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
mp3tools unpack-subdirs [dir] [subdir-filter] [filter] [copy-mode] [remove-dir]")
|
|
42
46
|
[dir] determines the directory in which to perform the script. Use '.' to select the current directory
|
|
43
47
|
[subdir-filter] Filter the subdir list according to this. Use '*' to select any subdirectory
|
|
44
48
|
[filter] Filter the file list according to this
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.1
|
|
@@ -1,25 +1,15 @@
|
|
|
1
|
-
# Merge mp3 files from the current directory or from subfolders (each into one mp3 file)
|
|
2
|
-
# Group files into subfolders. Create groups
|
|
3
|
-
# Ungroup files from subfolders.
|
|
4
|
-
# Carsten Engelke
|
|
5
|
-
# version:
|
|
6
|
-
# 0.1.0 initial port from windows script, introducing automation
|
|
7
|
-
# 0.2.0 bug corrected foobar needs to be called from working directory as the command line plugin cannot handle empty
|
|
8
|
-
# spaces in file names or paths given by command line
|
|
9
|
-
# 1.0.0 first automated working version, migrated to vs code
|
|
10
|
-
# 1.0.1 migrated all scripts into one module
|
|
11
|
-
# 1.0.4-6 corrected auto wait time option
|
|
12
|
-
# 1.0.7 adjusted standard variables -> file-filter is now .mp3, copy-mode is off, removesubdir-mode is on and subdir-filter is set to subdir- for safety purposes
|
|
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
|
|
13
5
|
|
|
14
6
|
import os
|
|
15
7
|
import subprocess
|
|
16
8
|
import sys
|
|
17
9
|
import time
|
|
18
|
-
from os.path import basename
|
|
19
10
|
|
|
20
|
-
import natsort
|
|
21
11
|
from _thread import start_new_thread
|
|
22
|
-
from pynput.keyboard import Controller, Key
|
|
12
|
+
from pynput.keyboard import Controller, Key # type: ignore
|
|
23
13
|
import math as m
|
|
24
14
|
from shutil import copyfile
|
|
25
15
|
|
|
@@ -81,49 +71,54 @@ def mergedir(dir, copytoparent):
|
|
|
81
71
|
|
|
82
72
|
|
|
83
73
|
def callfoobar(foobarpath, workdir, filelist, autowaittime):
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
filenamelist
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
print("
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
print("
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
74
|
+
# if not in windows skip foobar2000 execution
|
|
75
|
+
if os.name == "nt":
|
|
76
|
+
filenamelist = []
|
|
77
|
+
for f in filelist:
|
|
78
|
+
filenamelist.append(f.name)
|
|
79
|
+
rebuildcmdlist = [foobarpath]
|
|
80
|
+
rebuildcmdlist.append("/runcmd-files=Util/Rebuild")
|
|
81
|
+
rebuildcmdlist.extend(filenamelist)
|
|
82
|
+
fixcmdlist = [foobarpath]
|
|
83
|
+
fixcmdlist.append("/runcmd-files=Util/Fix")
|
|
84
|
+
fixcmdlist.extend(filenamelist)
|
|
85
|
+
minimizecmdlist = [foobarpath]
|
|
86
|
+
minimizecmdlist.append(
|
|
87
|
+
"/runcmd-files=Utilities/Optimize file layout + minimize file size")
|
|
88
|
+
minimizecmdlist.extend(filenamelist)
|
|
89
|
+
os.chdir(workdir)
|
|
90
|
+
if (autowaittime >= 0):
|
|
91
|
+
print("Calling foobar2000 for rebuilding the mp3 stream. Automatically ending in:" +
|
|
92
|
+
str(autowaittime*len(filenamelist)), end="...", flush=True)
|
|
93
|
+
start_new_thread(
|
|
94
|
+
closefoobar, (foobarpath, autowaittime, len(filelist), True))
|
|
95
|
+
else:
|
|
96
|
+
print("Calling foobar2000 for rebuilding the mp3 stream. Please close the foobar window to continue", end="...", flush=True)
|
|
97
|
+
subprocess.call(rebuildcmdlist)
|
|
98
|
+
print("done")
|
|
99
|
+
if (autowaittime >= 0):
|
|
100
|
+
print("Calling foobar2000 for fixing the mp3 metadata length. Automatically ending in:" +
|
|
101
|
+
str(autowaittime*len(filenamelist)/2), end="...", flush=True)
|
|
102
|
+
start_new_thread(
|
|
103
|
+
closefoobar, (foobarpath, autowaittime/2, len(filelist), True))
|
|
104
|
+
else:
|
|
105
|
+
print("Calling foobar2000 for fixing the mp3 metadata length. Please close the foobar window to continue", end="...", flush=True)
|
|
106
|
+
subprocess.call(fixcmdlist)
|
|
107
|
+
print("done")
|
|
108
|
+
if (autowaittime >= 0):
|
|
109
|
+
print("Calling foobar2000 for minimizing file. Automatically ending in " +
|
|
110
|
+
str(autowaittime*len(filenamelist)/3), end="...", flush=True)
|
|
111
|
+
start_new_thread(
|
|
112
|
+
closefoobar, (foobarpath, autowaittime/3, len(filelist), False))
|
|
113
|
+
else:
|
|
114
|
+
print("Calling foobar2000 for minimizing file. Please close the foobar window to continue",
|
|
115
|
+
end="...", flush=True)
|
|
116
|
+
subprocess.call(minimizecmdlist)
|
|
117
|
+
print("done")
|
|
118
|
+
return True
|
|
121
119
|
else:
|
|
122
|
-
print("
|
|
123
|
-
|
|
124
|
-
subprocess.call(minimizecmdlist)
|
|
125
|
-
print("done")
|
|
126
|
-
return True
|
|
120
|
+
print("foobar2000 onyl available in windows - skipping. Use mp3diags manually in linux e.g.")
|
|
121
|
+
return False
|
|
127
122
|
|
|
128
123
|
|
|
129
124
|
def closefoobar(foobarpath, sleeptime, filenumber, press):
|
|
@@ -148,9 +143,9 @@ def mergemp3cli(args):
|
|
|
148
143
|
|
|
149
144
|
print("mp3-tools merge-mp3 {0}".format(VERSIONSTR))
|
|
150
145
|
print(
|
|
151
|
-
"Usage:
|
|
146
|
+
"Usage: mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]")
|
|
152
147
|
print(" [dir] determines the directory in which to perform the script. Use '.' to select the current directory")
|
|
153
|
-
print(" [subdir-mode] determines wheter all mp3 files in subfolders should be merged into one file each. ('
|
|
148
|
+
print(" [subdir-mode] determines wheter all mp3 files in subfolders should be merged into one file each. ('True' to do so)")
|
|
154
149
|
print(" [foobarpath] determines the path to your foobar2000 installation. Please provide in case it differs from 'C:/Program Files (x86)/foobar2000/foobar2000.exe'. Use '.' to remain unchanged.")
|
|
155
150
|
print(" [autowaittime] determines whether to automatically clos foobar2000 after some seconds. Use -1 to disable and any number to set the waiting time.")
|
|
156
151
|
|
|
@@ -215,7 +210,7 @@ def packsubdirscli(args):
|
|
|
215
210
|
global copymode
|
|
216
211
|
|
|
217
212
|
print("pack-subdirs {0}".format(VERSIONSTR))
|
|
218
|
-
print("Use:
|
|
213
|
+
print("Use: mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]")
|
|
219
214
|
print(" [group-size] determines the number of files to put into each directory")
|
|
220
215
|
print(" [dir] determines the directory in which to perform the script. Use '.' to select the current directory")
|
|
221
216
|
print(" [file-filter] Filter the file list according to this.")
|
|
@@ -288,7 +283,7 @@ def unpackdirscli(args):
|
|
|
288
283
|
global removesubdirmode
|
|
289
284
|
|
|
290
285
|
print("unpack-subdirs {0}".format(VERSIONSTR))
|
|
291
|
-
print("Use:
|
|
286
|
+
print("Use: mp3tools unpack-subdirs [dir] [subdir-filter] [file-filter] [copy-mode] [removesubdir-mode]")
|
|
292
287
|
print(" [dir] determines the directory in which to perform the script. Use '.' to select the current directory")
|
|
293
288
|
print(" [subdir-filter] Filter the subdir list according to this. Use '*' to select any subdirectory")
|
|
294
289
|
print(" [file-filter] Filter the file list according to this.")
|
|
@@ -374,10 +369,10 @@ def main():
|
|
|
374
369
|
"""
|
|
375
370
|
global autowaittime
|
|
376
371
|
|
|
377
|
-
print ("Usage:
|
|
378
|
-
print ("Usage:
|
|
379
|
-
print ("Usage:
|
|
380
|
-
print ("Usage:
|
|
372
|
+
print ("Usage: mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]")
|
|
373
|
+
print ("Usage: mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]")
|
|
374
|
+
print ("Usage: mp3tools unpack-subdirs [dir] [subdir-filter] [file-filter] [copy-mode] [removesubdir-mode]")
|
|
375
|
+
print ("Usage: mp3tools wait=seconds")
|
|
381
376
|
print ("Note: This script depends on a foobar2000 installation! (Get it from: https://www.foobar2000.org/)")
|
|
382
377
|
args = sys.argv[1:]
|
|
383
378
|
if (len(args) > 0):
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
import tkinter as tk
|
|
3
|
+
import tkinter.ttk as ttk
|
|
4
|
+
import os
|
|
5
|
+
import subprocess
|
|
6
|
+
|
|
7
|
+
class GuiMp3ToolsApp:
|
|
8
|
+
def __init__(self, master=None):
|
|
9
|
+
# build ui
|
|
10
|
+
self.notebook = ttk.Notebook(master)
|
|
11
|
+
self.notebook.configure(height=600, width=800)
|
|
12
|
+
self.frame_merge = ttk.Frame(self.notebook)
|
|
13
|
+
self.frame_merge.configure(height=200, width=200)
|
|
14
|
+
label3 = ttk.Label(self.frame_merge)
|
|
15
|
+
label3.configure(state="normal", text='Working Directory:')
|
|
16
|
+
label3.grid(column=0, row=0)
|
|
17
|
+
entry1 = ttk.Entry(self.frame_merge)
|
|
18
|
+
self.workingdir = tk.StringVar()
|
|
19
|
+
self.workingdir.set(os.getcwd())
|
|
20
|
+
entry1.configure(textvariable=self.workingdir)
|
|
21
|
+
entry1.grid(column=1, padx=10, row=0, sticky="ew")
|
|
22
|
+
frame12 = ttk.Frame(self.frame_merge)
|
|
23
|
+
frame12.configure(height=200, padding=5, relief="sunken", width=200)
|
|
24
|
+
label9 = ttk.Label(frame12)
|
|
25
|
+
label9.configure(text='Command parameters:')
|
|
26
|
+
label9.grid(column=0, columnspan=2, row=0, sticky="ew")
|
|
27
|
+
label10 = ttk.Label(frame12)
|
|
28
|
+
label10.configure(text='Directory:')
|
|
29
|
+
label10.grid(column=0, row=1, sticky="e")
|
|
30
|
+
label12 = ttk.Label(frame12)
|
|
31
|
+
label12.configure(text='FooBar2000 Path:')
|
|
32
|
+
label12.grid(column=0, row=3, sticky="e")
|
|
33
|
+
label13 = ttk.Label(frame12)
|
|
34
|
+
label13.configure(state="normal", text='Waiting Time [s]:')
|
|
35
|
+
label13.grid(column=0, row=4, sticky="e")
|
|
36
|
+
entry3 = ttk.Entry(frame12)
|
|
37
|
+
self.mergedir = tk.StringVar(value='.')
|
|
38
|
+
entry3.configure(textvariable=self.mergedir)
|
|
39
|
+
_text_ = '.'
|
|
40
|
+
entry3.delete("0", "end")
|
|
41
|
+
entry3.insert("0", _text_)
|
|
42
|
+
entry3.grid(column=1, row=1, sticky="ew")
|
|
43
|
+
entry5 = ttk.Entry(frame12)
|
|
44
|
+
self.mergefoobarpath = tk.StringVar(
|
|
45
|
+
value='.')
|
|
46
|
+
entry5.configure(textvariable=self.mergefoobarpath)
|
|
47
|
+
entry5.grid(column=1, row=3, sticky="ew")
|
|
48
|
+
entry6 = ttk.Entry(frame12)
|
|
49
|
+
self.mergewaittime = tk.IntVar(value=5)
|
|
50
|
+
entry6.configure(textvariable=self.mergewaittime)
|
|
51
|
+
_text_ = '5'
|
|
52
|
+
entry6.delete("0", "end")
|
|
53
|
+
entry6.insert("0", _text_)
|
|
54
|
+
entry6.grid(column=1, row=4, sticky="ew")
|
|
55
|
+
button1 = ttk.Button(frame12)
|
|
56
|
+
button1.configure(text='Start Script')
|
|
57
|
+
button1.grid(
|
|
58
|
+
column=0,
|
|
59
|
+
columnspan=3,
|
|
60
|
+
padx=10,
|
|
61
|
+
pady=10,
|
|
62
|
+
row=5,
|
|
63
|
+
sticky="nsew")
|
|
64
|
+
button1.configure(command=self.startscript)
|
|
65
|
+
buttonfoo = ttk.Button(frame12)
|
|
66
|
+
buttonfoo.configure(text='Start foobar2000')
|
|
67
|
+
buttonfoo.grid(
|
|
68
|
+
column=2,
|
|
69
|
+
padx=10,
|
|
70
|
+
pady=10,
|
|
71
|
+
row=3,
|
|
72
|
+
sticky="nsew")
|
|
73
|
+
buttonfoo.configure(command=self.startfoo)
|
|
74
|
+
label1 = ttk.Label(frame12)
|
|
75
|
+
self.cmdtext = tk.StringVar()
|
|
76
|
+
label1.configure(font="TkFixedFont", textvariable=self.cmdtext)
|
|
77
|
+
label1.grid(column=0, columnspan=2, row=8, sticky="ew")
|
|
78
|
+
separator1 = ttk.Separator(frame12)
|
|
79
|
+
separator1.configure(orient="horizontal")
|
|
80
|
+
separator1.grid(column=0, columnspan=2, row=7, sticky="ew")
|
|
81
|
+
checkbutton1 = ttk.Checkbutton(frame12)
|
|
82
|
+
self.mergesubfoldermode = tk.BooleanVar()
|
|
83
|
+
self.mergesubfoldermode.set(True)
|
|
84
|
+
checkbutton1.configure(
|
|
85
|
+
state="normal",
|
|
86
|
+
text='Subfolder Mode',
|
|
87
|
+
variable=self.mergesubfoldermode)
|
|
88
|
+
checkbutton1.grid(column=1, row=2, sticky="w")
|
|
89
|
+
frame12.grid(column=0, columnspan=2, row=1, sticky="nsew")
|
|
90
|
+
frame12.rowconfigure(0, pad=10)
|
|
91
|
+
frame12.rowconfigure(6, weight=1)
|
|
92
|
+
frame12.rowconfigure("all", pad=10)
|
|
93
|
+
frame12.columnconfigure(0, pad=10)
|
|
94
|
+
frame12.columnconfigure(1, weight=1)
|
|
95
|
+
self.frame_merge.grid(column=0, row=0, sticky="nsew")
|
|
96
|
+
self.frame_merge.rowconfigure(0, pad=10)
|
|
97
|
+
self.frame_merge.rowconfigure(1, weight=1)
|
|
98
|
+
self.frame_merge.columnconfigure(0, pad=10)
|
|
99
|
+
self.frame_merge.columnconfigure(1, weight=1)
|
|
100
|
+
self.notebook.add(
|
|
101
|
+
self.frame_merge,
|
|
102
|
+
state="normal",
|
|
103
|
+
sticky="nsew",
|
|
104
|
+
text='merge')
|
|
105
|
+
self.frame_createsubdirs = ttk.Frame(self.notebook)
|
|
106
|
+
self.frame_createsubdirs.configure(height=200, width=200)
|
|
107
|
+
label15 = ttk.Label(self.frame_createsubdirs)
|
|
108
|
+
label15.configure(state="normal", text='Working Directory:')
|
|
109
|
+
label15.grid(column=0, row=0)
|
|
110
|
+
entry7 = ttk.Entry(self.frame_createsubdirs)
|
|
111
|
+
entry7.configure(textvariable=self.workingdir)
|
|
112
|
+
entry7.grid(column=1, row=0, sticky="ew")
|
|
113
|
+
frame14 = ttk.Frame(self.frame_createsubdirs)
|
|
114
|
+
frame14.configure(height=200, padding=5, relief="sunken", width=200)
|
|
115
|
+
label16 = ttk.Label(frame14)
|
|
116
|
+
label16.configure(text='Command parameters:')
|
|
117
|
+
label16.grid(column=0, columnspan=2, row=0, sticky="ew")
|
|
118
|
+
label17 = ttk.Label(frame14)
|
|
119
|
+
label17.configure(text='Directory:')
|
|
120
|
+
label17.grid(column=0, row=1, sticky="e")
|
|
121
|
+
label18 = ttk.Label(frame14)
|
|
122
|
+
label18.configure(state="normal", takefocus=False, text='Group Size:')
|
|
123
|
+
label18.grid(column=0, row=2, sticky="e")
|
|
124
|
+
label19 = ttk.Label(frame14)
|
|
125
|
+
label19.configure(text='File Filter:')
|
|
126
|
+
label19.grid(column=0, row=3, sticky="e")
|
|
127
|
+
entry9 = ttk.Entry(frame14)
|
|
128
|
+
self.createdir = tk.StringVar(value='.')
|
|
129
|
+
entry9.configure(textvariable=self.createdir)
|
|
130
|
+
_text_ = '.'
|
|
131
|
+
entry9.delete("0", "end")
|
|
132
|
+
entry9.insert("0", _text_)
|
|
133
|
+
entry9.grid(column=1, row=1, sticky="ew")
|
|
134
|
+
entry10 = ttk.Entry(frame14)
|
|
135
|
+
self.creategroupsize = tk.StringVar(value='15')
|
|
136
|
+
entry10.configure(textvariable=self.creategroupsize)
|
|
137
|
+
_text_ = '15'
|
|
138
|
+
entry10.delete("0", "end")
|
|
139
|
+
entry10.insert("0", _text_)
|
|
140
|
+
entry10.grid(column=1, row=2, sticky="ew")
|
|
141
|
+
entry11 = ttk.Entry(frame14)
|
|
142
|
+
self.createfilefilter = tk.StringVar(value='.mp3')
|
|
143
|
+
entry11.configure(textvariable=self.createfilefilter)
|
|
144
|
+
_text_ = '.mp3'
|
|
145
|
+
entry11.delete("0", "end")
|
|
146
|
+
entry11.insert("0", _text_)
|
|
147
|
+
entry11.grid(column=1, row=3, sticky="ew")
|
|
148
|
+
button2 = ttk.Button(frame14)
|
|
149
|
+
button2.configure(text='Start Script')
|
|
150
|
+
button2.grid(
|
|
151
|
+
column=0,
|
|
152
|
+
columnspan=2,
|
|
153
|
+
padx=10,
|
|
154
|
+
pady=10,
|
|
155
|
+
row=5,
|
|
156
|
+
sticky="nsew")
|
|
157
|
+
button2.configure(command=self.startscript)
|
|
158
|
+
label2 = ttk.Label(frame14)
|
|
159
|
+
label2.configure(font="TkFixedFont", textvariable=self.cmdtext)
|
|
160
|
+
label2.grid(column=0, columnspan=2, row=8, sticky="ew")
|
|
161
|
+
separator2 = ttk.Separator(frame14)
|
|
162
|
+
separator2.configure(orient="horizontal")
|
|
163
|
+
separator2.grid(column=0, columnspan=2, row=7, sticky="ew")
|
|
164
|
+
checkbutton2 = ttk.Checkbutton(frame14)
|
|
165
|
+
self.createcopymode = tk.BooleanVar()
|
|
166
|
+
checkbutton2.configure(
|
|
167
|
+
state="normal",
|
|
168
|
+
text='Copy Mode',
|
|
169
|
+
variable=self.createcopymode)
|
|
170
|
+
checkbutton2.grid(column=1, row=4, sticky="w")
|
|
171
|
+
frame14.grid(column=0, columnspan=2, row=1, sticky="nsew")
|
|
172
|
+
frame14.rowconfigure(0, pad=10)
|
|
173
|
+
frame14.rowconfigure(6, weight=1)
|
|
174
|
+
frame14.rowconfigure("all", pad=10)
|
|
175
|
+
frame14.columnconfigure(0, pad=10)
|
|
176
|
+
frame14.columnconfigure(1, weight=1)
|
|
177
|
+
self.frame_createsubdirs.grid(column=0, row=0, sticky="nsew")
|
|
178
|
+
self.frame_createsubdirs.rowconfigure(0, pad=10)
|
|
179
|
+
self.frame_createsubdirs.rowconfigure(1, weight=1)
|
|
180
|
+
self.frame_createsubdirs.columnconfigure(0, pad=10)
|
|
181
|
+
self.frame_createsubdirs.columnconfigure(1, pad=10, weight=1)
|
|
182
|
+
self.notebook.add(
|
|
183
|
+
self.frame_createsubdirs,
|
|
184
|
+
sticky="nsew",
|
|
185
|
+
text='create subdirs')
|
|
186
|
+
self.frame_removesubdirs = ttk.Frame(self.notebook)
|
|
187
|
+
self.frame_removesubdirs.configure(height=200, width=200)
|
|
188
|
+
label22 = ttk.Label(self.frame_removesubdirs)
|
|
189
|
+
label22.configure(state="normal", text='Working Directory:')
|
|
190
|
+
label22.grid(column=0, row=0)
|
|
191
|
+
entry13 = ttk.Entry(self.frame_removesubdirs)
|
|
192
|
+
entry13.configure(textvariable=self.workingdir)
|
|
193
|
+
entry13.grid(column=1, row=0, sticky="ew")
|
|
194
|
+
frame16 = ttk.Frame(self.frame_removesubdirs)
|
|
195
|
+
frame16.configure(height=200, padding=5, relief="sunken", width=200)
|
|
196
|
+
label23 = ttk.Label(frame16)
|
|
197
|
+
label23.configure(text='Command parameters:')
|
|
198
|
+
label23.grid(column=0, columnspan=2, row=0, sticky="ew")
|
|
199
|
+
label24 = ttk.Label(frame16)
|
|
200
|
+
label24.configure(text='Directory:')
|
|
201
|
+
label24.grid(column=0, row=1, sticky="e")
|
|
202
|
+
label25 = ttk.Label(frame16)
|
|
203
|
+
label25.configure(justify="left", text='Subfolder Filter:')
|
|
204
|
+
label25.grid(column=0, row=2, sticky="e")
|
|
205
|
+
label26 = ttk.Label(frame16)
|
|
206
|
+
label26.configure(text='File Filter:')
|
|
207
|
+
label26.grid(column=0, row=3, sticky="e")
|
|
208
|
+
entry15 = ttk.Entry(frame16)
|
|
209
|
+
self.removedir = tk.StringVar(value='.')
|
|
210
|
+
entry15.configure(textvariable=self.removedir)
|
|
211
|
+
_text_ = '.'
|
|
212
|
+
entry15.delete("0", "end")
|
|
213
|
+
entry15.insert("0", _text_)
|
|
214
|
+
entry15.grid(column=1, row=1, sticky="ew")
|
|
215
|
+
entry16 = ttk.Entry(frame16)
|
|
216
|
+
self.removesubfolderfilter = tk.StringVar(value='*')
|
|
217
|
+
entry16.configure(textvariable=self.removesubfolderfilter)
|
|
218
|
+
_text_ = '*'
|
|
219
|
+
entry16.delete("0", "end")
|
|
220
|
+
entry16.insert("0", _text_)
|
|
221
|
+
entry16.grid(column=1, row=2, sticky="ew")
|
|
222
|
+
entry17 = ttk.Entry(frame16)
|
|
223
|
+
self.removefilefilter = tk.StringVar(value='.mp3')
|
|
224
|
+
entry17.configure(textvariable=self.removefilefilter)
|
|
225
|
+
_text_ = '.mp3'
|
|
226
|
+
entry17.delete("0", "end")
|
|
227
|
+
entry17.insert("0", _text_)
|
|
228
|
+
entry17.grid(column=1, row=3, sticky="ew")
|
|
229
|
+
button3 = ttk.Button(frame16)
|
|
230
|
+
button3.configure(text='Start Script')
|
|
231
|
+
button3.grid(
|
|
232
|
+
column=0,
|
|
233
|
+
columnspan=2,
|
|
234
|
+
padx=10,
|
|
235
|
+
pady=10,
|
|
236
|
+
row=6,
|
|
237
|
+
sticky="nsew")
|
|
238
|
+
button3.configure(command=self.startscript)
|
|
239
|
+
label4 = ttk.Label(frame16)
|
|
240
|
+
label4.configure(font="TkFixedFont", textvariable=self.cmdtext)
|
|
241
|
+
label4.grid(column=0, columnspan=2, row=9, sticky="ew")
|
|
242
|
+
separator3 = ttk.Separator(frame16)
|
|
243
|
+
separator3.configure(orient="horizontal")
|
|
244
|
+
separator3.grid(column=0, columnspan=2, row=8, sticky="ew")
|
|
245
|
+
checkbutton3 = ttk.Checkbutton(frame16)
|
|
246
|
+
self.removecopymode = tk.BooleanVar()
|
|
247
|
+
checkbutton3.configure(text='Copy Mode', variable=self.removecopymode)
|
|
248
|
+
checkbutton3.grid(column=1, row=4, sticky="w")
|
|
249
|
+
checkbutton4 = ttk.Checkbutton(frame16)
|
|
250
|
+
self.removeemptySubfolder = tk.BooleanVar()
|
|
251
|
+
self.removeemptySubfolder.set(True)
|
|
252
|
+
checkbutton4.configure(
|
|
253
|
+
text='Remove Empty Subfolders',
|
|
254
|
+
variable=self.removeemptySubfolder)
|
|
255
|
+
checkbutton4.grid(column=1, row=5, sticky="w")
|
|
256
|
+
frame16.grid(column=0, columnspan=2, row=1, sticky="nsew")
|
|
257
|
+
frame16.rowconfigure(0, pad=10)
|
|
258
|
+
frame16.rowconfigure(7, weight=1)
|
|
259
|
+
frame16.rowconfigure("all", pad=10)
|
|
260
|
+
frame16.columnconfigure(0, pad=10)
|
|
261
|
+
frame16.columnconfigure(1, weight=1)
|
|
262
|
+
self.frame_removesubdirs.grid(column=0, row=0, sticky="nsew")
|
|
263
|
+
self.frame_removesubdirs.rowconfigure(0, pad=10)
|
|
264
|
+
self.frame_removesubdirs.rowconfigure(1, weight=1)
|
|
265
|
+
self.frame_removesubdirs.columnconfigure(0, pad=10)
|
|
266
|
+
self.frame_removesubdirs.columnconfigure(1, pad=10, weight=1)
|
|
267
|
+
self.notebook.add(
|
|
268
|
+
self.frame_removesubdirs,
|
|
269
|
+
sticky="nsew",
|
|
270
|
+
text='remove subdirs')
|
|
271
|
+
self.notebook.grid(column=0, row=0)
|
|
272
|
+
self.notebook.bind(
|
|
273
|
+
"<<NotebookTabChanged>>",
|
|
274
|
+
self.updateCommand,
|
|
275
|
+
add="")
|
|
276
|
+
|
|
277
|
+
# Main widget
|
|
278
|
+
self.mainwindow = self.notebook
|
|
279
|
+
|
|
280
|
+
def run(self):
|
|
281
|
+
self.mainwindow.mainloop()
|
|
282
|
+
|
|
283
|
+
def startscript(self):
|
|
284
|
+
self.updateCommand()
|
|
285
|
+
os.chdir(self.workingdir.get())
|
|
286
|
+
subprocess.Popen(self.cmdtext.get())
|
|
287
|
+
|
|
288
|
+
def startfoo(self):
|
|
289
|
+
foobarpath = self.mergefoobarpath.get()
|
|
290
|
+
if self.mergefoobarpath.get() == ".":
|
|
291
|
+
foobarpath = "C:/Program Files (x86)/foobar2000/foobar2000.exe"
|
|
292
|
+
subprocess.Popen(foobarpath)
|
|
293
|
+
|
|
294
|
+
def updateCommand(self, event=None):
|
|
295
|
+
tabtext = self.notebook.tab(self.notebook.select(), "text")
|
|
296
|
+
if tabtext == "merge":
|
|
297
|
+
self.cmdtext.set("mp3tools merge-mp3"
|
|
298
|
+
+ " " + self.mergedir.get()
|
|
299
|
+
+ " " + str(self.mergesubfoldermode.get())
|
|
300
|
+
+ " " + self.mergefoobarpath.get()
|
|
301
|
+
+ " " + str(self.mergewaittime.get())
|
|
302
|
+
)
|
|
303
|
+
if tabtext == "create subdirs":
|
|
304
|
+
self.cmdtext.set("mp3tools pack-subdirs"
|
|
305
|
+
+ " " + str(self.creategroupsize.get())
|
|
306
|
+
+ " " + self.createdir.get()
|
|
307
|
+
+ " " + self.createfilefilter.get()
|
|
308
|
+
+ " " + str(self.createcopymode.get())
|
|
309
|
+
)
|
|
310
|
+
if tabtext == "remove subdirs":
|
|
311
|
+
self.cmdtext.set("mp3tools unpack-subdirs"
|
|
312
|
+
+ " " + self.removedir.get()
|
|
313
|
+
+ " " + self.removesubfolderfilter.get()
|
|
314
|
+
+ " " + self.removefilefilter.get()
|
|
315
|
+
+ " " + str(self.removecopymode.get())
|
|
316
|
+
+ " " + str(self.removeemptySubfolder.get())
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
if __name__ == "__main__":
|
|
320
|
+
root = tk.Tk()
|
|
321
|
+
app = GuiMp3ToolsApp(root)
|
|
322
|
+
root.title("mp3tool")
|
|
323
|
+
app.run()
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mp3tools
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Awesome mp3tools created by carsten-engelke
|
|
5
5
|
Home-page: https://github.com/carsten-engelke/mp3tools/
|
|
6
6
|
Author: carsten-engelke
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: autopep8>=1
|
|
10
|
-
Requires-Dist: natsort>=7
|
|
11
10
|
Requires-Dist: pycodestyle>=2
|
|
12
11
|
Requires-Dist: pynput>=1
|
|
13
12
|
Requires-Dist: six>=1
|
|
@@ -21,17 +20,27 @@ Requires-Dist: pytest-cov; extra == "test"
|
|
|
21
20
|
Requires-Dist: mypy; extra == "test"
|
|
22
21
|
Requires-Dist: gitchangelog; extra == "test"
|
|
23
22
|
Requires-Dist: mkdocs; extra == "test"
|
|
23
|
+
Dynamic: author
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: provides-extra
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: summary
|
|
24
31
|
|
|
25
32
|
# mp3tools
|
|
26
33
|
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.
|
|
27
34
|
|
|
28
35
|
|
|
29
|
-

|
|
30
|
-
- merge-mp3
|
|
31
|
-
- pack-subdirs
|
|
32
|
-
- unpack-subdirs.py: unpack files from grouped subdirectories (undo pack-subdirs
|
|
36
|
+

|
|
37
|
+
- mp3tools merge-mp3: merging script, works with foobar2000
|
|
38
|
+
- mp3tools pack-subdirs: pack files into grouped subdirectories (good for large audiobooks)
|
|
39
|
+
- mp3tools unpack-subdirs.py: unpack files from grouped subdirectories (undo mp3tools pack-subdirs)
|
|
33
40
|
|
|
34
41
|
## Version
|
|
42
|
+
1.2.2 Fixed
|
|
43
|
+
|
|
35
44
|
1.2.0 Added PI/CI Support thanks to https://github.com/rochacbruno/python-project-template
|
|
36
45
|
|
|
37
46
|
1.0.0 release version. Ported to vscode.
|
|
@@ -45,24 +54,26 @@ Merge mp3 files and set correct audio length using foobar2000 with an automated
|
|
|
45
54
|
- foobar2000 (https://www.foobar2000.org/)
|
|
46
55
|
|
|
47
56
|
## Installation
|
|
48
|
-
|
|
49
|
-
- run the script and follow the instructions, alternatively use the following command line
|
|
57
|
+
pip install mp3tools
|
|
50
58
|
|
|
59
|
+
## Usage
|
|
51
60
|
Command-line-use:
|
|
52
61
|
```
|
|
53
|
-
|
|
62
|
+
mp3tools -> start tools using standard wizard, just follow instructions.
|
|
63
|
+
|
|
64
|
+
mp3tools merge-mp3 [dir] [subdir-mode] [foobarpath] [autowaittime]
|
|
54
65
|
[dir] determines the directory in which to perform. Use '.' to select the current directory
|
|
55
|
-
[
|
|
66
|
+
[subdir-mode] determines wheter all mp3 files in subfolders should be merged into one file each. ('True' to do so)")
|
|
56
67
|
[foobarpath] determines the path to your foobar2000 installation. Please provide in case it differs from 'C:/Program Files (x86)/foobar2000/foobar2000.exe'
|
|
57
|
-
[autowaittime] determines whether to automatically
|
|
68
|
+
[autowaittime] determines whether to automatically close foobar2000 after some seconds. Use -1 to disable and any number to set the waiting time.
|
|
58
69
|
|
|
59
|
-
|
|
70
|
+
mp3tools pack-subdirs [group-size] [dir] [file-filter] [copy-mode]
|
|
60
71
|
[group-size] determines the number of files to put into each directory
|
|
61
72
|
[dir] determines the directory in which to perform the script. Use '.' to select the current directory
|
|
62
|
-
[filter] Filter the file list according to this
|
|
73
|
+
[file-filter] Filter the file list according to this
|
|
63
74
|
[copy-mode] If 'True', the files are copied into the created subfolders. If 'False' they are moved (Use with caution).
|
|
64
75
|
|
|
65
|
-
|
|
76
|
+
mp3tools unpack-subdirs [dir] [subdir-filter] [filter] [copy-mode] [remove-dir]")
|
|
66
77
|
[dir] determines the directory in which to perform the script. Use '.' to select the current directory
|
|
67
78
|
[subdir-filter] Filter the subdir list according to this. Use '*' to select any subdirectory
|
|
68
79
|
[filter] Filter the file list according to this
|
mp3tools-1.2.0/mp3tools/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.2.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|