tiegz-ruby-mtv 1.0 → 1.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/README CHANGED
@@ -4,13 +4,13 @@ ruby-mtv
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- This is a Ruby library for the MTV api. Right now it has classes for Artists and Videos, although
7
+ This is a Ruby library for the MTV Networks api. Right now it has classes for Artists and Videos, although
8
8
  there is much to be done, spec'd and/or tested!
9
9
 
10
10
  == REQUIREMENTS:
11
11
 
12
- * git (http://git.or.cz) tested with 1.5.3.4
13
-
12
+ * ActiveSupport
13
+
14
14
  == INSTALL:
15
15
 
16
16
  $ gem sources -a http://gems.github.com/ (you only need to do this once)
@@ -42,6 +42,13 @@ To find a video,
42
42
  v.artist
43
43
  # => #<MTV::Artist name: "Dinosaur Jr.", uid: "dinosaur_jr", uri: "http://api.mtvnservices.com/1/artist/dinosaur_jr/">
44
44
 
45
+ To get html embed markup for the video swf,
46
+
47
+ v.embed_code(:width => 200)
48
+ # => "<embed src=\"http://media.mtvnservices.com/mgid:uma:video:api.mtvnservices.com:143042\"
49
+ type=\"application/x-shockwave-flash\" width=\"200\" height=\"163\"
50
+ allowFullScreen=\"true\" allowScriptAccess=\"always\" />"
51
+
45
52
  To find all videos for an artist,
46
53
 
47
54
  artist.videos
data/lib/mtv/artist.rb ADDED
@@ -0,0 +1,112 @@
1
+ module MTV
2
+ # This class represents a music artist in MTV's database.
3
+ class Artist < Base
4
+ attr_accessor :name, :uid, :uri, :links, :updated
5
+
6
+ #-----------------
7
+ # Class Methods
8
+ #-----------------
9
+ class << self
10
+ # MTV::Artist.browse 'x' => X, X-Clan, The X-Ecutioners, Xiren, Xscape, Xtreme, Xzibit
11
+ def browse(letter='a')
12
+ response = request "artist/browse/#{letter.to_s.first}/"
13
+ raise Error, "That artist not found!" if response.nil? || response.empty?
14
+ parse_many response
15
+ end
16
+
17
+ # MTV::Artist.find 'beck'
18
+ # MTV::Artist.find 'meGADeath'
19
+ def find(name, options={})
20
+ return name if name.is_a? Artist
21
+
22
+ options.symbolize_keys!
23
+ name = string_to_uid(options[:name] || name)
24
+
25
+ response = request "artist/#{name}/"
26
+ raise Error, "That artist not found!" if response.nil? || response.empty?
27
+ parse_one response
28
+ end
29
+
30
+ # MTV::Artist.related 'qtip'
31
+ # MTV::Artist.related MTV::Artist.find('qtip')
32
+ def related(artist)
33
+ artist = find(artist)
34
+ response = request "artist/#{artist.uid}/related/"
35
+ raise Error, "That artist not found!" if response.nil? || response.empty?
36
+ parse_many response
37
+ end
38
+
39
+ # MTV::Artist.search 'beck', :max_results => 1, :start_index => 1
40
+ def search(term=nil, options={})
41
+ options.symbolize_keys!
42
+ params = {}
43
+ params[:'max-results'] = options[:max_results] || 1
44
+ params[:'start-index'] = options[:start_index]
45
+ term = options[:term] || term
46
+ params.reject! { |k,v| !v }
47
+ response = request "artist/search?#{term.to_query('term')}&#{params.to_param}"
48
+ raise Error, "That artist not found!" if response.nil? || response.empty?
49
+ parse_many response
50
+ end
51
+
52
+ # MTV::Artist.find('beck').videos
53
+ def videos(artist)
54
+ MTV::Video.from_artist(artist)
55
+ end
56
+
57
+ protected
58
+ def parse_many(body)
59
+ entries = XmlSimple.xml_in(body)['entry']
60
+ raise Error, "That artist not found!" if entries.nil?
61
+ entries = [entries] unless entries.is_a? Array
62
+ entries.map { |entry|
63
+ instantiate entry
64
+ }.reject { |artist| MTV::Artist.name.nil? || MTV::Artist.name.empty? }
65
+ end
66
+
67
+ def parse_one(body)
68
+ entry = XmlSimple.xml_in(body)
69
+ raise Error, "That artist not found!" if entry['author'].first['name'].nil? || entry['author'].first['name'].empty?
70
+ instantiate entry
71
+ end
72
+
73
+ def instantiate(entry={})
74
+ Artist.new(:name => entry['author'].first['name'].to_s,
75
+ :uri => entry['author'].first['uri'].to_s,
76
+ :links => entry['link'].map { |link| link['href'].to_s },
77
+ :updated => entry['updated'].to_s.to_datetime)
78
+ end
79
+ end
80
+
81
+ #-----------------
82
+ # Instance Methods
83
+ #-----------------
84
+ def initialize(values={})
85
+ super(values)
86
+ self.uid = uri.gsub(self.class.base_url + "/artist", '').delete '/' unless @uri.nil?
87
+ end
88
+
89
+ def inspect
90
+ attrs = [:name].map { |name| "#{name}: #{attribute_for_inspect(name)}" }.compact.join(", ")
91
+ "#<#{self.class} #{attrs}>"
92
+ end
93
+
94
+ # artist = MTV::Artist.search('In Flames')[2]
95
+ # MTV::Artist.browse => I Am Ghost, IB3, INXS, Ice Cube, ...
96
+ def browse
97
+ @browse ||= Artist.browse(uid.first)
98
+ end
99
+
100
+ # artist = MTV::Artist.search 'Frank Zappa'
101
+ # MTV::Artist.browse => Amon Amarth, Amorphis, Arch Enemy, Arcturus, Borknagar, ...
102
+ def related
103
+ @related ||= Artist.related(self)
104
+ end
105
+
106
+ # artist = MTV::Artist.find('beck')
107
+ # MTV::Artist.videos => ...
108
+ def videos
109
+ @videos ||= Video.from_artist(self)
110
+ end
111
+ end
112
+ end
data/lib/mtv/base.rb ADDED
@@ -0,0 +1,57 @@
1
+ module MTV
2
+ class Base
3
+ #-----------------
4
+ # Class Methods
5
+ #-----------------
6
+
7
+ class << self
8
+ cattr_accessor :host, :protocol, :base_url, :debug
9
+
10
+ def request path
11
+ url = URI.escape "#{base_url}/#{path}"
12
+ response = nil
13
+ seconds = Benchmark.realtime { response = open url }
14
+ puts " \e[4;36;1mREQUEST (#{sprintf("%f", seconds)})\e[0m \e[0;1m#{url}\e[0m" if debug
15
+ response.is_a?(String) ? response : response.read
16
+ rescue OpenURI::HTTPError => e
17
+ puts " \e[4;36;1mREQUEST (404)\e[0m \e[0;1m#{url}\e[0m" if debug
18
+ nil
19
+ end
20
+
21
+ protected
22
+ # assuming that the uid for the artist is downcase and no spaces, this tries to match better
23
+ def string_to_uid(str)
24
+ str.downcase.underscore.gsub(" ", "_")
25
+ end
26
+ end
27
+
28
+ # These are the default settings for the Base class. Change them, even per subclass if needed.
29
+ # Appears that MTVN doesn't have SSL enabled for the api yet (10/08).
30
+ self.host = "api.mtvnservices.com/1"
31
+ self.protocol = "http"
32
+ self.base_url = "#{protocol}://#{host}"
33
+ self.debug = true if ENV['DEBUG']
34
+
35
+ #-----------------
36
+ # Instance Methods
37
+ #-----------------
38
+ def initialize(values={})
39
+ values.each { |k, v| send "#{k}=", v }
40
+ end
41
+
42
+ # Copied from ActiveRecord::Base
43
+ def attribute_for_inspect(attr_name)
44
+ value = send(attr_name)
45
+
46
+ if value.is_a?(String) && value.length > 50
47
+ "#{value[0..50]}...".inspect
48
+ elsif value.is_a?(Date) || value.is_a?(Time)
49
+ %("#{value.to_s(:db)}")
50
+ else
51
+ value.inspect
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+
@@ -0,0 +1,10 @@
1
+ module MTV
2
+ class Thumbnail
3
+ attr_accessor :url, :width, :height
4
+ def initialize(url, width, height)
5
+ self.url = url
6
+ self.width = width
7
+ self.height = height
8
+ end
9
+ end
10
+ end
data/lib/mtv/video.rb ADDED
@@ -0,0 +1,131 @@
1
+ module MTV
2
+ # This class represents a music video in MTV's database.
3
+ class Video < Base
4
+ attr_accessor :artist, :artist_name, :artist_uri, :category, :content, :credit,
5
+ :media_player_url, :media_thumbnails, :media_title, :media_description,
6
+ :media_keywords, :media_duration, :media_expression, :media_url, :media_type,
7
+ :media_credits, :media_category, :media_medium,
8
+ :title, :published, :uid, :updated, :uri, :vid
9
+
10
+ #-----------------
11
+ # Class Methods
12
+ #-----------------
13
+ class << self
14
+ # MTV::Video.find '1234abcd'
15
+ def find(uid, options={})
16
+ return uid if uid.is_a? Artist
17
+
18
+ options.symbolize_keys!
19
+ uid = options[:uid] || uid
20
+
21
+ response = request "video/#{uid}/"
22
+ raise Error, "That video not found!" if response.nil? || response.empty?
23
+ parse_one response
24
+ end
25
+
26
+ # MTV::Video.from_artist(Artist.find('beck'))
27
+ # MTV::Video.from_artist('beck')
28
+ def from_artist(artist)
29
+ artist_uid = artist.is_a?(Artist) ? artist.uid : string_to_uid(artist)
30
+
31
+ response = request "artist/#{artist_uid}/videos"
32
+ raise Error, "No videos found!" if response.nil? || response.empty?
33
+ parse_many response
34
+ end
35
+
36
+ # http://api.mtvnservices.com/1/video/search/[parameters]
37
+ # MTV::Video.search 'the golden age', :max_results => 1, :start_index => 1
38
+ def search(term=nil, options={})
39
+ options.symbolize_keys!
40
+ params = { :'max-results' => (options[:max_results] || 1),
41
+ :'start-index' => options[:start_index] }.reject { |k,v| v.nil? || v.to_s.empty? }.to_query
42
+ params = "&#{params}" unless params.empty?
43
+ term = (options[:term] || term).to_query('term')
44
+
45
+ response = request "video/search?#{term}#{params}"
46
+ raise Error, "No videos not found!" if response.nil? || response.empty?
47
+ parse_many response
48
+ end
49
+
50
+ protected
51
+ def parse_many(body)
52
+ body = hack_media_enclosures(body)
53
+ entries = XmlSimple.xml_in(body)['entry']
54
+ entries = [entries] unless entries.is_a? Array
55
+ entries.reject! { |entry| entry.nil? }
56
+ entries.map { |entry|
57
+ instantiate entry
58
+ }
59
+ end
60
+
61
+ def parse_one(body)
62
+ body = hack_media_enclosures(body)
63
+ entry = XmlSimple.xml_in(body)
64
+ raise Error, "That artist not found!" if entry['author']['name'].nil? || entry['author']['name'].empty?
65
+ instantiate entry
66
+ end
67
+
68
+ # HACK because XmlSimple doesn't seem to handle enclosures, we'll replace colons with hyphens
69
+ # TODO write a better regexp for that hack :\
70
+ def hack_media_enclosures(body)
71
+ body.gsub("<media:", "<media_").gsub("</media:", "</media_")
72
+ end
73
+
74
+ def instantiate(entry={})
75
+ Video.new(:title => entry['title'].to_s,
76
+ :artist_uri => entry['author'].first['uri'].to_s,
77
+ :artist_name => entry['author'].first['name'].to_s,
78
+ :published => entry['published'].to_s,
79
+ :content => entry['content'], # Artist Name, Video Title, and Record Label
80
+ :uri => entry['link'].select { |link| link['rel'].to_s == 'self' }.first['href'].to_s,
81
+ :updated => (entry['updated'].to_s.to_datetime rescue nil),
82
+ :media_category => entry['media_category'].to_s, # governing agreement
83
+ :media_credits => entry['media_credit'].map { |credit| "#{credit['content'] || 'N/A'} (#{credit['role']})}" }.join(', '),
84
+ :media_description => entry['media_description'].to_s,
85
+ :media_duration => entry['media_content'].first['duration'].to_s,
86
+ :media_expression => entry['media_content'].first['expression'].to_s,
87
+ :media_keywords => entry['media_keywords'].to_s,
88
+ :media_medium => entry['media_content'].first['medium'].to_s,
89
+ :media_player_url => entry['media_player'].first['url'].to_s,
90
+ :media_thumbnails => entry['media_thumbnail'].to_s,
91
+ :media_title => entry['media_title'].to_s,
92
+ :media_type => entry['media_content'].first['type'].to_s,
93
+ :media_url => entry['media_content'].first['url'].to_s)
94
+ end
95
+ end
96
+
97
+ #-----------------
98
+ # Instance Methods
99
+ #-----------------
100
+ def initialize(values={})
101
+ super(values)
102
+ self.uid = uri.gsub(self.class.base_url + "/video", '').delete '/' unless @uid
103
+ self.vid = media_url.split(':').last
104
+ end
105
+
106
+ # MTV::Video.search('gold').first.artist
107
+ def artist
108
+ @artist ||= Artist.find(artist_uri.gsub(self.class.base_url + "/artist", '').delete('/'))
109
+ end
110
+
111
+ # HTML to embed the Flash player for this video
112
+ def embed_code(options={})
113
+ options[:width] ||= (options[:height] ? ((options[:height]*448).to_f/366).to_i : 448)
114
+ options[:height] ||= (options[:width]==448 ? 366 : ((options[:width]*366).to_f/448).to_i)
115
+
116
+ <<-EOS
117
+ <embed src="#{media_url}" type="#{media_type}" width="#{options[:width]}" height="#{options[:height]}"
118
+ allowFullScreen="true" allowScriptAccess="always" />
119
+ EOS
120
+ end
121
+
122
+ def inspect
123
+ attrs = [:title, :artist_uri].map { |name| "#{name}: #{attribute_for_inspect(name)}" }.compact.join(", ")
124
+ "#<#{self.class} #{attrs}>"
125
+ end
126
+
127
+ def thumbnails=(val)
128
+ @thumbnails = (val.is_a?(Array) ? val : [val]).map { |t| Thumbnail.new(t['url'], t['width'], t['height']) unless t.nil? }
129
+ end
130
+ end
131
+ end
data/lib/mtv.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'activesupport'
2
+ require 'open-uri'
3
+ require 'benchmark'
4
+
5
+ require 'lib/mtv/base.rb'
6
+ require 'lib/mtv/thumbnail'
7
+ require 'lib/mtv/artist'
8
+ require 'lib/mtv/video'
9
+
10
+
11
+ module MTV
12
+ class Error < StandardError; end
13
+ end
data/ruby-mtv.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "ruby-mtv"
3
- s.version = "1.0"
4
- s.date = "2008-09-16"
3
+ s.version = "1.1"
4
+ s.date = "2008-10-27"
5
5
  s.summary = "Ruby wrapper library for MTV api"
6
6
  s.email = "tiegzaharia@gmail.com"
7
7
  s.homepage = "http://github.com/tiegz/ruby-mtv"
@@ -12,10 +12,14 @@ Gem::Specification.new do |s|
12
12
  "Rakefile",
13
13
  "README",
14
14
  "ruby-mtv.gemspec",
15
- "ruby-mtv.rb",
16
- "TODO"]
15
+ "TODO",
16
+ "lib/mtv.rb",
17
+ "lib/mtv/artist.rb",
18
+ "lib/mtv/base.rb",
19
+ "lib/mtv/thumbnail.rb",
20
+ "lib/mtv/video.rb"]
17
21
  s.test_files = []
18
22
  s.rdoc_options = ["--main", "README"]
19
23
  s.extra_rdoc_files = ["README"]
20
24
  s.add_dependency("active-support", ["> 2.0.2"])
21
- end
25
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiegz-ruby-mtv
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.0"
4
+ version: "1.1"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tieg Zaharia
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-09-16 00:00:00 -07:00
12
+ date: 2008-10-27 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -34,8 +34,12 @@ files:
34
34
  - Rakefile
35
35
  - README
36
36
  - ruby-mtv.gemspec
37
- - ruby-mtv.rb
38
37
  - TODO
38
+ - lib/mtv.rb
39
+ - lib/mtv/artist.rb
40
+ - lib/mtv/base.rb
41
+ - lib/mtv/thumbnail.rb
42
+ - lib/mtv/video.rb
39
43
  has_rdoc: true
40
44
  homepage: http://github.com/tiegz/ruby-mtv
41
45
  post_install_message:
data/ruby-mtv.rb DELETED
@@ -1,283 +0,0 @@
1
- require 'rubygems'
2
- require 'activesupport'
3
- require 'open-uri'
4
- require 'benchmark'
5
-
6
- module MTV
7
- class Error < StandardError; end
8
-
9
- class << self
10
- attr_accessor :base_url, :host, :protocol, :debug
11
-
12
- end
13
-
14
- self.host = "api.mtvnservices.com/1"
15
- self.protocol = "http"
16
- self.base_url = "#{protocol}://#{host}"
17
- self.debug = true if ENV['DEBUG']
18
-
19
- class Base
20
- def initialize(values={})
21
- values.each { |k, v| send "#{k}=", v }
22
- end
23
-
24
- class << self
25
- def request path
26
- url = URI.escape "#{MTV.base_url}/#{path}"
27
- response = nil
28
- seconds = Benchmark.realtime { response = open url }
29
- puts " \e[4;36;1mREQUEST (#{sprintf("%f", seconds)})\e[0m \e[0;1m#{url}\e[0m" if MTV.debug
30
- response.is_a?(String) ? response : response.read
31
- rescue OpenURI::HTTPError => e
32
- puts " \e[4;36;1mREQUEST (404)\e[0m \e[0;1m#{url}\e[0m" if MTV.debug
33
- nil
34
- end
35
-
36
- protected
37
- # assuming that the uid for the artist is downcase and no spaces, this tries to match better
38
- def string_to_uid(str)
39
- str.downcase.underscore.gsub(" ", "_")
40
- end
41
- end
42
-
43
- # Copied from ActiveRecord::Base
44
- def attribute_for_inspect(attr_name)
45
- value = send(attr_name)
46
-
47
- if value.is_a?(String) && value.length > 50
48
- "#{value[0..50]}...".inspect
49
- elsif value.is_a?(Date) || value.is_a?(Time)
50
- %("#{value.to_s(:db)}")
51
- else
52
- value.inspect
53
- end
54
- end
55
- end
56
-
57
- # This class represents a musical artist in MTV's database.
58
- class Artist < Base
59
- attr_accessor :name, :uid, :uri, :links, :updated
60
-
61
- def initialize(values={})
62
- super(values)
63
- self.uid = uri.gsub(MTV.base_url + "/artist", '').delete '/' unless @uid
64
- end
65
-
66
- def inspect
67
- attrs = [:name, :uid, :uri].map { |name| "#{name}: #{attribute_for_inspect(name)}" }.compact.join(", ")
68
- "#<#{self.class} #{attrs}>"
69
- end
70
-
71
- # artist = MTV::Artist.search('In Flames')[2]
72
- # MTV::Artist.browse => I Am Ghost, IB3, INXS, Ice Cube, ...
73
- def browse
74
- @browse ||= Artist.browse(uid.first)
75
- end
76
-
77
- # artist = MTV::Artist.search 'Frank Zappa'
78
- # MTV::Artist.browse => Amon Amarth, Amorphis, Arch Enemy, Arcturus, Borknagar, ...
79
- def related
80
- @related ||= Artist.related(self)
81
- end
82
-
83
- # artist = MTV::Artist.find('beck')
84
- # MTV::Artist.videos => ...
85
- def videos
86
- @videos ||= Video.from_artist(self)
87
- end
88
-
89
- class << self
90
- # MTV::Artist.browse 'x' => X, X-Clan, The X-Ecutioners, Xiren, Xscape, Xtreme, Xzibit
91
- def browse(letter='a')
92
- response = request "artist/browse/#{letter.to_s.first}/"
93
- raise Error, "That artist not found!" if response.nil? || response.empty?
94
- parse_many response
95
- end
96
-
97
- # MTV::Artist.find 'beck'
98
- # MTV::Artist.find 'meGADeath'
99
- def find(name, options={})
100
- return name if name.is_a? Artist
101
-
102
- options.symbolize_keys!
103
- name = string_to_uid(options[:name] || name)
104
-
105
- response = request "artist/#{name}/"
106
- raise Error, "That artist not found!" if response.nil? || response.empty?
107
- parse_one response
108
- end
109
-
110
- # MTV::Artist.related 'qtip'
111
- # MTV::Artist.related MTV::Artist.find('qtip')
112
- def related(artist)
113
- artist = find(artist)
114
- response = request "artist/#{artist.uid}/related/"
115
- raise Error, "That artist not found!" if response.nil? || response.empty?
116
- parse_many response
117
- end
118
-
119
- # MTV::Artist.search 'beck', :max_results => 1, :start_index => 1
120
- def search(term=nil, options={})
121
- options.symbolize_keys!
122
- params = {}
123
- params[:'max-results'] = options[:max_results] || 1
124
- params[:'start-index'] = options[:start_index]
125
- term = options[:term] || term
126
- params.reject! { |k,v| !v }
127
- response = request "artist/search?#{term.to_query('term')}&#{params.to_param}"
128
- raise Error, "That artist not found!" if response.nil? || response.empty?
129
- parse_many response
130
- end
131
-
132
- def videos(artist)
133
- MTV::Video.from_artist(artist)
134
- end
135
-
136
- protected
137
- def parse_many(body)
138
- entries = XmlSimple.xml_in(body)['entry']
139
- raise Error, "That artist not found!" if entries.nil?
140
- entries = [entries] unless entries.is_a? Array
141
- entries.map { |entry|
142
- instantiate entry
143
- }.reject { |artist| MTV::Artist.name.nil? || MTV::Artist.name.empty? }
144
- end
145
-
146
- def parse_one(body)
147
- entry = XmlSimple.xml_in(body)
148
- raise Error, "That artist not found!" if entry['author'].first['name'].nil? || entry['author'].first['name'].empty?
149
- instantiate entry
150
- end
151
-
152
- def instantiate(entry={})
153
- Artist.new(:name => entry['author'].first['name'].to_s,
154
- :uri => entry['author'].first['uri'].to_s,
155
- :links => entry['link'].map { |link| link['href'].to_s },
156
- :updated => entry['updated'].to_s.to_datetime)
157
- end
158
- end
159
- end
160
-
161
- # This class represents a music video in MTV's database.
162
- class Video < Base
163
- attr_accessor :artist, :artist_name, :artist_uri, :category, :content, :credit,
164
- :media_player_url, :media_thumbnails, :media_title, :media_description,
165
- :media_keywords, :media_duration, :media_expression, :media_url, :media_type,
166
- :media_credits, :media_category, :media_medium,
167
- :title, :published, :uid, :updated, :uri, :vid
168
-
169
- def initialize(values={})
170
- super(values)
171
- self.uid = uri.gsub(MTV.base_url + "/video", '').delete '/' unless @uid
172
- self.vid = media_url.split(':').last
173
- end
174
-
175
- def artist
176
- @artist ||= Artist.find(artist_uri.gsub(MTV.base_url + "/artist", '').delete('/'))
177
- end
178
-
179
- def inspect
180
- attrs = [:title, :uid, :artist_name, :uri, :artist_uri].map { |name| "#{name}: #{attribute_for_inspect(name)}" }.compact.join(", ")
181
- "#<#{self.class} #{attrs}>"
182
- end
183
-
184
- def thumbnails=(val)
185
- @thumbnails = (val.is_a?(Array) ? val : [val]).map { |t| Thumbnail.new(t['url'], t['width'], t['height']) unless t.nil? }
186
- end
187
-
188
- class << self
189
- # MTV::Video.find '1234abcd'
190
- def find(uid, options={})
191
- return uid if uid.is_a? Artist
192
-
193
- options.symbolize_keys!
194
- uid = options[:uid] || uid
195
-
196
- response = request "video/#{uid}/"
197
- raise Error, "That video not found!" if response.nil? || response.empty?
198
- parse_one response
199
- end
200
-
201
- # MTV::Video.from_artist(Artist.find('beck'))
202
- # MTV::Video.from_artist('beck')
203
- def from_artist(artist)
204
- artist_uid = artist.is_a?(Artist) ? artist.uid : string_to_uid(artist)
205
-
206
- response = request "artist/#{artist_uid}/videos"
207
- raise Error, "No videos found!" if response.nil? || response.empty?
208
- parse_many response
209
- end
210
-
211
- # http://api.mtvnservices.com/1/video/search/[parameters]
212
- # MTV::Video.search 'the golden age', :max_results => 1, :start_index => 1
213
- def search(term=nil, options={})
214
- options.symbolize_keys!
215
- params = { :'max-results' => (options[:max_results] || 1),
216
- :'start-index' => options[:start_index] }.reject { |k,v| v.nil? || v.to_s.empty? }.to_param
217
- params = "&#{params}" unless params.empty?
218
- term = (options[:term] || term).to_query('term')
219
-
220
- response = request "video/search?#{term}#{params}"
221
- raise Error, "No videos not found!" if response.nil? || response.empty?
222
- parse_many response
223
- end
224
-
225
- protected
226
- def parse_many(body)
227
- body = hack_media_enclosures(body)
228
- entries = XmlSimple.xml_in(body)['entry']
229
- entries = [entries] unless entries.is_a? Array
230
- entries.reject! { |entry| entry.nil? }
231
- entries.map { |entry|
232
- instantiate entry
233
- }
234
- end
235
-
236
- def parse_one(body)
237
- body = hack_media_enclosures(body)
238
- entry = XmlSimple.xml_in(body)
239
- raise Error, "That artist not found!" if entry['author']['name'].nil? || entry['author']['name'].empty?
240
- instantiate entry
241
- end
242
-
243
- # HACK because XmlSimple doesn't seem to handle enclosures, we'll replace colons with hyphens
244
- # TODO write a better regexp for that hack :\
245
- def hack_media_enclosures(body)
246
- body.gsub("<media:", "<media_").gsub("</media:", "</media_")
247
- end
248
-
249
- def instantiate(entry={})
250
- Video.new(:title => entry['title'],
251
- :artist_uri => entry['author'].first['uri'],
252
- :artist_name => entry['author'].first['name'],
253
- :published => entry['published'],
254
- :content => entry['content'], # Artist Name, Video Title, and Record Label
255
- :uri => entry['link'].select { |link| link['rel'] == 'self' }.first['href'],
256
- :updated => (entry['updated'].to_datetime rescue nil),
257
- :media_category => entry['media_category'], # governing agreement
258
- :media_credits => entry['media_credit'].map { |credit| "#{credit['content'] || 'N/A'} (#{credit['role']})}" }.join(', '),
259
- :media_description => entry['media_description'],
260
- :media_duration => entry['media_content'].first['duration'],
261
- :media_expression => entry['media_content'].first['expression'],
262
- :media_keywords => entry['media_keywords'],
263
- :media_medium => entry['media_content'].first['medium'],
264
- :media_player_url => entry['media_player'].first['url'],
265
- :media_thumbnails => entry['media_thumbnail'],
266
- :media_title => entry['media_title'],
267
- :media_type => entry['media_content'].first['type'],
268
- :media_url => entry['media_content'].first['url'])
269
- end
270
- end
271
- end
272
-
273
- class Thumbnail
274
- attr_accessor :url, :width, :height
275
- def initialize(url, width, height)
276
- self.url = url
277
- self.width = width
278
- self.height = height
279
- end
280
- end
281
-
282
- end
283
-