got_mp3 0.1.2 → 0.3.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/got_mp3.rb +229 -8
- data.tar.gz.sig +0 -0
- metadata +24 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c34d1db35e8baadaaf24b2fa70f3598a64ec38ddd47095188a82eae76e063573
|
4
|
+
data.tar.gz: 86bb8da65ce447a7bbd168b068cc9b992b551b0db201eac8a3e2949fdc1d5dba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c666482d88a53d4e608316cbbbe83dd8b7b2c1fed9d725f666fdbf0c32c4e20ff809e5a2a51f72f87cf63659dc94f3f1bf5420b823bbebb0638b7e95781bcfe
|
7
|
+
data.tar.gz: f6508835a0db94da8febc2d301ed40ab8b490caf17caf74af73c46418e0ffddb80142a3c24f8a82ca157a355bec0fa792cb6b813af9ae8dcf3c66ac350c702d4
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/got_mp3.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
# file: got_mp3.rb
|
4
4
|
|
5
|
+
require 'dxlite'
|
6
|
+
require 'ostruct'
|
5
7
|
require "mp3info"
|
6
8
|
|
7
9
|
|
@@ -21,6 +23,8 @@ class GotMP3
|
|
21
23
|
def add_jpg()
|
22
24
|
|
23
25
|
find_by_ext('.jpg').each do |directory, img_filename|
|
26
|
+
|
27
|
+
puts 'add_jpg to directory: ' + directory.inspect if @debug
|
24
28
|
add_image directory, img_filename
|
25
29
|
end
|
26
30
|
|
@@ -40,7 +44,71 @@ class GotMP3
|
|
40
44
|
|
41
45
|
end
|
42
46
|
|
43
|
-
#
|
47
|
+
# copy all MP3 directories through the category file-directory stucture
|
48
|
+
#
|
49
|
+
def compile(source_directory: '', target_directory: '')
|
50
|
+
|
51
|
+
raise 'target_directory cannot be empty' if target_directory.empty?
|
52
|
+
|
53
|
+
find_by_ext('.txt').each do |directory, _ |
|
54
|
+
|
55
|
+
Dir[File.join(directory, '*.txt')].each do |txt_filename|
|
56
|
+
|
57
|
+
album = File.join(source_directory,
|
58
|
+
File.basename(txt_filename).sub(/\.txt$/,''))
|
59
|
+
library_dir = File.join(target_directory, File.basename(directory))
|
60
|
+
FileUtils.mkdir_p library_dir
|
61
|
+
|
62
|
+
if @debug then
|
63
|
+
puts 'copying from:' + album.inspect
|
64
|
+
puts 'copying to: ' + library_dir.inspect
|
65
|
+
end
|
66
|
+
|
67
|
+
puts 'copying ' + album + ' ...'
|
68
|
+
FileUtils.cp_r album, library_dir, remove_destination: true
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def consolidate_txt(target_directory: '')
|
76
|
+
|
77
|
+
raise 'target_directory cannot be empty' if target_directory.empty?
|
78
|
+
|
79
|
+
find_by_ext('.mp3').each do |directory, _ |
|
80
|
+
|
81
|
+
txt_filename = Dir[File.join(directory, '*.txt')].first
|
82
|
+
|
83
|
+
next unless txt_filename
|
84
|
+
|
85
|
+
target_file = File.basename(directory)
|
86
|
+
FileUtils.cp txt_filename, File.join(target_directory,
|
87
|
+
target_file + '.txt')
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
def each_mp3_file(directory='.', &blk)
|
94
|
+
|
95
|
+
puts 'each_mp3 - directory: ' + directory.inspect if @debug
|
96
|
+
found = Dir[File.join(directory, "*.mp3")].sort_by { |x| File.mtime(x) }
|
97
|
+
puts 'each_mp3 - found: ' + found.inspect if @debug
|
98
|
+
|
99
|
+
found.reverse.each.with_index do |mp3_filepath, i|
|
100
|
+
|
101
|
+
puts 'each_mp3 - mp3_filepath: ' + mp3_filepath.inspect if @debug
|
102
|
+
|
103
|
+
next unless File.exists? mp3_filepath
|
104
|
+
|
105
|
+
blk.call(mp3_filepath, i )
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
# Adds the album art, track title, renames the MP3 file, and adds a playlist
|
44
112
|
#
|
45
113
|
def go()
|
46
114
|
|
@@ -48,6 +116,7 @@ class GotMP3
|
|
48
116
|
|
49
117
|
# find the image file
|
50
118
|
img_filename = Dir[File.join(directory, '*.jpg')].first
|
119
|
+
puts 'img_filename: ' + img_filename.inspect if @debug
|
51
120
|
|
52
121
|
# find the text file
|
53
122
|
txt_filename = Dir[File.join(directory, '*.txt')].first
|
@@ -59,16 +128,110 @@ class GotMP3
|
|
59
128
|
|
60
129
|
end
|
61
130
|
|
131
|
+
# rename 1 or more mp3 files within 1 or more file directories
|
132
|
+
#
|
133
|
+
# example usage:
|
134
|
+
# rename() {|mp3file| mp3files.sub(/Disc \d - /,'')}
|
135
|
+
# rename() {|mp3file| mp3file.sub(/Disc \d - (\d+) - /,'\1. ')}
|
136
|
+
#
|
137
|
+
def rename()
|
138
|
+
|
139
|
+
each_mp3_file do |mp3_filepath|
|
140
|
+
|
141
|
+
mp3_directory = File.dirname(mp3_filepath)
|
142
|
+
mp3_filename = File.basename(mp3_filepath)
|
143
|
+
|
144
|
+
newname = yield(mp3_filename)
|
145
|
+
File.rename(mp3_filepath, File.join(mp3_directory, newname))
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
def write_titles(format: 'txt')
|
152
|
+
|
153
|
+
puts 'inside write_titles()' if @debug
|
154
|
+
|
155
|
+
find_by_ext('.mp3').each do |directory, _ |
|
156
|
+
|
157
|
+
puts 'write_titles() - directory: ' + directory.inspect if @debug
|
158
|
+
txt_filename = Dir[File.join(directory, '*.txt')].first
|
159
|
+
|
160
|
+
next if txt_filename and format.to_sym == :txt
|
161
|
+
|
162
|
+
tracks = []
|
163
|
+
|
164
|
+
each_mp3_track(directory) do |mp3, trackno, mp3_filepath|
|
165
|
+
|
166
|
+
tracks << OpenStruct.new({
|
167
|
+
title: mp3.tag.title.sub(/^\d+\. */,''),
|
168
|
+
artist: mp3.tag.artist,
|
169
|
+
album: mp3.tag.album,
|
170
|
+
album_artist: mp3.tag2['TPE2'] || mp3.tag.artist,
|
171
|
+
disc: mp3.tag2['TPOS'] || 1,
|
172
|
+
tracknum: mp3.tag.tracknum,
|
173
|
+
filename: File.basename(mp3_filepath)
|
174
|
+
})
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
puts 'tracks: ' + tracks.inspect if @debug
|
179
|
+
|
180
|
+
heading = tracks[0].album_artist + ' - ' + tracks[0].album
|
181
|
+
|
182
|
+
s = "# %s\n\n" % [heading]
|
183
|
+
h = tracks.group_by(&:disc)
|
184
|
+
|
185
|
+
|
186
|
+
if format.to_sym == :txt then
|
187
|
+
|
188
|
+
body = if h.length == 1 then
|
189
|
+
|
190
|
+
list(tracks)
|
191
|
+
|
192
|
+
else
|
193
|
+
|
194
|
+
"\n" + h.map do |disc, tracks2|
|
195
|
+
("## Disc %d\n\n" % disc) + list(tracks2) + "\n\n"
|
196
|
+
end.join("\n")
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
File.write File.join(directory, heading + '.txt'), s + body
|
201
|
+
|
202
|
+
else
|
203
|
+
|
204
|
+
# :xml
|
205
|
+
puts 'xml' if @debug
|
206
|
+
|
207
|
+
dx = DxLite.new('album[album_artist, album]/track(tracknum, title, ' +
|
208
|
+
'artist, disc, album_artist)')
|
209
|
+
|
210
|
+
h.each {|_,x| puts x.inspect } if @debug
|
211
|
+
h.each {|_,x| x.each {|track| dx.create(track.to_h) } }
|
212
|
+
|
213
|
+
dx.album_artist = dx.all[0].album_artist
|
214
|
+
dx.album = dx.all[0].album
|
215
|
+
dx.save File.join(directory, 'playlist.dx')
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
62
223
|
private
|
63
224
|
|
64
225
|
# adds album art to each mp3 file in a file directory
|
65
226
|
#
|
66
227
|
def add_image(directory, img_filename)
|
67
228
|
|
229
|
+
puts 'inside add_image - directory: ' + directory.inspect if @debug
|
230
|
+
puts 'img_filename: ' + img_filename.inspect if @debug
|
68
231
|
image_file = File.new(File.join(directory, img_filename),'rb')
|
69
232
|
img = image_file.read
|
70
233
|
|
71
|
-
|
234
|
+
each_mp3_track(directory) do |mp3, _, _|
|
72
235
|
|
73
236
|
mp3.tag2.remove_pictures
|
74
237
|
mp3.tag2.add_picture img
|
@@ -82,7 +245,7 @@ class GotMP3
|
|
82
245
|
txt_file = File.join(directory, txt_filename)
|
83
246
|
track_titles = File.read(txt_file).lines[1..-1].map(&:strip)
|
84
247
|
|
85
|
-
|
248
|
+
each_mp3_track(directory) do |mp3, trackno, _|
|
86
249
|
|
87
250
|
mp3.tag.title = track_titles[trackno-1]
|
88
251
|
|
@@ -97,6 +260,10 @@ class GotMP3
|
|
97
260
|
|
98
261
|
track_titles = File.read(txt_file).lines[1..-1].map(&:strip)
|
99
262
|
|
263
|
+
titles_mp3 = track_titles.map do |title|
|
264
|
+
title[/^[^\/]+/].gsub(/:/,'_').rstrip + '.mp3'
|
265
|
+
end
|
266
|
+
|
100
267
|
found = Dir[File.join(directory, "*.mp3")].sort_by { |x| File.mtime(x) }
|
101
268
|
found.each.with_index do |mp3_filepath, i|
|
102
269
|
|
@@ -110,16 +277,17 @@ class GotMP3
|
|
110
277
|
mp3.tag.title = track_titles[i]
|
111
278
|
end
|
112
279
|
|
113
|
-
File.rename(mp3_filepath, File.join(directory,
|
114
|
-
|
280
|
+
File.rename(mp3_filepath, File.join(directory, titles_mp3[i]))
|
281
|
+
|
115
282
|
end
|
116
283
|
|
284
|
+
File.write File.join(directory, 'playlist.m3u'), titles_mp3.join("\n")
|
285
|
+
|
117
286
|
end
|
118
287
|
|
119
|
-
def
|
288
|
+
def each_mp3_track(directory, &blk)
|
120
289
|
|
121
|
-
|
122
|
-
found.each.with_index do |mp3_filepath, i|
|
290
|
+
each_mp3_file(directory) do |mp3_filepath, i|
|
123
291
|
|
124
292
|
Mp3Info.open(mp3_filepath) {|mp3| blk.call(mp3, i+1, mp3_filepath) }
|
125
293
|
|
@@ -129,6 +297,7 @@ class GotMP3
|
|
129
297
|
|
130
298
|
def find_by_ext(extension)
|
131
299
|
|
300
|
+
puts 'find_by_ext() - @dir' + @dir.inspect if @debug
|
132
301
|
a = Dir[File.join(@dir, "**", "*" + extension)]
|
133
302
|
puts 'a: ' + a.inspect if @debug
|
134
303
|
|
@@ -140,4 +309,56 @@ class GotMP3
|
|
140
309
|
end
|
141
310
|
end
|
142
311
|
|
312
|
+
def list(tracks)
|
313
|
+
|
314
|
+
a = if tracks.map(&:artist).uniq.length < 2 then
|
315
|
+
tracks.map {|x| "%02d. %s" % [x.tracknum, x.title] }
|
316
|
+
else
|
317
|
+
tracks.map {|x| "%02d. %s - %s" % [x.tracknum, x.title, x.artist] }
|
318
|
+
end
|
319
|
+
|
320
|
+
a.join("\n")
|
321
|
+
|
322
|
+
end
|
323
|
+
|
324
|
+
end
|
325
|
+
|
326
|
+
class Titles
|
327
|
+
|
328
|
+
def initialize(filename, target_directory: 'titles')
|
329
|
+
@titles = File.read filename
|
330
|
+
@target_directory = target_directory
|
331
|
+
end
|
332
|
+
|
333
|
+
def titleize()
|
334
|
+
@titles.gsub(/[\w']+/) {|x| x[0].upcase + x[1..-1]}
|
335
|
+
end
|
336
|
+
|
337
|
+
def titleize!()
|
338
|
+
@titles.gsub!(/[\w']+/) {|x| x[0].upcase + x[1..-1]}
|
339
|
+
end
|
340
|
+
|
341
|
+
def split(target_directory: @target_directory)
|
342
|
+
|
343
|
+
FileUtils.mkdir_p @target_directory
|
344
|
+
a = @titles.strip.split(/(?=^#)/)
|
345
|
+
|
346
|
+
a.each do |x|
|
347
|
+
|
348
|
+
filename = x.lines.first.chomp[/(?<=# cd ).*/i].strip + '.txt'
|
349
|
+
puts 'processing file ' + filename.inspect
|
350
|
+
heading = x.lstrip.lines.first
|
351
|
+
|
352
|
+
tracks = x.strip.lines[1..-1].map.with_index do |line, i|
|
353
|
+
"%02d. %s" % [i+1, line]
|
354
|
+
end
|
355
|
+
|
356
|
+
File.write File.join(target_directory, filename), heading + tracks.join
|
357
|
+
|
358
|
+
end
|
359
|
+
|
360
|
+
puts 'split done'
|
361
|
+
|
362
|
+
end
|
363
|
+
|
143
364
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: got_mp3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,8 +35,28 @@ cert_chain:
|
|
35
35
|
RFrZsrDO1Cwk4v03qCUvuZ8H/nCojYYJGMrJE1JhBBJNJXCAULivh/zlOYcDhG69
|
36
36
|
uPtZOD7YKrG45OftX8aNxlNv
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2021-11-
|
38
|
+
date: 2021-11-27 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: dxlite
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.3'
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.3.5
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - "~>"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0.3'
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 0.3.5
|
40
60
|
- !ruby/object:Gem::Dependency
|
41
61
|
name: ruby-mp3info
|
42
62
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,6 +107,6 @@ rubyforge_project:
|
|
87
107
|
rubygems_version: 2.7.10
|
88
108
|
signing_key:
|
89
109
|
specification_version: 4
|
90
|
-
summary: A ruby-mp3info wrapper to make it convenient to update the
|
91
|
-
MP3 files
|
110
|
+
summary: A ruby-mp3info wrapper to make it convenient to update the album art and
|
111
|
+
track titles of multiple MP3 files in a batch process.
|
92
112
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|