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.
@@ -0,0 +1,3 @@
1
+ MPD - Ruby controller
2
+ ======================
3
+ This is just a simple library to control [MPD](http://mpd.wikia.com/wiki/Music_Player_Daemon_Wiki).
@@ -0,0 +1,8 @@
1
+ #! /usr/bin/env ruby
2
+ require 'mpd'
3
+ require 'optparse'
4
+
5
+ options = {}
6
+
7
+ OptionParser.new do |o|
8
+ end.parse!
@@ -0,0 +1,12 @@
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
+ require 'mpd/controller'
12
+ require 'mpd/version'
@@ -0,0 +1,206 @@
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
+ require 'socket'
12
+
13
+ require 'mpd/protocol'
14
+
15
+ module MPD
16
+
17
+ # This is the main class to manage moc.
18
+ #
19
+ # The class also acts as a Socket if needed.
20
+ class Controller
21
+ autoload :Do, 'mpd/controller/do'
22
+ autoload :Database, 'mpd/controller/database'
23
+ autoload :Stats, 'mpd/controller/stats'
24
+ autoload :Config, 'mpd/controller/config'
25
+ autoload :SupportedTags, 'mpd/controller/supported_tags'
26
+ autoload :SupportedProtocols, 'mpd/controller/supported_protocols'
27
+ autoload :Commands, 'mpd/controller/commands'
28
+ autoload :Decoders, 'mpd/controller/decoders'
29
+ autoload :Audio, 'mpd/controller/audio'
30
+ autoload :Toggle, 'mpd/controller/toggle'
31
+ autoload :Player, 'mpd/controller/player'
32
+ autoload :CurrentPlaylist, 'mpd/controller/current_playlist'
33
+ autoload :Playlists, 'mpd/controller/playlists.rb'
34
+ autoload :Status, 'mpd/controller/status'
35
+ autoload :Channels, 'mpd/controller/channels'
36
+ autoload :Stickers, 'mpd/controller/stickers'
37
+
38
+ attr_reader :path, :host, :port, :version
39
+
40
+ def initialize (host = 'localhost', port = 6600)
41
+ @socket = File.exists?(host) ? UNIXSocket.new(host) : TCPSocket.new(host, port)
42
+ @version = @socket.readline.chomp.split(' ', 3).last
43
+
44
+ if unix?
45
+ @path = host
46
+ else
47
+ @host = host
48
+ @port = port
49
+ end
50
+ end
51
+
52
+ def unix?
53
+ @socket.is_a? UNIXSocket
54
+ end
55
+
56
+ def tcp?
57
+ @socket.is_a? TCPSocket
58
+ end
59
+
60
+ def respond_to_missing? (id, include_private = false)
61
+ @socket.respond_to? id, include_private
62
+ end
63
+
64
+ def method_missing (id, *args, &block)
65
+ if @socket.respond_to? id
66
+ return @socket.__send__ id, *args, &block
67
+ end
68
+
69
+ super
70
+ end
71
+
72
+ def do (*args, &block)
73
+ if block
74
+ Do.new(self, &block).send
75
+ else
76
+ name = args.shift
77
+ command = Protocol::Command.new(name, args)
78
+
79
+ @socket.puts command.to_s
80
+
81
+ Protocol::Response.read(self, command)
82
+ end
83
+ end
84
+
85
+ def do_and_raise_if_needed (*args)
86
+ response = self.do *args
87
+
88
+ if response.is_a?(Protocol::Error)
89
+ raise response.message
90
+ end
91
+
92
+ response
93
+ end
94
+
95
+ def authenticate (password)
96
+ self.do :password, password
97
+
98
+ self
99
+ end
100
+
101
+ def active?
102
+ self.do(:ping).success?
103
+ rescue
104
+ false
105
+ end
106
+
107
+ def kill!
108
+ self.do :kill
109
+ end
110
+
111
+ def disconnect!
112
+ self.do :close
113
+ end
114
+
115
+ def database
116
+ @database ||= Database.new(self)
117
+ end
118
+
119
+ def stats
120
+ Stats.new(self)
121
+ end
122
+
123
+ def audio
124
+ Audio.new(self)
125
+ end
126
+
127
+ def config
128
+ Config.new(self)
129
+ end
130
+
131
+ def supported_tags
132
+ SupportedTags.new(self)
133
+ end
134
+
135
+ def supported_protocols
136
+ SupportedProtocols.new(self)
137
+ end
138
+
139
+ def commands
140
+ Commands.new(self)
141
+ end
142
+
143
+ def decoders
144
+ Decoders.new(self)
145
+ end
146
+
147
+ def toggle
148
+ @toggle ||= Toggle.new(self)
149
+ end
150
+
151
+ def player
152
+ @player ||= Player.new(self)
153
+ end
154
+
155
+ def playlists
156
+ @playlists ||= Playlists.new(self)
157
+ end
158
+
159
+ def playlist (name = nil)
160
+ if name
161
+ playlists[name]
162
+ else
163
+ @playlist ||= CurrentPlaylist.new(self)
164
+ end
165
+ end
166
+
167
+ def status
168
+ Status.new(self)
169
+ end
170
+
171
+ def channels
172
+ @channels ||= Channels.new(self)
173
+ end
174
+
175
+ def stickers
176
+ @stickers ||= Stickers.new(self)
177
+ end
178
+
179
+ def channel (name)
180
+ channels[name]
181
+ end
182
+
183
+ def wait
184
+ self.do(:idle).map(&:last)
185
+ rescue Interrupt
186
+ stop_waiting and raise # my undead army
187
+ end
188
+
189
+ def wait_for (*args)
190
+ self.do(:idle, *args.flatten.compact.uniq).map(&:last)
191
+ rescue Interrupt
192
+ stop_waiting and raise # my undead army
193
+ end
194
+
195
+ def stop_waiting
196
+ self.do :noidle
197
+ end
198
+
199
+ def loop (*what)
200
+ loop do
201
+ yield wait_for *what
202
+ end
203
+ end
204
+ end
205
+
206
+ end
@@ -0,0 +1,78 @@
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 Audio
14
+ class Output
15
+ attr_reader :audio, :id
16
+
17
+ def initialize (audio, id)
18
+ @audio = audio
19
+ @id = id
20
+ end
21
+
22
+ def name
23
+ audio.controller.do_and_raise_if_needed(:outputs).each_slice(3) {|(_, id), (_, name), (_, enabled)|
24
+ return name if @id == id
25
+ }
26
+ end
27
+
28
+ def enabled?
29
+ audio.controller.do_and_raise_if_needed(:outputs).each_slice(3) {|(_, id), (_, name), (_, enabled)|
30
+ return enabled if @id == id
31
+ }
32
+ end
33
+
34
+ def enable!
35
+ audio.controller.do_and_raise_if_needed :enableoutput, id
36
+
37
+ self
38
+ end
39
+
40
+ def disable!
41
+ audio.controller.do_and_raise_if_needed :disableoutput, id
42
+
43
+ self
44
+ end
45
+
46
+ def inspect
47
+ "#<#{self.class.name}(#{id}, #{enabled? ? 'enabled' : 'disabled'}): #{name}>"
48
+ end
49
+ end
50
+
51
+ include Enumerable
52
+
53
+ attr_reader :controller
54
+
55
+ def initialize (controller)
56
+ @controller = controller
57
+ end
58
+
59
+ def each
60
+ return to_enum unless block_given?
61
+
62
+ controller.do_and_raise_if_needed(:outputs).each_slice(3) {|(_, id), (_, name), (_, enabled)|
63
+ yield Output.new(self, id)
64
+ }
65
+
66
+ self
67
+ end
68
+
69
+ def [] (matches)
70
+ controller.do_and_raise_if_needed(:outputs).each_slice(3) {|(_, id), (_, name), (_, enabled)|
71
+ return Output.new(self, id) if matches == id || matches == name
72
+ }
73
+
74
+ nil
75
+ end
76
+ end
77
+
78
+ end; end
@@ -0,0 +1,117 @@
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
+ require 'weakref'
12
+
13
+ module MPD; class Controller
14
+
15
+ class Channels
16
+ class Channel
17
+ attr_reader :name
18
+
19
+ def initialize (channels, name)
20
+ @channels = channels
21
+ @name = name
22
+ @buffer = []
23
+ end
24
+
25
+ def incoming (text)
26
+ @buffer << text
27
+ end
28
+
29
+ def send_message (text)
30
+ @channels.send_message(@name, text)
31
+ end
32
+
33
+ def read_message
34
+ @channels.send :read_messages, true while @buffer.empty?
35
+ @buffer.shift
36
+ end
37
+
38
+ def read_message_nonblock
39
+ @channels.send :read_messages
40
+ @buffer.shift
41
+ end
42
+ end
43
+
44
+ include Enumerable
45
+
46
+ attr_reader :controller
47
+
48
+ def initialize (controller)
49
+ @controller = controller
50
+ @channels = []
51
+ end
52
+
53
+ def names
54
+ controller.do_and_raise_if_needed(:channels).map(&:last)
55
+ end
56
+
57
+ def each_name (&block)
58
+ names.each(&block)
59
+ end
60
+
61
+ def each
62
+ return to_enum unless block_given?
63
+
64
+ each_name {|name|
65
+ yield self[name]
66
+ }
67
+
68
+ self
69
+ end
70
+
71
+ def [] (name, sub = true)
72
+ subscribe name if sub
73
+
74
+ Channel.new(self, name).tap {|channel|
75
+ @channels << WeakRef.new(channel)
76
+ }
77
+ end
78
+
79
+ def subscribe (name)
80
+ controller.do_and_raise_if_needed :subscribe, name
81
+ end
82
+
83
+ def unsubscribe (name)
84
+ controller.do_and_raise_if_needed :unsubscribe, name
85
+ end
86
+
87
+ def send_message (name, text)
88
+ controller.do_and_raise_if_needed :sendmessage, name, text
89
+ end
90
+
91
+ private
92
+ def read_messages (wait = false)
93
+ response = controller.do_and_raise_if_needed :readmessages
94
+
95
+ if response.empty?
96
+ if wait
97
+ controller.wait_for :message
98
+ else
99
+ return false
100
+ end
101
+ end
102
+
103
+ response.each_slice(2) {|(_, name), (_, message)|
104
+ @channels.each {|channel|
105
+ next unless channel.weakref_alive? && channel.name.to_s == name.to_s
106
+
107
+ channel.incoming(message)
108
+ }
109
+ }
110
+
111
+ @channels.select!(&:weakref_alive?)
112
+
113
+ true
114
+ end
115
+ end
116
+
117
+ end; end
@@ -0,0 +1,57 @@
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 Commands
14
+ class Command
15
+ attr_reader :name
16
+
17
+ def initialize (name, usable = true)
18
+ @name = name
19
+ @usable = usable
20
+ end
21
+
22
+ def usable?
23
+ @usable
24
+ end
25
+ end
26
+
27
+ include Enumerable
28
+
29
+ attr_reader :controller
30
+
31
+ def initialize (controller)
32
+ @controller = controller
33
+ @commands = []
34
+
35
+ controller.do_and_raise_if_needed(:commands).each {|_, name|
36
+ @commands << Command.new(name)
37
+ }
38
+
39
+ controller.do_and_raise_if_needed(:notcommands).each {|_, name|
40
+ @commands << Command.new(name, false)
41
+ }
42
+ end
43
+
44
+ def each (&block)
45
+ return to_enum unless block_given?
46
+
47
+ @commands.each(&block)
48
+
49
+ self
50
+ end
51
+
52
+ def inspect
53
+ "#<#{self.class.name}: #{map {|c| "#{'-' unless c.usable?}#{c.name}"}.join ' '}>"
54
+ end
55
+ end
56
+
57
+ end; end