googletastic 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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>
|