unitf-tag 0.1.0 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd3119525797c4f3343cfbd7bd9228f75e47fae37d1eb2eea927a1d11c73819d
4
- data.tar.gz: fe80b8b243dc3416c27fc31ec4b89cbe37891914e24a748d5e7827d5d0101af3
3
+ metadata.gz: 3844f8f9883d9584a03a19be4ca9200c7b2203ec5b0f6d7615477d097d430628
4
+ data.tar.gz: 55e82e675756dbb52721575c888b0e3b7fb1bb2f0a59c9eb8b6557c657c54f2a
5
5
  SHA512:
6
- metadata.gz: 49a9d9a21aed7678da48f39f97a8c90283c818094dd6247a45f8425939e7641bac26c0698d3ba8d5fa3615f4a7b793e57b7fb7236a9d55909038482c99d89e75
7
- data.tar.gz: 1afd544df883c40dd04fe37703c278df76e3064809c2d7a6b968ef43cd8545e4927097d8f78926c6147df24b9844d04ae24712a5fc346171e17f3a1376bee12b
6
+ metadata.gz: eb091d040bab764dda18aded5e23a7ed370f0b3b253a8b4b21b324b22a85b6ac079e6ce8fd530665f84fd9a0b30e454a846f7af64305b1bc601e988266bb4b31
7
+ data.tar.gz: 90448d8bf47f1973c1639c6fc81f18b258ed24e248f314f37a6d79a119e2e09420b14bede4c2276d6030bfeb7e7ec5f64929d9e51ee24c59ef662e9cccb315d2
data/.vscode/tasks.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "presentation": {
17
17
  "clear": true
18
18
  },
19
- "command": "bundle exec ruby bin/test.rb"
19
+ "command": "bundle exec ruby exe/rtag /Users/mbaron/tag/music"
20
20
  },
21
21
  {
22
22
  "label": "test-project",
data/bin/test.rb CHANGED
@@ -2,7 +2,10 @@ require 'optparse'
2
2
 
3
3
  require 'unitf/tag'
4
4
 
5
- file_str = '/Users/mbaron/tag/music/fIREHOSE3/Sometimes'
6
- file = UnitF::Tag::File.new(file_str)
5
+ file_str = '/Users/mbaron/tag/music/fIREHOSE3/Sometimes/01 - Sometimes.flac'
7
6
 
8
- puts file.to_s
7
+ file = UnitF::Tag::FLAC.new(file_str)
8
+
9
+ file.open do |o|
10
+ pp o.info
11
+ end
data/exe/rtag CHANGED
@@ -11,32 +11,44 @@ logger = Logger.new($stdout)
11
11
  actions = []
12
12
  files = []
13
13
  opt = {
14
- :recursive => false,
15
- :force => false
14
+ recursive: false,
15
+ force: false
16
16
  }
17
17
 
18
18
  targets = OptionParser.new do |opts|
19
- opts.on('-r', '--recursive', 'Auto Cover') do |item|
19
+ opts.on('-r', '--recursive', 'Auto Cover') do
20
20
  opt[:recursive] = true
21
21
  end
22
22
 
23
- opts.on('-d', '--dump', 'Dump Tags') do |item|
23
+ opts.on('--dump', 'Dump Tags') do
24
24
  opt[:dump] = true
25
25
  end
26
26
 
27
- opts.on('--auto_cover', 'Auto Cover') do |item|
27
+ opts.on('-d', '--debug', 'Debug') do
28
+ UnitF::Tag.logger.level = Logger::DEBUG
29
+ end
30
+
31
+ opts.on('-j', '--json', 'JSON Output') do
32
+ opt[:format] = :json
33
+ end
34
+
35
+ opts.on('-l', '--line', 'Single Line Output') do
36
+ opt[:format] = :line
37
+ end
38
+
39
+ opts.on('--auto_cover', 'Auto Cover') do
28
40
  actions << :auto_cover
29
41
  end
30
42
 
31
- opts.on('--delete_cover', 'Delete Cover') do |item|
43
+ opts.on('--delete_cover', 'Delete Cover') do
32
44
  actions << :delete_cover
33
45
  end
34
46
 
35
- opts.on('--auto_tag', 'Auto Tag') do |item|
47
+ opts.on('--auto_tag', 'Auto Tag') do
36
48
  actions << :auto_tag
37
49
  end
38
50
 
39
- opts.on('-f', '--force', 'Force') do |arg|
51
+ opts.on('-f', '--force', 'Force') do
40
52
  opt[:force] = true
41
53
  end
42
54
 
@@ -61,25 +73,14 @@ targets = OptionParser.new do |opts|
61
73
  end
62
74
  end.parse!
63
75
 
64
- targets.each do |target|
65
- files.concat(UnitF::Tag::process_target(target))
66
- end
67
-
68
- if files.size.zero? && actions.size.zero?
69
- files = UnitF::Tag::find_files('.')
70
- end
76
+ files = UnitF::Tag::FileSet.new(targets)
71
77
 
72
78
  if files.size.zero?
73
79
  logger.error('Cannot find any files to operate on')
74
80
  end
75
81
 
76
82
  if actions.size.zero?
77
- files.each do |file|
78
- file.open do |o|
79
- o.print unless opt[:dump]
80
- o.dump if opt[:dump]
81
- end
82
- end
83
+ UnitF::Tag.list(files, format: opt[:format])
83
84
  exit 0
84
85
  end
85
86
 
@@ -89,7 +90,7 @@ files.each do |file|
89
90
  actions.each do |action|
90
91
  case action
91
92
  when :delete_cover
92
- logger.info("Delete cover")
93
+ logger.info('Delete cover')
93
94
  o.delete_cover!
94
95
  when :auto_cover
95
96
  unless o.cover?
@@ -101,7 +102,7 @@ files.each do |file|
101
102
  end
102
103
  end
103
104
  when :auto_tag
104
- logger.info("Auto Tag")
105
+ logger.info('Auto Tag')
105
106
  o.auto_tag!
106
107
  when :artist
107
108
  logger.info("Setting artist to #{opt[:artist]}")
@@ -120,6 +121,6 @@ files.each do |file|
120
121
  o.tag.genre = opt[:track]
121
122
  end
122
123
  end
123
- o.save
124
+ o.save || logger.error("Unable to save changes to #{file}")
124
125
  end
125
126
  end
@@ -0,0 +1,18 @@
1
+ require 'json'
2
+
3
+ module UnitF
4
+ module Tag
5
+ class Exporter
6
+ def initialize
7
+ @objects = []
8
+ end
9
+
10
+ def spool(object)
11
+ end
12
+
13
+ def dump
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,7 @@ require 'find'
2
2
  require 'taglib'
3
3
  require 'pathname'
4
4
  require 'logger'
5
+ require 'json'
5
6
 
6
7
  module UnitF
7
8
  module Tag
@@ -14,6 +15,31 @@ module UnitF
14
15
  @file.tag
15
16
  end
16
17
 
18
+ def format_json
19
+ JSON.pretty_generate(info)
20
+ end
21
+
22
+ def format_line
23
+ buff = []
24
+ info.each_key do |key|
25
+ buff << "#{key}=#{info[key]}"
26
+ end
27
+ buff.join(',')
28
+ end
29
+
30
+ def info
31
+ {
32
+ file: realpath.to_path,
33
+ artist: tag.artist,
34
+ album: tag.album,
35
+ title: tag.title,
36
+ track: tag.track,
37
+ genre: tag.genre,
38
+ year: tag.year,
39
+ cover: cover?
40
+ }
41
+ end
42
+
17
43
  def print
18
44
  puts "File : #{realpath}"
19
45
  puts "Artist: #{tag.artist}"
@@ -0,0 +1,28 @@
1
+ module UnitF
2
+ module Tag
3
+ class FileSet < Array
4
+ def initialize(targets)
5
+ targets.each do |target|
6
+ process_target(target)
7
+ end
8
+ end
9
+
10
+ def process_target(target)
11
+ if ::File.directory?(target)
12
+ find_files(target)
13
+ elsif UnitF::Tag.valid_file?(target)
14
+ append(UnitF::Tag::File.new(target))
15
+ end
16
+ end
17
+
18
+ def find_files(root_path)
19
+ Find.find(root_path) do |file_path|
20
+ UnitF::Log.debug("Considering #{file_path}")
21
+ next unless UnitF::Tag.valid_file?(file_path)
22
+ UnitF::Log.debug("Including #{file_path}")
23
+ append(UnitF::Tag::File.new(file_path))
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -6,6 +6,14 @@ module UnitF
6
6
  @file = TagLib::FLAC::File.new(file_path)
7
7
  end
8
8
 
9
+ def info
10
+ super.merge!({
11
+ stats: stats,
12
+ sample_rate: @file.audio_properties.sample_rate,
13
+ bits_per_sample: @file.audio_properties.bits_per_sample
14
+ })
15
+ end
16
+
9
17
  def cover?
10
18
  @file.picture_list.each do |pic|
11
19
  return true if pic.type == TagLib::FLAC::Picture::FrontCover
data/lib/unitf/tag/mp3.rb CHANGED
@@ -10,6 +10,14 @@ module UnitF
10
10
  sprintf("%.1fkHz/%dkbps", @file.audio_properties.sample_rate / 1000.to_f, @file.audio_properties.bitrate)
11
11
  end
12
12
 
13
+ def info
14
+ super.merge!({
15
+ stats: stats,
16
+ sample_rate: @file.audio_properties.sample_rate,
17
+ bitrate: @file.audio_properties.bitrate
18
+ })
19
+ end
20
+
13
21
  def cover?
14
22
  @file.id3v2_tag.frame_list('APIC').size > 0
15
23
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Unitf
4
4
  module Tag
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.6"
6
6
  end
7
7
  end
data/lib/unitf/tag.rb CHANGED
@@ -2,20 +2,30 @@
2
2
 
3
3
  require_relative 'tag/version'
4
4
  require_relative 'tag/file'
5
+ require_relative 'tag/fileset'
5
6
  require_relative 'tag/flac'
6
7
  require_relative 'tag/mp3'
7
8
 
9
+ require 'unitf/logging'
10
+
8
11
  module UnitF
9
12
  module Tag
10
13
  class Error < StandardError; end
11
14
  class MissingCover < Error; end
12
15
 
13
16
  def self.logger
14
- @logger ||= Logger.new($stdout)
17
+ unless @logger
18
+ @logger = UnitF::Logging::Logger.new
19
+ @logger.add_writer(UnitF::Logging::ConsoleWriter.new)
20
+ end
21
+ @logger
15
22
  end
16
23
 
17
24
  def self.valid_file?(file_path)
18
- ::File.file?(file_path) && file_path.match(/\.(flac|mp3)$/i)
25
+ ::File.file?(file_path) && file_path.encode.match(/\.(flac|mp3)$/i)
26
+ rescue ArgumentError => e
27
+ logger.error("Error processing #{file_path} - #{e.message}")
28
+ false
19
29
  end
20
30
 
21
31
  def self.process_target(target)
@@ -31,10 +41,28 @@ module UnitF
31
41
  def self.find_files(root_path)
32
42
  files = []
33
43
  Find.find(root_path) do |file_path|
44
+ logger.debug("Considering #{file_path}")
34
45
  next unless valid_file?(file_path)
35
46
  files << UnitF::Tag::File.new(file_path)
36
47
  end
37
48
  files
38
49
  end
50
+
51
+ def self.list(files, format: :json)
52
+ buff = []
53
+ files.each do |file|
54
+ file.open do |o|
55
+ case format
56
+ when :json
57
+ buff << o.info
58
+ when :line
59
+ puts o.format_line
60
+ else
61
+ o.print
62
+ end
63
+ end
64
+ end
65
+ puts JSON.pretty_generate(buff) if format == :json
66
+ end
39
67
  end
40
68
  end
data/unitf-tag.gemspec CHANGED
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ["lib"]
29
29
 
30
30
  spec.add_dependency "taglib-ruby"
31
+ spec.add_dependency "unitf-logging"
31
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unitf-tag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Baron
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-27 00:00:00.000000000 Z
11
+ date: 2021-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: taglib-ruby
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: unitf-logging
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: Audio File Tagging
28
42
  email:
29
43
  - mwb@unitf.net
@@ -47,11 +61,12 @@ files:
47
61
  - bin/test.rb
48
62
  - exe/rtag
49
63
  - lib/unitf/tag.rb
64
+ - lib/unitf/tag/export/exporter.rb
50
65
  - lib/unitf/tag/file.rb
66
+ - lib/unitf/tag/fileset.rb
51
67
  - lib/unitf/tag/flac.rb
52
68
  - lib/unitf/tag/mp3.rb
53
69
  - lib/unitf/tag/version.rb
54
- - lib/unitf/version.rb
55
70
  - tag
56
71
  - test.rb
57
72
  - unitf-tag.gemspec
@@ -78,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
93
  - !ruby/object:Gem::Version
79
94
  version: '0'
80
95
  requirements: []
81
- rubygems_version: 3.2.22
96
+ rubygems_version: 3.2.32
82
97
  signing_key:
83
98
  specification_version: 4
84
99
  summary: Audio File Tagging
data/lib/unitf/version.rb DELETED
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Unitf
4
- module Tagger
5
- VERSION = "0.1.0"
6
- end
7
- end