msp-youtube-g 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,5 +1,8 @@
1
1
  == trunk
2
2
 
3
+ * Add error-handling for video upload errors. [FiXato]
4
+ * Add error-handling for authentication errors from YouTube during video upload. [FiXato]
5
+ * Add support for making videos private upon video upload. [FiXato]
3
6
  * Fix issue with REXML parsing of video upload response. [FiXato]
4
7
  * Fix issue with response code comparison. [FiXato]
5
8
  * Authcode is now retrieved for video uploads. [FiXato]
@@ -7,6 +7,7 @@ class YouTubeG
7
7
 
8
8
  module Upload
9
9
  class UploadError < Exception; end
10
+ class AuthenticationError < Exception; end
10
11
 
11
12
  # require 'youtube_g'
12
13
  #
@@ -17,9 +18,23 @@ class YouTubeG
17
18
  # :keywords => %w[cool blah test]
18
19
 
19
20
  class VideoUpload
20
-
21
- def initialize user, pass, dev_key, client_id = 'youtube_g'
22
- @user, @pass, @dev_key, @client_id = user, pass, dev_key, client_id
21
+
22
+ attr_accessor :auth_token
23
+ def initialize user, pass, dev_key, client_id = 'youtube_g', auth_token = nil
24
+ @user, @pass, @dev_key, @client_id, @auth_token = user, pass, dev_key, client_id, auth_token
25
+ end
26
+
27
+ # TODO merge this in with logger.rb or replace logger.rb
28
+ def logger
29
+ if not Object.const_defined?(get_rails_default_logger_name)
30
+ Logger.new(STDOUT)
31
+ else
32
+ eval(get_rails_default_logger_name)
33
+ end
34
+ end
35
+
36
+ def get_rails_default_logger_name
37
+ "RAILS_DEFAULT_LOGGER"
23
38
  end
24
39
 
25
40
  #
@@ -32,8 +47,14 @@ class YouTubeG
32
47
  # :description
33
48
  # :category
34
49
  # :keywords
50
+ # :private
51
+ # Specifying :private will make the video private, otherwise it will be public.
35
52
  #
36
-
53
+ # When one of the fields is invalid according to YouTube,
54
+ # an UploadError will be returned. Its message contains a list of newline separated
55
+ # errors, containing the key and its error code.
56
+ #
57
+ # When the authentication credentials are incorrect, an AuthenticationError will be raised.
37
58
  def upload data, opts = {}
38
59
  data = data.respond_to?(:read) ? data.read : data
39
60
  @opts = { :mime_type => 'video/mp4',
@@ -46,29 +67,33 @@ class YouTubeG
46
67
  upload_body = generate_upload_body(boundary, video_xml, data)
47
68
 
48
69
  upload_header = {
49
- "Authorization" => "GoogleLogin auth=#{auth_token}",
70
+ "Authorization" => "GoogleLogin auth=#{derive_auth_token}",
50
71
  "X-GData-Client" => "#{@client_id}",
51
72
  "X-GData-Key" => "key=#{@dev_key}",
52
73
  "Slug" => "#{@opts[:filename]}",
53
74
  "Content-Type" => "multipart/related; boundary=#{boundary}",
54
75
  "Content-Length" => "#{upload_body.length}",
55
76
  }
56
- puts("MSP upload_header [#{upload_header}]")
77
+ logger.debug("upload_header [#{upload_header}]")
57
78
 
58
79
  direct_upload_url = "/feeds/api/users/#{@user}/uploads"
59
- puts("MSP direct_upload_url [#{direct_upload_url}]")
80
+ logger.debug("direct_upload_url [#{direct_upload_url}]")
60
81
 
61
82
  Net::HTTP.start(base_url) do |upload|
62
83
  response = upload.post(direct_upload_url, upload_body, upload_header)
63
- xml = REXML::Document.new(response.body)
64
- if (xml.elements["//id"])
65
- puts("MSP response xml [#{xml}]")
66
- return xml.elements["//id"].text[/videos\/(.+)/, 1]
67
- else
68
- return xml
84
+ if response.code.to_i == 403
85
+ raise AuthenticationError, response.body[/<TITLE>(.+)<\/TITLE>/, 1]
86
+ elsif response.code.to_i != 201
87
+ upload_error = ''
88
+ xml = REXML::Document.new(response.body)
89
+ errors = xml.elements["//errors"]
90
+ errors.each do |error|
91
+ location = error.elements["location"].text[/media:group\/media:(.*)\/text\(\)/,1]
92
+ code = error.elements["code"].text
93
+ upload_error << sprintf("%s: %s\r\n", location, code)
94
+ end
95
+ raise UploadError, upload_error
69
96
  end
70
-
71
-
72
97
  end
73
98
 
74
99
  end
@@ -83,31 +108,34 @@ class YouTubeG
83
108
  "An43094fu"
84
109
  end
85
110
 
86
- def auth_token
111
+ def derive_auth_token
87
112
  unless @auth_token
88
113
  http = Net::HTTP.new("www.google.com", 443)
89
114
  http.use_ssl = true
90
115
  body = "Email=#{CGI::escape @user}&Passwd=#{CGI::escape @pass}&service=youtube&source=#{CGI::escape @client_id}"
91
- puts("MSP auth body [#{body}]")
116
+ logger.debug("auth body [#{body}]")
92
117
  response = http.post("/youtube/accounts/ClientLogin", body, "Content-Type" => "application/x-www-form-urlencoded")
93
- raise UploadError, "MSP "+response.body[/Error=(.+)/,1] if response.code.to_i != 200
94
- puts("MSP response.body [#{response.body}]")
118
+ raise UploadError, ""+response.body[/Error=(.+)/,1] if response.code.to_i != 200
119
+ logger.debug("response.body [#{response.body}]")
95
120
  @auth_token = response.body[/Auth=(.+)/, 1]
96
121
 
97
122
  end
98
- puts "MSP auth_token [#{@auth_token}]"
123
+ logger.debug "auth_token [#{@auth_token}]"
99
124
  @auth_token
100
125
  end
101
126
 
102
127
  def video_xml
103
- %[<?xml version="1.0"?>
104
- <entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
105
- <media:group>
106
- <media:title type="plain">#{@opts[:title]}</media:title>
107
- <media:description type="plain">#{@opts[:description]}</media:description>
108
- <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">#{@opts[:category]}</media:category>
109
- <media:keywords>#{@opts[:keywords].join ","}</media:keywords>
110
- </media:group></entry> ]
128
+ video_xml = ''
129
+ video_xml << '<?xml version="1.0"?>'
130
+ video_xml << '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">'
131
+ video_xml << '<media:group>'
132
+ video_xml << '<media:title type="plain">%s</media:title>' % @opts[:title]
133
+ video_xml << '<media:description type="plain">%s</media:description>' % @opts[:description]
134
+ video_xml << '<media:keywords>%s</media:keywords>' % @opts[:keywords].join(",")
135
+ video_xml << '<media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">%s</media:category>' % @opts[:category]
136
+ video_xml << '<yt:private/>' if @opts[:private]
137
+ video_xml << '</media:group>'
138
+ video_xml << '</entry>'
111
139
  end
112
140
 
113
141
  def generate_upload_body(boundary, video_xml, data)
@@ -119,8 +147,8 @@ class YouTubeG
119
147
  upload_body << "Content-Type: #{@opts[:mime_type]}\r\nContent-Transfer-Encoding: binary\r\n\r\n"
120
148
  upload_body << data
121
149
  upload_body << "\r\n--#{boundary}--\r\n"
122
- end
123
-
150
+ end
151
+
124
152
  end
125
153
  end
126
154
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msp-youtube-g
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Vitarana