roo 0.7.0 → 0.8.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.
@@ -1,99 +1,180 @@
1
+ require 'rubygems' #TODO:
2
+ require 'gdata/spreadsheet'
3
+ #require 'log4r'
1
4
 
2
- #require 'net/http'
3
- #require 'net/https'
4
- #require 'uri'
5
- require 'rubygems'
6
- #require 'hpricot'
7
- require 'timeout'
8
- #require 'GData'
9
- require 'gdata'
10
-
11
- # Make it easy to use some of the convenience methods using https
12
- #
13
- #module Net class HTTPS < HTTP
14
- # def initialize(address, port = nil)
15
- # super(address, port)
16
- # self.use_ssl = true
17
- # end
18
- # end
19
- #end
20
- #
21
- #class GoogleSpreadSheet
22
- # GOOGLE_LOGIN_URL = URI.parse('https://www.google.com/accounts/ClientLogin')
23
- #
24
- # def initialize(spreadsheet_key)
25
- # @spreadsheet_key = spreadsheet_key
26
- # @headers = nil
27
- # @default_sheet = nil
28
- # end
29
- #
30
- # def default_sheet=(numberofsheet)
31
- # @default_sheet = numberofsheet
32
- # end
33
- #
34
- # def authenticate(email, password)
35
- # $VERBOSE = nil
36
- # response = Net::HTTPS.post_form(GOOGLE_LOGIN_URL,
37
- # {'Email' => email,
38
- # 'Passwd' => password,
39
- # 'source' => "formula",
40
- # 'service' => 'wise' })
41
- # @headers = { 'Authorization' => "GoogleLogin auth=#{response.body.split(/=/).last}",
42
- # 'Content-Type' => 'application/atom+xml'
43
- # }
44
- # end
45
- #
46
- # def evaluate_cell(cell)
47
- # path = "/feeds/cells/#{@spreadsheet_key}/#{@default_sheet}/#{@headers ? "private" : "public"}/basic/#{cell}"
48
- #
49
- # doc = Hpricot(request(path))
50
- # result = (doc/"content[@type='text']").inner_html
51
- # end
52
- #
53
- # def set_entry(entry)
54
- # path = "/feeds/cells/#{@spreadsheet_key}/#{@default_sheet}/#{@headers ? 'private' : 'public'}/full"
55
- #
56
- # post(path, entry)
57
- # end
58
- #
59
- # def entry(formula, row=1, col=1)
60
- # <<XML
61
- #<?xml version='1.0' ?>
62
- #<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
63
- # <gs:cell row='#{row}' col='#{col}' inputValue='=#{formula}' />
64
- #</entry>
65
- #XML
66
- # end
67
- #
68
- # def add_to_cell(formula) #puts entry(formula)
69
- # set_entry(entry(formula))
70
- # end
71
- #
72
- # private
73
- # def request(path)
74
- # response, data = get_http.get(path, @headers)
75
- # data
76
- # end
77
- #
78
- # def post(path, entry)
79
- # get_http.post(path, entry, @headers)
80
- # end
81
- #
82
- # def get_http
83
- # http = Net::HTTP.new('spreadsheets.google.com', 80)
84
- # #http.set_debug_output $stderr
85
- # http
86
- # end
87
- #end
5
+ # overwrite some methods from the gdata-gem:
6
+ module GData
7
+ class Spreadsheet < GData::Base
8
+ #-- modified
9
+ def evaluate_cell(cell, sheet_no=1)
10
+ raise ArgumentError, "invalid cell: #{cell}" unless cell
11
+ raise ArgumentError, "invalid sheet_no: #{sheet_no}" unless sheet_no >0 and sheet_no.class == Fixnum
12
+ path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{@headers ? "private" : "public"}/basic/#{cell}"
13
+
14
+ doc = Hpricot(request(path))
15
+ result = (doc/"content").inner_html
16
+ end
88
17
 
89
- class Google < Openoffice #:nodoc:
18
+ #-- new
19
+ def sheetlist
20
+ path = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
21
+ doc = Hpricot(request(path))
22
+ result = []
23
+ (doc/"content").each { |elem|
24
+ result << elem.inner_html
25
+ }
26
+ result
27
+ end
28
+
29
+ # #-- new (testing only)
30
+ # def raw_url(url)
31
+ # path = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
32
+ # path = url
33
+ # doc = Hpricot(request(path))
34
+ # end
35
+
36
+ #-- new
37
+ def save_entry_roo(entry)
38
+ path = "/feeds/cells/#{@spreadsheet_id}/1/#{@headers ? 'private' : 'public'}/full"
39
+ post(path, entry)
40
+ end
41
+
42
+ #-- new
43
+ def entry_roo(formula, row=1, col=1)
44
+ <<XML
45
+ <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
46
+ <gs:cell row='#{row}' col='#{col}' inputValue='#{formula}' />
47
+ </entry>
48
+ XML
49
+ end
50
+
51
+ #-- new
52
+ def add_to_cell_roo(row,col,value)
53
+ save_entry_roo(entry_roo(value,row,col))
54
+ end
55
+
56
+ #-- new
57
+ def get_one_sheet
58
+ ath = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
59
+ path = "/feeds/cells/#{@spreadsheet_id}/1/private/full"
60
+ doc = Hpricot(request(path))
61
+ #pp doc
62
+ #p doc # TODO:prey:
63
+ # result = (doc/"content[@type='text']").inner_html
64
+ # p (doc/"content").inner_html
65
+ #result = (doc/"content").inner_html.each { |item| item + '#'}
66
+ #-- result = []
67
+ #-- (doc/"content").each { |elem|
68
+ #-- #p elem
69
+ #-- result << elem.inner_html
70
+ #-- }
71
+ #-- result
72
+ end
73
+
74
+ #new
75
+ def oben_unten_links_rechts(sheet_no)
76
+ #sheet_no = sheets.index(sheet) + 1
77
+ path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/private/full"
78
+ doc = Hpricot(request(path))
79
+ #(doc/"entry").each {|item|
80
+ rows = []
81
+ cols = []
82
+ (doc/"gs:cell").each {|item|
83
+ # p item
84
+ #p item['row']
85
+ rows.push item['row'].to_i
86
+ #p item['col']
87
+ cols.push item['col'].to_i
88
+ }
89
+ # $log.debug("row min: #{rows.min}")
90
+ # $log.debug("row max: #{rows.max}")
91
+ # $log.debug("col min: #{cols.min}")
92
+ # $log.debug("col max: #{cols.max}")
93
+ return rows.min, rows.max, cols.min, cols.max
94
+ end
95
+
96
+ def fulldoc(sheet_no)
97
+ path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/private/full"
98
+ doc = Hpricot(request(path))
99
+ return doc
100
+ #(doc/"entry").each {|item|
101
+ rows = []
102
+ cols = []
103
+ (doc/"gs:cell").each {|item|
104
+ # p item
105
+ #p item['row']
106
+ rows.push item['row'].to_i
107
+ #p item['col']
108
+ cols.push item['col'].to_i
109
+ }
110
+ # $log.debug("row min: #{rows.min}")
111
+ # $log.debug("row max: #{rows.max}")
112
+ # $log.debug("col min: #{cols.min}")
113
+ # $log.debug("col max: #{cols.max}")
114
+ return rows.min, rows.max, cols.min, cols.max
115
+ end
116
+ end # class
117
+ end # module
90
118
 
91
- TIMEOUT_IN_SECONDS = 2
119
+ class Google < GenericSpreadsheet
120
+ #include Log4r
121
+
122
+ attr_accessor :header_line
92
123
 
93
- def initialize(user, password, spreadsheetkey, spreadsheetname)
94
- @cells_read = false
124
+ # TIMEOUT_IN_SECONDS = 42
125
+ # GOOGLE_MAX_ROWS = 99
126
+ # GOOGLE_MAX_COLS = 10 # TODO:
127
+
128
+ # Creates a new Google spreadsheet object.
129
+ def initialize(spreadsheetkey,user=nil,password=nil)
130
+ @filename = spreadsheetkey
131
+ # $log = Logger.new("my_log")
132
+ # $log.outputters = FileOutputter.new("f1", :filename => "roo.log")
133
+
134
+ # $log.debug("created a new Google-object")
135
+ @spreadsheetkey = spreadsheetkey
136
+ @user = user
137
+ @password = password
138
+ unless user
139
+ user = ENV['GOOGLE_MAIL']
140
+ end
141
+ unless password
142
+ password = ENV['GOOGLE_PASSWORD']
143
+ end
144
+ #p spreadsheetkey
145
+ #p user
146
+ #p password
147
+ #spreadsheetkey = ENV['GOOGLE_KEY']
148
+ @default_sheet = nil
95
149
  @cell = Hash.new
96
150
  @cell_type = Hash.new
151
+ @formula = Hash.new
152
+ @first_row = Hash.new
153
+ @last_row = Hash.new
154
+ @first_column = Hash.new
155
+ @last_column = Hash.new
156
+ @cells_read = Hash.new
157
+ @header_line = 1
158
+ #??? @sheets = Array.new
159
+
160
+ @gs = GData::Spreadsheet.new(spreadsheetkey)
161
+ #@column = FromGData::Spreadsheet.new(spreadsheetkey)
162
+ @gs.authenticate(user, password)
163
+
164
+ #--Test only
165
+ #@gs.get_one_sheet
166
+ #@gs.oben_unten_links_rechts
167
+ #--
168
+ #-- ----------------------------------------------------------------------
169
+ #-- Behandlung von Berechtigungen hier noch einbauen
170
+ #-- ----------------------------------------------------------------------
171
+
172
+ #result = gs.add_to_cell formula
173
+ #puts gs.evaluate_cell('A1')
174
+ #p gs.evaluate_cell('A1')
175
+ #puts gs.evaluate_cell('A2')
176
+ #puts gs.evaluate_cell('A3')
177
+
97
178
  #Timeout.timeout(TIMEOUT_IN_SECONDS) {
98
179
  # @gs = GoogleSpreadSheet.new(spreadsheetkey)
99
180
  # @gs.authenticate(user, password)
@@ -105,90 +186,524 @@ class Google < Openoffice #:nodoc:
105
186
  # @spreadsheet= spreadsheet[spreadsheetname]
106
187
 
107
188
  #gb = GData::Base.new
108
- #gb.authenticate("thopre@gmail.com","nora3033")
189
+ #gb.authenticate("thopre@gmail.com","secret")
109
190
 
110
- g = GData::Spreadsheet.new("ttt")
111
- @default_sheet = nil
191
+ #g = GData::Spreadsheet.new("ttt")
192
+ #@default_sheet = nil
193
+ if self.sheets.size == 1
194
+ @default_sheet = self.sheets.first
195
+ end
112
196
  end
113
197
 
198
+ #def gssheetlist
199
+ # @gs.sheetlist
200
+ #end
201
+
202
+ # returns an array of sheet names in the spreadsheet
114
203
  def sheets
115
- # http://spreadsheets.google.com/feeds/worksheets/ptu6bbahNZpYrdGHwteUNCw/private/full
116
- #if DateTime.now < Date.new(2007,6,15)
117
- # return ["Sheet eins","Sheet zwei","Sheet drei"]
118
- #else
119
- # return []
120
- #end
121
- @spreadsheet
204
+ #if @sheets == []
205
+ # @sheets = @gs.sheetlist
206
+ #end
207
+ #return @sheets
208
+ #p gssheetlist
209
+ return @gs.sheetlist
122
210
  end
123
211
 
124
- def default_sheet=(numberofsheet)
125
- @gs.default_sheet = numberofsheet
212
+ #def reload
213
+ # sav_default_sheet = default_sheet
214
+ # super
215
+ # @sheets = sheets #[]
216
+ # puts "DEBUG: reload: erneutes Einlesen ergibt @sheets=#{@sheets.to_s}"
217
+ # @default_sheet = sav_default_sheet
218
+ #end
219
+
220
+ # set the working sheet in the document
221
+ #--
222
+ # TODO: eigenlich identisch mit Openoffice => refactoring
223
+ def default_sheet=(sheet)
224
+ #puts "DEBUG: default_sheet=#{sheet}"
225
+ if ! sheet.kind_of?(String)
226
+ raise TypeError, "what are you trying to set as default sheet?"
227
+ end
228
+ @default_sheet = sheet
229
+ check_default_sheet
230
+ @first_row[sheet] = @last_row[sheet] = @first_column[sheet] = @last_column[sheet] = nil
231
+ #--TODO: @cells_read[sheet] = false
232
+ end
233
+
234
+ # is String a date with format DD/MM/YYYY
235
+ def Google.date?(string)
236
+ return false if string.class == Float
237
+ return true if string.class == Date
238
+ return string.strip =~ /^([0-9]+)\/([0-9]+)\/([0-9]+)$/
126
239
  end
127
240
 
128
- def cell(row, col)
241
+ # Returns the content of a spreadsheet-cell.
242
+ # (1,1) is the upper left corner.
243
+ # (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
244
+ # cell at the first line and first row.
245
+ def cell(row, col, sheet=nil)
246
+ sheet = @default_sheet unless sheet
247
+ check_default_sheet #TODO: 2007-12-16
248
+ read_cells(sheet) unless @cells_read[sheet]
129
249
  row,col = normalize(row,col)
130
- # formula = 42 || 'sin(0.2)'
131
-
132
- # gs = GoogleSpreadSheet.new("ptu6bbahNZpYrdGHwteUNCw")
133
- # gs.authenticate('thopre@gmail.com', 'nora3033')
134
- # gs.add_to_cell formula
135
- cellname = number_to_letter(col)+row.to_s
136
- Timeout.timeout(TIMEOUT_IN_SECONDS) {
137
- return @gs.evaluate_cell(cellname) # 'A1')
138
- }
250
+
251
+ if celltype(row,col,sheet) == :date
252
+ # $log.debug("splitte Datumsfeld auf (#{row},#{col}): #{ @cell[sheet]["#{row},#{col}"]}")
253
+ yyyy,mm,dd = @cell[sheet]["#{row},#{col}"].split('-')
254
+ # $log.debug(yyyy)
255
+ # $log.debug(mm)
256
+ # $log.debug(dd)
257
+ #TODO:
258
+ if dd.to_i < 1 or dd.to_i >31 or mm.to_i < 1 or mm.to_i > 12 or yyyy.to_i < 1900 or yyyy.to_i > 3000
259
+ raise "Invalid date parameter: #{yyyy}, #{mm}, #{dd}"
260
+ end
261
+ return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
262
+ end
263
+ return @cell[sheet]["#{row},#{col}"]
264
+ end
265
+
266
+ # returns the type of a cell:
267
+ # * :float
268
+ # * :string,
269
+ # * :date
270
+ # * :percentage
271
+ def celltype(row, col, sheet=nil)
272
+ sheet = @default_sheet unless sheet
273
+ read_cells(sheet) unless @cells_read[sheet]
274
+ row,col = normalize(row,col)
275
+ if @formula[sheet]["#{row},#{col}"]
276
+ return :formula
277
+ else
278
+ @cell_type[sheet]["#{row},#{col}"]
279
+ end
280
+ end
281
+
282
+ # Returns the formula at (row,col).
283
+ # Returns nil if there is no formula.
284
+ # The method #formula? checks if there is a formula.
285
+ def formula(row,col,sheet=nil)
286
+ sheet = @default_sheet unless sheet
287
+ read_cells(sheet) unless @cells_read[sheet]
288
+ row,col = normalize(row,col)
289
+ if @formula[sheet]["#{row},#{col}"] == nil
290
+ return nil
291
+ else
292
+ return @formula[sheet]["#{row},#{col}"] #TODO: ["oooc:".length..-1]
293
+ end
294
+ end
295
+
296
+ # true, if there is a formula
297
+ def formula?(row,col,sheet=nil)
298
+ sheet = @default_sheet unless sheet
299
+ read_cells unless @cells_read[sheet]
300
+ row,col = normalize(row,col)
301
+ formula(row,col) != nil
302
+ end
303
+
304
+ # returns each formula in the selected sheet as an array of elements
305
+ # [row, col, formula]
306
+ def formulas(sheet=nil)
307
+ theformulas = Array.new
308
+ sheet = @default_sheet unless sheet
309
+ read_cells(sheet) unless @cells_read[sheet]
310
+ first_row(sheet).upto(last_row(sheet)) {|row|
311
+ first_column(sheet).upto(last_column(sheet)) {|col|
312
+ if formula?(row,col,sheet)
313
+ f = [row, col, formula(row,col,sheet)]
314
+ theformulas << f
315
+ end
316
+ }
317
+ }
318
+ theformulas
319
+ end
320
+
321
+ # # returns all values in this row as an array
322
+ # # row numbers are 1,2,3,... like in the spreadsheet
323
+ # def row_old(rownumber,sheet=nil)
324
+ # sheet = @default_sheet unless sheet
325
+ # result = []
326
+ # 1.upto(GOOGLE_MAX_ROWS) { |col| # TODO: maximum size of x-coordinate of google spreadsheet
327
+ # result[col] = cell(rownumber,col,sheet)
328
+ # }
329
+ # result = result[1..-1]
330
+ # while result[-1] == '' #TODO: besser?
331
+ # result = result[0..-2]
332
+ # end
333
+ # result
334
+ # end
335
+
336
+ # returns all values in this row as an array
337
+ # row numbers are 1,2,3,... like in the spreadsheet
338
+ def row(rownumber,sheet=nil)
339
+ sheet = @default_sheet unless sheet
340
+ read_cells(sheet) unless @cells_read[sheet]
341
+ result = []
342
+ tmp_arr = []
343
+ @cell[sheet].each_pair {|key,value|
344
+ y,x = key.split(',')
345
+ x = x.to_i
346
+ y = y.to_i
347
+ if y == rownumber
348
+ tmp_arr[x] = value
349
+ end
350
+ }
351
+ result = tmp_arr[1..-1]
352
+ while result[-1] == nil
353
+ result = result[0..-2]
354
+ end
355
+ result
356
+ end
357
+
358
+ # true, if the cell is empty
359
+ def empty?(row, col, sheet=nil)
360
+ value = cell(row, col, sheet)
361
+ return true unless value
362
+ return false if value.class == Date # a date is never empty
363
+ return false if value.class == Float
364
+ value.empty?
139
365
  end
366
+
367
+ # returns all values in this column as an array
368
+ # column numbers are 1,2,3,... like in the spreadsheet
369
+ #--
370
+ #TODO: refactoring nach GenericSpreadsheet?
371
+ def column(columnnumber, sheet=nil)
372
+ if columnnumber.class == String
373
+ columnnumber = GenericSpreadsheet.letter_to_number(columnnumber)
374
+ end
375
+ sheet = @default_sheet unless sheet
376
+ read_cells(sheet) unless @cells_read[sheet]
377
+ result = []
378
+ first_row(sheet).upto(last_row(sheet)) do |row|
379
+ result << cell(row,columnnumber,sheet)
380
+ end
381
+ result
382
+ end
140
383
 
141
- def celltype(row, col)
142
- "string"
384
+ # sets the cell to the content of 'value'
385
+ # a formula can be set in the form of '=SUM(...)'
386
+ def set_value(row,col,value)
387
+ @gs.add_to_cell_roo(row,col,value)
388
+ end
389
+
390
+ # returns the first non-empty row in a sheet
391
+ def first_row(sheet=nil)
392
+ sheet = @default_sheet unless sheet
393
+ unless @first_row[sheet]
394
+ sheet_no = sheets.index(sheet) + 1
395
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
396
+ end
397
+ return @first_row[sheet]
398
+ end
399
+
400
+ # returns the last non-empty row in a sheet
401
+ def last_row(sheet=nil)
402
+ sheet = @default_sheet unless sheet
403
+ unless @last_row[sheet]
404
+ sheet_no = sheets.index(sheet) + 1
405
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
406
+ end
407
+ return @last_row[sheet]
408
+ end
409
+
410
+ # returns the first non-empty column in a sheet
411
+ def first_column(sheet=nil)
412
+ sheet = @default_sheet unless sheet
413
+ unless @first_column[sheet]
414
+ sheet_no = sheets.index(sheet) + 1
415
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
416
+ end
417
+ return @first_column[sheet]
418
+ end
419
+
420
+ # returns the last non-empty column in a sheet
421
+ def last_column(sheet=nil)
422
+ sheet = @default_sheet unless sheet
423
+ unless @last_column[sheet]
424
+ sheet_no = sheets.index(sheet) + 1
425
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
426
+ end
427
+ return @last_column[sheet]
428
+ end
429
+
430
+ # write the current spreadsheet to stdout or into a file
431
+ #--
432
+ #TODO: refactoring --> GenericSpreadsheet
433
+ def to_csv(filename=nil,sheet=nil)
434
+ sheet = @default_sheet unless sheet
435
+ if filename
436
+ file = File.open(filename,"w") # do |file|
437
+ write_csv_content(file,sheet)
438
+ file.close
439
+ else
440
+ write_csv_content(STDOUT,sheet)
441
+ end
442
+ true
143
443
  end
144
444
 
145
- def empty?(row, col)
146
- cell(row, col).empty?
147
- end
148
-
149
- def read_cells
150
- # http://spreadsheets.google.com/feeds/list/ptu6bbahNZpYrdGHwteUNCw/1/private/full
151
- file = File.new("/home/tp/aaa.xml")
152
- @doc = REXML::Document.new file
153
- file.close
154
- @doc.each_element do |element|
155
- if element.name == "feed"
156
- p "feed gefunden"
157
- element.each_element do |feed|
158
- p feed
159
- feed.each_element do |fe|
160
- p fe.name
445
+
446
+ # find a row either by row number or a condition
447
+ # Caution: this works only within the default sheet -> set default_sheet before you call this method
448
+ # (experimental. see examples in the test_roo.rb file)
449
+ #--
450
+ # -----------------------------------------------------
451
+ # !!!TODO: should be factored out to GenericSpreadsheet
452
+ # also in Openofiffe
453
+ # -----------------------------------------------------
454
+ #++
455
+ def find(*args)
456
+ result_array = false
457
+ args.each {|arg,val|
458
+ if arg.class == Hash
459
+ arg.each { |hkey,hval|
460
+ if hkey == :array and hval == true
461
+ result_array = true
161
462
  end
162
- end
463
+ }
464
+ end
465
+ }
466
+ column_with = {}
467
+ 1.upto(last_column) do |col|
468
+ column_with[cell(@header_line,col)] = col
469
+ end
470
+ result = Array.new
471
+ #-- id
472
+ if args[0].class == Fixnum
473
+ rownum = args[0]
474
+ tmp = {}
475
+ 1.upto(self.row(rownum).size) {|j|
476
+ x = ''
477
+ column_with.each { |key,val|
478
+ if val == j
479
+ x = key
480
+ end
481
+ }
482
+ tmp[x] = cell(rownum,j)
483
+ }
484
+ result = [ tmp ] # row(rownum)
485
+ #-- :all
486
+ elsif args[0] == :all
487
+ if args[1].class == Hash
488
+ args[1].each {|key,val|
489
+ if key == :conditions
490
+ column_with = {}
491
+ 1.upto(last_column) do |col|
492
+ column_with[cell(@header_line,col)] = col
493
+ end
494
+ conditions = val
495
+ first_row.upto(last_row) do |i|
496
+ # are all conditions met?
497
+ found = 1
498
+ conditions.each { |key,val|
499
+ if cell(i,column_with[key]) == val
500
+ found *= 1
501
+ else
502
+ found *= 0
503
+ end
504
+ }
505
+ # p self.row(i) if found > 0
506
+ if found > 0
507
+ tmp = {}
508
+ 1.upto(self.row(i).size) {|j|
509
+ x = ''
510
+ column_with.each { |key,val|
511
+ if val == j
512
+ x = key
513
+ end
514
+ }
515
+ tmp[x] = cell(i,j)
516
+ }
517
+ if result_array
518
+ result << self.row(i)
519
+ else
520
+ result << tmp
521
+ end
522
+ end
523
+ end
524
+ end # :conditions
525
+ }
163
526
  end
164
-
165
527
  end
166
- # @cell["1,2"] = 42
167
- # @cell_type["1,2"] = "string"
168
- # @cells_read = true
169
- # return
528
+ result
529
+ end
530
+ private
531
+
532
+ # def read_cells_old(sheet=nil) #TODO:
533
+ # sheet = @default_sheet unless sheet
534
+ # sheet_found = true # TODO:
535
+ # #TODO: raise ArgumentError falls sheet nicht existiert - siehe openoffice
536
+ # #TODO: boundaries !!!
537
+ # 1.upto(25) { |y|
538
+ # 1.upto(20) { |x|
539
+ # key = "#{y},#{x}"
540
+ # @cell[sheet] = {} unless @cell[sheet]
541
+ # value = cell(y,x,sheet)
542
+ # @cell[sheet][key] = value unless value == "" or value == nil
543
+ # }
544
+ # }
545
+ # if !sheet_found
546
+ # raise RangeErrror, "invalid sheet name"
547
+ # end
548
+ # @cells_read[sheet] = true
549
+ # end
170
550
 
171
- #TODO: die Grenzen sind noch fix
172
- 1.upto(10) do |y|
173
- Openoffice.letter_to_number('A').upto(Openoffice.letter_to_number('H')) do |x|
174
- # p x.to_s+", "+y.to_s
175
- # unless empty?(y,x)
176
- # @cell["#{y},#{x}"] = cell(y,x)
177
- # @cell_type["#{y},#{x}"] = cell(y,x)
178
- # end
551
+ # read all cells in a sheet
552
+ def read_cells(sheet=nil)
553
+ sheet = @default_sheet unless sheet
554
+ # sheet_no = sheets.index(sheet) + 1
555
+ # @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
556
+ #@first_row[sheet].upto(@last_row[sheet]) { |y|
557
+ # @first_column[sheet].upto(@last_column[sheet]) { |x|
558
+ # key = "#{y},#{x}"
559
+ # @cell[sheet] = {} unless @cell[sheet]
560
+ # value = cell(y,x,sheet)
561
+ # @cell[sheet][key] = value unless value == "" or value == nil
562
+ # }
563
+ #}
564
+ sheet_no = sheets.index(sheet)+1
565
+ doc = @gs.fulldoc(sheet_no)
566
+ (doc/"gs:cell").each {|item|
567
+ row = item['row']
568
+ col = item['col']
569
+ value = item['inputvalue']
570
+ numericvalue = item['numericvalue']
571
+ # puts numericvalue
572
+ # puts value
573
+ # puts value[0,1]
574
+ if value[0,1] == '='
575
+ formula = value
576
+ # $log.debug("formula: <#{formula}>")
577
+ # puts "Formel gefunden"
578
+ else
579
+ formula = nil
580
+ end
581
+ # puts formula
582
+ #--
583
+ @cell_type[sheet] = {} unless @cell_type[sheet]
584
+ if formula
585
+ ty = :formula
586
+ if numeric?(numericvalue)
587
+ value = numericvalue.to_f
588
+ else
589
+ value = numericvalue
590
+ end
591
+ elsif Google.date?(value)
592
+ ty = :date
593
+ elsif numeric?(value) # or o.class ???
594
+ ty = :float
595
+ value = value.to_f
596
+ else
597
+ ty = :string
598
+ end
599
+ key = "#{row},#{col}"
600
+ @cell[sheet] = {} unless @cell[sheet]
601
+ if ty == :date
602
+ dd,mm,yyyy = value.split('/')
603
+ @cell[sheet][key] = sprintf("%04d-%02d-%02d",yyyy.to_i,mm.to_i,dd.to_i)
604
+ else
605
+ @cell[sheet][key] = value unless value == "" or value == nil
179
606
  end
180
- end
181
- @cells_read = true
607
+ @cell_type[sheet][key] = ty # Openoffice.oo_type_2_roo_type(vt)
608
+ @formula[sheet] = {} unless @formula[sheet]
609
+ # $log.debug("formula vor belegen @formula: <#{formula}>") if formula
610
+ @formula[sheet][key] = formula if formula
611
+ # $log.debug("@formula[#{sheet}][#{key}] = #{formula}") if formula
612
+ # $log.debug("#{@formula[sheet][key]}") if formula
613
+
614
+
615
+ }
616
+ @cells_read[sheet] = true
617
+ end
618
+
619
+ # Checks if the default_sheet exists. Otherwise a RangeError exception is
620
+ # raised
621
+ def check_default_sheet
622
+ sheet_found = false
623
+ raise ArgumentError, "Error: default_sheet not set" if @default_sheet == nil
624
+ if sheets.index(@default_sheet)
625
+ sheet_found = true
626
+ end
627
+ if ! sheet_found
628
+ raise RangeError, "sheet '#{@default_sheet}' not found"
629
+ end
182
630
  end
183
631
 
184
- def first_row
185
- read_cells unless @cells_read
186
- 1
632
+ def numeric?(string)
633
+ string =~ /^[0-9]+[\.]*[0-9]*$/
187
634
  end
188
635
 
189
- def last_row
190
- read_cells unless @cells_read
191
- 100
636
+ # convert string DD/MM/YYYY into a Date-object
637
+ #TODO: was ist mit verschiedenen Typen der Datumseingabe bei Google?
638
+ def Google.to_date(string)
639
+ if string.strip =~ /^([0-9]+)\/([0-9]+)\/([0-9]+)$/
640
+ return Date.new($3.to_i,$2.to_i,$1.to_i)
641
+ else
642
+ return nil
643
+ end
644
+ end
645
+
646
+ #TODO: refactoring to GenericSpreadsheet?
647
+ def write_csv_content(file=nil,sheet=nil)
648
+ file = STDOUT unless file
649
+ if first_row # sheet is not empty
650
+ first_row(sheet).upto(last_row(sheet)) do |row|
651
+ 1.upto(last_column(sheet)) do |col|
652
+ file.print(",") if col > 1
653
+ onecell = cell(row,col,sheet)
654
+ onecelltype = celltype(row,col,sheet)
655
+ file.print one_cell_output(onecelltype,onecell,empty?(row,col,sheet))
656
+ end
657
+ file.print("\n")
658
+ end # sheet not empty
659
+ end
660
+ end
661
+
662
+ #TODO: refactor to Generic....
663
+ def one_cell_output(onecelltype,onecell,empty)
664
+ str = ""
665
+ if empty
666
+ str += ''
667
+ else
668
+ case onecelltype
669
+ when :string
670
+ if onecell == ""
671
+ str << ''
672
+ else
673
+ onecell.gsub!(/"/,'""')
674
+ str << ('"'+onecell+'"')
675
+ end
676
+ when :float,:percentage
677
+ if onecell == onecell.to_i
678
+ str << onecell.to_i.to_s
679
+ else
680
+ str << onecell.to_s
681
+ end
682
+ when :formula
683
+ if onecell.class == String
684
+ if onecell == ""
685
+ str << ''
686
+ else
687
+ onecell.gsub!(/"/,'""')
688
+ str << '"'+onecell+'"'
689
+ end
690
+ elsif onecell.class == Float
691
+ if onecell == onecell.to_i
692
+ str << onecell.to_i.to_s
693
+ else
694
+ str << onecell.to_s
695
+ end
696
+ else
697
+ raise "unhandled onecell-class "+onecell.class.to_s
698
+ end
699
+ when :date
700
+ str << '"'+onecell.to_s+'"'
701
+ else
702
+ raise "unhandled celltype "+onecelltype.to_s
703
+ end
704
+ end
705
+ #cells << onecell
706
+ str
192
707
  end
193
708
 
194
709
  end # class