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.
- data/chocolate_rain.gemspec +3 -4
- data/lib/chocolate_rain/daemon.rb +67 -0
- data/lib/chocolate_rain/ftp_files_and_upload.rb +54 -0
- data/lib/chocolate_rain/mail_rain/inbox.rb +39 -0
- data/lib/chocolate_rain/mail_rain/mail_handler.rb +53 -0
- data/lib/chocolate_rain/version.rb +1 -1
- data/lib/chocolate_rain/y_video.rb +49 -0
- data/lib/chocolate_rain.rb +45 -4
- metadata +22 -39
- data/generators/youtube_model/USAGE +0 -3
- data/generators/youtube_model/templates/config.yml +0 -6
- data/generators/youtube_model/templates/model.rb +0 -17
- data/generators/youtube_model/templates/unit_test.rb +0 -7
- data/generators/youtube_model/youtube_model_generator.rb +0 -15
- data/lib/.DS_Store +0 -0
- data/lib/gdata/auth/authsub.rb +0 -161
- data/lib/gdata/auth/clientlogin.rb +0 -102
- data/lib/gdata/client/apps.rb +0 -27
- data/lib/gdata/client/base.rb +0 -182
- data/lib/gdata/client/blogger.rb +0 -28
- data/lib/gdata/client/booksearch.rb +0 -28
- data/lib/gdata/client/calendar.rb +0 -58
- data/lib/gdata/client/contacts.rb +0 -28
- data/lib/gdata/client/doclist.rb +0 -28
- data/lib/gdata/client/finance.rb +0 -28
- data/lib/gdata/client/gbase.rb +0 -28
- data/lib/gdata/client/gmail.rb +0 -28
- data/lib/gdata/client/health.rb +0 -28
- data/lib/gdata/client/notebook.rb +0 -28
- data/lib/gdata/client/photos.rb +0 -29
- data/lib/gdata/client/spreadsheets.rb +0 -28
- data/lib/gdata/client/webmaster_tools.rb +0 -28
- data/lib/gdata/client/youtube.rb +0 -47
- data/lib/gdata/client.rb +0 -84
- data/lib/gdata/g_data.rb +0 -22
- data/lib/gdata/http/default_service.rb +0 -82
- data/lib/gdata/http/mime_body.rb +0 -95
- data/lib/gdata/http/request.rb +0 -74
- data/lib/gdata/http/response.rb +0 -44
- data/lib/gdata/http.rb +0 -18
- data/lib/youtube_helpers.rb +0 -58
- data/lib/youtube_model.rb +0 -341
data/chocolate_rain.gemspec
CHANGED
@@ -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{
|
12
|
-
s.description = %q{
|
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.
|
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
|
@@ -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
|
data/lib/chocolate_rain.rb
CHANGED
@@ -1,5 +1,46 @@
|
|
1
|
-
require
|
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
|
-
|
4
|
-
|
5
|
-
|
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.
|
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-
|
13
|
-
dependencies:
|
14
|
-
|
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/
|
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:
|
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:
|
66
|
+
summary: Monitor E-Mail and FTP for videos to upload to YouTube
|
84
67
|
test_files: []
|
@@ -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,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
|
data/lib/gdata/auth/authsub.rb
DELETED
@@ -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
|