chocolate_rain 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +1 -0
  4. data/chocolate_rain.gemspec +26 -0
  5. data/generators/youtube_model/USAGE +3 -0
  6. data/generators/youtube_model/templates/config.yml +6 -0
  7. data/generators/youtube_model/templates/model.rb +17 -0
  8. data/generators/youtube_model/templates/unit_test.rb +7 -0
  9. data/generators/youtube_model/youtube_model_generator.rb +15 -0
  10. data/lib/.DS_Store +0 -0
  11. data/lib/chocolate_rain.rb +5 -0
  12. data/lib/chocolate_rain/version.rb +3 -0
  13. data/lib/gdata/auth/authsub.rb +161 -0
  14. data/lib/gdata/auth/clientlogin.rb +102 -0
  15. data/lib/gdata/client.rb +84 -0
  16. data/lib/gdata/client/apps.rb +27 -0
  17. data/lib/gdata/client/base.rb +182 -0
  18. data/lib/gdata/client/blogger.rb +28 -0
  19. data/lib/gdata/client/booksearch.rb +28 -0
  20. data/lib/gdata/client/calendar.rb +58 -0
  21. data/lib/gdata/client/contacts.rb +28 -0
  22. data/lib/gdata/client/doclist.rb +28 -0
  23. data/lib/gdata/client/finance.rb +28 -0
  24. data/lib/gdata/client/gbase.rb +28 -0
  25. data/lib/gdata/client/gmail.rb +28 -0
  26. data/lib/gdata/client/health.rb +28 -0
  27. data/lib/gdata/client/notebook.rb +28 -0
  28. data/lib/gdata/client/photos.rb +29 -0
  29. data/lib/gdata/client/spreadsheets.rb +28 -0
  30. data/lib/gdata/client/webmaster_tools.rb +28 -0
  31. data/lib/gdata/client/youtube.rb +47 -0
  32. data/lib/gdata/g_data.rb +22 -0
  33. data/lib/gdata/http.rb +18 -0
  34. data/lib/gdata/http/default_service.rb +82 -0
  35. data/lib/gdata/http/mime_body.rb +95 -0
  36. data/lib/gdata/http/request.rb +74 -0
  37. data/lib/gdata/http/response.rb +44 -0
  38. data/lib/youtube_helpers.rb +58 -0
  39. data/lib/youtube_model.rb +341 -0
  40. metadata +84 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in chocolate_rain.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "chocolate_rain/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "chocolate_rain"
7
+ s.version = ChocolateRain::VERSION
8
+ s.authors = ["Kevin Hopkins"]
9
+ s.email = ["kevin@wearefound.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{YouTube API wrapper for 1.9.2 compatible with Rails >= 3.1}
12
+ s.description = %q{YouTube API wrapper for 1.9.2 compatible with Rails >= 3.1}
13
+
14
+ s.rubyforge_project = "chocolate_rain"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ s.required_rubygems_version = ">= 1.8.6"
25
+
26
+ end
@@ -0,0 +1,3 @@
1
+ ./script/generate youtube_model MODELNAME
2
+
3
+ Generates an ActiveResource model that is ready for interact with YouTube API
@@ -0,0 +1,6 @@
1
+ developer_tag: your_developer_tag
2
+ auth_sub:
3
+ secure: 0
4
+ session: 0
5
+ developer_key: YourAPIKeyGoesHere
6
+ client_key: And-Here-Goes-Your-Client-Key
@@ -0,0 +1,17 @@
1
+ class <%= class_name %> < YouTubeModel::Base #inherits from ActiveResource::Base
2
+ self.default_youtube_options= {:itemPerPage => 10}
3
+
4
+ schema do
5
+ attribute :title, :string
6
+ attribute :description, :string
7
+ attribute :keywords, :string
8
+ attribute :category, :string
9
+ attribute :file, :string
10
+ attribute :token, :string
11
+ end
12
+
13
+ validates_presence_of :title
14
+ validates_presence_of :token #needed on remote crud operation
15
+ validates_presence_of :file, :if => Proc.new{|<%=singular_name%>| <%=singular_name%>.new? }
16
+
17
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>Test < Test::Unit::TestCase
4
+ def test_this_plugin
5
+ # needs some tests...
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ class YoutubeModelGenerator < Rails::Generators::NamedBase
2
+
3
+ desc "Generate youtube_model files, Usage: rails g youtube_model ModelName"
4
+
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ check_class_collision
8
+
9
+ def manifest
10
+ template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
11
+ template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
12
+ template 'config.yml', File.join('config', "#{file_name}_config.yml")
13
+ end
14
+
15
+ end
data/lib/.DS_Store ADDED
Binary file
@@ -0,0 +1,5 @@
1
+ require "chocolate_rain/version"
2
+
3
+ module ChocolateRain
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,3 @@
1
+ module ChocolateRain
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,161 @@
1
+ # Copyright (C) 2008 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'cgi'
16
+ require 'openssl'
17
+ require 'base64'
18
+
19
+ module GData
20
+ module Auth
21
+
22
+ # This class implements AuthSub signatures for Data API requests.
23
+ # It can be used with a GData::Client::GData object.
24
+ class AuthSub
25
+
26
+ # The URL of AuthSubRequest.
27
+ REQUEST_HANDLER = 'https://www.google.com/accounts/AuthSubRequest'
28
+ # The URL of AuthSubSessionToken.
29
+ SESSION_HANDLER = 'https://www.google.com/accounts/AuthSubSessionToken'
30
+ # The URL of AuthSubRevokeToken.
31
+ REVOKE_HANDLER = 'https://www.google.com/accounts/AuthSubRevokeToken'
32
+ # The URL of AuthSubInfo.
33
+ INFO_HANDLER = 'https://www.google.com/accounts/AuthSubTokenInfo'
34
+ # 2 ** 64, the largest 64 bit unsigned integer
35
+ BIG_INT_MAX = 18446744073709551616
36
+
37
+ # AuthSub access token.
38
+ attr_accessor :token
39
+ # Private RSA key used to sign secure requests.
40
+ attr_reader :private_key
41
+
42
+ # Initialize the class with a new token. Optionally pass a private
43
+ # key or custom URLs.
44
+ def initialize(token, options = {})
45
+ if token.nil?
46
+ raise ArgumentError, "Token cannot be nil."
47
+ elsif token.class != String
48
+ raise ArgumentError, "Token must be a String."
49
+ end
50
+
51
+ @token = token
52
+
53
+ options.each do |key, value|
54
+ self.send("#{key}=", value)
55
+ end
56
+ end
57
+
58
+ # Set the private key to use with this AuthSub token.
59
+ # The key can be an OpenSSL::PKey::RSA object, a string containing a
60
+ # private key in PEM format, or a string specifying a path to a PEM
61
+ # file that contains the private key.
62
+ def private_key=(key)
63
+ begin
64
+ if key.nil? or key.class == OpenSSL::PKey::RSA
65
+ @private_key = key
66
+ elsif File.exists?(key)
67
+ key_from_file = File.read(key)
68
+ @private_key = OpenSSL::PKey::RSA.new(key_from_file)
69
+ else
70
+ @private_key = OpenSSL::PKey::RSA.new(key)
71
+ end
72
+ rescue
73
+ raise ArgumentError, "Not a valid private key."
74
+ end
75
+ end
76
+
77
+ # Sign a GData::Http::Request object with a valid AuthSub Authorization
78
+ # header.
79
+ def sign_request!(request)
80
+ header = "AuthSub token=\"#{@token}\""
81
+
82
+ if @private_key
83
+ time = Time.now.to_i
84
+ nonce = OpenSSL::BN.rand_range(BIG_INT_MAX)
85
+ method = request.method.to_s.upcase
86
+ data = "#{method} #{request.url} #{time} #{nonce}"
87
+ sig = @private_key.sign(OpenSSL::Digest::SHA1.new, data)
88
+ sig = Base64.encode64(sig).gsub(/\n/, '')
89
+ header = "#{header} sigalg=\"rsa-sha1\" data=\"#{data}\""
90
+ header = "#{header} sig=\"#{sig}\""
91
+ end
92
+
93
+ request.headers['Authorization'] = header
94
+ end
95
+
96
+ # Upgrade the current token into a session token.
97
+ def upgrade
98
+ request = GData::HTTP::Request.new(SESSION_HANDLER)
99
+ sign_request!(request)
100
+ service = GData::HTTP::DefaultService.new
101
+ response = service.make_request(request)
102
+ if response.status_code != 200
103
+ raise GData::Client::AuthorizationError.new(response)
104
+ end
105
+
106
+ @token = response.body[/Token=(.*)/,1]
107
+ return @token
108
+
109
+ end
110
+
111
+ # Return some information about the current token. If the current token
112
+ # is a one-time use token, this operation will use it up!
113
+ def info
114
+ request = GData::HTTP::Request.new(INFO_HANDLER)
115
+ sign_request!(request)
116
+ service = GData::HTTP::DefaultService.new
117
+ response = service.make_request(request)
118
+ if response.status_code != 200
119
+ raise GData::Client::AuthorizationError.new(response)
120
+ end
121
+
122
+ result = {}
123
+ result[:target] = response.body[/Target=(.*)/,1]
124
+ result[:scope] = response.body[/Scope=(.*)/,1]
125
+ result[:secure] = response.body[/Secure=(.*)/,1]
126
+ return result
127
+
128
+ end
129
+
130
+ # Revoke the token.
131
+ def revoke
132
+ request = GData::HTTP::Request.new(REVOKE_HANDLER)
133
+ sign_request!(request)
134
+ service = GData::HTTP::DefaultService.new
135
+ response = service.make_request(request)
136
+ if response.status_code != 200
137
+ raise GData::Client::AuthorizationError.new(response)
138
+ end
139
+
140
+ end
141
+
142
+ # Return the proper URL for an AuthSub approval page with the requested
143
+ # scope. next_url should be a URL that points back to your code that
144
+ # will receive the token. domain is optionally a Google Apps domain.
145
+ def self.get_url(next_url, scope, secure = false, session = true,
146
+ domain = nil)
147
+ next_url = CGI.escape(next_url)
148
+ scope = CGI.escape(scope)
149
+ secure = secure ? 1 : 0
150
+ session = session ? 1 : 0
151
+ body = "next=#{next_url}&scope=#{scope}&session=#{session}" +
152
+ "&secure=#{secure}"
153
+ if domain
154
+ domain = CGI.escape(domain)
155
+ body = "#{body}&hd=#{domain}"
156
+ end
157
+ return "#{REQUEST_HANDLER}?#{body}"
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,102 @@
1
+ # Copyright (C) 2008 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'cgi'
16
+
17
+ module GData
18
+ module Auth
19
+
20
+ # This class implements ClientLogin signatures for Data API requests.
21
+ # It can be used with a GData::Client::GData object.
22
+ class ClientLogin
23
+
24
+ # The ClientLogin authentication handler
25
+ attr_accessor :auth_url
26
+ # One of 'HOSTED_OR_GOOGLE', 'GOOGLE', or 'HOSTED'.
27
+ # See documentation here:
28
+ # http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html
29
+ attr_accessor :account_type
30
+ # The access token
31
+ attr_accessor :token
32
+ # The service name for the API you are working with
33
+ attr_accessor :service
34
+
35
+ # Initialize the class with the service name of an API that you wish
36
+ # to request a token for.
37
+ def initialize(service, options = {})
38
+ if service.nil?
39
+ raise ArgumentError, "Service name cannot be nil"
40
+ end
41
+
42
+ @service = service
43
+
44
+ options.each do |key, value|
45
+ self.send("#{key}=", value)
46
+ end
47
+
48
+ @auth_url ||= 'https://www.google.com/accounts/ClientLogin'
49
+ @account_type ||= 'HOSTED_OR_GOOGLE'
50
+ end
51
+
52
+ # Retrieves a token for the given username and password.
53
+ # source identifies your application.
54
+ # login_token and login_captcha are used only if you are responding
55
+ # to a previously issued CAPTCHA challenge.
56
+ def get_token(username, password, source, login_token = nil,
57
+ login_captcha = nil)
58
+ body = Hash.new
59
+ body['accountType'] = @account_type
60
+ body['Email'] = username
61
+ body['Passwd'] = password
62
+ body['service'] = @service
63
+ body['source'] = source
64
+ if login_token and login_captcha
65
+ body['logintoken'] = login_token
66
+ body['logincaptcha'] = login_captcha
67
+ end
68
+
69
+ request = GData::HTTP::Request.new(@auth_url, :body => body,
70
+ :method => :post)
71
+ service = GData::HTTP::DefaultService.new
72
+ response = service.make_request(request)
73
+ if response.status_code != 200
74
+ url = response.body[/Url=(.*)/,1]
75
+ error = response.body[/Error=(.*)/,1]
76
+
77
+ if error == "CaptchaRequired"
78
+ captcha_token = response.body[/CaptchaToken=(.*)/,1]
79
+ captcha_url = response.body[/CaptchaUrl=(.*)/,1]
80
+ raise GData::Client::CaptchaError.new(captcha_token, captcha_url),
81
+ "#{error} : #{url}"
82
+ end
83
+
84
+ raise GData::Client::AuthorizationError.new(response)
85
+ end
86
+
87
+ @token = response.body[/Auth=(.*)/,1]
88
+ return @token
89
+ end
90
+
91
+ # Creates an appropriate Authorization header on a GData::HTTP::Request
92
+ # object.
93
+ def sign_request!(request)
94
+ if @token == nil
95
+ raise GData::Client::Error, "Cannot sign request without credentials"
96
+ end
97
+
98
+ request.headers['Authorization'] = "GoogleLogin auth=#{@token}"
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,84 @@
1
+ # Copyright (C) 2008 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'gdata/client/base'
16
+ require 'gdata/client/apps'
17
+ require 'gdata/client/blogger'
18
+ require 'gdata/client/booksearch'
19
+ require 'gdata/client/calendar'
20
+ require 'gdata/client/contacts'
21
+ require 'gdata/client/doclist'
22
+ require 'gdata/client/finance'
23
+ require 'gdata/client/gbase'
24
+ require 'gdata/client/gmail'
25
+ require 'gdata/client/health'
26
+ require 'gdata/client/notebook'
27
+ require 'gdata/client/photos'
28
+ require 'gdata/client/spreadsheets'
29
+ require 'gdata/client/webmaster_tools'
30
+ require 'gdata/client/youtube'
31
+
32
+ module GData
33
+ module Client
34
+
35
+ # Base class for GData::Client errors
36
+ class Error < RuntimeError
37
+ end
38
+
39
+ # Base class for errors raised due to requests
40
+ class RequestError < Error
41
+
42
+ # The Net::HTTPResponse that caused this error.
43
+ attr_accessor :response
44
+
45
+ # Creates a new RequestError from Net::HTTPResponse +response+ with a
46
+ # message containing the error code and response body.
47
+ def initialize(response)
48
+ @response = response
49
+
50
+ super "request error #{response.status_code}: #{response.body}"
51
+ end
52
+
53
+ end
54
+
55
+ class AuthorizationError < RequestError
56
+ end
57
+
58
+ class BadRequestError < RequestError
59
+ end
60
+
61
+ # An error caused by ClientLogin issuing a CAPTCHA error.
62
+ class CaptchaError < RuntimeError
63
+ # The token identifying the CAPTCHA
64
+ attr_reader :token
65
+ # The URL to the CAPTCHA image
66
+ attr_reader :url
67
+
68
+ def initialize(token, url)
69
+ @token = token
70
+ @url = url
71
+ end
72
+ end
73
+
74
+ class ServerError < RequestError
75
+ end
76
+
77
+ class UnknownError < RequestError
78
+ end
79
+
80
+ class VersionConflictError < RequestError
81
+ end
82
+
83
+ end
84
+ end