googletastic 0.0.3 → 0.0.4
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/lib/googletastic.rb +1 -1
- data/lib/googletastic/base.rb +2 -0
- data/lib/googletastic/document.rb +24 -4
- data/lib/googletastic/form.rb +82 -9
- data/lib/googletastic/mixins/actions.rb +8 -7
- data/lib/googletastic/mixins/attributes.rb +1 -1
- data/lib/googletastic/mixins/finders.rb +1 -0
- data/lib/googletastic/mixins/namespaces.rb +3 -1
- data/lib/googletastic/mixins/requesting.rb +1 -1
- data/lib/googletastic/row.rb +108 -0
- data/lib/googletastic/spreadsheet.rb +45 -11
- data/lib/googletastic/table.rb +59 -0
- data/lib/googletastic/worksheet.rb +47 -0
- data/spec/config.yml +1 -2
- data/spec/fixtures/data/doclist.xml +1 -1
- data/spec/googletastic/document_spec.rb +1 -0
- data/spec/googletastic/spreadsheet_spec.rb +39 -1
- metadata +5 -2
data/lib/googletastic.rb
CHANGED
data/lib/googletastic/base.rb
CHANGED
@@ -47,7 +47,7 @@ class Googletastic::Document < Googletastic::Base
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
body.xpath("//div[@id='google-view-footer']").each { |n| n.unlink }
|
50
|
-
@content = body.xpath("//div[@id='doc-contents']").first
|
50
|
+
@content = body.xpath("//div[@id='doc-contents']").first.to_html
|
51
51
|
end
|
52
52
|
|
53
53
|
def acl
|
@@ -98,11 +98,12 @@ class Googletastic::Document < Googletastic::Base
|
|
98
98
|
:language => "sourceLanguage",
|
99
99
|
:permanent_delete => "delete",
|
100
100
|
:convert => "convert",
|
101
|
-
:format => "exportFormat"
|
101
|
+
:format => "exportFormat",
|
102
|
+
:kind => "category"
|
102
103
|
}.merge(super)
|
103
104
|
end
|
104
105
|
|
105
|
-
def
|
106
|
+
def valid_kind?(value)
|
106
107
|
%w(document spreadsheet folder presentation pdf form).include?(value)
|
107
108
|
end
|
108
109
|
|
@@ -173,7 +174,7 @@ class Googletastic::Document < Googletastic::Base
|
|
173
174
|
title = record.xpath("atom:title", ns_tag("atom")).text
|
174
175
|
categories = record.xpath("atom:category", ns_tag("atom")).collect do |category|
|
175
176
|
value = category["label"].to_s
|
176
|
-
kind = value if !kind and
|
177
|
+
kind = value if !kind and valid_kind?(value)
|
177
178
|
value
|
178
179
|
end
|
179
180
|
resource_id = record.xpath("gd:resourceId", ns_tag("gd")).text
|
@@ -215,5 +216,24 @@ class Googletastic::Document < Googletastic::Base
|
|
215
216
|
}
|
216
217
|
}.to_xml
|
217
218
|
end
|
219
|
+
|
220
|
+
def get_clean_content(remote)
|
221
|
+
title = remote.title
|
222
|
+
ext = remote.ext
|
223
|
+
if ext == ".textile"
|
224
|
+
# google is putting strange characters at beginning of downloaded files
|
225
|
+
content = remote.download("txt").body.gsub(/\357\273\277/, "")
|
226
|
+
content = RedCloth.new(content).to_html
|
227
|
+
elsif ext == ".markdown"
|
228
|
+
content = remote.download("txt").body.gsub(/\357\273\277/, "")
|
229
|
+
content = BlueCloth.new(content).to_html
|
230
|
+
elsif ext.nil? || ext.empty?
|
231
|
+
# just use the html we have already
|
232
|
+
content = remote.content
|
233
|
+
else
|
234
|
+
content = remote.download("txt").body.gsub(/\357\273\277/, "")
|
235
|
+
end
|
236
|
+
content
|
237
|
+
end
|
218
238
|
end
|
219
239
|
end
|
data/lib/googletastic/form.rb
CHANGED
@@ -3,7 +3,7 @@ class Googletastic::Form < Googletastic::Base
|
|
3
3
|
|
4
4
|
FORM_KEY_EXPRESSION = /formkey["|']\s*:["|']\s*([^"|']+)"/ unless defined?(FORM_KEY_EXPRESSION)
|
5
5
|
|
6
|
-
attr_accessor :title, :body, :redirect_to, :form_key, :form_only, :authenticity_token
|
6
|
+
attr_accessor :title, :body, :redirect_to, :form_key, :form_only, :authenticity_token, :spreadsheet
|
7
7
|
|
8
8
|
def body(options = {}, &block)
|
9
9
|
@body ||= get(options, &block)
|
@@ -18,8 +18,69 @@ class Googletastic::Form < Googletastic::Base
|
|
18
18
|
self.class.show_url(self.form_key)
|
19
19
|
end
|
20
20
|
|
21
|
+
def form_key
|
22
|
+
@form_key ||= get_form_key
|
23
|
+
end
|
24
|
+
|
25
|
+
def properties
|
26
|
+
body
|
27
|
+
@properties
|
28
|
+
end
|
29
|
+
|
30
|
+
# this you want to call JUST BEFORE you render in the view
|
31
|
+
# body still gives you the nokogiri element
|
32
|
+
def render
|
33
|
+
if self.form_only
|
34
|
+
result = body.xpath("//form").first.unlink
|
35
|
+
else
|
36
|
+
body.xpath("//div[@class='ss-footer']").first.unlink
|
37
|
+
body.xpath("//script").each {|x| x.unlink }
|
38
|
+
result = body.xpath("//div[@class='ss-form-container']").first.unlink
|
39
|
+
end
|
40
|
+
result.to_html
|
41
|
+
end
|
42
|
+
|
43
|
+
# {columen_name => value}
|
44
|
+
def set_defaults(hash)
|
45
|
+
hash.each do |column, value|
|
46
|
+
entry = properties[column]
|
47
|
+
next unless entry and !entry.empty?
|
48
|
+
nodes = body.xpath("//*[@name='#{entry}']")
|
49
|
+
if entry =~ /group/
|
50
|
+
nodes.each do |node|
|
51
|
+
if node["value"] == value
|
52
|
+
node["checked"] = "checked"
|
53
|
+
break
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
node = nodes.first
|
58
|
+
next unless node
|
59
|
+
case node.name.to_s
|
60
|
+
when "input"
|
61
|
+
node["value"] = value
|
62
|
+
when "textarea"
|
63
|
+
node.content = value
|
64
|
+
when "select"
|
65
|
+
node.xpath("option").each do |option|
|
66
|
+
if option["value"] == value
|
67
|
+
option["selected"] = "selected"
|
68
|
+
break
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
21
76
|
class << self
|
22
77
|
|
78
|
+
def find_one(id, options)
|
79
|
+
options[:id] = id
|
80
|
+
options[:url] = self.get_url(id)
|
81
|
+
find_by_api(options).first
|
82
|
+
end
|
83
|
+
|
23
84
|
def client_class
|
24
85
|
"Spreadsheets"
|
25
86
|
end
|
@@ -28,6 +89,10 @@ class Googletastic::Form < Googletastic::Base
|
|
28
89
|
"http://spreadsheets.google.com/feeds/spreadsheets/private/full"
|
29
90
|
end
|
30
91
|
|
92
|
+
def get_url(id)
|
93
|
+
"http://spreadsheets.google.com/feeds/spreadsheets/private/full/#{id}"
|
94
|
+
end
|
95
|
+
|
31
96
|
def submit_url(id = "")
|
32
97
|
"http://spreadsheets.google.com/formResponse?formkey=#{id}"
|
33
98
|
end
|
@@ -61,7 +126,7 @@ class Googletastic::Form < Googletastic::Base
|
|
61
126
|
|
62
127
|
def get_form_key
|
63
128
|
begin
|
64
|
-
agent = WWW::Mechanize.new
|
129
|
+
agent = defined?(Mechanize) ? Mechanize.new : WWW::Mechanize.new
|
65
130
|
# google wants recent browsers!
|
66
131
|
# http://docs.google.com/support/bin/answer.py?answer=37560&hl=en
|
67
132
|
agent.user_agent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; ru-ru) AppleWebKit/533.2+ (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
|
@@ -119,17 +184,25 @@ class Googletastic::Form < Googletastic::Base
|
|
119
184
|
node.add_child Nokogiri::XML::Text.new("\n", html)
|
120
185
|
end
|
121
186
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
187
|
+
@properties = {}
|
188
|
+
html.css("div.ss-item").each do |item|
|
189
|
+
entry = item.xpath("div[@class='ss-form-entry']").first
|
190
|
+
label = entry.xpath("label[@class='ss-q-title']").first
|
191
|
+
next unless label
|
192
|
+
single = (item["class"].to_s =~ /ss-(grid|scale)/).nil?
|
193
|
+
type = single ? "single" : "group"
|
194
|
+
column = label.text.downcase.gsub(/[^a-z0-9\-]/, "")
|
195
|
+
input_name = label["for"].gsub("_", ".").squeeze("\.") + "." + type
|
196
|
+
@properties[column] = input_name
|
128
197
|
end
|
198
|
+
|
199
|
+
html
|
129
200
|
end
|
130
201
|
|
131
202
|
def add_redirect(doc, options, &block)
|
132
|
-
action = doc.xpath("//form").first
|
203
|
+
action = doc.xpath("//form").first
|
204
|
+
return if action.nil?
|
205
|
+
action = action["action"].to_s
|
133
206
|
submit_key = action.gsub(self.submit_url, "")
|
134
207
|
|
135
208
|
form = doc.xpath("//form").first
|
@@ -63,9 +63,7 @@ module Googletastic::Mixins::Actions
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def upload_url
|
66
|
-
puts "UPLOADURL"
|
67
66
|
self.class.upload_url(self.id)
|
68
|
-
puts "POST"
|
69
67
|
end
|
70
68
|
|
71
69
|
def save
|
@@ -95,17 +93,20 @@ module Googletastic::Mixins::Actions
|
|
95
93
|
|
96
94
|
def create
|
97
95
|
if has_attachment?
|
98
|
-
self.class.client.post_file(self.
|
96
|
+
self.class.client.post_file(self.index_url, self.attachment_path, mime_type, self.to_xml)
|
99
97
|
else
|
100
|
-
self.class.client.post(self.
|
98
|
+
self.class.client.post(self.index_url, self.to_xml)
|
101
99
|
end
|
102
100
|
end
|
103
|
-
|
101
|
+
|
104
102
|
def update(attribute_names = @attributes.keys)
|
105
103
|
if has_attachment?
|
106
|
-
self.class.client.put_file(self.
|
104
|
+
self.class.client.put_file(self.index_url, self.attachment_path, mime_type, self.to_xml)
|
107
105
|
else
|
108
|
-
|
106
|
+
original_headers = self.client.headers.dup
|
107
|
+
self.client.headers["If-Match"] = self.etag if self.respond_to?(:etag)
|
108
|
+
self.class.client.put(self.edit_url || self.index_url, self.to_xml)
|
109
|
+
self.client.headers = original_headers
|
109
110
|
end
|
110
111
|
end
|
111
112
|
end
|
@@ -21,7 +21,7 @@ module Googletastic::Mixins::Attributes
|
|
21
21
|
|
22
22
|
def inspect
|
23
23
|
hash = ""
|
24
|
-
attributes.each { |k,v| hash << " @#{k.to_s}=#{v.inspect}" }
|
24
|
+
attributes.each { |k,v| hash << " @#{k.to_s}=#{v.inspect}" unless k.to_s == "raw" }
|
25
25
|
"#<#{self.class.to_s}#{hash}/>"
|
26
26
|
end
|
27
27
|
end
|
@@ -12,7 +12,9 @@ module Googletastic::Mixins::Namespaces
|
|
12
12
|
"app" => "http://www.w3.org/2007/app",
|
13
13
|
"gCal" => "http://schemas.google.com/gCal/2005",
|
14
14
|
"gContact" => "http://schemas.google.com/contact/2008",
|
15
|
-
"batch" => "http://schemas.google.com/gdata/batch"
|
15
|
+
"batch" => "http://schemas.google.com/gdata/batch",
|
16
|
+
"gs" => "http://schemas.google.com/spreadsheets/2006",
|
17
|
+
"gsx" => "http://schemas.google.com/spreadsheets/2006/extended"
|
16
18
|
} unless defined?(NAMESPACES)
|
17
19
|
|
18
20
|
def self.included(base)
|
@@ -50,7 +50,7 @@ module Googletastic::Mixins::Requesting
|
|
50
50
|
options.inject({}) do |converted, (key, value)|
|
51
51
|
real_key = queries[key]
|
52
52
|
if queries.has_key?(key)
|
53
|
-
next if self.respond_to?("valid_#{real_key}?") and !self
|
53
|
+
next if self.respond_to?("valid_#{real_key}?") and !self.send("valid_#{real_key}?", value)
|
54
54
|
value = self.send("convert_#{real_key}", value) if self.respond_to?("convert_#{real_key}")
|
55
55
|
converted[real_key] = value
|
56
56
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
class Googletastic::Row < Googletastic::Base
|
2
|
+
|
3
|
+
attr_accessor :data, :worksheet_id, :spreadsheet_id, :title, :etag
|
4
|
+
|
5
|
+
def get_url
|
6
|
+
self.class.get_url(File.join(self.spreadsheet_id, self.worksheet_id), self.id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def index_url
|
10
|
+
"http://spreadsheets.google.com/feeds/list/#{self.spreadsheet_id}/#{self.worksheet_id}/private/full"
|
11
|
+
end
|
12
|
+
|
13
|
+
def edit_url
|
14
|
+
"http://spreadsheets.google.com/feeds/list/#{self.spreadsheet_id}/#{self.worksheet_id}/private/full/#{self.id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Time.now.xmlschema
|
18
|
+
class << self
|
19
|
+
|
20
|
+
def client_class
|
21
|
+
"Spreadsheets"
|
22
|
+
end
|
23
|
+
|
24
|
+
def index_url(path)
|
25
|
+
"http://spreadsheets.google.com/feeds/list/#{path}/private/full"
|
26
|
+
end
|
27
|
+
|
28
|
+
def show_url(path, id)
|
29
|
+
"http://spreadsheets.google.com/feeds/list/#{path}/private/full/#{id}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_url(path, id)
|
33
|
+
"http://spreadsheets.google.com/feeds/list/#{path}/private/full/#{id}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_url(options)
|
37
|
+
raise "You must specify a spreadsheet key 'key' and a 'worksheet_id' for a list of rows" unless (options[:key] and options[:worksheet_id])
|
38
|
+
options[:url] ||= index_url(File.join(options[:key], options[:worksheet_id]))
|
39
|
+
super(options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def unmarshall(xml)
|
43
|
+
records = xml.xpath("//atom:entry", ns_tag("atom")).collect do |record|
|
44
|
+
etag = record["etag"]
|
45
|
+
id = record.xpath("atom:id", ns_tag("atom")).first.text
|
46
|
+
ids = id =~ /http:\/\/spreadsheets\.google\.com\/feeds\/list\/([^\/]+)\/([^\/]+)\/([^\/]+)/
|
47
|
+
spreadsheet_id = $1
|
48
|
+
worksheet_id = $2
|
49
|
+
id = $3
|
50
|
+
title = record.xpath("atom:title", ns_tag("atom")).first.text
|
51
|
+
content = record.xpath("atom:content", ns_tag("atom")).first.text
|
52
|
+
created_at = record.xpath("atom:published", ns_tag("atom")).text
|
53
|
+
updated_at = record.xpath("atom:updated", ns_tag("atom")).text
|
54
|
+
data = {}
|
55
|
+
|
56
|
+
record.xpath("gsx:*", ns_tag('gsx')).each do |node|
|
57
|
+
next unless node.elem?
|
58
|
+
data[node.name] = node.text
|
59
|
+
end
|
60
|
+
|
61
|
+
Googletastic::Row.new(
|
62
|
+
:id => id,
|
63
|
+
:etag => etag,
|
64
|
+
:title => title,
|
65
|
+
:spreadsheet_id => spreadsheet_id,
|
66
|
+
:worksheet_id => worksheet_id,
|
67
|
+
:data => data,
|
68
|
+
:updated_at => DateTime.parse(updated_at),
|
69
|
+
:raw => record.to_xml
|
70
|
+
)
|
71
|
+
end
|
72
|
+
records
|
73
|
+
end
|
74
|
+
|
75
|
+
# for save and update
|
76
|
+
def marshall(record)
|
77
|
+
Nokogiri::XML::Builder.new { |xml|
|
78
|
+
attributes = nil
|
79
|
+
if record.id
|
80
|
+
attributes = {"etag" => record.etag}.merge(ns_xml("atom", "gsx"))
|
81
|
+
else
|
82
|
+
attributes = ns_xml("atom", "gsx")
|
83
|
+
end
|
84
|
+
xml.entry(attributes) {
|
85
|
+
if record.id # PUT = update
|
86
|
+
xml.id_ {
|
87
|
+
xml.text record.get_url
|
88
|
+
}
|
89
|
+
#xml.updated {
|
90
|
+
# xml.text record.updated.to_s
|
91
|
+
#}
|
92
|
+
end
|
93
|
+
if record.title
|
94
|
+
xml.title(:type => "text") {
|
95
|
+
xml.text record.title
|
96
|
+
}
|
97
|
+
end
|
98
|
+
record.data.each do |k,v|
|
99
|
+
xml["gsx"].send(k) {
|
100
|
+
xml.text v
|
101
|
+
}
|
102
|
+
end
|
103
|
+
}
|
104
|
+
}.to_xml
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -1,6 +1,32 @@
|
|
1
1
|
class Googletastic::Spreadsheet < Googletastic::Base
|
2
2
|
|
3
|
-
attr_accessor :title, :content
|
3
|
+
attr_accessor :title, :content, :edit_id
|
4
|
+
|
5
|
+
def worksheet_url
|
6
|
+
self.class.worksheet_url(self.id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def worksheet
|
10
|
+
@worksheet ||= Googletastic::Worksheet.first(:key => self.id)
|
11
|
+
end
|
12
|
+
|
13
|
+
def table
|
14
|
+
@table ||= Googletastic::Table.first(:key => self.id)
|
15
|
+
end
|
16
|
+
|
17
|
+
def rows
|
18
|
+
@rows ||= Googletastic::Row.all(:key => self.id, :worksheet_id => worksheet.id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def form
|
22
|
+
@form ||= Googletastic::Form.find(self.id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def columns
|
26
|
+
return @columns if @columns
|
27
|
+
row = @rows ? @rows.first : Googletastic::Row.first(:key => self.id, :worksheet_id => worksheet.id)
|
28
|
+
@columns = row.data.keys
|
29
|
+
end
|
4
30
|
|
5
31
|
# Time.now.xmlschema
|
6
32
|
class << self
|
@@ -12,24 +38,32 @@ class Googletastic::Spreadsheet < Googletastic::Base
|
|
12
38
|
def index_url
|
13
39
|
"http://spreadsheets.google.com/feeds/spreadsheets/private/full"
|
14
40
|
end
|
41
|
+
|
42
|
+
def show_url(id)
|
43
|
+
"http://spreadsheets.google.com/feeds/spreadsheets/private/full/#{id}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def worksheet_url(id)
|
47
|
+
"http://spreadsheets.google.com/feeds/worksheets/#{id}/private/full"
|
48
|
+
end
|
15
49
|
|
16
50
|
def unmarshall(xml)
|
17
51
|
records = xml.xpath("//atom:entry", ns_tag("atom")).collect do |record|
|
18
|
-
|
19
|
-
|
20
|
-
if
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
created_at = record.xpath("atom:published", ns_tag("atom")).text
|
26
|
-
updated_at = record.xpath("atom:updated", ns_tag("atom")).text
|
52
|
+
id = record.xpath("atom:id", ns_tag("atom")).first.text.gsub("http://spreadsheets.google.com/feeds/spreadsheets/", "")
|
53
|
+
edit_id = record.xpath("atom:link[@rel='alternate']", ns_tag("atom")).first
|
54
|
+
edit_id = edit_id["href"].gsub("http://spreadsheets.google.com/ccc?key=", "") if edit_id
|
55
|
+
title = record.xpath("atom:title", ns_tag("atom")).first.text
|
56
|
+
content = record.xpath("atom:content", ns_tag("atom")).first.text
|
57
|
+
created_at = record.xpath("atom:published", ns_tag("atom")).text
|
58
|
+
updated_at = record.xpath("atom:updated", ns_tag("atom")).text
|
27
59
|
|
28
60
|
Googletastic::Spreadsheet.new(
|
29
61
|
:id => id,
|
62
|
+
:edit_id => edit_id,
|
30
63
|
:title => title,
|
31
64
|
:content => content,
|
32
|
-
:updated_at => DateTime.parse(updated_at)
|
65
|
+
:updated_at => DateTime.parse(updated_at),
|
66
|
+
:raw => record.to_xml
|
33
67
|
)
|
34
68
|
end
|
35
69
|
records
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Googletastic::Table < Googletastic::Base
|
2
|
+
|
3
|
+
attr_accessor :title, :content, :summary, :columns, :spreadsheet_id, :num_rows, :start_row
|
4
|
+
|
5
|
+
# Time.now.xmlschema
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def client_class
|
9
|
+
"Spreadsheets"
|
10
|
+
end
|
11
|
+
|
12
|
+
def show_url(id)
|
13
|
+
"http://spreadsheets.google.com/feeds/#{id}/tables"
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_url(options)
|
17
|
+
raise "You must specify an spreadsheet key 'key' for a table" unless options[:key]
|
18
|
+
options[:url] ||= show_url(options[:key])
|
19
|
+
puts "URL: #{options[:url]}"
|
20
|
+
super(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def unmarshall(xml)
|
24
|
+
records = xml.xpath("//atom:entry", ns_tag("atom")).collect do |record|
|
25
|
+
id = record.xpath("atom:id", ns_tag("atom")).first.text
|
26
|
+
spreadsheet_id = id.gsub("http://spreadsheets.google.com/feeds/([^\/]+)/tables", "\1")
|
27
|
+
id = id.gsub("http://spreadsheets.google.com/feeds/([^\/]+)/tables/([^\/]+)", "\2")
|
28
|
+
title = record.xpath("atom:title", ns_tag("atom")).first.text
|
29
|
+
summary = record.xpath("atom:summary", ns_tag("atom")).first.text
|
30
|
+
content = record.xpath("atom:content", ns_tag("atom")).first.text
|
31
|
+
data = record.xpath("gs:data", ns_tag("gs"))
|
32
|
+
num_rows = data["numRows"].to_i
|
33
|
+
start_row = data["startRow"].to_i
|
34
|
+
columns = []
|
35
|
+
data.xpath("gs:column", ns_tag("gs")).each do |column|
|
36
|
+
columns << {:name => column["name"], :index => column["index"]}
|
37
|
+
end
|
38
|
+
columns = columns.sort {|a,b| b["index"] <=> a["index"]}.collect{|c| c["name"]}
|
39
|
+
created_at = record.xpath("atom:published", ns_tag("atom")).text
|
40
|
+
updated_at = record.xpath("atom:updated", ns_tag("atom")).text
|
41
|
+
|
42
|
+
Googletastic::Table.new(
|
43
|
+
:id => id,
|
44
|
+
:spreadsheet_id => spreadsheet_id,
|
45
|
+
:title => title,
|
46
|
+
:summary => summary,
|
47
|
+
:content => content,
|
48
|
+
:start_row => start_row,
|
49
|
+
:num_rows => num_rows,
|
50
|
+
:columns => columns,
|
51
|
+
:updated_at => DateTime.parse(updated_at),
|
52
|
+
:raw => record.to_xml
|
53
|
+
)
|
54
|
+
end
|
55
|
+
records
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Googletastic::Worksheet < Googletastic::Base
|
2
|
+
|
3
|
+
attr_accessor :title, :content, :spreadsheet_id
|
4
|
+
|
5
|
+
# Time.now.xmlschema
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def client_class
|
9
|
+
"Spreadsheets"
|
10
|
+
end
|
11
|
+
|
12
|
+
def show_url(id)
|
13
|
+
"http://spreadsheets.google.com/feeds/worksheets/#{id}/private/full"
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_url(options)
|
17
|
+
raise "You must specify an spreadsheet key 'key' for a worksheet" unless options[:key]
|
18
|
+
options[:url] ||= show_url(options[:key])
|
19
|
+
super(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def unmarshall(xml)
|
23
|
+
records = xml.xpath("//atom:entry", ns_tag("atom")).collect do |record|
|
24
|
+
id = record.xpath("atom:id", ns_tag("atom")).first.text
|
25
|
+
ids = id =~ /http:\/\/spreadsheets\.google\.com\/feeds\/worksheets\/([^\/]+)\/([^\/]+)/
|
26
|
+
spreadsheet_id = $1
|
27
|
+
id = $2
|
28
|
+
title = record.xpath("atom:title", ns_tag("atom")).first.text
|
29
|
+
content = record.xpath("atom:content", ns_tag("atom")).first.text
|
30
|
+
updated_at = record.xpath("atom:updated", ns_tag("atom")).text
|
31
|
+
|
32
|
+
worksheet = Googletastic::Worksheet.new(
|
33
|
+
:id => id,
|
34
|
+
:spreadsheet_id => spreadsheet_id,
|
35
|
+
:title => title,
|
36
|
+
:content => content,
|
37
|
+
:updated_at => DateTime.parse(updated_at),
|
38
|
+
:raw => record.to_xml
|
39
|
+
)
|
40
|
+
|
41
|
+
worksheet
|
42
|
+
end
|
43
|
+
records
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
data/spec/config.yml
CHANGED
@@ -2,5 +2,4 @@ username: "flexinstyle@gmail.com"
|
|
2
2
|
password: "flexyflexy"
|
3
3
|
application: "Googletastic Test"
|
4
4
|
account_type: "HOSTED_OR_GOOGLE"
|
5
|
-
youtube_login: "MrFlexinstyle"
|
6
|
-
youtube_dev_key: "AI39si7jkhs_ECjF4unOQz8gpWGSKXgq0KJpm8wywkvBSw4s8oJd5p5vkpvURHBNh-hiYJtoKwQqSfot7KoCkeCE32rNcZqMxA"
|
5
|
+
youtube_login: "MrFlexinstyle"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/"CkACSH88eip7ImA9WxBaEUQ."">
|
3
3
|
<id>http://docs.google.com/feeds/documents/private/full</id>
|
4
4
|
<updated>2010-03-21T16:59:29.172Z</updated>
|
@@ -2,8 +2,46 @@ require File.expand_path("./spec/spec_helper")
|
|
2
2
|
|
3
3
|
describe Googletastic::Spreadsheet do
|
4
4
|
|
5
|
+
it "should retrieve the records from a single spreadsheet" do
|
6
|
+
spreadsheet = Googletastic::Spreadsheet.find("tDewl4JDeSOAMMOiG9i2u-Q")
|
7
|
+
puts spreadsheet.inspect
|
8
|
+
spreadsheet.should be_an_instance_of(Googletastic::Spreadsheet)
|
9
|
+
end
|
10
|
+
=begin
|
5
11
|
it "should retrieve a list of spreadsheets" do
|
6
|
-
|
12
|
+
Googletastic::Spreadsheet.all
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should retrieve a spreadsheets worksheet" do
|
16
|
+
Googletastic::Spreadsheet.first.worksheet.should_not be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should retrieve a table within a spreadsheet" do
|
20
|
+
pending
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should retrieve a list of rows for a worksheet" do
|
24
|
+
rows = Googletastic::Spreadsheet.find("tDewl4JDeSOAMMOiG9i2u-Q&hl").rows
|
25
|
+
rows.each do |row|
|
26
|
+
puts row.data.inspect
|
27
|
+
# row.save
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should retrieve the form for the spreadsheet" do
|
32
|
+
form = Googletastic::Spreadsheet.first.form
|
33
|
+
puts form.inspect
|
7
34
|
end
|
8
35
|
|
36
|
+
it "should retrieve the form AND the formkey for the spreadsheet form" do
|
37
|
+
form = Googletastic::Spreadsheet.first.form
|
38
|
+
form.form_key
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should create a map of input entries to spreadsheet row data properties" do
|
42
|
+
spreadsheet = Googletastic::Spreadsheet.first
|
43
|
+
form = spreadsheet.form
|
44
|
+
form.set_defaults(spreadsheet.rows.first.data)
|
45
|
+
end
|
46
|
+
=end
|
9
47
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Lance Pollard
|
@@ -110,11 +110,14 @@ files:
|
|
110
110
|
- lib/googletastic/mixins/requesting.rb
|
111
111
|
- lib/googletastic/mixins.rb
|
112
112
|
- lib/googletastic/person.rb
|
113
|
+
- lib/googletastic/row.rb
|
113
114
|
- lib/googletastic/spreadsheet.rb
|
114
115
|
- lib/googletastic/sync/document.rb
|
115
116
|
- lib/googletastic/sync/form.rb
|
116
117
|
- lib/googletastic/sync.rb
|
118
|
+
- lib/googletastic/table.rb
|
117
119
|
- lib/googletastic/thumbnail.rb
|
120
|
+
- lib/googletastic/worksheet.rb
|
118
121
|
- lib/googletastic/youtube.rb
|
119
122
|
- lib/googletastic.rb
|
120
123
|
- spec/benchmarks/document_benchmark.rb
|