google-ft 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
@@ -0,0 +1,4 @@
1
+ google_ft
2
+ ===============
3
+
4
+ Google Fusion Tables API for ruby.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "google-ft"
6
+ s.version = "0.0.2"
7
+ s.authors = ["Jon Durbin"]
8
+ s.email = ["jond@greenviewdata.com"]
9
+ s.homepage = "https://github.com/gdi/google-ft"
10
+ s.summary = %q{Work with Google Fusion Tables using a service account}
11
+ s.description = %q{Work with Google Fusion Tables using a service account}
12
+
13
+ s.rubyforge_project = "google-ft"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency 'rspec'
21
+ s.add_dependency 'bundler'
22
+ s.add_dependency 'google-sa-auth'
23
+ s.add_dependency 'json'
24
+ end
@@ -0,0 +1,96 @@
1
+ require 'json'
2
+ require 'curb-fu'
3
+ require 'google-sa-auth'
4
+ require 'google-ft/table'
5
+ require 'google-ft/table/column'
6
+ require 'google-ft/table/permission'
7
+
8
+ # Quick and dirty method to symbolize keys of a hash.
9
+ class Hash
10
+ def symbolize
11
+ self.inject({}){|item,(k,v)| item[k.to_sym] = v; item}
12
+ end
13
+ end
14
+
15
+ class GoogleFT
16
+ class << self
17
+ # Method to convert values into google-compatible format.
18
+ def to_google_ft_format(value)
19
+ if value.class == String
20
+ bytes = value.bytes.each.collect {|l| l.chr.gsub(/\\|'/) { |c| "\\#{c}" }.gsub('&', '%26').gsub("\b", '\\b').gsub("\f", '\\f').gsub("\n", '\\n').gsub("\r", '\\r').gsub("\t",'\\t')}
21
+ "'#{bytes.join}'"
22
+ elsif value.class == Array
23
+ "'#{value.first} #{value.last}'"
24
+ else
25
+ value.to_json
26
+ end
27
+ end
28
+
29
+ # Quick wrapper method for utilizing curb-fu.
30
+ def get_and_parse_response(args)
31
+ response = GoogleSAAuth::Client.run(args)
32
+
33
+ # Make sure we get a 20* status.
34
+ unless response.status.to_s =~ /^20/
35
+ puts response.body.to_s
36
+ raise RuntimeError
37
+ end
38
+
39
+ # Return the symbolized hash of the response body.
40
+ begin
41
+ JSON.parse(response.body).symbolize
42
+ rescue
43
+ response.body
44
+ end
45
+ end
46
+ end
47
+
48
+ attr_accessor :authorization, :token
49
+
50
+ def get_auth_token(args)
51
+ # Make sure the token wasn't already set and hasn't yet expired.
52
+ @authorization = nil unless has_auth?
53
+
54
+ # (Re)create the authorization.
55
+ @authorization ||= GoogleSAAuth.new(args)
56
+
57
+ # Save the token.
58
+ @token = @authorization.token
59
+ @authorization
60
+ end
61
+
62
+ def show_tables
63
+ require_auth
64
+ GoogleFT::Table.show_tables(@authorization.token_string)
65
+ end
66
+
67
+ def create_table(args)
68
+ require_auth
69
+
70
+ # Create the table and save it.
71
+ args[:token] = @authorization.token_string
72
+ table = GoogleFT::Table.new(args)
73
+ table.save
74
+ table
75
+ end
76
+
77
+ def delete_table(table_id)
78
+ require_auth
79
+ GoogleFT::Table.get_table_by_id(table_id, @authorization.token_string).delete
80
+ end
81
+
82
+ def get_table(table_id)
83
+ require_auth
84
+ GoogleFT::Table.get_table_by_id(table_id, @authorization.token_string)
85
+ end
86
+
87
+ private
88
+ def has_auth?
89
+ return false unless @token
90
+ @token.expired? ? false : true
91
+ end
92
+
93
+ def require_auth
94
+ raise RuntimeError unless has_auth?
95
+ end
96
+ end
@@ -0,0 +1,173 @@
1
+ class GoogleFT
2
+ class Table
3
+ # Base URI for the fusion tables API.
4
+ $FT_BASE_URI = 'https://www.googleapis.com/fusiontables/v1/tables'
5
+
6
+ class << self
7
+ # Show a list of tables, requires the authentication token.
8
+ def show_tables(token)
9
+ args = {
10
+ :uri => "#{$FT_BASE_URI}",
11
+ :method => 'get',
12
+ :headers => {
13
+ 'Authorization' => "Bearer #{token}"
14
+ }
15
+ }
16
+ result = GoogleFT.get_and_parse_response(args)
17
+ return [] if result[:items].nil?
18
+ result[:items].each.collect do |table|
19
+ table = table.symbolize
20
+ GoogleFT::Table.new(
21
+ :token => token,
22
+ :id => table[:tableId],
23
+ :name => table[:name],
24
+ :columns => table[:columns],
25
+ :description => table[:description],
26
+ :exportable => table[:isExportable]
27
+ )
28
+ end
29
+ end
30
+
31
+ # Get a table by it's ID and return a table object.
32
+ def get_table_by_id(table_id, token = nil)
33
+ args = {
34
+ :uri => "#{$FT_BASE_URI}/#{table_id}",
35
+ :method => 'get'
36
+ }
37
+
38
+ # Add the auth token if it was provided.
39
+ args[:headers] = {'Authorization' => "Bearer #{token}"} unless token.nil?
40
+
41
+ # Get and parse results.
42
+ result = GoogleFT.get_and_parse_response(args)
43
+ GoogleFT::Table.new(
44
+ :token => token,
45
+ :id => result[:tableId],
46
+ :name => result[:name],
47
+ :columns => result[:columns],
48
+ :description => result[:description],
49
+ :exportable => result[:isExportable]
50
+ )
51
+ end
52
+ end
53
+
54
+
55
+ # Accessors.
56
+ attr_accessor :columns, :id, :name, :description, :exportable, :token
57
+ attr_accessor :permissions
58
+
59
+ # Create a new table object.
60
+ def initialize(args = {})
61
+ # Clean-up args.
62
+ args = args.symbolize.delete_if {|k,v| ![:id, :name, :columns, :description, :exportable, :token].include?(k)}
63
+
64
+ # Create nicely formated columns.
65
+ self.columns = args[:columns].nil? ? [] : args[:columns].each.collect do |col|
66
+ name = col[:name] || col['name']
67
+ type = col[:type] || col['type']
68
+ GoogleFT::Table::Column.new(name, type)
69
+ end
70
+
71
+ # Set other attributes.
72
+ self.token = args[:token]
73
+ self.id = args[:id]
74
+ self.name = args[:name].gsub(/[^a-zA-Z0-9_\-]/, '_')
75
+ self.description = args[:description] || ''
76
+ self.exportable = args[:exportable].nil? ? false : args[:exportable]
77
+ end
78
+
79
+ # Delete a table.
80
+ def delete
81
+ args = {
82
+ :uri => "#{$FT_BASE_URI}/#{self.id}",
83
+ :headers => {
84
+ 'Authorization' => "Bearer #{self.token}",
85
+ },
86
+ :data => '',
87
+ :method => 'delete'
88
+ }
89
+ GoogleFT.get_and_parse_response(args)
90
+ true
91
+ end
92
+
93
+ # Save this table to Google.
94
+ # Used for creating or updating tables.
95
+ def save
96
+ # If ID exists, we are updating a table,
97
+ # otherwise, we are creating it.
98
+ method = self.id.nil? ? 'post' : 'put'
99
+ uri = 'https://www.googleapis.com/fusiontables/v1/tables'
100
+ uri += "/#{self.id}" unless self.id.nil?
101
+ args = {
102
+ :uri => uri,
103
+ :headers => {
104
+ 'Content-Type' => 'application/json',
105
+ 'Authorization' => "Bearer #{self.token}"
106
+ },
107
+ :data => post_args,
108
+ :method => method
109
+ }
110
+ result = GoogleFT.get_and_parse_response(args)
111
+ self.id = result[:tableId]
112
+ result
113
+ end
114
+
115
+ # Set permissions for a table.
116
+ def set_permissions(permission)
117
+ args = {
118
+ :uri => "https://www.googleapis.com/drive/v2/files/#{self.id}/permissions",
119
+ :headers => {
120
+ 'Content-Type' => 'application/json',
121
+ 'Authorization' => "Bearer #{self.token}"
122
+ },
123
+ :method => 'post',
124
+ :data => permission.post_args
125
+ }
126
+ GoogleFT.get_and_parse_response(args)
127
+ end
128
+
129
+ # Return the JSON string of our table arguments.
130
+ # Used for creating and updating tables.
131
+ def post_args
132
+ {
133
+ :name => self.name,
134
+ :columns => self.columns.each.collect {|col| {:name => col.name, :type => col.type}},
135
+ :isExportable => self.exportable,
136
+ :description => self.description
137
+ }.to_json
138
+ end
139
+
140
+ # Insert rows into a table.
141
+ def insert(rows)
142
+ # Get the SQL-ish statement from arg hash.
143
+ inserts = []
144
+
145
+ # Go through each row.
146
+ rows.each do |row|
147
+
148
+ # Get all of the column/value pairs.
149
+ columns = []
150
+ values = []
151
+ row.each do |column,value|
152
+ columns.push(column)
153
+ values.push(value)
154
+ end
155
+
156
+ # Add this insert line.
157
+ inserts.push("INSERT INTO #{self.id} (#{columns.join(',')}) VALUES (#{values.each.collect {|v| GoogleFT.to_google_ft_format(v)}.join(',')});")
158
+ end
159
+
160
+ # Post the insert's to Google.
161
+ args = {
162
+ :uri => 'https://www.googleapis.com/fusiontables/v1/query',
163
+ :headers => {
164
+ 'Authorization' => "Bearer #{self.token}"
165
+ },
166
+ :method => 'post',
167
+ :data => "sql=#{inserts.join("\n")}"
168
+ }
169
+ puts "SQL:\n#{inserts.join("\n")}"
170
+ GoogleFT.get_and_parse_response(args)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,16 @@
1
+ class GoogleFT
2
+ class Table
3
+ class Column
4
+ attr_accessor :name, :type
5
+
6
+ def initialize(name, type = 'string')
7
+ # Cleanup the column name.
8
+ self.name = name.gsub(/[^a-zA-Z0-9_\-]/, '_')
9
+
10
+ # Store type and make sure it's valid.
11
+ self.type = type.upcase
12
+ raise ArgumentError unless ['STRING','NUMBER','DATETIME','LOCATION'].include?(self.type)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ class GoogleFT
2
+ class Table
3
+ class Permission
4
+ attr_accessor :role, :type, :value, :require_link
5
+ def initialize(args)
6
+ # Clean up args and make sure we were at least supplied the required ones.
7
+ args = args.symbolize.delete_if {|k,v| ![:role, :type, :value, :require_link].include?(k)}
8
+ raise ArgumentError unless args[:role] && args[:type]
9
+
10
+ # Set defaults.
11
+ args[:value] ||= 'me'
12
+ args[:require_link] ||= false
13
+
14
+ # Set the attributes.
15
+ self.role = args[:role]
16
+ self.type = args[:type]
17
+ self.value = args[:value]
18
+ self.require_link = args[:require_link]
19
+ end
20
+
21
+ def post_args
22
+ # JSON formatted string for this permission.
23
+ {
24
+ :role => self.role,
25
+ :type => self.type,
26
+ :value => self.value,
27
+ :withLink => self.require_link
28
+ }.to_json
29
+ end
30
+ end
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google-ft
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Durbin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !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: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: google-sa-auth
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Work with Google Fusion Tables using a service account
79
+ email:
80
+ - jond@greenviewdata.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - Gemfile
86
+ - README.md
87
+ - Rakefile
88
+ - google-ft.gemspec
89
+ - lib/google-ft.rb
90
+ - lib/google-ft/table.rb
91
+ - lib/google-ft/table/column.rb
92
+ - lib/google-ft/table/permission.rb
93
+ homepage: https://github.com/gdi/google-ft
94
+ licenses: []
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project: google-ft
113
+ rubygems_version: 1.8.24
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: Work with Google Fusion Tables using a service account
117
+ test_files: []
118
+ has_rdoc: