langrove-plugin-google 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.
data/.rvmrc ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.2" > .rvmrc
9
+ environment_id="ruby-1.9.2-p318@langrove-test"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.12.3 (master)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ if [[ $- == *i* ]] # check for interactive shells
29
+ then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
30
+ else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells
31
+ fi
32
+ else
33
+ # If the environment file has not yet been created, use the RVM CLI to select.
34
+ rvm --create use "$environment_id" || {
35
+ echo "Failed to create RVM environment '${environment_id}'."
36
+ return 1
37
+ }
38
+ fi
39
+
40
+
41
+ # If you use bundler, this might be useful to you:
42
+ # if [[ -s Gemfile ]] && {
43
+ # ! builtin command -v bundle >/dev/null ||
44
+ # builtin command -v bundle | grep $rvm_path/bin/bundle >/dev/null
45
+ # }
46
+ # then
47
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
48
+ # gem install bundler
49
+ # fi
50
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
51
+ # then
52
+ # bundle install | grep -vE '^Using|Your bundle is complete'
53
+ # fi
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source :gemcutter
2
+ source "http://rubygems.org"
3
+
4
+ group :development do
5
+
6
+ gem 'rspec'
7
+ gem 'guard-rspec'
8
+ gem 'guard'
9
+ gem 'em-rspec'
10
+
11
+ end
12
+
13
+ gem 'google_drive'
14
+
15
+ gem 'langrove', :git => "git@github.com:cluetechnologies/langrove-enterprise.git", :branch => "master"
@@ -0,0 +1,91 @@
1
+ GIT
2
+ remote: git@github.com:cluetechnologies/langrove-enterprise.git
3
+ revision: 0ef1dd1e662b80a378d09e1355f5d20c9cf28a4d
4
+ branch: master
5
+ specs:
6
+ langrove (0.0.5.2)
7
+ awesome_print
8
+ daemon-kit
9
+ em-http-request
10
+ em-websocket
11
+ eventmachine
12
+ eventmachine_httpserver
13
+
14
+ GEM
15
+ remote: http://rubygems.org/
16
+ remote: http://rubygems.org/
17
+ specs:
18
+ addressable (2.3.2)
19
+ awesome_print (1.0.2)
20
+ daemon-kit (0.1.8.2)
21
+ eventmachine (>= 0.12.10)
22
+ safely (>= 0.3.1)
23
+ diff-lcs (1.1.3)
24
+ em-http-request (0.3.0)
25
+ addressable (>= 2.0.0)
26
+ escape_utils
27
+ eventmachine (>= 0.12.9)
28
+ em-rspec (0.1.1)
29
+ eventmachine (>= 0.12.10)
30
+ em-websocket (0.3.8)
31
+ addressable (>= 2.1.1)
32
+ eventmachine (>= 0.12.9)
33
+ escape_utils (0.2.4)
34
+ eventmachine (0.12.10)
35
+ eventmachine_httpserver (0.2.1)
36
+ faraday (0.8.1)
37
+ multipart-post (~> 1.1)
38
+ ffi (1.1.1)
39
+ google_drive (0.3.1)
40
+ nokogiri (>= 1.4.4, != 1.5.2, != 1.5.1)
41
+ oauth (>= 0.3.6)
42
+ oauth2 (>= 0.5.0)
43
+ guard (1.2.3)
44
+ listen (>= 0.4.2)
45
+ thor (>= 0.14.6)
46
+ guard-rspec (1.2.0)
47
+ guard (>= 1.1)
48
+ httpauth (0.1)
49
+ jwt (0.1.5)
50
+ multi_json (>= 1.0)
51
+ listen (0.4.7)
52
+ rb-fchange (~> 0.0.5)
53
+ rb-fsevent (~> 0.9.1)
54
+ rb-inotify (~> 0.8.8)
55
+ multi_json (1.3.6)
56
+ multipart-post (1.1.5)
57
+ nokogiri (1.5.5)
58
+ oauth (0.4.6)
59
+ oauth2 (0.8.0)
60
+ faraday (~> 0.8)
61
+ httpauth (~> 0.1)
62
+ jwt (~> 0.1.4)
63
+ multi_json (~> 1.0)
64
+ rack (~> 1.2)
65
+ rack (1.4.1)
66
+ rb-fchange (0.0.5)
67
+ ffi
68
+ rb-fsevent (0.9.1)
69
+ rb-inotify (0.8.8)
70
+ ffi (>= 0.5.0)
71
+ rspec (2.11.0)
72
+ rspec-core (~> 2.11.0)
73
+ rspec-expectations (~> 2.11.0)
74
+ rspec-mocks (~> 2.11.0)
75
+ rspec-core (2.11.1)
76
+ rspec-expectations (2.11.2)
77
+ diff-lcs (~> 1.1.3)
78
+ rspec-mocks (2.11.1)
79
+ safely (0.3.2)
80
+ thor (0.15.4)
81
+
82
+ PLATFORMS
83
+ ruby
84
+
85
+ DEPENDENCIES
86
+ em-rspec
87
+ google_drive
88
+ guard
89
+ guard-rspec
90
+ langrove!
91
+ rspec
@@ -0,0 +1,11 @@
1
+ guard 'rspec',
2
+
3
+ :cli => "--color",
4
+ :all_on_start => false,
5
+ :all_after_pass => false,
6
+ :spec_paths => ['spec'] do
7
+
8
+ watch(%r{^spec/.+_spec\.rb$})
9
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10
+
11
+ end
@@ -0,0 +1,90 @@
1
+ `Plugin::Google`
2
+ =========================
3
+
4
+ * Intergates GoogleSpreadsheet support into the [LanGrove](https://github.com/cluetechnologies/langrove-enterprise) persistance layer.
5
+
6
+ `gem install langrove-plugin-google`
7
+
8
+
9
+ Implements
10
+ ----------
11
+
12
+ * [`LanGrove::Plugin::BufferedPersistor`](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin#persistor)
13
+
14
+
15
+ Supports
16
+ ---------
17
+
18
+ * [`LanGrove::Behaviour::Persistable`](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/behaviour#persistable)
19
+
20
+
21
+ Caveats
22
+ -------
23
+
24
+ * Only performs updates to SpreadSheet at specified intervals.
25
+ * Updates by row number, a sort that reorders rows while an update is in progress may cause perculiarities
26
+ * Done as an experiment (may not function all that terrifically)
27
+
28
+ Benefits
29
+ --------
30
+
31
+ * Updates columns by name, additional columns not in the capsule will not be affected.
32
+
33
+
34
+ Example
35
+ -------
36
+
37
+ ### Configuring the plugin.
38
+
39
+ <pre>
40
+ ...
41
+
42
+ :plugins:
43
+ :a_google_doc:
44
+ #
45
+ # reality may differ (unimplemented)
46
+ #
47
+ :class: GoogleSpreadsheet
48
+ :google_key: 0Ak66wsrXSMqjdEV
49
+ :username: can_edit@gmail.com
50
+ :password: passrod
51
+
52
+ #
53
+ # Buffered: calls to store() accumulate
54
+ # and a batched update runs at the
55
+ # specified interval (seconds)
56
+ #
57
+ :interval: 600
58
+
59
+ #
60
+ # Column name containing row key
61
+ #
62
+ :key:
63
+ :key_column_name: :key_column_name
64
+
65
+ ...
66
+
67
+ </pre>
68
+
69
+ ### Assigning the plugin to a daemon.
70
+
71
+ <pre>
72
+
73
+ ...
74
+
75
+ :server:
76
+ :behavior:
77
+ :persistable:
78
+ :plugin: :a_google_doc
79
+ :at:
80
+ :handler_after_receive:
81
+ #
82
+ # will default to storing the caspsule
83
+ # after the Handler.receive( data )
84
+ # method returns.
85
+ #
86
+
87
+ ...
88
+
89
+ </pre>
90
+
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = %q{langrove-plugin-google}
5
+ spec.version = '0.1'
6
+ spec.date = DateTime.now.strftime( "%Y-%m-%d" )
7
+ spec.authors = ["","","","","","","","Richard"]
8
+ spec.email = %q{ops@clue.co.za}
9
+ spec.summary = %q{GoogleDoc Spreadsheet LanGrove Persistor}
10
+ spec.homepage = %q{}
11
+ spec.description = %q{}
12
+ spec.add_dependency 'langrove'
13
+ spec.add_dependency 'google_drive'
14
+ spec.files = `git ls-files`.strip.split("\n")
15
+ end
@@ -0,0 +1,5 @@
1
+ # bundler looks for this by default
2
+
3
+ require 'langrove' unless defined?( LanGrove::Plugin )
4
+ require 'google_drive'
5
+ require 'plugin/google_sheet'
@@ -0,0 +1,122 @@
1
+ require 'google_drive'
2
+ require 'awesome_print'
3
+
4
+ module Plugin
5
+
6
+ #
7
+ # 2000+ rows:
8
+ #
9
+ # Timeout::Error:
10
+ # Timeout::Error
11
+ #
12
+
13
+ #
14
+ # Impractical for high frequency single row updates
15
+ #
16
+ # Can ony reference cells by column and row number
17
+ #
18
+ # Will need a key column to allow for sorting
19
+ # (to not break updates expecting certain records in certain rows)
20
+ #
21
+ #
22
+ # Not ENTIRELY compatable as a LanGrove Persistor...
23
+ #
24
+ # - cannot update one row without fetching the entire sheet
25
+ #
26
+ #
27
+ # unless perhaps:
28
+ #
29
+ # - streamline connecting
30
+ # - initializer to fetch whole sheet
31
+ # - expensive to update only one row....!!!!
32
+ # - will need to batch (somehow -- no such thing in persistor atm)
33
+ #
34
+
35
+ class GoogleSheet
36
+
37
+ def initialize( username, password, key )
38
+
39
+ @username = username
40
+ @password = password
41
+ @key = key
42
+
43
+ puts "loging in..."
44
+ @session = GoogleDrive.login( username, password )
45
+
46
+ puts "getting sheet..."
47
+ @spreadsheet = @session.spreadsheet_by_key( @key )
48
+
49
+ end
50
+
51
+
52
+ def play_more
53
+
54
+ puts "getting worksheet..."
55
+ sheet = @spreadsheet.worksheet_by_title('Sheet One')
56
+
57
+ puts "getting list..."
58
+ list = sheet.list
59
+
60
+ puts "to_hash_array..."
61
+ ap list.to_hash_array
62
+ #
63
+ # [
64
+ # [0] {
65
+ # "key column" => "key1",
66
+ # "value 1" => "2",
67
+ # "value 2" => "3"
68
+ # },
69
+ # [1] {
70
+ # "key column" => "key2",
71
+ # "value 1" => "5",
72
+ # "value 2" => "6"
73
+ # }
74
+ # ]
75
+ #
76
+
77
+ #puts "get List::Row..."
78
+ #row = list[ 98 ] # 100th row
79
+ #ap row.to_hash
80
+
81
+
82
+ end
83
+
84
+
85
+
86
+ def play_with_it
87
+
88
+ puts "getting worksheet..."
89
+ sheet = @spreadsheet.worksheet_by_title('Sheet One')
90
+
91
+ puts "updating rows..."
92
+ #
93
+ # Write into call A1
94
+ #
95
+ sheet[1,1] = 'key column'
96
+ sheet[1,2] = 'value 1'
97
+ sheet[1,3] = 'value 2'
98
+
99
+ sheet[2,1] = 'key1'
100
+ sheet[2,2] = '2'
101
+ sheet[2,3] = '3'
102
+
103
+ sheet[3,1] = 'key2'
104
+ sheet[3,2] = '5'
105
+ sheet[3,3] = '6'
106
+
107
+ sheet[100,1] = 'key3'
108
+ sheet[100,2] = '8'
109
+ sheet[100,3] = '9'
110
+
111
+ puts 'saving...'
112
+ sheet.save
113
+
114
+
115
+ puts 'done...'
116
+
117
+ end
118
+
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,202 @@
1
+ require 'google_drive'
2
+
3
+ module Plugin
4
+
5
+ class GoogleSheet < LanGrove::Plugin::BufferedPersistor
6
+
7
+ def validate_config
8
+
9
+ super
10
+
11
+ raise LanGrove::DaemonConfigException.new(
12
+
13
+ "#{self.class} requires :username:, :password: and :google_key:"
14
+
15
+ ) if (
16
+
17
+ @config[:username].nil? or
18
+ @config[:password].nil? or
19
+ @config[:google_key].nil?
20
+
21
+ )
22
+
23
+ @username = @config[:username]
24
+ @password = @config[:password]
25
+ @google_key = @config[:google_key]
26
+
27
+ connect
28
+
29
+ end
30
+
31
+ def connect
32
+
33
+ #
34
+ # TODO: restore session (a cookie or something)
35
+ #
36
+
37
+ @logger.debug "Connecting as user:#{@username}"
38
+
39
+ @session = GoogleDrive.login( @username, @password )
40
+
41
+ @logger.debug "Getting document: #{@google_key}"
42
+
43
+ @document = @session.spreadsheet_by_key( @google_key )
44
+
45
+ @document.title = @database
46
+
47
+
48
+ end
49
+
50
+ def store_all
51
+
52
+ new, sheet = get_sheet
53
+
54
+ update( sheet ) unless new
55
+
56
+ sheet.save
57
+
58
+ end
59
+
60
+ def get_sheet
61
+
62
+ @logger.debug "Getting sheet #{@table}"
63
+
64
+ sheet = @document.worksheet_by_title( @table )
65
+
66
+ if sheet.nil?
67
+
68
+ @logger.debug "Creating sheet #{@table}"
69
+
70
+ sheet = @document.add_worksheet( @table )
71
+
72
+ return true, create_new( sheet )
73
+
74
+ end
75
+
76
+ index sheet
77
+
78
+ return false, sheet
79
+
80
+ end
81
+
82
+ def index( sheet )
83
+
84
+ @logger.debug "Indexing for key: #{@key_column}"
85
+
86
+ @sheet_hash_array = sheet.list.to_hash_array
87
+
88
+ @row_index = {}
89
+ @row_count = 1 # first row for headings
90
+
91
+ @sheet_hash_array.each do |row|
92
+
93
+ @row_index[ row[ @key_column.to_s ] ] = @row_count += 1
94
+
95
+ end
96
+
97
+
98
+ @col_index = {}
99
+ @col_count = 0
100
+
101
+ @sheet_hash_array[0].each_key do |key|
102
+
103
+ @col_index[ key ] = @col_count += 1
104
+
105
+ end
106
+
107
+ end
108
+
109
+ def update( sheet )
110
+
111
+ @capsules.each do |key, row|
112
+
113
+ if @row_index.has_key?( key )
114
+
115
+ #
116
+ # Updates by row number (as indexed)
117
+ #
118
+ # Sorting the spreadsheet while this is in
119
+ # progress will have perculiar effects
120
+ #
121
+
122
+ update_row( sheet, @row_index[key], row )
123
+
124
+ else
125
+
126
+ add_row( sheet, row )
127
+
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+
134
+ def add_row( sheet, row )
135
+
136
+ #
137
+ # increment and offset for heading
138
+ #
139
+
140
+ next_row = (@row_count += 1)
141
+
142
+ @logger.debug "Creating row:#{next_row} with data: #{row.inspect}"
143
+
144
+ row.each do |k, value|
145
+
146
+ sheet[ next_row, @col_index[k.to_s] ] = value
147
+
148
+ end
149
+
150
+ end
151
+
152
+ def update_row( sheet, row_number, row )
153
+
154
+ @logger.debug "Updating row:#{row_number} with data: #{row.inspect}"
155
+
156
+ row.each do |k, value|
157
+
158
+ sheet[ row_number, @col_index[k.to_s] ] = value
159
+
160
+ end
161
+
162
+ end
163
+
164
+ def create_new( sheet )
165
+
166
+ row_number = 0
167
+
168
+ @capsules.each do |key, row|
169
+
170
+ row_number += 1
171
+
172
+ if row_number == 1
173
+
174
+ col_number = 0
175
+
176
+ row.each_key do |heading|
177
+
178
+ sheet[ row_number, col_number += 1 ] = heading
179
+
180
+ end
181
+
182
+ row_number += 1
183
+
184
+ end
185
+
186
+ col_number = 0
187
+
188
+ row.each do |k, value|
189
+
190
+ sheet[ row_number, col_number += 1 ] = value
191
+
192
+ end
193
+
194
+ end
195
+
196
+ return sheet
197
+
198
+ end
199
+
200
+ end
201
+
202
+ end
@@ -0,0 +1,75 @@
1
+ require 'langrove'
2
+ require 'plugin/google_sheet'
3
+ require 'em-rspec'
4
+
5
+
6
+ ROOT = LanGrove::FakeRoot.new
7
+
8
+ GOOGLE_PERSISTOR_CONFIG = {
9
+
10
+ :username => 'langrove11@gmail.com',
11
+
12
+ :password => 'langrove11',
13
+
14
+ :google_key => '0Ak66wsrXSMqjdEVnWi1ZNXZIR2Q0Q2E2eDE5TW02V0E',
15
+
16
+ :database => 'Spreadsheet Title',
17
+
18
+ :table => 'Sheet Name',
19
+
20
+ :key => {
21
+
22
+ :unique => :unique
23
+
24
+ }
25
+
26
+ }
27
+
28
+ describe Plugin::GoogleSheet do
29
+
30
+ subject {
31
+
32
+ LanGrove::ClassLoader.create( {
33
+
34
+ :module => 'Plugin',
35
+ :class => 'GoogleSheet'
36
+
37
+ } ).new( ROOT, GOOGLE_PERSISTOR_CONFIG, nil )
38
+
39
+ }
40
+
41
+ before :each do
42
+
43
+ @handler = LanGrove::Handler::Base.new()
44
+
45
+ @handler.capsule = {
46
+
47
+ :unique => 'unique thing',
48
+ :value1 => 'ONE',
49
+ :value2 => 'two'
50
+
51
+ }
52
+
53
+ end
54
+
55
+ pending 'can store()' do
56
+
57
+ subject.store( @handler )
58
+
59
+ subject.instance_variable_get(
60
+
61
+ :@capsules ).size.should == 1
62
+
63
+ end
64
+
65
+ it 'stores all' do
66
+
67
+ subject.store( @handler )
68
+ subject.store_all
69
+
70
+ end
71
+
72
+
73
+ it 'can hopefully use a cookie to save on login time'
74
+
75
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: langrove-plugin-google
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - ''
9
+ - ''
10
+ - ''
11
+ - ''
12
+ - ''
13
+ - ''
14
+ - ''
15
+ - Richard
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+ date: 2012-08-02 00:00:00.000000000 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: langrove
23
+ requirement: !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ! '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ type: :runtime
30
+ prerelease: false
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ - !ruby/object:Gem::Dependency
38
+ name: google_drive
39
+ requirement: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ description: ''
54
+ email: ops@clue.co.za
55
+ executables: []
56
+ extensions: []
57
+ extra_rdoc_files: []
58
+ files:
59
+ - .rvmrc
60
+ - Gemfile
61
+ - Gemfile.lock
62
+ - Guardfile
63
+ - README.md
64
+ - langrove-google-plugin.gemspec
65
+ - lib/langrove/plugin/google.rb
66
+ - lib/plugin/discovery.rb
67
+ - lib/plugin/google_sheet.rb
68
+ - spec/plugin/google_sheet_spec.rb
69
+ homepage: ''
70
+ licenses: []
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.24
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: GoogleDoc Spreadsheet LanGrove Persistor
93
+ test_files: []