sheetsapi 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.
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: []