mpd 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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