got_mp3 0.3.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 +145 -31
  4. data.tar.gz.sig +0 -0
  5. metadata +42 -2
  6. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c34d1db35e8baadaaf24b2fa70f3598a64ec38ddd47095188a82eae76e063573
4
- data.tar.gz: 86bb8da65ce447a7bbd168b068cc9b992b551b0db201eac8a3e2949fdc1d5dba
3
+ metadata.gz: a109d9369982eb251b2439256a7ab8ecb0494f8b693efeb869ed6e29329d23e4
4
+ data.tar.gz: 960ba30e1ab1178b77280f9f6068248cb82616040caa2fca2880dcccc78c1af0
5
5
  SHA512:
6
- metadata.gz: 5c666482d88a53d4e608316cbbbe83dd8b7b2c1fed9d725f666fdbf0c32c4e20ff809e5a2a51f72f87cf63659dc94f3f1bf5420b823bbebb0638b7e95781bcfe
7
- data.tar.gz: f6508835a0db94da8febc2d301ed40ab8b490caf17caf74af73c46418e0ffddb80142a3c24f8a82ca157a355bec0fa792cb6b813af9ae8dcf3c66ac350c702d4
6
+ metadata.gz: 8777628c7ec8d16460fe3ff59199b98bf34bf10494ffdb22afd432cb1f7110591bd48370998f4bc4757f9564d3b4a190ec03537e03d2f9c7cecd01b0ddafe744
7
+ data.tar.gz: 7c9b29dc4e6e889644c2cfef6464fcb09fb34ead8101670a7f08942344132994099444a144b5ee5a24e9f76d1c176f595837845accd9a6ef8efb1ff269994e80
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/got_mp3.rb CHANGED
@@ -4,11 +4,15 @@
4
4
 
5
5
  require 'dxlite'
6
6
  require 'ostruct'
7
- require "mp3info"
7
+ require 'mp3info'
8
+ require 'ogginfo'
9
+ require 'playlist_creator'
8
10
 
9
11
 
10
12
  class GotMP3
11
13
 
14
+ attr_accessor :dir
15
+
12
16
  def initialize(dir: '.', debug: false)
13
17
  @dir, @debug = dir, debug
14
18
  end
@@ -44,7 +48,58 @@ class GotMP3
44
48
 
45
49
  end
46
50
 
47
- # copy all MP3 directories through the category file-directory stucture
51
+ # Adds an XSPF playlist file to each file directory containing MP3s
52
+ #
53
+ def add_playlist(dir: @dir)
54
+
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.
48
103
  #
49
104
  def compile(source_directory: '', target_directory: '')
50
105
 
@@ -72,6 +127,8 @@ class GotMP3
72
127
 
73
128
  end
74
129
 
130
+ # copy the .txt file from each mp3 directory into a central file directory
131
+ #
75
132
  def consolidate_txt(target_directory: '')
76
133
 
77
134
  raise 'target_directory cannot be empty' if target_directory.empty?
@@ -90,19 +147,19 @@ class GotMP3
90
147
 
91
148
  end
92
149
 
93
- def each_mp3_file(directory='.', &blk)
150
+ def each_media_file(directory=@dir, &blk)
94
151
 
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
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
98
155
 
99
- found.reverse.each.with_index do |mp3_filepath, i|
156
+ found.each.with_index do |media_filepath, i|
100
157
 
101
- puts 'each_mp3 - mp3_filepath: ' + mp3_filepath.inspect if @debug
158
+ puts 'each_medi... - media_filepath: ' + media_filepath.inspect if @debug
102
159
 
103
- next unless File.exists? mp3_filepath
160
+ next unless File.exists? media_filepath
104
161
 
105
- blk.call(mp3_filepath, i )
162
+ blk.call(media_filepath, i )
106
163
 
107
164
  end
108
165
 
@@ -136,7 +193,7 @@ class GotMP3
136
193
  #
137
194
  def rename()
138
195
 
139
- each_mp3_file do |mp3_filepath|
196
+ each_media_file do |mp3_filepath|
140
197
 
141
198
  mp3_directory = File.dirname(mp3_filepath)
142
199
  mp3_filename = File.basename(mp3_filepath)
@@ -148,11 +205,28 @@ class GotMP3
148
205
 
149
206
  end
150
207
 
208
+ # sort MP3 or OGG by track number in the filename
209
+ #
210
+ def sort_by_tracknum!()
211
+
212
+ each_media_file do |filepath|
213
+
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
+ #
151
225
  def write_titles(format: 'txt')
152
226
 
153
227
  puts 'inside write_titles()' if @debug
154
228
 
155
- find_by_ext('.mp3').each do |directory, _ |
229
+ find_by_ext('.{mp3,ogg}').each do |directory, _ |
156
230
 
157
231
  puts 'write_titles() - directory: ' + directory.inspect if @debug
158
232
  txt_filename = Dir[File.join(directory, '*.txt')].first
@@ -161,17 +235,17 @@ class GotMP3
161
235
 
162
236
  tracks = []
163
237
 
164
- each_mp3_track(directory) do |mp3, trackno, mp3_filepath|
238
+ each_media_track(directory) do |media, trackno, media_filepath|
165
239
 
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
- })
240
+ info = case File.extname(media_filepath)
241
+ when '.mp3'
242
+ mp3info(media)
243
+ when '.ogg'
244
+ ogginfo(media)
245
+ end
246
+
247
+ info[:filename] = File.basename(media_filepath)
248
+ tracks << OpenStruct.new(info)
175
249
 
176
250
  end
177
251
 
@@ -180,11 +254,12 @@ class GotMP3
180
254
  heading = tracks[0].album_artist + ' - ' + tracks[0].album
181
255
 
182
256
  s = "# %s\n\n" % [heading]
183
- h = tracks.group_by(&:disc)
184
257
 
185
258
 
186
259
  if format.to_sym == :txt then
187
260
 
261
+ h = tracks.group_by(&:disc)
262
+
188
263
  body = if h.length == 1 then
189
264
 
190
265
  list(tracks)
@@ -207,13 +282,16 @@ class GotMP3
207
282
  dx = DxLite.new('album[album_artist, album]/track(tracknum, title, ' +
208
283
  'artist, disc, album_artist)')
209
284
 
210
- h.each {|_,x| puts x.inspect } if @debug
211
- h.each {|_,x| x.each {|track| dx.create(track.to_h) } }
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) }
212
288
 
213
289
  dx.album_artist = dx.all[0].album_artist
214
290
  dx.album = dx.all[0].album
215
291
  dx.save File.join(directory, 'playlist.dx')
216
292
 
293
+ yield(directory) if block_given?
294
+
217
295
  end
218
296
 
219
297
  end
@@ -231,7 +309,7 @@ class GotMP3
231
309
  image_file = File.new(File.join(directory, img_filename),'rb')
232
310
  img = image_file.read
233
311
 
234
- each_mp3_track(directory) do |mp3, _, _|
312
+ each_media_track(directory) do |mp3, _, _|
235
313
 
236
314
  mp3.tag2.remove_pictures
237
315
  mp3.tag2.add_picture img
@@ -240,14 +318,16 @@ class GotMP3
240
318
 
241
319
  end
242
320
 
321
+ # Modifies the MP3s' tags using the track titles in the .txt file
322
+ #
243
323
  def add_tracktitles(directory, txt_filename)
244
324
 
245
325
  txt_file = File.join(directory, txt_filename)
246
326
  track_titles = File.read(txt_file).lines[1..-1].map(&:strip)
247
327
 
248
- each_mp3_track(directory) do |mp3, trackno, _|
328
+ each_media_track(directory) do |media, trackno, _|
249
329
 
250
- mp3.tag.title = track_titles[trackno-1]
330
+ media.tag.title = track_titles[trackno-1]
251
331
 
252
332
  end
253
333
  end
@@ -285,11 +365,16 @@ class GotMP3
285
365
 
286
366
  end
287
367
 
288
- def each_mp3_track(directory, &blk)
368
+ def each_media_track(directory, &blk)
289
369
 
290
- each_mp3_file(directory) do |mp3_filepath, i|
370
+ each_media_file(directory) do |filepath, i|
291
371
 
292
- 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
293
378
 
294
379
  end
295
380
 
@@ -309,6 +394,8 @@ class GotMP3
309
394
  end
310
395
  end
311
396
 
397
+ # used by public method *write_titles* to list the tracks in plain text
398
+ #
312
399
  def list(tracks)
313
400
 
314
401
  a = if tracks.map(&:artist).uniq.length < 2 then
@@ -321,6 +408,33 @@ class GotMP3
321
408
 
322
409
  end
323
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
+
324
438
  end
325
439
 
326
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.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -35,7 +35,7 @@ cert_chain:
35
35
  RFrZsrDO1Cwk4v03qCUvuZ8H/nCojYYJGMrJE1JhBBJNJXCAULivh/zlOYcDhG69
36
36
  uPtZOD7YKrG45OftX8aNxlNv
37
37
  -----END CERTIFICATE-----
38
- date: 2021-11-27 00:00:00.000000000 Z
38
+ date: 2021-11-28 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: dxlite
@@ -77,6 +77,46 @@ dependencies:
77
77
  - - ">="
78
78
  - !ruby/object:Gem::Version
79
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'
80
120
  description:
81
121
  email: digital.robertson@gmail.com
82
122
  executables: []
metadata.gz.sig CHANGED
Binary file