model_to_googlesheet 1.0.0 → 2.0.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
  SHA1:
3
- metadata.gz: c153b7c2f6b311f25757ffcc28274b96fa8a5ff1
4
- data.tar.gz: 54c810e9e834270f737a7581bff1773e7bbcee2b
3
+ metadata.gz: ee372e20acc02c7b47bc25a06bcc5838976c4ff6
4
+ data.tar.gz: e1b392f32d8b8a570a2538f8dcfcfa5b20ff5137
5
5
  SHA512:
6
- metadata.gz: 90bab47ac2e13357273686ee38cf27b49e96ef99cebb990bf146baef739dc71498adb8bf2308a5af8ef033286228b5302e926fe8e359c756b4bbe6e7d95b5327
7
- data.tar.gz: 9263823d000b920b56250085a960e4105190fa36daf0b931d51315e621c780d3ad8ca05829256a8ae8435525fd96d23a2c7915f5a9bcaf78f22e2fde705862eb
6
+ metadata.gz: af76b355337279b44539817326c2eb033d274bbe59f0849770a438a2fd83a7dd022197d4b2e2d0b4035b9d3e107c47e7eda5b9d21bddd3e56b835ee9103a1e3b
7
+ data.tar.gz: 6d69ca4d58d15ba4011147d6a8117d653ee4e6030857e230ad2b83c107857f4575cbe4fb30d9036f04291e19afc68d4d2ec39b70df18ac7416dc0acb32c9f7f1
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- model_to_googlesheet (1.0.0)
5
- activerecord
4
+ model_to_googlesheet (2.0.0)
6
5
  google_drive (~> 1.0)
7
6
  rails (~> 4.2)
8
7
 
@@ -104,7 +103,7 @@ GEM
104
103
  multi_json (1.11.2)
105
104
  multi_xml (0.5.5)
106
105
  multipart-post (2.0.0)
107
- nokogiri (1.6.7)
106
+ nokogiri (1.6.7.1)
108
107
  mini_portile2 (~> 2.0.0.rc2)
109
108
  oauth (0.4.7)
110
109
  oauth2 (1.0.0)
@@ -192,4 +191,4 @@ DEPENDENCIES
192
191
  sqlite3
193
192
 
194
193
  BUNDLED WITH
195
- 1.10.6
194
+ 1.11.2
data/README.md CHANGED
@@ -19,12 +19,14 @@ Once you get **client_id** and **session_id**, you can get a **refresh_token** w
19
19
  Once you get your **client_id**, **client_secret** and **refresh_token**, you can set them either globally, permodel, or permethod.
20
20
  Available options are include:
21
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).
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
+ `update` - (optional, only works for separate records) true or false, whether to update rows found by :find_by option. that is, if you have googlesheet rows with unique :name values, you may want to update to set `update: true, find_by: :name`, so that on `user.export_to_googlesheet` gem will try to find a row with a name equal to user's name, and, if successful, update it (or append a new one if row wasn't found). default behavious is to append any record.
29
+ `find_by` - (optional, only works for separate records, necessary if `update: true`)
28
30
 
29
31
 
30
32
  ##You can put your configuration in */config/initializers*:
@@ -62,6 +64,10 @@ in your model. You can also avoid creating new method with proc or lambda:
62
64
  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
65
 
64
66
 
67
+ ##How to delete a record?
68
+ You can clear a record with `record.delete_from_googlesheet` method. It requires `:find_by` option to be able to find a record to delete. If spreadsheet or worksheet or record were not found, just returns.
65
69
 
70
+ ---------
71
+ Now works with Mongoid too.
66
72
 
67
73
 
@@ -17,29 +17,56 @@ module ModelToGooglesheet
17
17
 
18
18
  def export_to_googlesheet permethod_options={}
19
19
  options = Configuration.merge_configs permethod_options, model_to_googlesheet_configuration
20
+
20
21
  session = GoogleDrive::Session.new_for_gs({
21
22
  client_id: options[:client_id],
22
23
  client_secret: options[:client_secret],
23
24
  refresh_token: options[:refresh_token]
24
25
  })
25
-
26
- ws = session.get_or_create_ss(options[:spreadsheet]).get_or_create_ws(options[:worksheet])
26
+ ss = session.get_or_create_ss options[:spreadsheet]
27
+ ws = ss.get_or_create_ws options[:worksheet]
27
28
 
28
29
  record_hash = self.get_exportable_hash options[:convert_with]
29
- ws.export_hash record_hash
30
30
 
31
+ ws.export_hash record_hash,
32
+ update: options[:update], find_by: options[:find_by]
33
+
34
+ ws.save
35
+ end
36
+
37
+ def delete_from_googlesheet permethod_options={}
38
+ options = Configuration.merge_configs permethod_options, model_to_googlesheet_configuration
39
+
40
+ session = GoogleDrive::Session.new_for_gs({
41
+ client_id: options[:client_id],
42
+ client_secret: options[:client_secret],
43
+ refresh_token: options[:refresh_token]
44
+ })
45
+ ss = session.exact_ss options[:spreadsheet]
46
+ return unless ss
47
+ ws = ss.worksheet_by_title options[:worksheet]
48
+ return unless ws
49
+
50
+ record_hash = get_exportable_hash options[:convert_with]
51
+
52
+ row = ws.row_with_hash record_hash, find_by: options[:find_by]
53
+ return unless row
54
+
55
+ row.clear
31
56
  ws.save
32
57
  end
33
58
 
34
59
  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
60
+ ActiveSupport::HashWithIndifferentAccess.new(
61
+ case convert_with
62
+ when nil
63
+ attributes
64
+ when Symbol
65
+ self.send convert_with
66
+ when Proc
67
+ convert_with.call self
68
+ end
69
+ )
43
70
  end
44
71
 
45
72
 
@@ -50,13 +77,12 @@ module ModelToGooglesheet
50
77
 
51
78
  def export_to_googlesheet permethod_options={}
52
79
  options = Configuration.merge_configs permethod_options, model_to_googlesheet_configuration
53
-
80
+
54
81
  session = GoogleDrive::Session.new_for_gs({
55
82
  client_id: options[:client_id],
56
83
  client_secret: options[:client_secret],
57
84
  refresh_token: options[:refresh_token]
58
85
  })
59
-
60
86
  ss = session.get_or_create_ss options[:spreadsheet]
61
87
  ws = ss.create_or_recreate_ws options[:worksheet]
62
88
 
@@ -64,18 +90,22 @@ module ModelToGooglesheet
64
90
  (0..amount_of_batches_to_skip).each do |skip_n_batches|
65
91
  records = limit(BATCH_SIZE).offset(skip_n_batches*BATCH_SIZE)
66
92
 
67
- records.each do |record|
68
- record_hash = record.get_exportable_hash options[:convert_with]
69
- ws.export_hash record_hash
70
- end
93
+ -> {
94
+ records.each do |record|
95
+ record_hash = record.get_exportable_hash options[:convert_with]
96
+ ws.export_hash record_hash, update: false, find_by: false
97
+ end
98
+ ws.save
99
+ }.rescue(2)
100
+
71
101
 
72
- ws.save
73
102
  end
74
103
 
75
104
 
76
105
  end
77
106
 
78
107
 
108
+
79
109
  end
80
110
 
81
111
 
@@ -1,21 +1,38 @@
1
1
  module GoogleDrive
2
2
  class Worksheet
3
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
4
+ def export_hash hash, update:, find_by:
5
+ update_keys(hash)
6
+
7
+ if update #find by :id/:whatever and update if found, else append
8
+
9
+ row = row_with_hash hash, find_by: find_by
10
+ row ? row.update(hash) : list.push(hash)
11
+
12
+ else #append
13
+ list.push(hash)
15
14
  end
16
-
15
+
17
16
  end
18
17
 
18
+ #either returns first row with given condition true, or nil
19
+ def row_with_hash hash, find_by:
20
+ row = list.find do |row| #GoogleDrive::ListRow
21
+ row[find_by] == hash[find_by].to_s
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+
28
+ #merge existing keys with the new ones.
29
+ #(doesn't take additional request, since this request will preload other rows)
30
+ def update_keys hash
31
+ old_keys = self.list.keys
32
+ new_keys = (old_keys + hash.keys.map(&:to_s)).uniq
33
+ self.list.keys = new_keys #we are updating the first row.
34
+ end
35
+
19
36
 
20
37
 
21
38
  end
@@ -0,0 +1,15 @@
1
+ # -> { raise 'hi' }.rescue(3) { |m| puts m.backtrace[0] }
2
+ # -> { raise 'hi' }.rescue(3) { |m, n| puts "number_of_attempts left: #{n}" }
3
+ # p -> { 6 }.rescue(10)
4
+ Proc.class_eval do
5
+ def rescue number_of_attempts=0
6
+ @n = number_of_attempts
7
+ begin
8
+ self.call
9
+ rescue => message
10
+ yield message, @n if block_given?
11
+ @n -= 1
12
+ @n > 0 ? retry : raise
13
+ end
14
+ end
15
+ end
@@ -6,8 +6,11 @@ module ModelToGooglesheet
6
6
  load 'model_to_googlesheet/tasks/get_refresh_token.rake'
7
7
  end
8
8
 
9
- initializer 'model_to_googlesheet.extend_activerecord' do
10
- ActiveRecord::Base.extend ModelToGooglesheet::ClassMethods
9
+ initializer 'model_to_googlesheet.extend_db_mapper' do
10
+ # we may use ActiveRecord::Base.extend ModelToGooglesheet::ClassMethods, but
11
+ # let's extend Object
12
+ # for Mongoid eg, and maybe some other db mappers
13
+ Object.extend ModelToGooglesheet::ClassMethods
11
14
  end
12
15
 
13
16
  config.before_configuration do
@@ -1,3 +1,3 @@
1
1
  module ModelToGooglesheet
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -1,4 +1,3 @@
1
- require 'active_record'
2
1
  require 'rails/railtie'
3
2
  require 'google/api_client'
4
3
  require 'google_drive'
@@ -8,8 +7,6 @@ require 'model_to_googlesheet/google_drive/session'
8
7
  require 'model_to_googlesheet/google_drive/spreadsheet'
9
8
  require 'model_to_googlesheet/google_drive/worksheet'
10
9
 
11
- require 'model_to_googlesheet/export'
12
- require 'model_to_googlesheet/railtie'
13
10
 
14
11
  module ModelToGooglesheet
15
12
 
@@ -38,20 +35,26 @@ module ModelToGooglesheet
38
35
  class Configuration
39
36
  OPTIONS = [
40
37
  :client_id, :client_secret, :refresh_token,
41
- :worksheet, :spreadsheet,
42
- :convert_with
38
+ :spreadsheet, :worksheet,
39
+ :convert_with,
40
+ :update, :find_by
43
41
  ]
44
42
 
43
+
45
44
  attr_accessor *OPTIONS
46
45
 
47
46
  # defaults
48
47
  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
48
+ @client_id = nil
49
+ @client_secret = nil
50
+ @refresh_token = nil
51
+ @spreadsheet = nil
52
+ @worksheet = nil
53
+ @convert_with = nil #optional
54
+ @update = false #optional, will only be applied to separate records.
55
+ #if set to true, finds a record in a sheet by :id and updates it.
56
+ #if set to :symbol, finds a record in a sheet by :symbol and updates it
57
+ @find_by = :id
55
58
  end
56
59
 
57
60
  def self.merge_configs permethod_options, permodel_configuration
@@ -67,6 +70,8 @@ module ModelToGooglesheet
67
70
  end
68
71
 
69
72
 
70
-
73
+ require 'model_to_googlesheet/helpers'
74
+ require 'model_to_googlesheet/export'
75
+ require 'model_to_googlesheet/railtie'
71
76
 
72
77
 
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
17
17
  s.files = `git ls-files`.split("\n") - ['.gitignore']
18
18
  s.require_paths = ['lib']
19
19
 
20
- s.add_dependency 'activerecord'
21
20
  s.add_dependency 'rails', '~>4.2'
22
21
  s.add_dependency 'google_drive', '~>1.0'
23
22
 
@@ -1,8 +1,8 @@
1
1
 
2
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' }
3
+ let(:client_id) { 'inset yours' }
4
+ let(:client_secret) { 'inset yours' }
5
+ let(:refresh_token) { 'inset yours' }
6
6
  let(:session) {
7
7
  GoogleDrive::Session.new_for_gs({
8
8
  client_id: client_id,
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: model_to_googlesheet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Helga Karunus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-14 00:00:00.000000000 Z
11
+ date: 2015-12-25 00:00:00.000000000 Z
12
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
13
  - !ruby/object:Gem::Dependency
28
14
  name: rails
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -129,6 +115,7 @@ files:
129
115
  - lib/model_to_googlesheet/google_drive/session.rb
130
116
  - lib/model_to_googlesheet/google_drive/spreadsheet.rb
131
117
  - lib/model_to_googlesheet/google_drive/worksheet.rb
118
+ - lib/model_to_googlesheet/helpers.rb
132
119
  - lib/model_to_googlesheet/railtie.rb
133
120
  - lib/model_to_googlesheet/tasks/get_refresh_token.rake
134
121
  - lib/model_to_googlesheet/version.rb