chocolate_rain 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/chocolate_rain.gemspec +3 -4
  2. data/lib/chocolate_rain/daemon.rb +67 -0
  3. data/lib/chocolate_rain/ftp_files_and_upload.rb +54 -0
  4. data/lib/chocolate_rain/mail_rain/inbox.rb +39 -0
  5. data/lib/chocolate_rain/mail_rain/mail_handler.rb +53 -0
  6. data/lib/chocolate_rain/version.rb +1 -1
  7. data/lib/chocolate_rain/y_video.rb +49 -0
  8. data/lib/chocolate_rain.rb +45 -4
  9. metadata +22 -39
  10. data/generators/youtube_model/USAGE +0 -3
  11. data/generators/youtube_model/templates/config.yml +0 -6
  12. data/generators/youtube_model/templates/model.rb +0 -17
  13. data/generators/youtube_model/templates/unit_test.rb +0 -7
  14. data/generators/youtube_model/youtube_model_generator.rb +0 -15
  15. data/lib/.DS_Store +0 -0
  16. data/lib/gdata/auth/authsub.rb +0 -161
  17. data/lib/gdata/auth/clientlogin.rb +0 -102
  18. data/lib/gdata/client/apps.rb +0 -27
  19. data/lib/gdata/client/base.rb +0 -182
  20. data/lib/gdata/client/blogger.rb +0 -28
  21. data/lib/gdata/client/booksearch.rb +0 -28
  22. data/lib/gdata/client/calendar.rb +0 -58
  23. data/lib/gdata/client/contacts.rb +0 -28
  24. data/lib/gdata/client/doclist.rb +0 -28
  25. data/lib/gdata/client/finance.rb +0 -28
  26. data/lib/gdata/client/gbase.rb +0 -28
  27. data/lib/gdata/client/gmail.rb +0 -28
  28. data/lib/gdata/client/health.rb +0 -28
  29. data/lib/gdata/client/notebook.rb +0 -28
  30. data/lib/gdata/client/photos.rb +0 -29
  31. data/lib/gdata/client/spreadsheets.rb +0 -28
  32. data/lib/gdata/client/webmaster_tools.rb +0 -28
  33. data/lib/gdata/client/youtube.rb +0 -47
  34. data/lib/gdata/client.rb +0 -84
  35. data/lib/gdata/g_data.rb +0 -22
  36. data/lib/gdata/http/default_service.rb +0 -82
  37. data/lib/gdata/http/mime_body.rb +0 -95
  38. data/lib/gdata/http/request.rb +0 -74
  39. data/lib/gdata/http/response.rb +0 -44
  40. data/lib/gdata/http.rb +0 -18
  41. data/lib/youtube_helpers.rb +0 -58
  42. data/lib/youtube_model.rb +0 -341
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["Kevin Hopkins"]
9
9
  s.email = ["kevin@wearefound.com"]
10
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}
11
+ s.summary = %q{Monitor E-Mail and FTP for videos to upload to YouTube}
12
+ s.description = %q{Monitor E-Mail and FTP for videos to upload to YouTube}
13
13
 
14
14
  s.rubyforge_project = "chocolate_rain"
15
15
 
@@ -21,6 +21,5 @@ Gem::Specification.new do |s|
21
21
  # specify any dependencies here; for example:
22
22
  # s.add_development_dependency "rspec"
23
23
  # s.add_runtime_dependency "rest-client"
24
- s.required_rubygems_version = ">= 1.8.6"
25
-
24
+ s.add_dependency "youtube_it"
26
25
  end
@@ -0,0 +1,67 @@
1
+ require 'fileutils'
2
+
3
+ module Daemon
4
+ WorkingDirectory = File.expand_path(File.dirname(__FILE__))
5
+
6
+ class Base
7
+ def self.pid_fn
8
+ File.join(WorkingDirectory, "#{name}.pid")
9
+ end
10
+
11
+ def self.daemonize
12
+ Controller.daemonize(self)
13
+ end
14
+ end
15
+
16
+ module PidFile
17
+ def self.store(daemon, pid)
18
+ File.open(daemon.pid_fn, 'w') {|f| f << pid}
19
+ end
20
+
21
+ def self.recall(daemon)
22
+ IO.read(daemon.pid_fn).to_i rescue nil
23
+ end
24
+ end
25
+
26
+ module Controller
27
+ def self.daemonize(daemon)
28
+ case !ARGV.empty? && ARGV[0]
29
+ when 'start'
30
+ start(daemon)
31
+ when 'stop'
32
+ stop(daemon)
33
+ when 'restart'
34
+ stop(daemon)
35
+ start(daemon)
36
+ else
37
+ puts "Invalid command. Please specify start, stop or restart."
38
+ exit
39
+ end
40
+ end
41
+
42
+ def self.start(daemon)
43
+ fork do
44
+ Process.setsid
45
+ exit if fork
46
+ PidFile.store(daemon, Process.pid)
47
+ Dir.chdir WorkingDirectory
48
+ File.umask 0000
49
+ STDIN.reopen "/dev/null"
50
+ STDOUT.reopen "/dev/null", "a"
51
+ STDERR.reopen STDOUT
52
+ trap("TERM") {daemon.stop; exit}
53
+ daemon.start
54
+ end
55
+ end
56
+
57
+ def self.stop(daemon)
58
+ if !File.file?(daemon.pid_fn)
59
+ puts "Pid file not found. Is the daemon started?"
60
+ exit
61
+ end
62
+ pid = PidFile.recall(daemon)
63
+ FileUtils.rm(daemon.pid_fn)
64
+ pid && Process.kill("TERM", pid)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,54 @@
1
+ require 'net/ftp'
2
+ require 'fileutils'
3
+ require 'youtube_it'
4
+
5
+ module YouTuber
6
+ # Youtube Creds
7
+ def upload(f)
8
+ YT_CLIENT ||= YouTubeIt::Client.new(:username => "whyhermancain" , :password => "999m3@nsj0bs" , :dev_key => "AI39si79BSRx1X9AtG5zNxo-wk5YGiIHa-FAt5BNvb2poO7AVdNJEYoCgxg-JilsgHbNr0IUFk8j490v_LOZ8iPKueOUea6DdQ")
9
+
10
+ YT_CLIENT.video_upload(File.open("#{Rails.root.to_s}/public/videos/#{f}"), :title => "#{f}", :description => "Testimonial Video", :category => "Entertainment", :keywords => %w[herman cain whyhermancain republican politics testimonal donate donation], :list => "denied", :comments => "denied", :rate => "denied", :commentVote => "denied", :videoRespond => "denied", :embed => "denied", :syndicate => "denied")
11
+ puts "completed #{f}"
12
+ end
13
+ end
14
+
15
+ # FTP creds
16
+ URL = "fx0j7sls.rtmphost.com"
17
+ USERNAME = "fx0j7sls"
18
+ PASSWORD = "oi890_{PO"
19
+ DIRECTORY = "/fx0j7sls_apps/VideoGallery/streams/_definst_"
20
+ FORMAT = "flv"
21
+
22
+ @local_files = []
23
+
24
+ ftp = Net::FTP.new
25
+ ftp.connect(URL, 21)
26
+ ftp.login(USERNAME, PASSWORD)
27
+
28
+
29
+ ftp.chdir(DIRECTORY)
30
+ filenames = ftp.nlst("*.#{FORMAT}") # comes back as array
31
+
32
+ # loop by index
33
+ filenames.each_index do |i|
34
+ puts "working with index: #{i}"
35
+ localfile = "#{Rails.root.to_s}/public/videos/#{i}.#{FORMAT}"
36
+ ftp.getbinaryfile(filenames[i], localfile)
37
+ puts "got #{i}.#{FORMAT}"
38
+ @local_files << "#{i}.#{FORMAT}"
39
+ puts "*** \n"
40
+ end
41
+
42
+ filenames.each do |filename|
43
+ puts "Deleting #{filename}"
44
+ ftp.delete("#{filename}") # deleting from server so we don't re-download
45
+ puts "complete.\n***\n"
46
+ end
47
+
48
+ puts "Starting upload stack\n...\n......"
49
+ @local_files.each do |f|
50
+ YT_CLIENT.video_upload(File.open("#{Rails.root.to_s}/public/videos/#{f}"), :title => "#{f}", :description => "Testimonial Video", :category => "Entertainment", :keywords => %w[herman cain whyhermancain republican politics testimonal donate donation], :list => "denied", :comments => "denied", :rate => "denied", :commentVote => "denied", :videoRespond => "denied", :embed => "denied", :syndicate => "denied")
51
+ puts "completed #{f}"
52
+ end
53
+
54
+ puts "...el fine..."
@@ -0,0 +1,39 @@
1
+ require 'net/pop'
2
+ require 'mail'
3
+ require 'daemon'
4
+ require 'y_video'
5
+ require 'mail_handler'
6
+
7
+ class MailFetcher < Daemon::Base
8
+ def self.start
9
+ loop do
10
+ puts "Running Mail Importer..."
11
+ pop = Net::POP3.new('mail.hasflavor.com')
12
+
13
+ pop.start("app@hasflavor.com", "oi890po")
14
+
15
+ if pop.mails.empty?
16
+ puts "NO MAIL"
17
+ else
18
+ i = 0
19
+ puts "receiving mail..."
20
+ pop.each_mail do |m|
21
+ MailHandler.receive(m.pop)
22
+ m.delete
23
+ i += 1
24
+ end
25
+ puts "#{pop.mails.size} mails popped"
26
+ end
27
+ pop.finish
28
+ puts "Finished Mail Importer."
29
+
30
+ sleep(10)
31
+ end
32
+ end
33
+
34
+ def self.stop
35
+ puts "Stopping Mail Fetcher Daemon"
36
+ end
37
+ end
38
+
39
+ MailFetcher.start
@@ -0,0 +1,53 @@
1
+ require 'mail'
2
+ require 'stringio'
3
+ require 'y_video'
4
+
5
+ class MailHandler < ActionMailer::Base
6
+ def resend(sender, recipient, subject, body)
7
+ mail(:from => sender,
8
+ :to => recipient,
9
+ :subject => subject,
10
+ :body => body)
11
+ puts "Mail sent to #{recipient}"
12
+ end
13
+
14
+ def receive(email)
15
+ to_email = "apx05eq15zgx@m.youtube.com"
16
+ resend_multipart(email)
17
+ end
18
+
19
+ def resend_multipart(email)
20
+ email.attachments.each do |att|
21
+ fn = att.filename
22
+ v = YVideo.new()
23
+ begin
24
+ f = StringIO.new(att.body.decoded)
25
+ v.filename = fn
26
+ v.file_object = f
27
+ v.title = fn
28
+ begin
29
+ v.save
30
+ puts "Saving to S3 succeeded"
31
+ rescue Exception => e
32
+ puts "S3 Failed miserably: #{e.message}"
33
+ end
34
+ rescue Exception => e
35
+ puts "Unable to save data for #{fn} because of #{e.message}"
36
+ end
37
+ end
38
+
39
+ text_body = email.parts.select{|p| p.content_type.include? "text/plain" }.first.body.to_s
40
+ puts "Email subject: #{email.subject}"
41
+ begin
42
+ resent = MailHandler.resend(["whyhermancain@gmail.com"], ["support@wearefound.com"], "[CAIN] Successful Upload", "A new testimonial video has been uploaded via email to s3. Its url is http://s3.amazonaws.com/whyHermanCain/#{v.filename}")
43
+ resent.deliver
44
+ puts "sent"
45
+ rescue
46
+ return
47
+ end
48
+ end
49
+
50
+ def upload(f)
51
+ puts "completed #{f}"
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module ChocolateRain
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,49 @@
1
+ require 'youtube_it'
2
+ require 'aws/s3'
3
+
4
+ class YVideo
5
+ attr_accessor :filename, :file_object, :title, :description, :category, :keywords, :list, :comments, :rate, :commentVote, :videoRespond, :embed, :syndicate
6
+
7
+ @@YCONN = YouTubeIt::Client.new(:username => "whyhermancain" , :password => "999m3@nsj0bs" , :dev_key => "AI39si79BSRx1X9AtG5zNxo-wk5YGiIHa-FAt5BNvb2poO7AVdNJEYoCgxg-JilsgHbNr0IUFk8j490v_LOZ8iPKueOUea6DdQ")
8
+ @@y = YAML.load(File.open("#{Rails.root.to_s}/config/s3.yml"))
9
+ AWS::S3::Base.establish_connection!(
10
+ :access_key_id => @@y[(Rails.env)]["access_key_id"],
11
+ :secret_access_key => @@y[(Rails.env)]["secret_access_key"]
12
+ )
13
+
14
+ def initialize
15
+ @filename = nil
16
+ @description = nil
17
+ @category = nil
18
+ @keywords = []
19
+ @list = "denied"
20
+ @comments = "denied"
21
+ @rate = "denied"
22
+ @commentVote = "denied"
23
+ @videoRespond = "denied"
24
+ @embed = "denied"
25
+ @syndicate = "denied"
26
+ end
27
+
28
+ def to_hash
29
+ self.instance_variables.inject({}) { |hash,var| hash[var.to_s.delete("@")] = self.instance_variable_get(var); hash }
30
+ end
31
+
32
+ def upload
33
+ @@YCONN.video_upload(File.open("#{Rails.root.to_s}/public/videos/#{f}"), :title => "#{f}", :description => "Testimonial Video", :category => "Entertainment", :keywords => %w[herman cain whyhermancain republican politics testimonal donate donation], :list => "denied", :comments => "denied", :rate => "denied", :commentVote => "denied", :videoRespond => "denied", :embed => "denied", :syndicate => "denied")
34
+ end
35
+
36
+ def save
37
+ puts "in save"
38
+ begin
39
+ bucket = AWS::S3::Bucket.find(@@y[(Rails.env)]["bucket"])
40
+ rescue
41
+ bucket = AWS::S3::Bucket.create(@@y[(Rails.env)]["bucket"])
42
+ end
43
+ if AWS::S3::S3Object.store(self.filename, self.file_object, @@y[(Rails.env)]["bucket"], :access => :public_read)
44
+ return true
45
+ else
46
+ return false
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,46 @@
1
- require "chocolate_rain/version"
1
+ require 'logger'
2
+ %w(
3
+ version
4
+ daemon
5
+ y_video
6
+ mail_rain/mail_handler
7
+ mail_rain/inbox
8
+ ).each{|m| require File.dirname(__FILE__) + '/chocolate_rain/' + m }
2
9
 
3
- module ChocolateRain
4
- # Your code goes here...
5
- end
10
+ class ChocolateRain
11
+
12
+ # Base error class for the extension
13
+ class Error < RuntimeError
14
+ end
15
+
16
+ # URL-escape a string. Stolen from Camping (wonder how many Ruby libs in the wild can say the same)
17
+ def self.esc(s) #:nodoc:
18
+ s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr(' ', '+')
19
+ end
20
+
21
+ # Set the logger for the library
22
+ def self.logger=(any_logger)
23
+ @logger = any_logger
24
+ end
25
+
26
+ # Get the logger for the library (by default will log to STDOUT). TODO: this is where we grab the Rails logger too
27
+ def self.logger
28
+ @logger ||= create_default_logger
29
+ end
30
+
31
+ # Gets mixed into the classes to provide the logger method
32
+ module Logging #:nodoc:
33
+
34
+ # Return the base logger set for the library
35
+ def logger
36
+ YouTubeIt.logger
37
+ end
38
+ end
39
+
40
+ private
41
+ def self.create_default_logger
42
+ logger = Logger.new(STDOUT)
43
+ logger.level = Logger::DEBUG
44
+ logger
45
+ end
46
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chocolate_rain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,9 +9,20 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-22 00:00:00.000000000Z
13
- dependencies: []
14
- description: YouTube API wrapper for 1.9.2 compatible with Rails >= 3.1
12
+ date: 2011-11-23 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: youtube_it
16
+ requirement: &2152231740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2152231740
25
+ description: Monitor E-Mail and FTP for videos to upload to YouTube
15
26
  email:
16
27
  - kevin@wearefound.com
17
28
  executables: []
@@ -22,41 +33,13 @@ files:
22
33
  - Gemfile
23
34
  - Rakefile
24
35
  - chocolate_rain.gemspec
25
- - generators/youtube_model/USAGE
26
- - generators/youtube_model/templates/config.yml
27
- - generators/youtube_model/templates/model.rb
28
- - generators/youtube_model/templates/unit_test.rb
29
- - generators/youtube_model/youtube_model_generator.rb
30
- - lib/.DS_Store
31
36
  - lib/chocolate_rain.rb
37
+ - lib/chocolate_rain/daemon.rb
38
+ - lib/chocolate_rain/ftp_files_and_upload.rb
39
+ - lib/chocolate_rain/mail_rain/inbox.rb
40
+ - lib/chocolate_rain/mail_rain/mail_handler.rb
32
41
  - lib/chocolate_rain/version.rb
33
- - lib/gdata/auth/authsub.rb
34
- - lib/gdata/auth/clientlogin.rb
35
- - lib/gdata/client.rb
36
- - lib/gdata/client/apps.rb
37
- - lib/gdata/client/base.rb
38
- - lib/gdata/client/blogger.rb
39
- - lib/gdata/client/booksearch.rb
40
- - lib/gdata/client/calendar.rb
41
- - lib/gdata/client/contacts.rb
42
- - lib/gdata/client/doclist.rb
43
- - lib/gdata/client/finance.rb
44
- - lib/gdata/client/gbase.rb
45
- - lib/gdata/client/gmail.rb
46
- - lib/gdata/client/health.rb
47
- - lib/gdata/client/notebook.rb
48
- - lib/gdata/client/photos.rb
49
- - lib/gdata/client/spreadsheets.rb
50
- - lib/gdata/client/webmaster_tools.rb
51
- - lib/gdata/client/youtube.rb
52
- - lib/gdata/g_data.rb
53
- - lib/gdata/http.rb
54
- - lib/gdata/http/default_service.rb
55
- - lib/gdata/http/mime_body.rb
56
- - lib/gdata/http/request.rb
57
- - lib/gdata/http/response.rb
58
- - lib/youtube_helpers.rb
59
- - lib/youtube_model.rb
42
+ - lib/chocolate_rain/y_video.rb
60
43
  homepage: ''
61
44
  licenses: []
62
45
  post_install_message:
@@ -74,11 +57,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
57
  requirements:
75
58
  - - ! '>='
76
59
  - !ruby/object:Gem::Version
77
- version: 1.8.6
60
+ version: '0'
78
61
  requirements: []
79
62
  rubyforge_project: chocolate_rain
80
63
  rubygems_version: 1.8.6
81
64
  signing_key:
82
65
  specification_version: 3
83
- summary: YouTube API wrapper for 1.9.2 compatible with Rails >= 3.1
66
+ summary: Monitor E-Mail and FTP for videos to upload to YouTube
84
67
  test_files: []
@@ -1,3 +0,0 @@
1
- ./script/generate youtube_model MODELNAME
2
-
3
- Generates an ActiveResource model that is ready for interact with YouTube API
@@ -1,6 +0,0 @@
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
@@ -1,17 +0,0 @@
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
@@ -1,7 +0,0 @@
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
@@ -1,15 +0,0 @@
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 DELETED
Binary file
@@ -1,161 +0,0 @@
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