youtube-g 0.4.1 → 0.4.9.9

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.
@@ -1,3 +1,27 @@
1
+ == 0.4.9.9 / 2008-09-01
2
+
3
+ * Add Geodata information (thanks Jose Galisteo)
4
+ * Added :page and :per_page options, this allows easier usage of the will_paginate
5
+ plugin with the library. The :offset and :max_results options are no longer available. [Daniel Insley]
6
+ * Added ability to get video responses on the instances of the YouTube::Model::Video object. [Daniel Insley]
7
+ * Added and improved the existing documentation [Daniel Insley]
8
+ * Fixed usage of deprecated yt:racy, now using media:rating [Daniel Insley]
9
+ * Renamed can_embed? method to embeddable? [Daniel Insley]
10
+ * Added ability for padingation and ordering on standard feeds. [Daniel Insley]
11
+ * Add error-handling for video upload errors. [FiXato]
12
+ * Add error-handling for authentication errors from YouTube during video upload. [FiXato]
13
+ * Add support for making videos private upon video upload. [FiXato]
14
+ * Fix issue with REXML parsing of video upload response. [FiXato]
15
+ * Fix issue with response code comparison. [FiXato]
16
+ * Authcode is now retrieved for video uploads. [FiXato]
17
+ * Add basic support for uploading videos [thanks Joe Damato]
18
+ * Add basic support for related videos [tmm1]
19
+ * Improve docs for order_by attribute [thanks Jason Arora]
20
+ * Added support for the "racy" parameter (choices are "include" or "exclude") [thanks Jason Arora]
21
+ * Add missing attribute reader for description [tmm1]
22
+ * Fix issue with missing yt:statistics and viewCount [tmm1]
23
+ * Allow Client#video_by to take either a url or a video id [tmm1]
24
+
1
25
  == 0.4.1 / 2008-02-11
2
26
 
3
27
  * Added 3GPP video format [shane]
@@ -17,7 +17,11 @@ lib/youtube_g/model/user.rb
17
17
  lib/youtube_g/model/video.rb
18
18
  lib/youtube_g/parser.rb
19
19
  lib/youtube_g/record.rb
20
+ lib/youtube_g/request/base_search.rb
21
+ lib/youtube_g/request/standard_search.rb
22
+ lib/youtube_g/request/user_search.rb
20
23
  lib/youtube_g/request/video_search.rb
24
+ lib/youtube_g/request/video_upload.rb
21
25
  lib/youtube_g/response/video_search.rb
22
26
  test/test_client.rb
23
27
  test/test_video.rb
data/README.txt CHANGED
@@ -1,6 +1,9 @@
1
1
  youtube-g
2
2
  by Shane Vitarana and Walter Korman
3
- http://rubyforge.org/projects/youtube-g/
3
+
4
+ Rubyforge: http://rubyforge.org/projects/youtube-g/
5
+ RDoc: http://youtube-g.rubyforge.org/
6
+ Google Group: http://groups.google.com/group/ruby-youtube-library
4
7
 
5
8
  == DESCRIPTION:
6
9
 
@@ -23,13 +26,13 @@ http://code.google.com/apis/youtube/overview.html
23
26
 
24
27
  Create a client:
25
28
 
26
- require 'rubygems'
27
29
  require 'youtube_g'
28
30
  client = YouTubeG::Client.new
29
31
 
30
32
  Basic queries:
31
33
 
32
34
  client.videos_by(:query => "penguin")
35
+ client.videos_by(:query => "penguin", :page => 2, :per_page => 15)
33
36
  client.videos_by(:tags => ['tiger', 'leopard'])
34
37
  client.videos_by(:categories => [:news, :sports])
35
38
  client.videos_by(:categories => [:news, :sports], :tags => ['soccer', 'football'])
@@ -38,6 +41,7 @@ Basic queries:
38
41
  Standard feeds:
39
42
 
40
43
  client.videos_by(:most_viewed)
44
+ client.videos_by(:most_linked, :page => 3)
41
45
  client.videos_by(:top_rated, :time => :today)
42
46
 
43
47
  Advanced queries (with boolean operators OR (either), AND (include), NOT (exclude)):
data/TODO.txt CHANGED
@@ -1,12 +1,10 @@
1
1
  [ ] stub out http request/response cycle for tests
2
- [ ] consider defaulting the client to no-logger, rather than outputting to STDOUT.
3
2
  [ ] allow specifying values as single items where you don't need to wrap in a list, e.g. :tags => :chickens instead of :tags => [ 'chickens' ]
4
3
  [ ] make sure symbols will work as well as tags everywhere (again, :tags => :chickens is same as :tags => 'chickens')
5
4
  [ ] figure out better structure for class/file (either rename request/video_search.rb or split into one class per file again)
6
5
  [ ] restore spaces after method def names
7
6
  [ ] use a proxy for testing with static sample result xml so we have repeatable tests
8
7
  [ ] Clean up tests using Shoulda to define contexts
9
- [ ] Consolidate requires
10
8
  [ ] Allow :category and :categories for query DSL
11
9
  [ ] Exception handling
12
10
 
@@ -1,3 +1,10 @@
1
+ require 'logger'
2
+ require 'open-uri'
3
+ require 'net/https'
4
+ require 'digest/md5'
5
+ require 'rexml/document'
6
+ require 'cgi'
7
+
1
8
  require File.dirname(__FILE__) + '/youtube_g/client'
2
9
  require File.dirname(__FILE__) + '/youtube_g/record'
3
10
  require File.dirname(__FILE__) + '/youtube_g/parser'
@@ -10,9 +17,13 @@ require File.dirname(__FILE__) + '/youtube_g/model/rating'
10
17
  require File.dirname(__FILE__) + '/youtube_g/model/thumbnail'
11
18
  require File.dirname(__FILE__) + '/youtube_g/model/user'
12
19
  require File.dirname(__FILE__) + '/youtube_g/model/video'
20
+ require File.dirname(__FILE__) + '/youtube_g/request/base_search'
21
+ require File.dirname(__FILE__) + '/youtube_g/request/user_search'
22
+ require File.dirname(__FILE__) + '/youtube_g/request/standard_search'
23
+ require File.dirname(__FILE__) + '/youtube_g/request/video_upload'
13
24
  require File.dirname(__FILE__) + '/youtube_g/request/video_search'
14
25
  require File.dirname(__FILE__) + '/youtube_g/response/video_search'
15
26
 
16
- class YouTubeG
17
- VERSION = '0.4.1'
27
+ class YouTubeG #:nodoc:
28
+ VERSION = '0.4.9.9'
18
29
  end
@@ -1,35 +1,85 @@
1
- require 'logger'
2
-
3
1
  class YouTubeG
4
2
  class Client
5
3
  attr_accessor :logger
6
4
 
7
- def initialize(logger=Logger.new(STDOUT))
8
- @logger = logger
5
+ def initialize(logger=false)
6
+ @logger = Logger.new(STDOUT) if logger
9
7
  end
10
-
11
- # Params can be one of :most_viewed, :top_rated, :recently_featured, :watch_on_mobile
12
- # Or :tags, :categories, :query, :user
8
+
9
+ # Retrieves an array of standard feed, custom query, or user videos.
10
+ #
11
+ # === Parameters
12
+ # If fetching videos for a standard feed:
13
+ # params<Symbol>:: Accepts a symbol of :top_rated, :top_favorites, :most_viewed,
14
+ # :most_popular, :most_recent, :most_discussed, :most_linked,
15
+ # :most_responded, :recently_featured, and :watch_on_mobile.
16
+ #
17
+ # You can find out more specific information about what each standard feed provides
18
+ # by visiting: http://code.google.com/apis/youtube/reference.html#Standard_feeds
19
+ #
20
+ # options<Hash> (optional):: Accepts the options of :time, :page (default is 1),
21
+ # and :per_page (default is 25). :offset and :max_results
22
+ # can also be passed for a custom offset.
23
+ #
24
+ # If fetching videos by tags, categories, query:
25
+ # params<Hash>:: Accepts the keys :tags, :categories, :query, :order_by,
26
+ # :author, :racy, :response_format, :video_format, :page (default is 1),
27
+ # and :per_page(default is 25)
28
+ #
29
+ # options<Hash>:: Not used. (Optional)
30
+ #
31
+ # If fetching videos for a particular user:
32
+ # params<Hash>:: Key of :user with a value of the username.
33
+ # options<Hash>:: Not used. (Optional)
34
+ # === Returns
35
+ # YouTubeG::Response::VideoSearch
13
36
  def videos_by(params, options={})
37
+ request_params = params.respond_to?(:to_hash) ? params : options
38
+ request_params[:page] = integer_or_default(request_params[:page], 1)
39
+
40
+ unless request_params[:max_results]
41
+ request_params[:max_results] = integer_or_default(request_params[:per_page], 25)
42
+ end
43
+
44
+ unless request_params[:offset]
45
+ request_params[:offset] = calculate_offset(request_params[:page], request_params[:max_results] )
46
+ end
47
+
14
48
  if params.respond_to?(:to_hash) and not params[:user]
15
- request = YouTubeG::Request::VideoSearch.new(params)
16
-
49
+ request = YouTubeG::Request::VideoSearch.new(request_params)
17
50
  elsif (params.respond_to?(:to_hash) && params[:user]) || (params == :favorites)
18
- request = YouTubeG::Request::UserSearch.new(params, options)
19
-
51
+ request = YouTubeG::Request::UserSearch.new(request_params, options)
20
52
  else
21
- request = YouTubeG::Request::StandardSearch.new(params, options)
53
+ request = YouTubeG::Request::StandardSearch.new(params, request_params)
22
54
  end
23
55
 
24
- logger.debug "Submitting request [url=#{request.url}]."
56
+ logger.debug "Submitting request [url=#{request.url}]." if logger
25
57
  parser = YouTubeG::Parser::VideosFeedParser.new(request.url)
26
58
  parser.parse
27
59
  end
28
60
 
29
- def video_by(video_id)
61
+ # Retrieves a single YouTube video.
62
+ #
63
+ # === Parameters
64
+ # vid<String>:: The ID or URL of the video that you'd like to retrieve.
65
+ #
66
+ # === Returns
67
+ # YouTubeG::Model::Video
68
+ def video_by(vid)
69
+ video_id = vid =~ /^http/ ? vid : "http://gdata.youtube.com/feeds/videos/#{vid}"
30
70
  parser = YouTubeG::Parser::VideoFeedParser.new(video_id)
31
71
  parser.parse
32
72
  end
33
73
 
74
+ private
75
+
76
+ def calculate_offset(page, per_page)
77
+ page == 1 ? 1 : ((per_page * page) - per_page + 1)
78
+ end
79
+
80
+ def integer_or_default(value, default)
81
+ value = value.to_i
82
+ value > 0 ? value : default
83
+ end
34
84
  end
35
85
  end
@@ -1,5 +1,3 @@
1
- require 'logger'
2
-
3
1
  class YouTubeG
4
2
 
5
3
  # TODO: Why is this needed? Does this happen if running standalone w/o Rails?
@@ -1,7 +1,10 @@
1
1
  class YouTubeG
2
2
  module Model
3
3
  class Author < YouTubeG::Record
4
+ # *String*: Author's YouTube username.
4
5
  attr_reader :name
6
+
7
+ # *String*: Feed URL of the author.
5
8
  attr_reader :uri
6
9
  end
7
10
  end
@@ -1,7 +1,10 @@
1
1
  class YouTubeG
2
2
  module Model
3
3
  class Category < YouTubeG::Record
4
- attr_reader :label
4
+ # *String*:: Name of the YouTube category
5
+ attr_reader :label
6
+
7
+ # *String*:: Identifies the type of item described.
5
8
  attr_reader :term
6
9
  end
7
10
  end
@@ -1,7 +1,15 @@
1
1
  class YouTubeG
2
2
  module Model
3
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
+ #
4
10
  attr_reader :status
11
+
12
+ # *String*:: The Youtube username of the contact.
5
13
  attr_reader :username
6
14
  end
7
15
  end
@@ -1,10 +1,15 @@
1
1
  class YouTubeG
2
2
  module Model
3
3
  class Content < YouTubeG::Record
4
+ # *Boolean*:: Description of the video.
4
5
  attr_reader :default
6
+ # *Fixnum*:: Length of the video in seconds.
5
7
  attr_reader :duration
8
+ # YouTubeG::Model::Video::Format:: Specifies the video format of the video object
6
9
  attr_reader :format
10
+ # *String*:: Specifies the MIME type of the media object.
7
11
  attr_reader :mime_type
12
+ # *String*:: Specifies the URL for the media object.
8
13
  attr_reader :url
9
14
 
10
15
  alias :is_default? :default
@@ -1,6 +1,7 @@
1
1
  class YouTubeG
2
2
  module Model
3
3
  class Playlist < YouTubeG::Record
4
+ # *String*:: User entered description for the playlist.
4
5
  attr_reader :description
5
6
  end
6
7
  end
@@ -1,9 +1,16 @@
1
1
  class YouTubeG
2
2
  module Model
3
3
  class Rating < YouTubeG::Record
4
+ # *Float*:: Average rating given to the video
4
5
  attr_reader :average
6
+
7
+ # *Fixnum*:: Maximum rating that can be assigned to the video
5
8
  attr_reader :max
9
+
10
+ # *Fixnum*:: Minimum rating that can be assigned to the video
6
11
  attr_reader :min
12
+
13
+ # *Fixnum*:: Indicates how many people have rated the video
7
14
  attr_reader :rater_count
8
15
  end
9
16
  end
@@ -1,9 +1,16 @@
1
1
  class YouTubeG
2
2
  module Model
3
3
  class Thumbnail < YouTubeG::Record
4
+ # *String*:: URL for the thumbnail image.
4
5
  attr_reader :url
6
+
7
+ # *Fixnum*:: Height of the thumbnail image.
5
8
  attr_reader :height
9
+
10
+ # *Fixnum*:: Width of the thumbnail image.
6
11
  attr_reader :width
12
+
13
+ # *String*:: Specifies the time offset at which the frame shown in the thumbnail image appears in the video.
7
14
  attr_reader :time
8
15
  end
9
16
  end
@@ -1,87 +1,171 @@
1
+ # TODO
2
+ # * self atom feed
3
+ # * alternate youtube watch url
4
+ # * comments feedLink
5
+
1
6
  class YouTubeG
2
7
  module Model
3
8
  class Video < YouTubeG::Record
4
9
  # Describes the various file formats in which a Youtube video may be
5
10
  # made available and allows looking them up by format code number.
6
- #
7
11
  class Format
8
12
  @@formats = Hash.new
9
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
10
22
  def initialize(format_code, name)
11
23
  @format_code = format_code
12
24
  @name = name
13
25
 
14
26
  @@formats[format_code] = self
15
27
  end
16
-
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
17
40
  def self.by_code(format_code)
18
41
  @@formats[format_code]
19
42
  end
20
43
 
21
- # Flash format on YouTube site. All videos are available in this
22
- # format.
23
- #
44
+ # Flash format on YouTube site. All videos are available in this format.
24
45
  FLASH = YouTubeG::Model::Video::Format.new(0, :flash)
25
46
 
26
- # RTSP streaming URL for mobile video playback. H.263 video (176x144)
27
- # and AMR audio.
28
- #
47
+ # RTSP streaming URL for mobile video playback. H.263 video (176x144) and AMR audio.
29
48
  RTSP = YouTubeG::Model::Video::Format.new(1, :rtsp)
30
49
 
31
50
  # HTTP URL to the embeddable player (SWF) for this video. This format
32
51
  # is not available for a video that is not embeddable.
33
- #
34
52
  SWF = YouTubeG::Model::Video::Format.new(5, :swf)
35
53
 
54
+ # RTSP streaming URL for mobile video playback. MPEG-4 SP video (up to 176x144) and AAC audio.
36
55
  THREE_GPP = YouTubeG::Model::Video::Format.new(6, :three_gpp)
37
56
  end
38
-
57
+
58
+ # *Fixnum*:: Duration of a video in seconds.
39
59
  attr_reader :duration
60
+
61
+ # *Boolean*:: Specifies that a video may or may not be embedded on other websites.
40
62
  attr_reader :noembed
63
+
64
+ # *Fixnum*:: Specifies the order in which the video appears in a playlist.
41
65
  attr_reader :position
66
+
67
+ # *Boolean*:: Specifies that a video is flagged as adult or not.
42
68
  attr_reader :racy
43
- attr_reader :statistics
44
69
 
70
+ # *String*: Specifies a URI that uniquely and permanently identifies the video.
45
71
  attr_reader :video_id
72
+
73
+ # *Time*:: When the video was published on Youtube.
46
74
  attr_reader :published_at
75
+
76
+ # *Time*:: When the video's data was last updated.
47
77
  attr_reader :updated_at
78
+
79
+ # *Array*:: A array of YouTubeG::Model::Category objects that describe the videos categories.
48
80
  attr_reader :categories
81
+
82
+ # *Array*:: An array of words associated with the video.
49
83
  attr_reader :keywords
84
+
85
+ # *String*:: Description of the video.
86
+ attr_reader :description
87
+
88
+ # *String*:: Title for the video.
50
89
  attr_reader :title
90
+
91
+ # *String*:: Description of the video.
51
92
  attr_reader :html_content
93
+
94
+ # YouTubeG::Model::Author:: Information about the YouTube user who owns a piece of video content.
52
95
  attr_reader :author
53
-
54
- # YouTubeG::Model::Content records describing the individual media content
55
- # data available for this video. Most, but not all, videos offer this.
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.
56
98
  attr_reader :media_content
57
-
58
- attr_reader :thumbnails # YouTubeG::Model::Thumbnail records
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.
59
104
  attr_reader :player_url
105
+
106
+ # YouTubeG::Model::Rating:: Information about the videos rating.
60
107
  attr_reader :rating
108
+
109
+ # *Fixnum*:: Number of times that the video has been viewed
61
110
  attr_reader :view_count
62
111
 
63
- # TODO:
64
- # self atom feed
65
- # alternate youtube watch url
66
- # responses feed
67
- # related feed
68
- # comments feedLink
69
-
70
- # For convenience, the video_id with the URL stripped out, useful for searching for the video again
71
- # without having to store it anywhere. A regular query search, with this id will return the same video.
72
- # http://gdata.youtube.com/feeds/videos/ZTUVgYoeN_o
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.
73
145
  def unique_id
74
- video_id.match(/videos\/([^<]+)/).captures.first
146
+ video_id[/videos\/([^<]+)/, 1]
75
147
  end
76
148
 
77
- def can_embed?
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?
78
154
  not @noembed
79
155
  end
80
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.
81
161
  def default_media_content
82
162
  @media_content.find { |c| c.is_default? }
83
163
  end
84
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.
85
169
  def embed_html(width = 425, height = 350)
86
170
  <<EDOC
87
171
  <object width="#{width}" height="#{height}">
@@ -93,6 +177,10 @@ class YouTubeG
93
177
  EDOC
94
178
  end
95
179
 
180
+ # The URL needed for embedding the video in a page.
181
+ #
182
+ # === Returns
183
+ # String: Absolute URL for embedding video
96
184
  def embed_url
97
185
  @player_url.sub('watch?', '').sub('=', '/')
98
186
  end