ruby-mpd-client 0.2.0 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5d038318cf899183f6ed52cc1f3c13294b87d899
4
- data.tar.gz: 1c19d632d7c424d08ba14a5df9be67ca64217213
2
+ SHA256:
3
+ metadata.gz: 8ca78849c735d15541f0f0e04e83ac1af66d71c3c3202739a0718f7cfc7860e4
4
+ data.tar.gz: db532da5093220f87880cd0d47137866b089be98ba8d03a7aa89334869b6da9d
5
5
  SHA512:
6
- metadata.gz: 8ebe86c126933033f19be9e25b1c1e1a7e1c2b76856f1e65b60e16e0b685781d6c9f554688e3799a34221072b10b88495a3be94eb296d51f14d97b1092ba2e6b
7
- data.tar.gz: 93ae6e1f0904011acf8976c26bfc8616d64d7a3336bb382fd076b6e80747e464fbadab11af69a608a0822f84108ca0ba6922645298aacdf51890d820ddd5e95d
6
+ metadata.gz: 0d23063c2519c020bcf16009a1f6f1874b2d4f53ad41879fc023b5b460e9a531f13a5a665574399cef5836bd9fadbfd4213d2a64f8cef966fa2b8c2dd79194e4
7
+ data.tar.gz: 0423b775979eb61f9eff55fcfd05d29e6375a17df5e1caf2bb6b9828d7b2d3c32e84e10c792ade9ab004f0462a91292d225e0851f9164a417c6f55c1b698504d
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ script: rake spec
5
+ deploy:
6
+ provider: rubygems
7
+ api_key:
8
+ secure: CCtmgUnWoiG4tKRalp9kfEcaeDUfipES0mcWPV4K0D/K651nxZ0kHe+VV+3rpvV1KDs4i5W+TosVvpH5lDL7+oALLFTsYgo3iam+kzMLfoskkZUuizUDxYjXrWI0T+SM0gL3Ax1J9oJ0cd7j1sUGi5TZ/IHXrKknm1yqFIx83mgKCFxYKJUAwQuwpo924ukqyQ0IsJtYX7AJ31hQwFBZSscJbriaxsz3dN+ptmvYVt9/+oIowHrvZCFnlgejel/eZ9iKCMR8buxx1RF3Q3y7LZkpMb20UBfjMwUkz/XBXGFCFVUaCLEcdFnAuoRePJ8a+q3Qkd0wZp+5g2offguVycTWsPTGgSjSAXcPUK0fOnE6bsBZ9XnkAiwkPtxO3MeG7iBcGBX2XY/Tzl+8EW2FgGeIICBh5sg+UqmrGAuqzmtgrJJwOaBeyLEbAKemAdPRfN7M0Hq1DgbOHchttmiCAY1Ja/RBiYwbEkZsPn9VI2tH3CUvdqc0B4jPV05OKU1sv06hHKJTWoCjsmvd52Tr0Kbr5ofBvLMj+uHnyCx78SwfReVCPEb2PzK5GUBG6+Ufu8UOTFdlS8gDmSO09R/qd/kSILvxCLntNVQAn/aUlnZ0aBJURxhoTQkKRSBGcGrOUXhMKnj3jnwZw1othJ5xxiSXy6fM/8JrsxyPH7TalT8=
9
+ on:
10
+ branch: master
data/README.md CHANGED
@@ -18,13 +18,21 @@ It does not do much
18
18
  ```ruby
19
19
  require 'ruby-mpd-client'
20
20
 
21
- mpd = MPD::Client.new(host: 'localhost')
22
- mpd.volume(50)
23
- mpd.random(true)
24
- mpd.next
25
- # and so on
21
+ MPD::Commands::SetVolume.new(host: 'localhost') # :host can be ommited
22
+ .execute(75)
23
+ MPD::Commands::Next.new.execute
24
+
25
+ #
26
+ # to use one connection
27
+ #
28
+ conn = MPD::Connection.new(host: 'localhost', port: 6600)
29
+ conn.connect
30
+ MPD::Commands::Next.new(connection: conn).execute
31
+ MPD::Commands::Pause.new(connection: conn).execute
26
32
  ```
27
33
 
34
+ For available commands see [lib/mpd/commands](lib/mpd/commands).
35
+
28
36
  ## Contributing
29
37
 
30
38
  Bug reports and pull requests are welcome on GitHub at https://github.com/Nondv/ruby-mpd-client.
@@ -0,0 +1,61 @@
1
+ Dir[File.join(__dir__, 'commands', '*.rb')].each { |f| require f }
2
+
3
+ module MPD
4
+ #
5
+ # Contains classes representing MPD commands
6
+ #
7
+ module Commands
8
+ #
9
+ # To decrease code amount
10
+ #
11
+ def self.define_trivial_command(class_name, command)
12
+ klass = Class.new(::MPD::Commands::Abstract) do
13
+ define_method :execute do
14
+ super(command)
15
+ end
16
+ end
17
+
18
+ const_set(class_name, klass)
19
+ end
20
+
21
+ #
22
+ # To define commands like 'save "whatever this is"'
23
+ #
24
+ def self.define_text_argument_command(class_name, command)
25
+ klass = Class.new(::MPD::Commands::Abstract) do
26
+ define_method :execute do |arg|
27
+ super("#{command} \"#{arg}\"")
28
+ end
29
+ end
30
+
31
+ const_set(class_name, klass)
32
+ end
33
+
34
+ #
35
+ # To define commands like "random <1/0>"
36
+ #
37
+ def self.define_option_command(class_name, command)
38
+ klass = Class.new(::MPD::Commands::Abstract) do
39
+ define_method :execute do |state|
40
+ super(command + state ? ' 1' : ' 0')
41
+ end
42
+ end
43
+
44
+ const_set(class_name, klass)
45
+ end
46
+
47
+ define_trivial_command(:Pause, 'pause 1')
48
+ define_trivial_command(:Stop, 'stop')
49
+ define_trivial_command(:Previous, 'previous')
50
+ define_trivial_command(:Next, 'next')
51
+ define_trivial_command(:CurrentPlaylistClear, 'clear')
52
+
53
+ define_text_argument_command :PlaylistDelete, :rm
54
+ define_text_argument_command :PlaylistSave, :save
55
+ define_text_argument_command :PlaylistLoad, :load
56
+
57
+ %w[Consume Crossfade Random Repeat Single].each do |class_name|
58
+ define_option_command(class_name, class_name.downcase)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ require 'mpd/connection'
2
+ require 'mpd/server_response'
3
+ require 'mpd/playlist'
4
+
5
+ module MPD
6
+ module Commands
7
+ #
8
+ # Base class for MPD commands.
9
+ #
10
+ class Abstract
11
+ attr_reader :connection
12
+
13
+ #
14
+ # You can provide you own connection. It should have same
15
+ #
16
+ def initialize(connection: nil, host: 'localhost', port: 6600)
17
+ @connection = connection || Connection.new(host: host, port: port).tap(&:connect).tap(&:gets)
18
+ end
19
+
20
+ #
21
+ # This method should be overriden.
22
+ # Example:
23
+ #
24
+ # def execute
25
+ # super('ping')
26
+ # end
27
+ #
28
+ def execute(command)
29
+ exec_command(command)
30
+ end
31
+
32
+ private
33
+
34
+ def exec_command(command)
35
+ connection.puts(command)
36
+ response = ServerResponse.from_connection(connection)
37
+ raise(MpdError, response.status) if response.error?
38
+ response
39
+ end
40
+
41
+ def exec_command_list(commands)
42
+ connection.puts('command_list_begin')
43
+ commands.each { |c| connection.puts(c) }
44
+ connection.puts('command_list_end')
45
+
46
+ response = ServerResponse.from_connection(connection)
47
+ raise(MpdError, response.status) if response.error?
48
+ response
49
+ end
50
+
51
+ def resolve_range(arg)
52
+ if arg.is_a?(Range)
53
+ last = arg.exclude_end? ? arg.end : arg.end + 1
54
+ "#{arg.begin}:#{last}"
55
+ else
56
+ arg
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,17 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Uses "listall" command to get
7
+ # all files (directories are filtered out) from db.
8
+ #
9
+ class AllFiles < Abstract
10
+ def execute
11
+ super('listall').key_value_pairs
12
+ .select { |e| e[0] == 'file' }
13
+ .map(&:last)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Increases/decreases volume by some number
7
+ #
8
+ class ChangeVolume < Abstract
9
+ def execute(n)
10
+ super("volume #{n}")
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Adds song(s) to current playlist
7
+ # `songs` is an array of URIs.
8
+ #
9
+ class CurrentPlaylistAdd < Abstract
10
+ #
11
+ # `songs` is position (as int) or range
12
+ #
13
+ def execute(songs)
14
+ return exec_command("add \"#{songs}\"") unless songs.is_a?(Array)
15
+ exec_command_list(songs.map { |s| "add \"#{s}\"" })
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Info about songs in current playlist
7
+ #
8
+ class CurrentPlaylistInfo < Abstract
9
+ # `songs` can be range
10
+ # or integer (to show info about one song)
11
+ # or completely ommited (to show info about all songs)
12
+ def execute(songs = nil)
13
+ response = super("playlistinfo #{resolve_range(songs)}")
14
+ Playlist.from_response(response)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Removes songs from current playlist
7
+ # by id or position/range
8
+ #
9
+ class CurrentPlaylistRemove < Abstract
10
+ #
11
+ # `position` is int or range
12
+ # `id` is int song id
13
+ #
14
+ def execute(position: nil, id: nil)
15
+ raise(ArgumentError) if position && id || !position && !id
16
+ exec_command(id ? "deleteid #{id}" : "delete #{resolve_range(position)}")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Current song info as hash
7
+ #
8
+ class CurrentSong < Abstract
9
+ def execute
10
+ super('currentsong').to_h
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Tries to execute "ping" command.
7
+ # Returns `true` if succedeed,
8
+ # raises error if `MpdError` occurred,
9
+ # `false` otherwise
10
+ #
11
+ class Ping < Abstract
12
+ # rubocop:disable Lint/RescueWithoutErrorClass
13
+ def execute
14
+ super('ping')
15
+ true
16
+ rescue => e
17
+ raise e if e.is_a?(MpdError)
18
+ false
19
+ end
20
+ # rubocop:enable Lint/RescueWithoutErrorClass
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Play specific song (by id or cur. playlist position).
7
+ #
8
+ #
9
+ class Play < Abstract
10
+ def execute(position: nil, id: nil)
11
+ raise(ArgumentError, 'too many arguments') if position && id
12
+
13
+ if position
14
+ super("play #{position}")
15
+ elsif id
16
+ super("playid #{id}")
17
+ else
18
+ super('play')
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Set specific volume to specific value
7
+ #
8
+ class SetVolume < Abstract
9
+ def execute(n)
10
+ super("setvol #{n}")
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'mpd/commands/abstract'
2
+
3
+ module MPD
4
+ module Commands
5
+ #
6
+ # Player status
7
+ #
8
+ class Status < Abstract
9
+ def execute
10
+ super('status').to_h
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,41 @@
1
+ require 'socket'
2
+
3
+ module MPD
4
+ #
5
+ # Simple wrapper over Socket
6
+ #
7
+ class Connection
8
+ def initialize(host:, port:)
9
+ @host = host
10
+ @port = port
11
+ end
12
+
13
+ def connect
14
+ disconnect if socket
15
+ @socket = TCPSocket.open(host, port)
16
+ end
17
+
18
+ def disconnect
19
+ socket && socket.close
20
+ @socket = nil
21
+ end
22
+
23
+ def puts(text)
24
+ raise ConnectionError unless socket
25
+ socket.puts(text)
26
+ rescue Errno::ECONNRESET
27
+ raise ConnectionError
28
+ end
29
+
30
+ def gets
31
+ raise ConnectionError unless socket
32
+ socket.gets || raise(ConnectionError)
33
+ rescue Errno::ECONNRESET
34
+ raise ConnectionError
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :socket, :host, :port
40
+ end
41
+ end
@@ -0,0 +1,50 @@
1
+ module MPD
2
+ #
3
+ # Just a frozen string with some useful methods
4
+ #
5
+ class ServerResponse < String
6
+ def self.from_connection(conn)
7
+ line = ''
8
+ buffer = ''
9
+ while line != "OK\n" && !line.start_with?('ACK')
10
+ line = conn.gets
11
+ raise(ConnectionError) if line.nil?
12
+ buffer << line
13
+ end
14
+
15
+ new(buffer.force_encoding('UTF-8'))
16
+ end
17
+
18
+ def initialize(response_text)
19
+ super
20
+ freeze
21
+ end
22
+
23
+ def to_h
24
+ key_value_pairs.to_h
25
+ end
26
+
27
+ def key_value_pairs
28
+ content.split("\n").map do |line|
29
+ index = line.index(':')
30
+ raise "can't create key-value pair" unless index
31
+ key = line[0...index]
32
+ value = line[(index + 1)..-1].strip
33
+ [key, value]
34
+ end
35
+ end
36
+
37
+ # text without status
38
+ def content
39
+ lines[0..-2].join
40
+ end
41
+
42
+ def status
43
+ lines.last.chomp
44
+ end
45
+
46
+ def error?
47
+ status.start_with?('ACK')
48
+ end
49
+ end
50
+ end
data/lib/mpd/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module MPD
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -1,3 +1,3 @@
1
1
  require 'mpd/version'
2
2
  require 'mpd/errors'
3
- require 'mpd/client'
3
+ require 'mpd/commands'
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.13"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency 'rspec-its'
26
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-mpd-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitriy Non
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-02 00:00:00.000000000 Z
11
+ date: 2017-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-its
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description:
42
56
  email:
43
57
  - non.dmitriy@gmail.com
@@ -46,21 +60,29 @@ extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
62
  - ".gitignore"
63
+ - ".travis.yml"
49
64
  - Gemfile
50
65
  - LICENSE.txt
51
66
  - README.md
52
67
  - Rakefile
53
68
  - bin/console
54
69
  - bin/setup
55
- - lib/mpd/client.rb
56
- - lib/mpd/client/commands.rb
57
- - lib/mpd/client/commands/current_playlist.rb
58
- - lib/mpd/client/commands/playback_control.rb
59
- - lib/mpd/client/commands/playback_options.rb
60
- - lib/mpd/client/connection.rb
61
- - lib/mpd/client/server_response.rb
70
+ - lib/mpd/commands.rb
71
+ - lib/mpd/commands/abstract.rb
72
+ - lib/mpd/commands/all_files.rb
73
+ - lib/mpd/commands/change_volume.rb
74
+ - lib/mpd/commands/current_playlist_add.rb
75
+ - lib/mpd/commands/current_playlist_info.rb
76
+ - lib/mpd/commands/current_playlist_remove.rb
77
+ - lib/mpd/commands/current_song.rb
78
+ - lib/mpd/commands/ping.rb
79
+ - lib/mpd/commands/play.rb
80
+ - lib/mpd/commands/set_volume.rb
81
+ - lib/mpd/commands/status.rb
82
+ - lib/mpd/connection.rb
62
83
  - lib/mpd/errors.rb
63
84
  - lib/mpd/playlist.rb
85
+ - lib/mpd/server_response.rb
64
86
  - lib/mpd/song.rb
65
87
  - lib/mpd/version.rb
66
88
  - lib/ruby-mpd-client.rb
@@ -85,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
107
  version: '0'
86
108
  requirements: []
87
109
  rubyforge_project:
88
- rubygems_version: 2.6.12
110
+ rubygems_version: 2.7.3
89
111
  signing_key:
90
112
  specification_version: 4
91
113
  summary: yet another MPD client on Ruby
data/lib/mpd/client.rb DELETED
@@ -1,51 +0,0 @@
1
- require 'mpd/client/connection'
2
- require 'mpd/client/server_response'
3
- require 'mpd/client/commands'
4
-
5
- module MPD
6
- class Client
7
- def self.connect(host: 'localhost', port: 6600)
8
- new(host: host, port: port).tap(&:connect)
9
- end
10
-
11
- def initialize(host: 'localhost', port: 6600)
12
- @connection = Connection.new(host: host, port: port)
13
- end
14
-
15
- def current_song
16
- execute('currentsong').to_h
17
- end
18
-
19
- def status
20
- response = execute('status')
21
- response.to_h
22
- end
23
-
24
- def execute(command)
25
- connection.puts(command)
26
- response = ServerResponse.from_connection(connection)
27
- raise(MpdError, response.status) if response.error?
28
- response
29
- end
30
-
31
- def connected?
32
- execute('ping')
33
- rescue => e
34
- raise e if e.is_a?(MpdError)
35
- false
36
- end
37
-
38
- def connect
39
- connection.connect
40
- raise(ConnectionError) unless connection.gets =~ /^OK/
41
- end
42
-
43
- def disconnect
44
- connection.disconnect
45
- end
46
-
47
- private
48
-
49
- attr_reader :connection
50
- end
51
- end
@@ -1,10 +0,0 @@
1
- Dir[File.join(__dir__, 'commands', '*.rb')].each { |f| require f }
2
-
3
- module MPD
4
- class Client
5
- # Module of modules that implement some MPD commands
6
- module Commands
7
- constants.each { |mod| Client.include(const_get(mod)) }
8
- end
9
- end
10
- end
@@ -1,17 +0,0 @@
1
- require 'mpd/playlist'
2
-
3
- module MPD
4
- class Client
5
- module Commands
6
- # https://www.musicpd.org/doc/protocol/queue.html
7
- module CurrentPlaylist
8
- # songs - integer or range
9
- def playlist_info(songs = nil)
10
- argument = songs.is_a?(Range) ? "#{songs.begin}:#{songs.end}" : songs
11
- response = execute "playlistinfo #{argument}"
12
- Playlist.from_response(response)
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,36 +0,0 @@
1
- module MPD
2
- class Client
3
- module Commands
4
- # https://www.musicpd.org/doc/protocol/playback_commands.html
5
- module PlaybackControl
6
- def play(position: nil, id: nil)
7
- raise(ArgumentError, 'too many arguments') if position && id
8
-
9
- if position
10
- execute "play #{position}"
11
- elsif id
12
- execute "playid #{id}"
13
- else
14
- execute 'pause 0'
15
- end
16
- end
17
-
18
- def pause
19
- execute 'pause 1'
20
- end
21
-
22
- def stop
23
- execute 'stop'
24
- end
25
-
26
- def previous
27
- execute 'previous'
28
- end
29
-
30
- def next
31
- execute 'next'
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,36 +0,0 @@
1
- module MPD
2
- class Client
3
- module Commands
4
- # https://www.musicpd.org/doc/protocol/playback_option_commands.html
5
- module PlaybackOptions
6
- def consume(state)
7
- execute "consume #{state ? 1 : 0}"
8
- end
9
-
10
- def crossfade(state)
11
- execute "crossfade #{state ? 1 : 0}"
12
- end
13
-
14
- def random(state)
15
- execute "random #{state ? 1 : 0}"
16
- end
17
-
18
- def repeat(state)
19
- execute "repeat #{state ? 1 : 0}"
20
- end
21
-
22
- def single(state)
23
- execute "single #{state ? 1 : 0}"
24
- end
25
-
26
- def volume(val)
27
- execute "setvol #{val}"
28
- end
29
-
30
- def change_volume_by(val)
31
- execute("volume #{val}")
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,39 +0,0 @@
1
- require 'socket'
2
-
3
- module MPD
4
- class Client
5
- #
6
- # It's `Client`'s internal class. Don't use it outside `Client`
7
- #
8
- class Connection
9
- def initialize(host:, port:)
10
- @host = host
11
- @port = port
12
- end
13
-
14
- def connect
15
- disconnect if socket
16
- @socket = TCPSocket.open(host, port)
17
- end
18
-
19
- def disconnect
20
- socket && socket.close
21
- @socket = nil
22
- end
23
-
24
- def puts(text)
25
- raise ConnectionError unless socket
26
- socket.puts(text)
27
- end
28
-
29
- def gets
30
- raise ConnectionError unless socket
31
- socket.gets
32
- end
33
-
34
- private
35
-
36
- attr_reader :socket, :host, :port
37
- end
38
- end
39
- end
@@ -1,52 +0,0 @@
1
- module MPD
2
- class Client
3
- #
4
- # Just a frozen string with some useful methods
5
- #
6
- class ServerResponse < String
7
- def self.from_connection(conn)
8
- line = ''
9
- buffer = ''
10
- while line != "OK\n" && !line.start_with?('ACK')
11
- line = conn.gets
12
- raise(ConnectionError) if line.nil?
13
- buffer << line
14
- end
15
-
16
- new(buffer.force_encoding('UTF-8'))
17
- end
18
-
19
- def initialize(response_text)
20
- super
21
- freeze
22
- end
23
-
24
- def to_h
25
- key_value_pairs.to_h
26
- end
27
-
28
- def key_value_pairs
29
- content.split("\n").map do |line|
30
- index = line.index(':')
31
- raise "can't create key-value pair" unless index
32
- key = line[0...index]
33
- value = line[(index + 1)..-1].strip
34
- [key, value]
35
- end
36
- end
37
-
38
- # text without status
39
- def content
40
- lines[0..-2].join
41
- end
42
-
43
- def status
44
- lines.last.chomp
45
- end
46
-
47
- def error?
48
- status.start_with?('ACK')
49
- end
50
- end
51
- end
52
- end