popcap 0.8.0 → 0.9.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.
- checksums.yaml +4 -4
- data/README.md +82 -45
- data/lib/pop_cap/audio_file.rb +102 -30
- data/lib/pop_cap/formatted_hash.rb +40 -0
- data/lib/pop_cap/{tag/tag_struct.rb → tag_struct.rb} +10 -0
- data/lib/pop_cap/{tag/tag_hash.rb → unformatted_hash.rb} +5 -3
- data/lib/pop_cap/version.rb +1 -1
- data/spec/lib/pop_cap/audio_file_spec.rb +73 -23
- data/spec/lib/pop_cap/formatted_hash_spec.rb +32 -0
- data/spec/lib/pop_cap/formatter_spec.rb +9 -8
- data/spec/lib/pop_cap/{tag/tag_struct_spec.rb → tag_struct_spec.rb} +16 -3
- data/spec/lib/pop_cap/unformatted_hash_spec.rb +43 -0
- data/spec/support/popcap_spec_helper.rb +2 -20
- metadata +11 -20
- data/lib/pop_cap/tag/formatted_tag.rb +0 -31
- data/lib/pop_cap/taggable.rb +0 -120
- data/spec/integration/convert_audio_file_spec.rb +0 -15
- data/spec/integration/read_metatags_spec.rb +0 -12
- data/spec/integration/update_metatags_spec.rb +0 -20
- data/spec/lib/pop_cap/tag/formatted_tag_spec.rb +0 -29
- data/spec/lib/pop_cap/tag/tag_hash_spec.rb +0 -35
- data/spec/lib/pop_cap/taggable_spec.rb +0 -76
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe1804b885ed55227148832677e5697bd95d8ca8
|
4
|
+
data.tar.gz: f0d5ac62e3690a6aaaca546a7abc86a218268366
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c0bd62beca21f4fe86bee66638c69a594deb3418e1b9b12e6c5072dac4930482bc953c4f7404ab71e3fc3fefeb641b906e67d32fb7fa7debffa8d90df35992e
|
7
|
+
data.tar.gz: 7d11a95c9bc6829996d744764006ab049fbc5ac3b67eada66ae779aeb96475df35b71bfdcc07eda01cf9b73796556345258733abfbd4a543132f7ccf1775923e
|
data/README.md
CHANGED
@@ -22,40 +22,71 @@ Read the metadata tags from an audio file.
|
|
22
22
|
```
|
23
23
|
audio_file = PopCap::AudioFile.new('sample.flac')
|
24
24
|
|
25
|
-
audio_file.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
25
|
+
audio_file.raw_output => Returns JSON for the raw output from
|
26
|
+
running "ffprobe -show_format -print_format json."
|
27
|
+
|
28
|
+
{
|
29
|
+
"format":
|
30
|
+
{
|
31
|
+
"filename":"spec/fixtures/sample.flac",
|
32
|
+
"nb_streams":1,
|
33
|
+
"format_name":"flac",
|
34
|
+
"format_long_name":"raw FLAC",
|
35
|
+
"duration":"1.000000",
|
36
|
+
"size":"18291",
|
37
|
+
"bit_rate":"146328",
|
38
|
+
|
39
|
+
"tags":
|
40
|
+
{
|
41
|
+
"GENRE":"Sample Genre",
|
42
|
+
"track":"01",
|
43
|
+
"ALBUM":"Sample Album",
|
44
|
+
"DATE":"2012",
|
45
|
+
"TITLE":"Sample Title",
|
46
|
+
"ARTIST":"Sample Artist"
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
audio_file.unformatted => Returns a Ruby hash after sanitizing
|
52
|
+
the raw output of #raw_output.
|
53
|
+
|
54
|
+
{
|
55
|
+
filename: '$HOME/spec/fixtures/sample.flac',
|
56
|
+
nb_streams: 1,
|
57
|
+
format_name: 'flac',
|
58
|
+
format_long_name: 'raw FLAC',
|
59
|
+
duration: '1.000000',
|
60
|
+
filesize: '18291',
|
61
|
+
bit_rate: '146328',
|
62
|
+
genre: 'Sample Genre',
|
63
|
+
track: '01',
|
64
|
+
album: 'Sample Album',
|
65
|
+
date: '2012',
|
66
|
+
title: 'Sample Title',
|
67
|
+
artist: 'Sample Artist'
|
68
|
+
}
|
69
|
+
|
70
|
+
audio_file.formatted => Returns a Ruby hash after sanitizing
|
71
|
+
the raw output of #raw_output. It also applies internal formatters
|
72
|
+
on fields such as duration, bit_rate, filesize, & date,
|
73
|
+
returning human readable output.
|
74
|
+
|
75
|
+
{
|
76
|
+
filename: '$HOME/spec/fixtures/sample.flac',
|
77
|
+
nb_streams: 1,
|
78
|
+
format_name: 'flac',
|
79
|
+
format_long_name: 'raw FLAC',
|
80
|
+
duration: '1',
|
81
|
+
filesize: '17.9K',
|
82
|
+
bit_rate: '146 kb/s',
|
83
|
+
genre: 'Sample Genre',
|
84
|
+
track: '01',
|
85
|
+
album: 'Sample Album',
|
86
|
+
date: 2012,
|
87
|
+
title: 'Sample Title',
|
88
|
+
artist: 'Sample Artist'
|
89
|
+
}
|
59
90
|
|
60
91
|
audio_file.tags => Returns a tag structure using the #formatted values.
|
61
92
|
|
@@ -64,38 +95,43 @@ audio_file.tags => Returns a tag structure using the #formatted values.
|
|
64
95
|
.bit_rate => '146 kb/s'
|
65
96
|
.date => 2012
|
66
97
|
.duration => '1'
|
67
|
-
.filename => 'spec/fixtures/sample.flac'
|
98
|
+
.filename => ''$HOME/spec/fixtures/sample.flac'
|
68
99
|
.filesize => '17.9K'
|
69
100
|
.format_long_name => 'raw FLAC'
|
70
101
|
.format_name => 'flac'
|
71
102
|
.genre => 'Sample Genre'
|
72
|
-
.nb_streams =>
|
103
|
+
.nb_streams => 1
|
73
104
|
.start_time => 'N/A'
|
74
105
|
.title => 'Sample Title'
|
75
106
|
.track => '01'
|
76
107
|
|
77
|
-
audio_file.reload! => Reload an instance of itself,
|
108
|
+
audio_file.reload! => Reload an instance of itself,
|
109
|
+
useful when updating tags. This behavior is built in,
|
110
|
+
but will need to be called manually in certain situations;
|
111
|
+
(such as moving a file on the file system, deleting a file, etc.)
|
78
112
|
```
|
79
113
|
|
80
114
|
Update Tags
|
81
115
|
-----------
|
82
116
|
|
83
|
-
This will update the metadata tags for an audio file.
|
117
|
+
This will update the metadata tags for an audio file.
|
118
|
+
It will also dynamically add any newly provided tags.
|
119
|
+
It takes a hash of attributes.
|
84
120
|
|
85
121
|
```
|
86
122
|
audio_file = PopCap::AudioFile.new('sample.flac')
|
87
|
-
audio_file.
|
123
|
+
audio_file.update(artist: 'David Bowie')
|
88
124
|
|
89
|
-
audio_file.
|
125
|
+
audio_file.update(fancy_new_tag: 'Custom Tag Input')
|
90
126
|
```
|
91
127
|
|
92
128
|
Convert
|
93
129
|
-------
|
94
130
|
|
95
|
-
This will convert between audio file formats.
|
96
|
-
|
97
|
-
|
98
|
-
|
131
|
+
This will convert between audio file formats.
|
132
|
+
It is restricted to basic audio formats.
|
133
|
+
It also takes an optional bitrate for mp3 formats.
|
134
|
+
The original file is preserved during the conversion.
|
99
135
|
|
100
136
|
```
|
101
137
|
audio_file = PopCap::AudioFile.new('sample.flac')
|
@@ -128,7 +164,8 @@ audio_file.move('destination') # = > moves file to destination
|
|
128
164
|
|
129
165
|
audio_file.rename('new_name.flac') # => renames file
|
130
166
|
|
131
|
-
audio_file.restore # => restores file from backup_path
|
167
|
+
audio_file.restore # => restores file from backup_path;
|
168
|
+
takes an optional path
|
132
169
|
|
133
170
|
audio_file.tmppath # => returns the temporary path, e.g. '/tmp/sample.flac'
|
134
171
|
```
|
data/lib/pop_cap/audio_file.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'pop_cap/ffmpeg/converter'
|
2
2
|
require 'pop_cap/ffmpeg/tag_reader'
|
3
3
|
require 'pop_cap/ffmpeg/tag_writer'
|
4
|
+
require 'pop_cap/unformatted_hash'
|
5
|
+
require 'pop_cap/formatted_hash'
|
6
|
+
require 'pop_cap/tag_struct'
|
4
7
|
require 'pop_cap/fileable'
|
5
|
-
require 'pop_cap/taggable'
|
6
8
|
|
7
9
|
module PopCap
|
8
10
|
FileNotFound = Class.new(StandardError)
|
@@ -17,10 +19,10 @@ module PopCap
|
|
17
19
|
#
|
18
20
|
#
|
19
21
|
class AudioFile
|
22
|
+
include Fileable
|
20
23
|
attr_accessor :filepath
|
21
24
|
|
22
|
-
|
23
|
-
include Taggable
|
25
|
+
::MEMOIZABLES = %w(@raw @unformatted_hash @formatted_hash @tag_struct)
|
24
26
|
|
25
27
|
# Public: Initialize
|
26
28
|
#
|
@@ -43,8 +45,8 @@ module PopCap
|
|
43
45
|
# audio_file.convert('mp3', 128)
|
44
46
|
# # => 'spec/fixtures/sample.mp3'
|
45
47
|
#
|
46
|
-
def convert(format, bitrate=192)
|
47
|
-
|
48
|
+
def convert(format, bitrate=192, converter: Converter)
|
49
|
+
converter.convert(filepath, {format: format, bitrate: bitrate})
|
48
50
|
end
|
49
51
|
|
50
52
|
# Public: raw_tags
|
@@ -54,25 +56,96 @@ module PopCap
|
|
54
56
|
# audio_file = AudioFile.new('spec/fixtures/sample.flac')
|
55
57
|
# audio_file.raw_tags
|
56
58
|
# # =>
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
|
75
|
-
|
59
|
+
#
|
60
|
+
# {
|
61
|
+
# "format":
|
62
|
+
# {
|
63
|
+
# "filename":"spec/fixtures/sample.flac",
|
64
|
+
# "nb_streams":1,
|
65
|
+
# "format_name":"flac",
|
66
|
+
# "format_long_name":"raw FLAC",
|
67
|
+
# "duration":"1.000000",
|
68
|
+
# "size":"18291",
|
69
|
+
# "bit_rate":"146328",
|
70
|
+
# "tags":
|
71
|
+
# {
|
72
|
+
# "GENRE":"Sample Genre",
|
73
|
+
# "track":"01",
|
74
|
+
# "ALBUM":"Sample Album",
|
75
|
+
# "DATE":"2012",
|
76
|
+
# "TITLE":"Sample Title",
|
77
|
+
# "ARTIST":"Sample Artist"
|
78
|
+
# }
|
79
|
+
# }
|
80
|
+
# }
|
81
|
+
#
|
82
|
+
def raw_output(tag_reader: TagReader)
|
83
|
+
@raw ||= tag_reader.read(filepath)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Public: This method returns a sanitized version of #raw_tags.
|
87
|
+
#
|
88
|
+
# {
|
89
|
+
# filename: '$HOME/spec/fixtures/sample.flac',
|
90
|
+
# nb_streams: 1,
|
91
|
+
# format_name: 'flac',
|
92
|
+
# format_long_name: 'raw FLAC',
|
93
|
+
# duration: '1.000000',
|
94
|
+
# filesize: '18291',
|
95
|
+
# bit_rate: '146328',
|
96
|
+
# genre: 'Sample Genre',
|
97
|
+
# track: '01',
|
98
|
+
# album: 'Sample Album',
|
99
|
+
# date: '2012',
|
100
|
+
# title: 'Sample Title',
|
101
|
+
# artist: 'Sample Artist'
|
102
|
+
# }
|
103
|
+
#
|
104
|
+
def unformatted(unformatted_hash: UnformattedHash)
|
105
|
+
@unformatted_hash ||= unformatted_hash.hash(raw_output)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Public: This method returns #unformatted tags with
|
109
|
+
# any available Formatters automatically applied.
|
110
|
+
#
|
111
|
+
# {
|
112
|
+
# filename: '$HOME/spec/fixtures/sample.flac',
|
113
|
+
# nb_streams: 1,
|
114
|
+
# format_name: 'flac',
|
115
|
+
# format_long_name: 'raw FLAC',
|
116
|
+
# duration: '1',
|
117
|
+
# filesize: '17.9K',
|
118
|
+
# bit_rate: '146 kb/s',
|
119
|
+
# genre: 'Sample Genre',
|
120
|
+
# track: '01',
|
121
|
+
# album: 'Sample Album',
|
122
|
+
# date: 2012,
|
123
|
+
# title: 'Sample Title',
|
124
|
+
# artist: 'Sample Artist'
|
125
|
+
# }
|
126
|
+
def formatted(formatted_hash: FormattedHash)
|
127
|
+
@formatted_hash ||= formatted_hash.formatted(unformatted)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Public: This method builds a tag structure from #formatted.
|
131
|
+
#
|
132
|
+
# .album => 'Sample Album'
|
133
|
+
# .artist => 'Sample Artist'
|
134
|
+
# .bit_rate => '146 kb/s'
|
135
|
+
# .date => 2012
|
136
|
+
# .duration => '1'
|
137
|
+
# .filename => 'spec/fixtures/sample.flac'
|
138
|
+
# .filesize => '17.9K'
|
139
|
+
# .format_long_name => 'raw FLAC'
|
140
|
+
# .format_name => 'flac'
|
141
|
+
# .genre => 'Sample Genre'
|
142
|
+
# .nb_streams => '1'
|
143
|
+
# .start_time => 'N/A'
|
144
|
+
# .title => 'Sample Title'
|
145
|
+
# .track => '01'
|
146
|
+
#
|
147
|
+
def tags(tag_struct: TagStruct)
|
148
|
+
@tag_struct ||= tag_struct.new(formatted)
|
76
149
|
end
|
77
150
|
|
78
151
|
# Public: This method reloads the current instance.
|
@@ -81,20 +154,19 @@ module PopCap
|
|
81
154
|
# audio_file.reload!
|
82
155
|
#
|
83
156
|
def reload!
|
84
|
-
|
85
|
-
super
|
157
|
+
::MEMOIZABLES.each { |var| self.instance_variable_set(var, nil) }
|
86
158
|
end
|
87
159
|
|
88
|
-
# Public:
|
160
|
+
# Public: update(updates)
|
89
161
|
# Updates existing tags, adds a tag if it does not exist.
|
90
162
|
#
|
91
|
-
# updates - This takes a hash of
|
163
|
+
# updates - This takes a hash of tags.
|
92
164
|
#
|
93
165
|
# Examples
|
94
166
|
#
|
95
|
-
# audio_file.
|
167
|
+
# audio_file.update(artist: 'New Artist', album: 'New Album')
|
96
168
|
#
|
97
|
-
def
|
169
|
+
def update(updates={})
|
98
170
|
TagWriter.write(filepath, updates)
|
99
171
|
self.reload!
|
100
172
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'pop_cap/class_support'
|
2
|
+
require 'pop_cap/formatter'
|
3
|
+
|
4
|
+
module PopCap
|
5
|
+
# Public: This class will apply all Formatters to
|
6
|
+
# the supplied hash.
|
7
|
+
#
|
8
|
+
# new - Supply an unformatted hash.
|
9
|
+
#
|
10
|
+
class FormattedHash
|
11
|
+
def initialize(unformatted)
|
12
|
+
@unformatted = unformatted
|
13
|
+
end
|
14
|
+
|
15
|
+
# Public: This class will apply all Formatters to
|
16
|
+
# the supplied hash.
|
17
|
+
#
|
18
|
+
def formatted
|
19
|
+
@unformatted.merge(formatted_hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Public: This wraps #new & #formatted.
|
23
|
+
#
|
24
|
+
def self.formatted(unformatted)
|
25
|
+
new(unformatted).formatted
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def formatted_hash(formatters: Formatters::Formatter, support: ClassSupport)
|
30
|
+
formatters.subclasses.inject({}) do |formatted, formatter|
|
31
|
+
attribute = support.new(formatter).symbolize
|
32
|
+
formatted.merge(formatted_attribute(formatter, attribute))
|
33
|
+
end.reject { |_,val| val.nil? }
|
34
|
+
end
|
35
|
+
|
36
|
+
def formatted_attribute(formatter, attribute)
|
37
|
+
{attribute => formatter.format(@unformatted[attribute])}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -16,6 +16,7 @@ module PopCap
|
|
16
16
|
def initialize(hash)
|
17
17
|
raise(ArgumentError, argument_error_message) unless hash.kind_of?(Hash)
|
18
18
|
@hash = hash
|
19
|
+
@tags = {}
|
19
20
|
define_instance_methods
|
20
21
|
end
|
21
22
|
|
@@ -31,6 +32,14 @@ module PopCap
|
|
31
32
|
"#<#{self.class.name} " + methods + '>'
|
32
33
|
end
|
33
34
|
|
35
|
+
# Public: This method is a custom each iterator for tags.
|
36
|
+
#
|
37
|
+
def each(&block)
|
38
|
+
@tags.each do |tag|
|
39
|
+
block_given? ? block.call(tag) : tag
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
34
43
|
private
|
35
44
|
def argument_error_message
|
36
45
|
'Initialize with a hash.'
|
@@ -40,6 +49,7 @@ module PopCap
|
|
40
49
|
@hash.each do |key, val|
|
41
50
|
unless self.class.respond_to? key
|
42
51
|
define_singleton_method(key) { val }
|
52
|
+
@tags[key] = val
|
43
53
|
end
|
44
54
|
end
|
45
55
|
end
|
@@ -3,7 +3,7 @@ require 'json'
|
|
3
3
|
module PopCap
|
4
4
|
# Public: This class formats the JSON output of TagReader.
|
5
5
|
#
|
6
|
-
class
|
6
|
+
class UnformattedHash
|
7
7
|
attr_reader :json
|
8
8
|
|
9
9
|
def initialize(json)
|
@@ -14,7 +14,7 @@ module PopCap
|
|
14
14
|
# The keys have been converted to symbols.
|
15
15
|
#
|
16
16
|
def hash
|
17
|
-
renamed_hash
|
17
|
+
renamed_hash
|
18
18
|
end
|
19
19
|
|
20
20
|
# Public: This method wraps #new & #hash.
|
@@ -25,7 +25,9 @@ module PopCap
|
|
25
25
|
|
26
26
|
private
|
27
27
|
def renamed_hash
|
28
|
-
symbolized_hash.
|
28
|
+
symbolized_hash.
|
29
|
+
merge({filesize: size_element}).
|
30
|
+
reject { |key,_| key == :size }
|
29
31
|
end
|
30
32
|
|
31
33
|
def symbolized_hash
|
data/lib/pop_cap/version.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require 'pop_cap/audio_file'
|
2
1
|
require 'spec_helper'
|
3
2
|
require 'support/popcap_spec_helper'
|
3
|
+
require 'pop_cap/audio_file'
|
4
4
|
|
5
5
|
module PopCap
|
6
6
|
describe AudioFile do
|
7
7
|
let(:audio_file) { AudioFile.new(filepath) }
|
8
|
-
let(:filepath) { PopCapSpecHelper::SAMPLE_FILE }
|
8
|
+
let(:filepath) { File.realpath(PopCapSpecHelper::SAMPLE_FILE) }
|
9
9
|
let(:included_modules) { AudioFile.included_modules }
|
10
10
|
|
11
11
|
before { PopCapSpecHelper.setup }
|
@@ -13,8 +13,8 @@ module PopCap
|
|
13
13
|
|
14
14
|
subject { audio_file }
|
15
15
|
|
16
|
-
|
17
|
-
its(:filepath) { should eq File.realpath(
|
16
|
+
describe '#filepath' do
|
17
|
+
its(:filepath) { should eq File.realpath(PopCapSpecHelper::SAMPLE_FILE) }
|
18
18
|
|
19
19
|
it 'raises an error if file does not exist' do
|
20
20
|
expect do
|
@@ -23,43 +23,93 @@ module PopCap
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
context 'ffmpeg methods' do
|
27
|
-
it { expect(audio_file).to respond_to(:convert) }
|
28
|
-
it { expect(audio_file).to respond_to(:raw_tags) }
|
29
|
-
it { expect(audio_file).to respond_to(:update_tags) }
|
30
|
-
end
|
31
|
-
|
32
26
|
context 'included modules' do
|
33
27
|
it 'includes Fileable' do
|
34
28
|
expect(included_modules).to include Fileable
|
35
29
|
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#raw_output' do
|
33
|
+
it 'is memoized' do
|
34
|
+
audio_file.raw_output
|
35
|
+
TagReader.should_not_receive(:read).with(filepath)
|
36
|
+
audio_file.raw_output
|
37
|
+
end
|
38
|
+
|
39
|
+
it { expect(audio_file.raw_output).to eq(PopCapSpecHelper.raw_output) }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#unformatted' do
|
43
|
+
it 'is memoized' do
|
44
|
+
audio_file.unformatted
|
45
|
+
UnformattedHash.should_not_receive(:hash).with(audio_file.raw_output)
|
46
|
+
audio_file.unformatted
|
47
|
+
end
|
48
|
+
|
49
|
+
it do
|
50
|
+
expect(audio_file.unformatted).to eq PopCapSpecHelper.unformatted_hash
|
51
|
+
end
|
52
|
+
end
|
36
53
|
|
37
|
-
|
38
|
-
|
54
|
+
describe '#formatted' do
|
55
|
+
it 'is memoized' do
|
56
|
+
audio_file.formatted
|
57
|
+
FormattedHash.should_not_receive(:formatted).
|
58
|
+
with(audio_file.unformatted)
|
59
|
+
audio_file.formatted
|
39
60
|
end
|
61
|
+
|
62
|
+
it { expect(audio_file.formatted).to eq(PopCapSpecHelper.formatted_hash) }
|
40
63
|
end
|
41
64
|
|
42
|
-
|
65
|
+
describe '#tags' do
|
43
66
|
it 'is memoized' do
|
44
|
-
audio_file.
|
45
|
-
|
46
|
-
|
67
|
+
audio_file.tags
|
68
|
+
TagStruct.should_not_receive(:new).with(audio_file.formatted)
|
69
|
+
audio_file.tags
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'includes all tags for the sample file' do
|
73
|
+
PopCapSpecHelper.formatted_hash.each do |key,val|
|
74
|
+
expect(audio_file.tags.send(key)).to eq val
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'is a TagStruct' do
|
79
|
+
expect(audio_file.tags).to be_a TagStruct
|
47
80
|
end
|
48
81
|
end
|
49
82
|
|
50
|
-
|
51
|
-
it '
|
52
|
-
audio_file.
|
53
|
-
expect(audio_file.instance_variable_get('@raw')).not_to be_nil
|
83
|
+
describe '#reload!' do
|
84
|
+
it 'resets all MEMOIZABLES' do
|
85
|
+
audio_file.tags
|
54
86
|
audio_file.reload!
|
55
|
-
|
87
|
+
::MEMOIZABLES.each do |var|
|
88
|
+
expect(audio_file.instance_variable_get(var)).to be_nil
|
89
|
+
end
|
56
90
|
end
|
57
91
|
end
|
58
92
|
|
59
|
-
|
93
|
+
describe '#update' do
|
60
94
|
it 'reloads after tags updated' do
|
61
95
|
audio_file.should_receive(:reload!)
|
62
|
-
audio_file.
|
96
|
+
audio_file.update({foo: 'foo'})
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'updates tags for file' do
|
100
|
+
expect(audio_file.tags.artist).to eq 'Sample Artist'
|
101
|
+
updates = {artist: 'New Artist'}
|
102
|
+
audio_file.update(updates)
|
103
|
+
expect(audio_file.tags.artist).to eq 'New Artist'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#convert' do
|
108
|
+
after { PopCapSpecHelper.remove_converted }
|
109
|
+
|
110
|
+
it 'creates a new audio file with the specified format & bitrate' do
|
111
|
+
audio_file.convert(:mp3, 128)
|
112
|
+
expect(File.exists?('spec/fixtures/sample.mp3')).to be_true
|
63
113
|
end
|
64
114
|
end
|
65
115
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pop_cap/formatted_hash'
|
3
|
+
|
4
|
+
module PopCap
|
5
|
+
describe FormattedHash do
|
6
|
+
describe '.formatted' do
|
7
|
+
it 'wraps #new & #formatted' do
|
8
|
+
instance = double('FormattedHash')
|
9
|
+
FormattedHash.should_receive(:new).with('foo') { instance }
|
10
|
+
instance.should_receive(:formatted)
|
11
|
+
FormattedHash.formatted('foo')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#formatted' do
|
16
|
+
it 'does not return the formatter element, if not supplied' do
|
17
|
+
hash = FormattedHash.new(filesize: 123456)
|
18
|
+
expect(hash.formatted).not_to have_key(:date)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'applies a formatter if it is in the supplied hash' do
|
22
|
+
hash = FormattedHash.new(filesize: 123456)
|
23
|
+
expect(hash.formatted).to eq(filesize: '120.6K')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'merges in non-formattable attributes' do
|
27
|
+
hash = FormattedHash.new({filesize: 123456, artist: 'foo'})
|
28
|
+
expect(hash.formatted).to eq({filesize: '120.6K', artist: 'foo'})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -4,15 +4,15 @@ require 'pop_cap/formatter'
|
|
4
4
|
module PopCap
|
5
5
|
module Formatters
|
6
6
|
describe Formatter do
|
7
|
-
class
|
7
|
+
class Filesize < Formatter
|
8
8
|
def format; 'baz'; end
|
9
9
|
end
|
10
10
|
|
11
11
|
describe '.format' do
|
12
|
-
let(:taggy) { Formatters::
|
12
|
+
let(:taggy) { Formatters::Filesize.new('foo', {option: 'bar'}) }
|
13
13
|
|
14
14
|
it 'wraps #format in a class method' do
|
15
|
-
klass = Formatters::
|
15
|
+
klass = Formatters::Filesize.format('foo', {option: 'bar'})
|
16
16
|
instance = taggy.format
|
17
17
|
expect(klass).to eq instance
|
18
18
|
end
|
@@ -20,12 +20,12 @@ module PopCap
|
|
20
20
|
|
21
21
|
describe '.subclasses' do
|
22
22
|
it 'returns a list of all subclasses in the ObjectSpace' do
|
23
|
-
expect(Formatter.subclasses).to include(PopCap::Formatters::
|
23
|
+
expect(Formatter.subclasses).to include(PopCap::Formatters::Filesize)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'includes the subclass only once' do
|
27
27
|
unique = Formatter.subclasses.select do |cls|
|
28
|
-
cls == PopCap::Formatters::
|
28
|
+
cls == PopCap::Formatters::Filesize
|
29
29
|
end
|
30
30
|
expect(unique.size).to eq 1
|
31
31
|
end
|
@@ -45,19 +45,20 @@ module PopCap
|
|
45
45
|
|
46
46
|
describe '.subclasses_demodulized' do
|
47
47
|
it 'returns of the subclasses with their names demodulized' do
|
48
|
-
expect(Formatter.subclasses_demodulized).
|
48
|
+
expect(Formatter.subclasses_demodulized).
|
49
|
+
to include('Filesize')
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
54
|
describe '#format' do
|
54
|
-
let(:taggy) { Formatters::
|
55
|
+
let(:taggy) { Formatters::Filesize.new('foo', {option: 'bar'}) }
|
55
56
|
|
56
57
|
it { expect(taggy).to respond_to(:format) }
|
57
58
|
end
|
58
59
|
|
59
60
|
describe '#new' do
|
60
|
-
let(:taggy) { Formatters::
|
61
|
+
let(:taggy) { Formatters::Filesize.new('foo', {option: 'bar'}) }
|
61
62
|
|
62
63
|
it 'has a getter for value' do
|
63
64
|
expect(taggy.value).to eq 'foo'
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'pop_cap/
|
2
|
+
require 'pop_cap/tag_struct'
|
3
3
|
|
4
4
|
module PopCap
|
5
5
|
describe TagStruct do
|
@@ -36,8 +36,21 @@ module PopCap
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
describe '#to_s' do
|
40
|
+
it 'has a custom #to_s method' do
|
41
|
+
expect(ts.to_s).to eq "#<PopCap::TagStruct artist: Artist, date: 1984>"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#each' do
|
46
|
+
let(:tags) { {foo: 'foo', bar: 'bar', baz: 'baz'} }
|
47
|
+
let(:tag_struct) { TagStruct.new tags }
|
48
|
+
|
49
|
+
it 'has a custom #each method for all defined methods' do
|
50
|
+
tag_struct.each do |key,val|
|
51
|
+
expect(tags[key]).to eq val
|
52
|
+
end
|
53
|
+
end
|
41
54
|
end
|
42
55
|
|
43
56
|
describe 'already defined methods' do
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/popcap_spec_helper'
|
3
|
+
require 'pop_cap/unformatted_hash'
|
4
|
+
|
5
|
+
module PopCap
|
6
|
+
describe UnformattedHash do
|
7
|
+
describe '#hash' do
|
8
|
+
let(:json) { '{"format":{"size":"10","tags":{"artist":"artist"}}}' }
|
9
|
+
let(:unformatted_hash) do
|
10
|
+
UnformattedHash.new(PopCapSpecHelper.raw_output)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'symbolizes all keys' do
|
14
|
+
unformatted_hash.hash.each_key do |key|
|
15
|
+
expect(key).to be_a Symbol
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'renames filesize to size' do
|
20
|
+
expect(unformatted_hash.hash[:size]).to be_nil
|
21
|
+
expect(unformatted_hash.hash[:filesize]).not_to be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'formats json output as a hash' do
|
25
|
+
expect(unformatted_hash.hash).to be_a Hash
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'merges tags section with format section' do
|
29
|
+
unformatted = UnformattedHash.new(json)
|
30
|
+
expect(unformatted.hash).to eq({filesize: '10', artist: 'artist'})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.hash' do
|
35
|
+
it 'wraps #new & #hash' do
|
36
|
+
instance = double('UnformattedHash')
|
37
|
+
UnformattedHash.should_receive(:new).with('foo') { instance }
|
38
|
+
instance.should_receive(:hash)
|
39
|
+
UnformattedHash.hash('foo')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -6,7 +6,7 @@ module PopCapSpecHelper
|
|
6
6
|
SAMPLE_FILE = 'spec/fixtures/sample.flac'
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def
|
9
|
+
def raw_output
|
10
10
|
'{"format":{"filename":"/home/marsalis/.apps/popcap/spec/fixtures/'\
|
11
11
|
'sample.flac","nb_streams":1,"format_name":"flac","format_long_name"'\
|
12
12
|
':"raw FLAC","duration":"1.000000","size":"18291","bit_rate":"146328"'\
|
@@ -54,7 +54,7 @@ module PopCapSpecHelper
|
|
54
54
|
OpenStruct.new(
|
55
55
|
{
|
56
56
|
filename: File.realpath(SAMPLE_FILE),
|
57
|
-
nb_streams:
|
57
|
+
nb_streams: 1,
|
58
58
|
format_name: 'flac',
|
59
59
|
format_long_name: 'raw FLAC',
|
60
60
|
start_time: 'N/A',
|
@@ -81,23 +81,5 @@ module PopCapSpecHelper
|
|
81
81
|
FileUtils.mv('spec/fixtures/backup.flac', SAMPLE_FILE)
|
82
82
|
FileUtils.rm_f('spec/fixtures/sample.mp3')
|
83
83
|
end
|
84
|
-
|
85
|
-
def object_names(const)
|
86
|
-
ObjectSpace.each_object(const).map { |cls| cls.name }
|
87
|
-
end
|
88
|
-
|
89
|
-
def all_names
|
90
|
-
ObjectSpace.each_object(Object).map do |obj|
|
91
|
-
obj.name if(obj.is_a?(Class) || obj.is_a?(Module))
|
92
|
-
end.compact
|
93
|
-
end
|
94
|
-
|
95
|
-
def classes
|
96
|
-
ObjectSpace.each_object(Class).map { |cls| cls }
|
97
|
-
end
|
98
|
-
|
99
|
-
def modules
|
100
|
-
ObjectSpace.each_object(Module).map { |cls| cls }
|
101
|
-
end
|
102
84
|
end
|
103
85
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: popcap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Culley Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-03-
|
11
|
+
date: 2013-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: reek
|
@@ -60,22 +60,18 @@ files:
|
|
60
60
|
- lib/pop_cap/ffmpeg/tag_reader.rb
|
61
61
|
- lib/pop_cap/ffmpeg/tag_writer.rb
|
62
62
|
- lib/pop_cap/fileable.rb
|
63
|
+
- lib/pop_cap/formatted_hash.rb
|
63
64
|
- lib/pop_cap/formatter.rb
|
64
65
|
- lib/pop_cap/formatters/bit_rate.rb
|
65
66
|
- lib/pop_cap/formatters/date.rb
|
66
67
|
- lib/pop_cap/formatters/duration.rb
|
67
68
|
- lib/pop_cap/formatters/filesize.rb
|
68
|
-
- lib/pop_cap/
|
69
|
-
- lib/pop_cap/
|
70
|
-
- lib/pop_cap/tag/tag_struct.rb
|
71
|
-
- lib/pop_cap/taggable.rb
|
69
|
+
- lib/pop_cap/tag_struct.rb
|
70
|
+
- lib/pop_cap/unformatted_hash.rb
|
72
71
|
- lib/pop_cap/version.rb
|
73
72
|
- lib/popcap.rb
|
74
73
|
- popcap.gemspec
|
75
74
|
- spec/fixtures/sample.flac
|
76
|
-
- spec/integration/convert_audio_file_spec.rb
|
77
|
-
- spec/integration/read_metatags_spec.rb
|
78
|
-
- spec/integration/update_metatags_spec.rb
|
79
75
|
- spec/lib/pop_cap/audio_file_spec.rb
|
80
76
|
- spec/lib/pop_cap/class_support_spec.rb
|
81
77
|
- spec/lib/pop_cap/ffmpeg/commander_spec.rb
|
@@ -84,15 +80,14 @@ files:
|
|
84
80
|
- spec/lib/pop_cap/ffmpeg/tag_reader_spec.rb
|
85
81
|
- spec/lib/pop_cap/ffmpeg/tag_writer_spec.rb
|
86
82
|
- spec/lib/pop_cap/fileable_spec.rb
|
83
|
+
- spec/lib/pop_cap/formatted_hash_spec.rb
|
87
84
|
- spec/lib/pop_cap/formatter_spec.rb
|
88
85
|
- spec/lib/pop_cap/formatters/bit_rate_spec.rb
|
89
86
|
- spec/lib/pop_cap/formatters/date_spec.rb
|
90
87
|
- spec/lib/pop_cap/formatters/duration_spec.rb
|
91
88
|
- spec/lib/pop_cap/formatters/filesize_spec.rb
|
92
|
-
- spec/lib/pop_cap/
|
93
|
-
- spec/lib/pop_cap/
|
94
|
-
- spec/lib/pop_cap/tag/tag_struct_spec.rb
|
95
|
-
- spec/lib/pop_cap/taggable_spec.rb
|
89
|
+
- spec/lib/pop_cap/tag_struct_spec.rb
|
90
|
+
- spec/lib/pop_cap/unformatted_hash_spec.rb
|
96
91
|
- spec/spec_helper.rb
|
97
92
|
- spec/support/popcap_spec_helper.rb
|
98
93
|
- spec/support/reek_spec.rb
|
@@ -121,9 +116,6 @@ specification_version: 4
|
|
121
116
|
summary: A library work with audio files on the filesystem .
|
122
117
|
test_files:
|
123
118
|
- spec/fixtures/sample.flac
|
124
|
-
- spec/integration/convert_audio_file_spec.rb
|
125
|
-
- spec/integration/read_metatags_spec.rb
|
126
|
-
- spec/integration/update_metatags_spec.rb
|
127
119
|
- spec/lib/pop_cap/audio_file_spec.rb
|
128
120
|
- spec/lib/pop_cap/class_support_spec.rb
|
129
121
|
- spec/lib/pop_cap/ffmpeg/commander_spec.rb
|
@@ -132,15 +124,14 @@ test_files:
|
|
132
124
|
- spec/lib/pop_cap/ffmpeg/tag_reader_spec.rb
|
133
125
|
- spec/lib/pop_cap/ffmpeg/tag_writer_spec.rb
|
134
126
|
- spec/lib/pop_cap/fileable_spec.rb
|
127
|
+
- spec/lib/pop_cap/formatted_hash_spec.rb
|
135
128
|
- spec/lib/pop_cap/formatter_spec.rb
|
136
129
|
- spec/lib/pop_cap/formatters/bit_rate_spec.rb
|
137
130
|
- spec/lib/pop_cap/formatters/date_spec.rb
|
138
131
|
- spec/lib/pop_cap/formatters/duration_spec.rb
|
139
132
|
- spec/lib/pop_cap/formatters/filesize_spec.rb
|
140
|
-
- spec/lib/pop_cap/
|
141
|
-
- spec/lib/pop_cap/
|
142
|
-
- spec/lib/pop_cap/tag/tag_struct_spec.rb
|
143
|
-
- spec/lib/pop_cap/taggable_spec.rb
|
133
|
+
- spec/lib/pop_cap/tag_struct_spec.rb
|
134
|
+
- spec/lib/pop_cap/unformatted_hash_spec.rb
|
144
135
|
- spec/spec_helper.rb
|
145
136
|
- spec/support/popcap_spec_helper.rb
|
146
137
|
- spec/support/reek_spec.rb
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module PopCap
|
2
|
-
# Public: This class will apply a provided Formatter to
|
3
|
-
# the supplied value.
|
4
|
-
#
|
5
|
-
class FormattedTag
|
6
|
-
attr_reader :formatter, :value
|
7
|
-
|
8
|
-
# Public: To construct an instance, provide a Formatter
|
9
|
-
# and the value to format.
|
10
|
-
#
|
11
|
-
# formatter - A class of type Formatters::Formatter.
|
12
|
-
# value - The value to format.
|
13
|
-
#
|
14
|
-
def initialize(formatter, value)
|
15
|
-
@formatter, @value = formatter, value
|
16
|
-
end
|
17
|
-
|
18
|
-
# Public: This returns the formatted value.
|
19
|
-
#
|
20
|
-
def format
|
21
|
-
formatter.format(value)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Public: A class level method that initializes the class
|
25
|
-
# and formats the value.
|
26
|
-
#
|
27
|
-
def self.format(formatter, value)
|
28
|
-
new(formatter, value).format
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/lib/pop_cap/taggable.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
require 'pop_cap/class_support'
|
2
|
-
require 'pop_cap/formatter'
|
3
|
-
require 'pop_cap/tag/formatted_tag'
|
4
|
-
require 'pop_cap/tag/tag_hash'
|
5
|
-
require 'pop_cap/tag/tag_struct'
|
6
|
-
|
7
|
-
module PopCap
|
8
|
-
# Public: This module is included in anything with a #raw_tags
|
9
|
-
# attribute. It is used to parse and build tags from FFmpeg raw output.
|
10
|
-
#
|
11
|
-
module Taggable
|
12
|
-
# Public: This method reloads memoized tags.
|
13
|
-
#
|
14
|
-
def reload!
|
15
|
-
@unformatted_hash, @formatted_hash, @tag_struct = nil, nil, nil
|
16
|
-
end
|
17
|
-
|
18
|
-
# Public: This method builds an unformatted hash of tags.
|
19
|
-
#
|
20
|
-
# Examples
|
21
|
-
# class SomeClass
|
22
|
-
# def raw_tags
|
23
|
-
# end
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# klass = SomeClass.new
|
27
|
-
# klass.unformatted
|
28
|
-
# # =>
|
29
|
-
# { filename: 'spec/fixtures/sample.flac',
|
30
|
-
# format_name: 'flac',
|
31
|
-
# duration: '1.000000',
|
32
|
-
# filesize: '18291',
|
33
|
-
# bit_rate: '146328',
|
34
|
-
# genre: 'Sample Genre',
|
35
|
-
# track: '01',
|
36
|
-
# album: 'Sample Album',
|
37
|
-
# date: '2012',
|
38
|
-
# title: 'Sample Title',
|
39
|
-
# artist: 'Sample Artist' }
|
40
|
-
#
|
41
|
-
def unformatted(tag_hash: TagHash)
|
42
|
-
@unformatted_hash ||= tag_hash.hash(self.raw_tags)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Public: This method builds an unformatted hash of tags.
|
46
|
-
#
|
47
|
-
# Examples
|
48
|
-
# class SomeClass
|
49
|
-
# def raw_tags
|
50
|
-
# end
|
51
|
-
# end
|
52
|
-
#
|
53
|
-
# klass = SomeClass.new
|
54
|
-
# klass.unformatted
|
55
|
-
# # =>
|
56
|
-
# { filename: 'spec/fixtures/sample.flac',
|
57
|
-
# format_name: 'flac',
|
58
|
-
# duration: '1.000000',
|
59
|
-
# filesize: '18291',
|
60
|
-
# bit_rate: '146328',
|
61
|
-
# genre: 'Sample Genre',
|
62
|
-
# track: '01',
|
63
|
-
# album: 'Sample Album',
|
64
|
-
# date: '2012',
|
65
|
-
# title: 'Sample Title',
|
66
|
-
# artist: 'Sample Artist' }
|
67
|
-
#
|
68
|
-
def formatted
|
69
|
-
@formatted_hash ||= unformatted.merge(formatted_tags)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Public: This method builds an tag structure from #to_hash. Also,
|
73
|
-
# TagFormatters are applied to any tag with a custom formatter.
|
74
|
-
#
|
75
|
-
# Examples
|
76
|
-
# class SomeClass
|
77
|
-
# def raw_tags
|
78
|
-
# end
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# klass = SomeClass.new
|
82
|
-
# klass.tags
|
83
|
-
#
|
84
|
-
# # =>
|
85
|
-
# .album => 'Sample Album'
|
86
|
-
# .artist => 'Sample Artist'
|
87
|
-
# .bit_rate => '146 kb/s'
|
88
|
-
# .date => 2012
|
89
|
-
# .duration => '1'
|
90
|
-
# .filename => 'spec/fixtures/sample.flac'
|
91
|
-
# .filesize => '17.9K'
|
92
|
-
# .format_long_name => 'raw FLAC'
|
93
|
-
# .format_name => 'flac'
|
94
|
-
# .genre => 'Sample Genre'
|
95
|
-
# .nb_streams => '1'
|
96
|
-
# .start_time => 'N/A'
|
97
|
-
# .title => 'Sample Title'
|
98
|
-
# .track => '01'
|
99
|
-
#
|
100
|
-
def tags
|
101
|
-
@tag_struct ||= build_tag_struct(formatted)
|
102
|
-
end
|
103
|
-
|
104
|
-
private
|
105
|
-
def build_tag_struct(hash)
|
106
|
-
TagStruct.new(hash)
|
107
|
-
end
|
108
|
-
|
109
|
-
def formatted_tags(support: ClassSupport)
|
110
|
-
Formatters::Formatter.subclasses.inject({}) do |formatted, formatter|
|
111
|
-
attribute = support.new(formatter).symbolize
|
112
|
-
formatted.merge({attribute => format(formatter, attribute)})
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def format(formatter, attribute, tag: FormattedTag)
|
117
|
-
tag.format(formatter, unformatted[attribute])
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'support/popcap_spec_helper'
|
3
|
-
require 'pop_cap/audio_file'
|
4
|
-
|
5
|
-
module PopCap
|
6
|
-
describe 'Convert Audio Files' do
|
7
|
-
after { PopCapSpecHelper.remove_converted }
|
8
|
-
|
9
|
-
it 'creates a new audio file with the specified format & bitrate' do
|
10
|
-
audio_file = AudioFile.new(PopCapSpecHelper::SAMPLE_FILE)
|
11
|
-
audio_file.convert(:mp3, 128)
|
12
|
-
expect(File.exists?('spec/fixtures/sample.mp3')).to be_true
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'popcap'
|
2
|
-
require 'spec_helper'
|
3
|
-
require 'support/popcap_spec_helper'
|
4
|
-
|
5
|
-
describe PopCap do
|
6
|
-
let(:audio_file) { PopCap::AudioFile.new(filepath) }
|
7
|
-
let(:filepath) { PopCapSpecHelper::SAMPLE_FILE }
|
8
|
-
|
9
|
-
it '#raw_tags' do
|
10
|
-
expect(audio_file.raw_tags).to eq PopCapSpecHelper.raw_tags
|
11
|
-
end
|
12
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'popcap'
|
2
|
-
require 'spec_helper'
|
3
|
-
require 'support/popcap_spec_helper'
|
4
|
-
|
5
|
-
describe PopCap do
|
6
|
-
let(:audio_file) { PopCap::AudioFile.new(filepath) }
|
7
|
-
let(:filepath) { PopCapSpecHelper::SAMPLE_FILE }
|
8
|
-
|
9
|
-
context '#update_tags' do
|
10
|
-
before { PopCapSpecHelper.setup }
|
11
|
-
after { PopCapSpecHelper.teardown }
|
12
|
-
|
13
|
-
it 'updates tags for file' do
|
14
|
-
expect(audio_file.tags.artist).to eq 'Sample Artist'
|
15
|
-
updates = {artist: 'New Artist'}
|
16
|
-
audio_file.update_tags(updates)
|
17
|
-
expect(audio_file.tags.artist).to eq 'New Artist'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'pop_cap/tag/formatted_tag'
|
3
|
-
|
4
|
-
module PopCap
|
5
|
-
describe FormattedTag do
|
6
|
-
class FakeFormatter
|
7
|
-
def self.format(value)
|
8
|
-
value.to_i
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#format' do
|
13
|
-
it 'formats a value with the formatter' do
|
14
|
-
tag = FormattedTag.new(FakeFormatter, '123')
|
15
|
-
expect(tag.format).to eq 123
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '.format' do
|
20
|
-
it 'wraps #new & #format' do
|
21
|
-
instance = double('FormattedTagInstance')
|
22
|
-
FormattedTag.should_receive(:new).with(FakeFormatter, '123').
|
23
|
-
and_return(instance)
|
24
|
-
instance.should_receive(:format)
|
25
|
-
FormattedTag.format(FakeFormatter, '123')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'support/popcap_spec_helper'
|
3
|
-
require 'pop_cap/tag/tag_hash'
|
4
|
-
|
5
|
-
module PopCap
|
6
|
-
describe TagHash do
|
7
|
-
describe '#hash' do
|
8
|
-
let(:tag_hash) { TagHash.new(PopCapSpecHelper.raw_tags) }
|
9
|
-
|
10
|
-
it 'symbolizes all keys' do
|
11
|
-
tag_hash.hash.each_key do |key|
|
12
|
-
expect(key).to be_a Symbol
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'renames filesize to size' do
|
17
|
-
expect(tag_hash.hash[:size]).to be_nil
|
18
|
-
expect(tag_hash.hash[:filesize]).not_to be_nil
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'formats json output as a hash' do
|
22
|
-
expect(tag_hash.hash).to eq(PopCapSpecHelper.unformatted_hash)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '.hash' do
|
27
|
-
it 'wraps #new & #hash' do
|
28
|
-
instance = double('TagHash')
|
29
|
-
TagHash.should_receive(:new).with('foo') { instance }
|
30
|
-
instance.should_receive(:hash)
|
31
|
-
TagHash.hash('foo')
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'support/popcap_spec_helper'
|
3
|
-
require 'pop_cap/taggable'
|
4
|
-
|
5
|
-
module PopCap
|
6
|
-
describe Taggable do
|
7
|
-
class SomeClass
|
8
|
-
include Taggable
|
9
|
-
def raw_tags
|
10
|
-
PopCapSpecHelper.raw_tags
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
let(:sc) { SomeClass.new }
|
15
|
-
|
16
|
-
it 'has #raw_tags' do
|
17
|
-
expect(sc).to respond_to(:raw_tags)
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#unformatted' do
|
21
|
-
it 'returns TagHash#hash' do
|
22
|
-
TagHash.should_receive(:hash).with(sc.raw_tags)
|
23
|
-
sc.unformatted
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'is memoized' do
|
27
|
-
sc.unformatted
|
28
|
-
TagHash.should_not_receive(:new)
|
29
|
-
sc.unformatted
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe '#formatted' do
|
34
|
-
it 'builds a formatted hash' do
|
35
|
-
expect(sc.formatted).to include(PopCapSpecHelper.formatted_hash)
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'is memoized' do
|
39
|
-
sc.formatted
|
40
|
-
FormattedTag.should_not_receive(:new)
|
41
|
-
sc.formatted
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe '#tags' do
|
46
|
-
it 'builds a tag structure from #formatted_hash' do
|
47
|
-
expect(sc.tags.album).to eq PopCapSpecHelper.tags.album
|
48
|
-
expect(sc.tags.artist).to eq PopCapSpecHelper.tags.artist
|
49
|
-
expect(sc.tags.bit_rate).to eq PopCapSpecHelper.tags.bit_rate
|
50
|
-
expect(sc.tags.date).to eq PopCapSpecHelper.tags.date
|
51
|
-
expect(sc.tags.duration).to eq PopCapSpecHelper.tags.duration
|
52
|
-
expect(sc.tags.filename).to eq PopCapSpecHelper.tags.filename
|
53
|
-
expect(sc.tags.filesize).to eq PopCapSpecHelper.tags.filesize
|
54
|
-
expect(sc.tags.format_name).to eq PopCapSpecHelper.tags.format_name
|
55
|
-
expect(sc.tags.genre).to eq PopCapSpecHelper.tags.genre
|
56
|
-
expect(sc.tags.title).to eq PopCapSpecHelper.tags.title
|
57
|
-
expect(sc.tags.track).to eq PopCapSpecHelper.tags.track
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'is memoized' do
|
61
|
-
sc.tags
|
62
|
-
TagStruct.should_not_receive(:new)
|
63
|
-
sc.tags
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context '#reload!' do
|
68
|
-
it 'sets instance variables to nil' do
|
69
|
-
%w(@formatted_hash @unformatted_hash @tag_struct).each do |instance|
|
70
|
-
sc.reload!
|
71
|
-
expect(sc.instance_variable_get(instance)).to be_nil
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|