moc 2.5.0 → 2.5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/moc/controller.rb +57 -10
- data/lib/moc/controller/player.rb +1 -1
- data/lib/moc/controller/playlist.rb +1 -24
- data/lib/moc/controller/status.rb +110 -46
- data/lib/moc/controller/tags.rb +1 -18
- data/lib/moc/controller/toggle.rb +15 -55
- data/lib/moc/protocol.rb +6 -2
- data/lib/moc/protocol/integer.rb +4 -4
- data/lib/moc/protocol/time.rb +4 -0
- data/lib/moc/version.rb +1 -1
- metadata +2 -2
data/lib/moc/controller.rb
CHANGED
@@ -50,7 +50,7 @@ class Controller
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def send (object)
|
53
|
-
write object.pack
|
53
|
+
@socket.write object.respond_to?(:pack) ? object.pack : object.to_s
|
54
54
|
end
|
55
55
|
|
56
56
|
def send_command (command)
|
@@ -69,6 +69,35 @@ class Controller
|
|
69
69
|
send Protocol::String.new(string.to_s)
|
70
70
|
end
|
71
71
|
|
72
|
+
def send_item (item)
|
73
|
+
if item
|
74
|
+
send_string item.file
|
75
|
+
send_string item.title_tags || ''
|
76
|
+
send_tags item.tags
|
77
|
+
send_time item.mtime
|
78
|
+
else
|
79
|
+
send_string ''
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def send_tags (tags)
|
84
|
+
if tags
|
85
|
+
send_string tags.title
|
86
|
+
send_string tags.artist
|
87
|
+
send_string tags.album
|
88
|
+
send_integer tags.track
|
89
|
+
send_integer tags.time
|
90
|
+
send_integer 0x01 | 0x02
|
91
|
+
else
|
92
|
+
send_string ''
|
93
|
+
send_string ''
|
94
|
+
send_string ''
|
95
|
+
send_integer -1
|
96
|
+
send_integer -1
|
97
|
+
send_integer 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
72
101
|
def read_string
|
73
102
|
Protocol::String.read(@socket)
|
74
103
|
end
|
@@ -85,10 +114,10 @@ class Controller
|
|
85
114
|
Protocol::Event.read(@socket).tap {|event|
|
86
115
|
event.data = case event.to_sym
|
87
116
|
when :PLIST_ADD, :QUEUE_ADD
|
88
|
-
|
117
|
+
read_item
|
89
118
|
|
90
119
|
when :PLIST_DEL, :QUEUE_DEL, :STATUS_MSG
|
91
|
-
|
120
|
+
read_string
|
92
121
|
|
93
122
|
when :FILE_TAGS
|
94
123
|
FileTags.new(read_string, read_tags)
|
@@ -104,14 +133,34 @@ class Controller
|
|
104
133
|
end
|
105
134
|
|
106
135
|
def read_item
|
107
|
-
|
136
|
+
return if (file = read_string.to_s).empty?
|
137
|
+
|
138
|
+
title_tags = read_string.to_s
|
139
|
+
|
140
|
+
Playlist::Item.new(file, title_tags.empty? ? nil : title_tags, read_tags, read_time)
|
108
141
|
end
|
109
142
|
|
110
143
|
def read_tags
|
111
|
-
|
144
|
+
title = read_string.to_s
|
145
|
+
artist = read_string.to_s
|
146
|
+
album = read_string.to_s
|
147
|
+
track = read_integer.to_i
|
148
|
+
time = read_integer.to_i
|
149
|
+
filled = read_integer.to_i
|
150
|
+
|
151
|
+
title = nil if title.empty?
|
152
|
+
artist = nil if artist.empty?
|
153
|
+
album = nil if album.empty?
|
154
|
+
track = nil if track == -1
|
155
|
+
|
156
|
+
if title.nil? && artist.nil? && album.nil? && track.nil? && time == -1 && filled == 0
|
157
|
+
return nil
|
158
|
+
end
|
159
|
+
|
160
|
+
Tags.new(title, artist, album, track, time)
|
112
161
|
end
|
113
162
|
|
114
|
-
%w[string integer time
|
163
|
+
%w[string integer time state tags].each {|name|
|
115
164
|
define_method "get_#{name}" do
|
116
165
|
wait_for :data
|
117
166
|
|
@@ -135,8 +184,6 @@ class Controller
|
|
135
184
|
}
|
136
185
|
end
|
137
186
|
|
138
|
-
private :fire
|
139
|
-
|
140
187
|
def loop
|
141
188
|
while event = read_event
|
142
189
|
fire event
|
@@ -171,8 +218,8 @@ class Controller
|
|
171
218
|
@player ||= Player.new(self)
|
172
219
|
end
|
173
220
|
|
174
|
-
def status
|
175
|
-
@status ||= Status.new(self)
|
221
|
+
def status (live = false)
|
222
|
+
live ? (@status ||= Status::Live.new(self)) : Status.new(self)
|
176
223
|
end
|
177
224
|
|
178
225
|
def inspect
|
@@ -11,30 +11,7 @@
|
|
11
11
|
module Moc; class Controller
|
12
12
|
|
13
13
|
class Playlist
|
14
|
-
|
15
|
-
attr_reader :controller
|
16
|
-
|
17
|
-
def initialize (controller)
|
18
|
-
@controller = controller
|
19
|
-
|
20
|
-
if (file = controller.read_string).empty?
|
21
|
-
@nil = true
|
22
|
-
else
|
23
|
-
@nil = false
|
24
|
-
|
25
|
-
super(
|
26
|
-
file,
|
27
|
-
controller.read_string,
|
28
|
-
controller.read_tags,
|
29
|
-
controller.read_time
|
30
|
-
)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def nil?
|
35
|
-
@nil
|
36
|
-
end
|
37
|
-
end
|
14
|
+
Item = Struct.new(:file, :title_tags, :tags, :mtime)
|
38
15
|
end
|
39
16
|
|
40
17
|
Move = Struct.new(:from, :to)
|
@@ -11,51 +11,119 @@
|
|
11
11
|
module Moc; class Controller
|
12
12
|
|
13
13
|
class Status
|
14
|
-
class
|
14
|
+
class Live
|
15
|
+
class Song
|
16
|
+
attr_reader :controller
|
17
|
+
|
18
|
+
def initialize (controller)
|
19
|
+
@controller = controller
|
20
|
+
end
|
21
|
+
|
22
|
+
def channels
|
23
|
+
controller.send_command :get_channels
|
24
|
+
controller.get_integer.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def rate
|
28
|
+
controller.send_command :get_rate
|
29
|
+
controller.get_integer.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
def bitrate
|
33
|
+
controller.send_command :get_bitrate
|
34
|
+
controller.get_integer.to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
def average_bitrate
|
38
|
+
controller.send_command :get_avg_bitrate
|
39
|
+
controller.get_integer.to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
def position
|
43
|
+
controller.send_command :get_ctime
|
44
|
+
controller.get_integer.to_i
|
45
|
+
end
|
46
|
+
|
47
|
+
def file
|
48
|
+
controller.send_command :get_sname
|
49
|
+
controller.get_string.to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
def tags
|
53
|
+
path = file
|
54
|
+
|
55
|
+
if path.start_with?('http://') || path.start_with?('ftp://')
|
56
|
+
controller.send_command :get_tags
|
57
|
+
controller.get_tags
|
58
|
+
else
|
59
|
+
controller.send_command :get_file_tags
|
60
|
+
controller.send_string path
|
61
|
+
controller.send_integer 0x01 | 0x02
|
62
|
+
|
63
|
+
controller.wait_for(:file_tags).tags
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
%w[title artist album track].each {|name|
|
68
|
+
define_method name do
|
69
|
+
tags.send name
|
70
|
+
end
|
71
|
+
}
|
72
|
+
|
73
|
+
def duration
|
74
|
+
tags.time
|
75
|
+
end
|
76
|
+
|
77
|
+
def inspect
|
78
|
+
"#<#{self.class.name}: track=#{track} title=#{title.inspect} artist=#{artist.inspect} album=#{album.inspect} channels=#{channels} bitrate=#{bitrate}(#{average_bitrate}) position=#{position}/#{duration}>"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
15
82
|
attr_reader :controller
|
16
83
|
|
17
84
|
def initialize (controller)
|
18
85
|
@controller = controller
|
19
86
|
end
|
20
87
|
|
21
|
-
def
|
22
|
-
|
23
|
-
controller.get_integer
|
88
|
+
def == (other)
|
89
|
+
super || state == other
|
24
90
|
end
|
25
91
|
|
26
|
-
def
|
27
|
-
controller.send_command :
|
28
|
-
controller.
|
92
|
+
def state
|
93
|
+
controller.send_command :get_state
|
94
|
+
controller.get_state
|
29
95
|
end
|
30
96
|
|
31
|
-
def
|
32
|
-
controller.send_command :
|
33
|
-
controller.get_integer
|
34
|
-
end
|
35
|
-
|
36
|
-
def average_bitrate
|
37
|
-
controller.send_command :get_avg_bitrate
|
38
|
-
controller.get_integer
|
97
|
+
def volume
|
98
|
+
controller.send_command :get_mixer
|
99
|
+
controller.get_integer.to_i
|
39
100
|
end
|
40
101
|
|
41
|
-
def
|
42
|
-
|
43
|
-
controller.get_integer
|
44
|
-
end
|
102
|
+
def song
|
103
|
+
return if self == :stop
|
45
104
|
|
46
|
-
|
47
|
-
controller.send_command :get_sname
|
48
|
-
controller.get_string
|
105
|
+
Song.new(controller)
|
49
106
|
end
|
50
107
|
|
51
|
-
def
|
52
|
-
|
108
|
+
def to_sym
|
109
|
+
state.to_sym
|
110
|
+
end
|
111
|
+
end
|
53
112
|
|
54
|
-
|
55
|
-
|
56
|
-
controller.send_integer 0x01 | 0x02
|
113
|
+
class Song
|
114
|
+
attr_reader :controller, :channels, :rate, :bitrate, :average_bitrate, :position, :file, :tags
|
57
115
|
|
58
|
-
|
116
|
+
def initialize (controller)
|
117
|
+
@controller = controller
|
118
|
+
@internal = Live::Song.new(controller)
|
119
|
+
|
120
|
+
@channels = @internal.channels
|
121
|
+
@rate = @internal.rate
|
122
|
+
@bitrate = @internal.bitrate
|
123
|
+
@average_bitrate = @internal.average_bitrate
|
124
|
+
@position = @internal.position
|
125
|
+
@file = @internal.file
|
126
|
+
@tags = @internal.tags
|
59
127
|
end
|
60
128
|
|
61
129
|
%w[title artist album track].each {|name|
|
@@ -64,35 +132,31 @@ class Status
|
|
64
132
|
end
|
65
133
|
}
|
66
134
|
|
135
|
+
def duration
|
136
|
+
tags.time
|
137
|
+
end
|
138
|
+
|
67
139
|
def inspect
|
68
|
-
"#<#{self.class.name}: track=#{track} title=#{title} artist=#{artist} album=#{album} channels=#{channels} bitrate=#{bitrate}(#{average_bitrate}) position=#{
|
140
|
+
"#<#{self.class.name}: track=#{track} title=#{title.inspect} artist=#{artist.inspect} album=#{album.inspect} channels=#{channels} bitrate=#{bitrate}(#{average_bitrate}) position=#{position}/#{duration}>"
|
69
141
|
end
|
70
142
|
end
|
71
143
|
|
72
|
-
attr_reader :controller
|
144
|
+
attr_reader :controller, :state, :volume, :song
|
73
145
|
|
74
146
|
def initialize (controller)
|
75
147
|
@controller = controller
|
76
|
-
|
77
|
-
|
78
|
-
def == (other)
|
79
|
-
state == other
|
80
|
-
end
|
148
|
+
@internal = Live.new(controller)
|
81
149
|
|
82
|
-
|
83
|
-
|
84
|
-
controller.get_state
|
85
|
-
end
|
150
|
+
@state = @internal.state
|
151
|
+
@volume = @internal.volume
|
86
152
|
|
87
|
-
|
88
|
-
|
89
|
-
|
153
|
+
if state != :stop
|
154
|
+
@song = Song.new(controller)
|
155
|
+
end
|
90
156
|
end
|
91
157
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
Song.new(controller)
|
158
|
+
def == (other)
|
159
|
+
super || state == other
|
96
160
|
end
|
97
161
|
|
98
162
|
def to_sym
|
data/lib/moc/controller/tags.rb
CHANGED
@@ -10,24 +10,7 @@
|
|
10
10
|
|
11
11
|
module Moc; class Controller
|
12
12
|
|
13
|
-
|
14
|
-
attr_reader :controller
|
15
|
-
|
16
|
-
def initialize (controller)
|
17
|
-
@controller = controller
|
18
|
-
|
19
|
-
super(
|
20
|
-
controller.read_string,
|
21
|
-
controller.read_string,
|
22
|
-
controller.read_string,
|
23
|
-
controller.read_integer,
|
24
|
-
controller.read_integer
|
25
|
-
)
|
26
|
-
|
27
|
-
controller.read_integer
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
13
|
+
Tags = Struct.new(:title, :artist, :album, :track, :time)
|
31
14
|
FileTags = Struct.new(:file, :tags)
|
32
15
|
|
33
16
|
end; end
|
@@ -57,65 +57,25 @@ class Toggle
|
|
57
57
|
!controller.get_integer.zero?
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
toggle :Repeat
|
63
|
-
end
|
64
|
-
|
65
|
-
# enable repeat
|
66
|
-
def repeat!
|
67
|
-
on :Repeat
|
68
|
-
end
|
69
|
-
|
70
|
-
# disable repeat
|
71
|
-
def no_repeat!
|
72
|
-
off :Repeat
|
73
|
-
end
|
60
|
+
%w[repeat shuffle auto_next].each {|name|
|
61
|
+
option_name = name.capitalize.gsub(/_(\w)/) { $1.upcase }
|
74
62
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
63
|
+
define_method name do
|
64
|
+
toggle option_name
|
65
|
+
end
|
79
66
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
67
|
+
define_method "#{name}!" do
|
68
|
+
on option_name
|
69
|
+
end
|
84
70
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
# disable shuffle
|
91
|
-
def no_shuffle!
|
92
|
-
off :Shuffle
|
93
|
-
end
|
71
|
+
define_method "no_#{name}!" do
|
72
|
+
off option_name
|
73
|
+
end
|
94
74
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
# toggle the auto next status
|
101
|
-
def auto_next
|
102
|
-
toggle :AutoNext
|
103
|
-
end
|
104
|
-
|
105
|
-
# enable auto next
|
106
|
-
def auto_next!
|
107
|
-
on :AutoNext
|
108
|
-
end
|
109
|
-
|
110
|
-
# disable auto next
|
111
|
-
def no_auto_next!
|
112
|
-
off :AutoNext
|
113
|
-
end
|
114
|
-
|
115
|
-
# check if auto next is enabled
|
116
|
-
def auto_next?
|
117
|
-
on? :AutoNext
|
118
|
-
end
|
75
|
+
define_method "#{name}?" do
|
76
|
+
on? option_name
|
77
|
+
end
|
78
|
+
}
|
119
79
|
|
120
80
|
# toggle the pause status
|
121
81
|
def pause
|
data/lib/moc/protocol.rb
CHANGED
data/lib/moc/protocol/integer.rb
CHANGED
@@ -14,15 +14,15 @@ class Integer < BasicObject
|
|
14
14
|
extend Type
|
15
15
|
|
16
16
|
def self.read (io)
|
17
|
-
new(io.read(4).unpack('
|
17
|
+
new(io.read(4).unpack('i').first)
|
18
18
|
end
|
19
19
|
|
20
20
|
def initialize (value)
|
21
21
|
@internal = value
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
@internal.respond_to?
|
24
|
+
def respond_to? (id, include_private = false)
|
25
|
+
return true if id == :pack || @internal.respond_to?(id, include_private)
|
26
26
|
end
|
27
27
|
|
28
28
|
def method_missing (id, *args, &block)
|
@@ -34,7 +34,7 @@ class Integer < BasicObject
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def pack
|
37
|
-
[self].pack('
|
37
|
+
[self].pack('i')
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
data/lib/moc/protocol/time.rb
CHANGED
data/lib/moc/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.0
|
4
|
+
version: 2.5.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-21 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email: meh@paranoici.org
|