tiegz-ruby-mtv 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
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
-