stream2tracks 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|