model_to_googlesheet 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c153b7c2f6b311f25757ffcc28274b96fa8a5ff1
4
+ data.tar.gz: 54c810e9e834270f737a7581bff1773e7bbcee2b
5
+ SHA512:
6
+ metadata.gz: 90bab47ac2e13357273686ee38cf27b49e96ef99cebb990bf146baef739dc71498adb8bf2308a5af8ef033286228b5302e926fe8e359c756b4bbe6e7d95b5327
7
+ data.tar.gz: 9263823d000b920b56250085a960e4105190fa36daf0b931d51315e621c780d3ad8ca05829256a8ae8435525fd96d23a2c7915f5a9bcaf78f22e2fde705862eb
data/Gemfile ADDED
@@ -0,0 +1 @@
1
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,195 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ model_to_googlesheet (1.0.0)
5
+ activerecord
6
+ google_drive (~> 1.0)
7
+ rails (~> 4.2)
8
+
9
+ GEM
10
+ specs:
11
+ actionmailer (4.2.5)
12
+ actionpack (= 4.2.5)
13
+ actionview (= 4.2.5)
14
+ activejob (= 4.2.5)
15
+ mail (~> 2.5, >= 2.5.4)
16
+ rails-dom-testing (~> 1.0, >= 1.0.5)
17
+ actionpack (4.2.5)
18
+ actionview (= 4.2.5)
19
+ activesupport (= 4.2.5)
20
+ rack (~> 1.6)
21
+ rack-test (~> 0.6.2)
22
+ rails-dom-testing (~> 1.0, >= 1.0.5)
23
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
24
+ actionview (4.2.5)
25
+ activesupport (= 4.2.5)
26
+ builder (~> 3.1)
27
+ erubis (~> 2.7.0)
28
+ rails-dom-testing (~> 1.0, >= 1.0.5)
29
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
30
+ activejob (4.2.5)
31
+ activesupport (= 4.2.5)
32
+ globalid (>= 0.3.0)
33
+ activemodel (4.2.5)
34
+ activesupport (= 4.2.5)
35
+ builder (~> 3.1)
36
+ activerecord (4.2.5)
37
+ activemodel (= 4.2.5)
38
+ activesupport (= 4.2.5)
39
+ arel (~> 6.0)
40
+ activesupport (4.2.5)
41
+ i18n (~> 0.7)
42
+ json (~> 1.7, >= 1.7.7)
43
+ minitest (~> 5.1)
44
+ thread_safe (~> 0.3, >= 0.3.4)
45
+ tzinfo (~> 1.1)
46
+ addressable (2.4.0)
47
+ arel (6.0.3)
48
+ autoparse (0.3.3)
49
+ addressable (>= 2.3.1)
50
+ extlib (>= 0.9.15)
51
+ multi_json (>= 1.0.0)
52
+ builder (3.2.2)
53
+ coderay (1.1.0)
54
+ concurrent-ruby (1.0.0)
55
+ diff-lcs (1.2.5)
56
+ erubis (2.7.0)
57
+ extlib (0.9.16)
58
+ faraday (0.9.2)
59
+ multipart-post (>= 1.2, < 3)
60
+ globalid (0.3.6)
61
+ activesupport (>= 4.1.0)
62
+ google-api-client (0.8.6)
63
+ activesupport (>= 3.2)
64
+ addressable (~> 2.3)
65
+ autoparse (~> 0.3)
66
+ extlib (~> 0.9)
67
+ faraday (~> 0.9)
68
+ googleauth (~> 0.3)
69
+ launchy (~> 2.4)
70
+ multi_json (~> 1.10)
71
+ retriable (~> 1.4)
72
+ signet (~> 0.6)
73
+ google_drive (1.0.4)
74
+ google-api-client (>= 0.7.0, < 0.9)
75
+ nokogiri (>= 1.4.4, != 1.5.2, != 1.5.1)
76
+ oauth (>= 0.3.6)
77
+ oauth2 (>= 0.5.0)
78
+ googleauth (0.4.2)
79
+ faraday (~> 0.9)
80
+ jwt (~> 1.4)
81
+ logging (~> 2.0)
82
+ memoist (~> 0.12)
83
+ multi_json (~> 1.11)
84
+ signet (~> 0.6)
85
+ i18n (0.7.0)
86
+ interception (0.5)
87
+ json (1.8.3)
88
+ jwt (1.5.2)
89
+ launchy (2.4.3)
90
+ addressable (~> 2.3)
91
+ little-plugger (1.1.4)
92
+ logging (2.0.0)
93
+ little-plugger (~> 1.1)
94
+ multi_json (~> 1.10)
95
+ loofah (2.0.3)
96
+ nokogiri (>= 1.5.9)
97
+ mail (2.6.3)
98
+ mime-types (>= 1.16, < 3)
99
+ memoist (0.13.0)
100
+ method_source (0.8.2)
101
+ mime-types (2.99)
102
+ mini_portile2 (2.0.0)
103
+ minitest (5.8.3)
104
+ multi_json (1.11.2)
105
+ multi_xml (0.5.5)
106
+ multipart-post (2.0.0)
107
+ nokogiri (1.6.7)
108
+ mini_portile2 (~> 2.0.0.rc2)
109
+ oauth (0.4.7)
110
+ oauth2 (1.0.0)
111
+ faraday (>= 0.8, < 0.10)
112
+ jwt (~> 1.0)
113
+ multi_json (~> 1.3)
114
+ multi_xml (~> 0.5)
115
+ rack (~> 1.2)
116
+ pry (0.10.3)
117
+ coderay (~> 1.1.0)
118
+ method_source (~> 0.8.1)
119
+ slop (~> 3.4)
120
+ pry-rescue (1.4.2)
121
+ interception (>= 0.5)
122
+ pry
123
+ rack (1.6.4)
124
+ rack-test (0.6.3)
125
+ rack (>= 1.0)
126
+ rails (4.2.5)
127
+ actionmailer (= 4.2.5)
128
+ actionpack (= 4.2.5)
129
+ actionview (= 4.2.5)
130
+ activejob (= 4.2.5)
131
+ activemodel (= 4.2.5)
132
+ activerecord (= 4.2.5)
133
+ activesupport (= 4.2.5)
134
+ bundler (>= 1.3.0, < 2.0)
135
+ railties (= 4.2.5)
136
+ sprockets-rails
137
+ rails-deprecated_sanitizer (1.0.3)
138
+ activesupport (>= 4.2.0.alpha)
139
+ rails-dom-testing (1.0.7)
140
+ activesupport (>= 4.2.0.beta, < 5.0)
141
+ nokogiri (~> 1.6.0)
142
+ rails-deprecated_sanitizer (>= 1.0.1)
143
+ rails-html-sanitizer (1.0.2)
144
+ loofah (~> 2.0)
145
+ railties (4.2.5)
146
+ actionpack (= 4.2.5)
147
+ activesupport (= 4.2.5)
148
+ rake (>= 0.8.7)
149
+ thor (>= 0.18.1, < 2.0)
150
+ rake (10.4.2)
151
+ retriable (1.4.1)
152
+ rspec (3.4.0)
153
+ rspec-core (~> 3.4.0)
154
+ rspec-expectations (~> 3.4.0)
155
+ rspec-mocks (~> 3.4.0)
156
+ rspec-core (3.4.1)
157
+ rspec-support (~> 3.4.0)
158
+ rspec-expectations (3.4.0)
159
+ diff-lcs (>= 1.2.0, < 2.0)
160
+ rspec-support (~> 3.4.0)
161
+ rspec-mocks (3.4.0)
162
+ diff-lcs (>= 1.2.0, < 2.0)
163
+ rspec-support (~> 3.4.0)
164
+ rspec-support (3.4.1)
165
+ signet (0.7.0)
166
+ addressable (~> 2.3)
167
+ faraday (~> 0.9)
168
+ jwt (~> 1.5)
169
+ multi_json (~> 1.10)
170
+ slop (3.6.0)
171
+ sprockets (3.5.2)
172
+ concurrent-ruby (~> 1.0)
173
+ rack (> 1, < 3)
174
+ sprockets-rails (2.3.3)
175
+ actionpack (>= 3.0)
176
+ activesupport (>= 3.0)
177
+ sprockets (>= 2.8, < 4.0)
178
+ sqlite3 (1.3.11)
179
+ thor (0.19.1)
180
+ thread_safe (0.3.5)
181
+ tzinfo (1.2.2)
182
+ thread_safe (~> 0.1)
183
+
184
+ PLATFORMS
185
+ ruby
186
+
187
+ DEPENDENCIES
188
+ model_to_googlesheet!
189
+ pry
190
+ pry-rescue
191
+ rspec (~> 3.4)
192
+ sqlite3
193
+
194
+ BUNDLED WITH
195
+ 1.10.6
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ ###ModelToGooglesheet
2
+
3
+ ###How to install?
4
+
5
+ gem 'model_to_googlesheet'
6
+
7
+ ###How to obtain client_id, **client_secret** and **refresh_token**?
8
+ https://auth0.com/docs/connections/social/google
9
+
10
+ After creation, go to https://console.developers.google.com/apis/library?project=db-to-gs and enable Drive api.
11
+
12
+ Choose 'other' as an application type.
13
+
14
+ Once you get **client_id** and **session_id**, you can get a **refresh_token** with:
15
+
16
+ `rake model_to_googlesheet:get_refresh_token client_id='274709489501-ekvsdc8cpuh9nrps73h55m29i1kbgtgk.apps.googleusercontent.com' client_secret='hbSi0Q7VWArzLQZ2maJoagdx'`
17
+
18
+ ###Configuration
19
+ Once you get your **client_id**, **client_secret** and **refresh_token**, you can set them either globally, permodel, or permethod.
20
+ Available options are include:
21
+
22
+ client_id
23
+ client_secret
24
+ refresh_token
25
+ spreadsheet - title of the spreadheet you'd like to export your data in.
26
+ worksheet - title of the worksheet you'd like to export your data in. if either worksheet or spreadsheet with such titles don't exit, they will be created.
27
+ convert_with - (optional) either symbol of method name in your model or Proc that will return hash (columns and values to include in a worksheet created).
28
+
29
+
30
+ ##You can put your configuration in */config/initializers*:
31
+
32
+ ModelToGooglesheet.configure do |config|
33
+ config.client_id = client_id
34
+ config.client_secret = client_secret
35
+ config.refresh_token = refresh_token
36
+ end
37
+
38
+ ##You can override that configuration, or add new one options in your model:
39
+
40
+ exportable_to_googlesheet refresh_token: refresh_token,
41
+ spreadsheet: 'My App', worksheet: 'Users'
42
+
43
+ ##And finally you can override it all, or add nothing at all permethod:
44
+
45
+ User.last.export_to_googlesheet spreadsheet: 'Another one',
46
+ convert_with: :exportize
47
+
48
+ provided you have a method
49
+
50
+ def exportize
51
+ {
52
+ name: name.upcase,
53
+ age: age
54
+ }
55
+ end
56
+
57
+ in your model. You can also avoid creating new method with proc or lambda:
58
+
59
+ convert_with: -> (record) { { name: record.name.upcase, age: record.age } }
60
+
61
+
62
+ If you export a collection of users, gem will recreate your worksheet and export it all to a clean one. If you export one user, gem will add it to the worksheet if it was already created and create a new one (with a spreadsheet if needed) if it couldn't find one, adding record to a newly created one.
63
+
64
+
65
+
66
+
67
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+
2
+ require 'bundler/setup'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+
6
+ # require_relative 'lib/model_to_googlesheet'
7
+ # import 'lib/model_to_googlesheet/tasks/get_refresh_token.rake'
8
+
9
+
10
+
11
+
12
+
@@ -0,0 +1,90 @@
1
+ # list Provides access to cells using column names, assuming the first row ALREADY contains column names.
2
+ # keys() --- Column names i.e. the contents of the first row. Duplicates are removed.
3
+ # keys=(ary) --- Updates column names i.e. the contents of the first row.
4
+
5
+
6
+ # ws.list
7
+ # ws.list.keys --- waits, but caches
8
+ # ws.list.push
9
+
10
+ module ModelToGooglesheet
11
+ module Export
12
+
13
+ def self.included(base)
14
+ base.extend ClassMethods
15
+ end
16
+
17
+
18
+ def export_to_googlesheet permethod_options={}
19
+ options = Configuration.merge_configs permethod_options, model_to_googlesheet_configuration
20
+ session = GoogleDrive::Session.new_for_gs({
21
+ client_id: options[:client_id],
22
+ client_secret: options[:client_secret],
23
+ refresh_token: options[:refresh_token]
24
+ })
25
+
26
+ ws = session.get_or_create_ss(options[:spreadsheet]).get_or_create_ws(options[:worksheet])
27
+
28
+ record_hash = self.get_exportable_hash options[:convert_with]
29
+ ws.export_hash record_hash
30
+
31
+ ws.save
32
+ end
33
+
34
+ def get_exportable_hash convert_with
35
+ case convert_with
36
+ when nil
37
+ attributes
38
+ when Symbol
39
+ self.send convert_with
40
+ when Proc
41
+ convert_with.call self
42
+ end
43
+ end
44
+
45
+
46
+
47
+
48
+ module ClassMethods
49
+ BATCH_SIZE = 500 #google drive has trouble with saving about 2000 of rows right away, so we're saving them in batches. we may raise batch size up to about 1000.
50
+
51
+ def export_to_googlesheet permethod_options={}
52
+ options = Configuration.merge_configs permethod_options, model_to_googlesheet_configuration
53
+
54
+ session = GoogleDrive::Session.new_for_gs({
55
+ client_id: options[:client_id],
56
+ client_secret: options[:client_secret],
57
+ refresh_token: options[:refresh_token]
58
+ })
59
+
60
+ ss = session.get_or_create_ss options[:spreadsheet]
61
+ ws = ss.create_or_recreate_ws options[:worksheet]
62
+
63
+ amount_of_batches_to_skip = self.count/BATCH_SIZE
64
+ (0..amount_of_batches_to_skip).each do |skip_n_batches|
65
+ records = limit(BATCH_SIZE).offset(skip_n_batches*BATCH_SIZE)
66
+
67
+ records.each do |record|
68
+ record_hash = record.get_exportable_hash options[:convert_with]
69
+ ws.export_hash record_hash
70
+ end
71
+
72
+ ws.save
73
+ end
74
+
75
+
76
+ end
77
+
78
+
79
+ end
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+ end
89
+ end
90
+
@@ -0,0 +1,18 @@
1
+ module GoogleDrive
2
+ module AuthenticationHelper
3
+
4
+ # private
5
+ def self.set_auth client_id, client_secret
6
+ auth = Google::APIClient.new({application_name: 'Db To Googlesheet'}).authorization
7
+ auth.client_id = client_id
8
+ auth.client_secret = client_secret
9
+
10
+ auth.scope =
11
+ "https://www.googleapis.com/auth/drive " +
12
+ "https://spreadsheets.google.com/feeds/"
13
+ auth.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
14
+
15
+ auth
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'authentication_helper'
2
+ module GoogleDrive
3
+ class Session
4
+
5
+ def self.new_for_gs client_id:, client_secret:, refresh_token:
6
+ auth = GoogleDrive::AuthenticationHelper.set_auth client_id, client_secret
7
+
8
+ auth.refresh_token = refresh_token
9
+ auth.fetch_access_token!
10
+ @session = login_with_oauth(auth.access_token)
11
+ end
12
+
13
+ def get_or_create_ss title
14
+ ss = exact_ss title
15
+ ss ||= create_spreadsheet(title)
16
+ end
17
+
18
+ #spreadsheets(title:) returns trashed files too.
19
+ #gs doesn't allow to create worksheets with the same title in one spreadsheet
20
+ #and it doesn't trash ws-s
21
+ def exact_ss title
22
+ exact_sss(title).first
23
+ end
24
+ def exact_sss title
25
+ spreadsheets(title: title, 'title-exact': true).select { |ss| !ss.labels.trashed }
26
+ end
27
+
28
+
29
+
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module GoogleDrive
2
+ class Spreadsheet
3
+
4
+ def get_or_create_ws title
5
+ ws = worksheet_by_title title
6
+ ws ||= add_worksheet(title)
7
+ end
8
+
9
+ # to delete everything in the worksheet, deleting row by row is too slow
10
+ def create_or_recreate_ws title
11
+ if ws = worksheet_by_title(title)
12
+ ws.delete
13
+ end
14
+ add_worksheet title
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module GoogleDrive
2
+ class Worksheet
3
+
4
+ def export_hash hash
5
+ begin
6
+ self.list.push hash #will raise error if unfamiliar key. faster than making a request everytime asking for present keys.
7
+ rescue GoogleDrive::Error => error #GoogleDrive::Error: Column doesn't exist: "hi"
8
+ if error.message.include? "Column doesn't exist:"
9
+ old_keys = self.list.keys # then update all keys, because it'll take same amount of time as updating specific keys
10
+ new_keys = (old_keys + hash.keys).uniq
11
+ self.list.keys = new_keys #we are updating the first row.
12
+ retry
13
+ end
14
+ raise
15
+ end
16
+
17
+ end
18
+
19
+
20
+
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+
2
+ module ModelToGooglesheet
3
+ class Railtie < Rails::Railtie
4
+
5
+ rake_tasks do
6
+ load 'model_to_googlesheet/tasks/get_refresh_token.rake'
7
+ end
8
+
9
+ initializer 'model_to_googlesheet.extend_activerecord' do
10
+ ActiveRecord::Base.extend ModelToGooglesheet::ClassMethods
11
+ end
12
+
13
+ config.before_configuration do
14
+ ModelToGooglesheet.configuration = ModelToGooglesheet::Configuration.new
15
+ end
16
+
17
+ end
18
+ end
19
+
20
+
21
+
22
+
23
+
24
+
@@ -0,0 +1,22 @@
1
+ require 'google/api_client'
2
+ require 'google_drive'
3
+ require 'model_to_googlesheet/google_drive/authentication_helper'
4
+
5
+ namespace :model_to_googlesheet do
6
+
7
+ # add credentials --- CHOOSE other client
8
+ # use this task manually unless you already know your refresh token
9
+ desc "What's my refresh token?\nrake model_to_googlesheet:get_refresh_token client_id='274709489501-ekvsdc8cpuh9nrps73h55m29i1kbgtgk.apps.googleusercontent.com' client_secret='hbSi0Q7VWArzLQZ2maJoagdx'"
10
+ task :get_refresh_token do
11
+ auth = GoogleDrive::AuthenticationHelper.set_auth ENV['client_id'], ENV['client_secret']
12
+ puts "1. Open this page:\n #{auth.authorization_uri}\n\n"
13
+ print "2. Enter the authorization code shown in the page: "
14
+
15
+ auth.code = $stdin.gets.chomp
16
+ auth.fetch_access_token!
17
+ puts "\nYour refresh token is: #{auth.refresh_token}"
18
+ end
19
+
20
+ end
21
+
22
+
@@ -0,0 +1,3 @@
1
+ module ModelToGooglesheet
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,72 @@
1
+ require 'active_record'
2
+ require 'rails/railtie'
3
+ require 'google/api_client'
4
+ require 'google_drive'
5
+
6
+
7
+ require 'model_to_googlesheet/google_drive/session'
8
+ require 'model_to_googlesheet/google_drive/spreadsheet'
9
+ require 'model_to_googlesheet/google_drive/worksheet'
10
+
11
+ require 'model_to_googlesheet/export'
12
+ require 'model_to_googlesheet/railtie'
13
+
14
+ module ModelToGooglesheet
15
+
16
+ module ClassMethods
17
+ def exportable_to_googlesheet options={}
18
+ mattr_accessor :model_to_googlesheet_configuration
19
+ self.model_to_googlesheet_configuration = ModelToGooglesheet.configuration #here we are initializing permodel configuration with perapp configuration
20
+
21
+ options.each do |k, v|
22
+ self.model_to_googlesheet_configuration.send("#{k}=", v)
23
+ end #unfamiliar option will raise an error
24
+
25
+ include ModelToGooglesheet::Export
26
+ end
27
+ end
28
+
29
+ class << self
30
+ attr_accessor :configuration
31
+ end
32
+ # for config/initializers
33
+ def self.configure
34
+ yield configuration
35
+ end
36
+
37
+
38
+ class Configuration
39
+ OPTIONS = [
40
+ :client_id, :client_secret, :refresh_token,
41
+ :worksheet, :spreadsheet,
42
+ :convert_with
43
+ ]
44
+
45
+ attr_accessor *OPTIONS
46
+
47
+ # defaults
48
+ def initialize
49
+ @client_id = nil
50
+ @client_secret = nil
51
+ @refresh_token = nil
52
+ @worksheet = nil
53
+ @spreadsheet = nil
54
+ @convert_with = nil #optional
55
+ end
56
+
57
+ def self.merge_configs permethod_options, permodel_configuration
58
+ options = ActiveSupport::HashWithIndifferentAccess.new permethod_options
59
+ ModelToGooglesheet::Configuration::OPTIONS.each do |option_name|
60
+ options[option_name] ||= permodel_configuration.send(option_name)
61
+ end
62
+ options
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
69
+
70
+
71
+
72
+
@@ -0,0 +1,39 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+
3
+ # Maintain your gem's version:
4
+ require 'model_to_googlesheet/version'
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |s|
8
+ s.name = 'model_to_googlesheet'
9
+ s.version = ModelToGooglesheet::VERSION
10
+ s.authors = ['Helga Karunus']
11
+ s.email = ['lakesare@gmail.com']
12
+ s.homepage = 'https://github.com/lakesare/model_to_googlesheet'
13
+ s.summary = 'Export your Rails model to Googlesheets'
14
+ s.description = "A Railtie that allows you to configute model export to your google worksheet with just a few configurations, and will manage export of either a record or a set of records (with customized fields if you feel like it), export in batches (google spreadsheet gets buggy with large sets of data otherwise), creation of spreadsheet or worksheet if either was nonexistent"
15
+ s.license = 'MIT'
16
+
17
+ s.files = `git ls-files`.split("\n") - ['.gitignore']
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_dependency 'activerecord'
21
+ s.add_dependency 'rails', '~>4.2'
22
+ s.add_dependency 'google_drive', '~>1.0'
23
+
24
+ s.add_development_dependency 'sqlite3'
25
+ s.add_development_dependency 'rspec', '~>3.4'
26
+ s.add_development_dependency 'pry'
27
+ s.add_development_dependency 'pry-rescue'
28
+
29
+
30
+ s.required_ruby_version = '>= 1.8.6'
31
+ end
32
+
33
+
34
+
35
+
36
+
37
+ # 'title-exact': true везде понаставлять
38
+
39
+
@@ -0,0 +1,99 @@
1
+ # WARNING: these tests are not isolated, you need to run them all together. because making them isolated would make them run forever.
2
+
3
+ require 'spec_helper'
4
+ require 'helpers/active_record_helper'
5
+
6
+ RSpec.configure do |c|
7
+ c.include ActiveRecordHelper
8
+ end
9
+
10
+ describe ModelToGooglesheet::Export do
11
+
12
+ before(:context){
13
+ ModelToGooglesheet::Railtie.run_initializers
14
+ ModelToGooglesheet.configuration = ModelToGooglesheet::Configuration.new
15
+ }
16
+
17
+ include_context :create_session
18
+ include_context :set_spreadsheets
19
+
20
+ before(:context) do
21
+ connect_to_db
22
+ end
23
+
24
+ #we sacrifice some modularity for speed
25
+ it 'gets every level configs and creates keys in empty worksheet' do
26
+ setup_table(:users)
27
+
28
+ ModelToGooglesheet.configure do |config|
29
+ config.client_id = client_id
30
+ config.client_secret = client_secret
31
+ config.refresh_token = refresh_token + 'wrong one'
32
+ end
33
+
34
+ #because User doesn't know about our local vars (like refesh_token)
35
+ User = Class.new ActiveRecord::Base
36
+ User.exportable_to_googlesheet refresh_token: refresh_token,
37
+ spreadsheet: was_0_title, worksheet: 'wrong one'
38
+
39
+ User.create name: 'Cesilia', age: 38
40
+ User.create name: 'Tom', age: 17
41
+
42
+ #appends first record to the list
43
+ User.first.export_to_googlesheet worksheet: 'wow'
44
+
45
+ ws = session.exact_ss(was_0_title).worksheet_by_title('wow')
46
+
47
+ expect(ws.list.keys).to eq(['id', 'name', 'age'])
48
+ end
49
+
50
+ it ':convert_with Symbol option' do
51
+ User.class_eval do
52
+ def exportize
53
+ {
54
+ name: name.upcase,
55
+ comment: 'riddle'
56
+ }
57
+ end
58
+ end
59
+
60
+ User.last.export_to_googlesheet spreadsheet: was_1_title, worksheet: 'wow',
61
+ convert_with: :exportize
62
+
63
+ ws = session.exact_ss(was_1_title).worksheet_by_title('wow')
64
+
65
+ expect(ws.list.keys).to eq(['name', 'comment'])
66
+ expect(ws.list[0].to_a).to eq([["name", "TOM"], ["comment", "riddle"]])
67
+ end
68
+
69
+ it ':convert_with Proc option' do
70
+ User.last.export_to_googlesheet spreadsheet: was_0_title, worksheet: 'wow',
71
+ convert_with: -> (record) { { age: record.age } }
72
+
73
+ ws = session.exact_ss(was_0_title).worksheet_by_title('wow')
74
+ expect(ws.list[0].to_a).to eq([["age", "17"]])
75
+ end
76
+
77
+ it 'User.export' do
78
+ User.export_to_googlesheet spreadsheet: was_1_title, worksheet: 'wow'
79
+ #make it return ws so that tests are faster?
80
+
81
+ ws = session.exact_ss(was_1_title).worksheet_by_title('wow')
82
+ expect(ws.list[0].to_a).to eq([["id", "1"], ["name", "Cesilia"], ["age", "38"]])
83
+ end
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+ end
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
@@ -0,0 +1,23 @@
1
+ module ActiveRecordHelper
2
+ def setup_table name
3
+ connection = ActiveRecord::Base.connection
4
+ if connection.table_exists? name
5
+ connection.drop_table name
6
+ end
7
+ connection.create_table name do |t|
8
+ if block_given?
9
+ yield t
10
+ else
11
+ t.string :name
12
+ t.integer :age
13
+ end
14
+ end
15
+ end
16
+
17
+ def connect_to_db
18
+ ActiveRecord::Base.establish_connection(
19
+ :adapter => 'sqlite3',
20
+ :database => 'spec/test.sqlite3.db'
21
+ )
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoogleDrive::Session do
4
+
5
+ include_context :create_session
6
+ include_context :set_spreadsheets
7
+
8
+ it 'fetches existent spreadsheet' do
9
+ session.get_or_create_ss was_1_title
10
+ i = session.exact_sss(was_1_title).size
11
+
12
+ expect(i).to eq(1)
13
+ end
14
+
15
+ it "creates spreadsheet if can't fetch it" do
16
+ session.get_or_create_ss was_0_title
17
+ i = session.exact_sss(was_0_title).size
18
+
19
+ expect(i).to eq(1)
20
+ end
21
+
22
+ it "creates worksheet and spreadsheet if can't fetch both" do
23
+ spreadsheet = session.get_or_create_ss was_0_title
24
+ worksheet = spreadsheet.get_or_create_ws 'worksheety'
25
+
26
+ expect(spreadsheet.title).to eq(was_0_title)
27
+ expect(worksheet.title).to eq('worksheety')
28
+ end
29
+
30
+ it "creates worksheet if only spreadsheet exists" do
31
+ spreadsheet = session.get_or_create_ss was_1_title
32
+ worksheet = spreadsheet.get_or_create_ws 'worksheety'
33
+
34
+ expect(worksheet.title).to eq('worksheety')
35
+ end
36
+
37
+ it 'recreates worksheet' do
38
+ spreadsheet = session.get_or_create_ss was_1_title
39
+ worksheet = spreadsheet.get_or_create_ws 'worksheety'
40
+
41
+ worksheet[1, 1] = 'filled in'
42
+ worksheet.save
43
+
44
+ new_worksheet = spreadsheet.create_or_recreate_ws 'filled in'
45
+ expect(new_worksheet[1, 1]).to eq('')
46
+ end
47
+
48
+ end
49
+
@@ -0,0 +1,61 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'model_to_googlesheet'
3
+ require 'pry'
4
+ require 'pry-rescue'
5
+
6
+ Dir['./spec/support/*.rb'].each { |file| require file }
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+ # exportable_to_googlesheet
16
+
17
+
18
+
19
+ # User.export_to_googlesheet 'OurUsersInfo' #appends all the users to sheet
20
+
21
+ # User.find(3).export_to_googlesheet 'OurUsersInfo' #appends one user to sheet
22
+
23
+
24
+
25
+ # User.find(3).export_to_googlesheet 'OurUsersInfo' #appends one user to sheet
26
+
27
+
28
+
29
+
30
+ # # and the in configs allow to set any amount of defaults. no defaults except for fields: defaults to all fields with their column names
31
+
32
+ # exportable_to_googlesheet name: 'OurUsersInfo', fields: :fields_like_a, client_id:, client_secret:, refresh_token:
33
+
34
+ # User.export_to_googlesheet #but can override!
35
+
36
+ # def export_to_googlesheet
37
+ # ...if not hash, to hash acc to :fields||default...
38
+ # (if hash and :fields on method itself and not by default, WARNING)
39
+ # end
40
+
41
+
42
+
43
+
44
+
45
+ # before(:context) do
46
+ # ActiveRecord::Base.establish_connection(
47
+ # :adapter => 'sqlite3',
48
+ # :database => 'spec/test.sqlite3.db'
49
+ # )
50
+
51
+ # ActiveRecord::Base.connection.create_table :users do |t|
52
+ # t.string :name
53
+ # t.integer :age
54
+ # end
55
+
56
+ # class User < ActiveRecord::Base
57
+ # exportable_to_googlesheet
58
+ # end
59
+
60
+ # end
61
+
@@ -0,0 +1,22 @@
1
+
2
+ shared_context :create_session do
3
+ let(:client_id) { '274709489501-ekvsdc8cpuh9nrps73h55m29i1kbgtgk.apps.googleusercontent.com' }
4
+ let(:client_secret) { 'hbSi0Q7VWArzLQZ2maJoagdx' }
5
+ let(:refresh_token) { '1/iNO0L49Mnn1EOmhnc5Rn_AEF-6SYlGbAt9cmITdhD4hIgOrJDtdun6zK6XiATCKT' }
6
+ let(:session) {
7
+ GoogleDrive::Session.new_for_gs({
8
+ client_id: client_id,
9
+ client_secret: client_secret,
10
+ refresh_token: refresh_token
11
+ })
12
+ }
13
+ end
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
@@ -0,0 +1,12 @@
1
+
2
+ shared_context :set_spreadsheets do
3
+ let(:was_1_title) { 'existent_spreadsheet_for_tests' }
4
+ let(:was_0_title) { 'nonexistent_spreadsheet_for_tests' }
5
+
6
+ before(:example) do
7
+ session.exact_sss(was_1_title).each(&:delete)
8
+ session.create_spreadsheet was_1_title
9
+
10
+ session.exact_sss(was_0_title).each(&:delete)
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: model_to_googlesheet
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Helga Karunus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: google_drive
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-rescue
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A Railtie that allows you to configute model export to your google worksheet
112
+ with just a few configurations, and will manage export of either a record or a set
113
+ of records (with customized fields if you feel like it), export in batches (google
114
+ spreadsheet gets buggy with large sets of data otherwise), creation of spreadsheet
115
+ or worksheet if either was nonexistent
116
+ email:
117
+ - lakesare@gmail.com
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - README.md
125
+ - Rakefile
126
+ - lib/model_to_googlesheet.rb
127
+ - lib/model_to_googlesheet/export.rb
128
+ - lib/model_to_googlesheet/google_drive/authentication_helper.rb
129
+ - lib/model_to_googlesheet/google_drive/session.rb
130
+ - lib/model_to_googlesheet/google_drive/spreadsheet.rb
131
+ - lib/model_to_googlesheet/google_drive/worksheet.rb
132
+ - lib/model_to_googlesheet/railtie.rb
133
+ - lib/model_to_googlesheet/tasks/get_refresh_token.rake
134
+ - lib/model_to_googlesheet/version.rb
135
+ - model_to_googlesheet.gemspec
136
+ - spec/export_spec.rb
137
+ - spec/helpers/active_record_helper.rb
138
+ - spec/session_spec.rb
139
+ - spec/spec_helper.rb
140
+ - spec/support/create_session.rb
141
+ - spec/support/set_spreadsheets.rb
142
+ homepage: https://github.com/lakesare/model_to_googlesheet
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: 1.8.6
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 2.4.6
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: Export your Rails model to Googlesheets
166
+ test_files: []