tagfile 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/Gemfile +7 -0
- data/LICENSE +9 -0
- data/README.md +83 -0
- data/lib/tagfile.rb +8 -0
- data/lib/tagfile/document.rb +22 -0
- data/lib/tagfile/extractions.rb +30 -0
- data/lib/tagfile/extractor.rb +37 -0
- data/lib/tagfile/shared.rb +16 -0
- data/lib/tagfile/verifications.rb +19 -0
- data/lib/tagfile/verifier.rb +32 -0
- data/lib/tagfile/version.rb +3 -0
- data/spec/files/invalid_file_format.txt +0 -0
- data/spec/files/missing_all.flac +0 -0
- data/spec/files/missing_artist.flac +0 -0
- data/spec/files/tranc/303/251 (ft.) _.mp3 +0 -0
- data/spec/files/valid_file.flac +0 -0
- data/spec/files/valid_file.mp3 +0 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/tagfile/document_spec.rb +17 -0
- data/spec/tagfile/encoding_spec.rb +20 -0
- data/spec/tagfile/extractor_spec.rb +99 -0
- data/spec/tagfile/verifier_spec.rb +87 -0
- data/tagfile.gemspec +26 -0
- metadata +115 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright (C) 2012 Culley Smith
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
8
|
+
|
9
|
+
Released under MIT License.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
TagFile
|
2
|
+
=======
|
3
|
+
|
4
|
+
TagFile is a simple Class for building objects from binary audio files. It currently supports .flac, .mp3, & .ogg file formats. Using the ultra-fast [TagLib2](http://rubygems.org/gems/taglib2), TagFile extracts embedded metadata and builds a hash from user-defined values. This hash can be easily serialized and persisted in a database or document store.
|
5
|
+
|
6
|
+
Example usage
|
7
|
+
-------------
|
8
|
+
|
9
|
+
```
|
10
|
+
class Track < TagFile::Document
|
11
|
+
extract_tag_for :artist, :album
|
12
|
+
end
|
13
|
+
|
14
|
+
track = Track.new('valid_file.flac')
|
15
|
+
track.tags => {artist: 'artist', album: 'album'}
|
16
|
+
```
|
17
|
+
|
18
|
+
Extractions
|
19
|
+
-----------
|
20
|
+
In order to build '#tags' you *must* specify which *tags* to use. The following tags can be extracted:
|
21
|
+
|
22
|
+
Embedded tags (from TagLib2)
|
23
|
+
|
24
|
+
* album
|
25
|
+
* artist
|
26
|
+
* genre
|
27
|
+
* title
|
28
|
+
* track
|
29
|
+
* year
|
30
|
+
|
31
|
+
Custom tags (from TagFile)
|
32
|
+
|
33
|
+
* path
|
34
|
+
* filename
|
35
|
+
* format
|
36
|
+
|
37
|
+
```
|
38
|
+
class Track < TagFile::Document
|
39
|
+
extract_tag_for :artist
|
40
|
+
|
41
|
+
# extract_tag_for :artist, :path, :title
|
42
|
+
# extract_tag_for :all
|
43
|
+
# extract_tag_for :all, except: [:artist, :album]
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
Verifications
|
48
|
+
-------------
|
49
|
+
|
50
|
+
TagFile includes several user-specified verifications. While **path** and **format** have built-in verifications, format can be customized to verify a subset of formats. Note: all valid TagFile objects will have a filename, length, path, and format attribute by default.
|
51
|
+
|
52
|
+
```
|
53
|
+
class Track < TagFile::Document
|
54
|
+
extract_tag_for :artist
|
55
|
+
|
56
|
+
verify_tag_for :artist
|
57
|
+
end
|
58
|
+
|
59
|
+
class Track < TagFile::Document
|
60
|
+
extract_tags_for :all
|
61
|
+
|
62
|
+
verify_tag_for :artist, :album
|
63
|
+
# verify_tag_for :all
|
64
|
+
# verify_tag_for :all, except: [:artist, :genre]
|
65
|
+
# verify_format_is :flac, :mp3
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
Errors
|
70
|
+
------
|
71
|
+
|
72
|
+
With custom verifications in place, all errors are written to '#errors'.
|
73
|
+
|
74
|
+
```
|
75
|
+
class Track < TagFile::Document
|
76
|
+
extract_tag_for :artist
|
77
|
+
verify_tag_for :artist
|
78
|
+
verify_format_is :mp3
|
79
|
+
end
|
80
|
+
|
81
|
+
track = Track.new('missing_artist.flac')
|
82
|
+
track.errors => ["Missing artist tag: missing_artist.flac", "File not of format :mp3: missing_artist.flac"]
|
83
|
+
```
|
data/lib/tagfile.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'tagfile'
|
2
|
+
require 'tagfile/extractor'
|
3
|
+
require 'tagfile/verifier'
|
4
|
+
|
5
|
+
module TagFile
|
6
|
+
class Document
|
7
|
+
include Extractor
|
8
|
+
include Verifier
|
9
|
+
|
10
|
+
attr_reader :path, :tags
|
11
|
+
attr_accessor :errors
|
12
|
+
|
13
|
+
def initialize(path)
|
14
|
+
@path = verify_presence_of(path)
|
15
|
+
@filename = File.basename(@path)
|
16
|
+
@format = verify_format_of(@path)
|
17
|
+
@taglib = TagLib::File.new(@path)
|
18
|
+
@tags = make_tag_attributes
|
19
|
+
@errors = run_all_verifications
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'tagfile'
|
2
|
+
|
3
|
+
module Extractions
|
4
|
+
def extract_tag_for(*tags)
|
5
|
+
tags = build_list_of(tags)
|
6
|
+
tags.each { |tag| define_tag_method(tag) }
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
def define_tag_method(meth)
|
11
|
+
if EMBEDDED_TAGS.include?(meth)
|
12
|
+
define_embedded_tags(meth)
|
13
|
+
elsif CUSTOM_TAGS.include?(meth)
|
14
|
+
define_custom_tags(meth)
|
15
|
+
else
|
16
|
+
raise("Invalid tag: #{meth}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def define_embedded_tags(meth)
|
21
|
+
define_method(meth) do
|
22
|
+
taglib = self.instance_variable_get('@taglib')
|
23
|
+
format_embedded_value(meth, taglib)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def define_custom_tags(meth)
|
28
|
+
define_method(meth) { self.instance_variable_get("@#{meth}") }
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'tagfile'
|
2
|
+
require 'tagfile/extractions'
|
3
|
+
require 'tagfile/shared'
|
4
|
+
|
5
|
+
module TagFile
|
6
|
+
module Extractor
|
7
|
+
private
|
8
|
+
def make_tag_attributes
|
9
|
+
attrs = {}
|
10
|
+
self.class.instance_methods(false).sort.each {|a| attrs[a] = self.send(a) if ALL_TAGS.include?(a) }
|
11
|
+
attrs
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included(base)
|
15
|
+
base.extend(Extractions)
|
16
|
+
base.extend(Shared)
|
17
|
+
end
|
18
|
+
|
19
|
+
def format_embedded_value(meth, taglib)
|
20
|
+
sent = taglib.send(meth)
|
21
|
+
sanitized = remove_zeroes(meth, sent)
|
22
|
+
encoded = utf_encoded(sanitized)
|
23
|
+
end
|
24
|
+
|
25
|
+
def time_format(length)
|
26
|
+
Time.at(length).gmtime.strftime("%R:%S")
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_zeroes(meth, tag)
|
30
|
+
[:track, :year].include?(meth) && tag == 0 ? "" : tag
|
31
|
+
end
|
32
|
+
|
33
|
+
def utf_encoded(tag)
|
34
|
+
tag.to_s.force_encoding('UTF-8')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'tagfile'
|
2
|
+
|
3
|
+
module Shared
|
4
|
+
private
|
5
|
+
def build_list_of(options)
|
6
|
+
all_tags = ALL_TAGS
|
7
|
+
|
8
|
+
if options == [:all]
|
9
|
+
options = all_tags
|
10
|
+
elsif options[0] == :all && options[1][:except]
|
11
|
+
options = all_tags - options[1][:except]
|
12
|
+
else
|
13
|
+
options
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'tagfile'
|
2
|
+
|
3
|
+
module Verifications
|
4
|
+
def verify_tag_for(*tags)
|
5
|
+
tags = build_list_of(tags)
|
6
|
+
tags.each do |tag|
|
7
|
+
define_method "verify_tag_for_#{tag}" do
|
8
|
+
"Missing #{tag} tag: #{self.path}" if self.send(tag).empty?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def verify_format_is(*formats)
|
14
|
+
define_method "verify_format_is_#{formats}" do
|
15
|
+
format = self.instance_variable_get('@format').to_sym
|
16
|
+
"File is not of format #{formats}: #{self.path}" unless formats.include?(format)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'tagfile'
|
2
|
+
require 'tagfile/verifications'
|
3
|
+
require 'tagfile/shared'
|
4
|
+
|
5
|
+
module TagFile
|
6
|
+
module Verifier
|
7
|
+
private
|
8
|
+
def verify_presence_of(path)
|
9
|
+
raise("Path not found: #{path}") unless File.exists?(path)
|
10
|
+
path
|
11
|
+
end
|
12
|
+
|
13
|
+
def verify_format_of(path)
|
14
|
+
format = File.extname(self.path).downcase.gsub(/\./,'')
|
15
|
+
formats = %w(flac mp3 ogg)
|
16
|
+
raise("Invalid file format: #{path} *valid formats: #{formats}") unless formats.include?(format)
|
17
|
+
format
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_all_verifications
|
21
|
+
errs = []
|
22
|
+
verification_methods = self.methods.select {|meth| meth =~ /^verify_/}
|
23
|
+
verification_methods.each { |veri| errs << self.send(veri) }
|
24
|
+
errs.compact
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.included(base)
|
28
|
+
base.extend(Verifications)
|
29
|
+
base.extend(Shared)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'tagfile/document'
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
5
|
+
config.run_all_when_everything_filtered = true
|
6
|
+
config.filter_run :focus
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_document_with(attr)
|
10
|
+
Class.new(TagFile::Document){ extract_tag_for attr }
|
11
|
+
end
|
12
|
+
|
13
|
+
def verify_document_with(extracts, tags, formats)
|
14
|
+
Class.new(TagFile::Document) do
|
15
|
+
extract_tag_for extracts
|
16
|
+
verify_tag_for tags
|
17
|
+
verify_format_is formats
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TagFile
|
4
|
+
describe Document do
|
5
|
+
let(:path) { 'spec/files/valid_file.flac' }
|
6
|
+
|
7
|
+
subject { Document.new(path) }
|
8
|
+
|
9
|
+
it { should respond_to(:path) }
|
10
|
+
it { should respond_to(:tags) }
|
11
|
+
|
12
|
+
it { should respond_to(:errors) }
|
13
|
+
its(:errors) { should == [] }
|
14
|
+
|
15
|
+
its(:path) { should == path }
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe "file with foreign characters" do
|
6
|
+
let(:document) { create_document_with(:all) }
|
7
|
+
subject { document.new(path) }
|
8
|
+
|
9
|
+
let(:album) { 'trancé' }
|
10
|
+
let(:artist) { 'trancé' }
|
11
|
+
let(:filename) { 'trancé (ft.) _.mp3' }
|
12
|
+
let(:path) { 'spec/files/trancé (ft.) _.mp3' }
|
13
|
+
let(:title) { 'trancé' }
|
14
|
+
|
15
|
+
its(:album) { should == album }
|
16
|
+
its(:artist) { should == artist }
|
17
|
+
its(:filename) { should == filename }
|
18
|
+
its(:path) { should == path }
|
19
|
+
its(:title) { should == title }
|
20
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TagFile
|
4
|
+
describe Extractor do
|
5
|
+
context "class methods" do
|
6
|
+
let(:document) { create_document_with(:all) }
|
7
|
+
subject { document }
|
8
|
+
|
9
|
+
it { should respond_to(:extract_tag_for) }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#extract_tags_for" do
|
13
|
+
subject { document.new(path) }
|
14
|
+
|
15
|
+
let(:album) { 'Llama Album' }
|
16
|
+
let(:artist) { 'Llama Artist' }
|
17
|
+
let(:filename) { 'valid_file.flac' }
|
18
|
+
let(:genre) { 'Llama Genre' }
|
19
|
+
let(:path) { 'spec/files/valid_file.flac' }
|
20
|
+
let(:title) { 'Llama Title' }
|
21
|
+
let(:track) { '1' }
|
22
|
+
let(:format) { 'flac' }
|
23
|
+
let(:year) { '2012' }
|
24
|
+
let(:all) { { album: album,
|
25
|
+
artist: artist,
|
26
|
+
filename: filename,
|
27
|
+
genre: genre,
|
28
|
+
path: path,
|
29
|
+
title: title,
|
30
|
+
track: track,
|
31
|
+
format: format,
|
32
|
+
year: year
|
33
|
+
} }
|
34
|
+
|
35
|
+
context "embedded" do
|
36
|
+
let(:document) { create_document_with(:artist) }
|
37
|
+
|
38
|
+
it { should respond_to(:artist) }
|
39
|
+
its(:artist) { should == artist }
|
40
|
+
its(:tags) { should == {artist: artist} }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "custom" do
|
44
|
+
let(:document) { create_document_with(:path) }
|
45
|
+
|
46
|
+
it { should respond_to(:path) }
|
47
|
+
its(:path) { should == path }
|
48
|
+
its(:tags) { should == {path: path} }
|
49
|
+
end
|
50
|
+
|
51
|
+
context ":all" do
|
52
|
+
let(:document) { create_document_with(:all) }
|
53
|
+
|
54
|
+
it { should respond_to(:album) }
|
55
|
+
it { should respond_to(:artist) }
|
56
|
+
it { should respond_to(:filename) }
|
57
|
+
it { should respond_to(:genre) }
|
58
|
+
it { should respond_to(:path) }
|
59
|
+
it { should respond_to(:title) }
|
60
|
+
it { should respond_to(:track) }
|
61
|
+
it { should respond_to(:format) }
|
62
|
+
it { should respond_to(:year) }
|
63
|
+
|
64
|
+
its(:album) { should == album }
|
65
|
+
its(:artist) { should == artist }
|
66
|
+
its(:filename) { should == filename }
|
67
|
+
its(:genre) { should == genre }
|
68
|
+
its(:path) { should == path }
|
69
|
+
its(:title) { should == title }
|
70
|
+
its(:track) { should == track }
|
71
|
+
its(:format) { should == format }
|
72
|
+
its(:year) { should == year }
|
73
|
+
its(:tags) { should == all }
|
74
|
+
end
|
75
|
+
|
76
|
+
context ":all, except: [:path, :genre]" do
|
77
|
+
let(:document) { Class.new(TagFile::Document) { extract_tag_for :all, except: [:genre, :path] } }
|
78
|
+
|
79
|
+
its(:tags) { should == { artist: artist,
|
80
|
+
album: album,
|
81
|
+
filename: filename,
|
82
|
+
title: title,
|
83
|
+
track: track,
|
84
|
+
format: format,
|
85
|
+
year: year
|
86
|
+
} }
|
87
|
+
end
|
88
|
+
|
89
|
+
context "raise errors" do
|
90
|
+
it "invalid tag" do
|
91
|
+
expect{
|
92
|
+
document = create_document_with(:none)
|
93
|
+
document.new(path)
|
94
|
+
}.to raise_error("Invalid tag: none")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TagFile
|
4
|
+
describe Verifier do
|
5
|
+
let(:document) { Class.new(TagFile::Document) }
|
6
|
+
let(:path) { 'spec/files/valid_file.flac' }
|
7
|
+
|
8
|
+
subject { document }
|
9
|
+
|
10
|
+
it { should respond_to(:verify_tag_for).with(1).argument }
|
11
|
+
|
12
|
+
describe "raise error" do
|
13
|
+
it "path not found" do
|
14
|
+
@bad_path = "bad path"
|
15
|
+
expect{
|
16
|
+
Document.new(@bad_path)
|
17
|
+
}.to raise_error("Path not found: #{@bad_path}")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "invalid file format" do
|
21
|
+
@bad_format = 'spec/files/invalid_file_format.txt'
|
22
|
+
expect{
|
23
|
+
Document.new(@bad_format)
|
24
|
+
}.to raise_error("Invalid file format: #{@bad_format} *valid formats: [\"flac\", \"mp3\", \"ogg\"]")
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "verify_tag_for errors" do
|
28
|
+
let(:missing_artist) { 'spec/files/missing_artist.flac' }
|
29
|
+
let(:missing_all) { 'spec/files/missing_all.flac' }
|
30
|
+
|
31
|
+
context "missing artist" do
|
32
|
+
let(:document) { verify_document_with(:artist, :artist, :flac) }
|
33
|
+
subject { document.new(missing_artist) }
|
34
|
+
|
35
|
+
its(:errors) { should == ["Missing artist tag: #{missing_artist}"] }
|
36
|
+
|
37
|
+
it "tags should not include verify_tag_for errors" do
|
38
|
+
subject.tags.
|
39
|
+
should_not include(:verify_tag_for_artist=>["Missing artist tag: #{missing_artist}"])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context ":all" do
|
44
|
+
let(:document) { verify_document_with(:all, :all, :flac) }
|
45
|
+
subject { document.new(missing_all) }
|
46
|
+
|
47
|
+
its(:errors) { should include("Missing album tag: #{missing_all}") }
|
48
|
+
its(:errors) { should include("Missing artist tag: #{missing_all}") }
|
49
|
+
its(:errors) { should include("Missing genre tag: #{missing_all}") }
|
50
|
+
its(:errors) { should include("Missing title tag: #{missing_all}") }
|
51
|
+
its(:errors) { should include("Missing track tag: #{missing_all}") }
|
52
|
+
its(:errors) { should include("Missing year tag: #{missing_all}") }
|
53
|
+
end
|
54
|
+
|
55
|
+
it ":all, except: [:artist, :album]" do
|
56
|
+
document = Class.new(TagFile::Document) do
|
57
|
+
extract_tag_for :all
|
58
|
+
verify_tag_for :all, except: [:artist]
|
59
|
+
end
|
60
|
+
new = document.new(missing_all)
|
61
|
+
|
62
|
+
new.errors.should_not include("Missing artist tag: #{missing_all}")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "verify_format_is" do
|
67
|
+
let(:document) { verify_document_with(:artist, :artist, :flac) }
|
68
|
+
let(:mp3) { 'spec/files/valid_file.mp3' }
|
69
|
+
|
70
|
+
context "not flac" do
|
71
|
+
subject { document.new(mp3) }
|
72
|
+
|
73
|
+
its(:errors) { should include("File is not of format [:flac]: #{mp3}") }
|
74
|
+
end
|
75
|
+
|
76
|
+
context "is flac" do
|
77
|
+
subject { document.new(path) }
|
78
|
+
|
79
|
+
it "format" do
|
80
|
+
puts subject.instance_variable_get('@format')
|
81
|
+
end
|
82
|
+
its(:errors) { should_not include("File is not of format [:flac]: #{path}") }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/tagfile.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
|
5
|
+
require 'tagfile'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'tagfile'
|
9
|
+
s.version = TagFile::VERSION
|
10
|
+
s.authors = ["Culley Smith"]
|
11
|
+
s.email = ["culley.smith@gmail.com"]
|
12
|
+
s.homepage = %q{http://madcasts.com}
|
13
|
+
s.summary = %q{A library for extracting tags from binary files.}
|
14
|
+
s.description = %q{TagFile is a simple Class for building objects from binary audio files. It currently supports .flac, .mp3, & .ogg file formats.}
|
15
|
+
|
16
|
+
s.required_ruby_version = '>= 1.9.3'
|
17
|
+
s.required_rubygems_version = '>= 1.3.6'
|
18
|
+
|
19
|
+
s.add_dependency 'taglib2', '~> 0.1.5'
|
20
|
+
s.add_development_dependency 'rspec', '~> 2.0'
|
21
|
+
|
22
|
+
git_files = `git ls-files -z`.split("\0") rescue ''
|
23
|
+
s.files = git_files
|
24
|
+
s.test_files = `git ls-files -z -- {test,spec,features}/*`.split("\0")
|
25
|
+
s.require_paths = ['lib']
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tagfile
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Culley Smith
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: taglib2
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.1.5
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.1.5
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.0'
|
46
|
+
description: TagFile is a simple Class for building objects from binary audio files.
|
47
|
+
It currently supports .flac, .mp3, & .ogg file formats.
|
48
|
+
email:
|
49
|
+
- culley.smith@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- .rspec
|
56
|
+
- Gemfile
|
57
|
+
- LICENSE
|
58
|
+
- README.md
|
59
|
+
- lib/tagfile.rb
|
60
|
+
- lib/tagfile/document.rb
|
61
|
+
- lib/tagfile/extractions.rb
|
62
|
+
- lib/tagfile/extractor.rb
|
63
|
+
- lib/tagfile/shared.rb
|
64
|
+
- lib/tagfile/verifications.rb
|
65
|
+
- lib/tagfile/verifier.rb
|
66
|
+
- lib/tagfile/version.rb
|
67
|
+
- spec/files/invalid_file_format.txt
|
68
|
+
- spec/files/missing_all.flac
|
69
|
+
- spec/files/missing_artist.flac
|
70
|
+
- spec/files/trancé (ft.) _.mp3
|
71
|
+
- spec/files/valid_file.flac
|
72
|
+
- spec/files/valid_file.mp3
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
- spec/tagfile/document_spec.rb
|
75
|
+
- spec/tagfile/encoding_spec.rb
|
76
|
+
- spec/tagfile/extractor_spec.rb
|
77
|
+
- spec/tagfile/verifier_spec.rb
|
78
|
+
- tagfile.gemspec
|
79
|
+
homepage: http://madcasts.com
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.9.3
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.6
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 1.8.21
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: A library for extracting tags from binary files.
|
103
|
+
test_files:
|
104
|
+
- spec/files/invalid_file_format.txt
|
105
|
+
- spec/files/missing_all.flac
|
106
|
+
- spec/files/missing_artist.flac
|
107
|
+
- spec/files/trancé (ft.) _.mp3
|
108
|
+
- spec/files/valid_file.flac
|
109
|
+
- spec/files/valid_file.mp3
|
110
|
+
- spec/spec_helper.rb
|
111
|
+
- spec/tagfile/document_spec.rb
|
112
|
+
- spec/tagfile/encoding_spec.rb
|
113
|
+
- spec/tagfile/extractor_spec.rb
|
114
|
+
- spec/tagfile/verifier_spec.rb
|
115
|
+
has_rdoc:
|