unitf-tag 0.1.25 → 0.1.27
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
- data/.vscode/tasks.json +9 -1
- data/CHANGELOG.md +3 -0
- data/bin/test.rb +5 -18
- data/exe/tag +6 -0
- data/lib/unitf/tag/auto_tags.rb +63 -0
- data/lib/unitf/tag/file.rb +11 -88
- data/lib/unitf/tag/mp3.rb +4 -0
- data/lib/unitf/tag/version.rb +1 -1
- data/lib/unitf/tag.rb +1 -0
- data/unitf-tag.gemspec +7 -2
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14e1d8e28d9848b67e6bb7d268d1fa8e6218d61c72222c9f46a54cfec761648b
|
4
|
+
data.tar.gz: b012aacd324ab95d197f3d4b5bd683157693cb05919908256ad3d317d66f1c29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5600015d8ceb5a8cf60a498a77f430127a130d4371751a0407540084f59cfc5f2a9c1c58d022ef6f65d3f7f5a90375fdab901544c72879d2fa172af6d025dc8f
|
7
|
+
data.tar.gz: 040ec01ad18ef917a39b9c36f981df172b48c3ff817c065ab595d8445fa9d1cc15ee12b3224c3446cecdf52a5a42a9e7b24d70f90025e7d8cbd4841339c2a45a
|
data/.vscode/tasks.json
CHANGED
@@ -16,7 +16,15 @@
|
|
16
16
|
"presentation": {
|
17
17
|
"clear": true
|
18
18
|
},
|
19
|
-
"command": "bundle exec
|
19
|
+
"command": "bundle exec ruby bin/test.rb"
|
20
|
+
},
|
21
|
+
{
|
22
|
+
"label": "tag-test",
|
23
|
+
"type": "shell",
|
24
|
+
"options": {
|
25
|
+
"cwd": "${workspaceFolder}",
|
26
|
+
},
|
27
|
+
"command": "bundle exec ruby exe/tag --auto_tag '/Users/mbaron/music2/Dinosaur Jr/Little Fury Things'"
|
20
28
|
},
|
21
29
|
{
|
22
30
|
"label": "test-project",
|
data/CHANGELOG.md
CHANGED
data/bin/test.rb
CHANGED
@@ -4,23 +4,10 @@ require 'unitf/tag'
|
|
4
4
|
|
5
5
|
UnitF::Log.to_console
|
6
6
|
|
7
|
-
UnitF::Tag.
|
8
|
-
file.tag.artist = 'bar123'
|
9
|
-
file.tag.year = 1972
|
10
|
-
file.tag.album = 'This is the album'
|
11
|
-
file.tag.title = 'This is the title'
|
12
|
-
file.tag.track = 99
|
13
|
-
file.auto_cover!
|
14
|
-
end
|
7
|
+
# file = UnitF::Tag::File.new('/Users/mbaron/music2/BJ/2025/foo/bar/../../bj250321.mp3')
|
15
8
|
|
16
|
-
|
17
|
-
# file.tag
|
9
|
+
# puts file.auto_tags
|
18
10
|
|
19
|
-
file.update do |f|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
file.open do |f|
|
25
|
-
f.tag.title = 'Hello world9!'
|
26
|
-
end
|
11
|
+
# file.update do |f|
|
12
|
+
# f.auto_tag!
|
13
|
+
# end
|
data/exe/tag
CHANGED
@@ -54,6 +54,10 @@ targets = OptionParser.new do |opts|
|
|
54
54
|
actions << :auto_tag
|
55
55
|
end
|
56
56
|
|
57
|
+
opts.on('--auto_tags', 'Auto Tags') do
|
58
|
+
actions << :auto_tags
|
59
|
+
end
|
60
|
+
|
57
61
|
opts.on('-f', '--force', 'Force') do
|
58
62
|
opt[:force] = true
|
59
63
|
end
|
@@ -109,6 +113,8 @@ files.each do |file|
|
|
109
113
|
o.auto_cover!
|
110
114
|
when :auto_tag
|
111
115
|
o.auto_tag!
|
116
|
+
when :auto_tags
|
117
|
+
puts "\tauto_tags: #{o.auto_tags}\n\n"
|
112
118
|
end
|
113
119
|
end
|
114
120
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module UnitF
|
2
|
+
module Tag
|
3
|
+
class AutoTags < Hash
|
4
|
+
def initialize(pathname)
|
5
|
+
super
|
6
|
+
|
7
|
+
pathname = Pathname.new(pathname) if pathname.is_a?(String)
|
8
|
+
@pathname = pathname.realpath
|
9
|
+
@dirname = pathname.realpath.dirname
|
10
|
+
|
11
|
+
merge!(from_path)
|
12
|
+
merge!(from_file)
|
13
|
+
end
|
14
|
+
|
15
|
+
def auto_tag_path
|
16
|
+
return @auto_tag_path unless @auto_tag_path.nil?
|
17
|
+
|
18
|
+
["#{@dirname}/.autotag", "#{@dirname}/../.autotag"].each do |path|
|
19
|
+
return @auto_tag_path = path if ::File.exist?(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def from_path
|
26
|
+
tags = {}
|
27
|
+
|
28
|
+
tags[:title] = ::File.basename(@pathname)
|
29
|
+
tags[:track] = tags[:title].match(/^\s*\d+/).to_s.to_i
|
30
|
+
|
31
|
+
# Specific formatting for dated radio
|
32
|
+
if tags[:title].scan(/(\.|_|-)((\d\d\d\d)(\.|-)\d\d(\.|-)\d\d(\w*))\./).any?
|
33
|
+
tags[:title] = ::Regexp.last_match[2]
|
34
|
+
tags[:year] = ::Regexp.last_match[3].to_i
|
35
|
+
else
|
36
|
+
tags[:title].gsub!(/\.\w+$/, '')
|
37
|
+
tags[:title].gsub!(/^\d*\s*(-|\.)*\s*/, '')
|
38
|
+
end
|
39
|
+
|
40
|
+
path_parts = @dirname.to_s.split('/')
|
41
|
+
tags[:artist] = path_parts[-2]
|
42
|
+
tags[:album] = tags[:album_artist] = path_parts[-1]
|
43
|
+
|
44
|
+
tags
|
45
|
+
end
|
46
|
+
|
47
|
+
def from_file
|
48
|
+
tags = {}
|
49
|
+
return tags unless ::File.exist?(auto_tag_path)
|
50
|
+
|
51
|
+
::File.read(auto_tag_path).each_line do |line|
|
52
|
+
line.chomp!
|
53
|
+
tag, value = line.split(/\s*=\s*/)
|
54
|
+
tags[tag.strip.to_sym] = value.strip
|
55
|
+
end
|
56
|
+
|
57
|
+
tags
|
58
|
+
rescue StandardError
|
59
|
+
{}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/unitf/tag/file.rb
CHANGED
@@ -68,12 +68,8 @@ module UnitF
|
|
68
68
|
["#{dirname}/cover.jpg", "#{dirname}/../cover.jpg"].each do |path|
|
69
69
|
return ::File.realpath(path) if ::File.exist?(path)
|
70
70
|
end
|
71
|
-
end
|
72
71
|
|
73
|
-
|
74
|
-
["#{dirname}/.autotag", "#{dirname}/../.autotag"].each do |path|
|
75
|
-
return ::File.realpath(path) if ::File.exist?(path)
|
76
|
-
end
|
72
|
+
nil
|
77
73
|
end
|
78
74
|
|
79
75
|
def mp3?
|
@@ -85,104 +81,31 @@ module UnitF
|
|
85
81
|
end
|
86
82
|
|
87
83
|
def cover_available?
|
88
|
-
cover_path
|
84
|
+
!cover_path.nil?
|
89
85
|
end
|
90
86
|
|
91
87
|
def auto_cover!
|
92
88
|
raise Error, "File is not open #{self.class.name}" if tag.nil?
|
93
89
|
|
94
|
-
cover!(cover_path)
|
90
|
+
cover!(cover_path) if cover_available?
|
95
91
|
true
|
96
92
|
rescue StandardError => e
|
97
93
|
UnitF::Log.error("Failed to auto-cover file #{e}")
|
98
94
|
false
|
99
95
|
end
|
100
96
|
|
101
|
-
def
|
102
|
-
UnitF::
|
103
|
-
tags = {}
|
104
|
-
return {} unless ::File.exist?(auto_tag_path)
|
105
|
-
::File.read(auto_tag_path).each_line do |line|
|
106
|
-
line.chomp!
|
107
|
-
UnitF::Log.info(line)
|
108
|
-
tag, value = line.split(/\s*=\s*/)
|
109
|
-
tags[tag.to_sym] = value
|
110
|
-
end
|
111
|
-
tags
|
112
|
-
rescue StandardError
|
113
|
-
{}
|
114
|
-
end
|
115
|
-
|
116
|
-
# def auto_tags
|
117
|
-
# manual_tags = manual_auto_tags
|
118
|
-
# tags = {}
|
119
|
-
|
120
|
-
# tags[:title] = ::File.basename(realpath.to_path)
|
121
|
-
# track = tags[:title].match(/^\s*\d+/).to_s.to_i
|
122
|
-
|
123
|
-
# if tags[:title].scan(/(\.|_|-)(\d\d\d\d(\.|-)\d\d(\.|-)\d\d)/)
|
124
|
-
# tags[:title] = ::Regexp::last_match
|
125
|
-
# else
|
126
|
-
# tags[:title].gsub!(/\.\w+$/, '')
|
127
|
-
# tags[:title].gsub!(/^\d*\s*(-|\.)*\s*/, '')
|
128
|
-
# end
|
129
|
-
|
130
|
-
# path_parts = realpath.dirname.to_path.split('/')
|
131
|
-
# tags[:album] = path_parts[-1]
|
132
|
-
# tags[:artist] = path_parts[-2]
|
133
|
-
|
134
|
-
# tags.merge(manual_auto_tags)
|
135
|
-
# end
|
136
|
-
|
137
|
-
def path_tags
|
138
|
-
tags = {}
|
139
|
-
|
140
|
-
tags[:title] = ::File.basename(realpath.to_path)
|
141
|
-
tags[:track] = tags[:title].match(/^\s*\d+/).to_s.to_i
|
142
|
-
|
143
|
-
# Specific formatting for dated radio
|
144
|
-
if tags[:title].scan(/(\.|_|-)((\d\d\d\d)(\.|-)\d\d(\.|-)\d\d(\w*))\./).any?
|
145
|
-
tags[:title] = ::Regexp.last_match[2]
|
146
|
-
tags[:year] = ::Regexp.last_match[3].to_i
|
147
|
-
else
|
148
|
-
tags[:title].gsub!(/\.\w+$/, '')
|
149
|
-
tags[:title].gsub!(/^\d*\s*(-|\.)*\s*/, '')
|
150
|
-
end
|
151
|
-
|
152
|
-
tags[:artist] = path_parts[-2]
|
153
|
-
tags[:album] = tags[:album_artist] = path_parts[-1]
|
97
|
+
def auto_tags
|
98
|
+
@auto_tags ||= UnitF::Tag::AutoTags.new(self)
|
154
99
|
end
|
155
100
|
|
156
101
|
def auto_tag!
|
157
102
|
UnitF::Log.info("Auto tagging #{self}")
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
year =
|
163
|
-
|
164
|
-
# This must come before gsubbing the title
|
165
|
-
track = title.match(/^\s*\d+/).to_s.to_i
|
166
|
-
|
167
|
-
# Specific formatting for dated radio
|
168
|
-
if title.scan(/(\.|_|-)((\d\d\d\d)(\.|-)\d\d(\.|-)\d\d(\w*))\./).any?
|
169
|
-
title = ::Regexp.last_match[2]
|
170
|
-
album = path_parts[-1]
|
171
|
-
year = ::Regexp.last_match[3].to_i
|
172
|
-
else
|
173
|
-
title.gsub!(/\.\w+$/, '')
|
174
|
-
title.gsub!(/^\d*\s*(-|\.)*\s*/, '')
|
175
|
-
album = path_parts[-1]
|
176
|
-
end
|
177
|
-
|
178
|
-
artist = path_parts[-2]
|
179
|
-
|
180
|
-
tag.year = year unless year.nil?
|
181
|
-
tag.album = album
|
182
|
-
tag.artist = artist
|
183
|
-
tag.title = title
|
184
|
-
tag.track = track if track.positive?
|
185
|
-
self.album_artist = artist
|
103
|
+
tag.album = auto_tags[:album]
|
104
|
+
tag.artist = auto_tags[:artist]
|
105
|
+
tag.title = auto_tags[:title]
|
106
|
+
tag.track = auto_tags[:track] if auto_tags.key?(:track)
|
107
|
+
tag.year = auto_tags[:year] if auto_tags.key?(:year)
|
108
|
+
self.album_artist = auto_tags[:artist]
|
186
109
|
end
|
187
110
|
|
188
111
|
def properties!(properties)
|
data/lib/unitf/tag/mp3.rb
CHANGED
@@ -23,6 +23,10 @@ module UnitF
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def cover!(file_path)
|
26
|
+
return unless ::File.exist?(file_path.to_s)
|
27
|
+
|
28
|
+
delete_cover! if cover?
|
29
|
+
|
26
30
|
UnitF::Log.info("Setting cover #{file_path}")
|
27
31
|
apic = TagLib::ID3v2::AttachedPictureFrame.new
|
28
32
|
apic.mime_type = 'image/jpeg'
|
data/lib/unitf/tag/version.rb
CHANGED
data/lib/unitf/tag.rb
CHANGED
data/unitf-tag.gemspec
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'lib/unitf/tag/version'
|
4
|
+
# require 'rbconfig'
|
5
|
+
|
6
|
+
# taglib_ruby_version = '>= 2.0.0' unless RbConfig::CONFIG['host_os'].match?(/linux/)
|
7
|
+
# taglib_ruby_version = '1.1.3' if RbConfig::CONFIG['host_os'].match?(/linux/)
|
4
8
|
|
5
9
|
Gem::Specification.new do |spec|
|
6
10
|
spec.name = 'unitf-tag'
|
@@ -27,7 +31,8 @@ Gem::Specification.new do |spec|
|
|
27
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
28
32
|
spec.require_paths = ['lib']
|
29
33
|
|
30
|
-
|
31
|
-
spec.add_dependency 'taglib-ruby'
|
34
|
+
spec.add_dependency 'logger'
|
35
|
+
spec.add_dependency 'taglib-ruby', '1.1.3'
|
36
|
+
# spec.add_dependency 'taglib-ruby', '>= 2.0.0'
|
32
37
|
spec.add_dependency 'unitf-logging'
|
33
38
|
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unitf-tag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Baron
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-03-
|
10
|
+
date: 2025-03-27 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
|
-
name:
|
13
|
+
name: logger
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
16
|
- - ">="
|
@@ -23,6 +23,20 @@ dependencies:
|
|
23
23
|
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
25
|
version: '0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: taglib-ruby
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - '='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.3
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 1.1.3
|
26
40
|
- !ruby/object:Gem::Dependency
|
27
41
|
name: unitf-logging
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,6 +74,7 @@ files:
|
|
60
74
|
- exe/tag
|
61
75
|
- exe/unitf-autotags
|
62
76
|
- lib/unitf/tag.rb
|
77
|
+
- lib/unitf/tag/auto_tags.rb
|
63
78
|
- lib/unitf/tag/export/exporter.rb
|
64
79
|
- lib/unitf/tag/file.rb
|
65
80
|
- lib/unitf/tag/fileset.rb
|