roo 1.9.3 → 1.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,325 +1,330 @@
1
- #require 'xml'
2
- require "google_spreadsheet"
3
-
4
- class GoogleHTTPError < RuntimeError; end
5
- class GoogleReadError < RuntimeError; end
6
- class GoogleWriteError < RuntimeError; end
7
-
8
- class Google < GenericSpreadsheet
9
- attr_accessor :date_format, :datetime_format
10
-
11
- # Creates a new Google spreadsheet object.
12
- def initialize(spreadsheetkey,user=nil,password=nil)
13
- @filename = spreadsheetkey
14
- @spreadsheetkey = spreadsheetkey
15
- @user = user
16
- @password = password
17
- unless user
18
- user = ENV['GOOGLE_MAIL']
19
- end
20
- unless password
21
- password = ENV['GOOGLE_PASSWORD']
22
- end
23
- @cell = Hash.new {|h,k| h[k]=Hash.new}
24
- @cell_type = Hash.new {|h,k| h[k]=Hash.new}
25
- @formula = Hash.new
26
- @first_row = Hash.new
27
- @last_row = Hash.new
28
- @first_column = Hash.new
29
- @last_column = Hash.new
30
- @cells_read = Hash.new
31
- @header_line = 1
32
- @date_format = '%d/%m/%Y'
33
- @datetime_format = '%d/%m/%Y %H:%M:%S'
34
- @time_format = '%H:%M:%S'
35
- session = GoogleSpreadsheet.login(user, password)
36
- @sheetlist = []
37
- session.spreadsheet_by_key(@spreadsheetkey).worksheets.each { |sheet|
38
- @sheetlist << sheet.title
39
- }
40
- @default_sheet = self.sheets.first
41
- @worksheets = session.spreadsheet_by_key(@spreadsheetkey).worksheets
42
- end
43
-
44
- # returns an array of sheet names in the spreadsheet
45
- def sheets
46
- @sheetlist
47
- end
48
-
49
- def date?(string)
50
- begin
51
- Date.strptime(string, @date_format)
52
- true
53
- rescue
54
- false
55
- end
56
- end
57
-
58
- # is String a time with format HH:MM:SS?
59
- def time?(string)
60
- begin
61
- DateTime.strptime(string, @time_format)
62
- true
63
- rescue
64
- false
65
- end
66
- end
67
-
68
- def datetime?(string)
69
- begin
70
- DateTime.strptime(string, @datetime_format)
71
- true
72
- rescue
73
- false
74
- end
75
- end
76
-
77
- def numeric?(string)
78
- string =~ /^[0-9]+[\.]*[0-9]*$/
79
- end
80
-
81
- def timestring_to_seconds(value)
82
- hms = value.split(':')
83
- hms[0].to_i*3600 + hms[1].to_i*60 + hms[2].to_i
84
- end
85
-
86
- # Returns the content of a spreadsheet-cell.
87
- # (1,1) is the upper left corner.
88
- # (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
89
- # cell at the first line and first row.
90
- def cell(row, col, sheet=nil)
91
- sheet = @default_sheet unless sheet
92
- check_default_sheet #TODO: 2007-12-16
93
- read_cells(sheet) unless @cells_read[sheet]
94
- row,col = normalize(row,col)
95
- value = @cell[sheet]["#{row},#{col}"]
96
- if celltype(row,col,sheet) == :date
97
- begin
98
- return Date.strptime(value, @date_format)
99
- rescue ArgumentError
100
- raise "Invalid Date #{sheet}[#{row},#{col}] #{value} using format '{@date_format}'"
101
- end
102
- elsif celltype(row,col,sheet) == :datetime
103
- begin
104
- return DateTime.strptime(value, @datetime_format)
105
- rescue ArgumentError
106
- raise "Invalid DateTime #{sheet}[#{row},#{col}] #{value} using format '{@datetime_format}'"
107
- end
108
- end
109
- return value
110
- end
111
-
112
- # returns the type of a cell:
113
- # * :float
114
- # * :string
115
- # * :date
116
- # * :percentage
117
- # * :formula
118
- # * :time
119
- # * :datetime
120
- def celltype(row, col, sheet=nil)
121
- sheet = @default_sheet unless sheet
122
- read_cells(sheet) unless @cells_read[sheet]
123
- row,col = normalize(row,col)
124
- if @formula.size > 0 && @formula[sheet]["#{row},#{col}"]
125
- return :formula
126
- else
127
- @cell_type[sheet]["#{row},#{col}"]
128
- end
129
- end
130
-
131
- # Returns the formula at (row,col).
132
- # Returns nil if there is no formula.
133
- # The method #formula? checks if there is a formula.
134
- def formula(row,col,sheet=nil)
135
- sheet = @default_sheet unless sheet
136
- read_cells(sheet) unless @cells_read[sheet]
137
- row,col = normalize(row,col)
138
- if @formula[sheet]["#{row},#{col}"] == nil
139
- return nil
140
- else
141
- return @formula[sheet]["#{row},#{col}"]
142
- end
143
- end
144
-
145
- # true, if there is a formula
146
- def formula?(row,col,sheet=nil)
147
- sheet = @default_sheet unless sheet
148
- read_cells(sheet) unless @cells_read[sheet]
149
- row,col = normalize(row,col)
150
- formula(row,col) != nil
151
- end
152
-
153
- # returns each formula in the selected sheet as an array of elements
154
- # [row, col, formula]
155
- def formulas(sheet=nil)
156
- theformulas = Array.new
157
- sheet = @default_sheet unless sheet
158
- read_cells(sheet) unless @cells_read[sheet]
159
- first_row(sheet).upto(last_row(sheet)) {|row|
160
- first_column(sheet).upto(last_column(sheet)) {|col|
161
- if formula?(row,col,sheet)
162
- f = [row, col, formula(row,col,sheet)]
163
- theformulas << f
164
- end
165
- }
166
- }
167
- theformulas
168
- end
169
-
170
- # true, if the cell is empty
171
- def empty?(row, col, sheet=nil)
172
- value = cell(row, col, sheet)
173
- return true unless value
174
- return false if value.class == Date # a date is never empty
175
- return false if value.class == Float
176
- return false if celltype(row,col,sheet) == :time
177
- value.empty?
178
- end
179
-
180
- # sets the cell to the content of 'value'
181
- # a formula can be set in the form of '=SUM(...)'
182
- def set_value(row,col,value,sheet=nil)
183
- sheet = @default_sheet unless sheet
184
- raise RangeError, "sheet not set" unless sheet
185
- #@@ Set and pass sheet_no
186
- begin
187
- sheet_no = sheets.index(sheet)+1
188
- rescue
189
- raise RangeError, "invalid sheet '"+sheet.to_s+"'"
190
- end
191
- row,col = normalize(row,col)
192
- add_to_cell_roo(row,col,value,sheet_no)
193
- # re-read the portion of the document that has changed
194
- if @cells_read[sheet]
195
- key = "#{row},#{col}"
196
- (value, value_type) = determine_datatype(value.to_s)
197
- @cell[sheet][key] = value
198
- @cell_type[sheet][key] = value_type
199
- end
200
- end
201
-
202
- # returns the first non-empty row in a sheet
203
- def first_row(sheet=nil)
204
- sheet = @default_sheet unless sheet
205
- unless @first_row[sheet]
206
- sheet_no = sheets.index(sheet) + 1
207
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
208
- oben_unten_links_rechts(sheet_no)
209
- end
210
- return @first_row[sheet]
211
- end
212
-
213
- # returns the last non-empty row in a sheet
214
- def last_row(sheet=nil)
215
- sheet = @default_sheet unless sheet
216
- unless @last_row[sheet]
217
- sheet_no = sheets.index(sheet) + 1
218
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
219
- oben_unten_links_rechts(sheet_no)
220
- end
221
- return @last_row[sheet]
222
- end
223
-
224
- # returns the first non-empty column in a sheet
225
- def first_column(sheet=nil)
226
- sheet = @default_sheet unless sheet
227
- unless @first_column[sheet]
228
- sheet_no = sheets.index(sheet) + 1
229
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
230
- oben_unten_links_rechts(sheet_no)
231
- end
232
- return @first_column[sheet]
233
- end
234
-
235
- # returns the last non-empty column in a sheet
236
- def last_column(sheet=nil)
237
- sheet = @default_sheet unless sheet
238
- unless @last_column[sheet]
239
- sheet_no = sheets.index(sheet) + 1
240
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
241
- oben_unten_links_rechts(sheet_no)
242
- end
243
- return @last_column[sheet]
244
- end
245
-
246
- private
247
-
248
- # read all cells in a sheet.
249
- def read_cells(sheet=nil)
250
- sheet = @default_sheet unless sheet
251
- raise RangeError, "illegal sheet <#{sheet}>" unless sheets.index(sheet)
252
- sheet_no = sheets.index(sheet)
253
- ws = @worksheets[sheet_no]
254
- for row in 1..ws.num_rows
255
- for col in 1..ws.num_cols
256
- key = "#{row},#{col}"
257
- string_value = ws.input_value(row,col) # item['inputvalue'] || item['inputValue']
258
- numeric_value = ws[row,col] #item['numericvalue'] || item['numericValue']
259
- (value, value_type) = determine_datatype(string_value, numeric_value)
260
- @cell[sheet][key] = value unless value == "" or value == nil
261
- @cell_type[sheet][key] = value_type
262
- @formula[sheet] = {} unless @formula[sheet]
263
- @formula[sheet][key] = string_value if value_type == :formula
264
- ############
265
- #$log.debug("key: #{key}")
266
- #$log.debug "#{ws[row,col].inspect}"
267
- #@cell[sheet][key] = ws[row,col]
268
- #$log.debug "@cell[sheet][key]: #{@cell[sheet][key]}"
269
- ############
270
- end
271
- end
272
- @cells_read[sheet] = true
273
- end
274
-
275
- def determine_datatype(val, numval=nil)
276
- # $log.debug "val: #{val} numval: #{numval}"
277
- if val.nil? || val[0,1] == '='
278
- ty = :formula
279
- if numeric?(numval)
280
- val = numval.to_f
281
- else
282
- val = numval
283
- end
284
- else
285
- if datetime?(val)
286
- ty = :datetime
287
- elsif date?(val)
288
- ty = :date
289
- elsif numeric?(val)
290
- ty = :float
291
- val = val.to_f
292
- elsif time?(val)
293
- ty = :time
294
- val = timestring_to_seconds(val)
295
- else
296
- ty = :string
297
- end
298
- end
299
- #$log.debug "val: #{val} ty: #{ty}" if ty == :date
300
- return val, ty
301
- end
302
-
303
- def add_to_cell_roo(row,col,value, sheet_no=1)
304
- sheet_no -= 1
305
- @worksheets[sheet_no][row,col] = value
306
- @worksheets[sheet_no].save
307
- end
308
- def entry_roo(value,row,col)
309
- return value,row,col
310
- end
311
-
312
- def oben_unten_links_rechts(sheet_no)
313
- ws = @worksheets[sheet_no-1]
314
- rows = []
315
- cols = []
316
- for row in 1..ws.num_rows
317
- for col in 1..ws.num_cols
318
- rows << row if ws[row,col] and ws[row,col] != '' #TODO: besser?
319
- cols << col if ws[row,col] and ws[row,col] != '' #TODO: besser?
320
- end
321
- end
322
- return rows.min, rows.max, cols.min, cols.max
323
- end
324
-
325
- end # class
1
+ require "google_spreadsheet"
2
+
3
+ class GoogleHTTPError < RuntimeError; end
4
+ class GoogleReadError < RuntimeError; end
5
+ class GoogleWriteError < RuntimeError; end
6
+
7
+ class Google < GenericSpreadsheet
8
+ attr_accessor :date_format, :datetime_format
9
+
10
+ # Creates a new Google spreadsheet object.
11
+ def initialize(spreadsheetkey,user=nil,password=nil)
12
+ @filename = spreadsheetkey
13
+ @spreadsheetkey = spreadsheetkey
14
+ @user = user
15
+ @password = password
16
+ unless user
17
+ user = ENV['GOOGLE_MAIL']
18
+ end
19
+ unless password
20
+ password = ENV['GOOGLE_PASSWORD']
21
+ end
22
+ unless user and user.size > 0
23
+ warn "user not set"
24
+ end
25
+ unless password and password.size > 0
26
+ warn "password not set"
27
+ end
28
+ @cell = Hash.new {|h,k| h[k]=Hash.new}
29
+ @cell_type = Hash.new {|h,k| h[k]=Hash.new}
30
+ @formula = Hash.new
31
+ @first_row = Hash.new
32
+ @last_row = Hash.new
33
+ @first_column = Hash.new
34
+ @last_column = Hash.new
35
+ @cells_read = Hash.new
36
+ @header_line = 1
37
+ @date_format = '%d/%m/%Y'
38
+ @datetime_format = '%d/%m/%Y %H:%M:%S'
39
+ @time_format = '%H:%M:%S'
40
+ session = GoogleSpreadsheet.login(user, password)
41
+ @sheetlist = []
42
+ session.spreadsheet_by_key(@spreadsheetkey).worksheets.each { |sheet|
43
+ @sheetlist << sheet.title
44
+ }
45
+ @default_sheet = self.sheets.first
46
+ @worksheets = session.spreadsheet_by_key(@spreadsheetkey).worksheets
47
+ end
48
+
49
+ # returns an array of sheet names in the spreadsheet
50
+ def sheets
51
+ @sheetlist
52
+ end
53
+
54
+ def date?(string)
55
+ begin
56
+ Date.strptime(string, @date_format)
57
+ true
58
+ rescue
59
+ false
60
+ end
61
+ end
62
+
63
+ # is String a time with format HH:MM:SS?
64
+ def time?(string)
65
+ begin
66
+ DateTime.strptime(string, @time_format)
67
+ true
68
+ rescue
69
+ false
70
+ end
71
+ end
72
+
73
+ def datetime?(string)
74
+ begin
75
+ DateTime.strptime(string, @datetime_format)
76
+ true
77
+ rescue
78
+ false
79
+ end
80
+ end
81
+
82
+ def numeric?(string)
83
+ string =~ /^[0-9]+[\.]*[0-9]*$/
84
+ end
85
+
86
+ def timestring_to_seconds(value)
87
+ hms = value.split(':')
88
+ hms[0].to_i*3600 + hms[1].to_i*60 + hms[2].to_i
89
+ end
90
+
91
+ # Returns the content of a spreadsheet-cell.
92
+ # (1,1) is the upper left corner.
93
+ # (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
94
+ # cell at the first line and first row.
95
+ def cell(row, col, sheet=nil)
96
+ sheet = @default_sheet unless sheet
97
+ check_default_sheet #TODO: 2007-12-16
98
+ read_cells(sheet) unless @cells_read[sheet]
99
+ row,col = normalize(row,col)
100
+ value = @cell[sheet]["#{row},#{col}"]
101
+ if celltype(row,col,sheet) == :date
102
+ begin
103
+ return Date.strptime(value, @date_format)
104
+ rescue ArgumentError
105
+ raise "Invalid Date #{sheet}[#{row},#{col}] #{value} using format '{@date_format}'"
106
+ end
107
+ elsif celltype(row,col,sheet) == :datetime
108
+ begin
109
+ return DateTime.strptime(value, @datetime_format)
110
+ rescue ArgumentError
111
+ raise "Invalid DateTime #{sheet}[#{row},#{col}] #{value} using format '{@datetime_format}'"
112
+ end
113
+ end
114
+ return value
115
+ end
116
+
117
+ # returns the type of a cell:
118
+ # * :float
119
+ # * :string
120
+ # * :date
121
+ # * :percentage
122
+ # * :formula
123
+ # * :time
124
+ # * :datetime
125
+ def celltype(row, col, sheet=nil)
126
+ sheet = @default_sheet unless sheet
127
+ read_cells(sheet) unless @cells_read[sheet]
128
+ row,col = normalize(row,col)
129
+ if @formula.size > 0 && @formula[sheet]["#{row},#{col}"]
130
+ return :formula
131
+ else
132
+ @cell_type[sheet]["#{row},#{col}"]
133
+ end
134
+ end
135
+
136
+ # Returns the formula at (row,col).
137
+ # Returns nil if there is no formula.
138
+ # The method #formula? checks if there is a formula.
139
+ def formula(row,col,sheet=nil)
140
+ sheet = @default_sheet unless sheet
141
+ read_cells(sheet) unless @cells_read[sheet]
142
+ row,col = normalize(row,col)
143
+ if @formula[sheet]["#{row},#{col}"] == nil
144
+ return nil
145
+ else
146
+ return @formula[sheet]["#{row},#{col}"]
147
+ end
148
+ end
149
+
150
+ # true, if there is a formula
151
+ def formula?(row,col,sheet=nil)
152
+ sheet = @default_sheet unless sheet
153
+ read_cells(sheet) unless @cells_read[sheet]
154
+ row,col = normalize(row,col)
155
+ formula(row,col) != nil
156
+ end
157
+
158
+ # returns each formula in the selected sheet as an array of elements
159
+ # [row, col, formula]
160
+ def formulas(sheet=nil)
161
+ theformulas = Array.new
162
+ sheet = @default_sheet unless sheet
163
+ read_cells(sheet) unless @cells_read[sheet]
164
+ first_row(sheet).upto(last_row(sheet)) {|row|
165
+ first_column(sheet).upto(last_column(sheet)) {|col|
166
+ if formula?(row,col,sheet)
167
+ f = [row, col, formula(row,col,sheet)]
168
+ theformulas << f
169
+ end
170
+ }
171
+ }
172
+ theformulas
173
+ end
174
+
175
+ # true, if the cell is empty
176
+ def empty?(row, col, sheet=nil)
177
+ value = cell(row, col, sheet)
178
+ return true unless value
179
+ return false if value.class == Date # a date is never empty
180
+ return false if value.class == Float
181
+ return false if celltype(row,col,sheet) == :time
182
+ value.empty?
183
+ end
184
+
185
+ # sets the cell to the content of 'value'
186
+ # a formula can be set in the form of '=SUM(...)'
187
+ def set_value(row,col,value,sheet=nil)
188
+ sheet = @default_sheet unless sheet
189
+ raise RangeError, "sheet not set" unless sheet
190
+ #@@ Set and pass sheet_no
191
+ begin
192
+ sheet_no = sheets.index(sheet)+1
193
+ rescue
194
+ raise RangeError, "invalid sheet '"+sheet.to_s+"'"
195
+ end
196
+ row,col = normalize(row,col)
197
+ add_to_cell_roo(row,col,value,sheet_no)
198
+ # re-read the portion of the document that has changed
199
+ if @cells_read[sheet]
200
+ key = "#{row},#{col}"
201
+ (value, value_type) = determine_datatype(value.to_s)
202
+ @cell[sheet][key] = value
203
+ @cell_type[sheet][key] = value_type
204
+ end
205
+ end
206
+
207
+ # returns the first non-empty row in a sheet
208
+ def first_row(sheet=nil)
209
+ sheet = @default_sheet unless sheet
210
+ unless @first_row[sheet]
211
+ sheet_no = sheets.index(sheet) + 1
212
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
213
+ oben_unten_links_rechts(sheet_no)
214
+ end
215
+ return @first_row[sheet]
216
+ end
217
+
218
+ # returns the last non-empty row in a sheet
219
+ def last_row(sheet=nil)
220
+ sheet = @default_sheet unless sheet
221
+ unless @last_row[sheet]
222
+ sheet_no = sheets.index(sheet) + 1
223
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
224
+ oben_unten_links_rechts(sheet_no)
225
+ end
226
+ return @last_row[sheet]
227
+ end
228
+
229
+ # returns the first non-empty column in a sheet
230
+ def first_column(sheet=nil)
231
+ sheet = @default_sheet unless sheet
232
+ unless @first_column[sheet]
233
+ sheet_no = sheets.index(sheet) + 1
234
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
235
+ oben_unten_links_rechts(sheet_no)
236
+ end
237
+ return @first_column[sheet]
238
+ end
239
+
240
+ # returns the last non-empty column in a sheet
241
+ def last_column(sheet=nil)
242
+ sheet = @default_sheet unless sheet
243
+ unless @last_column[sheet]
244
+ sheet_no = sheets.index(sheet) + 1
245
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
246
+ oben_unten_links_rechts(sheet_no)
247
+ end
248
+ return @last_column[sheet]
249
+ end
250
+
251
+ private
252
+
253
+ # read all cells in a sheet.
254
+ def read_cells(sheet=nil)
255
+ sheet = @default_sheet unless sheet
256
+ raise RangeError, "illegal sheet <#{sheet}>" unless sheets.index(sheet)
257
+ sheet_no = sheets.index(sheet)
258
+ ws = @worksheets[sheet_no]
259
+ for row in 1..ws.num_rows
260
+ for col in 1..ws.num_cols
261
+ key = "#{row},#{col}"
262
+ string_value = ws.input_value(row,col) # item['inputvalue'] || item['inputValue']
263
+ numeric_value = ws[row,col] #item['numericvalue'] || item['numericValue']
264
+ (value, value_type) = determine_datatype(string_value, numeric_value)
265
+ @cell[sheet][key] = value unless value == "" or value == nil
266
+ @cell_type[sheet][key] = value_type
267
+ @formula[sheet] = {} unless @formula[sheet]
268
+ @formula[sheet][key] = string_value if value_type == :formula
269
+ ############
270
+ #$log.debug("key: #{key}")
271
+ #$log.debug "#{ws[row,col].inspect}"
272
+ #@cell[sheet][key] = ws[row,col]
273
+ #$log.debug "@cell[sheet][key]: #{@cell[sheet][key]}"
274
+ ############
275
+ end
276
+ end
277
+ @cells_read[sheet] = true
278
+ end
279
+
280
+ def determine_datatype(val, numval=nil)
281
+ # $log.debug "val: #{val} numval: #{numval}"
282
+ if val.nil? || val[0,1] == '='
283
+ ty = :formula
284
+ if numeric?(numval)
285
+ val = numval.to_f
286
+ else
287
+ val = numval
288
+ end
289
+ else
290
+ if datetime?(val)
291
+ ty = :datetime
292
+ elsif date?(val)
293
+ ty = :date
294
+ elsif numeric?(val)
295
+ ty = :float
296
+ val = val.to_f
297
+ elsif time?(val)
298
+ ty = :time
299
+ val = timestring_to_seconds(val)
300
+ else
301
+ ty = :string
302
+ end
303
+ end
304
+ #$log.debug "val: #{val} ty: #{ty}" if ty == :date
305
+ return val, ty
306
+ end
307
+
308
+ def add_to_cell_roo(row,col,value, sheet_no=1)
309
+ sheet_no -= 1
310
+ @worksheets[sheet_no][row,col] = value
311
+ @worksheets[sheet_no].save
312
+ end
313
+ def entry_roo(value,row,col)
314
+ return value,row,col
315
+ end
316
+
317
+ def oben_unten_links_rechts(sheet_no)
318
+ ws = @worksheets[sheet_no-1]
319
+ rows = []
320
+ cols = []
321
+ for row in 1..ws.num_rows
322
+ for col in 1..ws.num_cols
323
+ rows << row if ws[row,col] and ws[row,col] != '' #TODO: besser?
324
+ cols << col if ws[row,col] and ws[row,col] != '' #TODO: besser?
325
+ end
326
+ end
327
+ return rows.min, rows.max, cols.min, cols.max
328
+ end
329
+
330
+ end # class