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.
@@ -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
- get_item
117
+ read_item
89
118
 
90
119
  when :PLIST_DEL, :QUEUE_DEL, :STATUS_MSG
91
- get_string
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
- Playlist::Item.new(self)
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
- Tags.new(self)
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 event state].each {|name|
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
@@ -53,7 +53,7 @@ class Player
53
53
  controller.send_command :get_queue
54
54
  controller.wait_for :data
55
55
 
56
- until (item = controller.read_item).nil?
56
+ while item = controller.read_item
57
57
  block.call(item)
58
58
  end
59
59
  end
@@ -11,30 +11,7 @@
11
11
  module Moc; class Controller
12
12
 
13
13
  class Playlist
14
- class Item < Struct.new(:file, :title_tags, :tags, :mtime)
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 Song
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 channels
22
- controller.send_command :get_channels
23
- controller.get_integer
88
+ def == (other)
89
+ super || state == other
24
90
  end
25
91
 
26
- def rate
27
- controller.send_command :get_rate
28
- controller.get_integer
92
+ def state
93
+ controller.send_command :get_state
94
+ controller.get_state
29
95
  end
30
96
 
31
- def bitrate
32
- controller.send_command :get_bitrate
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 time
42
- controller.send_command :get_ctime
43
- controller.get_integer
44
- end
102
+ def song
103
+ return if self == :stop
45
104
 
46
- def file
47
- controller.send_command :get_sname
48
- controller.get_string
105
+ Song.new(controller)
49
106
  end
50
107
 
51
- def tags
52
- path = file
108
+ def to_sym
109
+ state.to_sym
110
+ end
111
+ end
53
112
 
54
- controller.send_command :get_file_tags
55
- controller.send_string path
56
- controller.send_integer 0x01 | 0x02
113
+ class Song
114
+ attr_reader :controller, :channels, :rate, :bitrate, :average_bitrate, :position, :file, :tags
57
115
 
58
- controller.wait_for(:file_tags).tags
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=#{time}>"
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
- end
77
-
78
- def == (other)
79
- state == other
80
- end
148
+ @internal = Live.new(controller)
81
149
 
82
- def state
83
- controller.send_command :get_state
84
- controller.get_state
85
- end
150
+ @state = @internal.state
151
+ @volume = @internal.volume
86
152
 
87
- def volume
88
- controller.send_command :get_mixer
89
- controller.get_integer
153
+ if state != :stop
154
+ @song = Song.new(controller)
155
+ end
90
156
  end
91
157
 
92
- def song
93
- return if self == :stop
94
-
95
- Song.new(controller)
158
+ def == (other)
159
+ super || state == other
96
160
  end
97
161
 
98
162
  def to_sym
@@ -10,24 +10,7 @@
10
10
 
11
11
  module Moc; class Controller
12
12
 
13
- class Tags < Struct.new(:title, :artist, :album, :track, :time)
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
- # toggle the repeat status
61
- def repeat
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
- # check if repeat is enabled
76
- def repeat?
77
- on? :Repeat
78
- end
63
+ define_method name do
64
+ toggle option_name
65
+ end
79
66
 
80
- # toggle the shuffle status
81
- def shuffle
82
- toggle :Shuffle
83
- end
67
+ define_method "#{name}!" do
68
+ on option_name
69
+ end
84
70
 
85
- # enable shuffle
86
- def shuffle!
87
- on :Shuffle
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
- # check if shuffle is enabled
96
- def shuffle?
97
- on? :Shuffle
98
- end
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
@@ -17,8 +17,12 @@ module Type
17
17
  raise 'no read has been implemented'
18
18
  end
19
19
 
20
- def unpack (text)
21
- read(StringIO.new(text))
20
+ def unpack (text, eat = false)
21
+ io = StringIO.new(text)
22
+
23
+ read(io).tap {
24
+ text[0, io.tell] = '' if eat
25
+ }
22
26
  end
23
27
  end
24
28
 
@@ -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('l').first)
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 respond_to_missing? (id, include_private = false)
25
- @internal.respond_to? id, include_private
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('l')
37
+ [self].pack('i')
38
38
  end
39
39
  end
40
40
 
@@ -16,6 +16,10 @@ class Time < ::Time
16
16
  def self.read (io)
17
17
  at Integer.read(io)
18
18
  end
19
+
20
+ def pack
21
+ Integer.new(to_i).pack
22
+ end
19
23
  end
20
24
 
21
25
  end; end
data/lib/moc/version.rb CHANGED
@@ -10,6 +10,6 @@
10
10
 
11
11
  module Moc
12
12
  def self.version
13
- '2.5.0'
13
+ '2.5.0.1'
14
14
  end
15
15
  end
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-20 00:00:00.000000000 Z
12
+ date: 2012-06-21 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: meh@paranoici.org