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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +81 -0
- data/lib/sheetsAPI.rb +121 -0
- 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: []
|