pius-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,190 @@
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
+ # Geodata
113
+ attr_reader :where
114
+ attr_reader :position
115
+ attr_reader :latitude
116
+ attr_reader :longitude
117
+
118
+ attr_reader :statistics
119
+
120
+ # Videos related to the current video.
121
+ #
122
+ # === Returns
123
+ # YouTubeG::Response::VideoSearch
124
+ def related
125
+ YouTubeG::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/related").parse
126
+ end
127
+
128
+ # Video responses to the current video.
129
+ #
130
+ # === Returns
131
+ # YouTubeG::Response::VideoSearch
132
+ def responses
133
+ YouTubeG::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/responses").parse
134
+ end
135
+
136
+ # The ID of the video, useful for searching for the video again without having to store it anywhere.
137
+ # A regular query search, with this id will return the same video.
138
+ #
139
+ # === Example
140
+ # >> video.unique_id
141
+ # => "ZTUVgYoeN_o"
142
+ #
143
+ # === Returns
144
+ # String: The Youtube video id.
145
+ def unique_id
146
+ video_id[/videos\/([^<]+)/, 1]
147
+ end
148
+
149
+ # Allows you to check whether the video can be embedded on a webpage.
150
+ #
151
+ # === Returns
152
+ # Boolean: True if the video can be embedded, false if not.
153
+ def embeddable?
154
+ not @noembed
155
+ end
156
+
157
+ # Provides a URL and various other types of information about a video.
158
+ #
159
+ # === Returns
160
+ # YouTubeG::Model::Content: Data about the embeddable video.
161
+ def default_media_content
162
+ @media_content.find { |c| c.is_default? }
163
+ end
164
+
165
+ # Gives you the HTML to embed the video on your website.
166
+ #
167
+ # === Returns
168
+ # String: The HTML for embedding the video on your website.
169
+ def embed_html(width = 425, height = 350)
170
+ <<EDOC
171
+ <object width="#{width}" height="#{height}">
172
+ <param name="movie" value="#{embed_url}"></param>
173
+ <param name="wmode" value="transparent"></param>
174
+ <embed src="#{embed_url}" type="application/x-shockwave-flash"
175
+ wmode="transparent" width="#{width}" height="#{height}"></embed>
176
+ </object>
177
+ EDOC
178
+ end
179
+
180
+ # The URL needed for embedding the video in a page.
181
+ #
182
+ # === Returns
183
+ # String: Absolute URL for embedding video
184
+ def embed_url
185
+ @player_url.sub('watch?', '').sub('=', '/')
186
+ end
187
+
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,169 @@
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
+ view_count = (el = entry.elements["yt:statistics"]) ? el.attributes["viewCount"].to_i : 0
90
+
91
+ noembed = entry.elements["yt:noembed"] ? true : false
92
+ racy = entry.elements["media:rating"] ? true : false
93
+
94
+ if where = entry.elements["georss:where"]
95
+ position = where.elements["gml:Point"].elements["gml:pos"].text
96
+ latitude, longitude = position.split(" ")
97
+ end
98
+
99
+ YouTubeG::Model::Video.new(
100
+ :video_id => video_id,
101
+ :published_at => published_at,
102
+ :updated_at => updated_at,
103
+ :categories => categories,
104
+ :keywords => keywords,
105
+ :title => title,
106
+ :html_content => html_content,
107
+ :author => author,
108
+ :description => description,
109
+ :duration => duration,
110
+ :media_content => media_content,
111
+ :player_url => player_url,
112
+ :thumbnails => thumbnails,
113
+ :rating => rating,
114
+ :view_count => view_count,
115
+ :noembed => noembed,
116
+ :racy => racy,
117
+ :where => where,
118
+ :position => position,
119
+ :latitude => latitude,
120
+ :longitude => longitude)
121
+ end
122
+
123
+ def parse_media_content (media_content_element)
124
+ content_url = media_content_element.attributes["url"]
125
+ format_code = media_content_element.attributes["yt:format"].to_i
126
+ format = YouTubeG::Model::Video::Format.by_code(format_code)
127
+ duration = media_content_element.attributes["duration"].to_i
128
+ mime_type = media_content_element.attributes["type"]
129
+ default = (media_content_element.attributes["isDefault"] == "true")
130
+
131
+ YouTubeG::Model::Content.new(
132
+ :url => content_url,
133
+ :format => format,
134
+ :duration => duration,
135
+ :mime_type => mime_type,
136
+ :default => default)
137
+ end
138
+ end
139
+
140
+ class VideosFeedParser < VideoFeedParser #:nodoc:
141
+
142
+ private
143
+ def parse_content(content)
144
+ doc = REXML::Document.new(content)
145
+ feed = doc.elements["feed"]
146
+
147
+ feed_id = feed.elements["id"].text
148
+ updated_at = Time.parse(feed.elements["updated"].text)
149
+ total_result_count = feed.elements["openSearch:totalResults"].text.to_i
150
+ offset = feed.elements["openSearch:startIndex"].text.to_i
151
+ max_result_count = feed.elements["openSearch:itemsPerPage"].text.to_i
152
+
153
+ videos = []
154
+ feed.elements.each("entry") do |entry|
155
+ videos << parse_entry(entry)
156
+ end
157
+
158
+ YouTubeG::Response::VideoSearch.new(
159
+ :feed_id => feed_id,
160
+ :updated_at => updated_at,
161
+ :total_result_count => total_result_count,
162
+ :offset => offset,
163
+ :max_result_count => max_result_count,
164
+ :videos => videos)
165
+ end
166
+ end
167
+
168
+ end
169
+ end