tune 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +3 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +79 -0
- data/Rakefile +13 -0
- data/bin/tune +12 -0
- data/lib/tune/task.rb +134 -0
- data/lib/tune/version.rb +3 -0
- data/lib/tune.rb +19 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/tune_spec.rb +327 -0
- data/tune.gemspec +28 -0
- metadata +146 -0
data/.autotest
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Yasuhiro Asaka
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# tune
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/grauwoelfchen/tune.png)](http://travis-ci.org/grauwoelfchen/tune)
|
4
|
+
|
5
|
+
Simple controller for Radio Tray ♪♪♪
|
6
|
+
|
7
|
+
* [Radio Tray](http://radiotray.sourceforge.net/)
|
8
|
+
|
9
|
+
|
10
|
+
## Install
|
11
|
+
|
12
|
+
```
|
13
|
+
$ gem install tune (not yet)
|
14
|
+
|
15
|
+
or
|
16
|
+
|
17
|
+
$ git clone https://github.com/grauwoelfchen/tune.git
|
18
|
+
$ cd tune
|
19
|
+
$ rake build
|
20
|
+
$ gem install pkg/tune-x.x.x.gem
|
21
|
+
```
|
22
|
+
|
23
|
+
|
24
|
+
## Require
|
25
|
+
|
26
|
+
* dbus
|
27
|
+
* radiotray (runtime)
|
28
|
+
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
You can specify channel with number index.
|
33
|
+
|
34
|
+
```
|
35
|
+
# run radiotray
|
36
|
+
$ tune power on
|
37
|
+
on
|
38
|
+
|
39
|
+
# list channels
|
40
|
+
$ tune list
|
41
|
+
$[00] .977 Classic Rock
|
42
|
+
$[01] .977 The Hitz Channel
|
43
|
+
$[02] 181.FM
|
44
|
+
$[03] 181.FM Classic Hits
|
45
|
+
$[04] 80s Sky.FM
|
46
|
+
...
|
47
|
+
|
48
|
+
# start to listen
|
49
|
+
$ tune play 16
|
50
|
+
Groove Salad
|
51
|
+
```
|
52
|
+
|
53
|
+
See help.
|
54
|
+
|
55
|
+
```
|
56
|
+
Tasks:
|
57
|
+
tune help [TASK] # Describe available tasks or one specific task
|
58
|
+
tune list # Show bookmarks [synonym: ls]
|
59
|
+
tune off # Turn off [synonym: stop]
|
60
|
+
tune play # Play radio [synonym: start]
|
61
|
+
tune power {on|off} # On/Off radiotray [synonym: po]
|
62
|
+
tune show # Show radio channel [synonym: current]
|
63
|
+
tune volume {up|down} (1-5) # Change volume [synonym: vol]
|
64
|
+
```
|
65
|
+
|
66
|
+
|
67
|
+
## License
|
68
|
+
|
69
|
+
Copyright (c) 2012 Yasuhiro Asaka
|
70
|
+
|
71
|
+
MIT License
|
72
|
+
|
73
|
+
|
74
|
+
## Todo
|
75
|
+
|
76
|
+
* Improve spec description
|
77
|
+
* Add indicator (:play action takes sometimes a few seconds)
|
78
|
+
* Create action for management of bookmarks (add, edit, delete)
|
79
|
+
* Display current song (possible ??)
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
|
4
|
+
task :default => [:spec]
|
5
|
+
begin
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
9
|
+
spec.rspec_opts = ['-cpf d']
|
10
|
+
end
|
11
|
+
rescue LoadError => e
|
12
|
+
puts e
|
13
|
+
end
|
data/bin/tune
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'rubygems' if RUBY_VERSION.to_f < 1.9
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
root = Pathname.new(__FILE__).realpath.parent.parent
|
8
|
+
$:.unshift root.join('lib') if $0 == __FILE__
|
9
|
+
|
10
|
+
require 'tune'
|
11
|
+
|
12
|
+
Tune::Task.start ARGV
|
data/lib/tune/task.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems' if RUBY_VERSION.to_f < 1.9
|
4
|
+
require 'thor'
|
5
|
+
require 'dbus'
|
6
|
+
|
7
|
+
module Tune
|
8
|
+
class Task < Thor
|
9
|
+
|
10
|
+
def initialize(args, opts={}, conf={})
|
11
|
+
unless %w[
|
12
|
+
help power
|
13
|
+
].include?(conf[:current_task].name)
|
14
|
+
unless connect
|
15
|
+
puts 'please power on ;)'
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'power {on|off}', 'On/Off radiotray [synonym: po]'
|
23
|
+
map 'po' => :power
|
24
|
+
method_options :action => :string
|
25
|
+
def power action=''
|
26
|
+
res = `ps aux | grep '[r]adiotray'`.empty?
|
27
|
+
on = "\033[1;32mon\033[m"
|
28
|
+
off = "\033[1;31moff\033[m"
|
29
|
+
case action
|
30
|
+
when /^on$/i
|
31
|
+
res = `radiotray 1>/dev/null 2>&1 &`.nil? unless connect
|
32
|
+
when /^off$/i
|
33
|
+
res = `killall -15 radiotray` if connect
|
34
|
+
end
|
35
|
+
puts (res ? off : on)
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'list', 'Show bookmarks [synonym: ls]'
|
39
|
+
map 'ls' => :list
|
40
|
+
def list
|
41
|
+
all_names = channels
|
42
|
+
var_width = all_names.length.to_s.length
|
43
|
+
all_names.each_with_index do |channel, index|
|
44
|
+
var = index.to_s.rjust var_width, '0'
|
45
|
+
if channel == playing
|
46
|
+
puts "\033[1;30m$\[#{var}\] \033[1;31m#{channel}\033[m"
|
47
|
+
else
|
48
|
+
puts "\033[1;30m$\[#{var}\] \033[1;34m#{channel}\033[m"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'play', 'Play radio [synonym: start]'
|
54
|
+
map 'start' => :play
|
55
|
+
method_options :channel => :string
|
56
|
+
def play channel=''
|
57
|
+
if channel =~ /^(\$*)(\d+)$/
|
58
|
+
name = channels[$2.to_i]
|
59
|
+
end
|
60
|
+
if channel.empty?
|
61
|
+
# same as `show`
|
62
|
+
puts playing
|
63
|
+
elsif !name
|
64
|
+
puts "$#{channel} does not exist"
|
65
|
+
else
|
66
|
+
@player.playRadio name
|
67
|
+
puts name
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'off', 'Turn off [synonym: stop]'
|
72
|
+
map 'stop' => :off
|
73
|
+
def off
|
74
|
+
if name = playing
|
75
|
+
@player.turnOff
|
76
|
+
puts name
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
desc 'show', 'Show radio channel [synonym: current]'
|
81
|
+
map 'current' => :show
|
82
|
+
def show
|
83
|
+
puts playing
|
84
|
+
end
|
85
|
+
|
86
|
+
desc 'volume {up|down} (1-5)', 'Change volume [synonym: vol]'
|
87
|
+
map 'vol' => :volume
|
88
|
+
method_options :action => :string, :value => :numeric
|
89
|
+
def volume action=nil, value='1'
|
90
|
+
if action =~ /^(up|down)$/
|
91
|
+
value = value.to_i > 5 ? 5 : value.to_i
|
92
|
+
value.times do
|
93
|
+
@player.send "volume#{action.capitalize}".to_sym
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def connect
|
101
|
+
(setup and init_player)
|
102
|
+
end
|
103
|
+
|
104
|
+
def setup
|
105
|
+
begin
|
106
|
+
@bus = DBus::SessionBus.instance
|
107
|
+
@service = @bus.service('net.sourceforge.radiotray')
|
108
|
+
return true
|
109
|
+
rescue DBus::Error, Errno::ECONNREFUSED
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def init_player
|
115
|
+
begin
|
116
|
+
@player = @service.object('/net/sourceforge/radiotray')
|
117
|
+
@player.default_iface = 'net.sourceforge.radiotray'
|
118
|
+
@player.introspect
|
119
|
+
return true
|
120
|
+
rescue DBus::Error
|
121
|
+
return false
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def channels
|
126
|
+
@player.listRadios.first.sort
|
127
|
+
end
|
128
|
+
|
129
|
+
def playing
|
130
|
+
radio = @player.getCurrentRadio
|
131
|
+
radio.first if radio
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/tune/version.rb
ADDED
data/lib/tune.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'tune/task'
|
4
|
+
|
5
|
+
# NOTE
|
6
|
+
# $ dbus-send --help
|
7
|
+
# Usage: dbus-send [--help] [--system | --session | --address=ADDRESS] [--dest=NAME] [--type=TYPE] [--print-reply[=literal]] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]
|
8
|
+
#
|
9
|
+
# Remote methods
|
10
|
+
# * ListRadios
|
11
|
+
# * turnOff
|
12
|
+
# * volumeDown
|
13
|
+
# * playRadio
|
14
|
+
# * getCurrentMetaData
|
15
|
+
# * volumeUp
|
16
|
+
# * playUrl
|
17
|
+
# * getCurrentRadio
|
18
|
+
module Tune
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
9
|
+
$:.unshift File.dirname(__FILE__)
|
10
|
+
require 'rspec'
|
11
|
+
require 'tune'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
|
18
|
+
# Run specs in random order to surface order dependencies. If you find an
|
19
|
+
# order dependency and want to debug it, you can fix the order by providing
|
20
|
+
# the seed, which is printed after each run.
|
21
|
+
# --seed 1234
|
22
|
+
config.order = 'random'
|
23
|
+
|
24
|
+
# ruby version filter
|
25
|
+
config.filter_run_excluding :ruby => lambda { |version|
|
26
|
+
!(RUBY_VERSION.to_s =~ /^#{version.to_s}/)
|
27
|
+
}
|
28
|
+
end
|
data/spec/tune_spec.rb
ADDED
@@ -0,0 +1,327 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
require 'ostruct'
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
6
|
+
|
7
|
+
module Kernel
|
8
|
+
# for stdout/stderr
|
9
|
+
def capture(stream)
|
10
|
+
begin
|
11
|
+
stream = stream.to_s
|
12
|
+
eval "$#{stream} = StringIO.new"
|
13
|
+
yield
|
14
|
+
result = eval("$#{stream}").string
|
15
|
+
ensure
|
16
|
+
eval "$#{stream} = #{stream.upcase}"
|
17
|
+
end
|
18
|
+
result
|
19
|
+
end
|
20
|
+
# for backtick
|
21
|
+
def `(command)
|
22
|
+
return ''
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe Tune::Task do
|
27
|
+
context 'radiotray process does not exist yet' do
|
28
|
+
before do
|
29
|
+
@dbus = mock(DBus::SessionBus)
|
30
|
+
@dbus.stub(:service).with('net.sourceforge.radiotray').and_raise(Errno::ECONNREFUSED)
|
31
|
+
DBus::SessionBus.stub(:instance).and_return(@dbus)
|
32
|
+
end
|
33
|
+
describe ':power action with on' do
|
34
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'power')} }
|
35
|
+
let(:task){ Tune::Task.new(['power'], [], conf) }
|
36
|
+
before do
|
37
|
+
@stdout = capture(:stdout) {
|
38
|
+
task.should_receive(:'`').with(/ps aux/).once.and_return('')
|
39
|
+
task.should_receive(:'`').with(/radiotray/).once.and_return('done')
|
40
|
+
@result = task.power('on')
|
41
|
+
}
|
42
|
+
end
|
43
|
+
it 'should on power' do
|
44
|
+
@stdout.chomp.should match(/on/)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
describe ':power action with off' do
|
48
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'power')} }
|
49
|
+
let(:task){ Tune::Task.new(['power'], [], conf) }
|
50
|
+
before do
|
51
|
+
@stdout = capture(:stdout) {
|
52
|
+
task.should_receive(:'`').with(/ps aux/).once.and_return('')
|
53
|
+
task.should_not_receive(:'`').with(/radiotray/).never
|
54
|
+
task.should_not_receive(:'`').with(/killall/).never
|
55
|
+
@result = task.power('off')
|
56
|
+
}
|
57
|
+
end
|
58
|
+
it 'should not change state off' do
|
59
|
+
@stdout.chomp.should match(/off/)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
describe ':list action' do
|
63
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'list')} }
|
64
|
+
it 'should raise SystemExit at initialize' do
|
65
|
+
lambda {
|
66
|
+
capture(:stdout){ Tune::Task.new(['list'], [], conf) }
|
67
|
+
}.should raise_error(SystemExit)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
describe ':play action' do
|
71
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'play')} }
|
72
|
+
it 'should raise SystemExit at initialize' do
|
73
|
+
lambda {
|
74
|
+
capture(:stdout){ Tune::Task.new(['play'], [], conf) }
|
75
|
+
}.should raise_error(SystemExit)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
describe ':off action' do
|
79
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'off')} }
|
80
|
+
it 'should raise SystemExit at initialize' do
|
81
|
+
lambda {
|
82
|
+
capture(:stdout){ Tune::Task.new(['off'], [], conf) }
|
83
|
+
}.should raise_error(SystemExit)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
describe ':show action' do
|
87
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'show')} }
|
88
|
+
it 'should raise SystemExit at initialize' do
|
89
|
+
lambda {
|
90
|
+
capture(:stdout){ Tune::Task.new(['show'], [], conf) }
|
91
|
+
}.should raise_error(SystemExit)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
describe ':volume action' do
|
95
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'volume')} }
|
96
|
+
it 'should raise SystemExit at initialize' do
|
97
|
+
lambda {
|
98
|
+
capture(:stdout){ Tune::Task.new(['volume'], [], conf) }
|
99
|
+
}.should raise_error(SystemExit)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'radiotray process is already started' do
|
105
|
+
before do
|
106
|
+
@player = double('player')
|
107
|
+
@player.stub(:default_iface=).with('net.sourceforge.radiotray').and_return(true)
|
108
|
+
@player.stub(:introspect)
|
109
|
+
@service = double('service')
|
110
|
+
@service.stub(:object).with('/net/sourceforge/radiotray').and_return(@player)
|
111
|
+
@dbus = mock(DBus::SessionBus)
|
112
|
+
@dbus.stub(:service).with('net.sourceforge.radiotray').and_return(@service)
|
113
|
+
DBus::SessionBus.stub(:instance).and_return(@dbus)
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when playing Jazz channel' do
|
117
|
+
before do
|
118
|
+
@player.stub(:getCurrentRadio).and_return(['Jazz'])
|
119
|
+
@player.stub(:listRadios).and_return([[
|
120
|
+
'Jazz', # $[01]
|
121
|
+
'R&B', # $[02]
|
122
|
+
'Country' # $[03]
|
123
|
+
]])
|
124
|
+
end
|
125
|
+
describe ':power action with on' do
|
126
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'power')} }
|
127
|
+
let(:task){ Tune::Task.new(['power'], [], conf) }
|
128
|
+
before do
|
129
|
+
@stdout = capture(:stdout) {
|
130
|
+
task.should_receive(:'`').with(/ps aux/).once.and_return(
|
131
|
+
'user 99999 0.0 0.0 99999 999 pts/0 S+ 00:00 /usr/bin/pytho2.7 /usr/bin/radiotray'
|
132
|
+
)
|
133
|
+
@result = task.power('on')
|
134
|
+
}
|
135
|
+
end
|
136
|
+
it 'should not change state on' do
|
137
|
+
@stdout.chomp.should match(/on/)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
describe ':power action with off' do
|
141
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'power')} }
|
142
|
+
let(:task){ Tune::Task.new(['power'], [], conf) }
|
143
|
+
before do
|
144
|
+
@stdout = capture(:stdout) {
|
145
|
+
task.should_receive(:'`').with(/ps aux/).once.and_return(
|
146
|
+
'user 99999 0.0 0.0 99999 999 pts/0 S+ 00:00 /usr/bin/pytho2.7 /usr/bin/radiotray'
|
147
|
+
)
|
148
|
+
task.should_receive(:'`').with(/killall/).once.and_return('done')
|
149
|
+
@result = task.power('off')
|
150
|
+
}
|
151
|
+
end
|
152
|
+
it 'should off power' do
|
153
|
+
@stdout.chomp.should match(/off/)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
describe ':list action' do
|
157
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'list')} }
|
158
|
+
let(:task){ Tune::Task.new(['list'], [], conf) }
|
159
|
+
before do
|
160
|
+
@stdout = capture(:stdout){ @result = task.list }
|
161
|
+
end
|
162
|
+
it 'should return all channels' do
|
163
|
+
@stdout.split("\n").length.should eq 3
|
164
|
+
@result.length.should eq 3
|
165
|
+
end
|
166
|
+
it 'should return sorted list' do
|
167
|
+
@stdout.split("\n").length.should eq 3
|
168
|
+
@result.should eq ['Country', 'Jazz', 'R&B']
|
169
|
+
end
|
170
|
+
it 'should call :puts 3 times', :ruby => 1.9 do
|
171
|
+
$stdout.should_receive(:puts).with(/Country|Jazz|R&B/).exactly(3).times
|
172
|
+
task.list.length.should eq 3
|
173
|
+
end
|
174
|
+
end
|
175
|
+
describe ':play action with invalid index' do
|
176
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'play')} }
|
177
|
+
let(:task){ Tune::Task.new(['play'], [], conf) }
|
178
|
+
before do
|
179
|
+
@player.stub(:playRadio).with(/Jazz|R&B/)
|
180
|
+
@stdout = capture(:stdout){ @result = task.play('05') }
|
181
|
+
end
|
182
|
+
it 'should display error' do
|
183
|
+
@result.should eq nil
|
184
|
+
@stdout.chomp.should eq '$05 does not exist'
|
185
|
+
end
|
186
|
+
it 'should call :puts once', :ruby => 1.9 do
|
187
|
+
$stdout.should_receive(:puts).with(/\w?does\snot\sexist$/).once
|
188
|
+
task.play('05').should eq nil
|
189
|
+
end
|
190
|
+
end
|
191
|
+
describe ':play action with any args' do
|
192
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'play')} }
|
193
|
+
let(:task){ Tune::Task.new(['play'], [], conf) }
|
194
|
+
before do
|
195
|
+
@player.stub(:playRadio).with(/Jazz|R&B/)
|
196
|
+
@stdout = capture(:stdout){ @result = task.play }
|
197
|
+
end
|
198
|
+
it 'should display current channel' do
|
199
|
+
@result.should eq nil
|
200
|
+
@stdout.chomp.should eq 'Jazz'
|
201
|
+
end
|
202
|
+
it 'should call :puts once', :ruby => 1.9 do
|
203
|
+
$stdout.should_receive(:puts).with('Jazz').once
|
204
|
+
task.play.should eq nil
|
205
|
+
end
|
206
|
+
end
|
207
|
+
describe ':play action with other channel' do
|
208
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'play')} }
|
209
|
+
let(:task){ Tune::Task.new(['play'], [], conf) }
|
210
|
+
before do
|
211
|
+
@player.stub(:playRadio).with(/Jazz|R&B/)
|
212
|
+
@stdout = capture(:stdout){ @result = task.play('02') }
|
213
|
+
end
|
214
|
+
it 'should display switched new channel' do
|
215
|
+
@result.should eq nil
|
216
|
+
@stdout.chomp.should eq 'R&B'
|
217
|
+
end
|
218
|
+
it 'should call :puts once', :ruby => 1.9 do
|
219
|
+
$stdout.should_receive(:puts).with('R&B').once
|
220
|
+
task.play('02').should eq nil
|
221
|
+
end
|
222
|
+
end
|
223
|
+
describe ':off action' do
|
224
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'off')} }
|
225
|
+
let(:task){ Tune::Task.new(['off'], [], conf) }
|
226
|
+
before do
|
227
|
+
@player.stub(:turnOff).and_return(true)
|
228
|
+
@stdout = capture(:stdout){ @result = task.off }
|
229
|
+
end
|
230
|
+
it 'should display stoped channel' do
|
231
|
+
@result.should eq nil
|
232
|
+
@stdout.chomp.should eq 'Jazz'
|
233
|
+
end
|
234
|
+
it 'should call :puts once', :ruby => 1.9 do
|
235
|
+
$stdout.should_receive(:puts).with(/Jazz/).once
|
236
|
+
task.off.should eq nil
|
237
|
+
end
|
238
|
+
end
|
239
|
+
describe ':show action' do
|
240
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'show')} }
|
241
|
+
let(:task){ Tune::Task.new(['show'], [], conf) }
|
242
|
+
before do
|
243
|
+
@stdout = capture(:stdout){ @result = task.show }
|
244
|
+
end
|
245
|
+
it 'should display current channel' do
|
246
|
+
@result.should eq nil
|
247
|
+
@stdout.chomp.should eq 'Jazz'
|
248
|
+
end
|
249
|
+
it 'should call :puts once', :ruby => 1.9 do
|
250
|
+
$stdout.should_receive(:puts).with(/Jazz/).once
|
251
|
+
task.show.should eq nil
|
252
|
+
end
|
253
|
+
end
|
254
|
+
describe ':volume action with invalid value' do
|
255
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'volume')} }
|
256
|
+
let(:task){ Tune::Task.new(['volume'], [], conf) }
|
257
|
+
before do
|
258
|
+
@player.stub(:volumeUp).and_return(true)
|
259
|
+
@player.stub(:volumeDown).and_return(true)
|
260
|
+
end
|
261
|
+
it 'should up volume as 5 with too big value' do
|
262
|
+
task.volume('up', '99').should eq 5
|
263
|
+
end
|
264
|
+
it 'should down volume as 5 with too big value' do
|
265
|
+
task.volume('down', '99').should eq 5
|
266
|
+
end
|
267
|
+
it 'should not respond with invalid direction' do
|
268
|
+
task.volume('keep', '5').should eq nil
|
269
|
+
end
|
270
|
+
end
|
271
|
+
describe ':volume action with valid value' do
|
272
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'volume')} }
|
273
|
+
let(:task){ Tune::Task.new(['volume'], [], conf) }
|
274
|
+
before do
|
275
|
+
@player.stub(:volumeUp).and_return(true)
|
276
|
+
@player.stub(:volumeDown).and_return(true)
|
277
|
+
end
|
278
|
+
it 'should up volume' do
|
279
|
+
task.volume('up', '1').should eq 1
|
280
|
+
task.volume('up', '3').should eq 3
|
281
|
+
end
|
282
|
+
it 'should down volume' do
|
283
|
+
task.volume('down', '2').should eq 2
|
284
|
+
task.volume('down', '4').should eq 4
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context 'when not playing any channel' do
|
290
|
+
before do
|
291
|
+
@player.stub(:getCurrentRadio).and_return(['not playing'])
|
292
|
+
@player.stub(:turnOff).and_return(nil)
|
293
|
+
end
|
294
|
+
describe ':off action' do
|
295
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'off')} }
|
296
|
+
let(:task){ Tune::Task.new(['off'], [], conf) }
|
297
|
+
before do
|
298
|
+
@stdout = capture(:stdout){ @result = task.off }
|
299
|
+
end
|
300
|
+
it 'should not respond and display "not playing"' do
|
301
|
+
@result.should eq nil
|
302
|
+
@stdout.chomp.should eq 'not playing'
|
303
|
+
end
|
304
|
+
it 'should call :puts once', :ruby => 1.9 do
|
305
|
+
$stdout.should_receive(:puts).with('not playing').once
|
306
|
+
task.off.should eq nil
|
307
|
+
end
|
308
|
+
end
|
309
|
+
describe ':show action' do
|
310
|
+
let(:conf){ {:current_task => OpenStruct.new(:name => 'show')} }
|
311
|
+
let(:task){ Tune::Task.new(['show'], [], conf) }
|
312
|
+
before do
|
313
|
+
@stdout = capture(:stdout){ @result = task.show }
|
314
|
+
end
|
315
|
+
it 'should display "not playing"' do
|
316
|
+
@result.should eq nil
|
317
|
+
@stdout.chomp.should eq 'not playing'
|
318
|
+
end
|
319
|
+
it 'should call :puts once', :ruby => 1.9 do
|
320
|
+
$stdout.should_receive(:puts).with('not playing').once
|
321
|
+
task.show.should eq nil
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
end
|
data/tune.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/tune/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Yasuhiro Asaka"]
|
6
|
+
gem.email = ["grauwoelfchen@gmail.com"]
|
7
|
+
gem.description = %q{tune is a command line interface of Radio Tray via dbus}
|
8
|
+
gem.summary = %q{tune is a small controller for Radio Tray}
|
9
|
+
gem.homepage = "https://github.com/grauwoelfchen/tune"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "tune"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Tune::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'ruby-dbus'
|
19
|
+
gem.add_dependency 'thor'
|
20
|
+
|
21
|
+
gem.add_development_dependency 'rspec'
|
22
|
+
gem.add_development_dependency 'fuubar'
|
23
|
+
gem.add_development_dependency 'ZenTest'
|
24
|
+
|
25
|
+
# travis
|
26
|
+
gem.add_development_dependency 'rake', '~> 0.9.2.2'
|
27
|
+
gem.add_development_dependency 'rdoc', '~> 3.11'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tune
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Yasuhiro Asaka
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ruby-dbus
|
16
|
+
requirement: &3249080 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *3249080
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: thor
|
27
|
+
requirement: &3248500 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *3248500
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &3248080 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *3248080
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: fuubar
|
49
|
+
requirement: &3263520 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *3263520
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: ZenTest
|
60
|
+
requirement: &3262320 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *3262320
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: &3260780 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.9.2.2
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *3260780
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rdoc
|
82
|
+
requirement: &3258940 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '3.11'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *3258940
|
91
|
+
description: tune is a command line interface of Radio Tray via dbus
|
92
|
+
email:
|
93
|
+
- grauwoelfchen@gmail.com
|
94
|
+
executables:
|
95
|
+
- tune
|
96
|
+
extensions: []
|
97
|
+
extra_rdoc_files: []
|
98
|
+
files:
|
99
|
+
- .autotest
|
100
|
+
- .gitignore
|
101
|
+
- .rspec
|
102
|
+
- .travis.yml
|
103
|
+
- Gemfile
|
104
|
+
- LICENSE
|
105
|
+
- README.md
|
106
|
+
- Rakefile
|
107
|
+
- bin/tune
|
108
|
+
- lib/tune.rb
|
109
|
+
- lib/tune/task.rb
|
110
|
+
- lib/tune/version.rb
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
- spec/tune_spec.rb
|
113
|
+
- tune.gemspec
|
114
|
+
homepage: https://github.com/grauwoelfchen/tune
|
115
|
+
licenses: []
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
hash: -336486918070267591
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
hash: -336486918070267591
|
138
|
+
requirements: []
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 1.8.10
|
141
|
+
signing_key:
|
142
|
+
specification_version: 3
|
143
|
+
summary: tune is a small controller for Radio Tray
|
144
|
+
test_files:
|
145
|
+
- spec/spec_helper.rb
|
146
|
+
- spec/tune_spec.rb
|