google_spreadsheet_fetcher 1.2.0 → 1.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8931e371e571bd4765be2b63a647d8028d4ed763abddd82dacf9f6d70f30a987
4
- data.tar.gz: ce41e8fa0daf651ea25ffecb195a74dad258d4a9ad6b5abde05c80999de3609a
3
+ metadata.gz: adf35fcabe96fa86ae6e1a6e30d728531471b24c8a1e358e7bf7506db08286ba
4
+ data.tar.gz: e6fa6c579750fb93ab46f28bfdf8f6ddda7d00b2c00c79dd29aff62ea9e269eb
5
5
  SHA512:
6
- metadata.gz: 325db541542d87960f7bd388be44f6d4977bb6e74df8804bfdeb152fd8b82f1079d1c0387bd8e1e878a629e2266aa3baad58264e5c4696056158b9d1f6e34377
7
- data.tar.gz: 9e297605b02343a4f688df0790b1c1e980689c74e092477967f385687dc36773f17ca1326a2521d0c9196a04c4c21dfc42e23b3127cc209cda88809eefae33ff
6
+ metadata.gz: 40492b6fbe256c65df40a92fc1e4a9d941a2eb25feb82f9f04a68226eb3d4b60defb5d5ba9cebf4dae042d8cb0e8c8ed2b60d76d9b61f2c886d646b04ba88d3d
7
+ data.tar.gz: 1ccab637e4927b1031c6e4b262461fb108a5728582bc9e7c9ffd31f29545c23ab146640da89543a56912958bf200452874e8cb5614329eb1ece7ccdc5a909e1d
data/README.md CHANGED
@@ -25,20 +25,32 @@ Or install it yourself as:
25
25
  - Make OAuth 2.0 Client. (other)
26
26
  - Download client secret json
27
27
 
28
+
28
29
  ```ruby
29
- credential_store_file = Rails.root.join('config', 'credential-oauth2-supporter.json').to_s
30
- sheet_key = 'YOUR_SHEET_KEY'
30
+ sheet_key = 'example_sheet_id'
31
31
 
32
32
  GoogleSpreadsheetFetcher.configure do |config|
33
- config.client_secrets_file_path = Rails.root.join('config', 'client_secrets_pokota_supporter.json').to_s
33
+ config.client_secrets_file = 'client_secrets_file_path.json'
34
+ config.credential_store_file = 'credential_store_file_path.json'
34
35
  end
35
36
 
36
37
  user_id = 'sample'
37
- fetcher = GoogleSpreadsheetFetcher::Fetcher.new(credential_store_file, user_id, sheet_key)
38
38
 
39
- fetcher.fetch_by_index(0)
40
- fetcher.fetch_by_title('title')
41
- fetcher.fetch_by_gid('gid')
39
+ fetcher = GoogleSpreadsheetFetcher::Fetcher.new(sheet_key, user_id)
40
+
41
+ fetcher.fetch_all_rows_by!(index: 0)
42
+ fetcher.fetch_all_rows_by!(title: 'sheet_title')
43
+ fetcher.fetch_all_rows_by!(sheet_id: 1234567890)
44
+
45
+
46
+ # or, you can do a bulk fetching. In this case, you only need to access the API once,
47
+ # but it will take a little longer on first fetch.
48
+ fetcher = GoogleSpreadsheetFetcher::BulkFetcher.new(sheet_key, user_id)
49
+ fetcher.fetch
50
+
51
+ fetcher.all_rows_by!(index: 0)
52
+ fetcher.all_rows_by!(title: 'sheet_title')
53
+ fetcher.all_rows_by!(sheet_id: 1234567890)
42
54
  ```
43
55
 
44
56
  ## Development
@@ -6,8 +6,8 @@ require 'google_spreadsheet_fetcher/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "google_spreadsheet_fetcher"
8
8
  spec.version = GoogleSpreadsheetFetcher::VERSION
9
- spec.authors = ["Takahiro Ooishi"]
10
- spec.email = ["taka0125@gmail.com"]
9
+ spec.authors = ["Takahiro Ooishi", "Yuya Yokosuka"]
10
+ spec.email = ["taka0125@gmail.com", "yuya.yokosuka@gmail.com"]
11
11
 
12
12
  spec.summary = %q{Google Spreadsheet fetcher}
13
13
  spec.description = %q{Google Spreadsheet fetcher}
@@ -1,8 +1,11 @@
1
+ require "active_support/json"
1
2
  require "active_support/core_ext"
2
3
  require "google_spreadsheet_fetcher/version"
3
4
  require "google_spreadsheet_fetcher/config"
4
5
  require "google_spreadsheet_fetcher/error"
5
6
  require "google_spreadsheet_fetcher/fetcher"
7
+ require "google_spreadsheet_fetcher/bulk_fetcher"
8
+ require "google_spreadsheet_fetcher/sheets_service_builder"
6
9
 
7
10
  module GoogleSpreadsheetFetcher
8
11
  def self.config
@@ -0,0 +1,82 @@
1
+ require 'google/apis/sheets_v4'
2
+ require 'shellwords'
3
+
4
+ module GoogleSpreadsheetFetcher
5
+ class BulkFetcher
6
+ # @param [String] spreadsheet_id
7
+ # @param [String] user_id
8
+ # @param [GoogleSpreadsheetFetcher::Config] config
9
+ # @param [String] application_name
10
+ def initialize(spreadsheet_id, user_id, config: nil, application_name: nil)
11
+ @spreadsheet_id = spreadsheet_id
12
+ @user_id = user_id
13
+ @config = config || GoogleSpreadsheetFetcher.config
14
+ @application_name = application_name
15
+
16
+ @spreadsheet = nil
17
+ end
18
+
19
+ def fetch
20
+ @spreadsheet = service.get_spreadsheet(@spreadsheet_id, fields: 'sheets(properties,data.rowData.values(formattedValue))')
21
+ self
22
+ end
23
+
24
+ # @param [Integer] index
25
+ # @param [Integer] sheet_id
26
+ # @param [String] title
27
+ # @param [Integer] skip
28
+ # @param [Boolean] structured
29
+ def all_rows_by!(index: nil, sheet_id: nil, title: nil, skip: 0, structured: false)
30
+ sheet = sheet_by!(index: index, sheet_id: sheet_id, title: title)
31
+ sheet_to_array(sheet, skip: skip, structured: structured)
32
+ end
33
+
34
+ def service
35
+ @service ||= GoogleSpreadsheetFetcher::SheetsServiceBuilder.new(@user_id, config: @config, application_name: @application_name).build
36
+ end
37
+
38
+ private
39
+
40
+ def sheet_by!(index: nil, sheet_id: nil, title: nil)
41
+ raise SpreadsheetNotFound if @spreadsheet.sheets.blank?
42
+
43
+ if index.present?
44
+ return @spreadsheet.sheets.find { |sheet| sheet.properties.index == index }
45
+ elsif sheet_id.present?
46
+ return @spreadsheet.sheets.find { |sheet| sheet.properties.sheet_id == sheet_id }
47
+ elsif title.present?
48
+ return @spreadsheet.sheets.find { |sheet| sheet.properties.title == title }
49
+ end
50
+
51
+ raise SheetNotFound
52
+ end
53
+
54
+ def sheet_to_array(sheet, skip: 0, structured: false)
55
+ sheet_data = sheet&.data&.first
56
+ return [] if sheet_data.nil?
57
+
58
+ rows = sheet_data.row_data.map do |row_data|
59
+ values = row_data.values
60
+ next [''] if values.nil?
61
+
62
+ values.map { |cell| cell&.formatted_value || "" }
63
+ end
64
+
65
+ headers = rows.first
66
+ count = headers.count
67
+
68
+ if structured
69
+ rows.delete_at(0)
70
+ rows.slice!(0, skip)
71
+ rows.map { |r| headers.zip(r).to_h }
72
+ else
73
+ rows.slice!(0, skip)
74
+ rows.map { |r| fill_array(r, count) }
75
+ end
76
+ end
77
+
78
+ def fill_array(items, count, fill: '')
79
+ items + (count - items.count).times.map { fill }
80
+ end
81
+ end
82
+ end
@@ -1,3 +1,5 @@
1
+ require 'active_support/configurable'
2
+
1
3
  module GoogleSpreadsheetFetcher
2
4
  class Config
3
5
  include ActiveSupport::Configurable
@@ -1,3 +1,4 @@
1
1
  module GoogleSpreadsheetFetcher
2
+ class SpreadsheetNotFound < StandardError; end
2
3
  class SheetNotFound < StandardError; end
3
4
  end
@@ -1,6 +1,4 @@
1
- require 'googleauth'
2
- require 'googleauth/stores/file_token_store'
3
- require "google/apis/sheets_v4"
1
+ require 'google/apis/sheets_v4'
4
2
  require 'shellwords'
5
3
 
6
4
  module GoogleSpreadsheetFetcher
@@ -14,71 +12,66 @@ module GoogleSpreadsheetFetcher
14
12
  def initialize(spreadsheet_id, user_id, config: nil, application_name: nil)
15
13
  @spreadsheet_id = spreadsheet_id
16
14
  @user_id = user_id
17
- @config = config || GoogleSpreadsheetFetcher.config
15
+ @config = config
18
16
  @application_name = application_name
19
17
  end
20
18
 
21
- # @param [String] range(https://developers.google.com/sheets/api/guides/concepts#a1_notation)
19
+ def fetch_all_rows_by!(index: nil, sheet_id: nil, title: nil, skip: 0, structured: false)
20
+ sheet = fetch_sheet_by!(index: index, sheet_id: sheet_id, title: title)
21
+ fetch_all_rows(sheet, skip: skip, structured: structured)
22
+ end
23
+
24
+ def service
25
+ @service ||= GoogleSpreadsheetFetcher::SheetsServiceBuilder.new(@user_id, config: @config, application_name: @application_name).build
26
+ end
27
+
28
+ private
29
+
30
+ # @param [Google::Apis::SheetsV4::Sheet] sheet
22
31
  # @param [Integer] skip
23
- def fetch_all_rows(range, skip: 0, structured: false)
24
- rows = service.batch_get_spreadsheet_values(@spreadsheet_id, ranges: [range])&.value_ranges&.first&.values
32
+ # @param [Boolean] structured
33
+ def fetch_all_rows(sheet, skip: 0, structured: false)
34
+ # https://developers.google.com/sheets/api/guides/concepts#a1_notation
35
+ range = "#{sheet.properties.title}!A:ZZ"
36
+ rows = service.get_spreadsheet_values(@spreadsheet_id, range)&.values
25
37
  return [] if rows.blank?
26
38
 
39
+ headers = rows.first
40
+ count = headers.count
41
+
27
42
  if structured
28
- headers = rows.delete_at(0)
43
+ rows.delete_at(0)
29
44
  rows.slice!(0, skip)
30
45
  rows.map { |r| headers.zip(r).to_h }
31
46
  else
32
47
  rows.slice!(0, skip)
33
- rows
34
- end
35
- end
36
-
37
- def fetch_all_rows_by!(index: nil, sheet_id: nil, title: nil, skip: 0, structured: false)
38
- sheet = fetch_sheet_by!(index: index, sheet_id: sheet_id, title: title)
39
-
40
- range = "#{sheet.properties.title}!A:Z"
41
- fetch_all_rows(range, skip: skip, structured: structured)
42
- end
43
-
44
- def service
45
- @service ||= Google::Apis::SheetsV4::SheetsService.new.tap do |service|
46
- service.authorization = fetch_credentials
47
- service.client_options.application_name = @application_name if @application_name.present?
48
+ rows.map { |r| fill_array(r, count) }
48
49
  end
49
50
  end
50
51
 
51
- private
52
-
53
52
  def fetch_sheet_by!(index: nil, sheet_id: nil, title: nil)
54
53
  sheets = spreadsheet.sheets
55
54
  raise SheetNotFound if sheets.blank?
56
55
 
57
- return sheets[index] if index.present?
58
- return sheets.find { |s| s.properties.sheet_id == sheet_id } if sheet_id.present?
59
- return sheets.find { |s| s.properties.title == title } if title.present?
56
+ sheet = if index.present?
57
+ sheets[index]
58
+ elsif sheet_id.present?
59
+ sheets.find { |s| s.properties.sheet_id == sheet_id }
60
+ elsif title.present?
61
+ sheets.find { |s| s.properties.title == title }
62
+ end
63
+
64
+ return sheet if sheet.present?
60
65
 
61
66
  raise SheetNotFound
62
67
  end
63
68
 
64
- def fetch_credentials
65
- client_id = Google::Auth::ClientId.from_file(@config.client_secrets_file)
66
- token_store = Google::Auth::Stores::FileTokenStore.new(file: @config.credential_store_file)
67
- authorizer = Google::Auth::UserAuthorizer.new(client_id, @config.scopes, token_store)
68
-
69
- credentials = authorizer.get_credentials(@user_id)
70
- return credentials if credentials.present?
71
-
72
- url = authorizer.get_authorization_url(base_url: OOB_URI)
73
- escaped_url = url.shellescape
74
- system("open #{escaped_url}")
75
- puts "Open #{url} in your browser and enter the resulting code: "
76
- code = STDIN.gets
77
- authorizer.get_and_store_credentials_from_code(user_id: @user_id, code: code, base_url: OOB_URI)
69
+ def spreadsheet
70
+ @spreadsheet ||= service.get_spreadsheet(@spreadsheet_id)
78
71
  end
79
72
 
80
- def spreadsheet
81
- service.get_spreadsheet(@spreadsheet_id)
73
+ def fill_array(items, count, fill: "")
74
+ items + (count - items.count).times.map { fill }
82
75
  end
83
76
  end
84
77
  end
@@ -0,0 +1,44 @@
1
+ require 'google/apis/sheets_v4'
2
+ require 'googleauth'
3
+ require 'googleauth/stores/file_token_store'
4
+ require 'shellwords'
5
+
6
+ module GoogleSpreadsheetFetcher
7
+ class SheetsServiceBuilder
8
+ OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
9
+
10
+ # @param [String] user_id
11
+ # @param [GoogleSpreadsheetFetcher::Config] config
12
+ # @param [String] application_name
13
+ def initialize(user_id, config: nil, application_name: nil)
14
+ @user_id = user_id
15
+ @config = config || GoogleSpreadsheetFetcher.config
16
+ @application_name = application_name
17
+ end
18
+
19
+ def build
20
+ Google::Apis::SheetsV4::SheetsService.new.tap do |service|
21
+ service.authorization = fetch_credentials
22
+ service.client_options.application_name = @application_name if @application_name.present?
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def fetch_credentials
29
+ client_id = Google::Auth::ClientId.from_file(@config.client_secrets_file)
30
+ token_store = Google::Auth::Stores::FileTokenStore.new(file: @config.credential_store_file)
31
+ authorizer = Google::Auth::UserAuthorizer.new(client_id, @config.scopes, token_store)
32
+
33
+ credentials = authorizer.get_credentials(@user_id)
34
+ return credentials if credentials.present?
35
+
36
+ url = authorizer.get_authorization_url(base_url: OOB_URI)
37
+ escaped_url = url.shellescape
38
+ system("open #{escaped_url}")
39
+ puts "Open #{url} in your browser and enter the resulting code: "
40
+ code = STDIN.gets
41
+ authorizer.get_and_store_credentials_from_code(user_id: @user_id, code: code, base_url: OOB_URI)
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module GoogleSpreadsheetFetcher
2
- VERSION = "1.2.0"
2
+ VERSION = "1.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_spreadsheet_fetcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takahiro Ooishi
8
+ - Yuya Yokosuka
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2019-10-03 00:00:00.000000000 Z
12
+ date: 2020-07-17 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: google-api-client
@@ -83,6 +84,7 @@ dependencies:
83
84
  description: Google Spreadsheet fetcher
84
85
  email:
85
86
  - taka0125@gmail.com
87
+ - yuya.yokosuka@gmail.com
86
88
  executables: []
87
89
  extensions: []
88
90
  extra_rdoc_files: []
@@ -97,9 +99,11 @@ files:
97
99
  - bin/setup
98
100
  - google_spreadsheet_fetcher.gemspec
99
101
  - lib/google_spreadsheet_fetcher.rb
102
+ - lib/google_spreadsheet_fetcher/bulk_fetcher.rb
100
103
  - lib/google_spreadsheet_fetcher/config.rb
101
104
  - lib/google_spreadsheet_fetcher/error.rb
102
105
  - lib/google_spreadsheet_fetcher/fetcher.rb
106
+ - lib/google_spreadsheet_fetcher/sheets_service_builder.rb
103
107
  - lib/google_spreadsheet_fetcher/version.rb
104
108
  homepage: https://github.com/taka0125/google_spreadsheet_fetcher
105
109
  licenses: []