stream2tracks 0.0.2 → 0.0.3
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/CHANGES +40 -0
- data/README +5 -2
- data/lib/stream2tracks/cli.rb +10 -2
- data/lib/stream2tracks/process.rb +3 -3
- data/lib/stream2tracks/stream_track_ripper.rb +23 -24
- data/spec/stream2tracks/asx_stream_spec.rb +43 -0
- data/spec/stream2tracks/cli_spec.rb +35 -0
- data/spec/stream2tracks/mimms +13 -0
- data/spec/stream2tracks/process_spec.rb +79 -0
- data/spec/stream2tracks/stream_spec.rb +14 -2
- data/spec/stream2tracks/stream_track_ripper_spec.rb +138 -0
- data/spec/stream2tracks/test.wav +0 -0
- metadata +19 -12
data/CHANGES
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
= 0.0.3 / 2012-01-02
|
2
|
+
|
3
|
+
* Put under test using rspec.
|
4
|
+
* Minor improvements in API facilitating testing.
|
5
|
+
|
6
|
+
= 0.0.2 / 2011-12-31
|
7
|
+
|
8
|
+
* Package as a gem.
|
9
|
+
* Add a Rakefile, rspec stubs.
|
10
|
+
* Provide setup.rb as alternate install method.
|
11
|
+
* More extensive restructuring into classes, proper project structure.
|
12
|
+
* Improve process model using Ruby 1.9 spawn, with legacy Ruby 1.8 supported
|
13
|
+
via sfl. Closes #1, #3, #9.
|
14
|
+
* Add multi mode using new process model. Closes #16.
|
15
|
+
* Properly support logging via Logger.
|
16
|
+
* Add debug mode.
|
17
|
+
* Add rudimentary error handling and validation.
|
18
|
+
* Support progress bar and quiet mode to suppress output.
|
19
|
+
* Change from tagging via id3v2 and vorbiscomment to taglib2. Closes #2, #4.
|
20
|
+
* Change from lltag to rename tracks to internal renaming scheme. Closes #5.
|
21
|
+
* Fix all tracks downloaded to same filename overwriting prior tracks,
|
22
|
+
introduced in an interim commit. Closes #15.
|
23
|
+
|
24
|
+
= 0.0.1 / 2011-11-27
|
25
|
+
|
26
|
+
* Rename from asx2mp3 to stream2tracks.
|
27
|
+
* Support any output format ffmpeg supports.
|
28
|
+
* Initial restructuring of code into classes.
|
29
|
+
* Initial command line interface support.
|
30
|
+
* Initial documentation.
|
31
|
+
* Keep a log for each system command.
|
32
|
+
|
33
|
+
= Unversioned / 2011-11-17
|
34
|
+
|
35
|
+
* First working version.
|
36
|
+
* Use nokogiri to parse ASX stream.
|
37
|
+
* Get files from stream via mplayer -dumpstream.
|
38
|
+
* Initial tagging support via id3v2.
|
39
|
+
* Hardcoded conversion of wmv to mp3 via ffmpeg.
|
40
|
+
|
data/README
CHANGED
@@ -14,9 +14,12 @@ stream2tracks-
|
|
14
14
|
Download:
|
15
15
|
|
16
16
|
1. On Debian Wheezy/Sid, install these dependencies. For other platforms,
|
17
|
-
install the equivalents.
|
17
|
+
install the equivalents. stream2tracks uses mimms to download mms streams
|
18
|
+
contained within ASX stream containers and ffmpeg to transcode the tracks
|
19
|
+
into the desired format. The -dev packages are required to build native
|
20
|
+
gems for nokogiri and taglib2.
|
18
21
|
|
19
|
-
$ sudo apt-get install mimms ffmpeg
|
22
|
+
$ sudo apt-get install mimms ffmpeg libxml2-dev libxslt-dev libtagc0-dev
|
20
23
|
|
21
24
|
2. Install the gem.
|
22
25
|
|
data/lib/stream2tracks/cli.rb
CHANGED
@@ -9,7 +9,9 @@ def stream2tracks argv
|
|
9
9
|
options.debug=false
|
10
10
|
options.log=nil
|
11
11
|
|
12
|
-
OptionParser.new do |opts|
|
12
|
+
opts=OptionParser.new do |opts|
|
13
|
+
opts.banner = 'Usage: stream2tracks [options] FILENAME|URL'
|
14
|
+
|
13
15
|
opts.on('-d','--debug','Output debugging info.') do
|
14
16
|
options.debug=true
|
15
17
|
end
|
@@ -39,7 +41,13 @@ def stream2tracks argv
|
|
39
41
|
puts StreamTrackRipper::Version.join('.')
|
40
42
|
exit
|
41
43
|
end
|
42
|
-
end
|
44
|
+
end
|
45
|
+
opts.parse! argv
|
46
|
+
|
47
|
+
unless argv.size == 1
|
48
|
+
puts opts
|
49
|
+
exit
|
50
|
+
end
|
43
51
|
|
44
52
|
input_filename=argv.shift
|
45
53
|
|
@@ -9,7 +9,7 @@ class WatchedProcessGroup < Array
|
|
9
9
|
@bar=nil
|
10
10
|
update_bar=proc do |current,total|
|
11
11
|
# FIXME: remove hardwired 'Downloading' label
|
12
|
-
@bar=ProgressBar.new('Downloading',total) if total!=@old_total or @bar.nil?
|
12
|
+
@bar=ProgressBar.new('Downloading',total,$stderr) if total!=@old_total or @bar.nil?
|
13
13
|
@old_total=total
|
14
14
|
@bar.set current
|
15
15
|
end
|
@@ -57,10 +57,10 @@ class WatchedProcess
|
|
57
57
|
MAX_READ_LEN=1024 # completely arbitrary
|
58
58
|
class Status < Struct.new :eof,:valid,:current,:total ; end
|
59
59
|
|
60
|
-
def initialize cmd
|
60
|
+
def initialize cmd,env={}
|
61
61
|
@out,out_write=IO.pipe
|
62
62
|
@cmd=cmd
|
63
|
-
@pid=spawn
|
63
|
+
@pid=spawn env,@cmd,:in=>:close,:out=>out_write,:err=>[:child,:out]
|
64
64
|
out_write.close
|
65
65
|
yield self if block_given?
|
66
66
|
end
|
@@ -6,13 +6,17 @@ require 'stream2tracks/asx_stream'
|
|
6
6
|
require 'stream2tracks/process'
|
7
7
|
|
8
8
|
class StreamTrackRipper
|
9
|
-
Version=['0','0','
|
9
|
+
Version=['0','0','3']
|
10
|
+
|
11
|
+
attr_accessor :tracks,:trackfiles
|
10
12
|
|
11
13
|
def initialize stream,options
|
12
14
|
@stream=stream
|
13
15
|
@options=options
|
16
|
+
@options.env||={}
|
14
17
|
@log=Logger.new @options.log=='-' ? $stderr : @options.log if @options.log
|
15
18
|
@tracks=@stream.parse
|
19
|
+
@trackfiles=[]
|
16
20
|
@log.info 'Processing stream: %s' % @stream.key if @log
|
17
21
|
@log.info 'Found %i tracks' % @tracks.count if @log
|
18
22
|
album=@stream.tags[:album]
|
@@ -22,18 +26,17 @@ class StreamTrackRipper
|
|
22
26
|
mkdir_p @workdir
|
23
27
|
if block_given?
|
24
28
|
# TODO: support (re)processing selected tracks from any stage
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
get
|
30
|
+
convert
|
31
|
+
tag
|
32
|
+
rename
|
29
33
|
yield
|
30
34
|
end
|
31
35
|
# TODO: report on any failures
|
32
36
|
end
|
33
37
|
|
34
38
|
TO_BYTES={'GB'=>1000000000,'MB'=>1000000,'KB'=>1000}
|
35
|
-
def get
|
36
|
-
trackfiles=[]
|
39
|
+
def get
|
37
40
|
processes=WatchedProcessGroup.new
|
38
41
|
options=@options.dup
|
39
42
|
unless options.quiet
|
@@ -50,7 +53,7 @@ class StreamTrackRipper
|
|
50
53
|
buffer.include? 'Download complete!'
|
51
54
|
end
|
52
55
|
end
|
53
|
-
tracks.each do |track|
|
56
|
+
@tracks.each do |track|
|
54
57
|
tags=track.tags
|
55
58
|
# TODO: support formats which may not be possible to determine
|
56
59
|
# from the file extension of the entry in the stream (using
|
@@ -64,20 +67,19 @@ class StreamTrackRipper
|
|
64
67
|
end
|
65
68
|
cmd='mimms "%s" "%s"' % [track.uri,output_filename]
|
66
69
|
@log.info 'Spawning: %s' % cmd if @log
|
67
|
-
processes << WatchedProcess.new(cmd)
|
68
|
-
trackfiles << TrackFile.new(tags,output_filename,format)
|
70
|
+
processes << WatchedProcess.new(cmd,@options.env)
|
71
|
+
@trackfiles << TrackFile.new(tags,output_filename,format)
|
69
72
|
processes[-1,1].watch options unless @options.multi
|
70
73
|
end
|
71
74
|
processes.watch options if @options.multi
|
72
|
-
trackfiles
|
73
75
|
end
|
74
76
|
|
75
|
-
def convert
|
76
|
-
trackfiles.each do |trackfile|
|
77
|
+
def convert
|
78
|
+
@trackfiles.each do |trackfile|
|
77
79
|
tags=trackfile.tags
|
78
80
|
input_filename=trackfile.filename
|
79
|
-
output_filename=File.join @workdir,'%02d.%s' % [tags[:track]
|
80
|
-
cmd=case format
|
81
|
+
output_filename=File.join @workdir,'%02d.%s' % [tags[:track],@options.format]
|
82
|
+
cmd=case @options.format
|
81
83
|
when 'ogg'
|
82
84
|
'ffmpeg -i "%s" -acodec libvorbis "%s"' %
|
83
85
|
[input_filename,output_filename]
|
@@ -86,16 +88,15 @@ class StreamTrackRipper
|
|
86
88
|
[input_filename,output_filename]
|
87
89
|
end
|
88
90
|
@log.info 'Spawning: %s' % cmd if @log
|
89
|
-
WatchedProcessGroup.new([WatchedProcess.new(cmd)]).watch(@options)
|
91
|
+
WatchedProcessGroup.new([WatchedProcess.new(cmd,@options.env)]).watch(@options)
|
90
92
|
rm input_filename
|
91
93
|
trackfile.filename=output_filename
|
92
|
-
trackfile.format
|
94
|
+
trackfile.format=@options.format
|
93
95
|
end
|
94
|
-
trackfiles
|
95
96
|
end
|
96
97
|
|
97
|
-
def tag
|
98
|
-
trackfiles.each do |trackfile|
|
98
|
+
def tag
|
99
|
+
@trackfiles.each do |trackfile|
|
99
100
|
@log.info 'Tagging: %s' % trackfile.filename if @log
|
100
101
|
tags=trackfile.tags
|
101
102
|
file=TagLib::File.new trackfile.filename
|
@@ -105,11 +106,10 @@ class StreamTrackRipper
|
|
105
106
|
file.track = tags[:track]
|
106
107
|
file.save
|
107
108
|
end
|
108
|
-
trackfiles
|
109
109
|
end
|
110
110
|
|
111
|
-
def rename
|
112
|
-
trackfiles.each do |trackfile|
|
111
|
+
def rename
|
112
|
+
@trackfiles.each do |trackfile|
|
113
113
|
tags=trackfile.tags
|
114
114
|
input_filename=trackfile.filename
|
115
115
|
output_filename='%02d-%s-%s.%s' %
|
@@ -126,7 +126,6 @@ class StreamTrackRipper
|
|
126
126
|
mv input_filename,output_filename
|
127
127
|
trackfile.filename=output_filename
|
128
128
|
end
|
129
|
-
trackfiles
|
130
129
|
end
|
131
130
|
end
|
132
131
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'stream2tracks/asx_stream'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe ASXStream do
|
5
|
+
before :each do
|
6
|
+
@album="Some Album"
|
7
|
+
@artist="Some Person"
|
8
|
+
@titles=[["Title One","file:///file1.wav"],["Title Two","file:///file2.wav"]]
|
9
|
+
|
10
|
+
@stream_file=Tempfile.new ['stream','.asx']
|
11
|
+
@stream_file.puts %[<ASX VERSION="3.0">\n<TITLE>%s</TITLE>] % @album
|
12
|
+
@titles.each do |params|
|
13
|
+
@stream_file.puts %[<ENTRY>\n<TITLE>%s</TITLE>\n<REF HREF="%s" />] % params
|
14
|
+
@stream_file.puts %[<AUTHOR>%s</AUTHOR>\n<PARAM NAME="Prebuffer" VALUE="true" />] % @artist
|
15
|
+
@stream_file.puts %[</ENTRY>]
|
16
|
+
end
|
17
|
+
@stream_file.puts %[</ASX>]
|
18
|
+
@stream_file.close
|
19
|
+
@stream=ASXStream.new @stream_file.path
|
20
|
+
end
|
21
|
+
after :each do
|
22
|
+
@stream_file.unlink
|
23
|
+
end
|
24
|
+
describe '#entries' do
|
25
|
+
it 'should return entries for an ASX stream' do
|
26
|
+
entries=@stream.entries
|
27
|
+
entries.size.should == 2
|
28
|
+
entries.first.class.should == Nokogiri::XML::Element
|
29
|
+
end
|
30
|
+
end
|
31
|
+
describe '#parse' do
|
32
|
+
it 'should return tracks for an ASX stream' do
|
33
|
+
tracks=@stream.parse
|
34
|
+
tracks.size.should == 2
|
35
|
+
tags=tracks.first.tags
|
36
|
+
tags[:title].should == @titles.first[0]
|
37
|
+
tags[:artist].should == @artist
|
38
|
+
tags[:album].should == @album
|
39
|
+
tracks.first.uri.should == @titles.first[1]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'stream2tracks/cli'
|
2
|
+
require 'stringio'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
describe 'stream2tracks' do
|
6
|
+
before :each do
|
7
|
+
$stderr=StringIO.new
|
8
|
+
$stdout=StringIO.new
|
9
|
+
end
|
10
|
+
it 'should require a filename' do
|
11
|
+
lambda {stream2tracks ['/dev/null']}.should_not raise_error
|
12
|
+
lambda {stream2tracks []}.should raise_error(SystemExit)
|
13
|
+
$stdout.string.should match /^Usage:/
|
14
|
+
end
|
15
|
+
it 'should display help' do
|
16
|
+
lambda {stream2tracks ['--help']}.should raise_error(SystemExit)
|
17
|
+
$stdout.string.should match /^Usage:/
|
18
|
+
end
|
19
|
+
it 'should display version' do
|
20
|
+
lambda {stream2tracks ['--version','/dev/null']}.should raise_error(SystemExit)
|
21
|
+
$stdout.string.should match /^\d+\.\d+\.\d+$/
|
22
|
+
end
|
23
|
+
it 'should accept format' do
|
24
|
+
lambda {stream2tracks ['--format','ogg','/dev/null']}.should_not raise_error
|
25
|
+
end
|
26
|
+
it 'should accept log' do
|
27
|
+
lambda {stream2tracks ['--log','/dev/null','/dev/null']}.should_not raise_error
|
28
|
+
end
|
29
|
+
it 'should accept quiet' do
|
30
|
+
lambda {stream2tracks ['--quiet','/dev/null']}.should_not raise_error
|
31
|
+
end
|
32
|
+
it 'should accept multi' do
|
33
|
+
lambda {stream2tracks ['--multi','/dev/null']}.should_not raise_error
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#! /bin/sh
|
2
|
+
|
3
|
+
LIBMMS_ERROR=${LIBMMS_ERROR:=0}
|
4
|
+
input_file="$1"
|
5
|
+
input_file="${input_file#file://}"
|
6
|
+
output_file="$2"
|
7
|
+
|
8
|
+
if [ $LIBMMS_ERROR -eq 1 ] ; then
|
9
|
+
echo "libmms: error"
|
10
|
+
else
|
11
|
+
cp -v "$input_file" "$output_file"
|
12
|
+
echo "Download complete!"
|
13
|
+
fi
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'stream2tracks/process'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module WatchedProcessSpecHelpers
|
5
|
+
def set_params
|
6
|
+
@cmd=%[for i in $(seq 3); do echo $i; sleep .1; done; echo done]
|
7
|
+
@validate=proc{|buf|$out << buf ; /done/.match(buf) ? true : false}
|
8
|
+
@progress=proc{|buf|cur=0; buf.scan(/\d+/).each{|i|cur+=i.to_i} ; [cur,6]}
|
9
|
+
@current=[1,3,6,6]
|
10
|
+
@single=%[1\n2\n3\ndone\n]
|
11
|
+
@multi=%[1\n1\n1\n2\n1\n2\n1\n2\n3\n1\n2\n3\n1\n2\n3\ndone\n1\n2\n3\ndone\n]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe WatchedProcess do
|
16
|
+
describe '#watch' do
|
17
|
+
include WatchedProcessSpecHelpers
|
18
|
+
before :each do
|
19
|
+
set_params
|
20
|
+
$out=''
|
21
|
+
@process=WatchedProcess.new @cmd
|
22
|
+
end
|
23
|
+
it 'should validate output' do
|
24
|
+
options=OpenStruct.new
|
25
|
+
options.validate=@validate
|
26
|
+
eof,status,count=nil,nil,0
|
27
|
+
while !eof
|
28
|
+
status=@process.watch options
|
29
|
+
count+=1
|
30
|
+
eof=status.eof
|
31
|
+
end
|
32
|
+
count.should == 4
|
33
|
+
status.valid.should == true
|
34
|
+
end
|
35
|
+
it 'should measure progress' do
|
36
|
+
options=OpenStruct.new
|
37
|
+
options.progress=@progress
|
38
|
+
eof,status,count,total=nil,nil,0,0
|
39
|
+
while !eof
|
40
|
+
status=@process.watch options
|
41
|
+
status.current.should == @current[count]
|
42
|
+
count+=1
|
43
|
+
eof=status.eof
|
44
|
+
end
|
45
|
+
count.should == 4
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe WatchedProcessGroup do
|
51
|
+
describe '#watch' do
|
52
|
+
include WatchedProcessSpecHelpers
|
53
|
+
before :each do
|
54
|
+
set_params
|
55
|
+
$out=''
|
56
|
+
$stderr=StringIO.new
|
57
|
+
@options=OpenStruct.new
|
58
|
+
@options.validate=@validate
|
59
|
+
@options.progress=@progress
|
60
|
+
@processes=WatchedProcessGroup.new
|
61
|
+
end
|
62
|
+
it 'should run a single process' do
|
63
|
+
@processes << WatchedProcess.new(@cmd)
|
64
|
+
@processes.watch @options
|
65
|
+
$out.should match(@single)
|
66
|
+
end
|
67
|
+
it 'should run multiple processes concurrently' do
|
68
|
+
2.times{@processes << WatchedProcess.new(@cmd)}
|
69
|
+
@processes.watch @options
|
70
|
+
$out.should match(@multi)
|
71
|
+
end
|
72
|
+
it 'should display a progress bar' do
|
73
|
+
@processes << WatchedProcess.new(@cmd)
|
74
|
+
@processes.watch @options
|
75
|
+
$stderr.string.should match(/100%/)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -1,6 +1,18 @@
|
|
1
|
+
require 'stream2tracks/stream'
|
2
|
+
require 'tempfile'
|
3
|
+
|
1
4
|
describe 'Stream' do
|
2
|
-
describe '.new' do
|
3
|
-
end
|
4
5
|
describe '#key' do
|
6
|
+
it 'should make an MD5 digest from raw contents' do
|
7
|
+
stream_file=Tempfile.new ['test_stream','.asx']
|
8
|
+
begin
|
9
|
+
stream_file.puts 'abcd'
|
10
|
+
stream_file.close
|
11
|
+
Stream.new(stream_file.path).key.should == 'f5ac8127b3b6b85cdc13f237c6005d80'
|
12
|
+
ensure
|
13
|
+
stream_file.close
|
14
|
+
stream_file.unlink
|
15
|
+
end
|
16
|
+
end
|
5
17
|
end
|
6
18
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'stream2tracks/stream_track_ripper'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'fileutils'
|
4
|
+
include FileUtils
|
5
|
+
require 'ostruct'
|
6
|
+
require 'stringio'
|
7
|
+
require 'taglib2'
|
8
|
+
|
9
|
+
describe StreamTrackRipper do
|
10
|
+
before :each do
|
11
|
+
@album="Some Album"
|
12
|
+
@artist="Some Person"
|
13
|
+
@titles=["Title One","Title Two"]
|
14
|
+
|
15
|
+
@wav_files=[]
|
16
|
+
2.times do
|
17
|
+
temp_file=Tempfile.new ['test','.wav']
|
18
|
+
temp_file.close
|
19
|
+
@wav_files << temp_file
|
20
|
+
# Generate contents of stream
|
21
|
+
cp File.join(File.dirname(__FILE__),'test.wav'),temp_file.path
|
22
|
+
end
|
23
|
+
@stream_file=Tempfile.new ['stream','.asx']
|
24
|
+
@stream_file.puts %[<ASX VERSION="3.0">\n<TITLE>%s</TITLE>] % @album
|
25
|
+
i=0
|
26
|
+
@titles.each do |title|
|
27
|
+
# FIXME: use temporary files
|
28
|
+
@stream_file.puts %[<ENTRY>\n<TITLE>%s</TITLE>\n<REF HREF="file://%s" />] %
|
29
|
+
[title,File.expand_path(@wav_files[i].path)]
|
30
|
+
@stream_file.puts %[<AUTHOR>%s</AUTHOR>\n<PARAM NAME="Prebuffer" VALUE="true" />] % @artist
|
31
|
+
@stream_file.puts %[</ENTRY>]
|
32
|
+
i+=1
|
33
|
+
end
|
34
|
+
@stream_file.puts %[</ASX>]
|
35
|
+
@stream_file.close
|
36
|
+
@stream=ASXStream.new @stream_file.path
|
37
|
+
@options=OpenStruct.new
|
38
|
+
@options.format='ogg'
|
39
|
+
$stderr=StringIO.new
|
40
|
+
end
|
41
|
+
|
42
|
+
after :each do
|
43
|
+
@wav_files.each{|file|file.unlink}
|
44
|
+
@stream_file.unlink
|
45
|
+
@trackfiles=@ripper.instance_variable_get('@trackfiles')
|
46
|
+
@trackfiles.each {|trackfile| rm_f trackfile[:filename]} if @trackfiles
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '.new' do
|
50
|
+
it 'should create a log' do
|
51
|
+
@options.log='-'
|
52
|
+
@ripper=StreamTrackRipper.new(@stream,@options)
|
53
|
+
$stderr.string.should match('INFO -- : Processing stream:')
|
54
|
+
$stderr.string.should match('INFO -- : Found 2 tracks')
|
55
|
+
$stderr.string.should match('INFO -- : Found stream title: Some Album')
|
56
|
+
end
|
57
|
+
it 'should apply all processing stages when supplied with a block' do
|
58
|
+
@options.log='-'
|
59
|
+
@options.env={'PATH'=>"#{File.dirname(__FILE__)}:/bin:/usr/bin"}
|
60
|
+
@ripper=StreamTrackRipper.new(@stream,@options){}
|
61
|
+
$stderr.string.should match('INFO -- : Found 2 tracks')
|
62
|
+
$stderr.string.should match('INFO -- : Found stream title: Some Album')
|
63
|
+
$stderr.string.should match(/INFO -- : Spawning: mimms.*\/01\.wav/)
|
64
|
+
$stderr.string.should match(/INFO -- : Spawning: mimms.*\/02\.wav/)
|
65
|
+
$stderr.string.should match(/INFO -- : Spawning: ffmpeg.*\/01\.ogg/)
|
66
|
+
$stderr.string.should match(/INFO -- : Spawning: ffmpeg.*\/02\.ogg/)
|
67
|
+
$stderr.string.should match(/INFO -- : Tagging: .*\/01\.ogg/)
|
68
|
+
$stderr.string.should match(/INFO -- : Tagging: .*\/02\.ogg/)
|
69
|
+
$stderr.string.should match(/INFO -- : Renaming: .*01-.*\.ogg/)
|
70
|
+
$stderr.string.should match(/INFO -- : Renaming: .*02-.*\.ogg/)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
describe '#get' do
|
74
|
+
it 'should get track files' do
|
75
|
+
@options.env={'PATH'=>"#{File.dirname(__FILE__)}:/bin:/usr/bin"}
|
76
|
+
@ripper=StreamTrackRipper.new(@stream,@options)
|
77
|
+
@ripper.get
|
78
|
+
trackfiles=@ripper.trackfiles
|
79
|
+
trackfiles.count.should == 2
|
80
|
+
trackfiles.each do |trackfile|
|
81
|
+
File.exist?(trackfile[:filename]).should be true
|
82
|
+
trackfile[:filename].should match /\.wav$/
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
describe '#convert' do
|
87
|
+
it 'should convert track files to specified format' do
|
88
|
+
@options.env={'PATH'=>"#{File.dirname(__FILE__)}:/bin:/usr/bin"}
|
89
|
+
@ripper=StreamTrackRipper.new(@stream,@options)
|
90
|
+
@ripper.get
|
91
|
+
@ripper.convert
|
92
|
+
trackfiles=@ripper.trackfiles
|
93
|
+
trackfiles.each{|trackfile| File.exist?(trackfile[:filename]).should be true}
|
94
|
+
trackfiles.count.should == 2
|
95
|
+
trackfiles.each do |trackfile|
|
96
|
+
File.exist?(trackfile[:filename]).should be true
|
97
|
+
trackfile[:filename].should match /\.ogg$/
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
describe '#tag' do
|
102
|
+
it 'should tag files with metadata from stream' do
|
103
|
+
@options.env={'PATH'=>"#{File.dirname(__FILE__)}:/bin:/usr/bin"}
|
104
|
+
@ripper=StreamTrackRipper.new(@stream,@options)
|
105
|
+
@ripper.get
|
106
|
+
@ripper.convert
|
107
|
+
@ripper.tag
|
108
|
+
trackfiles=@ripper.trackfiles
|
109
|
+
trackfiles.each{|trackfile| File.exist?(trackfile[:filename]).should be true}
|
110
|
+
trackfiles.count.should == 2
|
111
|
+
trackfiles.each do |trackfile|
|
112
|
+
File.exist?(trackfile[:filename]).should be true
|
113
|
+
# TODO: eliminate duplication here
|
114
|
+
tags=TagLib::File.new(trackfile[:filename])
|
115
|
+
tags.album.should == trackfile[:tags][:album]
|
116
|
+
tags.title.should == trackfile[:tags][:title]
|
117
|
+
tags.artist.should == trackfile[:tags][:artist]
|
118
|
+
tags.track.should == trackfile[:tags][:track]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
describe '#rename' do
|
123
|
+
it 'should rename files based on metadata from stream' do
|
124
|
+
@options.env={'PATH'=>"#{File.dirname(__FILE__)}:/bin:/usr/bin"}
|
125
|
+
@ripper=StreamTrackRipper.new(@stream,@options)
|
126
|
+
@ripper.get
|
127
|
+
@ripper.convert
|
128
|
+
@ripper.rename
|
129
|
+
trackfiles=@ripper.trackfiles
|
130
|
+
trackfiles.each{|trackfile| File.exist?(trackfile[:filename]).should be true}
|
131
|
+
trackfiles.count.should == 2
|
132
|
+
trackfiles.each do |trackfile|
|
133
|
+
File.exist?(trackfile[:filename]).should be true
|
134
|
+
trackfile[:filename].should match /\d+-#{@album.gsub(' ','_')}-.*\.ogg$/
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stream2tracks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &12170400 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '1.5'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *12170400
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: progressbar
|
27
|
-
requirement: &
|
27
|
+
requirement: &12169940 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0.9'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *12169940
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sfl
|
38
|
-
requirement: &
|
38
|
+
requirement: &12169480 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '2.0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *12169480
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: taglib2
|
49
|
-
requirement: &
|
49
|
+
requirement: &12169000 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -57,10 +57,10 @@ dependencies:
|
|
57
57
|
version: '0.2'
|
58
58
|
type: :runtime
|
59
59
|
prerelease: false
|
60
|
-
version_requirements: *
|
60
|
+
version_requirements: *12169000
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rspec
|
63
|
-
requirement: &
|
63
|
+
requirement: &12168360 !ruby/object:Gem::Requirement
|
64
64
|
none: false
|
65
65
|
requirements:
|
66
66
|
- - ! '>='
|
@@ -68,7 +68,7 @@ dependencies:
|
|
68
68
|
version: '0'
|
69
69
|
type: :development
|
70
70
|
prerelease: false
|
71
|
-
version_requirements: *
|
71
|
+
version_requirements: *12168360
|
72
72
|
description: Stream ripper and tagger supporting asx, ogg, mp3, flac, etc.
|
73
73
|
email: synrg@debian.org
|
74
74
|
executables:
|
@@ -81,8 +81,15 @@ files:
|
|
81
81
|
- README
|
82
82
|
- TODO
|
83
83
|
- COPYING
|
84
|
+
- CHANGES
|
84
85
|
- bin/stream2tracks
|
86
|
+
- spec/stream2tracks/cli_spec.rb
|
87
|
+
- spec/stream2tracks/test.wav
|
88
|
+
- spec/stream2tracks/process_spec.rb
|
89
|
+
- spec/stream2tracks/mimms
|
90
|
+
- spec/stream2tracks/asx_stream_spec.rb
|
85
91
|
- spec/stream2tracks/stream_spec.rb
|
92
|
+
- spec/stream2tracks/stream_track_ripper_spec.rb
|
86
93
|
- lib/stream2tracks/process.rb
|
87
94
|
- lib/stream2tracks/asx_stream.rb
|
88
95
|
- lib/stream2tracks/cli.rb
|