googletastic 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +47 -0
- data/Rakefile +103 -0
- data/lib/googletastic/access_rule.rb +45 -0
- data/lib/googletastic/album.rb +22 -0
- data/lib/googletastic/app_engine.rb +103 -0
- data/lib/googletastic/attendee.rb +7 -0
- data/lib/googletastic/base.rb +46 -0
- data/lib/googletastic/calendar.rb +60 -0
- data/lib/googletastic/comment.rb +3 -0
- data/lib/googletastic/document.rb +219 -0
- data/lib/googletastic/event.rb +149 -0
- data/lib/googletastic/ext/file.rb +219 -0
- data/lib/googletastic/ext/pretty_print.xsl +47 -0
- data/lib/googletastic/ext/xml.rb +10 -0
- data/lib/googletastic/ext.rb +1 -0
- data/lib/googletastic/form.rb +131 -0
- data/lib/googletastic/group.rb +44 -0
- data/lib/googletastic/helpers/document.rb +70 -0
- data/lib/googletastic/helpers/event.rb +26 -0
- data/lib/googletastic/helpers/form.rb +102 -0
- data/lib/googletastic/helpers.rb +18 -0
- data/lib/googletastic/image.rb +121 -0
- data/lib/googletastic/mixins/actions.rb +113 -0
- data/lib/googletastic/mixins/attributes.rb +27 -0
- data/lib/googletastic/mixins/finders.rb +78 -0
- data/lib/googletastic/mixins/namespaces.rb +42 -0
- data/lib/googletastic/mixins/parsing.rb +68 -0
- data/lib/googletastic/mixins/requesting.rb +84 -0
- data/lib/googletastic/mixins.rb +5 -0
- data/lib/googletastic/person.rb +41 -0
- data/lib/googletastic/spreadsheet.rb +35 -0
- data/lib/googletastic/sync/document.rb +120 -0
- data/lib/googletastic/sync/form.rb +106 -0
- data/lib/googletastic/sync.rb +46 -0
- data/lib/googletastic/thumbnail.rb +7 -0
- data/lib/googletastic/youtube.rb +25 -0
- data/lib/googletastic.rb +115 -0
- data/spec/benchmarks/document_benchmark.rb +40 -0
- data/spec/config.yml +6 -0
- data/spec/fixtures/data/Doing business in the eMarketPlace.doc +0 -0
- data/spec/fixtures/data/basic.txt +1 -0
- data/spec/fixtures/data/calendar.list.xml +64 -0
- data/spec/fixtures/data/doc_as_html.html +3097 -0
- data/spec/fixtures/data/doc_as_html_html.html +0 -0
- data/spec/fixtures/data/doclist.xml +76 -0
- data/spec/fixtures/data/document.single.xml +30 -0
- data/spec/fixtures/data/end.xml +446 -0
- data/spec/fixtures/data/event.list.xml +62 -0
- data/spec/fixtures/data/form.html +66 -0
- data/spec/fixtures/data/group.list.xml +58 -0
- data/spec/fixtures/data/person.list.xml +53 -0
- data/spec/fixtures/data/photo.list.xml +111 -0
- data/spec/fixtures/data/sample_upload.mp4 +0 -0
- data/spec/fixtures/data/spreadsheet.list.xml +43 -0
- data/spec/fixtures/models/document.rb +7 -0
- data/spec/fixtures/models/event.rb +3 -0
- data/spec/fixtures/models/form.rb +6 -0
- data/spec/fixtures/models/test_model.rb +3 -0
- data/spec/fixtures/results/test.txt +185 -0
- data/spec/googletastic/access_rule_spec.rb +13 -0
- data/spec/googletastic/album_spec.rb +9 -0
- data/spec/googletastic/app_engine_spec.rb +12 -0
- data/spec/googletastic/base_spec.rb +49 -0
- data/spec/googletastic/calendar_spec.rb +11 -0
- data/spec/googletastic/document_spec.rb +163 -0
- data/spec/googletastic/event_spec.rb +34 -0
- data/spec/googletastic/form_spec.rb +43 -0
- data/spec/googletastic/group_spec.rb +9 -0
- data/spec/googletastic/image_spec.rb +9 -0
- data/spec/googletastic/person_spec.rb +9 -0
- data/spec/googletastic/post_spec.rb +46 -0
- data/spec/googletastic/spreadsheet_spec.rb +9 -0
- data/spec/googletastic/youtube_spec.rb +58 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +25 -0
- metadata +187 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
class Googletastic::Person < Googletastic::Base
|
2
|
+
|
3
|
+
attr_accessor :name, :email
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def index_url
|
8
|
+
"http://www.google.com/m8/feeds/contacts/default/full"
|
9
|
+
end
|
10
|
+
|
11
|
+
def client_class
|
12
|
+
"Contacts"
|
13
|
+
end
|
14
|
+
|
15
|
+
# http://code.google.com/apis/contacts/docs/2.0/reference.html#Parameters
|
16
|
+
def valid_queries
|
17
|
+
{
|
18
|
+
:order => "orderby",
|
19
|
+
:sort => "sortorder",
|
20
|
+
:group => "group"
|
21
|
+
}.merge(super)
|
22
|
+
end
|
23
|
+
|
24
|
+
def unmarshall(xml)
|
25
|
+
records = xml.xpath("//atom:entry", ns_tag("atom")).collect do |record|
|
26
|
+
id = record.xpath("atom:id", ns_tag("atom")).first.text
|
27
|
+
name = record.xpath("atom:title", ns_tag("atom")).first.text
|
28
|
+
email = record.xpath("gd:email", ns_tag("gd")).first["address"].to_s
|
29
|
+
|
30
|
+
Googletastic::Person.new(
|
31
|
+
:id => id,
|
32
|
+
:name => name,
|
33
|
+
:email => email
|
34
|
+
)
|
35
|
+
end
|
36
|
+
records
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Googletastic::Spreadsheet < Googletastic::Base
|
2
|
+
|
3
|
+
attr_accessor :title, :content
|
4
|
+
|
5
|
+
# Time.now.xmlschema
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def client_class
|
9
|
+
"Spreadsheets"
|
10
|
+
end
|
11
|
+
|
12
|
+
def index_url
|
13
|
+
"http://spreadsheets.google.com/feeds/spreadsheets/private/full"
|
14
|
+
end
|
15
|
+
|
16
|
+
def unmarshall(xml)
|
17
|
+
records = xml.xpath("//atom:entry", ns_tag("atom")).collect do |record|
|
18
|
+
id = record.xpath("atom:id", ns_tag("atom")).first.text.gsub("http://spreadsheets.google.com/feeds/spreadsheets/", "")
|
19
|
+
title = record.xpath("atom:title", ns_tag("atom")).first.text
|
20
|
+
content = record.xpath("atom:content", ns_tag("atom")).first.text
|
21
|
+
created_at = record.xpath("atom:published", ns_tag("atom")).text
|
22
|
+
updated_at = record.xpath("atom:updated", ns_tag("atom")).text
|
23
|
+
|
24
|
+
Googletastic::Spreadsheet.new(
|
25
|
+
:id => id,
|
26
|
+
:title => title,
|
27
|
+
:content => content,
|
28
|
+
:updated_at => DateTime.parse(updated_at)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
records
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Googletastic::Sync::Document
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def sync(documents, options, &block)
|
10
|
+
updated = process(documents, options)
|
11
|
+
key = options[:key].to_s
|
12
|
+
data = {key => []}
|
13
|
+
documents.each do |document|
|
14
|
+
data[key] << {
|
15
|
+
:id => document.remote.id
|
16
|
+
}
|
17
|
+
yield(data, key, document) if block_given?
|
18
|
+
end
|
19
|
+
response = Googletastic::Sync.post(
|
20
|
+
:url => options[:url],
|
21
|
+
:path => options[:path],
|
22
|
+
:format => :json,
|
23
|
+
:data => data
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def process(documents, options = {})
|
28
|
+
options[:key] ||= "documents"
|
29
|
+
# defaults to a reasonable limit (3MB) for heroku
|
30
|
+
options[:max_size] ||= 3000000
|
31
|
+
# per max_size chunk
|
32
|
+
documents_processed = []
|
33
|
+
# total
|
34
|
+
updated_documents = []
|
35
|
+
counted_size = 0
|
36
|
+
documents.each_with_index do |document, index|
|
37
|
+
next if document.remote.kind != "document"
|
38
|
+
if document.synced_at and document.synced_at >= document.remote.updated_at
|
39
|
+
puts "Skipping Document... #{document.title}"
|
40
|
+
if documents_processed.length > 0 and index == documents.length - 1
|
41
|
+
Googletastic::Sync.push(options[:username], options[:password], options)
|
42
|
+
cleanup(documents_processed, options)
|
43
|
+
end
|
44
|
+
next
|
45
|
+
end
|
46
|
+
remote = document.remote
|
47
|
+
content = nil
|
48
|
+
title = remote.title
|
49
|
+
ext = remote.ext
|
50
|
+
puts "Processing Document... #{document.title}"
|
51
|
+
begin
|
52
|
+
if ext == ".textile"
|
53
|
+
# google is putting strange characters at beginning of downloaded files
|
54
|
+
content = remote.download("txt").body.gsub(/\357\273\277/, "")
|
55
|
+
content = RedCloth.new(content).to_html
|
56
|
+
elsif ext == ".markdown"
|
57
|
+
content = remote.download("txt").body.gsub(/\357\273\277/, "")
|
58
|
+
content = BlueCloth.new(content).to_html
|
59
|
+
elsif ext.nil? || ext.empty?
|
60
|
+
# just use the html we have already
|
61
|
+
content = remote.content
|
62
|
+
else
|
63
|
+
content = remote.download("txt").body.gsub(/\357\273\277/, "")
|
64
|
+
end
|
65
|
+
|
66
|
+
document.content = content
|
67
|
+
title = remote.id
|
68
|
+
|
69
|
+
tempfile = Tempfile.new("googltastic-tempfiles-#{title}-#{Time.now}-#{rand(10000)}")
|
70
|
+
tempfile.write(content)
|
71
|
+
|
72
|
+
path = File.join(options[:folder], options[:key])
|
73
|
+
Dir.mkdir(path) unless File.exists?(path)
|
74
|
+
path = File.join(path, title)
|
75
|
+
|
76
|
+
# if we have passed the 5MB (or our 3MB) limit,
|
77
|
+
# then push the files to GAE
|
78
|
+
if tempfile.size + counted_size >= options[:max_size] || index == documents.length - 1
|
79
|
+
Googletastic::Sync.push(options[:username], options[:password], options)
|
80
|
+
cleanup(documents_processed, options)
|
81
|
+
counted_size = 0
|
82
|
+
documents_processed = []
|
83
|
+
end
|
84
|
+
|
85
|
+
content = Googletastic::PrettyPrint.xml(content)
|
86
|
+
|
87
|
+
File.open(path, 'w') {|f| f.write(content) }
|
88
|
+
documents_processed << document
|
89
|
+
counted_size += tempfile.size
|
90
|
+
tempfile.close
|
91
|
+
|
92
|
+
updated_documents << document
|
93
|
+
|
94
|
+
rescue Exception => e
|
95
|
+
puts "Error... #{e.inspect}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
updated_documents
|
100
|
+
end
|
101
|
+
|
102
|
+
def cleanup(syncables, options)
|
103
|
+
syncables.each do |syncable|
|
104
|
+
syncable.synced_at = Time.now
|
105
|
+
syncable.save!
|
106
|
+
path = File.join(options[:folder], options[:key], syncable.remote.id)
|
107
|
+
path += options[:ext] if options.has_key?(:ext)
|
108
|
+
begin
|
109
|
+
File.delete(path)
|
110
|
+
rescue Exception => e
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
Googletastic::Document.class_eval do
|
119
|
+
include Googletastic::Sync::Document
|
120
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Googletastic::Sync::Form
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def sync(forms, options = {}, &block)
|
10
|
+
updated = process(forms, options)
|
11
|
+
key = options[:key].to_s
|
12
|
+
data = {key => []}
|
13
|
+
updated.each do |form|
|
14
|
+
data[key] << {
|
15
|
+
:id => form.remote.id,
|
16
|
+
:formkey => form.formkey
|
17
|
+
}
|
18
|
+
yield(data, key, form) if block_given?
|
19
|
+
end
|
20
|
+
response = Googletastic::Sync.post(
|
21
|
+
:url => options[:url],
|
22
|
+
:path => options[:path],
|
23
|
+
:format => :json,
|
24
|
+
:data => data
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def process(forms, options = {})
|
29
|
+
options[:key] ||= "forms"
|
30
|
+
# defaults to a reasonable limit (3MB) for heroku
|
31
|
+
options[:max_size] ||= 3000000
|
32
|
+
# per max_size chunk
|
33
|
+
forms_processed = []
|
34
|
+
# total
|
35
|
+
updated_forms = []
|
36
|
+
counted_size = 0
|
37
|
+
forms.each_with_index do |form, index|
|
38
|
+
if form.formkey.nil?
|
39
|
+
puts "Missing formkey... #{form.title}"
|
40
|
+
if forms_processed.length > 0 and index == forms.length - 1
|
41
|
+
Googletastic::Sync.push(options[:username], options[:password], options)
|
42
|
+
cleanup(forms_processed, options.merge(:ext => ".html"))
|
43
|
+
end
|
44
|
+
next
|
45
|
+
end
|
46
|
+
remote = form.remote
|
47
|
+
content = nil
|
48
|
+
puts "Processing Form... #{form.title}"
|
49
|
+
begin
|
50
|
+
form.remote.form_key = form.formkey
|
51
|
+
title = form.formkey + ".html"
|
52
|
+
content = form.remote.body
|
53
|
+
|
54
|
+
tempfile = Tempfile.new("googltastic-form-tempfiles-#{title}-#{Time.now}-#{rand(10000)}")
|
55
|
+
tempfile.write(content)
|
56
|
+
|
57
|
+
path = File.join(options[:folder], options[:key])
|
58
|
+
Dir.mkdir(path) unless File.exists?(path)
|
59
|
+
path = File.join(path, title)
|
60
|
+
|
61
|
+
# if we have passed the 5MB (or our 3MB) limit,
|
62
|
+
# then push the files to GAE
|
63
|
+
if tempfile.size + counted_size >= options[:max_size] || index == forms.length - 1
|
64
|
+
Googletastic::Sync.push(options[:username], options[:password], options)
|
65
|
+
cleanup(forms_processed, options.merge(:ext => ".html"))
|
66
|
+
counted_size = 0
|
67
|
+
forms_processed = []
|
68
|
+
end
|
69
|
+
|
70
|
+
content = Googletastic::PrettyPrint.xml(content)
|
71
|
+
|
72
|
+
File.open(path, 'w') {|f| f.write(content) }
|
73
|
+
forms_processed << form
|
74
|
+
counted_size += tempfile.size
|
75
|
+
tempfile.close
|
76
|
+
|
77
|
+
updated_forms << form
|
78
|
+
|
79
|
+
rescue Exception => e
|
80
|
+
puts "Error... #{e.inspect}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
updated_forms
|
85
|
+
end
|
86
|
+
|
87
|
+
def cleanup(syncables, options)
|
88
|
+
syncables.each do |syncable|
|
89
|
+
syncable.synced_at = Time.now
|
90
|
+
syncable.save!
|
91
|
+
path = File.join(options[:folder], options[:key], syncable.formkey)
|
92
|
+
path += options[:ext] if options.has_key?(:ext)
|
93
|
+
begin
|
94
|
+
File.delete(path)
|
95
|
+
rescue Exception => e
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
Googletastic::Form.class_eval do
|
105
|
+
include Googletastic::Sync::Form
|
106
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Googletastic::Sync
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def sync_documents(documents, options = {}, &block)
|
6
|
+
Googletastic::Document.sync(documents, options, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def sync_forms(forms, options = {}, &block)
|
10
|
+
Googletastic::Form.sync(forms, options, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def push(username, password, options = {})
|
14
|
+
Googletastic.client_for(:app_engine).push(username, password, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
# POSTs to your registered application
|
18
|
+
def post(options = {})
|
19
|
+
url = URI.parse(options[:url])
|
20
|
+
# POST update to registered application
|
21
|
+
http = Net::HTTP.new(url.host, url.port)
|
22
|
+
header = options[:header] || {}
|
23
|
+
header.merge!('Content-Type' =>'application/json')
|
24
|
+
data = options[:data].to_json
|
25
|
+
response = http.post(options[:path], data, header)
|
26
|
+
end
|
27
|
+
|
28
|
+
def cleanup(syncables, options)
|
29
|
+
syncables.each do |syncable|
|
30
|
+
syncable.synced_at = Time.now
|
31
|
+
syncable.save!
|
32
|
+
path = File.join(options[:folder], syncable.title)
|
33
|
+
path += options[:ext] if options.has_key?(:ext)
|
34
|
+
begin
|
35
|
+
File.delete(path)
|
36
|
+
rescue Exception => e
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
require_local "sync/*", __FILE__
|
@@ -0,0 +1,25 @@
|
|
1
|
+
=begin
|
2
|
+
module Thing
|
3
|
+
module Google
|
4
|
+
class YouTube < CouchRest::ExtendedDocument
|
5
|
+
|
6
|
+
MEDIA_NS = "http://search.yahoo.com/mrss" unless defined?(MEDIA_NS)
|
7
|
+
YT_NS = "http://gdata.youtube.com/schemas/2007" unless defined?(YT_NS)
|
8
|
+
|
9
|
+
API = "http://gdata.youtube.com" unless defined?(API)
|
10
|
+
GET_UPLOAD_TOKEN = "action/GetUploadToken"
|
11
|
+
UPLOAD = "http://uploads.gdata.youtube.com/feeds/api/users"
|
12
|
+
MULTIPART = "multipart/related"
|
13
|
+
|
14
|
+
def self.unmarshall(object)
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.marshall(xml)
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
=end
|
data/lib/googletastic.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'date'
|
4
|
+
require 'rake/clean'
|
5
|
+
#require 'rbconfig'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'nokogiri'
|
8
|
+
require 'active_support'
|
9
|
+
require 'active_record'
|
10
|
+
require 'gdata'
|
11
|
+
require 'liquid'
|
12
|
+
|
13
|
+
GOOGLETASTIC_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(GOOGLETASTIC_ROOT)
|
14
|
+
|
15
|
+
class Module
|
16
|
+
def include_class_and_instance_modules
|
17
|
+
self.module_eval <<-eos
|
18
|
+
def self.included(base)
|
19
|
+
base.extend(ClassMethods)
|
20
|
+
base.class_eval do
|
21
|
+
include InstanceMethods
|
22
|
+
end
|
23
|
+
end
|
24
|
+
eos
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def require_local(path, from = __FILE__)
|
29
|
+
files(path, from) {|file| require file if File.extname(file) == ".rb"}
|
30
|
+
end
|
31
|
+
|
32
|
+
def files(path, from = __FILE__, &block)
|
33
|
+
Dir.glob(File.expand_path(File.join(File.dirname(from), path))) {|file| yield file}
|
34
|
+
end
|
35
|
+
|
36
|
+
def require_spec
|
37
|
+
require File.join(GOOGLETASTIC_ROOT, "/spec/spec_helper")
|
38
|
+
end
|
39
|
+
|
40
|
+
class String
|
41
|
+
# active_support isn't letting me do this!
|
42
|
+
def parameterize(sep = '-')
|
43
|
+
# replace accented chars with ther ascii equivalents
|
44
|
+
# parameterized_string = transliterate(string)
|
45
|
+
parameterized_string = self.dup
|
46
|
+
# Turn unwanted chars into the seperator
|
47
|
+
parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
|
48
|
+
unless sep.blank?
|
49
|
+
re_sep = Regexp.escape(sep)
|
50
|
+
# No more than one of the separator in a row.
|
51
|
+
parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
|
52
|
+
# Remove leading/trailing separator.
|
53
|
+
parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
|
54
|
+
end
|
55
|
+
parameterized_string.downcase
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module Googletastic
|
60
|
+
# :stopdoc:
|
61
|
+
VERSION = '0.0.1'
|
62
|
+
# :startdoc
|
63
|
+
class << self; attr_accessor :keys, :clients, :options; end
|
64
|
+
|
65
|
+
def self.credentials
|
66
|
+
return self.keys if self.keys
|
67
|
+
|
68
|
+
config_file = "#{RAILS_ROOT}/config/gdata.yml"
|
69
|
+
raise "Sorry, you must have #{config_file}" unless File.exists?(config_file)
|
70
|
+
self.keys = YAML.load_file(config_file).symbolize_keys
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.client_for(model)
|
74
|
+
self.clients ||= {}
|
75
|
+
model = model.to_sym
|
76
|
+
return self.clients[model] if self.clients.has_key?(model)
|
77
|
+
client = ("GData::Client::#{model.to_s.camelize}").constantize.new(:source => credentials[:application])
|
78
|
+
client.clientlogin(credentials[:username], credentials[:password], nil, nil, nil, credentials[:account_type])
|
79
|
+
self.clients[model] = client
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.options_for(klass, value = {})
|
83
|
+
self.options ||= {}
|
84
|
+
klass = klass.is_a?(Class) ? klass : klass.class
|
85
|
+
name = klass.to_s.underscore.downcase.to_sym
|
86
|
+
if value and !value.blank?
|
87
|
+
value.symbolize_keys!
|
88
|
+
self.options[name] = value
|
89
|
+
else
|
90
|
+
self.options[name] ||= {}
|
91
|
+
end
|
92
|
+
self.options[name]
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.[](value)
|
96
|
+
self.options_for(value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# main includes
|
101
|
+
require_local "googletastic/ext/*"
|
102
|
+
|
103
|
+
require File.dirname(__FILE__) + '/googletastic/mixins'
|
104
|
+
require File.dirname(__FILE__) + '/googletastic/base'
|
105
|
+
|
106
|
+
require_local "googletastic/*"
|
107
|
+
|
108
|
+
#files("googletastic/mixins/*") do |file|
|
109
|
+
# Googletastic::Base.send(:include, "Googletastic::Mixins::#{File.basename(file, '.rb').camelize}".constantize)
|
110
|
+
#end
|
111
|
+
|
112
|
+
if defined?(ActiveRecord::Base)
|
113
|
+
ActiveRecord::Base.send(:include, Googletastic::Helpers)
|
114
|
+
end
|
115
|
+
# EOF
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
$:.unshift(File.dirname(__FILE__) + '/..')
|
5
|
+
require 'spec_helper'
|
6
|
+
|
7
|
+
id = "0AT1-fvkm5vJPZGN2NzR3bmJfMGZiMnh3N2R0"
|
8
|
+
many = 1
|
9
|
+
|
10
|
+
Benchmark.bmbm(7) do |x|
|
11
|
+
x.report ("Find the Document") do
|
12
|
+
many.times do |i|
|
13
|
+
doc = Googletastic::Document.find(id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
x.report("View the Raw HTML: ") do
|
17
|
+
many.times do |i|
|
18
|
+
doc = Googletastic::Document.find(id)
|
19
|
+
result = doc.view
|
20
|
+
end
|
21
|
+
end
|
22
|
+
x.report("Download as HTML: ") do
|
23
|
+
many.times do |i|
|
24
|
+
doc = Googletastic::Document.find(id)
|
25
|
+
result = doc.download("html")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
x.report("Download as TXT: ") do
|
29
|
+
many.times do |i|
|
30
|
+
doc = Googletastic::Document.find(id)
|
31
|
+
result = doc.download("txt")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
x.report("Download as PDF: ") do
|
35
|
+
many.times do |i|
|
36
|
+
doc = Googletastic::Document.find(id)
|
37
|
+
result = doc.download("pdf")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/config.yml
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
username: "flexinstyle@gmail.com"
|
2
|
+
password: "flexyflexy"
|
3
|
+
application: "Googletastic Test"
|
4
|
+
account_type: "HOSTED_OR_GOOGLE"
|
5
|
+
youtube_login: "MrFlexinstyle"
|
6
|
+
youtube_dev_key: "AI39si7jkhs_ECjF4unOQz8gpWGSKXgq0KJpm8wywkvBSw4s8oJd5p5vkpvURHBNh-hiYJtoKwQqSfot7KoCkeCE32rNcZqMxA"
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
something
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:gCal="http://schemas.google.com/gCal/2005" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/"AkACRXkyeSp7IWA9WxBaEk8."" gd:kind="calendar#calendarFeed">
|
3
|
+
<id>http://www.google.com/calendar/feeds/default/allcalendars/full</id>
|
4
|
+
<updated>2010-03-22T03:32:44.791Z</updated>
|
5
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
6
|
+
<title>flexinstyle@gmail.com's Calendar List</title>
|
7
|
+
<link rel="alternate" type="text/html" href="http://www.google.com/calendar/render"/>
|
8
|
+
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.google.com/calendar/feeds/default/allcalendars/full"/>
|
9
|
+
<link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="http://www.google.com/calendar/feeds/default/allcalendars/full"/>
|
10
|
+
<link rel="self" type="application/atom+xml" href="http://www.google.com/calendar/feeds/default/allcalendars/full"/>
|
11
|
+
<author>
|
12
|
+
<name>flexinstyle@gmail.com</name>
|
13
|
+
<email>flexinstyle@gmail.com</email>
|
14
|
+
</author>
|
15
|
+
<generator version="1.0" uri="http://www.google.com/calendar">Google Calendar</generator>
|
16
|
+
<openSearch:startIndex>1</openSearch:startIndex>
|
17
|
+
<entry gd:etag="W/"A0cFSX47eCp7IWA9WxBaEU0."" gd:kind="calendar#calendar">
|
18
|
+
<id>http://www.google.com/calendar/feeds/default/calendars/flexinstyle%40gmail.com</id>
|
19
|
+
<published>2010-03-22T03:32:44.788Z</published>
|
20
|
+
<updated>2010-03-20T18:16:58.000Z</updated>
|
21
|
+
<app:edited>2010-03-20T18:16:58.000Z</app:edited>
|
22
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
23
|
+
<title type="text">flexinstyle@gmail.com</title>
|
24
|
+
<content type="application/atom+xml" src="http://www.google.com/calendar/feeds/flexinstyle%40gmail.com/private/full"/>
|
25
|
+
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/flexinstyle%40gmail.com/private/full"/>
|
26
|
+
<link rel="http://schemas.google.com/gCal/2005#eventFeed" type="application/atom+xml" href="http://www.google.com/calendar/feeds/flexinstyle%40gmail.com/private/full"/>
|
27
|
+
<link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="http://www.google.com/calendar/feeds/flexinstyle%40gmail.com/acl/full"/>
|
28
|
+
<link rel="self" type="application/atom+xml" href="http://www.google.com/calendar/feeds/default/allcalendars/full/flexinstyle%40gmail.com"/>
|
29
|
+
<link rel="edit" type="application/atom+xml" href="http://www.google.com/calendar/feeds/default/allcalendars/full/flexinstyle%40gmail.com"/>
|
30
|
+
<author>
|
31
|
+
<name>flexinstyle@gmail.com</name>
|
32
|
+
<email>flexinstyle@gmail.com</email>
|
33
|
+
</author>
|
34
|
+
<gCal:accesslevel value="owner"/>
|
35
|
+
<gCal:color value="#A32929"/>
|
36
|
+
<gCal:hidden value="false"/>
|
37
|
+
<gCal:selected value="true"/>
|
38
|
+
<gCal:timezone value="America/Phoenix"/>
|
39
|
+
<gCal:timesCleaned value="0"/>
|
40
|
+
</entry>
|
41
|
+
<entry gd:etag="W/"A0QBRX47eCp7IWA9WxBaEk0."" gd:kind="calendar#calendar">
|
42
|
+
<id>http://www.google.com/calendar/feeds/default/calendars/en.usa%23holiday%40group.v.calendar.google.com</id>
|
43
|
+
<published>2010-03-22T03:32:44.788Z</published>
|
44
|
+
<updated>2010-03-21T22:09:14.000Z</updated>
|
45
|
+
<app:edited>2010-03-21T22:09:14.000Z</app:edited>
|
46
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
47
|
+
<title type="text">US Holidays</title>
|
48
|
+
<summary type="text">US Holidays</summary>
|
49
|
+
<content type="application/atom+xml" src="http://www.google.com/calendar/feeds/en.usa%23holiday%40group.v.calendar.google.com/private/full"/>
|
50
|
+
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/en.usa%23holiday%40group.v.calendar.google.com/private/full"/>
|
51
|
+
<link rel="http://schemas.google.com/gCal/2005#eventFeed" type="application/atom+xml" href="http://www.google.com/calendar/feeds/en.usa%23holiday%40group.v.calendar.google.com/private/full"/>
|
52
|
+
<link rel="self" type="application/atom+xml" href="http://www.google.com/calendar/feeds/default/allcalendars/full/en.usa%23holiday%40group.v.calendar.google.com"/>
|
53
|
+
<link rel="edit" type="application/atom+xml" href="http://www.google.com/calendar/feeds/default/allcalendars/full/en.usa%23holiday%40group.v.calendar.google.com"/>
|
54
|
+
<author>
|
55
|
+
<name>US Holidays</name>
|
56
|
+
</author>
|
57
|
+
<gCal:accesslevel value="read"/>
|
58
|
+
<gCal:color value="#2952A3"/>
|
59
|
+
<gCal:hidden value="false"/>
|
60
|
+
<gCal:selected value="true"/>
|
61
|
+
<gCal:timezone value="America/Phoenix"/>
|
62
|
+
<gCal:timesCleaned value="0"/>
|
63
|
+
</entry>
|
64
|
+
</feed>
|