moc 2.5.0 → 2.5.0.1
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/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
|