Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added original source tree into repository

Created unit tests for Artists and Releases
  • Loading branch information...
commit b671360fe867b01a4578dee17a7b1307607b3603 1 parent 83fb75a
authored August 07, 2008
47  lib/rest.rb
... ...
@@ -0,0 +1,47 @@
  1
+require 'net/https'
  2
+
  3
+module REST
  4
+	class Connection
  5
+		def initialize(base_url, args = {})
  6
+			@base_url = base_url
  7
+			@username = args[:username]
  8
+			@password = args[:password]
  9
+		end
  10
+
  11
+		def get(resource, args = nil)
  12
+			request(resource, "get", args)
  13
+		end
  14
+
  15
+		def post(resource, args = nil)
  16
+			request(resource, "post", args)
  17
+		end
  18
+
  19
+		def request(resource, method = "get", args = nil)
  20
+			url = URI.join(@base_url, resource)
  21
+
  22
+			if args
  23
+				# TODO: What about keys without value?
  24
+				url.query = args.map { |k,v| "%s=%s" % [URI.encode(k), URI.encode(v)] }.join("&")
  25
+			end
  26
+			
  27
+			pp (@base_url + url.request_uri).squeeze('/')
  28
+			
  29
+			case method
  30
+			when "get"
  31
+				req = Net::HTTP::Get.new(url.request_uri)
  32
+			when "post"
  33
+				req = Net::HTTP::Post.new(url.request_uri)
  34
+			end
  35
+
  36
+			if @username and @password
  37
+				req.basic_auth(@username, @password)
  38
+			end
  39
+
  40
+			http = Net::HTTP.new(url.host, url.port)
  41
+			http.use_ssl = (url.port == 443)
  42
+
  43
+			res = http.start() { |conn| conn.request(req) }
  44
+			res.body
  45
+		end
  46
+	end
  47
+end
17  lib/yahoo-music.rb
... ...
@@ -1,7 +1,24 @@
  1
+%w{rubygems cgi hpricot activesupport}.each { |x| require x }
  2
+
1 3
 $:.unshift(File.dirname(__FILE__)) unless
2 4
   $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3 5
 
  6
+require 'rest'
  7
+require 'yahoo-music/base'
  8
+require 'yahoo-music/version'
  9
+
  10
+require 'yahoo-music/artist'
  11
+require 'yahoo-music/category'
  12
+require 'yahoo-music/release'
  13
+require 'yahoo-music/review'
  14
+require 'yahoo-music/track'
  15
+require 'yahoo-music/video'
  16
+
4 17
 module Yahoo
5 18
   module Music
  19
+    LOCALE      = "us"
  20
+    API_URL     = "http://#{LOCALE}.music.yahooapis.com/"
  21
+    API_VERSION = 'v1'
  22
+    APP_ID      = "25BJGafV34GnIar0alwCNe6VkJfrSe4.FKqHZlzwM73lP5aCWu4K48eUEVszu3dI7aPcTwc-"    
6 23
   end
7 24
 end
31  lib/yahoo-music/artist.rb
... ...
@@ -0,0 +1,31 @@
  1
+# <Artist
  2
+#         catzillaID = xs:int
  3
+#         flags = xs:int
  4
+#         hotzillaID = xs:int
  5
+#         id = xs:string
  6
+#         name = xs:string
  7
+#         rating = xs:int
  8
+#         salesGenreCode = xs:int
  9
+#         sortName = xs:string
  10
+#         trackCount = xs:int
  11
+#         website = xs:string
  12
+#         >
  13
+# 
  14
+#     Content: 
  15
+#         Image*, Category*, Releases?, TopTracks?, TopSimilarArtists?, RadioStations?, Events?, Fans?, NewsArticles?, ReleaseReviews?, ShortBio?, FullBio?, ItemInfo?, Video*
  16
+# </Artist>
  17
+
  18
+module Yahoo
  19
+  module Music
  20
+    class Artist < Base      
  21
+      attribute :id,          Integer
  22
+      attribute :name,        String
  23
+      attribute :sort_name,   String, :matcher => "sortName"
  24
+      attribute :website,     String
  25
+      
  26
+      attribute :releases,    Release
  27
+      attribute :categories,  Category
  28
+      attribute :videos,      Video
  29
+    end
  30
+  end
  31
+end
148  lib/yahoo-music/base.rb
... ...
@@ -0,0 +1,148 @@
  1
+module Yahoo
  2
+  module Music
  3
+    class Base
  4
+      class << self
  5
+        attr_accessor :attributes, :associations
  6
+        
  7
+        def attribute(*args)
  8
+          @attributes   ||= {}
  9
+          @associations ||= []
  10
+          
  11
+          options = args.extract_options!
  12
+          name, type = args
  13
+          class_eval %(attr_accessor :#{name})
  14
+          @attributes[name] = options.update({:type => type})
  15
+          
  16
+          if Yahoo::Music::Base.subclasses.include?(type.inspect)
  17
+            @associations << name
  18
+            
  19
+            # Define plural and singular association methods
  20
+            define_method("#{name}".pluralize.to_sym) do
  21
+              value = instance_variable_get("@#{name}") || query_association_by_id(name, self.id)
  22
+              instance_variable_set("@#{name}", value)
  23
+              return value
  24
+            end
  25
+            
  26
+            define_method("#{name}".singularize.to_sym) do
  27
+              value = instance_variable_get("@#{name}") || query_association_by_id(name, self.id)
  28
+              value = value.first
  29
+              instance_variable_set("@#{name}", value)
  30
+              return value
  31
+            end
  32
+          end
  33
+          
  34
+          if options[:type] == Boolean
  35
+            define_method("#{name}?".to_sym) do
  36
+              value = instance_variable_get("@#{name}")
  37
+              return value
  38
+            end
  39
+          end
  40
+        end
  41
+        
  42
+        def attributes
  43
+          @attributes || {}
  44
+        end
  45
+        
  46
+        def associations
  47
+          @associations || []
  48
+        end
  49
+        
  50
+        def name_with_demodulization
  51
+          self.name_without_demodulization.demodulize        
  52
+        end
  53
+        
  54
+        alias_method_chain :name, :demodulization
  55
+        
  56
+        def connection
  57
+          @connection ||= REST::Connection.new(API_URL)
  58
+        end
  59
+      
  60
+        def fetch_and_parse(resource, options = {})          
  61
+          options = options.update({'appid' => APP_ID})
  62
+          options = options.update({'response' => self.associations.join(',')}) if self.associations.any?
  63
+          return Hpricot::XML(connection.get(resource, options))
  64
+        end
  65
+        
  66
+        def api_path(service, resource, method, *args)
  67
+          response_type = method.nil? ? :item : :list
  68
+          parameters = [service, API_VERSION, response_type, resource, method, *args].compact
  69
+          return parameters.collect!{|param| CGI::escape(param.to_s).downcase}.join('/')
  70
+        end
  71
+        
  72
+        # Search by a parameter for a specific service
  73
+        # Ex. Artist.search(term)
  74
+        # options[:search_mode]
  75
+        def search(*args)
  76
+          options = args.extract_options!
  77
+          xml = fetch_and_parse(api_path(self.name, nil, :search, options[:search_mode] || :all, args.join(',')), options)
  78
+          return xml.search(self.name).collect{|elem| self.new(elem)}
  79
+        end
  80
+      end
  81
+            
  82
+      def initialize(xml)
  83
+        raise ArgumentError unless xml.kind_of?(Hpricot)
  84
+                
  85
+        self.class.attributes.each do |attribute, options|
  86
+          value = xml.attributes[options[:matcher] || attribute.to_s]
  87
+          begin
  88
+            if options[:type] == Integer
  89
+              value = value.to_i
  90
+            elsif options[:type] == Float
  91
+              value = value.to_f
  92
+            elsif options[:type] == Date
  93
+              value = Date.parse(value) rescue nil
  94
+            elsif options[:type] == Boolean
  95
+              value = !! value.to_i.nonzero?
  96
+            elsif self.class.associations.include?(attribute)
  97
+              klass = options[:type]
  98
+              value = xml.search(klass.name).collect{|elem| klass.new(elem)}
  99
+              value = nil if value.empty?
  100
+            end
  101
+          ensure
  102
+            self.instance_variable_set("@#{attribute}", value)
  103
+          end     
  104
+        end        
  105
+      end
  106
+      
  107
+      def initialize_with_polymorphism(arg)
  108
+        case arg
  109
+        when String
  110
+          initialize_without_polymorphism(query_by_string(arg))
  111
+        when Integer
  112
+          initialize_without_polymorphism(query_by_id(arg))
  113
+        when Hpricot
  114
+          initialize_without_polymorphism(arg)
  115
+        end
  116
+      end
  117
+     
  118
+      alias_method_chain :initialize, :polymorphism
  119
+      
  120
+    protected
  121
+      def query_by_id(id)
  122
+        xml = self.class.fetch_and_parse(self.class.api_path(self.class.name, nil, nil, id))
  123
+        return xml.at(self.class.name)
  124
+      end
  125
+      
  126
+      def query_by_string(string)
  127
+        xml = self.class.fetch_and_parse(self.class.api_path(self.class.name, nil, :search, :all, string ))
  128
+        return xml.at(self.class.name)
  129
+      end   
  130
+      
  131
+      def query_association_by_id(association, id)
  132
+        klass = "yahoo/music/#{association.to_s.singularize}".camelize.constantize
  133
+        xml = self.query_by_id(id).search(klass.name)
  134
+        return xml.collect{|elem| klass.new(elem)}
  135
+      end   
  136
+    end
  137
+  
  138
+    class Artist    < Base; end
  139
+    class Category  < Base; end
  140
+    class Image     < Base; end
  141
+    class Release   < Base; end
  142
+    class Review     < Base; end
  143
+    class Track     < Base; end
  144
+    class Video     < Base; end
  145
+  end
  146
+end
  147
+
  148
+class Boolean; end
26  lib/yahoo-music/category.rb
... ...
@@ -0,0 +1,26 @@
  1
+# <Category
  2
+#         artistCount = xs:int
  3
+#         hasAudioStation = xs:boolean
  4
+#         hasRadioStation = xs:boolean
  5
+#         hasVideoStation = xs:boolean
  6
+#         id = xs:string
  7
+#         name = xs:string
  8
+#         rating = xs:int
  9
+#         releaseCount = xs:int
  10
+#         trackCount = xs:int
  11
+#         type = ("Genre"|"Theme"|"Era")
  12
+#         videoCount = xs:int
  13
+#         >
  14
+# 
  15
+#     Content: 
  16
+#         ShortDescription?, LongDescription?, Artist*, Station*, Category*
  17
+# </Category>
  18
+
  19
+module Yahoo
  20
+  module Music
  21
+    class Category < Base      
  22
+      attribute :id,    Integer
  23
+      attribute :name,  String
  24
+    end
  25
+  end
  26
+end
35  lib/yahoo-music/release.rb
... ...
@@ -0,0 +1,35 @@
  1
+# <Release
  2
+#         UPC = xs:string
  3
+#         catzillaID = xs:int
  4
+#         explicit = xs:boolean
  5
+#         flags = xs:int
  6
+#         id = xs:string
  7
+#         label = xs:string
  8
+#         rating = xs:int
  9
+#         releaseDate = xs:dateTime
  10
+#         releaseYear = xs:int
  11
+#         rights = xs:int
  12
+#         title = xs:string
  13
+#         typeID = xs:int
  14
+#         >
  15
+# 
  16
+#     Content: 
  17
+#         Image*, Price*, Track*, Artist*, Category*, Fan*, Review*, ItemInfo?
  18
+# </Release>
  19
+
  20
+module Yahoo
  21
+  module Music
  22
+    class Release < Base      
  23
+      attribute :id,          Integer
  24
+      attribute :title,       String
  25
+      attribute :upc,         String,  :matcher => "UPC"
  26
+      attribute :explicit,    Boolean, :matcher => "explicit"
  27
+      attribute :released_on, Date,    :matcher => "releaseDate"
  28
+      
  29
+      attribute :artists,     Artist
  30
+      attribute :categories,  Category
  31
+      attribute :reviews,     Review
  32
+      attribute :tracks,      Track
  33
+    end
  34
+  end
  35
+end
32  lib/yahoo-music/review.rb
... ...
@@ -0,0 +1,32 @@
  1
+# <Review
  2
+#         id = xs:int
  3
+#         publishDate = dateTime
  4
+#         source = xs:string
  5
+#         writer = xs:string
  6
+#         >
  7
+#
  8
+#     Content:
  9
+#         { xs:string }
  10
+# </Review>
  11
+
  12
+module Yahoo
  13
+  module Music
  14
+    class Review < Base      
  15
+      attr_reader :content
  16
+      
  17
+      attribute :id,            Integer
  18
+      attribute :source,        String
  19
+      attribute :published_on,  Date, :matcher => "publishDate"
  20
+      attribute :website,       String
  21
+      
  22
+      def initialize(xml)
  23
+        @content = xml.inner_html
  24
+        super
  25
+      end
  26
+      
  27
+      def to_s
  28
+        self.content
  29
+      end
  30
+    end
  31
+  end
  32
+end
35  lib/yahoo-music/track.rb
... ...
@@ -0,0 +1,35 @@
  1
+# <Track
  2
+#         discNumber = xs:int
  3
+#         duration = xs:int
  4
+#         explicit = xs:boolean
  5
+#         flags = xs:int
  6
+#         id = xs:string
  7
+#         label = xs:string
  8
+#         popularity = xs:int
  9
+#         rating = xs:int
  10
+#         releaseYear = xs:int
  11
+#         rights = xs:int
  12
+#         title = xs:string
  13
+#         >
  14
+# 
  15
+#      Content: 
  16
+#          Image*, Price*, Track*, Artist*, Category*, Fan*, Review*, ItemInfo?
  17
+# </Track>
  18
+
  19
+module Yahoo
  20
+  module Music
  21
+    class Track < Base      
  22
+      attribute :id,           Integer
  23
+      attribute :title,        String
  24
+      attribute :duration,     Integer
  25
+      attribute :explicit,     Boolean
  26
+      
  27
+      attribute :release_year, Integer, :matcher => "releaseYear"
  28
+      attribute :track_number, Integer, :matcher => "trackNumber"
  29
+      attribute :disc_number,  Integer, :matcher => "discNumber"
  30
+      
  31
+      attribute :artists,       Artist
  32
+      attribute :releases,      Release
  33
+    end
  34
+  end
  35
+end
31  lib/yahoo-music/video.rb
... ...
@@ -0,0 +1,31 @@
  1
+# <Video
  2
+#         copyrightYear = xs:int
  3
+#         duration = xs:int
  4
+#         explicit = xs:boolean
  5
+#         flags = xs:int
  6
+#         id = xs:string
  7
+#         label = xs:string
  8
+#         localOnly = xs:boolean
  9
+#         rating = xs:int
  10
+#         rights = xs:int
  11
+#         salesGenre = xs:int
  12
+#         title = xs:string
  13
+#         typeID = xs:int
  14
+#         >
  15
+# 
  16
+#     Content: 
  17
+#         Image*, Artist*, Client*, Category*, Album*, Media*, Bumper?, PaymentLabel?, FlaggedWith*, ItemInfo?, xspf:track?, RecentlyPlayed?
  18
+# </Video>
  19
+
  20
+module Yahoo
  21
+  module Music
  22
+    class Video < Base      
  23
+      attribute :id,        Integer
  24
+      attribute :title,     String
  25
+      attribute :duration,  Integer
  26
+      attribute :explicit,  Boolean
  27
+      
  28
+      attribute :copyright_year, Integer, :matcher => "copyrightYear"      
  29
+    end
  30
+  end
  31
+end
16  test/fixtures/artist.xml
... ...
@@ -0,0 +1,16 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<Artists start="1" count="3" total="3" errorCount="0">
  3
+  <Artist id="33892447" name="Beirut" rating="-1" flags="12943" hotzillaID="1809721513" trackCount="24" website="http://www.beirutband.com/">
  4
+    <Releases>
  5
+      <Release id="34523710" rating="-1" title="Gulag Orkestar" rights="3952" label="Ba Da Bing!" UPC="600197004821" explicit="0" typeID="2" releaseYear="2006" releaseDate="2006-05-09T06:00:00Z" flags="0"/>
  6
+      <Release id="39477375" rating="-1" title="Lon Gisland EP" rights="3952" label="Ba Da Bing!" UPC="600197005224" explicit="0" typeID="2" releaseYear="2007" releaseDate="2007-01-30T06:00:00Z" flags="128"/>
  7
+      <Release id="43462404" rating="-1" title="Pompeii" rights="3952" label="Ba Da Bing!" UPC="600197005217" explicit="0" typeID="4" releaseYear="2007" releaseDate="2007-04-24T06:00:00Z" flags="0"/>
  8
+      <Release id="47216786" rating="-1" title="Elephant Gun" rights="2048" label="Ba Da Bing!" UPC="600197005231" explicit="0" typeID="4" releaseYear="2007" releaseDate="2007-08-28T06:00:00Z" flags="128"/>
  9
+      <Release id="47825734" rating="-1" title="The Flying Club Cup" rights="3952" label="Ba Da Bing!" UPC="600197005521" explicit="0" typeID="2" releaseYear="2007" releaseDate="2007-10-09T05:00:00Z" flags="128"/>
  10
+    </Releases>
  11
+    <ItemInfo>
  12
+      <Relevancy index="6629"/>
  13
+    </ItemInfo>
  14
+  </Artist>
  15
+</Artists>
  16
+<!-- wsapi-ext1.music.mud.yahoo.com compressed/chunked Wed Aug  6 22:36:23 PDT 2008 -->
239  test/fixtures/categories.xml
... ...
@@ -0,0 +1,239 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<Categories>
  3
+  <CategoryType name="genre">
  4
+    <Category rating="-1" id="7318639" name="Blues" videoCount="104" artistCount="413" releaseCount="2809" trackCount="28997" hasVideoStation="1" hasAudioStation="1"/>
  5
+    <Category rating="-1" id="7318649" name="Christian" videoCount="5" artistCount="102" releaseCount="619" trackCount="6347" hasVideoStation="0" hasAudioStation="1">
  6
+      <Category rating="-1" id="40123846" name="1990s Cont. Christian" videoCount="7" artistCount="47" releaseCount="67" trackCount="109" hasVideoStation="1" hasAudioStation="1"/>
  7
+      <Category rating="-1" id="39468748" name="Christian Rock" videoCount="72" artistCount="90" releaseCount="515" trackCount="4484" hasVideoStation="1" hasAudioStation="1"/>
  8
+      <Category rating="-1" id="7318725" name="Contemporary Christian" videoCount="231" artistCount="321" releaseCount="1348" trackCount="11706" hasVideoStation="1" hasAudioStation="1"/>
  9
+      <Category rating="-1" id="7318726" name="Gospel" videoCount="65" artistCount="432" releaseCount="1554" trackCount="14733" hasVideoStation="1" hasAudioStation="1"/>
  10
+      <Category rating="-1" id="39468799" name="Praise and Worship" videoCount="1" artistCount="44" releaseCount="58" trackCount="82" hasVideoStation="0" hasAudioStation="1"/>
  11
+    </Category>
  12
+    <Category rating="-1" id="7321136" name="Classical" videoCount="28" artistCount="407" releaseCount="2108" trackCount="6560" hasVideoStation="1" hasAudioStation="1">
  13
+      <Category rating="-1" id="30958577" name="Classical Crossover" videoCount="49" artistCount="21" releaseCount="39" trackCount="97" hasVideoStation="1" hasAudioStation="1"/>
  14
+      <Category rating="-1" id="30958550" name="Opera" videoCount="0" artistCount="62" releaseCount="14" trackCount="140" hasVideoStation="0" hasAudioStation="1"/>
  15
+    </Category>
  16
+    <Category rating="-1" id="7318827" name="Comedy" videoCount="75" artistCount="316" releaseCount="647" trackCount="8102" hasVideoStation="1" hasAudioStation="1">
  17
+      <Category rating="-1" id="7318828" name="Country Comedy" videoCount="0" artistCount="29" releaseCount="210" trackCount="2545" hasVideoStation="0" hasAudioStation="1"/>
  18
+      <Category rating="-1" id="39469152" name="Naughty Comedy" videoCount="1" artistCount="65" releaseCount="63" trackCount="274" hasVideoStation="1" hasAudioStation="1"/>
  19
+      <Category rating="-1" id="39468834" name="Stand Up Comedy" videoCount="1" artistCount="37" releaseCount="35" trackCount="145" hasVideoStation="1" hasAudioStation="1"/>
  20
+    </Category>
  21
+    <Category rating="-1" id="7318640" name="Country" videoCount="2461" artistCount="705" releaseCount="6639" trackCount="71837" hasVideoStation="1" hasAudioStation="1">
  22
+      <Category rating="-1" id="39468636" name="Americana" videoCount="34" artistCount="237" releaseCount="493" trackCount="5001" hasVideoStation="1" hasAudioStation="1"/>
  23
+      <Category rating="-1" id="39468963" name="Bluegrass" videoCount="42" artistCount="154" releaseCount="307" trackCount="3790" hasVideoStation="1" hasAudioStation="1"/>
  24
+      <Category rating="-1" id="39468738" name="Classic Country" videoCount="6" artistCount="170" releaseCount="892" trackCount="12017" hasVideoStation="0" hasAudioStation="1"/>
  25
+      <Category rating="-1" id="39469132" name="Country" videoCount="521" artistCount="427" releaseCount="1736" trackCount="13190" hasVideoStation="1" hasAudioStation="1"/>
  26
+      <Category rating="-1" id="39468796" name="Greatest Country Hits" videoCount="14" artistCount="124" releaseCount="113" trackCount="203" hasVideoStation="1" hasAudioStation="1"/>
  27
+      <Category rating="-1" id="39468865" name="Soft Country" videoCount="76" artistCount="88" releaseCount="205" trackCount="238" hasVideoStation="1" hasAudioStation="1"/>
  28
+      <Category rating="-1" id="39468705" name="Vintage Country" videoCount="1" artistCount="63" releaseCount="84" trackCount="140" hasVideoStation="0" hasAudioStation="1"/>
  29
+    </Category>
  30
+    <Category rating="-1" id="7318636" name="Electronic/Dance" videoCount="915" artistCount="2015" releaseCount="4942" trackCount="23269" hasVideoStation="1" hasAudioStation="1">
  31
+      <Category rating="-1" id="39468688" name="Chill Out" videoCount="130" artistCount="215" releaseCount="520" trackCount="3602" hasVideoStation="1" hasAudioStation="1"/>
  32
+      <Category rating="-1" id="39468581" name="Dance" videoCount="127" artistCount="119" releaseCount="937" trackCount="6482" hasVideoStation="1" hasAudioStation="1"/>
  33
+      <Category rating="-1" id="7318779" name="Disco" videoCount="56" artistCount="107" releaseCount="371" trackCount="4022" hasVideoStation="1" hasAudioStation="1"/>
  34
+      <Category rating="-1" id="7318656" name="House" videoCount="68" artistCount="403" releaseCount="747" trackCount="4966" hasVideoStation="1" hasAudioStation="1"/>
  35
+      <Category rating="-1" id="7318655" name="Jungle/Drum &amp; Bass" videoCount="22" artistCount="134" releaseCount="153" trackCount="1336" hasVideoStation="1" hasAudioStation="1"/>
  36
+    </Category>
  37
+    <Category rating="-1" id="7318641" name="Folk" videoCount="331" artistCount="535" releaseCount="4243" trackCount="46963" hasVideoStation="1" hasAudioStation="1"/>
  38
+    <Category rating="-1" id="7318638" name="Hip-Hop/Rap" videoCount="2287" artistCount="1231" releaseCount="5889" trackCount="37295" hasVideoStation="1" hasAudioStation="1">
  39
+      <Category rating="-1" id="44649250" name="1980s Hip-Hop" videoCount="116" artistCount="92" releaseCount="635" trackCount="5299" hasVideoStation="1" hasAudioStation="1"/>
  40
+      <Category rating="-1" id="40123848" name="1990s Hip-Hop" videoCount="57" artistCount="96" releaseCount="138" trackCount="178" hasVideoStation="1" hasAudioStation="1"/>
  41
+      <Category rating="-1" id="44649261" name="Alternative Hip-Hop" videoCount="71" artistCount="172" releaseCount="451" trackCount="2887" hasVideoStation="1" hasAudioStation="1"/>
  42
+      <Category rating="-1" id="7318668" name="Dirty South" videoCount="38" artistCount="179" releaseCount="1566" trackCount="9694" hasVideoStation="1" hasAudioStation="1"/>
  43
+      <Category rating="-1" id="7318669" name="East Coast Rap" videoCount="84" artistCount="201" releaseCount="1763" trackCount="12561" hasVideoStation="1" hasAudioStation="1"/>
  44
+      <Category rating="-1" id="7318672" name="Hardcore Rap" videoCount="61" artistCount="317" releaseCount="2794" trackCount="25959" hasVideoStation="1" hasAudioStation="1"/>
  45
+      <Category rating="-1" id="40123865" name="Hip-Hop" videoCount="2352" artistCount="120" releaseCount="1221" trackCount="6371" hasVideoStation="1" hasAudioStation="1"/>
  46
+      <Category rating="-1" id="7318670" name="Mainstream Rap" videoCount="317" artistCount="275" releaseCount="2819" trackCount="18769" hasVideoStation="1" hasAudioStation="1"/>
  47
+      <Category rating="-1" id="7318671" name="Midwest Rap" videoCount="25" artistCount="47" releaseCount="587" trackCount="5236" hasVideoStation="1" hasAudioStation="1"/>
  48
+      <Category rating="-1" id="39468787" name="The Big Jams" videoCount="370" artistCount="180" releaseCount="359" trackCount="606" hasVideoStation="1" hasAudioStation="1"/>
  49
+      <Category rating="-1" id="39468574" name="Underground Hip-Hop" videoCount="36" artistCount="341" releaseCount="1760" trackCount="15354" hasVideoStation="1" hasAudioStation="1"/>
  50
+      <Category rating="-1" id="39469054" name="Urban New Releases" videoCount="7" artistCount="106" releaseCount="164" trackCount="311" hasVideoStation="1" hasAudioStation="1"/>
  51
+      <Category rating="-1" id="7318675" name="West Coast Rap" videoCount="37" artistCount="73" releaseCount="722" trackCount="5928" hasVideoStation="1" hasAudioStation="1"/>
  52
+    </Category>
  53
+    <Category rating="-1" id="7318642" name="Holiday" videoCount="73" artistCount="20" releaseCount="1578" trackCount="16374" hasVideoStation="1" hasAudioStation="1">
  54
+      <Category rating="-1" id="39468951" name="Breaking Up Is Hard" videoCount="0" artistCount="0" releaseCount="0" trackCount="175" hasVideoStation="0" hasAudioStation="1"/>
  55
+      <Category rating="-1" id="39469039" name="Christian Holiday" videoCount="0" artistCount="0" releaseCount="0" trackCount="118" hasVideoStation="0" hasAudioStation="1"/>
  56
+      <Category rating="-1" id="44649267" name="Christmas Classical" videoCount="0" artistCount="0" releaseCount="4" trackCount="151" hasVideoStation="0" hasAudioStation="1"/>
  57
+      <Category rating="-1" id="39468824" name="Comedy Christmas" videoCount="1" artistCount="0" releaseCount="0" trackCount="115" hasVideoStation="0" hasAudioStation="1"/>
  58
+      <Category rating="-1" id="39468811" name="Country Holiday" videoCount="0" artistCount="0" releaseCount="0" trackCount="599" hasVideoStation="0" hasAudioStation="1"/>
  59
+      <Category rating="-1" id="39468740" name="Country Valentine" videoCount="0" artistCount="0" releaseCount="0" trackCount="163" hasVideoStation="0" hasAudioStation="1"/>
  60
+      <Category rating="-1" id="39468812" name="Gospel Holiday" videoCount="0" artistCount="5" releaseCount="3" trackCount="109" hasVideoStation="0" hasAudioStation="1"/>
  61
+      <Category rating="-1" id="39469123" name="Holiday Lounge" videoCount="0" artistCount="0" releaseCount="4" trackCount="215" hasVideoStation="0" hasAudioStation="1"/>
  62
+      <Category rating="-1" id="39468808" name="Jazz Holiday" videoCount="0" artistCount="0" releaseCount="4" trackCount="378" hasVideoStation="0" hasAudioStation="1"/>
  63
+      <Category rating="-1" id="39468814" name="Kidz Holiday" videoCount="0" artistCount="0" releaseCount="0" trackCount="279" hasVideoStation="0" hasAudioStation="1"/>
  64
+      <Category rating="-1" id="39468823" name="Latin Holiday" videoCount="0" artistCount="0" releaseCount="1" trackCount="101" hasVideoStation="0" hasAudioStation="1"/>
  65
+      <Category rating="-1" id="39468582" name="Love Bites" videoCount="0" artistCount="0" releaseCount="0" trackCount="219" hasVideoStation="0" hasAudioStation="1"/>
  66
+      <Category rating="-1" id="39469107" name="Other Holiday" videoCount="0" artistCount="1" releaseCount="47" trackCount="531" hasVideoStation="0" hasAudioStation="1"/>
  67
+      <Category rating="-1" id="39468803" name="Pop Holiday" videoCount="0" artistCount="0" releaseCount="6" trackCount="368" hasVideoStation="0" hasAudioStation="1"/>
  68
+      <Category rating="-1" id="39469143" name="Pop Valentine" videoCount="0" artistCount="0" releaseCount="0" trackCount="110" hasVideoStation="0" hasAudioStation="1"/>
  69
+      <Category rating="-1" id="39468800" name="Rock Holiday" videoCount="5" artistCount="0" releaseCount="3" trackCount="340" hasVideoStation="0" hasAudioStation="1"/>
  70
+      <Category rating="-1" id="39468839" name="Rock Valentine" videoCount="0" artistCount="0" releaseCount="0" trackCount="194" hasVideoStation="0" hasAudioStation="1"/>
  71
+      <Category rating="-1" id="39468826" name="Scrooge Tunes" videoCount="0" artistCount="0" releaseCount="0" trackCount="144" hasVideoStation="0" hasAudioStation="1"/>
  72
+      <Category rating="-1" id="39468807" name="Traditional Christmas" videoCount="1" artistCount="0" releaseCount="3" trackCount="319" hasVideoStation="0" hasAudioStation="1"/>
  73
+      <Category rating="-1" id="39468801" name="Urban Holiday" videoCount="1" artistCount="0" releaseCount="4" trackCount="500" hasVideoStation="0" hasAudioStation="1"/>
  74
+      <Category rating="-1" id="39469142" name="Urban Valentine" videoCount="0" artistCount="0" releaseCount="0" trackCount="348" hasVideoStation="0" hasAudioStation="1"/>
  75
+    </Category>
  76
+    <Category rating="-1" id="7318643" name="Jazz" videoCount="164" artistCount="901" releaseCount="10563" trackCount="89749" hasVideoStation="1" hasAudioStation="1">
  77
+      <Category rating="-1" id="39468850" name="Big Band/Swing" videoCount="6" artistCount="173" releaseCount="1550" trackCount="9967" hasVideoStation="0" hasAudioStation="1"/>
  78
+      <Category rating="-1" id="39468791" name="Classic Vocal Standards" videoCount="3" artistCount="87" releaseCount="1479" trackCount="20663" hasVideoStation="1" hasAudioStation="1"/>
  79
+      <Category rating="-1" id="7318696" name="Fusion" videoCount="8" artistCount="160" releaseCount="718" trackCount="3505" hasVideoStation="1" hasAudioStation="1"/>
  80
+      <Category rating="-1" id="39468967" name="Jazz Bebop" videoCount="0" artistCount="68" releaseCount="1937" trackCount="18143" hasVideoStation="0" hasAudioStation="1"/>
  81
+      <Category rating="-1" id="39469134" name="Jazz Classics" videoCount="0" artistCount="78" releaseCount="160" trackCount="350" hasVideoStation="0" hasAudioStation="1"/>
  82
+      <Category rating="-1" id="7318697" name="Latin Jazz" videoCount="1" artistCount="135" releaseCount="774" trackCount="4141" hasVideoStation="0" hasAudioStation="1"/>
  83
+      <Category rating="-1" id="7318702" name="Modern Jazz" videoCount="0" artistCount="358" releaseCount="2707" trackCount="20035" hasVideoStation="0" hasAudioStation="1"/>
  84
+      <Category rating="-1" id="39468873" name="New Vocal Standards" videoCount="20" artistCount="74" releaseCount="134" trackCount="376" hasVideoStation="1" hasAudioStation="1"/>
  85
+      <Category rating="-1" id="7318699" name="Smooth Jazz" videoCount="63" artistCount="153" releaseCount="866" trackCount="4626" hasVideoStation="1" hasAudioStation="1"/>
  86
+      <Category rating="-1" id="39469081" name="Vocal Jazz" videoCount="31" artistCount="59" releaseCount="1274" trackCount="18018" hasVideoStation="0" hasAudioStation="1"/>
  87
+    </Category>
  88
+    <Category rating="-1" id="7318710" name="Kids" videoCount="25" artistCount="116" releaseCount="624" trackCount="2178" hasVideoStation="1" hasAudioStation="1">
  89
+      <Category rating="-1" id="39468764" name="Kidz Pop" videoCount="53" artistCount="89" releaseCount="173" trackCount="443" hasVideoStation="1" hasAudioStation="1"/>
  90
+      <Category rating="-1" id="39468813" name="Kidz Rock" videoCount="56" artistCount="95" releaseCount="135" trackCount="219" hasVideoStation="1" hasAudioStation="1"/>
  91
+      <Category rating="-1" id="39468769" name="Lil' Kidz Tunes" videoCount="0" artistCount="76" releaseCount="75" trackCount="289" hasVideoStation="0" hasAudioStation="1"/>
  92
+      <Category rating="-1" id="39468785" name="Lullaby Tunes" videoCount="2" artistCount="60" releaseCount="66" trackCount="182" hasVideoStation="1" hasAudioStation="1"/>
  93
+    </Category>
  94
+    <Category rating="-1" id="7318644" name="Latin" videoCount="1196" artistCount="1233" releaseCount="7554" trackCount="19028" hasVideoStation="1" hasAudioStation="1">
  95
+      <Category rating="-1" id="39468942" name="Classic Latin" videoCount="3" artistCount="65" releaseCount="184" trackCount="617" hasVideoStation="0" hasAudioStation="1"/>
  96
+      <Category rating="-1" id="39468771" name="Pop Latino" videoCount="415" artistCount="399" releaseCount="2427" trackCount="4921" hasVideoStation="1" hasAudioStation="1"/>
  97
+      <Category rating="-1" id="39468774" name="Rock En Español" videoCount="63" artistCount="144" releaseCount="695" trackCount="3597" hasVideoStation="1" hasAudioStation="1"/>
  98
+      <Category rating="-1" id="39468772" name="Salsa Cien Por Ciento" videoCount="2" artistCount="118" releaseCount="920" trackCount="2523" hasVideoStation="1" hasAudioStation="1"/>
  99
+      <Category rating="-1" id="39468773" name="Tejano" videoCount="2" artistCount="96" releaseCount="871" trackCount="4000" hasVideoStation="0" hasAudioStation="1"/>
  100
+    </Category>
  101
+    <Category rating="-1" id="7318645" name="Miscellaneous" videoCount="15" artistCount="89" releaseCount="715" trackCount="6629" hasVideoStation="1" hasAudioStation="1">
  102
+      <Category rating="-1" id="39469120" name="Karaoke" videoCount="9" artistCount="1" releaseCount="1074" trackCount="6362" hasVideoStation="1" hasAudioStation="1"/>
  103
+    </Category>
  104
+    <Category rating="-1" id="7318646" name="New Age" videoCount="38" artistCount="286" releaseCount="1022" trackCount="6257" hasVideoStation="1" hasAudioStation="1"/>
  105
+    <Category rating="-1" id="7318647" name="Pop" videoCount="3149" artistCount="1079" releaseCount="6251" trackCount="45861" hasVideoStation="1" hasAudioStation="1">
  106
+      <Category rating="-1" id="39469063" name="Brit Pop" videoCount="98" artistCount="41" releaseCount="483" trackCount="4363" hasVideoStation="1" hasAudioStation="1"/>
  107
+      <Category rating="-1" id="39468794" name="Greatest Pop Ballads" videoCount="28" artistCount="87" releaseCount="111" trackCount="119" hasVideoStation="1" hasAudioStation="1"/>
  108
+      <Category rating="-1" id="7318842" name="New Wave" videoCount="215" artistCount="254" releaseCount="1341" trackCount="13539" hasVideoStation="1" hasAudioStation="1"/>
  109
+      <Category rating="-1" id="7318718" name="Soft Pop" videoCount="335" artistCount="328" releaseCount="2894" trackCount="27453" hasVideoStation="1" hasAudioStation="1"/>
  110
+      <Category rating="-1" id="39468930" name="Teen Pop" videoCount="119" artistCount="68" releaseCount="590" trackCount="3744" hasVideoStation="1" hasAudioStation="1"/>
  111
+      <Category rating="-1" id="39468566" name="Today's Big Hits" videoCount="169" artistCount="150" releaseCount="247" trackCount="150" hasVideoStation="1" hasAudioStation="1"/>
  112
+    </Category>
  113
+    <Category rating="-1" id="7318648" name="R&amp;B" videoCount="1940" artistCount="748" releaseCount="6235" trackCount="48203" hasVideoStation="1" hasAudioStation="1">
  114
+      <Category rating="-1" id="39469056" name="Adult R&amp;B" videoCount="217" artistCount="364" releaseCount="957" trackCount="1604" hasVideoStation="1" hasAudioStation="1"/>
  115
+      <Category rating="-1" id="39469136" name="Classic Soul" videoCount="114" artistCount="347" releaseCount="4703" trackCount="57946" hasVideoStation="1" hasAudioStation="1"/>
  116
+      <Category rating="-1" id="39468744" name="Doo Wop" videoCount="0" artistCount="105" releaseCount="377" trackCount="6025" hasVideoStation="0" hasAudioStation="1"/>
  117
+      <Category rating="-1" id="39468739" name="Funk" videoCount="65" artistCount="96" releaseCount="1571" trackCount="15345" hasVideoStation="1" hasAudioStation="1"/>
  118
+      <Category rating="-1" id="40123867" name="Men of R&amp;B" videoCount="109" artistCount="130" releaseCount="400" trackCount="812" hasVideoStation="1" hasAudioStation="1"/>
  119
+      <Category rating="-1" id="39469076" name="Motown" videoCount="2" artistCount="24" releaseCount="746" trackCount="10596" hasVideoStation="0" hasAudioStation="1"/>
  120
+      <Category rating="-1" id="39468790" name="Neo Soul" videoCount="26" artistCount="55" releaseCount="299" trackCount="1833" hasVideoStation="1" hasAudioStation="1"/>
  121
+      <Category rating="-1" id="39469085" name="New Jack Swing" videoCount="26" artistCount="50" releaseCount="479" trackCount="2515" hasVideoStation="1" hasAudioStation="1"/>
  122
+      <Category rating="-1" id="7318723" name="Quiet Storm" videoCount="250" artistCount="98" releaseCount="1169" trackCount="8378" hasVideoStation="1" hasAudioStation="1"/>
  123
+      <Category rating="-1" id="39469131" name="R&amp;B" videoCount="1064" artistCount="468" releaseCount="4302" trackCount="27617" hasVideoStation="1" hasAudioStation="1"/>
  124
+      <Category rating="-1" id="40123871" name="Women Of R&amp;B" videoCount="137" artistCount="97" releaseCount="292" trackCount="712" hasVideoStation="1" hasAudioStation="1"/>
  125
+    </Category>
  126
+    <Category rating="-1" id="7318637" name="Reggae" videoCount="243" artistCount="328" releaseCount="3292" trackCount="24403" hasVideoStation="1" hasAudioStation="1">
  127
+      <Category rating="-1" id="39468733" name="Reggae Dancehall" videoCount="32" artistCount="102" releaseCount="1276" trackCount="7532" hasVideoStation="1" hasAudioStation="1"/>
  128
+      <Category rating="-1" id="39468632" name="Ska" videoCount="6" artistCount="73" releaseCount="394" trackCount="4998" hasVideoStation="1" hasAudioStation="1"/>
  129
+      <Category rating="-1" id="7318811" name="Soca" videoCount="8" artistCount="31" releaseCount="139" trackCount="982" hasVideoStation="1" hasAudioStation="1"/>
  130
+    </Category>
  131
+    <Category rating="-1" id="7318650" name="Rock" videoCount="6647" artistCount="3019" releaseCount="15052" trackCount="135919" hasVideoStation="1" hasAudioStation="1">
  132
+      <Category rating="-1" id="7318736" name="Adult Alternative" videoCount="3224" artistCount="1201" releaseCount="4360" trackCount="31930" hasVideoStation="1" hasAudioStation="1"/>
  133
+      <Category rating="-1" id="39469164" name="Alternative Rock" videoCount="4565" artistCount="2286" releaseCount="6398" trackCount="50259" hasVideoStation="1" hasAudioStation="1"/>
  134
+      <Category rating="-1" id="7318876" name="Avant-Garde Rock" videoCount="143" artistCount="63" releaseCount="566" trackCount="6056" hasVideoStation="1" hasAudioStation="1"/>
  135
+      <Category rating="-1" id="39468591" name="Brit Rock" videoCount="267" artistCount="106" releaseCount="1393" trackCount="14283" hasVideoStation="1" hasAudioStation="1"/>
  136
+      <Category rating="-1" id="7318731" name="Classic Rock" videoCount="661" artistCount="598" releaseCount="4546" trackCount="53161" hasVideoStation="1" hasAudioStation="1"/>
  137
+      <Category rating="-1" id="39468805" name="Cool As Folk" videoCount="64" artistCount="158" releaseCount="314" trackCount="890" hasVideoStation="1" hasAudioStation="1"/>
  138
+      <Category rating="-1" id="39468784" name="Emo" videoCount="53" artistCount="116" releaseCount="427" trackCount="3452" hasVideoStation="1" hasAudioStation="1"/>
  139
+      <Category rating="-1" id="39468683" name="Garage Rock" videoCount="43" artistCount="52" releaseCount="147" trackCount="1469" hasVideoStation="1" hasAudioStation="1"/>
  140
+      <Category rating="-1" id="39468863" name="Goth Rock" videoCount="28" artistCount="109" releaseCount="215" trackCount="2431" hasVideoStation="1" hasAudioStation="1"/>
  141
+      <Category rating="-1" id="39468867" name="Grunge" videoCount="33" artistCount="33" releaseCount="350" trackCount="4812" hasVideoStation="1" hasAudioStation="1"/>
  142
+      <Category rating="-1" id="39468709" name="Hair Flare" videoCount="226" artistCount="48" releaseCount="97" trackCount="176" hasVideoStation="1" hasAudioStation="1"/>
  143
+      <Category rating="-1" id="7318732" name="Hard Rock" videoCount="1752" artistCount="732" releaseCount="2388" trackCount="22468" hasVideoStation="1" hasAudioStation="1"/>
  144
+      <Category rating="-1" id="7318863" name="Indie Rock" videoCount="1000" artistCount="1979" releaseCount="4684" trackCount="32874" hasVideoStation="1" hasAudioStation="1"/>
  145
+      <Category rating="-1" id="39468789" name="Jam Bands" videoCount="27" artistCount="36" releaseCount="359" trackCount="4452" hasVideoStation="1" hasAudioStation="1"/>
  146
+      <Category rating="-1" id="7318734" name="Mainstream Rock" videoCount="309" artistCount="698" releaseCount="3224" trackCount="31489" hasVideoStation="1" hasAudioStation="1"/>
  147
+      <Category rating="-1" id="7318733" name="Metal" videoCount="382" artistCount="727" releaseCount="2720" trackCount="23411" hasVideoStation="1" hasAudioStation="1"/>
  148
+      <Category rating="-1" id="39468788" name="New School Punk Rock" videoCount="76" artistCount="96" releaseCount="177" trackCount="769" hasVideoStation="1" hasAudioStation="1"/>
  149
+      <Category rating="-1" id="39469135" name="Old School Punk Rock" videoCount="84" artistCount="738" releaseCount="2391" trackCount="24893" hasVideoStation="1" hasAudioStation="1"/>
  150
+      <Category rating="-1" id="39468818" name="Power Ballads" videoCount="11" artistCount="59" releaseCount="107" trackCount="129" hasVideoStation="1" hasAudioStation="1"/>
  151
+      <Category rating="-1" id="7318808" name="Powerpop" videoCount="117" artistCount="89" releaseCount="594" trackCount="7416" hasVideoStation="1" hasAudioStation="1"/>
  152
+      <Category rating="-1" id="39468876" name="Progressive Rock" videoCount="80" artistCount="50" releaseCount="399" trackCount="4446" hasVideoStation="1" hasAudioStation="1"/>
  153
+      <Category rating="-1" id="39469083" name="Rap-Rock" videoCount="76" artistCount="44" releaseCount="121" trackCount="258" hasVideoStation="1" hasAudioStation="1"/>
  154
+      <Category rating="-1" id="39469077" name="Rockabilly" videoCount="9" artistCount="47" releaseCount="623" trackCount="11793" hasVideoStation="1" hasAudioStation="1"/>
  155
+      <Category rating="-1" id="39468708" name="Soft Rock" videoCount="44" artistCount="55" releaseCount="838" trackCount="7597" hasVideoStation="1" hasAudioStation="1"/>
  156
+      <Category rating="-1" id="39469079" name="Southern Rock" videoCount="5" artistCount="33" releaseCount="302" trackCount="3791" hasVideoStation="1" hasAudioStation="1"/>
  157
+      <Category rating="-1" id="7318794" name="Surf Rock" videoCount="3" artistCount="43" releaseCount="33" trackCount="429" hasVideoStation="1" hasAudioStation="1"/>
  158
+      <Category rating="-1" id="39468968" name="The Coffeehouse" videoCount="331" artistCount="433" releaseCount="692" trackCount="1196" hasVideoStation="1" hasAudioStation="1"/>
  159
+      <Category rating="-1" id="36674374" name="Who's Next?" videoCount="213" artistCount="259" releaseCount="329" trackCount="586" hasVideoStation="1" hasAudioStation="1"/>
  160
+    </Category>
  161
+    <Category rating="-1" id="7318651" name="Shows &amp; Movies" videoCount="80" artistCount="138" releaseCount="756" trackCount="3828" hasVideoStation="1" hasAudioStation="1">
  162
+      <Category rating="-1" id="39468827" name="Classic Broadway" videoCount="0" artistCount="106" releaseCount="58" trackCount="149" hasVideoStation="0" hasAudioStation="1"/>
  163
+      <Category rating="-1" id="39468971" name="Film Scores" videoCount="1" artistCount="27" releaseCount="307" trackCount="3717" hasVideoStation="0" hasAudioStation="1"/>
  164
+      <Category rating="-1" id="39468829" name="Modern Broadway" videoCount="11" artistCount="191" releaseCount="220" trackCount="722" hasVideoStation="1" hasAudioStation="1"/>
  165
+      <Category rating="-1" id="39468620" name="Show Tunes" videoCount="8" artistCount="140" releaseCount="116" trackCount="190" hasVideoStation="1" hasAudioStation="1"/>
  166
+      <Category rating="-1" id="39469126" name="Soundtracks" videoCount="11" artistCount="55" releaseCount="4833" trackCount="53808" hasVideoStation="1" hasAudioStation="1"/>
  167
+    </Category>
  168
+    <Category rating="-1" id="7318652" name="World" videoCount="148" artistCount="470" releaseCount="1972" trackCount="12250" hasVideoStation="1" hasAudioStation="1">
  169
+      <Category rating="-1" id="39468751" name="African" videoCount="6" artistCount="70" releaseCount="79" trackCount="998" hasVideoStation="1" hasAudioStation="1"/>
  170
+      <Category rating="-1" id="39468754" name="Asian" videoCount="14" artistCount="124" releaseCount="117" trackCount="826" hasVideoStation="0" hasAudioStation="1"/>
  171
+      <Category rating="-1" id="39469067" name="Australian" videoCount="47" artistCount="30" releaseCount="80" trackCount="218" hasVideoStation="1" hasAudioStation="1"/>
  172
+      <Category rating="-1" id="39468857" name="Brazilian" videoCount="0" artistCount="65" releaseCount="390" trackCount="3533" hasVideoStation="0" hasAudioStation="1"/>
  173
+      <Category rating="-1" id="39468822" name="Cajun/Zydeco" videoCount="2" artistCount="50" releaseCount="251" trackCount="3242" hasVideoStation="1" hasAudioStation="1"/>
  174
+      <Category rating="-1" id="39469068" name="Caribbean" videoCount="0" artistCount="69" releaseCount="208" trackCount="3348" hasVideoStation="0" hasAudioStation="1"/>
  175
+      <Category rating="-1" id="39469069" name="Celtic" videoCount="13" artistCount="106" releaseCount="122" trackCount="1545" hasVideoStation="1" hasAudioStation="1"/>
  176
+      <Category rating="-1" id="39469072" name="India" videoCount="0" artistCount="33" releaseCount="40" trackCount="266" hasVideoStation="0" hasAudioStation="1"/>
  177
+      <Category rating="-1" id="39469073" name="Klezmer" videoCount="0" artistCount="35" releaseCount="64" trackCount="1019" hasVideoStation="0" hasAudioStation="1"/>
  178
+      <Category rating="-1" id="39469074" name="Middle Eastern" videoCount="4" artistCount="46" releaseCount="92" trackCount="379" hasVideoStation="0" hasAudioStation="1"/>
  179
+      <Category rating="-1" id="39469078" name="South Pacific" videoCount="0" artistCount="26" releaseCount="11" trackCount="212" hasVideoStation="0" hasAudioStation="1"/>
  180
+      <Category rating="-1" id="39469080" name="Spanish" videoCount="1" artistCount="35" releaseCount="28" trackCount="737" hasVideoStation="1" hasAudioStation="1"/>
  181
+      <Category rating="-1" id="39468775" name="World Beat" videoCount="9" artistCount="39" releaseCount="201" trackCount="2059" hasVideoStation="0" hasAudioStation="1"/>
  182
+    </Category>
  183
+  </CategoryType>
  184
+  <CategoryType name="theme">
  185
+    <Category rating="-1" id="44649273" name="Themes" videoCount="0" artistCount="0" releaseCount="0" trackCount="0" hasVideoStation="0" hasAudioStation="1">
  186
+      <Category rating="-1" id="53145927" name="2008 Grammy® Nominees" videoCount="92" artistCount="0" releaseCount="0" trackCount="126" hasVideoStation="1" hasAudioStation="1"/>
  187
+      <Category rating="-1" id="39468569" name="Beatles Legacy" videoCount="4" artistCount="113" releaseCount="144" trackCount="236" hasVideoStation="1" hasAudioStation="1"/>
  188
+      <Category rating="-1" id="60760093" name="Bonnaroo" videoCount="161" artistCount="0" releaseCount="0" trackCount="271" hasVideoStation="1" hasAudioStation="1"/>
  189
+      <Category rating="-1" id="39469011" name="Cover Art" videoCount="28" artistCount="239" releaseCount="276" trackCount="457" hasVideoStation="1" hasAudioStation="1"/>
  190
+      <Category rating="-1" id="39469017" name="Gay Club Mix" videoCount="48" artistCount="214" releaseCount="299" trackCount="255" hasVideoStation="1" hasAudioStation="1"/>
  191
+      <Category rating="-1" id="39469064" name="Led Zeppelin Legacy" videoCount="29" artistCount="33" releaseCount="163" trackCount="604" hasVideoStation="1" hasAudioStation="1"/>
  192
+      <Category rating="-1" id="39468905" name="Lite Office Music" videoCount="46" artistCount="139" releaseCount="229" trackCount="266" hasVideoStation="1" hasAudioStation="1"/>
  193
+      <Category rating="-1" id="39468776" name="Love Songs" videoCount="110" artistCount="141" releaseCount="202" trackCount="226" hasVideoStation="1" hasAudioStation="1"/>
  194
+      <Category rating="-1" id="39469031" name="Mardi Gras" videoCount="2" artistCount="71" releaseCount="94" trackCount="190" hasVideoStation="1" hasAudioStation="1"/>
  195
+      <Category rating="-1" id="39468577" name="Martini Lounge" videoCount="25" artistCount="60" releaseCount="242" trackCount="3036" hasVideoStation="1" hasAudioStation="1"/>
  196
+      <Category rating="-1" id="39468843" name="Meditation" videoCount="0" artistCount="88" releaseCount="46" trackCount="309" hasVideoStation="0" hasAudioStation="1"/>
  197
+      <Category rating="-1" id="39469059" name="Mood Swing" videoCount="19" artistCount="85" releaseCount="119" trackCount="238" hasVideoStation="1" hasAudioStation="1"/>
  198
+      <Category rating="-1" id="40476331" name="Nissan Live Sets: Artists" videoCount="392" artistCount="0" releaseCount="0" trackCount="0" hasVideoStation="1" hasAudioStation="1"/>
  199
+      <Category rating="-1" id="40123774" name="Pet Sounds" videoCount="0" artistCount="0" releaseCount="0" trackCount="271" hasVideoStation="0" hasAudioStation="1"/>
  200
+      <Category rating="-1" id="39469016" name="Video Games" videoCount="19" artistCount="92" releaseCount="78" trackCount="119" hasVideoStation="1" hasAudioStation="1"/>
  201
+      <Category rating="-1" id="37949764" name="Video Premieres" videoCount="170" artistCount="0" releaseCount="0" trackCount="0" hasVideoStation="1" hasAudioStation="1"/>
  202
+    </Category>
  203
+  </CategoryType>
  204
+  <CategoryType name="era">
  205
+    <Category rating="-1" id="44649268" name="Eras" videoCount="0" artistCount="0" releaseCount="0" trackCount="0" hasVideoStation="0" hasAudioStation="1">
  206
+      <Category rating="-1" id="40123448" name="1950s Country" videoCount="1" artistCount="40" releaseCount="59" trackCount="242" hasVideoStation="1" hasAudioStation="1"/>
  207
+      <Category rating="-1" id="40123782" name="1950s Rock" videoCount="0" artistCount="52" releaseCount="58" trackCount="106" hasVideoStation="0" hasAudioStation="1"/>
  208
+      <Category rating="-1" id="40123784" name="1960s Country" videoCount="0" artistCount="15" releaseCount="38" trackCount="211" hasVideoStation="0" hasAudioStation="1"/>
  209
+      <Category rating="-1" id="40123785" name="1960s Pop" videoCount="1" artistCount="109" releaseCount="100" trackCount="178" hasVideoStation="1" hasAudioStation="1"/>
  210
+      <Category rating="-1" id="40123786" name="1960s Rock" videoCount="3" artistCount="34" releaseCount="75" trackCount="298" hasVideoStation="1" hasAudioStation="1"/>
  211
+      <Category rating="-1" id="40123788" name="1970s Country" videoCount="1" artistCount="60" releaseCount="97" trackCount="256" hasVideoStation="1" hasAudioStation="1"/>
  212
+      <Category rating="-1" id="40123829" name="1970s Rock" videoCount="1" artistCount="78" releaseCount="111" trackCount="696" hasVideoStation="1" hasAudioStation="1"/>
  213
+      <Category rating="-1" id="40123830" name="1970s Soft Pop" videoCount="2" artistCount="214" releaseCount="373" trackCount="632" hasVideoStation="1" hasAudioStation="1"/>
  214
+      <Category rating="-1" id="40123832" name="1970s Soul" videoCount="1" artistCount="131" releaseCount="166" trackCount="384" hasVideoStation="1" hasAudioStation="1"/>
  215
+      <Category rating="-1" id="40123834" name="1980s Alternative" videoCount="2" artistCount="96" releaseCount="134" trackCount="146" hasVideoStation="0" hasAudioStation="1"/>
  216
+      <Category rating="-1" id="40123835" name="1980s Country" videoCount="0" artistCount="39" releaseCount="55" trackCount="74" hasVideoStation="0" hasAudioStation="1"/>
  217
+      <Category rating="-1" id="40123836" name="1980s Dance Party" videoCount="16" artistCount="74" releaseCount="88" trackCount="107" hasVideoStation="1" hasAudioStation="1"/>
  218
+      <Category rating="-1" id="40123838" name="1980s Love Songs" videoCount="0" artistCount="0" releaseCount="0" trackCount="189" hasVideoStation="0" hasAudioStation="1"/>
  219
+      <Category rating="-1" id="40123839" name="1980s Pop" videoCount="36" artistCount="104" releaseCount="134" trackCount="213" hasVideoStation="1" hasAudioStation="1"/>
  220
+      <Category rating="-1" id="40123840" name="1980s R&amp;B" videoCount="25" artistCount="86" releaseCount="158" trackCount="344" hasVideoStation="1" hasAudioStation="1"/>
  221
+      <Category rating="-1" id="40123841" name="1980s Rock" videoCount="53" artistCount="110" releaseCount="267" trackCount="520" hasVideoStation="1" hasAudioStation="1"/>
  222
+      <Category rating="-1" id="40123842" name="1980s Soft Pop" videoCount="13" artistCount="82" releaseCount="102" trackCount="126" hasVideoStation="1" hasAudioStation="1"/>
  223
+      <Category rating="-1" id="40123843" name="1980s Soft Rock" videoCount="14" artistCount="104" releaseCount="175" trackCount="241" hasVideoStation="1" hasAudioStation="1"/>
  224
+      <Category rating="-1" id="40123845" name="1990s Alternative" videoCount="325" artistCount="259" releaseCount="460" trackCount="803" hasVideoStation="1" hasAudioStation="1"/>
  225
+      <Category rating="-1" id="40123847" name="1990s Country" videoCount="21" artistCount="73" releaseCount="133" trackCount="176" hasVideoStation="1" hasAudioStation="1"/>
  226
+      <Category rating="-1" id="40123849" name="1990s Pop" videoCount="98" artistCount="155" releaseCount="220" trackCount="306" hasVideoStation="1" hasAudioStation="1"/>
  227
+      <Category rating="-1" id="40123850" name="1990s R&amp;B" videoCount="39" artistCount="79" releaseCount="114" trackCount="141" hasVideoStation="1" hasAudioStation="1"/>
  228
+      <Category rating="-1" id="40123851" name="1990s Rock" videoCount="118" artistCount="100" releaseCount="167" trackCount="260" hasVideoStation="1" hasAudioStation="1"/>
  229
+      <Category rating="-1" id="40123852" name="1990s Soft Pop" videoCount="39" artistCount="78" releaseCount="96" trackCount="110" hasVideoStation="1" hasAudioStation="1"/>
  230
+      <Category rating="-1" id="40123853" name="1990s Soft Rock" videoCount="51" artistCount="88" releaseCount="133" trackCount="176" hasVideoStation="1" hasAudioStation="1"/>
  231
+      <Category rating="-1" id="44649263" name="Big Hits Of The '60s" videoCount="5" artistCount="101" releaseCount="153" trackCount="238" hasVideoStation="1" hasAudioStation="1"/>
  232
+      <Category rating="-1" id="44649264" name="Big Hits Of The '70s" videoCount="4" artistCount="195" releaseCount="341" trackCount="527" hasVideoStation="1" hasAudioStation="1"/>
  233
+      <Category rating="-1" id="44649265" name="Big Hits Of The '80s" videoCount="381" artistCount="248" releaseCount="350" trackCount="549" hasVideoStation="1" hasAudioStation="1"/>
  234
+      <Category rating="-1" id="44649266" name="Big Hits Of The '90s" videoCount="186" artistCount="187" releaseCount="265" trackCount="354" hasVideoStation="1" hasAudioStation="1"/>
  235
+    </Category>
  236
+    <Category rating="-1" id="39468724" name="Oldies" videoCount="20" artistCount="195" releaseCount="385" trackCount="1063" hasVideoStation="1" hasAudioStation="1"/>
  237
+  </CategoryType>
  238
+</Categories>
  239
+<!-- wsapi-ext2.music.mud.yahoo.com compressed/chunked Thu Aug  7 16:21:34 PDT 2008 -->
28  test/fixtures/release.xml
... ...
@@ -0,0 +1,28 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<Releases start="1" count="1" total="1" errorCount="0">
  3
+  <Release id="39477375" rating="-1" title="Lon Gisland EP" rights="3952" label="Ba Da Bing!" UPC="600197005224" explicit="0" typeID="2" releaseYear="2007" releaseDate="2007-01-30T06:00:00Z" flags="128">
  4
+    <Track id="39487778" rating="-1" title="Elephant Gun" explicit="0" flags="0" duration="0" releaseYear="2007" popularity="3" rights="0" discNumber="1" trackNumber="1" label="Ba Da Bing!"/>
  5
+    <Track id="39484984" rating="-1" title="My Family's Role In The World Revolution" explicit="0" flags="0" duration="0" releaseYear="2007" popularity="3" rights="0" discNumber="1" trackNumber="2" label="Ba Da Bing!"/>
  6
+    <Track id="39479131" rating="-1" title="Scenic World (Version)" explicit="0" flags="0" duration="0" releaseYear="2007" popularity="3" rights="0" discNumber="1" trackNumber="3" label="Ba Da Bing!"/>
  7
+    <Track id="39482223" rating="-1" title="The Long Island Sound" explicit="0" flags="0" duration="0" releaseYear="2007" popularity="3" rights="0" discNumber="1" trackNumber="4" label="Ba Da Bing!"/>
  8
+    <Track id="39481724" rating="-1" title="Carousels" explicit="0" flags="0" duration="0" releaseYear="2007" popularity="3" rights="0" discNumber="1" trackNumber="5" label="Ba Da Bing!"/>
  9
+    <Review id="9990000" publishDate="01/31/2007" source="Pitchfork Media" writer="Brandon Stosuy">After the wild success of Gulag Orkestar, an album described (and derided) time and again as indie rock meets Balkan brass, authenticity becomes an issue in just about every Beirut review. Whether labeled "Gypsy Rock," Neutral Milk Hotel Jr., or flat-out village pillaging, Zach Condon's approach to songwriting's been questioned: Yup, the 20-year-old is from New Mexico and currently lives in New York. Yeah, he's a kid. So, based on that information, just what should his band sound like? In recent interviews Condon's discussed his interest in French pop and chanson. While that sound's yet to work its way into Beirut, this new EP includes some important upgrades.
  10
+Moving from his solo, Jeremy Barnes-accented bedroom recordings, Condon's now part of an eight-piece band. Smart move. Gulag showed promise and also limitations: In retrospect, the most intriguing sounds often amounted to ambient pastiche. Pretty but vacant. Now, a solid, pulsing group of players fleshing-out his songs, Condon opens to something less paint-by-numbers static-- it's more alive.
  11
+He shows, albeit briefly, that he can write songs without, as a friend called it, "that Beirut thing"-- i.e., not everything needs a quasi-Neutral Milk Hotel horn swell. But, note the subtle echo of On Avery Island in Lon Gisland, on which he even pokes fun at charges of cultural appropriation, transforming hairspray and pizza joints into foreign territory. Touché! Tellingly, the cover painting uses a collage technique to transport the band to a scene of black-and-white historical figures afloat in a green, green river.
  12
+It's a tiny offering, a 16-minute stopgap before the sophomore full-length scheduled for this fall. (The EP's been released in Europe as a part of Gulag Orkestar and as a one-side 12" by Chouette.) There are three new songs, a new incidental instrumental that echoes its neighbors, and a full-band remake of "Scenic World".
  13
+Opener "Elephant Gun" begins with that familiar ukulele sound and Condon giving his critics enough rope to hang themselves: "If I was young, I'd flee this town/ I'd bury my dreams underground." He's young... get over it. The song has joyousness to it-- it feels less downcast, nostalgic or mournful than the previous material; it's somehow more authentic for that. It's stately and deep, bottomed out with marching band drums, Condon's soaring vocals quaver. At the end, the track shifts gears, drifting into another flavor of accordion and horn.
  14
+A waltzing "Carousels" takes the listener to Coney Island with Morrissey to "watch the faces go 'round." Here, there's a whole lot of group singing. Musically, the repeated motifs are nice, showing Condon unafraid to really open up and play. A sound of water floats in the background-- but when you listen closer, it could also be the distant bustle of the city. It's hard to tell. Here, sounds are never clear-cut.
  15
+The incidental pieces are small but effective. "My Family's Role in the World Revolution", a polka piano rave-up, is an instrumental given signs of life with laughs and a sighing producer. Again, it's upbeat, opening up a riotous saw duster with Charlie Brown piano, glockenspiel, and martial beats. Tossed off, sure, but fun.
  16
+The other instrumental, "The Long Island Sound" plays on sound (something you hear, the physical space where you get wet, salt and fresh water mixing it up). You can make out water, or whatever, in the background as well as an echo of "Elephant Gun", an accordion and bass-trumpet reprise. It very much feels like it's coming over a wire recorder á la the Microphones. Like the other piece, it's a swatch of sound, another bit in the collage.
  17
+Most interesting is the band's new take on "Scenic World". For Gulag, it was the song that justifiably snagged Magnetic Fields comparisons. That cute lilt's been replaced with a slower, statelier unfurl: Condon comports himself in less bubbly way and any cartoonish residuals disappear in the slower pace. Also, tapping drum sticks are placed upfront and become a sort of undulating Indian percussion background; the original's horn parts are doubled on violin and accordion. Basically, you're hearing an older Beirut tuned played by a group, offering the listener a sense of community, rather than some kid alone in his room cuddling his 4-track. It's how this music should be experienced.
  18
+Lon Gisland marks a positive progression-- in these 16 minutes Condon has shown that, yes, there are songs behind the international flavors, that his work would be interesting even if kept the trumpet at home. It's clear, too, just how much age and gravity he holds in his voice and not just the sound around him. Most important of all? It seems Condon's getting all this-- by embracing the developments, he's started to go beyond chewing the scenery to, well, actually living in it.</Review>
  19
+    <Artist id="33892447" name="Beirut" rating="-1"/>
  20
+    <ItemInfo>
  21
+      <Relevancy index="8998"/>
  22
+    </ItemInfo>
  23
+  </Release>
  24
+  <SpellResults start="1" count="1" total="1">
  25
+    <SpellResult token="n-2361100218_q-W00WJ47uynkxDOuvtIfqgwAAAA@@" suggestion="long island ep"/>
  26
+  </SpellResults>
  27
+</Releases>
  28
+<!-- wsapi-ext1.music.mud.yahoo.com compressed/chunked Thu Aug  7 15:15:40 PDT 2008 -->
9  test/test_helper.rb
... ...
@@ -1,5 +1,12 @@
  1
+require 'rubygems'
  2
+gem 'flexmock'
  3
+
1 4
 require 'test/unit'
2 5
 require 'flexmock/test_unit'
3 6
 require File.dirname(__FILE__) + '/../lib/yahoo-music'
4 7
 
5  
-include Yahoo::Music
  8
+include Yahoo::Music
  9
+
  10
+def fixture(_filename)
  11
+  File.open(File.dirname(__FILE__) + '/fixtures/%s.xml' % _filename ).read
  12
+end
60  test/test_yahoo_music_artist.rb
... ...
@@ -0,0 +1,60 @@
  1
+require File.dirname(__FILE__) + '/test_helper.rb'
  2
+
  3
+class TestYahooMusicArtist < Test::Unit::TestCase  
  4
+  def test_artist_initialization_from_string
  5
+    flexmock(Artist).should_receive(:fetch_and_parse).
  6
+      once.with("artist/v1/list/search/all/beirut").
  7
+      and_return(Hpricot::XML(fixture(:artist)))
  8
+    
  9
+    assert_nothing_raised do
  10
+      @artist = Artist.new("Beirut")
  11
+    end
  12
+  end
  13
+  
  14
+  def test_artist_initialization_from_id
  15
+    flexmock(Artist).should_receive(:fetch_and_parse).
  16
+      once.with("artist/v1/item/33892447").
  17
+      and_return(Hpricot::XML(fixture(:artist)))
  18
+      
  19
+    assert_nothing_raised do
  20
+      @artist = Artist.new(33892447)
  21
+    end
  22
+  end
  23
+  
  24
+  def test_artist_class_attributes_and_associations
  25
+    flexmock(Artist).should_receive(:fetch_and_parse).
  26
+      once.with("artist/v1/item/33892447").
  27
+      and_return(Hpricot::XML(fixture(:artist)))
  28
+      
  29
+    assert_nothing_raised do
  30
+      @artist = Artist.new(33892447)
  31
+    end
  32
+    
  33
+    assert ! Artist.attributes.empty?
  34
+    Artist.attributes.keys.each do |attribute|
  35
+      assert_respond_to @artist, attribute
  36
+    end
  37
+    
  38
+    assert ! Artist.associations.empty?
  39
+    Artist.associations.each do |association|
  40
+      assert_respond_to @artist, association
  41
+    end
  42
+  end
  43
+  
  44
+  def test_artist_instance_variables
  45
+    flexmock(Artist).should_receive(:fetch_and_parse).
  46
+      once.with("artist/v1/item/33892447").
  47
+      and_return(Hpricot::XML(fixture(:artist)))
  48
+      
  49
+    assert_nothing_raised do
  50
+      @artist = Artist.new(33892447)
  51
+    end
  52
+    
  53
+    assert_equal @artist.id,       33892447
  54
+    assert_equal @artist.name,     "Beirut"
  55
+    assert_equal @artist.website,  "http://www.beirutband.com/"
  56
+    assert_nothing_raised do
  57
+      assert @artist.releases.collect{|release| release.title}.include?("Lon Gisland EP")
  58
+    end
  59
+  end
  60
+end
64  test/test_yahoo_music_release.rb
... ...
@@ -0,0 +1,64 @@
  1
+require File.dirname(__FILE__) + '/test_helper.rb'
  2
+
  3
+class TestYahooMusicRelease < Test::Unit::TestCase
  4
+  def test_release_initialization_from_string
  5
+    flexmock(Release).should_receive(:fetch_and_parse).
  6
+      once.with("release/v1/list/search/all/lon+gisland+ep").
  7
+      and_return(Hpricot::XML(fixture(:release)))
  8
+    
  9
+    assert_nothing_raised do
  10
+      @release = Release.new("Lon Gisland EP")
  11
+    end
  12
+  end
  13
+  
  14
+  def test_release_initialization_from_id
  15
+    flexmock(Release).should_receive(:fetch_and_parse).
  16
+      once.with("release/v1/item/39477375").
  17
+      and_return(Hpricot::XML(fixture(:release)))
  18
+      
  19
+    assert_nothing_raised do
  20
+      @release = Release.new(39477375)
  21
+    end
  22
+  end
  23
+  
  24
+  def test_release_class_attributes_and_associations
  25
+    flexmock(Release).should_receive(:fetch_and_parse).
  26
+      once.with("release/v1/item/39477375").
  27
+      and_return(Hpricot::XML(fixture(:release)))
  28
+      
  29
+    assert_nothing_raised do
  30
+      @release = Release.new(39477375)
  31
+    end
  32
+    
  33
+    assert ! Release.attributes.empty?
  34
+    Release.attributes.keys.each do |attribute|
  35
+      assert_respond_to @release, attribute
  36
+    end
  37
+    
  38
+    assert ! Release.associations.empty?
  39
+    Release.associations.each do |association|
  40
+      assert_respond_to @release, association
  41
+    end
  42
+  end
  43
+  
  44
+  def test_release_instance_variables
  45
+    flexmock(Release).should_receive(:fetch_and_parse).
  46
+      once.with("release/v1/item/39477375").
  47
+      and_return(Hpricot::XML(fixture(:release)))
  48
+      
  49
+    assert_nothing_raised do
  50
+      @release = Release.new(39477375)
  51
+    end
  52
+    
  53
+    assert_equal @release.id,       39477375
  54
+    assert_equal @release.title,    "Lon Gisland EP"
  55
+    assert_equal @release.upc,      "600197005224"
  56
+    assert_equal @release.explicit, false
  57
+    assert_nothing_raised do
  58
+      ["Elephant Gun", "My Family's Role In The World Revolution", "Scenic World (Version)",
  59
+       "The Long Island Sound", "Carousels"].each do |track_title|
  60
+         assert @release.tracks.collect{|track| track.title}.include?(track_title)
  61
+      end
  62
+    end
  63
+  end
  64
+end

0 notes on commit b671360

Please sign in to comment.
Something went wrong with that request. Please try again.