mintdigital-youtube-g 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ class YouTubeG
2
+ module Model
3
+ class Author < YouTubeG::Record
4
+ # *String*: Author's YouTube username.
5
+ attr_reader :name
6
+
7
+ # *String*: Feed URL of the author.
8
+ attr_reader :uri
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class YouTubeG
2
+ module Model
3
+ class Category < YouTubeG::Record
4
+ # *String*:: Name of the YouTube category
5
+ attr_reader :label
6
+
7
+ # *String*:: Identifies the type of item described.
8
+ attr_reader :term
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ class YouTubeG
2
+ module Model
3
+ class Contact < YouTubeG::Record
4
+ # *String*:: Identifies the status of a contact.
5
+ #
6
+ # * The tag's value will be accepted if the authenticated user and the contact have marked each other as friends.
7
+ # * The tag's value will be requested if the contact has asked to be added to the authenticated user's contact list, but the request has not yet been accepted (or rejected).
8
+ # * The tag's value will be pending if the authenticated user has asked to be added to the contact's contact list, but the request has not yet been accepted or rejected.
9
+ #
10
+ attr_reader :status
11
+
12
+ # *String*:: The Youtube username of the contact.
13
+ attr_reader :username
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ class YouTubeG
2
+ module Model
3
+ class Content < YouTubeG::Record
4
+ # *Boolean*:: Description of the video.
5
+ attr_reader :default
6
+ # *Fixnum*:: Length of the video in seconds.
7
+ attr_reader :duration
8
+ # YouTubeG::Model::Video::Format:: Specifies the video format of the video object
9
+ attr_reader :format
10
+ # *String*:: Specifies the MIME type of the media object.
11
+ attr_reader :mime_type
12
+ # *String*:: Specifies the URL for the media object.
13
+ attr_reader :url
14
+
15
+ alias :is_default? :default
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ class YouTubeG
2
+ module Model
3
+ class Playlist < YouTubeG::Record
4
+ # *String*:: User entered description for the playlist.
5
+ attr_reader :description
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ class YouTubeG
2
+ module Model
3
+ class Rating < YouTubeG::Record
4
+ # *Float*:: Average rating given to the video
5
+ attr_reader :average
6
+
7
+ # *Fixnum*:: Maximum rating that can be assigned to the video
8
+ attr_reader :max
9
+
10
+ # *Fixnum*:: Minimum rating that can be assigned to the video
11
+ attr_reader :min
12
+
13
+ # *Fixnum*:: Indicates how many people have rated the video
14
+ attr_reader :rater_count
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ class YouTubeG
2
+ module Model
3
+ class Thumbnail < YouTubeG::Record
4
+ # *String*:: URL for the thumbnail image.
5
+ attr_reader :url
6
+
7
+ # *Fixnum*:: Height of the thumbnail image.
8
+ attr_reader :height
9
+
10
+ # *Fixnum*:: Width of the thumbnail image.
11
+ attr_reader :width
12
+
13
+ # *String*:: Specifies the time offset at which the frame shown in the thumbnail image appears in the video.
14
+ attr_reader :time
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ class YouTubeG
2
+ module Model
3
+ class User < YouTubeG::Record
4
+ attr_reader :age
5
+ attr_reader :books
6
+ attr_reader :company
7
+ attr_reader :gender
8
+ attr_reader :hobbies
9
+ attr_reader :hometown
10
+ attr_reader :location
11
+ attr_reader :movies
12
+ attr_reader :music
13
+ attr_reader :occupation
14
+ attr_reader :relationship
15
+ attr_reader :school
16
+ attr_reader :description
17
+ attr_reader :username
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,194 @@
1
+ # TODO
2
+ # * self atom feed
3
+ # * alternate youtube watch url
4
+ # * comments feedLink
5
+
6
+ class YouTubeG
7
+ module Model
8
+ class Video < YouTubeG::Record
9
+ # Describes the various file formats in which a Youtube video may be
10
+ # made available and allows looking them up by format code number.
11
+ class Format
12
+ @@formats = Hash.new
13
+
14
+ # Instantiates a new video format object.
15
+ #
16
+ # == Parameters
17
+ # :format_code<Fixnum>:: The Youtube Format code of the object.
18
+ # :name<Symbol>:: The name of the format
19
+ #
20
+ # == Returns
21
+ # YouTubeG::Model::Video::Format: Video format object
22
+ def initialize(format_code, name)
23
+ @format_code = format_code
24
+ @name = name
25
+
26
+ @@formats[format_code] = self
27
+ end
28
+
29
+ # Allows you to get the video format for a specific format code.
30
+ #
31
+ # A full list of format codes is available at:
32
+ #
33
+ # http://code.google.com/apis/youtube/reference.html#youtube_data_api_tag_media:content
34
+ #
35
+ # == Parameters
36
+ # :format_code<Fixnum>:: The Youtube Format code of the object.
37
+ #
38
+ # == Returns
39
+ # YouTubeG::Model::Video::Format: Video format object
40
+ def self.by_code(format_code)
41
+ @@formats[format_code]
42
+ end
43
+
44
+ # Flash format on YouTube site. All videos are available in this format.
45
+ FLASH = YouTubeG::Model::Video::Format.new(0, :flash)
46
+
47
+ # RTSP streaming URL for mobile video playback. H.263 video (176x144) and AMR audio.
48
+ RTSP = YouTubeG::Model::Video::Format.new(1, :rtsp)
49
+
50
+ # HTTP URL to the embeddable player (SWF) for this video. This format
51
+ # is not available for a video that is not embeddable.
52
+ SWF = YouTubeG::Model::Video::Format.new(5, :swf)
53
+
54
+ # RTSP streaming URL for mobile video playback. MPEG-4 SP video (up to 176x144) and AAC audio.
55
+ THREE_GPP = YouTubeG::Model::Video::Format.new(6, :three_gpp)
56
+ end
57
+
58
+ # *Fixnum*:: Duration of a video in seconds.
59
+ attr_reader :duration
60
+
61
+ # *Boolean*:: Specifies that a video may or may not be embedded on other websites.
62
+ attr_reader :noembed
63
+
64
+ # *Fixnum*:: Specifies the order in which the video appears in a playlist.
65
+ attr_reader :position
66
+
67
+ # *Boolean*:: Specifies that a video is flagged as adult or not.
68
+ attr_reader :racy
69
+
70
+ # *String*: Specifies a URI that uniquely and permanently identifies the video.
71
+ attr_reader :video_id
72
+
73
+ # *Time*:: When the video was published on Youtube.
74
+ attr_reader :published_at
75
+
76
+ # *Time*:: When the video's data was last updated.
77
+ attr_reader :updated_at
78
+
79
+ # *Array*:: A array of YouTubeG::Model::Category objects that describe the videos categories.
80
+ attr_reader :categories
81
+
82
+ # *Array*:: An array of words associated with the video.
83
+ attr_reader :keywords
84
+
85
+ # *String*:: Description of the video.
86
+ attr_reader :description
87
+
88
+ # *String*:: Title for the video.
89
+ attr_reader :title
90
+
91
+ # *String*:: Description of the video.
92
+ attr_reader :html_content
93
+
94
+ # YouTubeG::Model::Author:: Information about the YouTube user who owns a piece of video content.
95
+ attr_reader :author
96
+
97
+ # *Array*:: An array of YouTubeG::Model::Content objects describing the individual media content data available for this video. Most, but not all, videos offer this.
98
+ attr_reader :media_content
99
+
100
+ # *Array*:: An array of YouTubeG::Model::Thumbnail objects that contain information regarding the videos thumbnail images.
101
+ attr_reader :thumbnails
102
+
103
+ # *String*:: The link to watch the URL on YouTubes website.
104
+ attr_reader :player_url
105
+
106
+ # YouTubeG::Model::Rating:: Information about the videos rating.
107
+ attr_reader :rating
108
+
109
+ # *Fixnum*:: Number of times that the video has been viewed
110
+ attr_reader :view_count
111
+
112
+ # *Fixnum*:: Number of times that the video has been favorited
113
+ attr_reader :favorite_count
114
+
115
+
116
+ # Geodata
117
+ attr_reader :where
118
+ attr_reader :position
119
+ attr_reader :latitude
120
+ attr_reader :longitude
121
+
122
+ attr_reader :statistics
123
+
124
+ # Videos related to the current video.
125
+ #
126
+ # === Returns
127
+ # YouTubeG::Response::VideoSearch
128
+ def related
129
+ YouTubeG::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/related").parse
130
+ end
131
+
132
+ # Video responses to the current video.
133
+ #
134
+ # === Returns
135
+ # YouTubeG::Response::VideoSearch
136
+ def responses
137
+ YouTubeG::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/responses").parse
138
+ end
139
+
140
+ # The ID of the video, useful for searching for the video again without having to store it anywhere.
141
+ # A regular query search, with this id will return the same video.
142
+ #
143
+ # === Example
144
+ # >> video.unique_id
145
+ # => "ZTUVgYoeN_o"
146
+ #
147
+ # === Returns
148
+ # String: The Youtube video id.
149
+ def unique_id
150
+ video_id[/videos\/([^<]+)/, 1]
151
+ end
152
+
153
+ # Allows you to check whether the video can be embedded on a webpage.
154
+ #
155
+ # === Returns
156
+ # Boolean: True if the video can be embedded, false if not.
157
+ def embeddable?
158
+ not @noembed
159
+ end
160
+
161
+ # Provides a URL and various other types of information about a video.
162
+ #
163
+ # === Returns
164
+ # YouTubeG::Model::Content: Data about the embeddable video.
165
+ def default_media_content
166
+ @media_content.find { |c| c.is_default? }
167
+ end
168
+
169
+ # Gives you the HTML to embed the video on your website.
170
+ #
171
+ # === Returns
172
+ # String: The HTML for embedding the video on your website.
173
+ def embed_html(width = 425, height = 350)
174
+ <<EDOC
175
+ <object width="#{width}" height="#{height}">
176
+ <param name="movie" value="#{embed_url}"></param>
177
+ <param name="wmode" value="transparent"></param>
178
+ <embed src="#{embed_url}" type="application/x-shockwave-flash"
179
+ wmode="transparent" width="#{width}" height="#{height}"></embed>
180
+ </object>
181
+ EDOC
182
+ end
183
+
184
+ # The URL needed for embedding the video in a page.
185
+ #
186
+ # === Returns
187
+ # String: Absolute URL for embedding video
188
+ def embed_url
189
+ @player_url.sub('watch?', '').sub('=', '/')
190
+ end
191
+
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,174 @@
1
+ class YouTubeG
2
+ module Parser #:nodoc:
3
+ class FeedParser #:nodoc:
4
+ def initialize(url)
5
+ @url = url
6
+ end
7
+
8
+ def parse
9
+ parse_content open(@url).read
10
+ end
11
+ end
12
+
13
+ class VideoFeedParser < FeedParser #:nodoc:
14
+
15
+ def parse_content(content)
16
+ doc = REXML::Document.new(content)
17
+ entry = doc.elements["entry"]
18
+ parse_entry(entry)
19
+ end
20
+
21
+ protected
22
+ def parse_entry(entry)
23
+ video_id = entry.elements["id"].text
24
+ published_at = Time.parse(entry.elements["published"].text)
25
+ updated_at = Time.parse(entry.elements["updated"].text)
26
+
27
+ # parse the category and keyword lists
28
+ categories = []
29
+ keywords = []
30
+ entry.elements.each("category") do |category|
31
+ # determine if it's really a category, or just a keyword
32
+ scheme = category.attributes["scheme"]
33
+ if (scheme =~ /\/categories\.cat$/)
34
+ # it's a category
35
+ categories << YouTubeG::Model::Category.new(
36
+ :term => category.attributes["term"],
37
+ :label => category.attributes["label"])
38
+
39
+ elsif (scheme =~ /\/keywords\.cat$/)
40
+ # it's a keyword
41
+ keywords << category.attributes["term"]
42
+ end
43
+ end
44
+
45
+ title = entry.elements["title"].text
46
+ html_content = entry.elements["content"].text
47
+
48
+ # parse the author
49
+ author_element = entry.elements["author"]
50
+ author = nil
51
+ if author_element
52
+ author = YouTubeG::Model::Author.new(
53
+ :name => author_element.elements["name"].text,
54
+ :uri => author_element.elements["uri"].text)
55
+ end
56
+
57
+ media_group = entry.elements["media:group"]
58
+ description = media_group.elements["media:description"].text
59
+ duration = media_group.elements["yt:duration"].attributes["seconds"].to_i
60
+
61
+ media_content = []
62
+ media_group.elements.each("media:content") do |mce|
63
+ media_content << parse_media_content(mce)
64
+ end
65
+
66
+ player_url = media_group.elements["media:player"].attributes["url"]
67
+
68
+ # parse thumbnails
69
+ thumbnails = []
70
+ media_group.elements.each("media:thumbnail") do |thumb_element|
71
+ # TODO: convert time HH:MM:ss string to seconds?
72
+ thumbnails << YouTubeG::Model::Thumbnail.new(
73
+ :url => thumb_element.attributes["url"],
74
+ :height => thumb_element.attributes["height"].to_i,
75
+ :width => thumb_element.attributes["width"].to_i,
76
+ :time => thumb_element.attributes["time"])
77
+ end
78
+
79
+ rating_element = entry.elements["gd:rating"]
80
+ rating = nil
81
+ if rating_element
82
+ rating = YouTubeG::Model::Rating.new(
83
+ :min => rating_element.attributes["min"].to_i,
84
+ :max => rating_element.attributes["max"].to_i,
85
+ :rater_count => rating_element.attributes["numRaters"].to_i,
86
+ :average => rating_element.attributes["average"].to_f)
87
+ end
88
+
89
+ if (el = entry.elements["yt:statistics"])
90
+ view_count, favorite_count = el.attributes["viewCount"].to_i, el.attributes["favoriteCount"].to_i
91
+ else
92
+ view_count, favorite_count = 0,0
93
+ end
94
+
95
+ noembed = entry.elements["yt:noembed"] ? true : false
96
+ racy = entry.elements["media:rating"] ? true : false
97
+
98
+ if where = entry.elements["georss:where"]
99
+ position = where.elements["gml:Point"].elements["gml:pos"].text
100
+ latitude, longitude = position.split(" ")
101
+ end
102
+
103
+ YouTubeG::Model::Video.new(
104
+ :video_id => video_id,
105
+ :published_at => published_at,
106
+ :updated_at => updated_at,
107
+ :categories => categories,
108
+ :keywords => keywords,
109
+ :title => title,
110
+ :html_content => html_content,
111
+ :author => author,
112
+ :description => description,
113
+ :duration => duration,
114
+ :media_content => media_content,
115
+ :player_url => player_url,
116
+ :thumbnails => thumbnails,
117
+ :rating => rating,
118
+ :view_count => view_count,
119
+ :favorite_count => favorite_count,
120
+ :noembed => noembed,
121
+ :racy => racy,
122
+ :where => where,
123
+ :position => position,
124
+ :latitude => latitude,
125
+ :longitude => longitude)
126
+ end
127
+
128
+ def parse_media_content (media_content_element)
129
+ content_url = media_content_element.attributes["url"]
130
+ format_code = media_content_element.attributes["yt:format"].to_i
131
+ format = YouTubeG::Model::Video::Format.by_code(format_code)
132
+ duration = media_content_element.attributes["duration"].to_i
133
+ mime_type = media_content_element.attributes["type"]
134
+ default = (media_content_element.attributes["isDefault"] == "true")
135
+
136
+ YouTubeG::Model::Content.new(
137
+ :url => content_url,
138
+ :format => format,
139
+ :duration => duration,
140
+ :mime_type => mime_type,
141
+ :default => default)
142
+ end
143
+ end
144
+
145
+ class VideosFeedParser < VideoFeedParser #:nodoc:
146
+
147
+ private
148
+ def parse_content(content)
149
+ doc = REXML::Document.new(content)
150
+ feed = doc.elements["feed"]
151
+
152
+ feed_id = feed.elements["id"].text
153
+ updated_at = Time.parse(feed.elements["updated"].text)
154
+ total_result_count = feed.elements["openSearch:totalResults"].text.to_i
155
+ offset = feed.elements["openSearch:startIndex"].text.to_i
156
+ max_result_count = feed.elements["openSearch:itemsPerPage"].text.to_i
157
+
158
+ videos = []
159
+ feed.elements.each("entry") do |entry|
160
+ videos << parse_entry(entry)
161
+ end
162
+
163
+ YouTubeG::Response::VideoSearch.new(
164
+ :feed_id => feed_id,
165
+ :updated_at => updated_at,
166
+ :total_result_count => total_result_count,
167
+ :offset => offset,
168
+ :max_result_count => max_result_count,
169
+ :videos => videos)
170
+ end
171
+ end
172
+
173
+ end
174
+ end