dragonfly_audio 0.0.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +17 -8
- data/README.md +9 -1
- data/dragonfly_audio.gemspec +1 -0
- data/lib/dragonfly_audio.rb +4 -2
- data/lib/dragonfly_audio/analysers/audio_properties.rb +8 -17
- data/lib/dragonfly_audio/plugin.rb +11 -11
- data/lib/dragonfly_audio/processors/album_art.rb +3 -3
- data/lib/dragonfly_audio/processors/tag.rb +9 -9
- data/lib/dragonfly_audio/version.rb +1 -1
- data/samples/{BroadmoorSirenTest.mp3 → sample.mp3} +0 -0
- data/test/dragonfly_audio/analysers/audio_properties_test.rb +13 -45
- data/test/dragonfly_audio/plugin_test.rb +14 -20
- data/test/dragonfly_audio/processors/album_art_test.rb +12 -9
- data/test/dragonfly_audio/processors/tag_test.rb +8 -9
- data/test/test_helper.rb +7 -4
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 17a5552c98592630886d4acb067c52b0a33653e70ffbd0142371fba98226effa
|
4
|
+
data.tar.gz: 2e469efa5870480edc30235a10a0bc80e13e57d0a5defd6a3bfea5f8fc7e9d7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8be5fc0f587ecadd4e3593699b18388824852f25bce06677e6e65c81065a59579bc1eaf9d34b2814d2dde3a4ec08b9da71020845a96513f9f91061ad01ee6019
|
7
|
+
data.tar.gz: 8aa38d5d282294eacfb3550ab51bad5f3369f96859c24aa839596034911f951da887968c4e585f83fe945d4b5b328f5c3f910a0e953bcbab99bbea7ab4595f59
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dragonfly_audio (0.0
|
4
|
+
dragonfly_audio (1.0.0)
|
5
5
|
dragonfly (~> 1.0)
|
6
6
|
taglib-ruby
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
addressable (2.5.
|
12
|
-
public_suffix (
|
11
|
+
addressable (2.5.2)
|
12
|
+
public_suffix (>= 2.0.2, < 4.0)
|
13
|
+
ansi (1.5.0)
|
14
|
+
builder (3.2.3)
|
13
15
|
coderay (1.1.0)
|
14
|
-
dragonfly (1.1.
|
16
|
+
dragonfly (1.1.5)
|
15
17
|
addressable (~> 2.3)
|
16
18
|
multi_json (~> 1.0)
|
17
19
|
rack (>= 1.3)
|
@@ -36,7 +38,12 @@ GEM
|
|
36
38
|
lumberjack (1.0.9)
|
37
39
|
method_source (0.8.2)
|
38
40
|
minitest (5.8.1)
|
39
|
-
|
41
|
+
minitest-reporters (1.2.0)
|
42
|
+
ansi
|
43
|
+
builder
|
44
|
+
minitest (>= 5.0)
|
45
|
+
ruby-progressbar
|
46
|
+
multi_json (1.13.1)
|
40
47
|
nenv (0.2.0)
|
41
48
|
notiffany (0.0.8)
|
42
49
|
nenv (~> 0.1)
|
@@ -45,12 +52,13 @@ GEM
|
|
45
52
|
coderay (~> 1.1.0)
|
46
53
|
method_source (~> 0.8.1)
|
47
54
|
slop (~> 3.4)
|
48
|
-
public_suffix (
|
49
|
-
rack (2.0.
|
55
|
+
public_suffix (3.0.2)
|
56
|
+
rack (2.0.5)
|
50
57
|
rake (10.4.2)
|
51
58
|
rb-fsevent (0.9.6)
|
52
59
|
rb-inotify (0.9.5)
|
53
60
|
ffi (>= 0.5.0)
|
61
|
+
ruby-progressbar (1.9.0)
|
54
62
|
shellany (0.0.1)
|
55
63
|
slop (3.6.0)
|
56
64
|
taglib-ruby (0.7.1)
|
@@ -65,7 +73,8 @@ DEPENDENCIES
|
|
65
73
|
guard
|
66
74
|
guard-minitest
|
67
75
|
minitest
|
76
|
+
minitest-reporters
|
68
77
|
rake
|
69
78
|
|
70
79
|
BUNDLED WITH
|
71
|
-
1.
|
80
|
+
1.16.1
|
data/README.md
CHANGED
@@ -32,6 +32,14 @@ Dragonfly.app.configure do
|
|
32
32
|
end
|
33
33
|
```
|
34
34
|
|
35
|
+
## Supported Formats
|
36
|
+
|
37
|
+
List of supported formats is available as:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
DragonflyAudio::SUPPORTED_FORMATS # => ["aif", "aiff", …]
|
41
|
+
```
|
42
|
+
|
35
43
|
## Analysers
|
36
44
|
|
37
45
|
### audio_properties
|
@@ -84,7 +92,7 @@ Sets the file's album art:
|
|
84
92
|
audio.album_art('path_to_file')
|
85
93
|
```
|
86
94
|
|
87
|
-
Note
|
95
|
+
Note that this only works for mp3 files.
|
88
96
|
|
89
97
|
## Contributing
|
90
98
|
|
data/dragonfly_audio.gemspec
CHANGED
data/lib/dragonfly_audio.rb
CHANGED
@@ -2,6 +2,8 @@ require 'dragonfly'
|
|
2
2
|
require 'dragonfly_audio/plugin'
|
3
3
|
require 'dragonfly_audio/version'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
module DragonflyAudio
|
6
|
+
class UnsupportedFormat < RuntimeError; end
|
7
|
+
|
8
|
+
SUPPORTED_FORMATS = %w[aif aiff fla flac m4a mp4 mp4a mp4s mp3 mpga oga ogg ogx wav].freeze
|
7
9
|
end
|
@@ -5,29 +5,20 @@ require 'taglib'
|
|
5
5
|
module DragonflyAudio
|
6
6
|
module Analysers
|
7
7
|
class AudioProperties
|
8
|
-
TAGS = %
|
9
|
-
AUDIO_PROPS = %
|
8
|
+
TAGS = %w[title artist album year track genre comment].freeze
|
9
|
+
AUDIO_PROPS = %w[length bitrate channels sample_rate].freeze
|
10
10
|
|
11
11
|
def call(content)
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
private # =============================================================
|
12
|
+
return {} unless SUPPORTED_FORMATS.include?(content.ext)
|
16
13
|
|
17
|
-
def taglib_fileref(content)
|
18
14
|
res = {}
|
19
|
-
TagLib::FileRef.open(content.path) do |fileref|
|
20
|
-
unless fileref.null?
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
AUDIO_PROPS.each do |prop_name|
|
27
|
-
res[prop_name] = fileref.audio_properties.send(prop_name)
|
28
|
-
end
|
29
|
-
end
|
16
|
+
TagLib::FileRef.open(content.path) do |fileref|
|
17
|
+
return if fileref.null?
|
18
|
+
TAGS.each { |n| res[n] = fileref.tag.send(n) }
|
19
|
+
AUDIO_PROPS.each { |n| res[n] = fileref.audio_properties.send(n) }
|
30
20
|
end
|
21
|
+
|
31
22
|
res
|
32
23
|
end
|
33
24
|
end
|
@@ -1,23 +1,23 @@
|
|
1
1
|
require 'dragonfly_audio/analysers/audio_properties'
|
2
|
+
|
2
3
|
require 'dragonfly_audio/processors/tag'
|
3
4
|
require 'dragonfly_audio/processors/album_art'
|
4
5
|
|
5
6
|
module DragonflyAudio
|
6
7
|
class Plugin
|
7
|
-
def call(app,
|
8
|
-
app.add_analyser :audio_properties,
|
8
|
+
def call(app, options = {})
|
9
|
+
app.add_analyser :audio_properties, Analysers::AudioProperties.new
|
10
|
+
|
11
|
+
Analysers::AudioProperties::TAGS.each do |name|
|
12
|
+
app.add_analyser(name) { |c| c.analyse(:audio_properties)[name] }
|
13
|
+
end
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
DragonflyAudio::Analysers::AudioProperties::AUDIO_PROPS
|
13
|
-
].flatten.each do |analyser|
|
14
|
-
app.add_analyser analyser do |content|
|
15
|
-
content.analyse(:audio_properties)[analyser]
|
16
|
-
end
|
15
|
+
Analysers::AudioProperties::AUDIO_PROPS.each do |name|
|
16
|
+
app.add_analyser(name) { |c| c.analyse(:audio_properties)[name] }
|
17
17
|
end
|
18
18
|
|
19
|
-
app.add_processor :tag,
|
20
|
-
app.add_processor :album_art,
|
19
|
+
app.add_processor :tag, Processors::Tag.new
|
20
|
+
app.add_processor :album_art, Processors::AlbumArt.new
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -6,9 +6,9 @@ require 'rack'
|
|
6
6
|
module DragonflyAudio
|
7
7
|
module Processors
|
8
8
|
class AlbumArt
|
9
|
-
def call(content,
|
10
|
-
|
11
|
-
|
9
|
+
def call(content, album_art_file)
|
10
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
11
|
+
# raise UnsupportedFormat unless content.mime_type == 'audio/mpeg'
|
12
12
|
|
13
13
|
tempfile = content.temp_object
|
14
14
|
|
@@ -5,21 +5,21 @@ require 'taglib'
|
|
5
5
|
module DragonflyAudio
|
6
6
|
module Processors
|
7
7
|
class Tag
|
8
|
-
PERMISSIBLE_PROPERTIES =
|
8
|
+
PERMISSIBLE_PROPERTIES = Analysers::AudioProperties::TAGS
|
9
9
|
|
10
10
|
def call(content, properties)
|
11
|
-
|
11
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
12
|
+
|
13
|
+
# stringify keys
|
14
|
+
properties = properties.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v }
|
15
|
+
properties = properties.select { |key, _| PERMISSIBLE_PROPERTIES.include?(key) }
|
12
16
|
|
13
17
|
tempfile = Dragonfly::TempObject.new(content.tempfile)
|
14
18
|
|
15
19
|
TagLib::FileRef.open(tempfile.path) do |file|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
tag.send("#{key}=", value)
|
20
|
-
end
|
21
|
-
file.save
|
22
|
-
end
|
20
|
+
return if file.null?
|
21
|
+
properties.each { |k, v| file.tag.send("#{k}=", v) }
|
22
|
+
file.save
|
23
23
|
end
|
24
24
|
|
25
25
|
content.update(tempfile)
|
Binary file
|
@@ -2,49 +2,17 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyAudio::Analysers::AudioProperties do
|
4
4
|
let(:app) { test_app.configure_with(:audio) }
|
5
|
-
let(:
|
6
|
-
|
7
|
-
it '
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
it '
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
it '
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
it 'analyses "channels" property' do
|
20
|
-
audio.audio_properties[:channels].must_equal 2
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'analyses "comment" property' do
|
24
|
-
audio.audio_properties[:comment].must_equal ' Comment '
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'analyses "genre" property' do
|
28
|
-
audio.audio_properties[:genre].must_equal 'Dance'
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'analyses "length" property' do
|
32
|
-
audio.audio_properties[:length].must_equal 156
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'analyses "sample_rate" property' do
|
36
|
-
audio.audio_properties[:sample_rate].must_equal 44_100
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'analyses "title" property' do
|
40
|
-
audio.audio_properties[:title].must_equal 'SongTitle'
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'analyses "track" property' do
|
44
|
-
audio.audio_properties[:track].must_equal 0
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'analyses "year" property' do
|
48
|
-
audio.audio_properties[:year].must_equal 0
|
49
|
-
end
|
5
|
+
let(:content) { app.fetch_file(SAMPLES_DIR.join('sample.mp3')) }
|
6
|
+
|
7
|
+
it { content.audio_properties['album'].must_equal 'Album XYZ' }
|
8
|
+
it { content.audio_properties['artist'].must_equal 'Artist' }
|
9
|
+
it { content.audio_properties['bitrate'].must_equal 192 }
|
10
|
+
it { content.audio_properties['channels'].must_equal 2 }
|
11
|
+
it { content.audio_properties['comment'].must_equal ' Comment ' }
|
12
|
+
it { content.audio_properties['genre'].must_equal 'Dance' }
|
13
|
+
it { content.audio_properties['length'].must_be :>, 150 }
|
14
|
+
it { content.audio_properties['sample_rate'].must_equal 44_100 }
|
15
|
+
it { content.audio_properties['title'].must_equal 'SongTitle' }
|
16
|
+
it { content.audio_properties['track'].must_equal 0 }
|
17
|
+
it { content.audio_properties['year'].must_equal 0 }
|
50
18
|
end
|
@@ -1,29 +1,23 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
let(:audio) { app.fetch_file(SAMPLES_DIR.join('BroadmoorSirenTest.mp3')) }
|
3
|
+
describe DragonflyAudio::Plugin do
|
4
|
+
let(:app) { test_app.configure_with(:audio) }
|
5
|
+
let(:content) { app.fetch_file(SAMPLES_DIR.join('sample.mp3')) }
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
audio.must_respond_to :audio_properties
|
11
|
-
end
|
7
|
+
describe 'analysers' do
|
8
|
+
it { content.must_respond_to :audio_properties }
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
DragonflyAudio::Analysers::AudioProperties::AUDIO_PROPS
|
16
|
-
].flatten.each do |analyser|
|
17
|
-
it "adds ##{analyser}" do
|
18
|
-
audio.must_respond_to analyser
|
19
|
-
end
|
20
|
-
end
|
10
|
+
DragonflyAudio::Analysers::AudioProperties::TAGS.each do |analyser|
|
11
|
+
it { content.must_respond_to analyser }
|
21
12
|
end
|
22
13
|
|
23
|
-
|
24
|
-
it
|
25
|
-
audio.must_respond_to :tag
|
26
|
-
end
|
14
|
+
DragonflyAudio::Analysers::AudioProperties::AUDIO_PROPS.each do |analyser|
|
15
|
+
it { content.must_respond_to analyser }
|
27
16
|
end
|
28
17
|
end
|
18
|
+
|
19
|
+
describe 'processors' do
|
20
|
+
it { content.must_respond_to :album_art }
|
21
|
+
it { content.must_respond_to :tag }
|
22
|
+
end
|
29
23
|
end
|
@@ -2,23 +2,26 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyAudio::Processors::AlbumArt do
|
4
4
|
let(:app) { test_app.configure_with(:audio) }
|
5
|
-
let(:
|
6
|
-
let(:audio) { Dragonfly::Content.new(app, SAMPLES_DIR.join('BroadmoorSirenTest.mp3')) }
|
5
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.mp3')) }
|
7
6
|
let(:image) { Dragonfly::Content.new(app, SAMPLES_DIR.join('album.jpg')) }
|
7
|
+
let(:processor) { DragonflyAudio::Processors::AlbumArt.new }
|
8
8
|
|
9
9
|
let(:artist) { 'Elvis Presley' }
|
10
10
|
let(:title) { 'Hound Dawg' }
|
11
11
|
|
12
|
-
before { processor.call(
|
12
|
+
before { processor.call(content, image.file.path) }
|
13
13
|
|
14
14
|
describe 'properties' do
|
15
|
-
|
16
|
-
TagLib::MPEG::File.open(
|
17
|
-
|
18
|
-
|
19
|
-
cover = tag.frame_list('APIC').first
|
20
|
-
cover.picture.must_equal image.data
|
15
|
+
let(:picture) do
|
16
|
+
TagLib::MPEG::File.open(content.file.path) do |file|
|
17
|
+
file.id3v2_tag.frame_list('APIC').first.picture
|
21
18
|
end
|
22
19
|
end
|
20
|
+
|
21
|
+
it { picture.must_equal image.data }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'tempfile has extension' do
|
25
|
+
it { content.tempfile.path.must_match /\.mp3\z/i }
|
23
26
|
end
|
24
27
|
end
|
@@ -2,22 +2,21 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyAudio::Processors::Tag do
|
4
4
|
let(:app) { test_app.configure_with(:audio) }
|
5
|
-
let(:
|
5
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.mp3')) }
|
6
6
|
let(:analyser) { DragonflyAudio::Analysers::AudioProperties.new }
|
7
|
-
let(:
|
7
|
+
let(:processor) { DragonflyAudio::Processors::Tag.new }
|
8
8
|
|
9
9
|
let(:artist) { 'Elvis Presley' }
|
10
10
|
let(:title) { 'Hound Dawg' }
|
11
11
|
|
12
|
-
before { processor.call(
|
12
|
+
before { processor.call(content, artist: artist, title: title) }
|
13
13
|
|
14
14
|
describe 'properties' do
|
15
|
-
it '
|
16
|
-
|
17
|
-
|
15
|
+
it { analyser.call(content)['artist'].must_equal artist }
|
16
|
+
it { analyser.call(content)['title'].must_equal title }
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
19
|
+
describe 'tempfile has extension' do
|
20
|
+
it { content.tempfile.path.must_match /\.mp3\z/i }
|
22
21
|
end
|
23
22
|
end
|
data/test/test_helper.rb
CHANGED
@@ -2,6 +2,7 @@ require 'bundler/setup'
|
|
2
2
|
|
3
3
|
require 'minitest'
|
4
4
|
require 'minitest/autorun'
|
5
|
+
require 'minitest/reporters'
|
5
6
|
require 'minitest/spec'
|
6
7
|
|
7
8
|
require 'dragonfly'
|
@@ -9,9 +10,11 @@ require 'dragonfly_audio'
|
|
9
10
|
|
10
11
|
SAMPLES_DIR = Pathname.new(File.expand_path('../../samples', __FILE__))
|
11
12
|
|
13
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
14
|
+
|
12
15
|
def test_app(name = nil)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
Dragonfly::App.instance(name).tap do |app|
|
17
|
+
app.datastore = Dragonfly::MemoryDataStore.new
|
18
|
+
app.secret = 'test secret'
|
19
|
+
end
|
17
20
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dragonfly_audio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas Celizna
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-07-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dragonfly
|
@@ -109,6 +109,20 @@ dependencies:
|
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: minitest-reporters
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
112
126
|
description:
|
113
127
|
email:
|
114
128
|
- tomas.celizna@gmail.com
|
@@ -133,8 +147,8 @@ files:
|
|
133
147
|
- lib/dragonfly_audio/processors/album_art.rb
|
134
148
|
- lib/dragonfly_audio/processors/tag.rb
|
135
149
|
- lib/dragonfly_audio/version.rb
|
136
|
-
- samples/BroadmoorSirenTest.mp3
|
137
150
|
- samples/album.jpg
|
151
|
+
- samples/sample.mp3
|
138
152
|
- test/dragonfly_audio/analysers/audio_properties_test.rb
|
139
153
|
- test/dragonfly_audio/plugin_test.rb
|
140
154
|
- test/dragonfly_audio/processors/album_art_test.rb
|
@@ -160,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
174
|
version: '0'
|
161
175
|
requirements: []
|
162
176
|
rubyforge_project:
|
163
|
-
rubygems_version: 2.
|
177
|
+
rubygems_version: 2.7.6
|
164
178
|
signing_key:
|
165
179
|
specification_version: 4
|
166
180
|
summary: Wraps common audio-related tasks into Dragonfly analysers and processors.
|