google_spreadsheet_fetcher 1.2.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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: []