mpd 0.17.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.
- data/README.md +3 -0
- data/bin/mpc.rb +8 -0
- data/lib/mpd.rb +12 -0
- data/lib/mpd/controller.rb +206 -0
- data/lib/mpd/controller/audio.rb +78 -0
- data/lib/mpd/controller/channels.rb +117 -0
- data/lib/mpd/controller/commands.rb +57 -0
- data/lib/mpd/controller/config.rb +35 -0
- data/lib/mpd/controller/current_playlist.rb +110 -0
- data/lib/mpd/controller/database.rb +235 -0
- data/lib/mpd/controller/decoders.rb +54 -0
- data/lib/mpd/controller/do.rb +42 -0
- data/lib/mpd/controller/player.rb +109 -0
- data/lib/mpd/controller/playlists.rb +113 -0
- data/lib/mpd/controller/stats.rb +31 -0
- data/lib/mpd/controller/status.rb +69 -0
- data/lib/mpd/controller/stickers.rb +87 -0
- data/lib/mpd/controller/supported_protocols.rb +36 -0
- data/lib/mpd/controller/supported_tags.rb +36 -0
- data/lib/mpd/controller/toggle.rb +72 -0
- data/lib/mpd/protocol.rb +15 -0
- data/lib/mpd/protocol/command.rb +50 -0
- data/lib/mpd/protocol/command_list.rb +48 -0
- data/lib/mpd/protocol/response.rb +181 -0
- data/lib/mpd/version.rb +15 -0
- data/mpd.gemspec +16 -0
- metadata +71 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
module MPD; class Controller
|
12
|
+
|
13
|
+
class Player
|
14
|
+
attr_reader :controller
|
15
|
+
|
16
|
+
def initialize (controller)
|
17
|
+
@controller = controller
|
18
|
+
end
|
19
|
+
|
20
|
+
def play (what = {})
|
21
|
+
if what[:position]
|
22
|
+
controller.do_and_raise_if_needed :play, what[:position]
|
23
|
+
elsif what[:id]
|
24
|
+
controller.do_and_raise_if_needed :playid, what[:id]
|
25
|
+
else
|
26
|
+
controller.do_and_raise_if_needed :play, what.to_sym
|
27
|
+
end
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def pause
|
33
|
+
controller.do_and_raise_if_needed :pause, true
|
34
|
+
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def unpause
|
39
|
+
controller.do_and_raise_if_needed :pause, false
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def stop
|
45
|
+
controller.do_and_raise_if_needed :stop
|
46
|
+
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def next
|
51
|
+
controller.do_and_raise_if_needed :next
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def prev
|
57
|
+
controller.do_and_raise_if_needed :previous
|
58
|
+
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
def volume (volume)
|
63
|
+
controller.do_and_raise_if_needed :setvol, volume
|
64
|
+
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def crossfade (seconds)
|
69
|
+
controller.do_and_raise_if_needed :crossfade, seconds
|
70
|
+
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
def mixer (options)
|
75
|
+
if options[:decibels]
|
76
|
+
controller.do_and_raise_if_needed :mixrampdb, options[:decibels]
|
77
|
+
end
|
78
|
+
|
79
|
+
if options[:delay]
|
80
|
+
controller.do_and_raise_if_needed :mixrampdelay, options[:delay]
|
81
|
+
end
|
82
|
+
|
83
|
+
self
|
84
|
+
end
|
85
|
+
|
86
|
+
def replay_gain (mode = nil)
|
87
|
+
if mode
|
88
|
+
controller.do_and_raise_if_needed :replay_gain_mode, mode
|
89
|
+
|
90
|
+
self
|
91
|
+
else
|
92
|
+
controller.do_and_raise_if_needed(:replay_gain_status).first.last
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def seek (second, optional = {})
|
97
|
+
if optional[:position]
|
98
|
+
controller.do_and_raise_if_needed :seek, optional[:position], second
|
99
|
+
elsif optional[:id]
|
100
|
+
controller.do_and_raise_if_needed :seekid, optional[:id], second
|
101
|
+
else
|
102
|
+
controller.do_and_raise_if_needed :seekcur, second
|
103
|
+
end
|
104
|
+
|
105
|
+
self
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end; end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
module MPD; class Controller
|
12
|
+
|
13
|
+
class Playlists
|
14
|
+
class Playlist
|
15
|
+
include Enumerable
|
16
|
+
|
17
|
+
attr_reader :playlists, :name, :last_modified
|
18
|
+
|
19
|
+
def initialize (playlists, name, last_modified = nil)
|
20
|
+
@playlists = playlists
|
21
|
+
@name = name
|
22
|
+
@last_modified = last_modified
|
23
|
+
end
|
24
|
+
|
25
|
+
def each
|
26
|
+
return to_enum unless block_given?
|
27
|
+
|
28
|
+
Database::Song.from_data(playlists.controller.do_and_raise_if_needed(:listplaylistinfo, name)).each {|song|
|
29
|
+
yield song
|
30
|
+
}
|
31
|
+
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def load (range = nil)
|
36
|
+
playlists.controller.do_and_raise_if_needed :load, name, *range
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def rename (new)
|
42
|
+
playlists.controller.do_and_raise_if_needed :rename, name, new
|
43
|
+
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete!
|
48
|
+
playlists.controller.do_and_raise_if_needed :rm, name
|
49
|
+
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def add (uri)
|
54
|
+
playlists.controller.do_and_raise_if_needed :playlistadd, name, uri
|
55
|
+
end
|
56
|
+
|
57
|
+
def move (from, to)
|
58
|
+
playlists.controller.do_and_raise_if_needed :playlistmove, name, from, to
|
59
|
+
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def clear
|
64
|
+
playlists.controller.do_and_raise_if_needed :playlistclear, name
|
65
|
+
|
66
|
+
self
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
include Enumerable
|
71
|
+
|
72
|
+
attr_reader :controller
|
73
|
+
|
74
|
+
def initialize (controller)
|
75
|
+
@controller = controller
|
76
|
+
end
|
77
|
+
|
78
|
+
def [] (name)
|
79
|
+
find { |p| p.name == name.to_s }
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete (name)
|
83
|
+
self[name].delete! rescue nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def each
|
87
|
+
return to_enum unless block_given?
|
88
|
+
|
89
|
+
name = nil
|
90
|
+
last_modified = nil
|
91
|
+
|
92
|
+
controller.do_and_raise_if_needed(:listplaylists).each {|key, value|
|
93
|
+
if key == :playlist
|
94
|
+
if last_modified
|
95
|
+
yield Playlist.new(self, name, last_modified)
|
96
|
+
end
|
97
|
+
|
98
|
+
name = value
|
99
|
+
last_modified = nil
|
100
|
+
elsif key == :"Last-Modified"
|
101
|
+
last_modified = value
|
102
|
+
end
|
103
|
+
}
|
104
|
+
|
105
|
+
if name
|
106
|
+
yield Playlist.new(self, name, last_modified)
|
107
|
+
end
|
108
|
+
|
109
|
+
self
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end; end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
module MPD; class Controller
|
12
|
+
|
13
|
+
class Stats
|
14
|
+
Database = Struct.new(:playtime, :update)
|
15
|
+
|
16
|
+
attr_reader :controller, :artists, :songs, :uptime, :playtime, :database
|
17
|
+
|
18
|
+
def initialize (controller)
|
19
|
+
@controller = controller
|
20
|
+
|
21
|
+
response = controller.do_and_raise_if_needed(:stats).to_hash
|
22
|
+
|
23
|
+
@artists = response[:artists]
|
24
|
+
@songs = response[:songs]
|
25
|
+
@uptime = response[:uptime]
|
26
|
+
@playtime = response[:playtime]
|
27
|
+
@database = Database.new(response[:db_playtime], response[:db_update])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end; end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
module MPD; class Controller
|
12
|
+
|
13
|
+
class Status
|
14
|
+
Mixer = Struct.new(:decibels, :delay)
|
15
|
+
Playlist = Struct.new(:version, :length, :current, :next)
|
16
|
+
Playlist::Song = Struct.new(:position, :id, :elapsed)
|
17
|
+
|
18
|
+
attr_reader :controller, :song, :mixer, :volume, :crossfade, :playlist, :bitrate, :error
|
19
|
+
|
20
|
+
def initialize (controller)
|
21
|
+
@controller = controller
|
22
|
+
|
23
|
+
@mixer = Mixer.new
|
24
|
+
@playlist = Playlist.new
|
25
|
+
|
26
|
+
controller.do_and_raise_if_needed(:status).each {|name, value|
|
27
|
+
case name
|
28
|
+
when :state then @status = value
|
29
|
+
when :repeat then @repeat = value
|
30
|
+
when :random then @random = value
|
31
|
+
when :single then @single = value
|
32
|
+
when :consume then @consume = value
|
33
|
+
when :volume then @volume = value
|
34
|
+
when :xfade then @crossfade = value
|
35
|
+
when :mixrampdb then @mixer.decibels = value
|
36
|
+
when :mixrampdelay then @mixer.delay = value
|
37
|
+
when :bitrate then @bitrate = value
|
38
|
+
when :error then @error = value
|
39
|
+
when :playlist then @playlist.version = value
|
40
|
+
when :playlistlength then @playlist.length = value
|
41
|
+
|
42
|
+
when :song then (@playlist.current ||= Playlist::Song.new).position = value
|
43
|
+
when :songid then (@playlist.current ||= Playlist::Song.new).id = value
|
44
|
+
when :time then (@playlist.current ||= Playlist::Song.new).elapsed = value
|
45
|
+
when :elapsed then (@playlist.current ||= Playlist::Song.new).elapsed = value
|
46
|
+
|
47
|
+
when :nextsong then (@playlist.next ||= Playlist::Song.new).position = value
|
48
|
+
when :nextsongid then (@playlist.next ||= Playlist::Song.new).id = value
|
49
|
+
end
|
50
|
+
}
|
51
|
+
|
52
|
+
@song = Database::Song.from_data(controller.do_and_raise_if_needed(:currentsong))
|
53
|
+
end
|
54
|
+
|
55
|
+
def repeat?; @repeat; end
|
56
|
+
def random?; @random; end
|
57
|
+
def single?; @single; end
|
58
|
+
def consume?; @consume; end
|
59
|
+
|
60
|
+
def == (other)
|
61
|
+
super || to_sym.downcase == other.to_sym.downcase
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_sym
|
65
|
+
@status
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end; end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
module MPD; class Controller
|
12
|
+
|
13
|
+
class Stickers
|
14
|
+
class Sticker
|
15
|
+
attr_reader :element, :name
|
16
|
+
|
17
|
+
def initialize (element, name)
|
18
|
+
@element = element
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
def value
|
23
|
+
response = @element.stickers.controller.do_and_raise_if_needed(:sticker, :get, element.type, element.uri, name)
|
24
|
+
name, value = response.first.last.split '=', 2
|
25
|
+
|
26
|
+
value
|
27
|
+
end
|
28
|
+
|
29
|
+
def value= (value)
|
30
|
+
@element.stickers.controller.do_and_raise_if_needed(:sticker, :set, element.type, element.uri, name, value)
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete!
|
34
|
+
@element.stickers.controller.do_and_raise_if_needed(:sticker, :delete, element.type, element.uri, name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def inspect
|
38
|
+
"#<#{self.class.name}(#{name}): #{value.inspect}>"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Element
|
43
|
+
include Enumerable
|
44
|
+
|
45
|
+
attr_reader :stickers, :type, :uri
|
46
|
+
|
47
|
+
def initialize (stickers, type, uri)
|
48
|
+
@stickers = stickers
|
49
|
+
@type = type
|
50
|
+
@uri = uri
|
51
|
+
end
|
52
|
+
|
53
|
+
def [] (name)
|
54
|
+
find { |s| s.name == name.to_s }
|
55
|
+
end
|
56
|
+
|
57
|
+
def delete (name)
|
58
|
+
self[name].delete! rescue nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def each
|
62
|
+
return to_enum unless block_given?
|
63
|
+
|
64
|
+
@stickers.controller.do_and_raise_if_needed(:sticker, :list, type, uri).each {|_, sticker|
|
65
|
+
name, value = sticker.split '=', 2
|
66
|
+
|
67
|
+
yield Sticker.new(self, name)
|
68
|
+
}
|
69
|
+
|
70
|
+
self
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
include Enumerable
|
75
|
+
|
76
|
+
attr_reader :controller
|
77
|
+
|
78
|
+
def initialize (controller)
|
79
|
+
@controller = controller
|
80
|
+
end
|
81
|
+
|
82
|
+
def [] (uri, type = :song)
|
83
|
+
Element.new(self, type, uri)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end; end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
module MPD; class Controller
|
12
|
+
|
13
|
+
class SupportedProtocols
|
14
|
+
include Enumerable
|
15
|
+
|
16
|
+
attr_reader :controller
|
17
|
+
|
18
|
+
def initialize (controller)
|
19
|
+
@controller = controller
|
20
|
+
@supported = []
|
21
|
+
|
22
|
+
controller.do_and_raise_if_needed(:urlhandlers).each {|_, name|
|
23
|
+
@supported << name[0 .. -4]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def each (&block)
|
28
|
+
return to_enum unless block_given?
|
29
|
+
|
30
|
+
@supported.each(&block)
|
31
|
+
|
32
|
+
self
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end; end
|