nametag 0.2.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.
- data/.yardopts +1 -0
- data/README.md +112 -0
- data/Rakefile +58 -0
- data/bin/nametag +59 -0
- data/lib/nametag.rb +129 -0
- data/lib/nametag/version.rb +4 -0
- data/nametag.gemspec +33 -0
- data/spec/nametag_spec.rb +102 -0
- metadata +94 -0
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
[]: {{{1
|
2
|
+
|
3
|
+
File : README.md
|
4
|
+
Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
Date : 2013-09-06
|
6
|
+
|
7
|
+
Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
Version : v0.2.0
|
9
|
+
|
10
|
+
[]: }}}1
|
11
|
+
|
12
|
+
[](http://badge.fury.io/rb/nametag)
|
13
|
+
|
14
|
+
## Description
|
15
|
+
[]: {{{1
|
16
|
+
|
17
|
+
nametag - set audio file tags based on file name
|
18
|
+
|
19
|
+
nametag uses regular expressions to parse paths of audio files and
|
20
|
+
then sets the file tags based on the parsed data. This allows you
|
21
|
+
to keep paths and tags in sync by creating the tags from the paths.
|
22
|
+
|
23
|
+
Everything is configurable: the path regexes, the character
|
24
|
+
substitution, and the handling of special cases. For example, the
|
25
|
+
abum `if_then_else` by The Gathering should not have its underscores
|
26
|
+
interpreted as spaces.
|
27
|
+
|
28
|
+
[]: }}}1
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
[]: {{{1
|
32
|
+
|
33
|
+
$ nametag -h
|
34
|
+
nametag - set audio file tags based on file name
|
35
|
+
|
36
|
+
nametag [<option(s)>]
|
37
|
+
-c, --config-file FILE Configuration file
|
38
|
+
-v, --verbose Run verbosely
|
39
|
+
-n, --no-act Do not modify files
|
40
|
+
-h, --help Show this message
|
41
|
+
--version Show version
|
42
|
+
|
43
|
+
$ nametag -v ".../Between_the_Buried_and_Me/04-Colors_(2007)/05-Ants_of_the_Sky.mp3"
|
44
|
+
/.../Between_the_Buried_and_Me/04-Colors_(2007)/05-Ants_of_the_Sky.mp3:
|
45
|
+
artist="Between the Buried and Me" album="Colors" track="05" title="Ants of the Sky" ext="mp3" album_n="04" year="2007"
|
46
|
+
|
47
|
+
[]: }}}1
|
48
|
+
|
49
|
+
## Configuration
|
50
|
+
[]: {{{1
|
51
|
+
|
52
|
+
See `nametag.rb` for the default regex and substitution.
|
53
|
+
|
54
|
+
`~/.nametagrc`:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
NameTag.configure do |c|
|
58
|
+
c.regexes << %r{ ... }
|
59
|
+
c.tr['~'] = '_'
|
60
|
+
c.process do |info, opts, tr|
|
61
|
+
if info.artist == 'The_Gathering' && info.album == 'if_then_else'
|
62
|
+
info.map_values { |k,v| k == :album ? v : tr[v] }
|
63
|
+
end
|
64
|
+
# when nothing is returned, the default processing will be used
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
[]: }}}1
|
70
|
+
|
71
|
+
## Installing
|
72
|
+
[]: {{{1
|
73
|
+
|
74
|
+
$ sudo aptitude install libtag1-dev
|
75
|
+
$ gem install nametag
|
76
|
+
|
77
|
+
[]: }}}1
|
78
|
+
|
79
|
+
## Specs & Docs
|
80
|
+
[]: {{{1
|
81
|
+
|
82
|
+
$ rake spec
|
83
|
+
$ rake docs
|
84
|
+
|
85
|
+
[]: }}}1
|
86
|
+
|
87
|
+
## TODO
|
88
|
+
[]: {{{1
|
89
|
+
|
90
|
+
* test config: regexes, tr
|
91
|
+
* (use cucumber to) test tag writing/behaviour?
|
92
|
+
* more specs/docs?
|
93
|
+
* ...
|
94
|
+
|
95
|
+
[]: }}}1
|
96
|
+
|
97
|
+
## License
|
98
|
+
[]: {{{1
|
99
|
+
|
100
|
+
GPLv2 [1].
|
101
|
+
|
102
|
+
[]: }}}1
|
103
|
+
|
104
|
+
## References
|
105
|
+
[]: {{{1
|
106
|
+
|
107
|
+
[1] GNU General Public License, version 2
|
108
|
+
--- http://www.opensource.org/licenses/GPL-2.0
|
109
|
+
|
110
|
+
[]: }}}1
|
111
|
+
|
112
|
+
[]: ! ( vim: set tw=70 sw=2 sts=2 et fdm=marker : )
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
desc 'Run specs'
|
2
|
+
task :spec do
|
3
|
+
sh 'rspec -c'
|
4
|
+
end
|
5
|
+
|
6
|
+
desc 'Run specs verbosely'
|
7
|
+
task 'spec:verbose' do
|
8
|
+
sh 'rspec -cfd'
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Run specs verbosely, view w/ less'
|
12
|
+
task 'spec:less' do
|
13
|
+
sh 'rspec -cfd --tty | less -R'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Check for warnings'
|
17
|
+
task :warn do
|
18
|
+
sh "ruby -w -I lib -r nametag -e ''"
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Check for warnings in specs'
|
22
|
+
task 'warn:spec' do
|
23
|
+
reqs = Dir['spec/**/*.rb'].sort.map { |x| "-r ./#{x}" } * ' '
|
24
|
+
sh "ruby -w -I lib -r rspec #{reqs} -e ''"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Check for warnings in specs (but not void context)'
|
28
|
+
task 'warn:spec:novoid' do
|
29
|
+
sh 'rake warn:spec 2>&1 | grep -v "void context"'
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Generate docs'
|
33
|
+
task :docs do
|
34
|
+
sh 'yardoc | cat'
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'List undocumented objects'
|
38
|
+
task 'docs:undoc' do
|
39
|
+
sh 'yard stats --list-undoc'
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Cleanup'
|
43
|
+
task :clean do
|
44
|
+
sh 'rm -rf .yardoc/ doc/ *.gem'
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'Build SNAPSHOT gem'
|
48
|
+
task :snapshot do
|
49
|
+
v = Time.new.strftime '%Y%m%d%H%M%S'
|
50
|
+
f = 'lib/nametag/version.rb'
|
51
|
+
sh "sed -ri~ 's!(SNAPSHOT)!\\1.#{v}!' #{f}"
|
52
|
+
sh 'gem build nametag.gemspec'
|
53
|
+
end
|
54
|
+
|
55
|
+
desc 'Undo SNAPSHOT gem'
|
56
|
+
task 'snapshot:undo' do
|
57
|
+
sh 'git checkout -- lib/nametag/version.rb'
|
58
|
+
end
|
data/bin/nametag
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
require 'nametag'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
info = 'nametag - set audio file tags based on file name'
|
7
|
+
usage = 'nametag [<option(s)>]'
|
8
|
+
rc = "#{ Dir.home }/.nametagrc"
|
9
|
+
options = { cfgfile: nil, verbose: 0, noact: false }
|
10
|
+
|
11
|
+
op = OptionParser.new(usage) do |o| # {{{1
|
12
|
+
o.on('-c', '--config-file FILE', 'Configuration file') do |x|
|
13
|
+
options[:cfgfile] = x
|
14
|
+
end
|
15
|
+
|
16
|
+
o.on('-v', '--verbose', 'Run verbosely') do |x|
|
17
|
+
options[:verbose] += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
o.on('-n', '--no-act', 'Do not modify files') do |x|
|
21
|
+
options[:noact] = !x
|
22
|
+
end
|
23
|
+
|
24
|
+
o.on_tail('-h', '--help', 'Show this message') do
|
25
|
+
puts info, '', o; exit
|
26
|
+
end
|
27
|
+
|
28
|
+
o.on_tail('--version', 'Show version') do
|
29
|
+
puts "nametag version #{NameTag::VERSION}"; exit
|
30
|
+
end
|
31
|
+
end # }}}1
|
32
|
+
|
33
|
+
begin
|
34
|
+
op.parse! ARGV
|
35
|
+
rescue OptionParser::ParseError => e
|
36
|
+
$stderr.puts "Error: #{e}"; exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
opts = NameTag::DEFAULTS
|
40
|
+
v = options[:verbose]
|
41
|
+
cf = options[:cfgfile] || (File.exists?(rc) ? rc : nil)
|
42
|
+
|
43
|
+
load cf if cf
|
44
|
+
|
45
|
+
ARGV.each do |f| # {{{1
|
46
|
+
fn = File.realpath f
|
47
|
+
info = NameTag.parse(fn, opts) or raise "parse failed for: #{f}"
|
48
|
+
info_ = NameTag.process info, opts
|
49
|
+
|
50
|
+
if v > 0
|
51
|
+
puts "#{fn}:"
|
52
|
+
puts(v > 1 ? " - #{info}\n + #{info_}" : " #{info_}")
|
53
|
+
puts
|
54
|
+
end
|
55
|
+
|
56
|
+
NameTag.tag fn, info_ unless options[:noact]
|
57
|
+
end # }}}1
|
58
|
+
|
59
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
data/lib/nametag.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : nametag.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-09-06
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'nametag/version'
|
13
|
+
require 'taglib'
|
14
|
+
|
15
|
+
module NameTag
|
16
|
+
|
17
|
+
# default pattern; matches artist, album, track, title, ext;
|
18
|
+
# optionally: album_n, year; matches e.g.
|
19
|
+
# "Between_the_Buried_and_Me/04-Colors_(2007)/05-Ants_of_the_Sky.mp3"
|
20
|
+
RX = # {{{1
|
21
|
+
%r{ / (?<artist> [^/]* )
|
22
|
+
/ (?: (?<album_n> [0-9]+ ) - )?
|
23
|
+
(?<album> [^/]*? )
|
24
|
+
(?: _\( (?<year> \d{4} ) \) )?
|
25
|
+
/ (?<track> [0-9]+ ) (?: - (?<title> [^/]* ) )?
|
26
|
+
\. (?<ext> mp3 | ogg | flac )
|
27
|
+
\z }x # }}}1
|
28
|
+
|
29
|
+
# default character substitution
|
30
|
+
TR = { '_|' => ' /' }
|
31
|
+
|
32
|
+
# --
|
33
|
+
|
34
|
+
# substitute characters
|
35
|
+
TR_F = ->(o) { ->(x) {
|
36
|
+
x && o.tr.reduce(x) { |a,y;k,v| k, v = y; a.tr k, v }
|
37
|
+
} }
|
38
|
+
|
39
|
+
# tr all values
|
40
|
+
PROCESS = ->(i, o, f) { i.map { |k,v| [k, f[v]] } }
|
41
|
+
|
42
|
+
# --
|
43
|
+
|
44
|
+
# better struct
|
45
|
+
module BetterStruct # {{{1
|
46
|
+
def initialize(h = {})
|
47
|
+
h.each_pair { |k,v| self[k] = v }
|
48
|
+
end
|
49
|
+
def map(&b)
|
50
|
+
each_pair.map(&b)
|
51
|
+
end
|
52
|
+
def map_values(&b)
|
53
|
+
map { |k,v| [k,b[k,v]] }
|
54
|
+
end
|
55
|
+
end # }}}1
|
56
|
+
|
57
|
+
# options
|
58
|
+
Options = Struct.new(:regexes, :tr, :_process) do
|
59
|
+
include BetterStruct
|
60
|
+
def process(&b)
|
61
|
+
_process << b
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# info
|
66
|
+
Info = Struct.new(:artist, :album, :track, :title, # {{{1
|
67
|
+
:ext, :album_n, :year) do
|
68
|
+
include BetterStruct
|
69
|
+
def to_s
|
70
|
+
map { |k,v| "#{k}=#{v.inspect}" } *' '
|
71
|
+
end
|
72
|
+
end # }}}1
|
73
|
+
|
74
|
+
# default options
|
75
|
+
DEFAULTS = Options.new regexes: [RX], tr: TR, _process: []
|
76
|
+
|
77
|
+
# --
|
78
|
+
|
79
|
+
# configure nametag by changing DEFAULTS, which is passed to the
|
80
|
+
# block
|
81
|
+
def self.configure(c = DEFAULTS, &b)
|
82
|
+
b[c]; c
|
83
|
+
end
|
84
|
+
|
85
|
+
# --
|
86
|
+
|
87
|
+
# parse filename; tries each regex in turn
|
88
|
+
# @return [Info, nil]
|
89
|
+
def self.parse(filename, opts)
|
90
|
+
m = _first_map(opts.regexes) { |rx| rx.match filename }
|
91
|
+
m ? Info.new(Hash[m.names.map { |x| [x, m[x]] }]) : nil
|
92
|
+
end
|
93
|
+
|
94
|
+
# process info object; tries each processing function in turn
|
95
|
+
# @return [Info]
|
96
|
+
def self.process(info, opts) # {{{1
|
97
|
+
ps = opts._process + [PROCESS]; tr = TR_F[opts]
|
98
|
+
info_ = _first_map(ps) { |p| p[info, opts, tr] }
|
99
|
+
case info_
|
100
|
+
when Info ; info_
|
101
|
+
when Hash ; Info.new(info_)
|
102
|
+
when Array; Info.new(Hash[info_])
|
103
|
+
else raise 'processing function dit not return Info|Hash|Array'
|
104
|
+
end
|
105
|
+
end # }}}1
|
106
|
+
|
107
|
+
# process file: set tags from info, save file
|
108
|
+
def self.tag(filename, info) # {{{1
|
109
|
+
TagLib::FileRef.open(filename) do |file|
|
110
|
+
tag = file.tag
|
111
|
+
tag.artist = info[:artist]
|
112
|
+
tag.album = info[:album]
|
113
|
+
tag.track = info[:track].to_i
|
114
|
+
tag.title = info[:title] || "[track #{info[:track]}]"
|
115
|
+
tag.year = info[:year].to_i
|
116
|
+
file.save
|
117
|
+
end
|
118
|
+
end # }}}1
|
119
|
+
|
120
|
+
# --
|
121
|
+
|
122
|
+
# lazy xs.map(&f).first
|
123
|
+
def self._first_map(xs, &f)
|
124
|
+
xs.each { |x| y = f[x]; return y if y }; nil
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
data/nametag.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path('../lib/nametag/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'nametag'
|
5
|
+
s.homepage = 'https://github.com/obfusk/nametag'
|
6
|
+
s.summary = 'set audio file tags based on file name'
|
7
|
+
|
8
|
+
s.description = <<-END.gsub(/^ {4}/, '')
|
9
|
+
set audio file tags based on file name
|
10
|
+
|
11
|
+
...
|
12
|
+
END
|
13
|
+
|
14
|
+
s.version = NameTag::VERSION
|
15
|
+
s.date = NameTag::DATE
|
16
|
+
|
17
|
+
s.authors = [ 'Felix C. Stegerman' ]
|
18
|
+
s.email = %w{ flx@obfusk.net }
|
19
|
+
|
20
|
+
s.licenses = %w{ GPLv2 }
|
21
|
+
|
22
|
+
s.executables = %w{ nametag }
|
23
|
+
s.files = %w{ .yardopts README.md Rakefile bin/nametag } \
|
24
|
+
+ %w{ nametag.gemspec } \
|
25
|
+
+ Dir['{lib,spec}/**/*.rb']
|
26
|
+
|
27
|
+
s.add_runtime_dependency 'taglib-ruby'
|
28
|
+
|
29
|
+
s.add_development_dependency 'rake'
|
30
|
+
s.add_development_dependency 'rspec'
|
31
|
+
|
32
|
+
s.required_ruby_version = '>= 1.9.1'
|
33
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : nametag_spec.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-09-06
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'nametag'
|
13
|
+
|
14
|
+
nt = NameTag
|
15
|
+
|
16
|
+
describe nt do
|
17
|
+
|
18
|
+
ants = { # {{{1
|
19
|
+
file: '.../Between_the_Buried_and_Me/04-Colors_(2007)/' +
|
20
|
+
'05-Ants_of_the_Sky.mp3',
|
21
|
+
info: nt::Info.new(artist: 'Between_the_Buried_and_Me',
|
22
|
+
album: 'Colors', track: '05', title: 'Ants_of_the_Sky',
|
23
|
+
ext: 'mp3', album_n: '04', year: '2007'),
|
24
|
+
info_: nt::Info.new(artist: 'Between the Buried and Me',
|
25
|
+
album: 'Colors', track: '05', title: 'Ants of the Sky',
|
26
|
+
ext: 'mp3', album_n: '04', year: '2007')
|
27
|
+
} # }}}1
|
28
|
+
|
29
|
+
harl = { # {{{1
|
30
|
+
file: '.../Opeth/08-Ghost_Reveries_(2005)/' +
|
31
|
+
'05-Reverie|Harlequin_Forest.mp3',
|
32
|
+
info: nt::Info.new(artist: 'Opeth',
|
33
|
+
album: 'Ghost_Reveries', track: '05',
|
34
|
+
title: 'Reverie|Harlequin_Forest',
|
35
|
+
ext: 'mp3', album_n: '08', year: '2005'),
|
36
|
+
info_: nt::Info.new(artist: 'Opeth',
|
37
|
+
album: 'Ghost Reveries', track: '05',
|
38
|
+
title: 'Reverie/Harlequin Forest',
|
39
|
+
ext: 'mp3', album_n: '08', year: '2005')
|
40
|
+
} # }}}1
|
41
|
+
|
42
|
+
roll = { # {{{1
|
43
|
+
file: '.../The_Gathering/03-if_then_else_(2000)/' +
|
44
|
+
'01-Rollercoaster.mp3',
|
45
|
+
info: nt::Info.new(artist: 'The_Gathering',
|
46
|
+
album: 'if_then_else', track: '01',
|
47
|
+
title: 'Rollercoaster', ext: 'mp3',
|
48
|
+
album_n: '03', year: '2000'),
|
49
|
+
info_: nt::Info.new(artist: 'The Gathering',
|
50
|
+
album: 'if_then_else', track: '01',
|
51
|
+
title: 'Rollercoaster', ext: 'mp3',
|
52
|
+
album_n: '03', year: '2000')
|
53
|
+
} # }}}1
|
54
|
+
|
55
|
+
opts = nt.configure(nt::DEFAULTS.dup) do |c| # {{{1
|
56
|
+
c.process do |info, opts, tr|
|
57
|
+
if info.artist == 'The_Gathering' &&
|
58
|
+
info.album == 'if_then_else'
|
59
|
+
info.map_values { |k,v| k == :album ? v : tr[v] }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end # }}}1
|
63
|
+
|
64
|
+
context 'RX' do # {{{1
|
65
|
+
it 'matches ants' do
|
66
|
+
expect(nt::RX).to match ants[:file]
|
67
|
+
end
|
68
|
+
it 'matches harl' do
|
69
|
+
expect(nt::RX).to match harl[:file]
|
70
|
+
end
|
71
|
+
it 'matches roll' do
|
72
|
+
expect(nt::RX).to match roll[:file]
|
73
|
+
end
|
74
|
+
end # }}}1
|
75
|
+
|
76
|
+
context 'parse' do # {{{1
|
77
|
+
it 'matches ants' do
|
78
|
+
expect(nt.parse(ants[:file], opts)).to eq ants[:info]
|
79
|
+
end
|
80
|
+
it 'matches harl' do
|
81
|
+
expect(nt.parse(harl[:file], opts)).to eq harl[:info]
|
82
|
+
end
|
83
|
+
it 'matches roll' do
|
84
|
+
expect(nt.parse(roll[:file], opts)).to eq roll[:info]
|
85
|
+
end
|
86
|
+
end # }}}1
|
87
|
+
|
88
|
+
context 'process' do # {{{1
|
89
|
+
it 'transforms ants correctly' do
|
90
|
+
expect(nt.process(ants[:info], opts)).to eq ants[:info_]
|
91
|
+
end
|
92
|
+
it 'transforms harl correctly' do
|
93
|
+
expect(nt.process(harl[:info], opts)).to eq harl[:info_]
|
94
|
+
end
|
95
|
+
it 'transforms roll correctly' do
|
96
|
+
expect(nt.process(roll[:info], opts)).to eq roll[:info_]
|
97
|
+
end
|
98
|
+
end # }}}1
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nametag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Felix C. Stegerman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: taglib-ruby
|
16
|
+
requirement: &18703080 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *18703080
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &16200320 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *16200320
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &16197100 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *16197100
|
47
|
+
description: ! 'set audio file tags based on file name
|
48
|
+
|
49
|
+
|
50
|
+
...
|
51
|
+
|
52
|
+
'
|
53
|
+
email:
|
54
|
+
- flx@obfusk.net
|
55
|
+
executables:
|
56
|
+
- nametag
|
57
|
+
extensions: []
|
58
|
+
extra_rdoc_files: []
|
59
|
+
files:
|
60
|
+
- .yardopts
|
61
|
+
- README.md
|
62
|
+
- Rakefile
|
63
|
+
- bin/nametag
|
64
|
+
- nametag.gemspec
|
65
|
+
- lib/nametag.rb
|
66
|
+
- lib/nametag/version.rb
|
67
|
+
- spec/nametag_spec.rb
|
68
|
+
homepage: https://github.com/obfusk/nametag
|
69
|
+
licenses:
|
70
|
+
- GPLv2
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.9.1
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.8.11
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: set audio file tags based on file name
|
93
|
+
test_files: []
|
94
|
+
has_rdoc:
|