got_mp3 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/got_mp3.rb +235 -32
  4. data.tar.gz.sig +0 -0
  5. metadata +63 -3
  6. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94d8fc924be742f45265ce5ced2836859ad920e2813294107861e9530ce00ab0
4
- data.tar.gz: c60a80063c720c5a97a6cd0dc994688e9c6227c462c4bd857dc51307af2143c4
3
+ metadata.gz: a109d9369982eb251b2439256a7ab8ecb0494f8b693efeb869ed6e29329d23e4
4
+ data.tar.gz: 960ba30e1ab1178b77280f9f6068248cb82616040caa2fca2880dcccc78c1af0
5
5
  SHA512:
6
- metadata.gz: dc555a1313236f60e25892afbee007b6a2953b35c7a7c36ceeb0acf36865315b181a70d748c243b3c7385e2d5bb547a36742884465877bfc3796bd16a11b00af
7
- data.tar.gz: e07d01081c5002073e8f147559cc19022ce326d438698808d004eaff62bd35c1095139e3ccd0a91971caeade73993b6f5505ed967561458e3d660fed2edc0f86
6
+ metadata.gz: 8777628c7ec8d16460fe3ff59199b98bf34bf10494ffdb22afd432cb1f7110591bd48370998f4bc4757f9564d3b4a190ec03537e03d2f9c7cecd01b0ddafe744
7
+ data.tar.gz: 7c9b29dc4e6e889644c2cfef6464fcb09fb34ead8101670a7f08942344132994099444a144b5ee5a24e9f76d1c176f595837845accd9a6ef8efb1ff269994e80
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/got_mp3.rb CHANGED
@@ -2,12 +2,17 @@
2
2
 
3
3
  # file: got_mp3.rb
4
4
 
5
+ require 'dxlite'
5
6
  require 'ostruct'
6
- require "mp3info"
7
+ require 'mp3info'
8
+ require 'ogginfo'
9
+ require 'playlist_creator'
7
10
 
8
11
 
9
12
  class GotMP3
10
13
 
14
+ attr_accessor :dir
15
+
11
16
  def initialize(dir: '.', debug: false)
12
17
  @dir, @debug = dir, debug
13
18
  end
@@ -22,6 +27,8 @@ class GotMP3
22
27
  def add_jpg()
23
28
 
24
29
  find_by_ext('.jpg').each do |directory, img_filename|
30
+
31
+ puts 'add_jpg to directory: ' + directory.inspect if @debug
25
32
  add_image directory, img_filename
26
33
  end
27
34
 
@@ -41,12 +48,118 @@ class GotMP3
41
48
 
42
49
  end
43
50
 
44
- def each_mp3_file(directory='.', &blk)
51
+ # Adds an XSPF playlist file to each file directory containing MP3s
52
+ #
53
+ def add_playlist(dir: @dir)
45
54
 
46
- found = Dir[File.join(directory, "*.mp3")].sort_by { |x| File.mtime(x) }
47
- found.each.with_index do |mp3_filepath, i|
55
+ # .new('/home/james/Music2/Christmas)
56
+ #mp3s = Dir[File.join(@dir, '*.mp3')].sort_by {|x| File.mtime(x)}.reverse
57
+ a = Dir.glob(File.join(dir, '*')).select {|f| File.directory? f}
58
+
59
+ tracks = []
60
+
61
+ a.each do |dir|
62
+
63
+ tracks += add_playlist(dir: dir)
64
+
65
+ each_media_track(dir) do |media, trackno, filepath|
66
+
67
+ info = case File.extname(filepath)
68
+ when '.mp3'
69
+ mp3info(media)
70
+ when '.ogg'
71
+ ogginfo(media)
72
+ end
73
+
74
+ h = {
75
+ title: info[:title],
76
+ location: File.join(File.basename(dir), File.basename(filepath)),
77
+ album: info[:album]
78
+ }
79
+
80
+ tracks << h
81
+
82
+ end
83
+
84
+ end
85
+
86
+
87
+
88
+ pc = PlaylistCreator.new()
89
+
90
+ tracks.each do |x|
91
+ pc.add title: x[:title], location: x[:location], album: x[:album]
92
+ end
93
+
94
+ File.write File.join(dir,'playlist.xspf'), pc.to_xspf
95
+
96
+ return tracks
97
+
98
+ end
99
+
100
+ # Copies all MP3 directories through the category file-directory stucture.
101
+ # To accomplish this, it need a reference (source) directory containing the
102
+ # .txt for each album.
103
+ #
104
+ def compile(source_directory: '', target_directory: '')
105
+
106
+ raise 'target_directory cannot be empty' if target_directory.empty?
48
107
 
49
- blk.call(mp3_filepath, i )
108
+ find_by_ext('.txt').each do |directory, _ |
109
+
110
+ Dir[File.join(directory, '*.txt')].each do |txt_filename|
111
+
112
+ album = File.join(source_directory,
113
+ File.basename(txt_filename).sub(/\.txt$/,''))
114
+ library_dir = File.join(target_directory, File.basename(directory))
115
+ FileUtils.mkdir_p library_dir
116
+
117
+ if @debug then
118
+ puts 'copying from:' + album.inspect
119
+ puts 'copying to: ' + library_dir.inspect
120
+ end
121
+
122
+ puts 'copying ' + album + ' ...'
123
+ FileUtils.cp_r album, library_dir, remove_destination: true
124
+
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+ # copy the .txt file from each mp3 directory into a central file directory
131
+ #
132
+ def consolidate_txt(target_directory: '')
133
+
134
+ raise 'target_directory cannot be empty' if target_directory.empty?
135
+
136
+ find_by_ext('.mp3').each do |directory, _ |
137
+
138
+ txt_filename = Dir[File.join(directory, '*.txt')].first
139
+
140
+ next unless txt_filename
141
+
142
+ target_file = File.basename(directory)
143
+ FileUtils.cp txt_filename, File.join(target_directory,
144
+ target_file + '.txt')
145
+
146
+ end
147
+
148
+ end
149
+
150
+ def each_media_file(directory=@dir, &blk)
151
+
152
+ puts 'each_media_file - directory: ' + directory.inspect if @debug
153
+ found = Dir[File.join(directory, "*.{mp3,ogg}")].sort_by { |x| File.mtime(x) }
154
+ puts 'each_nedia_file - found: ' + found.inspect if @debug
155
+
156
+ found.each.with_index do |media_filepath, i|
157
+
158
+ puts 'each_medi... - media_filepath: ' + media_filepath.inspect if @debug
159
+
160
+ next unless File.exists? media_filepath
161
+
162
+ blk.call(media_filepath, i )
50
163
 
51
164
  end
52
165
 
@@ -60,6 +173,7 @@ class GotMP3
60
173
 
61
174
  # find the image file
62
175
  img_filename = Dir[File.join(directory, '*.jpg')].first
176
+ puts 'img_filename: ' + img_filename.inspect if @debug
63
177
 
64
178
  # find the text file
65
179
  txt_filename = Dir[File.join(directory, '*.txt')].first
@@ -79,7 +193,7 @@ class GotMP3
79
193
  #
80
194
  def rename()
81
195
 
82
- each_mp3_file do |mp3_filepath|
196
+ each_media_file do |mp3_filepath|
83
197
 
84
198
  mp3_directory = File.dirname(mp3_filepath)
85
199
  mp3_filename = File.basename(mp3_filepath)
@@ -91,43 +205,94 @@ class GotMP3
91
205
 
92
206
  end
93
207
 
94
- def write_titles()
208
+ # sort MP3 or OGG by track number in the filename
209
+ #
210
+ def sort_by_tracknum!()
211
+
212
+ each_media_file do |filepath|
95
213
 
96
- find_by_ext('.mp3').each do |directory, _ |
214
+ directory = File.dirname(filepath)
215
+ a = Dir[File.join(directory, '*.{mp3,ogg}')]
216
+ a.sort_by {|x| x[/^\d+/]}.each {|file| FileUtils.touch file}
217
+
218
+ end
219
+
220
+ end
221
+
222
+ # write either a track listing into the media filepath, either in
223
+ # plain text or XML format.
224
+ #
225
+ def write_titles(format: 'txt')
226
+
227
+ puts 'inside write_titles()' if @debug
228
+
229
+ find_by_ext('.{mp3,ogg}').each do |directory, _ |
230
+
231
+ puts 'write_titles() - directory: ' + directory.inspect if @debug
232
+ txt_filename = Dir[File.join(directory, '*.txt')].first
233
+
234
+ next if txt_filename and format.to_sym == :txt
97
235
 
98
236
  tracks = []
99
237
 
100
- each_mp3_track(directory) do |mp3, trackno, mp3_filepath|
238
+ each_media_track(directory) do |media, trackno, media_filepath|
239
+
240
+ info = case File.extname(media_filepath)
241
+ when '.mp3'
242
+ mp3info(media)
243
+ when '.ogg'
244
+ ogginfo(media)
245
+ end
101
246
 
102
- tracks << OpenStruct.new({
103
- title: mp3.tag.title,
104
- artist: mp3.tag.artist,
105
- album: mp3.tag.album,
106
- album_artist: mp3.tag2['TPE2'],
107
- disc: mp3.tag2['TPOS'],
108
- tracknum: mp3.tag.tracknum,
109
- filename: File.basename(mp3_filepath)
110
- })
247
+ info[:filename] = File.basename(media_filepath)
248
+ tracks << OpenStruct.new(info)
111
249
 
112
250
  end
113
251
 
252
+ puts 'tracks: ' + tracks.inspect if @debug
253
+
114
254
  heading = tracks[0].album_artist + ' - ' + tracks[0].album
255
+
115
256
  s = "# %s\n\n" % [heading]
116
- h = tracks.group_by(&:disc)
117
257
 
118
- body = if h.length == 1 then
119
258
 
120
- list(tracks)
259
+ if format.to_sym == :txt then
260
+
261
+ h = tracks.group_by(&:disc)
262
+
263
+ body = if h.length == 1 then
264
+
265
+ list(tracks)
266
+
267
+ else
268
+
269
+ "\n" + h.map do |disc, tracks2|
270
+ ("## Disc %d\n\n" % disc) + list(tracks2) + "\n\n"
271
+ end.join("\n")
272
+
273
+ end
274
+
275
+ File.write File.join(directory, heading + '.txt'), s + body
121
276
 
122
277
  else
123
278
 
124
- "\n" + h.map do |disc, tracks2|
125
- ("## Disc %d\n\n" % disc) + list(tracks2) + "\n\n"
126
- end.join("\n")
279
+ # :xml
280
+ puts 'xml' if @debug
127
281
 
128
- end
282
+ dx = DxLite.new('album[album_artist, album]/track(tracknum, title, ' +
283
+ 'artist, disc, album_artist)')
284
+
285
+ #h.each {|_,x| puts x.inspect } if @debug
286
+ #h.each {|_,x| x.each {|track| dx.create(track.to_h) } }
287
+ tracks.each {|track| dx.create(track.to_h) }
129
288
 
130
- File.write File.join(directory, heading + '.txt'), s + body
289
+ dx.album_artist = dx.all[0].album_artist
290
+ dx.album = dx.all[0].album
291
+ dx.save File.join(directory, 'playlist.dx')
292
+
293
+ yield(directory) if block_given?
294
+
295
+ end
131
296
 
132
297
  end
133
298
 
@@ -139,11 +304,12 @@ class GotMP3
139
304
  #
140
305
  def add_image(directory, img_filename)
141
306
 
307
+ puts 'inside add_image - directory: ' + directory.inspect if @debug
142
308
  puts 'img_filename: ' + img_filename.inspect if @debug
143
309
  image_file = File.new(File.join(directory, img_filename),'rb')
144
310
  img = image_file.read
145
311
 
146
- each_mp3_track(directory) do |mp3, _, _|
312
+ each_media_track(directory) do |mp3, _, _|
147
313
 
148
314
  mp3.tag2.remove_pictures
149
315
  mp3.tag2.add_picture img
@@ -152,14 +318,16 @@ class GotMP3
152
318
 
153
319
  end
154
320
 
321
+ # Modifies the MP3s' tags using the track titles in the .txt file
322
+ #
155
323
  def add_tracktitles(directory, txt_filename)
156
324
 
157
325
  txt_file = File.join(directory, txt_filename)
158
326
  track_titles = File.read(txt_file).lines[1..-1].map(&:strip)
159
327
 
160
- each_mp3_track(directory) do |mp3, trackno, _|
328
+ each_media_track(directory) do |media, trackno, _|
161
329
 
162
- mp3.tag.title = track_titles[trackno-1]
330
+ media.tag.title = track_titles[trackno-1]
163
331
 
164
332
  end
165
333
  end
@@ -197,11 +365,16 @@ class GotMP3
197
365
 
198
366
  end
199
367
 
200
- def each_mp3_track(directory, &blk)
368
+ def each_media_track(directory, &blk)
201
369
 
202
- each_mp3_file do |mp3_filepath, i|
370
+ each_media_file(directory) do |filepath, i|
203
371
 
204
- Mp3Info.open(mp3_filepath) {|mp3| blk.call(mp3, i+1, mp3_filepath) }
372
+ case File.extname(filepath)
373
+ when '.mp3'
374
+ Mp3Info.open(filepath) {|mp3| blk.call(mp3, i+1, filepath) }
375
+ when '.ogg'
376
+ OggInfo.open(filepath) {|ogg| blk.call(ogg, i+1, filepath) }
377
+ end
205
378
 
206
379
  end
207
380
 
@@ -209,6 +382,7 @@ class GotMP3
209
382
 
210
383
  def find_by_ext(extension)
211
384
 
385
+ puts 'find_by_ext() - @dir' + @dir.inspect if @debug
212
386
  a = Dir[File.join(@dir, "**", "*" + extension)]
213
387
  puts 'a: ' + a.inspect if @debug
214
388
 
@@ -220,6 +394,8 @@ class GotMP3
220
394
  end
221
395
  end
222
396
 
397
+ # used by public method *write_titles* to list the tracks in plain text
398
+ #
223
399
  def list(tracks)
224
400
 
225
401
  a = if tracks.map(&:artist).uniq.length < 2 then
@@ -232,6 +408,33 @@ class GotMP3
232
408
 
233
409
  end
234
410
 
411
+ def mp3info(mp3)
412
+ {
413
+ title: mp3.tag.title.sub(/^\d+\. */,''),
414
+ artist: mp3.tag.artist,
415
+ album: mp3.tag.album,
416
+ album_artist: mp3.tag2['TPE2'] || mp3.tag.artist,
417
+ disc: mp3.tag2['TPOS'] || 1,
418
+ tracknum: mp3.tag.tracknum,
419
+ }
420
+ end
421
+
422
+ def ogginfo(ogg)
423
+
424
+ # options
425
+ # ["title", "artist", "tracknumber", "tracktotal", "album", "albumartist",
426
+ # "genre", "discid", "musicbrainz_discid"]
427
+
428
+ {
429
+ title: ogg.tag.title.sub(/^\d+\. */,''),
430
+ artist: ogg.tag.artist,
431
+ album: ogg.tag.album,
432
+ album_artist: ogg.tag.albumartist || ogg.tag.artist,
433
+ disc: ogg.tag.discid || 1,
434
+ tracknum: ogg.tag.tracknumber,
435
+ }
436
+ end
437
+
235
438
  end
236
439
 
237
440
  class Titles
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.2.0
4
+ version: 0.4.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-25 00:00:00.000000000 Z
38
+ date: 2021-11-28 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
@@ -57,6 +77,46 @@ dependencies:
57
77
  - - ">="
58
78
  - !ruby/object:Gem::Version
59
79
  version: 0.8.10
80
+ - !ruby/object:Gem::Dependency
81
+ name: ruby-ogginfo
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '0.7'
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 0.7.2
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.7'
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 0.7.2
100
+ - !ruby/object:Gem::Dependency
101
+ name: playlist_creator
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 0.2.0
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.2'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 0.2.0
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '0.2'
60
120
  description:
61
121
  email: digital.robertson@gmail.com
62
122
  executables: []
@@ -88,5 +148,5 @@ rubygems_version: 2.7.10
88
148
  signing_key:
89
149
  specification_version: 4
90
150
  summary: A ruby-mp3info wrapper to make it convenient to update the album art and
91
- track titles of multiple MP3 files as a batch process.
151
+ track titles of multiple MP3 files in a batch process.
92
152
  test_files: []
metadata.gz.sig CHANGED
Binary file