sonos 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog.markdown CHANGED
@@ -1,3 +1,10 @@
1
+ ### Version 0.1.1 — Unreleased
2
+
3
+ * **Feature:** Queue
4
+ * **Feature:** Clear Queue
5
+ * **Feature:** Save Queue
6
+ * **Feature:** Device Description URL
7
+
1
8
  ### Version 0.1.0 — December 24, 2012
2
9
 
3
10
  * **Feature:** Stop
@@ -0,0 +1,55 @@
1
+ module Sonos
2
+ module ContentDirectory
3
+ CONTENT_DIRECTORY_ENDPOINT = '/MediaServer/ContentDirectory/Control'
4
+ CONTENT_DIRECTORY_XMLNS = 'urn:schemas-upnp-org:service:ContentDirectory:1'
5
+
6
+ # Get the current queue
7
+ def queue(starting_index = 0, requested_count = 100)
8
+ name = 'Browse'
9
+ action = "#{CONTENT_DIRECTORY_XMLNS}##{name}"
10
+ message = %Q{<u:#{name} xmlns:u="#{CONTENT_DIRECTORY_XMLNS}"><ObjectID>Q:0</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter>dc:title,res,dc:creator,upnp:artist,upnp:album,upnp:albumArtURI</Filter><StartingIndex>#{starting_index}</StartingIndex><RequestedCount>#{requested_count}</RequestedCount><SortCriteria></SortCriteria></u:Browse>}
11
+ result = content_directory_client.call name, soap_action: action, message: message
12
+ body = result.body[:browse_response]
13
+
14
+ hash = {
15
+ total: body[:total_matches].to_i,
16
+ items: parse_items(body[:result])
17
+ }
18
+
19
+ # Paginate
20
+ # TODO: This is ugly and inflexible
21
+ if starting_index == 0
22
+ start = starting_index
23
+ while hash[:items].count < hash[:total]
24
+ start += requested_count
25
+ hash[:items] += browse(start, requested_count)[:items]
26
+ end
27
+ end
28
+
29
+ hash
30
+ end
31
+
32
+ private
33
+
34
+ def content_directory_client
35
+ @content_directory_client ||= Savon.client endpoint: "http://#{self.ip}:#{PORT}#{CONTENT_DIRECTORY_ENDPOINT}", namespace: NAMESPACE
36
+ end
37
+
38
+ def parse_items(string)
39
+ result = []
40
+ doc = Nokogiri::XML(string)
41
+ doc.css('item').each do |item|
42
+ res = item.css('res').first
43
+ result << {
44
+ title: item.xpath('dc:title').inner_text,
45
+ artist: item.xpath('dc:creator').inner_text,
46
+ album: item.xpath('upnp:album').inner_text,
47
+ album_art: "http://#{self.ip}:#{PORT}#{item.xpath('upnp:albumArtURI').inner_text}",
48
+ duration: res['duration'],
49
+ id: res.inner_text
50
+ }
51
+ end
52
+ result
53
+ end
54
+ end
55
+ end
data/lib/sonos/speaker.rb CHANGED
@@ -2,12 +2,14 @@ require 'savon'
2
2
  require 'sonos/transport'
3
3
  require 'sonos/rendering'
4
4
  require 'sonos/device'
5
+ require 'sonos/content_directory'
5
6
 
6
7
  module Sonos
7
8
  class Speaker
8
9
  include Transport
9
10
  include Rendering
10
11
  include Device
12
+ include ContentDirectory
11
13
 
12
14
  attr_reader :ip, :zone_name, :zone_icon, :uid, :serial_number, :software_version, :hardware_version, :mac_address
13
15
 
@@ -18,6 +20,11 @@ module Sonos
18
20
  get_status
19
21
  end
20
22
 
23
+ # URL for giant dump of device information
24
+ def device_description_url
25
+ "http://#{self.ip}:#{PORT}/xml/device_description.xml"
26
+ end
27
+
21
28
  private
22
29
 
23
30
  # Get information about the speaker.
@@ -52,6 +52,19 @@ module Sonos
52
52
  send_transport_message('Previous')
53
53
  end
54
54
 
55
+ # Clear the queue
56
+ def clear_queue
57
+ send_transport_message('RemoveAllTracksFromQueue')
58
+ end
59
+
60
+ # Save queue
61
+ def save_queue(title)
62
+ name = 'SaveQueue'
63
+ action = "#{TRANSPORT_XMLNS}##{name}"
64
+ message = %Q{<u:#{name} xmlns:u="#{TRANSPORT_XMLNS}"><InstanceID>0</InstanceID><Title>#{title}</Title><ObjectID></ObjectID></u:#{name}>}
65
+ transport_client.call(name, soap_action: action, message: message)
66
+ end
67
+
55
68
  private
56
69
 
57
70
  # Play a stream.
data/lib/sonos/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sonos
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
data/sonos.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Sonos::VERSION
9
9
  gem.authors = ['Sam Soffes']
10
10
  gem.email = ['sam@soff.es']
11
- gem.description = 'Sonos Controller'
12
- gem.summary = 'Control Sonos speakers with Ruby'
11
+ gem.description = 'Control Sonos speakers with Ruby'
12
+ gem.summary = gem.description
13
13
  gem.homepage = 'https://github.com/soffes/sonos'
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sonos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -27,7 +27,7 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 2.0.2
30
- description: Sonos Controller
30
+ description: Control Sonos speakers with Ruby
31
31
  email:
32
32
  - sam@soff.es
33
33
  executables: []
@@ -41,6 +41,7 @@ files:
41
41
  - Rakefile
42
42
  - Readme.markdown
43
43
  - lib/sonos.rb
44
+ - lib/sonos/content_directory.rb
44
45
  - lib/sonos/device.rb
45
46
  - lib/sonos/rendering.rb
46
47
  - lib/sonos/speaker.rb
@@ -61,7 +62,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
62
  version: '0'
62
63
  segments:
63
64
  - 0
64
- hash: -1995798408343589310
65
+ hash: -921214504657487484
65
66
  required_rubygems_version: !ruby/object:Gem::Requirement
66
67
  none: false
67
68
  requirements:
@@ -70,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
71
  version: '0'
71
72
  segments:
72
73
  - 0
73
- hash: -1995798408343589310
74
+ hash: -921214504657487484
74
75
  requirements: []
75
76
  rubyforge_project:
76
77
  rubygems_version: 1.8.23