sheetsapi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +81 -0
  4. data/lib/sheetsAPI.rb +121 -0
  5. metadata +61 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5887f33b34b4d32d067e4cc69728f5532a157af1
4
+ data.tar.gz: e12c57c00648b6bbadbff69f140c49981b4c099a
5
+ SHA512:
6
+ metadata.gz: 53cbf7018790907f3aa5162fc84200ca85a620645c9848d8aae8290e2332d0d9f6238d6c221535a0d4222b5b1addaa293ab806533080966b124d56652d946ad1
7
+ data.tar.gz: 65b7c0fa468630afe0e453e1bc17b4b11dca4e61475375881a8771df733e89aa93594909af13f9c9d20996e4e3c5ee1548f97c22c7f0b682e3bf4d74648ffde1
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Phusion B.V.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ Simple Sheets API
2
+ ============================
3
+
4
+ This gem contains a simple API to insert data into google sheets.
5
+
6
+ Authentication
7
+ ==============
8
+
9
+ This gem needs to authenticate as a Google Service Account to access files.
10
+ Follow these steps to download the credentials you need:
11
+
12
+ 1. Go to https://console.developers.google.com/apis/dashboard
13
+ 2. Create a new Project (if you have to)
14
+ 2. Enable the Google Sheets API
15
+ 3. Go to 'Credentials'
16
+ 4. Create Credentials for a 'Service account key'
17
+ 6. Under 'Service account' select your Project. Key type JSON.
18
+ 7. Save the downloaded file as 'GoogleAPICredentials.json' in the root of your project
19
+
20
+ To give the API access to a sheet in Google Sheets, you need to specifically share that document with the Service Account.
21
+ In the GoogleAPICredentials.json file you will find a `client_email` field. Share a document with that email address to grant access.
22
+
23
+
24
+ Usage
25
+ =====
26
+
27
+ document = SheetsAPI.document("1xuQVCadaMmTPiz_13hXuZHGKDihc41w5aii4DtuxOmU5j_eQ4BD98T-H")
28
+ sheet = document.sheet("Daily Sales")
29
+ sheet.insert(
30
+ index: [:Date, :Client],
31
+ sort: true,
32
+ upsert: true,
33
+ rows: [
34
+ {
35
+ Date: Date.new(2017,3,9),
36
+ Client: "Some Guy",
37
+ Email: "guy@client.com",
38
+ Sales: 14,
39
+ Profit: 5
40
+ },
41
+ {
42
+ Date: Date.new(2017,3,9),
43
+ Client: "Other Guy",
44
+ Sales: 2,
45
+ Profit: -1
46
+ },
47
+ {
48
+ Date: Date.new(2017,3,10),
49
+ Client: "Some Guy",
50
+ Email: "guy@client.com",
51
+ Sales: 8,
52
+ Margin: 3
53
+ }
54
+ ]
55
+ )
56
+
57
+ Insert Parameters
58
+ =================
59
+
60
+ Index
61
+ -----
62
+ The headers to use for upsert matching and sorting. Case sensitive. Default: []
63
+ If no index is provided, sort and upsert have no effect.
64
+
65
+ Sort
66
+ ----
67
+ Sort the content of the sheet based on the index after all other operations are completed. Default: false
68
+
69
+ Upsert
70
+ ------
71
+ Attempt to match given inputs to existing rows, based on the index. Default: false
72
+ If the index fields are the same, the data provided in the row parameter will override the existing row in the sheet.
73
+
74
+ Rows
75
+ ----
76
+ An array of objects that represent rows to be updated. Default: []
77
+ Keys in the objects represent the header for the value. Keys are case sensitive.
78
+ The default behaviour is to insert new rows in the sheet for all provided rows.
79
+ Set the Upsert parameter to change to update instead.
80
+ It is not necessary to provide a value for every header value.
81
+ For the index headers, an empty value is considered "" for comparisons.
data/lib/sheetsAPI.rb ADDED
@@ -0,0 +1,121 @@
1
+ require 'set'
2
+ require 'googleauth'
3
+ require 'google/apis/sheets_v4'
4
+
5
+ # # Uncomment this to inspect requests made to the google API
6
+ # module Google
7
+ # module Apis
8
+ # module Core
9
+ # class HttpClientAdapter
10
+ # alias old_call call
11
+ # def call(request)
12
+ # puts request.inspect
13
+ # old_call(request)
14
+ # end
15
+ # end
16
+ # end
17
+ # end
18
+ # end
19
+
20
+ module SheetsAPI
21
+ if !File.file? "#{Dir.pwd}/GoogleAPICredentials.json"
22
+ raise "Missing Google API Credentials: #{Dir.pwd}/GoogleAPICredentials.json"
23
+ end
24
+
25
+ ENV["GOOGLE_APPLICATION_CREDENTIALS"] = "#{Dir.pwd}/GoogleAPICredentials.json"
26
+ scopes = ['https://www.googleapis.com/auth/drive']
27
+ authorization = Google::Auth.get_application_default(scopes)
28
+
29
+ SheetService = Google::Apis::SheetsV4::SheetsService.new
30
+ SheetService.authorization = authorization
31
+
32
+ class << self
33
+ # This will raise if the document cannot be opened
34
+ def document(id)
35
+ return Document.new(id)
36
+ end
37
+ end
38
+
39
+ class Sheet
40
+ def initialize(document, sheetName)
41
+ @document = document
42
+ @sheetName = sheetName
43
+ end
44
+
45
+ def insert(rows:[], index:[], upsert: false, sort: false)
46
+ # Get current content of sheet
47
+ sheetContent = SheetService.get_spreadsheet_values(@document.id, "'#{@sheetName}'")&.values || []
48
+
49
+ # Get current headers in the sheet
50
+ sheetHeaders = sheetContent.shift || []
51
+
52
+ # Add any missing headers
53
+ missingHeaders = ([Set.new(index)] + rows.map(&:keys)).reduce(&:merge).to_a.map(&:to_s) - sheetHeaders
54
+ newHeaders = sheetHeaders + missingHeaders
55
+ symbolHeaders = newHeaders.map(&:to_sym)
56
+
57
+ # If we need to upsert and an index is provided
58
+ if upsert && index.length > 0
59
+ # If we upsert a row it no longer needs further processing
60
+ rows.delete_if do |row|
61
+ rowIndex = index.map{ |i| row[i].to_s }
62
+ lineIndex = index.map{ |i| symbolHeaders.index(i) }
63
+ # Attempt to match the index of the row with the corresponding index of each line in the current content
64
+ match = sheetContent.index{ |line| lineIndex.map{ |i| line[i] } == rowIndex }
65
+ # If we match, replace the values in that line with the contents of our row, and return true to remove this row
66
+ if match
67
+ sheetContent[match] = symbolHeaders.each_with_index.map { |header, index| row[header] || sheetContent[match][index] }
68
+ true
69
+ else
70
+ false
71
+ end
72
+ end
73
+ end
74
+
75
+ # Append any remaining rows
76
+ sheetContent += rows.map{ |row| symbolHeaders.map{ |header| row[header] || "" }}
77
+
78
+ # Sort the output
79
+ if sort && index.length > 0
80
+ sortIndex = index.map{ |s| symbolHeaders.index(s) }
81
+ sheetContent.sort!{ |row1, row2| sortIndex.map{ |i| row1[i].to_s } <=> sortIndex.map{ |i| row2[i].to_s }}
82
+ end
83
+
84
+ # Write the updated content to the spreadsheet
85
+ SheetService.update_spreadsheet_value(@document.id, "'#{@sheetName}'", {major_dimension: "ROWS", values: sheetContent.unshift(newHeaders)}, value_input_option: 'USER_ENTERED')
86
+
87
+ end
88
+ end
89
+
90
+ class Document
91
+ def initialize(documentId)
92
+ @id = documentId
93
+ @document = SheetService.get_spreadsheet(documentId)
94
+ end
95
+ attr_reader :id
96
+
97
+ def sheet(sheetName)
98
+ @sheetName = sheetName
99
+
100
+ sheet = @document.sheets.find{|sheet| sheet.properties.title.downcase == sheetName.downcase}
101
+ if !sheet
102
+ createSheet(sheetName)
103
+ end
104
+
105
+ return Sheet.new(self, sheetName)
106
+ end
107
+
108
+ private
109
+
110
+ def createSheet(sheetName)
111
+ batch_update_request = {requests: [{
112
+ add_sheet: {
113
+ properties: {
114
+ title: sheetName
115
+ }
116
+ }
117
+ }]}
118
+ SheetService.batch_update_spreadsheet(@id, batch_update_request, {})
119
+ end
120
+ end
121
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sheetsapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Phusion
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: google-api-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
27
+ description: A simple API for writing to Google Sheets
28
+ email:
29
+ - team@phusion.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE
35
+ - README.md
36
+ - lib/sheetsAPI.rb
37
+ homepage: https://github.com/phusion/SheetsAPI
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.6.10
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: A simple API for writing to Google Sheets
61
+ test_files: []