chocolate_rain 0.0.1

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.
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