popcap 0.7.2
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/.gitignore +4 -0
- data/.rspec +4 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +52 -0
- data/LICENSE +9 -0
- data/README.md +137 -0
- data/lib/pop_cap/audio_file.rb +100 -0
- data/lib/pop_cap/commander.rb +64 -0
- data/lib/pop_cap/converter.rb +40 -0
- data/lib/pop_cap/ffmpeg.rb +130 -0
- data/lib/pop_cap/fileable.rb +134 -0
- data/lib/pop_cap/formatters/bit_rate.rb +29 -0
- data/lib/pop_cap/formatters/date.rb +42 -0
- data/lib/pop_cap/formatters/duration.rb +44 -0
- data/lib/pop_cap/formatters/filesize.rb +69 -0
- data/lib/pop_cap/formatters.rb +33 -0
- data/lib/pop_cap/helper.rb +53 -0
- data/lib/pop_cap/tag_key.rb +32 -0
- data/lib/pop_cap/tag_line.rb +36 -0
- data/lib/pop_cap/tag_struct.rb +45 -0
- data/lib/pop_cap/taggable.rb +100 -0
- data/lib/pop_cap/version.rb +3 -0
- data/lib/popcap.rb +5 -0
- data/popcap.gemspec +27 -0
- data/spec/integration/convert_audio_file_spec.rb +15 -0
- data/spec/integration/read_metatags_spec.rb +12 -0
- data/spec/integration/update_metatags_spec.rb +20 -0
- data/spec/lib/pop_cap/audio_file_spec.rb +72 -0
- data/spec/lib/pop_cap/commander_spec.rb +64 -0
- data/spec/lib/pop_cap/converter_spec.rb +67 -0
- data/spec/lib/pop_cap/ffmpeg_spec.rb +96 -0
- data/spec/lib/pop_cap/fileable_spec.rb +118 -0
- data/spec/lib/pop_cap/formatters/bit_rate_spec.rb +53 -0
- data/spec/lib/pop_cap/formatters/date_spec.rb +74 -0
- data/spec/lib/pop_cap/formatters/duration_spec.rb +64 -0
- data/spec/lib/pop_cap/formatters/filesize_spec.rb +89 -0
- data/spec/lib/pop_cap/formatters_spec.rb +36 -0
- data/spec/lib/pop_cap/helper_spec.rb +42 -0
- data/spec/lib/pop_cap/tag_key_spec.rb +48 -0
- data/spec/lib/pop_cap/tag_line_spec.rb +26 -0
- data/spec/lib/pop_cap/tag_struct_spec.rb +50 -0
- data/spec/lib/pop_cap/taggable_spec.rb +62 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/popcap_spec_helper.rb +86 -0
- data/spec/support/reek_spec.rb +8 -0
- data/spec/support/sample.flac +0 -0
- metadata +163 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
module PopCap
|
2
|
+
module Formatters
|
3
|
+
# Public: This is a formatter for the bit_rate tag. It is used
|
4
|
+
# to make the bitrate human readable.
|
5
|
+
#
|
6
|
+
# bitrate - The bitrate can be sent as a string or integer.
|
7
|
+
#
|
8
|
+
class BitRate
|
9
|
+
def initialize(bitrate)
|
10
|
+
@bitrate = bitrate
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: This method returns a bitrate represented in kilobytes.
|
14
|
+
#
|
15
|
+
# It returns nil for anything that is not a number greater than
|
16
|
+
# zero.
|
17
|
+
#
|
18
|
+
# Examples
|
19
|
+
# br = BitRate.new(128456)
|
20
|
+
# br.format
|
21
|
+
# # => '128 kb/s'
|
22
|
+
#
|
23
|
+
def format
|
24
|
+
return unless @bitrate.to_i > 0
|
25
|
+
@bitrate.to_s[0..-4] + ' kb/s'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PopCap
|
2
|
+
module Formatters
|
3
|
+
# Public: This is a formatter for the date tag. It is used
|
4
|
+
# to match and return the year.
|
5
|
+
#
|
6
|
+
# date - The date can be sent as a string or integer.
|
7
|
+
# options - An optional hash for a start & end date range.
|
8
|
+
# The start_date defaults to 1800, end_date defaults
|
9
|
+
# to 2100.
|
10
|
+
#
|
11
|
+
class Date
|
12
|
+
attr_reader :start_date, :end_date
|
13
|
+
|
14
|
+
def initialize(date, options={})
|
15
|
+
@date = date.to_s
|
16
|
+
@start_date = options[:start_date] || 1800
|
17
|
+
@end_date = options[:end_date] || 2100
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: This method returns a year if it is matched.
|
21
|
+
#
|
22
|
+
# Examples
|
23
|
+
# date = Date.new('October 5, 1975')
|
24
|
+
# date.format
|
25
|
+
# # => '1975'
|
26
|
+
#
|
27
|
+
def format
|
28
|
+
return unless ( date_match && within_date_range? )
|
29
|
+
@match[0].to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def date_match
|
34
|
+
@match ||= @date.match(/\b\d{4}\b/)
|
35
|
+
end
|
36
|
+
|
37
|
+
def within_date_range?
|
38
|
+
(start_date..end_date).include?(@match[0].to_i)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module PopCap
|
2
|
+
module Formatters
|
3
|
+
# Public: This will format a duration tag as strftime.
|
4
|
+
#
|
5
|
+
# time - Provide a string, float, or integer.
|
6
|
+
class Duration
|
7
|
+
def initialize(time)
|
8
|
+
@time = time
|
9
|
+
end
|
10
|
+
|
11
|
+
# Public: This will format a duration tag as strftime.
|
12
|
+
# It will raise a warning if the time is greater than 24 hours.
|
13
|
+
# Leading zeroes & colons are removed.
|
14
|
+
#
|
15
|
+
# Examples
|
16
|
+
# dur = Duration.new(420)
|
17
|
+
# dur.format
|
18
|
+
# # => '7:00'
|
19
|
+
#
|
20
|
+
def format
|
21
|
+
return unless @time.to_i > 0
|
22
|
+
return warning_message if over_twenty_four_hours?
|
23
|
+
remove_leading_zeroes(to_strftime)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def to_strftime
|
28
|
+
@strftime = Time.at(@time.to_f).gmtime.strftime('%H:%M:%S')
|
29
|
+
end
|
30
|
+
|
31
|
+
def remove_leading_zeroes(strftime)
|
32
|
+
@strftime.sub(/^(0+|:)+/,'')
|
33
|
+
end
|
34
|
+
|
35
|
+
def over_twenty_four_hours?
|
36
|
+
@time.to_i > 86399
|
37
|
+
end
|
38
|
+
|
39
|
+
def warning_message
|
40
|
+
'Warning: Time is greater than 24 hours.'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module PopCap
|
2
|
+
module Formatters
|
3
|
+
# Public: This class formats a filesize as human readable,
|
4
|
+
# following a UNIX formatting standard.
|
5
|
+
#
|
6
|
+
# filesize - Provide a filesize as string, integer, or float.
|
7
|
+
#
|
8
|
+
class Filesize
|
9
|
+
::BASE = 1024
|
10
|
+
::UNITS = %W{B K M G T}
|
11
|
+
|
12
|
+
def initialize(filesize)
|
13
|
+
@filesize = filesize
|
14
|
+
end
|
15
|
+
|
16
|
+
# Public: This method will format the filesize.
|
17
|
+
# It raises a warning message if size is greater than 999 terabytes.
|
18
|
+
#
|
19
|
+
# Examples
|
20
|
+
# fs = Filesize.new(12345678)
|
21
|
+
# fs.format
|
22
|
+
# # => '11.8M'
|
23
|
+
#
|
24
|
+
def format
|
25
|
+
return if @filesize.to_i == 0
|
26
|
+
return warning_message if too_large?
|
27
|
+
converted_filesize.to_s + measurement_character
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def binary_filesize
|
32
|
+
float / ::BASE ** exponent
|
33
|
+
end
|
34
|
+
|
35
|
+
def converted_filesize
|
36
|
+
rounded = rounded_filesize
|
37
|
+
is_zero_decimal? ? rounded.ceil : rounded
|
38
|
+
end
|
39
|
+
|
40
|
+
def exponent
|
41
|
+
(Math.log(float)/Math.log(::BASE)).to_i
|
42
|
+
end
|
43
|
+
|
44
|
+
def float
|
45
|
+
Float(@filesize)
|
46
|
+
end
|
47
|
+
|
48
|
+
def is_zero_decimal?
|
49
|
+
rounded_filesize.denominator == 1
|
50
|
+
end
|
51
|
+
|
52
|
+
def measurement_character
|
53
|
+
::UNITS[exponent]
|
54
|
+
end
|
55
|
+
|
56
|
+
def rounded_filesize
|
57
|
+
binary_filesize.round(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
def too_large?
|
61
|
+
@filesize.to_i > 1099400000000000
|
62
|
+
end
|
63
|
+
|
64
|
+
def warning_message
|
65
|
+
'Warning: Number is larger than 999 terabytes.'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module PopCap
|
2
|
+
# Internal: This module requires all formatters in "formatters/."
|
3
|
+
#
|
4
|
+
module Formatters
|
5
|
+
# Internal: This constant is a hash of all files in "formatters/."
|
6
|
+
# To add new custom formatters to Taggable#tags, add the formatter
|
7
|
+
# to "formatters/."
|
8
|
+
#
|
9
|
+
# Formatters should follow this format:
|
10
|
+
#
|
11
|
+
# Examples
|
12
|
+
# attribute - :custom_formatter
|
13
|
+
# path - lib/pop_cap/formatters/custom_formatter.rb
|
14
|
+
# class - CustomFormatter
|
15
|
+
# format instance method - #format
|
16
|
+
#
|
17
|
+
# # lib/pop_cap/formatters/custom_formatter.rb
|
18
|
+
# class CustomFormatter
|
19
|
+
# def format
|
20
|
+
# # code that formats
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
::INCLUDED_FORMATTERS= {}
|
25
|
+
|
26
|
+
Dir["#{File.dirname(__FILE__)}/formatters/*.rb"].each do |path|
|
27
|
+
@file_name = File.basename(path , '.rb')
|
28
|
+
@required = 'pop_cap/formatters/' + @file_name
|
29
|
+
require @required
|
30
|
+
::INCLUDED_FORMATTERS[@file_name.to_sym] = @required
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module PopCap
|
2
|
+
# Public: This class adds helper methods to construct a class.
|
3
|
+
#
|
4
|
+
# name - This is the name of the class.
|
5
|
+
#
|
6
|
+
# Examples
|
7
|
+
# Helper.new('array')
|
8
|
+
# Helper.new('active_support')
|
9
|
+
# Helper.new('active_record/base')
|
10
|
+
#
|
11
|
+
class Helper
|
12
|
+
def initialize(name)
|
13
|
+
@name = name.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
# Public: This method camel cases a string or symbol.
|
17
|
+
#
|
18
|
+
# Examples
|
19
|
+
# helper = Helper.new('active_support')
|
20
|
+
# helper.camelize
|
21
|
+
# # => 'ActiveSupport'
|
22
|
+
#
|
23
|
+
def camelize
|
24
|
+
@name.split('_').map { |word| word.capitalize }.join
|
25
|
+
end
|
26
|
+
|
27
|
+
# Public: This namespaces a string by converting a filepath
|
28
|
+
# to a namespaced constant.
|
29
|
+
#
|
30
|
+
# Examples
|
31
|
+
# helper = Helper.new('active_record/base')
|
32
|
+
# helper.namespace
|
33
|
+
# # => 'ActiveRecord::Base'
|
34
|
+
#
|
35
|
+
def namespace
|
36
|
+
camelize.split('/').map do |word|
|
37
|
+
_,head,tail = word.partition(%r(^[a-zA-Z]))
|
38
|
+
head.upcase + tail
|
39
|
+
end.join('::')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Public: This converts a string into a constant.
|
43
|
+
#
|
44
|
+
# Examples
|
45
|
+
# helper = Helper.new('active_record/base')
|
46
|
+
# helper.constantize
|
47
|
+
# # => ActiveSupport::Base
|
48
|
+
#
|
49
|
+
def constantize
|
50
|
+
Object.module_eval(namespace)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module PopCap
|
2
|
+
# Internal: This class sanitizes the raw output of FFmpeg to
|
3
|
+
# be used as a hash key.
|
4
|
+
#
|
5
|
+
# key - This is a single key as created by TagLine.
|
6
|
+
#
|
7
|
+
class TagKey
|
8
|
+
def initialize(key)
|
9
|
+
@key = key
|
10
|
+
end
|
11
|
+
|
12
|
+
# Internal: This method removes unwanted strings, downcases,
|
13
|
+
# & symbolizes a key. Additionally, it renames keys named
|
14
|
+
# 'size' to 'filesize' in order to avoid potential conflicts
|
15
|
+
# with Ruby's build-in method of the same name.
|
16
|
+
#
|
17
|
+
# Examples
|
18
|
+
# tk = TagKey.new('size')
|
19
|
+
# tk.format
|
20
|
+
# # => :filesize
|
21
|
+
#
|
22
|
+
def format
|
23
|
+
return '' if ( @key.nil? || @key.empty? )
|
24
|
+
|
25
|
+
@key.
|
26
|
+
sub(/^TAG:/,'').
|
27
|
+
sub(/^size\b/,'filesize').
|
28
|
+
downcase.
|
29
|
+
to_sym
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'pop_cap/tag_key'
|
2
|
+
require 'pop_cap/formatters'
|
3
|
+
|
4
|
+
module PopCap
|
5
|
+
# Internal: This class sanitizes the raw output of FFmpeg to
|
6
|
+
# and builds a hash.
|
7
|
+
#
|
8
|
+
# line - This is a single line of raw output from FFmpeg.
|
9
|
+
#
|
10
|
+
class TagLine
|
11
|
+
include
|
12
|
+
def initialize(line)
|
13
|
+
@line = line
|
14
|
+
end
|
15
|
+
|
16
|
+
# Internal: This method builds a hash by splitting on the
|
17
|
+
# first equal sign in a single line of content from FFmpeg.
|
18
|
+
# It uses TagKey to create the key for the hash.
|
19
|
+
#
|
20
|
+
# Examples
|
21
|
+
# tl = TagLine.new('TAG:ARTIST=David Bowie')
|
22
|
+
# to.to_hash
|
23
|
+
# # => {artist: 'David Bowie'}
|
24
|
+
#
|
25
|
+
def to_hash
|
26
|
+
return {} unless ( @line && is_a_tag? )
|
27
|
+
key,val = @line.split('=',2)
|
28
|
+
{TagKey.new(key).format => val}
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def is_a_tag?
|
33
|
+
@line.match('=')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module PopCap
|
2
|
+
# Public: This class is a simple implementation of a Ruby struct
|
3
|
+
# like object. It has a custom #to_s method & creates getter methods.
|
4
|
+
#
|
5
|
+
# new - This method takes a hash. It raises an error if anything else
|
6
|
+
# is provided.
|
7
|
+
#
|
8
|
+
# Examples
|
9
|
+
# ts = TagStruct.new({artist: 'Artist', date: 1984})
|
10
|
+
# ts.artist => 'Artist'
|
11
|
+
# ts.date => 1984
|
12
|
+
#
|
13
|
+
class TagStruct
|
14
|
+
def initialize(hash)
|
15
|
+
raise(ArgumentError, argument_error_message) unless hash.kind_of?(Hash)
|
16
|
+
@hash = hash
|
17
|
+
define_instance_methods
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: This method shows the class name & hash values as a string.
|
21
|
+
#
|
22
|
+
# Examples
|
23
|
+
# ts = TagStruct.new({artist: 'Artist', date: 1984})
|
24
|
+
# puts ts
|
25
|
+
# #=> '#<PopCap::TagStruct artist: Artist, date: 1984>'
|
26
|
+
#
|
27
|
+
def to_s
|
28
|
+
methods = @hash.map { |key,val| %(#{key}: #{val}) }.join(', ')
|
29
|
+
"#<#{self.class.name} " + methods + '>'
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def argument_error_message
|
34
|
+
'Initialize with a hash.'
|
35
|
+
end
|
36
|
+
|
37
|
+
def define_instance_methods
|
38
|
+
@hash.each do |key, val|
|
39
|
+
unless self.class.respond_to? key
|
40
|
+
define_singleton_method(key) { val }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'pop_cap/helper'
|
2
|
+
require 'pop_cap/formatters'
|
3
|
+
require 'pop_cap/tag_line'
|
4
|
+
require 'pop_cap/tag_struct'
|
5
|
+
|
6
|
+
module PopCap
|
7
|
+
# Internal: This module is included in anything with a #raw_tags
|
8
|
+
# attribute. It is used to parse and build tags from FFmpeg raw output.
|
9
|
+
#
|
10
|
+
module Taggable
|
11
|
+
include Formatters
|
12
|
+
|
13
|
+
# Internal: This method reloads memoized tags.
|
14
|
+
def reload!
|
15
|
+
@lined, @tags, @hash = nil, nil, nil
|
16
|
+
end
|
17
|
+
|
18
|
+
# Internal: This method builds a sanitized hash from #raw_tags.
|
19
|
+
#
|
20
|
+
# Examples
|
21
|
+
# class SomeClass
|
22
|
+
# def raw_tags
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# klass = SomeClass.new
|
27
|
+
# klass.to_hash
|
28
|
+
# # =>
|
29
|
+
# { filename: 'spec/support/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 to_hash
|
42
|
+
@hash ||= lined_hash.merge(formatted_hash)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Public: This method builds an tag structure from #to_hash. Also,
|
46
|
+
# TagFormatters are applied to any tag with a custom formatter.
|
47
|
+
#
|
48
|
+
# Examples
|
49
|
+
# class SomeClass
|
50
|
+
# def raw_tags
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# klass = SomeClass.new
|
55
|
+
# klass.tags
|
56
|
+
#
|
57
|
+
# # =>
|
58
|
+
# .album => 'Sample Album'
|
59
|
+
# .artist => 'Sample Artist'
|
60
|
+
# .bit_rate => '146 kb/s'
|
61
|
+
# .date => 2012
|
62
|
+
# .duration => '1'
|
63
|
+
# .filename => 'spec/support/sample.flac'
|
64
|
+
# .filesize => '17.9K'
|
65
|
+
# .format_long_name => 'raw FLAC'
|
66
|
+
# .format_name => 'flac'
|
67
|
+
# .genre => 'Sample Genre'
|
68
|
+
# .nb_streams => '1'
|
69
|
+
# .start_time => 'N/A'
|
70
|
+
# .title => 'Sample Title'
|
71
|
+
# .track => '01'
|
72
|
+
#
|
73
|
+
def tags
|
74
|
+
@tags ||= build_tag_struct(to_hash)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def lines
|
79
|
+
self.raw_tags.split("\n")
|
80
|
+
end
|
81
|
+
|
82
|
+
def build_tag_struct(hash)
|
83
|
+
TagStruct.new(hash)
|
84
|
+
end
|
85
|
+
|
86
|
+
def lined_hash
|
87
|
+
@lined ||=
|
88
|
+
lines.inject({}) { |hsh,line| hsh.merge(TagLine.new(line)).to_hash }
|
89
|
+
end
|
90
|
+
|
91
|
+
def formatted_hash
|
92
|
+
::INCLUDED_FORMATTERS.inject({}) do |formatted, formatter|
|
93
|
+
key, value = formatter
|
94
|
+
helper = Helper.new(value)
|
95
|
+
klass = helper.constantize
|
96
|
+
formatted.merge({key => klass.new(lined_hash[key]).format})
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/popcap.rb
ADDED
data/popcap.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
|
5
|
+
require 'popcap'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'popcap'
|
9
|
+
s.version = PopCap::VERSION
|
10
|
+
s.authors = ["Culley Smith"]
|
11
|
+
s.email = ["culley.smith@gmail.com"]
|
12
|
+
s.homepage = %q{http://madstance.com}
|
13
|
+
s.summary = %q{A library work with audio files on the filesystem .}
|
14
|
+
s.description = %q{Read & write metadata tags, convert audio files to alternate formats, manage files on the filesystem.}
|
15
|
+
|
16
|
+
s.required_ruby_version = '>= 1.9.3'
|
17
|
+
s.required_rubygems_version = '>= 1.3.6'
|
18
|
+
|
19
|
+
s.add_development_dependency 'reek', '~> 1.2'
|
20
|
+
s.add_development_dependency 'rspec', '~> 2.11'
|
21
|
+
s.add_development_dependency 'simplecov', '~> 0.7'
|
22
|
+
|
23
|
+
git_files = `git ls-files -z`.split("\0") rescue ''
|
24
|
+
s.files = git_files
|
25
|
+
s.test_files = `git ls-files -z -- {test,spec,features}/*`.split("\0")
|
26
|
+
s.require_paths = ['lib']
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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('spec/support/sample.flac')
|
11
|
+
audio_file.convert(:mp3, 128)
|
12
|
+
expect(File.exists?('spec/support/sample.mp3')).to be_true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
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) { 'spec/support/sample.flac' }
|
8
|
+
|
9
|
+
it '#raw_tags' do
|
10
|
+
expect(audio_file.raw_tags).to eq PopCapSpecHelper.raw_tags
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
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) { 'spec/support/sample.flac' }
|
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
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'pop_cap/audio_file'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'support/popcap_spec_helper'
|
4
|
+
|
5
|
+
module PopCap
|
6
|
+
describe AudioFile do
|
7
|
+
let(:audio_file) { AudioFile.new(filepath) }
|
8
|
+
let(:filepath) { 'spec/support/sample.flac' }
|
9
|
+
let(:included_modules) { AudioFile.included_modules }
|
10
|
+
|
11
|
+
before { PopCapSpecHelper.setup }
|
12
|
+
after { PopCapSpecHelper.teardown }
|
13
|
+
|
14
|
+
subject { audio_file }
|
15
|
+
|
16
|
+
context '#filepath' do
|
17
|
+
its(:filepath) { should eq File.realpath(filepath) }
|
18
|
+
|
19
|
+
it 'raises an error if file does not exist' do
|
20
|
+
expect do
|
21
|
+
AudioFile.new('not here.file')
|
22
|
+
end.to raise_error(FileNotFound, 'not here.file')
|
23
|
+
end
|
24
|
+
end
|
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
|
+
context 'included modules' do
|
33
|
+
it 'includes Fileable' do
|
34
|
+
expect(included_modules).to include Fileable
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'includes Taggable' do
|
38
|
+
expect(included_modules).to include Taggable
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context '#raw_tags' do
|
43
|
+
it 'is memoized' do
|
44
|
+
audio_file.raw_tags
|
45
|
+
expect(audio_file.instance_variable_get('@raw')).
|
46
|
+
to eq PopCapSpecHelper.raw_tags
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '#reload!' do
|
51
|
+
it 'reloads raw tags' do
|
52
|
+
audio_file.raw_tags
|
53
|
+
audio_file.reload!
|
54
|
+
expect(audio_file.instance_variable_get('@raw')).to be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'calls up to Taggable#reload!' do
|
58
|
+
audio_file.raw_tags
|
59
|
+
audio_file.reload!
|
60
|
+
expect(audio_file.instance_variable_get('@tags')).to be_nil
|
61
|
+
expect(audio_file.instance_variable_get('@to_hash')).to be_nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context '#update_tags' do
|
66
|
+
it 'reloads after tags updated' do
|
67
|
+
audio_file.should_receive(:reload!)
|
68
|
+
expect(audio_file.update_tags({foo: 'foo'}))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|