squeezer-ruby 0.1.1 → 0.2.0

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.
@@ -120,58 +120,90 @@ module Squeezer
120
120
  power(:off)
121
121
  end
122
122
 
123
- def <=>(target)
124
- self.name <=> target.name
123
+ # fade in seconds
124
+ def play(fade=0)
125
+ cmd("#{id} play #{fade}")
126
+ end
127
+
128
+ def stop
129
+ cmd("#{id} stop")
125
130
  end
126
131
 
127
- # TODO method_missing anyone? Those find methods could be nice with a ghost method.
132
+ def pause
133
+ cmd("#{id} pause")
134
+ end
128
135
 
129
- # beware of offline players, they still show up on the list
130
- # test if those players are connected with Player#connected?
131
- def players
132
- player_map = Hash.new
133
- count = cmd("player count ?").to_i
134
- count.to_i.times do |index|
135
- id = cmd("player id #{index} ?")
136
- player_map[id] = Models::Player.new(id)
137
- end
138
- player_map
136
+ def playing?
137
+ mode == :play
139
138
  end
140
139
 
141
- def self.all
142
- self.new(nil).players
140
+ def stopped?
141
+ mode == :stop
143
142
  end
144
143
 
145
- # handle duplicates in these find methods, specs expect only one result
146
- def find_by_name(name)
147
- find(:name => name)
144
+ def paused?
145
+ mode == :pause
148
146
  end
149
147
 
150
- def self.find_by_name(name)
151
- self.new(nil).find_by_name(name)
148
+ def mode
149
+ cmd("#{id} mode ?").to_sym
150
+ end
151
+
152
+ def show(options)
153
+ cmd("#{id} show font:#{options[:font]} line2:#{options[:line2]} centered:#{options[:centered]} duration:#{options[:duration]}")
152
154
  end
153
155
 
154
- def find_by_ip(ip)
155
- find(:ip => ip)
156
+ def alert(message, options={})
157
+ options = {:line2 => URI.escape(message), :centered => true, :duration => 3, :font => :huge}.merge(options)
158
+ show(options)
156
159
  end
157
160
 
158
- def self.find_by_ip(ip)
159
- p = self.new(nil)
160
- result = p.find_by_ip(ip)
161
- p = nil
161
+ def blink(message, times, duration=1, options={})
162
+ times.times do
163
+ alert(message, :duration => duration)
164
+ sleep duration
165
+ end
166
+ end
167
+
168
+ def playlist
169
+ Models::Playlist.new(id)
170
+ end
171
+
172
+ def <=>(target)
173
+ self.name <=> target.name
174
+ end
175
+
176
+ # beware of offline players, they still show up on the list
177
+ # test if those players are connected with Player#connected?
178
+ def players
179
+ Player.all
180
+ end
181
+
182
+ def self.all
183
+ result = Array.new
184
+ count = Connection.exec("player count ?").to_i
185
+ count.to_i.times do |index|
186
+ id = Connection.exec("player id #{index} ?")
187
+ result << Models::Player.new(id)
188
+ end
162
189
  result
163
190
  end
164
191
 
165
- def find_by_id(id)
166
- find(:id => id)
192
+ # handle duplicates in these find methods, specs expect only one result
193
+ def self.find_by_name(name)
194
+ find(:name => name)
167
195
  end
168
196
 
197
+ def self.find_by_ip(ip)
198
+ find(:ip => ip)
199
+ end
200
+
169
201
  def self.find_by_id(id)
170
- self.new(nil).find_by_id(id)
202
+ find(:id => id)
171
203
  end
172
-
173
- def find(values)
174
- players.each do |id,player|
204
+
205
+ def self.find(values)
206
+ all.each do |player|
175
207
  match = true
176
208
  values.each do |property,value|
177
209
  match = false unless player.send(property.to_sym) == value
@@ -180,11 +212,7 @@ module Squeezer
180
212
  end
181
213
  return nil
182
214
  end
183
-
184
- def self.find(values)
185
- self.new(nil).find(values)
186
- end
187
-
215
+
188
216
  end
189
217
  end
190
218
  end
@@ -0,0 +1,43 @@
1
+ module Squeezer
2
+ module Models
3
+
4
+ # initial playlist support
5
+ class Playlist < Model
6
+
7
+ attr_reader :id
8
+
9
+ def initialize(id, options={})
10
+ super options
11
+ @id = id
12
+ end
13
+
14
+ def add(entity)
15
+ playlistcontrol(:cmd => :add, :entity => entity_name(entity), :id => entity.id)
16
+ true
17
+ end
18
+
19
+ # starts playing directly
20
+ def load(entity)
21
+ playlistcontrol(:cmd => :load, :entity => entity_name(entity), :id => entity.id)
22
+ true
23
+ end
24
+
25
+ def clear
26
+ cmd "#{id} playlist clear"
27
+ end
28
+
29
+ private
30
+
31
+ def entity_name(entity)
32
+ entity.class.to_s.downcase.split('::').last
33
+ end
34
+
35
+ def playlistcontrol(options)
36
+ # TODO make better use of these options
37
+ # .. and what about entity lists?
38
+ cmd "#{id} playlistcontrol cmd:#{options[:cmd]} #{options[:entity]}_id:#{options[:id]}"
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ module Squeezer
2
+ module Models
3
+
4
+ class Track < Model
5
+ attr_accessor :id, :name
6
+
7
+ def initialize(record=nil)
8
+ unless record.nil?
9
+ @id = record[:id] if record.key?(:id)
10
+ @name = record[:title] if record.key?(:title)
11
+ end
12
+ end
13
+
14
+ def self.total
15
+ Connection.exec("info total songs ?").to_i
16
+ end
17
+
18
+ def self.all
19
+ results = Array.new
20
+ Model.extract_records(Connection.exec("tracks 0 #{total} charset:utf8 tags:s")).each do |record|
21
+ results << Track.new(record)
22
+ end
23
+ results
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -1,4 +1,4 @@
1
1
  module Squeezer
2
2
  # The version of the gem
3
- VERSION = '0.1.1'.freeze unless defined?(::Squeezer::VERSION)
3
+ VERSION = '0.2.0'.freeze unless defined?(::Squeezer::VERSION)
4
4
  end
data/script/console ADDED
@@ -0,0 +1,16 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ libs = []
4
+ libs << "irb/completion"
5
+ libs << File.expand_path("../../lib/squeezer.rb", __FILE__)
6
+
7
+ command_line = []
8
+ command_line << "irb"
9
+ command_line << libs.inject("") { |acc, lib| acc + %( -r "#{lib}") }
10
+ command_line << "--simple-prompt"
11
+ command_line << "-d"
12
+ command_line << "-W1"
13
+ command = command_line.join(" ")
14
+
15
+ puts "Welcome to the Squeezer console interface."
16
+ exec command
data/spec/spec_helper.rb CHANGED
@@ -1,41 +1,48 @@
1
- require 'simplecov'
2
- SimpleCov.start do
3
- add_group 'Squeezer', 'lib/squeezer'
4
- add_group 'Specs', 'spec'
5
- end
1
+ require 'rubygems'
2
+ require 'spork'
6
3
 
7
- #require 'mocha'
8
- RSpec.configure do |config|
9
- config.mock_with :mocha
4
+ Spork.prefork do
5
+ # Loading more in this block will cause your tests to run faster. However,
6
+ # if you change any configuration or code from libraries loaded here, you'll
7
+ # need to restart spork for it take effect.
10
8
 
11
- config.before(:each) do
12
- # TODO add authentication stuff to the mock
13
- @connection = mock("connection")
14
- sock = mock("sock")
15
- sock.stubs(:close).returns(true)
16
- @connection.stubs(:sock).returns(sock)
17
- @connection.stubs(:cmd).with("exit")
18
-
19
- # Net::Telnet.stubs(:new).returns(@connection)
20
-
21
- # maybe find a better way to mock the connection? Because the mock
22
- # stays in memory of the API's eigenclass if we mocked the telnet
23
- # connection directly. So we mock the connection getter instead.
24
- # But since we didn't find a way to mock a module method, we mock the
25
- # getter per class.
26
- Squeezer::Models::Player.any_instance.stubs(:connection).returns(@connection)
27
- Squeezer::Client.any_instance.stubs(:connection).returns(@connection)
9
+ require 'rspec'
10
+ require 'simplecov'
11
+ SimpleCov.start do
12
+ add_group 'Squeezer', 'lib/squeezer'
13
+ add_group 'Specs', 'spec'
14
+ add_filter __FILE__
28
15
  end
29
16
 
30
- config.after(:each) do
31
- # Squeezer.exit
17
+ RSpec.configure do |config|
18
+ config.mock_with :mocha
19
+
20
+ config.before(:each) do
21
+ # TODO add authentication stuff to the mock
22
+ @connection = mock("connection")
23
+ sock = mock("sock")
24
+ sock.stubs(:close).returns(true)
25
+ @connection.stubs(:sock).returns(sock)
26
+ @connection.stubs(:cmd).with("exit")
27
+
28
+ Net::Telnet.stubs(:new).returns(@connection)
29
+ end
30
+
31
+ config.after(:each) do
32
+ Squeezer.exit
33
+ end
32
34
  end
33
35
  end
34
36
 
35
- require File.expand_path('../../lib/squeezer', __FILE__)
37
+ Spork.each_run do
38
+ # This code will be run each time you run your specs.
39
+
40
+ load File.expand_path('../../lib/squeezer.rb', __FILE__)
41
+ end
36
42
 
37
- require 'rspec'
38
43
 
39
44
  def stub_connection
40
45
  @connection.stubs(:cmd)
41
- end
46
+ end
47
+
48
+
@@ -6,31 +6,31 @@ describe Squeezer::Client do
6
6
  end
7
7
 
8
8
  describe ".total_*" do
9
- it "should return the entity's total artists" do
9
+ it "should return the total artists" do
10
10
  stub_connection.with("info total artists ?").returns("info total artists 2\n")
11
11
  @client.total_artists.should == 2
12
12
  end
13
13
 
14
- it "should return the entity's total albums" do
14
+ it "should return the total albums" do
15
15
  stub_connection.with("info total albums ?").returns("info total albums 4\n")
16
16
  @client.total_albums.should == 4
17
17
  end
18
18
 
19
- it "should return the entity's total genres" do
19
+ it "should return the total genres" do
20
20
  stub_connection.with("info total genres ?").returns("info total genres 6\n")
21
21
  @client.total_genres.should == 6
22
22
  end
23
23
 
24
- it "should return the entity's total songs" do
24
+ it "should return the total songs" do
25
25
  stub_connection.with("info total songs ?").returns("info total songs 8\n")
26
- @client.total_songs.should == 8
26
+ @client.total_tracks.should == 8
27
27
  end
28
28
  end
29
29
 
30
30
  describe ".artists" do
31
31
  before do
32
32
  stub_connection.with("info total artists ?").returns("info total artists 1\n")
33
- stub_connection.with("artists 0 2 charset:utf8 tags:s").returns("artists 0 2 charset%3Autf8 tags%3As id%3A4631 artist%3AVarious%20Artists textkey%3A%20 id%3A3998 artist%3A1200%20Micrograms textkey%3A1 count%3A434\n")
33
+ stub_connection.with("artists 0 2 charset:utf8 tags:s").returns("artists 0 2 charset%3Autf8 tags%3As id%3A4631 artist%3AVarious%20Artists textkey%3A%20 id%3A3998 artist%3AAwesome%20Artist textkey%3AA count%3A434\n")
34
34
  end
35
35
 
36
36
  it "should return a list with Artist models" do
@@ -44,5 +44,96 @@ describe Squeezer::Client do
44
44
  artists.first.name.should == "Various Artists"
45
45
  end
46
46
  end
47
+
48
+ describe ".albums" do
49
+ before do
50
+ stub_connection.with("info total albums ?").returns("info total albums 2\n")
51
+ stub_connection.with("albums 0 2 charset:utf8 tags:tqs").returns("albums 0 2 charset%3Autf8 tags%3Atqs id%3A4631 title%3AAwesome%20Album disccount%3A1 textkey%3AA id%3A3998 title%3AAnother%20Album textkey%3AA count%3A434\n")
52
+ end
53
+
54
+ it "should return a list with Album models" do
55
+ albums = @client.albums
56
+ albums.first.should be_a Squeezer::Models::Album
57
+ end
58
+
59
+ it "should return a list with all the albums" do
60
+ albums = @client.albums
61
+ albums.should have(2).things
62
+ albums.first.name.should == "Awesome Album"
63
+ albums.first.discs.should == 1
64
+ end
65
+ end
66
+
67
+ describe ".tracks" do
68
+ before do
69
+ stub_connection.with("info total songs ?").returns("info total songs 2\n")
70
+ stub_connection.with("tracks 0 2 charset:utf8 tags:s").returns("albums 0 2 charset%3Autf8 tags%3As id%3A4631 title%3AAwesome%20Track textkey%3AA id%3A3998 title%3AAnother%20Track textkey%3AA count%3A434\n")
71
+ end
72
+
73
+ it "should return a list with Track models" do
74
+ tracks = @client.tracks
75
+ tracks.first.should be_a Squeezer::Models::Track
76
+ end
77
+
78
+ it "should return a list with all the tracks" do
79
+ tracks = @client.tracks
80
+ tracks.should have(2).things
81
+ tracks.first.name.should == "Awesome Track"
82
+ end
83
+ end
84
+
85
+ describe ".genres" do
86
+ before do
87
+ stub_connection.with("info total genres ?").returns("info total genres 2\n")
88
+ stub_connection.with("genres 0 2 charset:utf8 tags:s").returns("genres 0 2 charset%3Autf8 tags%3As id%3A4631 genre%3AAwesome%20Genre textkey%3AA id%3A3998 genre%3AAnother%20Genre textkey%3AA count%3A434\n")
89
+ end
90
+
91
+ it "should return a list with Genre models" do
92
+ genres = @client.genres
93
+ genres.first.should be_a Squeezer::Models::Genre
94
+ end
95
+
96
+ it "should return a list with all the genres" do
97
+ genres = @client.genres
98
+ genres.should have(2).things
99
+ genres.first.name.should == "Awesome Genre"
100
+ end
101
+ end
102
+
103
+ context "database scanning" do
104
+ describe ".rescan!" do
105
+ it "should initiate a rescan of the music database" do
106
+ stub_connection.with("rescan").returns("rescan")
107
+ @client.rescan!.should be true
108
+ end
109
+ end
47
110
 
111
+ describe ".scanning?" do
112
+ it "should indicate whether or not the database is scanning" do
113
+ stub_connection.with("rescan ?").returns("rescan 1")
114
+ @client.scanning?.should be true
115
+ end
116
+ end
117
+
118
+ describe ".abortscan!" do
119
+ it "should abort a scan" do
120
+ stub_connection.with("abortscan").returns("abortscan")
121
+ @client.abortscan!.should be true
122
+ end
123
+ end
124
+
125
+ describe ".wipecache!" do
126
+ it "should wipe the database" do
127
+ stub_connection.with("wipecache").returns("wipecache")
128
+ @client.wipecache!.should be true
129
+ end
130
+ end
131
+
132
+ describe ".rescan_progress" do
133
+ it "should return the rescan progress" do
134
+ stub_connection.with("rescanprogress").returns("rescan%3A1 directory%3A100 musicip%3A100 mergeva%3A100 cleanup1%3A100 cleanup2%3A100 steps%3Adirectory%2Cmusicip%2Cmergeva%2Ccleanup1%2Ccleanup2 totaltime%3A00%3A00%3A38")
135
+ @client.rescan_progress[:rescan].to_boolean.should be true
136
+ end
137
+ end
138
+ end
48
139
  end