rmpd 1.1.9 → 1.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), "rmpd/config")
2
2
  require File.join(File.dirname(__FILE__), "rmpd/command")
3
3
  require File.join(File.dirname(__FILE__), "rmpd/commands")
4
- require File.join(File.dirname(__FILE__), "rmpd/io")
5
4
  require File.join(File.dirname(__FILE__), "rmpd/connection")
6
5
  require File.join(File.dirname(__FILE__), "rmpd/response")
6
+ require File.join(File.dirname(__FILE__), "rmpd/nil_hash")
7
+
7
8
 
8
9
  module Rmpd
9
10
  ACK_RE = /^ACK \[(\d+)@(\d+)\] \{([^}]*)\} (.*)$/
@@ -23,6 +23,10 @@ module Rmpd
23
23
  CommandListOkStrategy
24
24
  elsif /command_list/ === name
25
25
  CommandListStrategy
26
+ elsif /^noidle$/ === name
27
+ NoidleStrategy
28
+ elsif /^idle$/ === name
29
+ IdleStrategy
26
30
  else
27
31
  CommandStrategy
28
32
  end
@@ -34,12 +38,45 @@ module Rmpd
34
38
  list
35
39
  end
36
40
 
41
+ module IdleStrategy
42
+
43
+ def execute(connection, *args, &block)
44
+ connection.send_command(@name, *args)
45
+ if block_given?
46
+ yield connection.socket rescue nil
47
+ connection.send_command("noidle")
48
+ end
49
+ Response.factory(@name).parse(connection.read_response)
50
+ rescue EOFError
51
+ puts "IdleStrategy EOFError received, retrying" if $DEBUG
52
+ connection.close
53
+ retry
54
+ end
55
+
56
+ end
57
+
58
+ module NoidleStrategy
59
+
60
+ def execute(connection, *args)
61
+ connection.send_command(@name, *args)
62
+ # The MPD server will never respond to a noidle command.
63
+ # http://www.mail-archive.com/musicpd-dev-team@lists.sourceforge.net/msg02246.html
64
+ nil
65
+ rescue EOFError
66
+ puts "NoidleStrategy EOFError received, retrying" if $DEBUG
67
+ connection.close
68
+ retry
69
+ end
70
+
71
+ end
72
+
37
73
  module CommandStrategy
38
74
 
39
75
  def execute(connection, *args)
40
76
  connection.send_command(@name, *args)
41
77
  Response.factory(@name).parse(connection.read_response)
42
78
  rescue EOFError
79
+ puts "CommandStrategy EOFError received, retrying" if $DEBUG
43
80
  connection.close
44
81
  retry
45
82
  end
@@ -58,6 +95,10 @@ module Rmpd
58
95
  end
59
96
  connection.send_command("command_list_end")
60
97
  Response.factory(@name).parse(connection.read_response)
98
+ rescue EOFError
99
+ puts "CommandListStrategy EOFError received, retrying" if $DEBUG
100
+ connection.close
101
+ retry
61
102
  end
62
103
 
63
104
  end
@@ -74,6 +115,10 @@ module Rmpd
74
115
  end
75
116
  connection.send_command("command_list_end")
76
117
  handle_command_list_ok_response(connection.read_response)
118
+ rescue EOFError
119
+ puts "CommandListOkStrategy EOFError received, retrying" if $DEBUG
120
+ connection.close
121
+ retry
77
122
  end
78
123
 
79
124
 
@@ -3,6 +3,7 @@ module Rmpd
3
3
 
4
4
  simple_command :count
5
5
  simple_command :find
6
+ simple_command :findadd
6
7
  simple_command :list
7
8
  simple_command :listall
8
9
  simple_command :listallinfo
@@ -1,11 +1,12 @@
1
1
  module Rmpd
2
2
  module Commands
3
3
 
4
+ simple_command :config
4
5
  simple_command :commands
5
6
  simple_command :notcommands
6
7
  simple_command :clearerror
7
- simple_command :_idle
8
- simple_command :_noidle
8
+ simple_command :idle
9
+ simple_command :noidle
9
10
  simple_command :password
10
11
  simple_command :ping
11
12
  simple_command :stats
@@ -20,20 +21,7 @@ module Rmpd
20
21
  simple_command :command_list
21
22
  simple_command :command_list_ok
22
23
 
23
- def idle(*subsystems)
24
- @in_idle = true
25
- _idle(mpd, *subsystems)
26
- ensure
27
- @in_idle = false
28
- end
29
-
30
- def noidle
31
- return unless @in_idle
32
- _noidle
33
- end
34
-
35
24
  alias_method :clear_error, :clearerror
36
25
  alias_method :not_commands, :notcommands
37
-
38
26
  end
39
27
  end
@@ -5,7 +5,6 @@ module Rmpd
5
5
  class Connection
6
6
  include Socket::Constants
7
7
  include Rmpd::Commands
8
- include Rmpd::IO
9
8
 
10
9
 
11
10
  MAX_RETRIES = 5
@@ -26,6 +25,24 @@ module Rmpd
26
25
  def connect
27
26
  return unless @socket.nil? || @socket.closed?
28
27
 
28
+ if %r{^/} === @config.hostname
29
+ connect_unix_socket
30
+ else
31
+ connect_inet_socket
32
+ end
33
+
34
+ read_response # protocol version, ignore for now
35
+ password(@config.password) if @config.password
36
+ end
37
+
38
+ def connect_unix_socket
39
+ @socket = UNIXSocket.new(@config.hostname)
40
+ rescue StandardError => error
41
+ @socket = nil
42
+ raise MpdConnRefusedError.new(error)
43
+ end
44
+
45
+ def connect_inet_socket
29
46
  Socket::getaddrinfo(@config.hostname, @config.port, nil, SOCK_STREAM).each do |info|
30
47
  begin
31
48
  sockaddr = Socket.pack_sockaddr_in(info[1], info[3])
@@ -38,9 +55,6 @@ module Rmpd
38
55
  break
39
56
  end
40
57
  end
41
-
42
- read_response # protocol version, ignore for now
43
- password(@config.password) if @config.password
44
58
  end
45
59
 
46
60
  def send_command(command, *args)
@@ -0,0 +1,11 @@
1
+ class NilHash < Hash
2
+
3
+ def method_missing(name, *args, &block)
4
+ super
5
+ rescue NoMethodError
6
+ if 0 == args.size
7
+ self[name]
8
+ end
9
+ end
10
+
11
+ end
@@ -40,6 +40,8 @@ module Rmpd
40
40
  "list",
41
41
  "outputs",
42
42
  "playlistinfo",
43
+ "plchanges",
44
+ "plchangesposid",
43
45
  "search",
44
46
  "tagtypes",
45
47
  ]
@@ -142,7 +144,7 @@ module Rmpd
142
144
 
143
145
  def parse(lines)
144
146
  @first_key = nil
145
- @temp = {}
147
+ @temp = NilHash.new
146
148
 
147
149
  super(lines)
148
150
  self << @temp unless @temp.empty?
@@ -155,12 +157,12 @@ module Rmpd
155
157
 
156
158
  if @first_key == key
157
159
  self << @temp
158
- @temp = {key => val}
160
+ @temp = NilHash.new({key => val})
159
161
  else
160
162
  @first_key ||= key
161
163
  @temp[key] = val
162
- define_getter(key, @temp)
163
164
  end
165
+ define_getter(key, @temp) unless respond_to?(key)
164
166
  end
165
167
 
166
168
  end
@@ -168,7 +170,7 @@ module Rmpd
168
170
  class SingleResponse < Response
169
171
 
170
172
  def initialize
171
- super({})
173
+ super(NilHash.new)
172
174
  end
173
175
 
174
176
  def register_key_val_pair(match_data)
@@ -1,3 +1,3 @@
1
1
  module Rmpd
2
- VERSION = "1.1.9"
2
+ VERSION = "1.1.11"
3
3
  end
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  s.add_development_dependency("rspec", "~> 2.6.0")
23
- s.add_development_dependency("ruby-debug")
23
+ s.add_development_dependency("debugger")
24
24
  s.add_development_dependency("rake")
25
25
  s.add_development_dependency("pry")
26
26
  end
@@ -17,6 +17,7 @@ describe Rmpd::Commands do
17
17
  before(:each) do
18
18
  @socket = mock_socket
19
19
  @config = mock_config
20
+ Socket.stub!(:new).and_return(@socket)
20
21
  @conn = Connection.new
21
22
  end
22
23
 
@@ -44,9 +45,9 @@ describe Rmpd::Commands do
44
45
 
45
46
  describe "close" do
46
47
  it "should close the socket" do
47
- @socket.should_receive(:puts).with("close")
48
48
  @socket.stub!(:readline).and_return(*connect_response)
49
49
  @socket.should_receive(:close).once
50
+ @conn.ping
50
51
  @conn.close
51
52
  end
52
53
  end
@@ -134,6 +135,27 @@ describe Rmpd::Commands do
134
135
  end
135
136
  end
136
137
 
138
+ describe "noidle" do
139
+
140
+ it "returns nil" do
141
+ @responses = connect_response
142
+ @socket.stub!(:readline).and_return(*@responses)
143
+
144
+ @conn.noidle.should be_nil
145
+ end
146
+
147
+ it "consumes no response, since none is tendered" do
148
+ @responses = connect_response + status_response + ok
149
+ @socket.stub!(:readline).and_return(*@responses)
150
+
151
+ response = @conn.status
152
+
153
+ response.should have(2).items, response.pretty_inspect
154
+ response.should include("volume")
155
+ response.should include("state")
156
+ end
157
+ end
158
+
137
159
  describe "command_list_ok" do
138
160
  it "should return a list of multi responses" do
139
161
  @responses = connect_response + command_list_ok_responses + ok
@@ -50,3 +50,7 @@ end
50
50
  def command_list_ok_responses
51
51
  ["Album: Foo\n", "list_OK\n", "Artist: Bar\n", "list_OK\n"]
52
52
  end
53
+
54
+ def status_response
55
+ ["volume: -1\n", "state: play\n",]
56
+ end
metadata CHANGED
@@ -1,90 +1,87 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rmpd
3
- version: !ruby/object:Gem::Version
4
- hash: 1
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.11
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 1
9
- - 9
10
- version: 1.1.9
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Eric Wollesen
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2013-03-07 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2013-07-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rspec
22
- version_requirements: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
23
17
  none: false
24
- requirements:
18
+ requirements:
25
19
  - - ~>
26
- - !ruby/object:Gem::Version
27
- hash: 23
28
- segments:
29
- - 2
30
- - 6
31
- - 0
20
+ - !ruby/object:Gem::Version
32
21
  version: 2.6.0
33
22
  type: :development
34
- requirement: *id001
35
23
  prerelease: false
36
- - !ruby/object:Gem::Dependency
37
- name: ruby-debug
38
- version_requirements: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
39
25
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.6.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: debugger
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
47
38
  type: :development
48
- requirement: *id002
49
39
  prerelease: false
50
- - !ruby/object:Gem::Dependency
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
51
47
  name: rake
52
- version_requirements: &id003 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
53
49
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
- version: "0"
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
61
54
  type: :development
62
- requirement: *id003
63
55
  prerelease: false
64
- - !ruby/object:Gem::Dependency
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
65
63
  name: pry
66
- version_requirements: &id004 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
67
65
  none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
75
70
  type: :development
76
- requirement: *id004
77
71
  prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
78
  description: Music Player Daemon client in Ruby
79
- email:
79
+ email:
80
80
  - ericw@xmtp.net
81
81
  executables: []
82
-
83
82
  extensions: []
84
-
85
83
  extra_rdoc_files: []
86
-
87
- files:
84
+ files:
88
85
  - .gitignore
89
86
  - .rspec
90
87
  - .rvmrc
@@ -102,7 +99,7 @@ files:
102
99
  - lib/rmpd/commands/playlist.rb
103
100
  - lib/rmpd/config.rb
104
101
  - lib/rmpd/connection.rb
105
- - lib/rmpd/io.rb
102
+ - lib/rmpd/nil_hash.rb
106
103
  - lib/rmpd/response.rb
107
104
  - lib/rmpd/response_splitter.rb
108
105
  - lib/rmpd/version.rb
@@ -123,36 +120,32 @@ files:
123
120
  - spec/spec_rcov.opts
124
121
  homepage: http://github.com/ewollesen/rmpd
125
122
  licenses: []
126
-
127
123
  post_install_message:
128
124
  rdoc_options: []
129
-
130
- require_paths:
125
+ require_paths:
131
126
  - lib
132
- required_ruby_version: !ruby/object:Gem::Requirement
127
+ required_ruby_version: !ruby/object:Gem::Requirement
133
128
  none: false
134
- requirements:
135
- - - ">="
136
- - !ruby/object:Gem::Version
137
- hash: 3
138
- segments:
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ segments:
139
134
  - 0
140
- version: "0"
141
- required_rubygems_version: !ruby/object:Gem::Requirement
135
+ hash: 2970925028450146323
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
137
  none: false
143
- requirements:
144
- - - ">="
145
- - !ruby/object:Gem::Version
146
- hash: 3
147
- segments:
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
148
143
  - 0
149
- version: "0"
144
+ hash: 2970925028450146323
150
145
  requirements: []
151
-
152
146
  rubyforge_project:
153
- rubygems_version: 1.8.24
147
+ rubygems_version: 1.8.23
154
148
  signing_key:
155
149
  specification_version: 3
156
150
  summary: Music Player Daemon client in Ruby
157
151
  test_files: []
158
-
@@ -1,18 +0,0 @@
1
- module Rmpd
2
- module IO
3
-
4
- def to_io
5
- send_command("idle") unless @in_idle
6
- @in_idle = true
7
- @socket
8
- end
9
-
10
- def check_select
11
- return unless @in_idle
12
- Response.factory("idle").parse(read_response)
13
- ensure
14
- @in_idle = false
15
- end
16
-
17
- end
18
- end