rmpd 1.1.15 → 1.1.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b9c7230c97e3cbfe65f19e3384b1de83457ac72
4
- data.tar.gz: e33c538d3f9e14964fecd306f34d356245cefa21
3
+ metadata.gz: 7ed7a0812069ac86c9233bca9760bcceb0acc079
4
+ data.tar.gz: 48355f71e90c5cdadd1130d5dab71ec705274783
5
5
  SHA512:
6
- metadata.gz: 85c9e1503c810b455ba4b40df7f7e4bc970ba3d3f1b4f89d4a7d6487d1ddf0ec16b8fbdab235c88413ec9f09cb234cf6ecd414423a9f6f8548684e02c23c7f99
7
- data.tar.gz: e6820320c75a8879894e64a7dd2809790f58b12099687acffa0078d7a29754ee8324d1d1f90a032d05485c502283bd17bbe5614ed2eaf0363ca15dff5d6329fb
6
+ metadata.gz: 368aabafe5d5d3aa6c115ea01594ebcac6e3e17580379aa6cd2c0f09f5a76725d438483f2f17d13dd40049722e11b7bf113d839fbd16e7d197b7df2d9591fb6d
7
+ data.tar.gz: f31ddb04deb6543737e1d4681fbb698f34ceb1f9b7ee5bfbe31cbdaffb64dfd02f630e3091c14a95893192a22f284ad2e1dd1feb385f2407f8c80ef9f181e371
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .ruby-version
data/console.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "pry"
4
4
  require "rmpd"
5
- require "ruby-debug"
5
+ require "byebug"
6
6
  require "stringio"
7
7
 
8
8
  conf = StringIO.new <<EOF
@@ -17,6 +17,8 @@ module Rmpd
17
17
 
18
18
  class MpdConnRefusedError < MpdError ; end
19
19
 
20
+ class MpdDisconnectedError < MpdError; end
21
+
20
22
  class MpdAckError < MpdError
21
23
  def initialize(regex_match)
22
24
  @error, @command_list_num, @current_command, @message = regex_match.values_at(1..-1)
@@ -41,31 +41,26 @@ module Rmpd
41
41
  module IdleStrategy
42
42
 
43
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")
44
+ connection.synchronize do
45
+ connection.send_command(@name, *args)
46
+ if block_given?
47
+ yield connection.socket rescue nil
48
+ connection.send_command("noidle")
49
+ end
50
+ Response.factory(@name).parse(connection.read_response)
48
51
  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
52
  end
55
-
56
53
  end
57
54
 
58
55
  module NoidleStrategy
59
56
 
60
57
  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
58
+ connection.synchronize do
59
+ connection.send_command(@name, *args)
60
+ # The MPD server will never respond to a noidle command.
61
+ # http://www.mail-archive.com/musicpd-dev-team@lists.sourceforge.net/msg02246.html
62
+ nil
63
+ end
69
64
  end
70
65
 
71
66
  end
@@ -73,52 +68,83 @@ module Rmpd
73
68
  module CommandStrategy
74
69
 
75
70
  def execute(connection, *args)
76
- connection.send_command(@name, *args)
77
- Response.factory(@name).parse(connection.read_response)
78
- rescue EOFError
79
- puts "CommandStrategy EOFError received, retrying" if $DEBUG
80
- connection.close
81
- retry
71
+ tries = 0
72
+ begin
73
+ connection.synchronize do
74
+ connection.send_command(@name, *args)
75
+ Response.factory(@name).parse(connection.read_response)
76
+ end
77
+ rescue MpdDisconnectedError => e
78
+ tries += 1
79
+ if tries < 5
80
+ puts "CommandStrategy MpdDisconnectedError received, retrying" if $DEBUG
81
+ connection.connect
82
+ retry
83
+ else
84
+ puts "CommandStrategy retries exceeded" if $DEBUG
85
+ raise e
86
+ end
87
+ end
82
88
  end
83
-
84
89
  end
85
90
 
86
91
  module CommandListStrategy
87
92
 
88
93
  def execute(connection, *args, &block)
94
+ tries = 0
89
95
  list = List.new
90
96
  yield list
91
97
 
92
- connection.send_command("command_list_begin")
93
- list.map do |command_w_args|
94
- connection.send_command(*command_w_args)
98
+ begin
99
+ connection.synchronize do
100
+ connection.send_command("command_list_begin")
101
+ list.map do |command_w_args|
102
+ connection.send_command(*command_w_args)
103
+ end
104
+ connection.send_command("command_list_end")
105
+ Response.factory(@name).parse(connection.read_response)
106
+ end
107
+ rescue MpdDisconnectedError => e
108
+ tries += 1
109
+ if tries < 5
110
+ puts "CommandListStrategy MpdDisconnectedError received, retrying" if $DEBUG
111
+ connect
112
+ retry
113
+ else
114
+ puts "CommandListStrategy retries exceeded" if $DEBUG
115
+ raise e
116
+ end
95
117
  end
96
- connection.send_command("command_list_end")
97
- Response.factory(@name).parse(connection.read_response)
98
- rescue EOFError
99
- puts "CommandListStrategy EOFError received, retrying" if $DEBUG
100
- connection.close
101
- retry
102
118
  end
103
-
104
119
  end
105
120
 
106
121
  module CommandListOkStrategy
107
122
 
108
123
  def execute(connection, *args, &block)
124
+ tries = 0
109
125
  @list = List.new
110
126
  yield @list
111
127
 
112
- connection.send_command("command_list_ok_begin")
113
- @list.map do |command_w_args|
114
- connection.send_command(*command_w_args)
128
+ begin
129
+ connection.synchronize do
130
+ connection.send_command("command_list_ok_begin")
131
+ @list.map do |command_w_args|
132
+ connection.send_command(*command_w_args)
133
+ end
134
+ connection.send_command("command_list_end")
135
+ handle_command_list_ok_response(connection.read_response)
136
+ end
137
+ rescue MpdDisconnectedError => e
138
+ tries += 1
139
+ if tries < 5
140
+ puts "CommandListOkStrategy MpdDisconnectedError received, retrying" if $DEBUG
141
+ connect
142
+ retry
143
+ else
144
+ puts "CommandListOkStrategy retries exceeded" if $DEBUG
145
+ raise e
146
+ end
115
147
  end
116
- connection.send_command("command_list_end")
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
122
148
  end
123
149
 
124
150
 
@@ -8,9 +8,9 @@ module Rmpd
8
8
  simple_command :update
9
9
 
10
10
  def kill
11
- send_command_without_reconnect("kill")
12
11
  @socket_mu.lock
13
12
  begin
13
+ send_command("kill")
14
14
  @socket.close
15
15
  ensure
16
16
  @socket_mu.unlock
@@ -13,8 +13,13 @@ module Rmpd
13
13
  simple_command :status
14
14
 
15
15
  def close
16
- send_command_without_reconnect("close")
17
- @socket.synchronize {@socket.close}
16
+ @socket_mu.lock
17
+ begin
18
+ send_command("close")
19
+ @socket.close
20
+ ensure
21
+ @socket_mu.unlock
22
+ end
18
23
  end
19
24
 
20
25
  simple_command :command_list
@@ -20,44 +20,71 @@ module Rmpd
20
20
  end
21
21
 
22
22
  def close
23
- @socket_mu.lock
24
- @socket.close
25
- @socket_mu.unlock
23
+ @socket_mu.synchronize {@socket.close}
24
+ end
25
+
26
+ def synchronize(&block)
27
+ @socket_mu.synchronize(&block)
26
28
  end
27
29
 
28
30
  def connect
29
31
  @socket_mu.lock
30
- unless @socket.nil? || @socket.closed?
32
+ begin
33
+ return unless @socket.nil? || @socket.closed?
34
+
35
+ if %r{^/} === @config.hostname
36
+ connect_unix_socket
37
+ else
38
+ connect_inet_socket
39
+ end
40
+
41
+ read_response # protocol version, ignore for now
42
+ if @config.password
43
+ send_command("password", @config.password)
44
+ Response.factory("password").parse(read_response)
45
+ end
46
+ ensure
31
47
  @socket_mu.unlock
32
- return
33
48
  end
34
- @socket_mu.unlock
49
+ end
35
50
 
36
- if %r{^/} === @config.hostname
37
- connect_unix_socket
38
- else
39
- connect_inet_socket
51
+ def read_response
52
+ response = []
53
+
54
+ while (line = @socket.readline.force_encoding("UTF-8"))
55
+ response << line.strip
56
+ break if END_RE === line
40
57
  end
41
58
 
42
- read_response # protocol version, ignore for now
43
- password(@config.password) if @config.password
59
+ response
44
60
  end
45
61
 
62
+ def send_command(command, *args)
63
+ @socket.puts("#{command} #{quote(args).join(" ")}".strip)
64
+ rescue Errno::EPIPE, EOFError => e
65
+ @socket.close
66
+ raise MpdDisconnectedError.new(e)
67
+ end
68
+
69
+
70
+ protected
71
+
72
+ def mpd
73
+ self
74
+ end
75
+
76
+
77
+ private
78
+
46
79
  def connect_unix_socket
47
- @socket_mu.lock
48
- begin
49
- @socket = UNIXSocket.new(@config.hostname)
50
- rescue StandardError => error
51
- @socket = nil
52
- raise MpdConnRefusedError.new(error)
53
- ensure
54
- @socket_mu.unlock
55
- end
80
+ @socket = UNIXSocket.new(@config.hostname)
81
+ rescue StandardError => error
82
+ @socket = nil
83
+ raise MpdConnRefusedError.new(error)
56
84
  end
57
85
 
58
86
  def connect_inet_socket
59
87
  Socket::getaddrinfo(@config.hostname, @config.port, nil, SOCK_STREAM).each do |info|
60
- @socket_mu.lock
61
88
  begin
62
89
  sockaddr = Socket.pack_sockaddr_in(info[1], info[3])
63
90
  @socket = Socket.new(info[4], info[5], 0)
@@ -67,52 +94,8 @@ module Rmpd
67
94
  raise MpdConnRefusedError.new(error)
68
95
  else
69
96
  break
70
- ensure
71
- @socket_mu.unlock
72
- end
73
- end
74
- end
75
-
76
- def send_command(command, *args)
77
- tries = 0
78
-
79
- begin
80
- connect
81
- send_command_without_reconnect(command, *args)
82
- rescue Errno::EPIPE, EOFError
83
- if (tries += 1) < MAX_RETRIES
84
- retry
85
- else
86
- raise MpdError.new("Retry count exceeded")
87
- end
88
- end
89
- end
90
-
91
- def send_command_without_reconnect(command, *args)
92
- @socket_mu.lock
93
- @socket.puts("#{command} #{quote(args).join(" ")}".strip)
94
- rescue => e
95
- @socket.close
96
- raise e
97
- ensure
98
- @socket_mu.unlock
99
- end
100
-
101
- def read_response
102
- response = []
103
-
104
- @socket_mu.synchronize do
105
- while (line = @socket.readline.force_encoding("UTF-8"))
106
- response << line.strip
107
- break if END_RE === line
108
97
  end
109
98
  end
110
-
111
- response
112
- end
113
-
114
- def mpd
115
- self
116
99
  end
117
100
 
118
101
  def quote(args)
@@ -1,3 +1,3 @@
1
1
  module Rmpd
2
- VERSION = "1.1.15"
2
+ VERSION = "1.1.16"
3
3
  end
@@ -30,23 +30,28 @@ describe Rmpd::Commands do
30
30
  @socket.stub!(:readline).and_return(*(connect_response + ok))
31
31
  @socket.should_receive(:close).exactly(5).times
32
32
  lambda do
33
+ @conn.connect
33
34
  @conn.ping
34
- end.should raise_error(Rmpd::MpdError, "Retry count exceeded")
35
+ end.should raise_error(Rmpd::MpdDisconnectedError)
35
36
  end
36
37
 
37
38
  it "should abort after a limited number of tries against a closed connection" do
38
- @socket.stub!(:puts).and_raise(EOFError)
39
- @socket.stub!(:readline).and_return(*(connect_response + ok))
40
- @socket.should_receive(:close).exactly(5).times
41
- lambda do
42
- @conn.ping
43
- end.should raise_error(MpdError, "Retry count exceeded")
39
+ pending do
40
+ @socket.stub!(:puts).and_raise(EOFError)
41
+ @socket.stub!(:readline).and_return(*(connect_response + ok))
42
+ @socket.should_receive(:close).exactly(5).times
43
+ lambda do
44
+ @conn.connect
45
+ @conn.ping
46
+ end.should raise_error(MpdError, "Retry count exceeded")
47
+ end
44
48
  end
45
49
 
46
50
  describe "close" do
47
51
  it "should close the socket" do
48
52
  @socket.stub!(:readline).and_return(*connect_response)
49
53
  @socket.should_receive(:close).once
54
+ @conn.connect
50
55
  @conn.ping
51
56
  @conn.close
52
57
  end
@@ -57,6 +62,7 @@ describe Rmpd::Commands do
57
62
  set_password
58
63
  @socket.stub!(:readline).and_return(*connect_and_auth_responses)
59
64
  $stderr.should_receive(:puts).with(/deprecated/i)
65
+ @conn.connect
60
66
  @conn.volume(0)
61
67
  end
62
68
  end
@@ -78,7 +84,7 @@ describe Rmpd::Commands do
78
84
  @song_id = 1
79
85
  @cmd = "playlistinfo \"#{@song_id}\""
80
86
  @responses = connect_and_auth_responses + ["file: blah\n", "boobies: yay!\n"] + ok
81
- @command = Proc.new {@conn.playlistinfo(@song_id)}
87
+ @command = Proc.new {@conn.connect; @conn.playlistinfo(@song_id)}
82
88
  end
83
89
 
84
90
  it_should_behave_like "a command with a song pos"
@@ -90,7 +96,7 @@ describe Rmpd::Commands do
90
96
  @song_id = 12
91
97
  @cmd = "play \"#{@song_id}\""
92
98
  @responses = connect_and_auth_responses + ok
93
- @command = Proc.new {@conn.play(@song_id)}
99
+ @command = Proc.new {@conn.connect; @conn.play(@song_id)}
94
100
  end
95
101
 
96
102
  it_should_behave_like "a command with a song pos"
@@ -102,7 +108,7 @@ describe Rmpd::Commands do
102
108
  @song_id = 23
103
109
  @cmd = "delete \"#{@song_id}\""
104
110
  @responses = connect_and_auth_responses + ok
105
- @command = Proc.new {@conn.delete(@song_id)}
111
+ @command = Proc.new {@conn.connect; @conn.delete(@song_id)}
106
112
  end
107
113
 
108
114
  it_should_behave_like "a command with a song pos"
@@ -115,6 +121,7 @@ describe Rmpd::Commands do
115
121
  @socket.stub!(:puts).and_return(@socket.puts)
116
122
  @socket.stub!(:eof?).and_return(false)
117
123
 
124
+ @conn.connect
118
125
  @conn.command_list do |c|
119
126
  c.status
120
127
  c.stats
@@ -127,6 +134,7 @@ describe Rmpd::Commands do
127
134
  @socket.stub!(:puts).and_return(@socket.puts)
128
135
  @socket.stub!(:eof?).and_return(false)
129
136
 
137
+ @conn.connect
130
138
  @conn.command_list do |c|
131
139
  c.addid("foo")
132
140
  end
@@ -139,6 +147,7 @@ describe Rmpd::Commands do
139
147
  @responses = connect_response
140
148
  @socket.stub!(:readline).and_return(*@responses)
141
149
 
150
+ @conn.connect
142
151
  @conn.noidle.should be_nil
143
152
  end
144
153
 
@@ -146,6 +155,7 @@ describe Rmpd::Commands do
146
155
  @responses = connect_response + status_response + ok
147
156
  @socket.stub!(:readline).and_return(*@responses)
148
157
 
158
+ @conn.connect
149
159
  response = @conn.status
150
160
 
151
161
  response.should have(2).items, response.pretty_inspect
@@ -161,6 +171,7 @@ describe Rmpd::Commands do
161
171
  @socket.stub!(:puts).and_return(@socket.puts)
162
172
  @socket.stub!(:eof?).and_return(false)
163
173
 
174
+ @conn.connect
164
175
  results = @conn.command_list_ok do |c|
165
176
  c.list("album")
166
177
  c.list("artist")
@@ -18,6 +18,7 @@ describe Connection do
18
18
  it "should connect successfully" do
19
19
  responses = connect_response + ok
20
20
  @socket.should_receive(:readline).and_return(*responses)
21
+ @conn.connect
21
22
  @conn.ping
22
23
  end
23
24
 
@@ -25,6 +26,7 @@ describe Connection do
25
26
  responses = connect_and_auth_responses + ok
26
27
  set_password
27
28
  @socket.should_receive(:readline).and_return(*responses)
29
+ @conn.connect
28
30
  @conn.ping
29
31
  end
30
32
 
@@ -40,6 +42,7 @@ describe Connection do
40
42
  it "should handle connection failures gracefully" do
41
43
  @socket.stub!(:connect).and_raise(Errno::ECONNREFUSED.new("test"))
42
44
  lambda do
45
+ @conn.connect
43
46
  @conn.ping
44
47
  end.should raise_error(Rmpd::MpdError)
45
48
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmpd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.15
4
+ version: 1.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Wollesen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-04 00:00:00.000000000 Z
11
+ date: 2016-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec