Module: SpotifyWeb::Schema
- Defined in:
- lib/spotify_web/schema.rb,
lib/spotify_web/schema/core.pb.rb,
lib/spotify_web/schema/radio.pb.rb,
lib/spotify_web/schema/mercury.pb.rb,
lib/spotify_web/schema/metadata.pb.rb,
lib/spotify_web/schema/playlist4.pb.rb,
lib/spotify_web/schema/socialgraph.pb.rb
Defined Under Namespace
Modules: Mercury, Metadata, Playlist4, Radio, Socialgraph Classes: DecorationData, Toplist
Constant Summary collapse
- SERVICES =
The services that are used
%w( mercury metadata playlist4changes playlist4content playlist4issues playlist4meta playlist4ops radio social socialgraph toplist )
Class Method Summary collapse
-
.build_all ⇒ Object
Rebuilds all of the Beecake::Message schema definitions in Spotify.
-
.data_url ⇒ Object
Looks up the url representing the current schema for all Spotify services.
-
.packages ⇒ Object
Generates the Protocol Buffer packages based on the current list of Spotify services.
-
.services ⇒ Object
Gets the collection of services defined in Spotify and the resource definitions associated with them.
Class Method Details
.build_all ⇒ Object
Rebuilds all of the Beecake::Message schema definitions in Spotify. Note that this schema is not always kept up-to-date in Spotify – and can sometimes include parser errors. As a result, there may be some manual changes that need to be made once the build is complete.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/spotify_web/schema.rb', line 27 def build_all # Prepare target directories proto_dir = File.join(File.dirname(__FILE__), '../../proto') schema_dir = File.join(File.dirname(__FILE__), 'schema') Dir.mkdir(proto_dir) unless Dir.exists?(proto_dir) # Build the proto files packages.each do |name, package| File.open("#{proto_dir}/#{name}.proto", 'w') {|f| f << package[:content]} end # Convert each proto file to a Beefcake message packages.each do |name, package| system( {'BEEFCAKE_NAMESPACE' => package[:namespace]}, "protoc --beefcake_out #{schema_dir} -I #{proto_dir} #{proto_dir}/#{name}.proto" ) end end |
.data_url ⇒ Object
Looks up the url representing the current schema for all Spotify services
105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/spotify_web/schema.rb', line 105 def data_url # Grab the login init options request = Net::HTTP::Get.new('https://play.spotify.com') request['User-Agent'] = SpotifyWeb::USER_AGENT response = Net::HTTP.start('play.spotify.com', 443, :use_ssl => true) do |http| http.request(request) end json = response.body.match(/Spotify\.Web\.Login\(document, (\{.+\}),[^\}]+\);/)[1] = JSON.parse(json) "#{['corejs']['protoSchemasLocation']}data.xml" end |
.packages ⇒ Object
Generates the Protocol Buffer packages based on the current list of Spotify services. This will merge certain services together under the same package if they have the same namespace.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/spotify_web/schema.rb', line 50 def packages packages = {} services.values.each do |service| namespace = 'SpotifyWeb::Schema' if match = service[:content].match(/package spotify\.(.+)\.proto;/) name = match[1] namespace << '::' + name.split('.').map {|part| part.capitalize} * '::' else name = 'core' end if package = packages[name] # Package already exists: just append the message definitions content = service[:content] content = content[content.index('message')..-1] package[:content] += "\n#{content}" else # Create a new package with the entire definition packages[name] = {:name => name, :namespace => namespace, :content => service[:content]} end end packages end |
.services ⇒ Object
Gets the collection of services defined in Spotify and the resource definitions associated with them
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/spotify_web/schema.rb', line 78 def services services = {} # Get the current schema request = Net::HTTP::Get.new(data_url) request['User-Agent'] = SpotifyWeb::USER_AGENT uri = URI(data_url) response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http| http.request(request) end # Parse each service definition doc = REXML::Document.new(response.body) doc.elements.each('services') do |root| root.elements.each do |service| name = service.name if SERVICES.include?(name) content = service.text.strip services[name] = {:name => name, :content => content} end end end services end |