nddrylliog_youtube_it 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/Gemfile +5 -0
  2. data/Gemfile.lock +38 -0
  3. data/Manifest.txt +37 -0
  4. data/README.rdoc +296 -0
  5. data/Rakefile +21 -0
  6. data/VERSION +1 -0
  7. data/lib/youtube_it.rb +91 -0
  8. data/lib/youtube_it/chain_io.rb +76 -0
  9. data/lib/youtube_it/client.rb +469 -0
  10. data/lib/youtube_it/middleware/faraday_authheader.rb +24 -0
  11. data/lib/youtube_it/middleware/faraday_oauth.rb +21 -0
  12. data/lib/youtube_it/middleware/faraday_oauth2.rb +13 -0
  13. data/lib/youtube_it/middleware/faraday_youtubeit.rb +30 -0
  14. data/lib/youtube_it/model/activity.rb +17 -0
  15. data/lib/youtube_it/model/author.rb +13 -0
  16. data/lib/youtube_it/model/category.rb +11 -0
  17. data/lib/youtube_it/model/comment.rb +16 -0
  18. data/lib/youtube_it/model/contact.rb +19 -0
  19. data/lib/youtube_it/model/content.rb +18 -0
  20. data/lib/youtube_it/model/message.rb +12 -0
  21. data/lib/youtube_it/model/playlist.rb +11 -0
  22. data/lib/youtube_it/model/rating.rb +23 -0
  23. data/lib/youtube_it/model/subscription.rb +7 -0
  24. data/lib/youtube_it/model/thumbnail.rb +17 -0
  25. data/lib/youtube_it/model/user.rb +28 -0
  26. data/lib/youtube_it/model/video.rb +243 -0
  27. data/lib/youtube_it/parser.rb +543 -0
  28. data/lib/youtube_it/record.rb +12 -0
  29. data/lib/youtube_it/request/base_search.rb +76 -0
  30. data/lib/youtube_it/request/error.rb +15 -0
  31. data/lib/youtube_it/request/standard_search.rb +43 -0
  32. data/lib/youtube_it/request/user_search.rb +47 -0
  33. data/lib/youtube_it/request/video_search.rb +105 -0
  34. data/lib/youtube_it/request/video_upload.rb +552 -0
  35. data/lib/youtube_it/response/video_search.rb +41 -0
  36. data/lib/youtube_it/version.rb +4 -0
  37. data/test/files/recorded_response.xml +1 -0
  38. data/test/files/youtube_video_response.xml +53 -0
  39. data/test/helper.rb +9 -0
  40. data/test/test.mov +0 -0
  41. data/test/test_chain_io.rb +63 -0
  42. data/test/test_client.rb +504 -0
  43. data/test/test_field_search.rb +48 -0
  44. data/test/test_video.rb +48 -0
  45. data/test/test_video_feed_parser.rb +264 -0
  46. data/test/test_video_search.rb +147 -0
  47. data/youtube_it.gemspec +95 -0
  48. metadata +149 -0
@@ -0,0 +1,24 @@
1
+ module Faraday
2
+ class Request::AuthHeader < Faraday::Middleware
3
+
4
+ def call(env)
5
+ req_headers = env[:request_headers]
6
+ req_headers.merge!(@headers)
7
+ unless req_headers.include?("GData-Version")
8
+ req_headers.merge!("GData-Version" => "2")
9
+ end
10
+ unless req_headers.include?("Content-Type")
11
+ req_headers.merge!("Content-Type" => "application/atom+xml; charset=UTF-8")
12
+ end
13
+ unless req_headers.include?("Content-Length")
14
+ req_headers.merge!("Content-Length" => env[:body] ? "#{env[:body].length}" : "0")
15
+ end
16
+
17
+ @app.call(env)
18
+ end
19
+
20
+ def initialize(app, headers)
21
+ @app, @headers = app, headers
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ module Faraday
2
+ class Request::OAuth < Faraday::Middleware
3
+ dependency 'simple_oauth'
4
+
5
+ def call(env)
6
+ params = env[:body].is_a?(Hash) ? env[:body] : {}
7
+
8
+ signature_params = params.reject{ |k,v| v.respond_to?(:content_type) }
9
+
10
+ header = SimpleOAuth::Header.new(env[:method], env[:url], signature_params, @options)
11
+
12
+ env[:request_headers]['Authorization'] = header.to_s
13
+
14
+ @app.call(env)
15
+ end
16
+
17
+ def initialize(app, options)
18
+ @app, @options = app, options
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module Faraday
2
+ class Request::OAuth2 < Faraday::Middleware
3
+ def call(env)
4
+ env[:request_headers]['Authorization'] = "Bearer #{@access_token.token}"
5
+
6
+ @app.call(env)
7
+ end
8
+
9
+ def initialize(app, access_token)
10
+ @app, @access_token = app, access_token
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ module Faraday
2
+ class Response::YouTubeIt < Response::Middleware
3
+ def parse_upload_error_from(string)
4
+ begin
5
+ REXML::Document.new(string).elements["//errors"].inject('') do | all_faults, error|
6
+ if error.elements["internalReason"]
7
+ msg_error = error.elements["internalReason"].text
8
+ elsif error.elements["location"]
9
+ msg_error = error.elements["location"].text[/media:group\/media:(.*)\/text\(\)/,1]
10
+ else
11
+ msg_error = "Unspecified error"
12
+ end
13
+ code = error.elements["code"].text if error.elements["code"]
14
+ all_faults + sprintf("%s: %s\n", msg_error, code)
15
+ end
16
+ rescue
17
+ string[/<TITLE>(.+)<\/TITLE>/, 1] || string
18
+ end
19
+ end
20
+
21
+ def on_complete(env) #this method is called after finish request
22
+ msg = parse_upload_error_from(env[:body].gsub(/\n/, ''))
23
+ if env[:status] == 403 || env[:status] == 401
24
+ raise ::AuthenticationError.new(msg, env[:status])
25
+ elsif env[:status] / 10 != 20
26
+ raise ::UploadError.new(msg, env[:status])
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Activity < YouTubeIt::Record
4
+ # Attributes common to multiple activity types
5
+ attr_reader :type, :author, :videos, :video_id, :time
6
+
7
+ # video_rated
8
+ attr_reader :user_rating, :video_rating
9
+
10
+ # video_commented
11
+ attr_reader :comment_thread_url, :video_url
12
+
13
+ # friend_added and user_subscription_added
14
+ attr_reader :username
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Author < YouTubeIt::Record
4
+ # *String*: Author's YouTube username.
5
+ attr_reader :name
6
+
7
+ # *String*: Feed URL of the author.
8
+ attr_reader :uri
9
+
10
+ attr_reader :thumbnail_url
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Category < YouTubeIt::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 YouTubeIt
2
+ module Model
3
+ class Comment < YouTubeIt::Record
4
+ attr_reader :content, :published, :title, :updated, :url
5
+
6
+ # YouTubeIt::Model::Author:: Information about the YouTube user who owns a piece of video content.
7
+ attr_reader :author
8
+
9
+ # unique ID of the comment.
10
+ def unique_id
11
+ url.split("/").last
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,19 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Contact < YouTubeIt::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
+
15
+ # *String*:: The Youtube title of the contact.
16
+ attr_reader :title
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Content < YouTubeIt::Record
4
+ # *Boolean*:: Description of the video.
5
+ attr_reader :default
6
+ # *Fixnum*:: Length of the video in seconds.
7
+ attr_reader :duration
8
+ # YouTubeIt::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,12 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Message < YouTubeIt::Record
4
+ attr_reader :id, :name, :title, :summary, :published
5
+
6
+ def content
7
+ # This tag contains the same value as the <summary> tag.
8
+ self.summary
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Playlist < YouTubeIt::Record
4
+ attr_reader :title, :description, :summary, :playlist_id, :xml, :published, :response_code
5
+ def videos
6
+ YouTubeIt::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/playlists/#{playlist_id}?v=2").parse_videos
7
+ end
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,23 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Rating < YouTubeIt::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
+
16
+ # *Fixnum*:: Indicates how many people likes this video
17
+ attr_reader :likes
18
+
19
+ # *Fixnum*:: Indicates how many people dislikes this video
20
+ attr_reader :dislikes
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Subscription < YouTubeIt::Record
4
+ attr_reader :id, :title, :published
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Thumbnail < YouTubeIt::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,28 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class User < YouTubeIt::Record
4
+ attr_reader :age
5
+ attr_reader :books
6
+ attr_reader :company
7
+ attr_reader :description
8
+ attr_reader :gender
9
+ attr_reader :hobbies
10
+ attr_reader :hometown
11
+ attr_reader :last_login
12
+ attr_reader :location
13
+ attr_reader :join_date
14
+ attr_reader :movies
15
+ attr_reader :music
16
+ attr_reader :occupation
17
+ attr_reader :relationship
18
+ attr_reader :school
19
+ attr_reader :subscribers
20
+ attr_reader :upload_views
21
+ attr_reader :username
22
+ attr_reader :videos_watched
23
+ attr_reader :view_count
24
+ attr_reader :avatar
25
+ attr_reader :insight_uri
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,243 @@
1
+ # TODO
2
+ # * self atom feed
3
+ # * alternate youtube watch url
4
+ # * comments feedLink
5
+
6
+ class YouTubeIt
7
+ module Model
8
+ class Video < YouTubeIt::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
+ # YouTubeIt::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
+ # YouTubeIt::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 = YouTubeIt::Model::Video::Format.new(0, :flash)
46
+
47
+ # RTSP streaming URL for mobile video playback. H.263 video (176x144) and AMR audio.
48
+ RTSP = YouTubeIt::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 = YouTubeIt::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 = YouTubeIt::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 16:9 ratio.
62
+ attr_reader :widescreen
63
+
64
+ # *Boolean*:: Specifies that a video may or may not be embedded on other websites.
65
+ attr_reader :noembed
66
+
67
+ # *Fixnum*:: Specifies the order in which the video appears in a playlist.
68
+ attr_reader :position
69
+
70
+ # *Boolean*:: Specifies that a video is flagged as adult or not.
71
+ attr_reader :safe_search
72
+
73
+ # *String*: Specifies a URI that uniquely and permanently identifies the video.
74
+ attr_reader :video_id
75
+
76
+ # *Time*:: When the video was published on Youtube.
77
+ attr_reader :published_at
78
+
79
+ # *Time*:: When the video's data was last updated.
80
+ attr_reader :updated_at
81
+
82
+ # *Array*:: A array of YouTubeIt::Model::Category objects that describe the videos categories.
83
+ attr_reader :categories
84
+
85
+ # *Array*:: An array of words associated with the video.
86
+ attr_reader :keywords
87
+
88
+ # *String*:: Description of the video.
89
+ attr_reader :description
90
+
91
+ # *String*:: Title for the video.
92
+ attr_reader :title
93
+
94
+ # *String*:: Description of the video.
95
+ attr_reader :html_content
96
+
97
+ # YouTubeIt::Model::Author:: Information about the YouTube user who owns a piece of video content.
98
+ attr_reader :author
99
+
100
+ # *Array*:: An array of YouTubeIt::Model::Content objects describing the individual media content data available for this video. Most, but not all, videos offer this.
101
+ attr_reader :media_content
102
+
103
+ # *Array*:: An array of YouTubeIt::Model::Thumbnail objects that contain information regarding the videos thumbnail images.
104
+ attr_reader :thumbnails
105
+
106
+ # *String*:: The link to watch the URL on YouTubes website.
107
+ attr_reader :player_url
108
+
109
+ # YouTubeIt::Model::Rating:: Information about the videos rating.
110
+ attr_reader :rating
111
+
112
+ # *Fixnum*:: Number of times that the video has been viewed
113
+ attr_reader :view_count
114
+
115
+ # *Fixnum*:: Number of times that the video has been favorited
116
+ attr_reader :favorite_count
117
+
118
+ # *String*:: State of the video (processing, restricted, deleted, rejected and failed)
119
+ attr_reader :state
120
+
121
+ # *String*:: URI for insight for this video, if present; nil otherwise
122
+ attr_reader :insight_uri
123
+
124
+
125
+ # Geodata
126
+ attr_reader :position
127
+ attr_reader :latitude
128
+ attr_reader :longitude
129
+
130
+ # Videos related to the current video.
131
+ #
132
+ # === Returns
133
+ # YouTubeIt::Response::VideoSearch
134
+ def related
135
+ YouTubeIt::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/related?v=2").parse
136
+ end
137
+ # Video responses to the current video.
138
+ #
139
+ # === Returns
140
+ # YouTubeIt::Response::VideoSearch
141
+ def responses
142
+ YouTubeIt::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/responses?v=2").parse
143
+ end
144
+ # The ID of the video, useful for searching for the video again without having to store it anywhere.
145
+ # A regular query search, with this id will return the same video.
146
+ #
147
+ # === Example
148
+ # >> video.unique_id
149
+ # => "ZTUVgYoeN_o"
150
+ #
151
+ # === Returns
152
+ # String: The Youtube video id.
153
+ def unique_id
154
+ @unique_id || video_id[/videos\/([^<]+)/, 1] || video_id[/video\:([^<]+)/, 1]
155
+ end
156
+
157
+ # Allows you to check whether the video can be embedded on a webpage.
158
+ #
159
+ # === Returns
160
+ # Boolean: True if the video can be embedded, false if not.
161
+ def embeddable?
162
+ not @noembed
163
+ end
164
+
165
+ # Allows you to check whether the video is widescreen (16:9) or not.
166
+ #
167
+ # === Returns
168
+ # Boolean: True if the video is (approximately) 16:9, false if not.
169
+ def widescreen?
170
+ @widescreen
171
+ end
172
+
173
+ # Provides a URL and various other types of information about a video.
174
+ #
175
+ # === Returns
176
+ # YouTubeIt::Model::Content: Data about the embeddable video.
177
+ def default_media_content
178
+ @media_content.find { |c| c.is_default? }
179
+ end
180
+
181
+ # Gives you the HTML to embed the video on your website.
182
+ #
183
+ # === Returns
184
+ # String: The HTML for embedding the video on your website.
185
+ def embed_html(width = 425, height = 350)
186
+ <<EDOC
187
+ <object width="#{width}" height="#{height}">
188
+ <param name="movie" value="#{embed_url}"></param>
189
+ <param name="wmode" value="transparent"></param>
190
+ <embed src="#{embed_url}" type="application/x-shockwave-flash"
191
+ wmode="transparent" width="#{width}" height="#{height}"></embed>
192
+ </object>
193
+ EDOC
194
+ end
195
+
196
+ # Gives you the HTML 5 to embed the video on your website.
197
+ # Usefull for mobile that not support flash but has html5 browser
198
+ # === Returns
199
+ # String: The HTML for embedding the video on your website.
200
+ def embed_html5(params = {})
201
+ opts = {:class => params[:class] || "",
202
+ :id => params[:id] || "",
203
+ :width => params[:width] || "425",
204
+ :height => params[:height] || "350",
205
+ :frameborder => params[:frameborder] || "0",
206
+ :url_params => params[:url_params] || {}
207
+ }
208
+ url_opts = opts[:url_params].empty? ? "" : "?#{Rack::Utils::build_query(opts[:url_params])}"
209
+ <<EDOC
210
+ <iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="http://www.youtube.com/embed/#{unique_id}#{url_opts}" frameborder="#{opts[:frameborder]}"></iframe>
211
+ EDOC
212
+ end
213
+
214
+ # Gives you the HTML to embed the video on your website.
215
+ #
216
+ # === Returns
217
+ # String: The HTML for embedding the video on your website.
218
+ def embed_html_with_width(width = 1280)
219
+ height = (widescreen? ? width * 9/16 : width * 3/4) + 25
220
+
221
+ <<EDOC
222
+ <object width="#{width}" height="#{height}">
223
+ <param name="movie" value="#{embed_url}"></param>
224
+ <param name="wmode" value="transparent"></param>
225
+ <embed src="#{embed_url}" type="application/x-shockwave-flash"
226
+ wmode="transparent" width="#{width}" height="#{height}"></embed>
227
+ </object>
228
+ EDOC
229
+ end
230
+
231
+ # The URL needed for embedding the video in a page.
232
+ #
233
+ # === Returns
234
+ # String: Absolute URL for embedding video
235
+ def embed_url
236
+ @player_url.sub('watch?', '').sub('=', '/').sub('feature/', 'feature=')
237
+ end
238
+
239
+
240
+ end
241
+ end
242
+ end
243
+