fetch binary
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
diff --git a/lib/mpd_client.rb b/lib/mpd_client.rb
index 82b9655..6a41dd7 100644
--- a/lib/mpd_client.rb
+++ b/lib/mpd_client.rb
@@ -1,13 +1,14 @@
# frozen_string_literal: true
require 'socket'
+require 'stringio'
require 'mpd_client/version'
module MPD
HELLO_PREFIX = 'OK MPD '
ERROR_PREFIX = 'ACK '
- SUCCESS = 'OK'
- NEXT = 'list_OK'
+ SUCCESS = "OK\n"
+ NEXT = "list_OK\n"
# MPD changelog: http://git.musicpd.org/cgit/master/mpd.git/plain/NEWS
# http://www.musicpd.org/doc/protocol/command_reference.html
@@ -241,6 +242,10 @@ module MPD
# Sets the +logger+ used by this instance of MPD::Client
attr_writer :log
+ def albumart(uri)
+ fetch_binary(StringIO.new, 0, 'albumart', uri)
+ end
+
private
def ensure_connected
@@ -286,10 +291,10 @@ module MPD
end
def read_line
- line = @socket.gets.force_encoding('utf-8')
+ line = @socket.gets
+
raise 'Connection lost while reading line' unless line.end_with?("\n")
- line.chomp!
if line.start_with?(ERROR_PREFIX)
error = line[/#{ERROR_PREFIX}(.*)/, 1].strip
raise error
@@ -309,10 +314,7 @@ module MPD
line = read_line
return if line.nil?
- pair = line.split(separator, 2)
- raise "Could now parse pair: '#{line}'" if pair.size < 2
-
- pair # Array
+ line.split(separator, 2)
end
def read_pairs(separator = ': ')
@@ -343,6 +345,8 @@ module MPD
seen = nil
read_pairs.each do |key, value|
+ value = value.chomp.force_encoding('utf-8')
+
if key != seen
raise "Expected key '#{seen}', got '#{key}'" unless seen.nil?
@@ -358,14 +362,18 @@ module MPD
def fetch_objects(delimeters = [])
result = []
obj = {}
+
read_pairs.each do |key, value|
key = key.downcase
+ value = value.chomp.force_encoding('utf-8')
+
if delimeters.include?(key)
result << obj unless obj.empty?
obj = {}
elsif obj.include?(key)
obj[key] << value
end
+
obj[key] = value
end
@@ -380,6 +388,41 @@ module MPD
objs ? objs[0] : {}
end
+ def fetch_binary(io = StringIO.new, offset = 0, *args)
+ data = {}
+
+ @mutex.synchronize do
+ write_command(*args, offset)
+
+ binary = false
+
+ read_pairs.each do |item|
+ if binary
+ io << item.join(': ')
+ next
+ end
+
+ key = item[0]
+ value = item[1].chomp
+
+ binary = (key == 'binary')
+
+ data[key] = value
+ end
+ end
+
+ size = data['size'].to_i
+ binary = data['binary'].to_i
+
+ next_offset = offset + binary
+
+ return [data, io] if next_offset >= size
+
+ io.seek(-1, IO::SEEK_CUR)
+
+ fetch_binary(io, next_offset, *args)
+ end
+
def fetch_changes
fetch_objects(['cpos'])
end
@@ -419,6 +462,7 @@ module MPD
def fetch_playlist
result = []
read_pairs(':').each do |_key, value|
+ value = value.chomp.force_encoding('utf-8')
result << value
end