chocolate_rain 0.0.1 → 0.0.2

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