nametag 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/nametag.png)](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:
|