knjrbfw 0.0.7 → 0.0.8

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.
Files changed (65) hide show
  1. data/Gemfile +3 -1
  2. data/VERSION +1 -1
  3. data/knjrbfw.gemspec +14 -4
  4. data/lib/knj/amixer.rb +148 -0
  5. data/lib/knj/arrayext.rb +14 -5
  6. data/lib/knj/autoload.rb +63 -57
  7. data/lib/knj/autoload/backups/facets_dictionary.rb +2 -2
  8. data/lib/knj/autoload/erubis.rb +2 -0
  9. data/lib/knj/cmd_gen.rb +71 -0
  10. data/lib/knj/compiler.rb +2 -2
  11. data/lib/knj/datarow.rb +138 -38
  12. data/lib/knj/datestamp.rb +2 -2
  13. data/lib/knj/datet.rb +72 -17
  14. data/lib/knj/erb/include.rb +5 -5
  15. data/lib/knj/errors.rb +4 -1
  16. data/lib/knj/eruby.rb +25 -11
  17. data/lib/knj/event_filemod.rb +27 -26
  18. data/lib/knj/event_handler.rb +8 -8
  19. data/lib/knj/exchangerates.rb +1 -1
  20. data/lib/knj/facebook_connect.rb +37 -0
  21. data/lib/knj/gettext_threadded.rb +4 -3
  22. data/lib/knj/google_sitemap.rb +1 -1
  23. data/lib/knj/hash_methods.rb +1 -1
  24. data/lib/knj/http.rb +35 -19
  25. data/lib/knj/http2.rb +249 -0
  26. data/lib/knj/image.rb +128 -0
  27. data/lib/knj/jruby-gtk2/gtk2.rb +1 -1
  28. data/lib/knj/knj.rb +1 -1
  29. data/lib/knj/knj_controller.rb +0 -2
  30. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +3 -3
  31. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +11 -11
  32. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +2 -2
  33. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +71 -14
  34. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +17 -14
  35. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +5 -5
  36. data/lib/knj/knjdb/libknjdb.rb +33 -16
  37. data/lib/knj/knjdb/libknjdb_row.rb +8 -8
  38. data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +1 -1
  39. data/lib/knj/mount.rb +6 -6
  40. data/lib/knj/mutexcl.rb +2 -2
  41. data/lib/knj/objects.rb +286 -73
  42. data/lib/knj/opts.rb +11 -4
  43. data/lib/knj/os.rb +16 -3
  44. data/lib/knj/php.rb +73 -26
  45. data/lib/knj/php_parser/php_parser.rb +1 -77
  46. data/lib/knj/retry.rb +4 -4
  47. data/lib/knj/rhodes/rhodes.rb +106 -0
  48. data/lib/knj/sshrobot/sshrobot.rb +1 -1
  49. data/lib/knj/strings.rb +72 -0
  50. data/lib/knj/sysuser.rb +1 -1
  51. data/lib/knj/tests/test_http2.rb +18 -0
  52. data/lib/knj/thread.rb +1 -5
  53. data/lib/knj/thread2.rb +3 -3
  54. data/lib/knj/threadhandler.rb +2 -2
  55. data/lib/knj/threadpool.rb +4 -4
  56. data/lib/knj/translations.rb +2 -17
  57. data/lib/knj/unix_proc.rb +3 -3
  58. data/lib/knj/web.rb +156 -77
  59. data/lib/knj/webscripts/image.rhtml +22 -3
  60. data/lib/knj/x11vnc.rb +3 -3
  61. data/spec/amixer_spec.rb +27 -0
  62. data/spec/knjrbfw_spec.rb +70 -12
  63. data/testfiles/image.jpg +0 -0
  64. metadata +32 -14
  65. data/Gemfile.lock +0 -32
@@ -1,3 +1,5 @@
1
+ module Erubis; end #bugfix
2
+
1
3
  begin
2
4
  require "erubis"
3
5
  rescue LoadError
@@ -0,0 +1,71 @@
1
+ class Knj::Cmd_gen
2
+ def self.rsync(args)
3
+ cmd = ""
4
+
5
+ if args[:bin]
6
+ cmd += args[:bin]
7
+ else
8
+ cmd += "rsync"
9
+ end
10
+
11
+ cmd += " -az"
12
+
13
+ if args[:verbose]
14
+ 1.upto(args[:verbose]) do
15
+ cmd += "v"
16
+ end
17
+ end
18
+
19
+ if args[:ssh]
20
+ cmd += " -e ssh"
21
+
22
+ if args[:port]
23
+ cmd += " --rsh='ssh -p #{args[:port]}'"
24
+ end
25
+ end
26
+
27
+ if args[:delete]
28
+ cmd += " --delete"
29
+ end
30
+
31
+ if args[:exclude]
32
+ args[:exclude].each do |dir|
33
+ cmd += " --exclude \"#{dir}\""
34
+ end
35
+ end
36
+
37
+ cmd += " \"#{args[:user]}@#{args[:host]}:#{args[:dir_host]}\" \"#{args[:dir_local]}\""
38
+
39
+ return cmd
40
+ end
41
+
42
+ def self.tar(args)
43
+ cmd = ""
44
+
45
+ if args[:bin]
46
+ cmd += args[:bin]
47
+ else
48
+ cmd += "tar"
49
+ end
50
+
51
+ cmd += " "
52
+ cmd += "z"if args[:gzip]
53
+ cmd += "x" if args[:extract]
54
+ cmd += "f" if args[:file]
55
+ cmd += "c" if args[:create]
56
+
57
+ if args[:verbose]
58
+ 1.upto(args[:verbose]) do
59
+ cmd += "v"
60
+ end
61
+ end
62
+
63
+ cmd += " \"#{args[:archive_path]}\""
64
+
65
+ args[:paths].each do |path|
66
+ cmd += " \"#{path}\""
67
+ end
68
+
69
+ return cmd
70
+ end
71
+ end
@@ -32,9 +32,9 @@ class Knj::Compiler
32
32
  #Compile and evaluate a file - it will be cached.
33
33
  def eval_file(args)
34
34
  #Compile if it hasnt been compiled yet.
35
- if !@compiled.has_key?(args[:filepath])
35
+ if !@compiled.key?(args[:filepath])
36
36
  @mutex.synchronize do
37
- compile_file(args) if !@compiled.has_key?(args[:filepath])
37
+ compile_file(args) if !@compiled.key?(args[:filepath])
38
38
  end
39
39
  end
40
40
 
@@ -1,5 +1,5 @@
1
1
  class Knj::Datarow
2
- attr_reader :data, :ob
2
+ attr_reader :data, :ob, :db
3
3
 
4
4
  def self.required_data
5
5
  @required_data = [] if !@required_data
@@ -10,7 +10,7 @@ class Knj::Datarow
10
10
  @depending_data = [] if !@depending_data
11
11
  return @depending_data
12
12
  end
13
-
13
+
14
14
  def is_knj?; return true; end
15
15
 
16
16
  def self.is_nullstamp?(stamp)
@@ -37,18 +37,41 @@ class Knj::Datarow
37
37
  raise "Unknown argument: '#{val.class.name}'."
38
38
  end
39
39
 
40
+ if val.is_a?(Hash) and val.key?(:where)
41
+ where_args = val[:where]
42
+ else
43
+ where_args = {}
44
+ end
45
+
46
+ raise "No classname given." if !classname
40
47
  methodname = "#{classname.to_s.downcase}s".to_sym if !methodname
41
48
 
42
- define_method(methodname) do |*args|
49
+ define_method(methodname) do |*args, &block|
43
50
  merge_args = args[0] if args and args[0]
44
51
  merge_args = {} if !merge_args
45
- return ob.list(classname, {colname.to_s => self.id}.merge(merge_args))
52
+
53
+ all_args = []
54
+ all_args << block if block
55
+
56
+ if block
57
+ @ob.list(classname, merge_args.merge(colname.to_s => self.id)) do |obj|
58
+ block.call(obj)
59
+ end
60
+ else
61
+ return @ob.list(classname, merge_args.merge(colname.to_s => self.id))
62
+ end
46
63
  end
47
64
 
48
65
  define_method("#{methodname}_count".to_sym) do |*args|
49
66
  merge_args = args[0] if args and args[0]
50
67
  merge_args = {} if !merge_args
51
- return ob.list(classname, {"count" => true, colname.to_s => self.id}.merge(merge_args))
68
+
69
+ return @ob.list(classname, merge_args.merge(colname.to_s => self.id, "count" => true))
70
+ end
71
+
72
+ define_method("#{methodname}_last".to_sym) do |args|
73
+ args = {} if !args
74
+ return @ob.list(classname, {"orderby" => [["id", "desc"]], "limit" => 1}.merge(args))
52
75
  end
53
76
  end
54
77
  end
@@ -83,13 +106,13 @@ class Knj::Datarow
83
106
  colname = "#{classname.to_s.downcase}_id".to_sym if !colname
84
107
 
85
108
  define_method(methodname) do
86
- return ob.get_try(self, colname, classname)
109
+ return @ob.get_try(self, colname, classname)
87
110
  end
88
111
 
89
112
  methodname_html = "#{methodname.to_s}_html".to_sym
90
113
  define_method(methodname_html) do |*args|
91
114
  obj = self.send(methodname)
92
- return ob.events.call(:no_html, classname) if !obj
115
+ return @ob.events.call(:no_html, classname) if !obj
93
116
 
94
117
  raise "Class '#{classname}' does not have a 'html'-method." if !obj.respond_to?(:html)
95
118
  return obj.html(*args)
@@ -97,6 +120,10 @@ class Knj::Datarow
97
120
  end
98
121
  end
99
122
 
123
+ def self.joined_tables(hash)
124
+ @columns_joined_tables = hash
125
+ end
126
+
100
127
  def self.table
101
128
  return self.name.split("::").last
102
129
  end
@@ -108,6 +135,7 @@ class Knj::Datarow
108
135
 
109
136
  def self.columns_load(d)
110
137
  return nil if @columns
138
+ @ob = d.ob
111
139
  @columns = d.db.tables[table].columns
112
140
  end
113
141
 
@@ -116,39 +144,60 @@ class Knj::Datarow
116
144
  end
117
145
 
118
146
  def self.list(d)
147
+ ec_col = d.db.enc_col
148
+ ec_table = d.db.enc_table
149
+
150
+ table_str = "#{ec_table}#{d.db.esc_table(self.table)}#{ec_table}"
151
+
119
152
  if d.args["count"]
120
153
  count = true
121
154
  d.args.delete("count")
122
- sql = "SELECT COUNT(*) AS count"
155
+ sql = "SELECT COUNT(#{table_str}.#{ec_col}id#{ec_col}) AS count"
123
156
  else
124
- sql = "SELECT *"
157
+ sql = "SELECT #{table_str}.*"
125
158
  end
126
159
 
127
- sql += " FROM #{d.db.enc_table}#{table}#{d.db.enc_table} WHERE 1=1"
160
+ ret = self.list_helper(d)
161
+
162
+ sql += " FROM #{table_str}"
163
+ sql += ret[:sql_joins]
164
+ sql += " WHERE 1=1"
128
165
 
129
- ret = list_helper(d)
130
166
  d.args.each do |key, val|
131
- raise "Invalid key: '#{key}'."
167
+ case key
168
+ when "return_sql"
169
+ #ignore
170
+ else
171
+ raise "Invalid key: '#{key}'."
172
+ end
132
173
  end
133
174
 
134
175
  sql += ret[:sql_where]
176
+
177
+ #The count will bug if there is a group-by-statement.
178
+ if !count
179
+ sql += " GROUP BY #{table_str}.#{ec_col}id#{ec_col}"
180
+ end
181
+
135
182
  sql += ret[:sql_order]
136
183
  sql += ret[:sql_limit]
137
184
 
138
- return d.db.query(sql).fetch[:count].to_i if count
139
- return d.ob.list_bysql(table, sql)
185
+ return sql.to_s if d.args["return_sql"]
186
+
187
+ if count
188
+ ret = d.db.query(sql).fetch
189
+ return ret[:count].to_i if ret
190
+ return 0
191
+ end
192
+
193
+ return d.ob.list_bysql(self.table, sql)
140
194
  end
141
195
 
142
196
  def self.load_columns(d)
143
- if @columns_sqlhelper_args_working
144
- sleep 0.1 while @columns_sqlhelper_args_working
145
- return false
146
- end
197
+ @mutex = Mutex.new if !@mutex
147
198
 
148
- begin
149
- @columns_sqlhelper_args_working = true
199
+ @mutex.synchronize do
150
200
  cols = self.columns(d)
151
-
152
201
  inst_methods = instance_methods(false)
153
202
 
154
203
  sqlhelper_args = {
@@ -158,11 +207,13 @@ class Knj::Datarow
158
207
  :cols_date => [],
159
208
  :cols_dbrows => [],
160
209
  :cols_num => [],
161
- :cols_str => []
210
+ :cols_str => [],
211
+ :cols => {}
162
212
  }
163
213
  cols.each do |col_name, col_obj|
164
214
  col_type = col_obj.type
165
215
  col_type = "int" if col_type == "bigint" or col_type == "tinyint" or col_type == "mediumint" or col_type == "smallint"
216
+ sqlhelper_args[:cols][col_name] = true
166
217
 
167
218
  if col_type == "enum" and col_obj.maxlength == "'0','1'"
168
219
  sqlhelper_args[:cols_bools] << col_name
@@ -187,23 +238,70 @@ class Knj::Datarow
187
238
  if !inst_methods.index(method_name)
188
239
  define_method(method_name) do |*args|
189
240
  if Knj::Datet.is_nullstamp?(self[col_name.to_sym])
190
- return ob.events.call(:no_date, self.class.name)
241
+ return @ob.events.call(:no_date, self.class.name)
191
242
  end
192
243
 
193
244
  return Knj::Datet.in(self[col_name.to_sym]).out(*args)
194
245
  end
195
246
  end
247
+
248
+ method_name = "#{col_name}".to_sym
249
+ if !inst_methods.index(method_name)
250
+ define_method(method_name) do |*args|
251
+ return false if Knj::Datet.is_nullstamp?(self[col_name.to_sym])
252
+ return Knj::Datet.in(self[col_name.to_sym])
253
+ end
254
+ end
255
+ end
256
+
257
+ if col_type == "int" or col_type == "decimal"
258
+ method_name = "#{col_name}_format"
259
+ if inst_methods.index(method_name) == nil
260
+ define_method(method_name) do |*args|
261
+ return Knj::Locales.number_out(self[col_name.to_sym], *args)
262
+ end
263
+ end
196
264
  end
265
+
266
+ if col_type == "int" or col_type == "varchar"
267
+ method_name = "by_#{col_name}".to_sym
268
+ if !inst_methods.index(method_name) and RUBY_VERSION.to_s.slice(0, 3) != "1.8"
269
+ define_singleton_method(method_name) do |arg|
270
+ return d.ob.get_by(self.table, {col_name.to_s => arg})
271
+ end
272
+ end
273
+ end
274
+
275
+ if col_type == "time"
276
+ method_name = "#{col_name}_dbt"
277
+ if !inst_methods.index(method_name)
278
+ define_method(method_name) do
279
+ return Knj::Db::Dbtime.new(self[col_name.to_sym])
280
+ end
281
+ end
282
+ end
283
+ end
284
+
285
+ if @columns_joined_tables
286
+ @columns_joined_tables.each do |table_name, table_data|
287
+ table_data[:where].each do |key, val|
288
+ val[:table] = self.table.to_sym if val.is_a?(Hash) and !val.key?(:table) and val[:type] == "col"
289
+ end
290
+
291
+ table_data[:datarow] = @ob.args[:module].const_get(table_name.to_sym) if !table_data.key?(:datarow)
292
+ end
293
+
294
+ sqlhelper_args[:joined_tables] = @columns_joined_tables
197
295
  end
198
296
 
199
297
  @columns_sqlhelper_args = sqlhelper_args
200
- ensure
201
- @columns_sqlhelper_args_working = false
202
298
  end
299
+
300
+ self.init_class(d) if self.respond_to?(:init_class)
203
301
  end
204
302
 
205
303
  def self.list_helper(d)
206
- load_columns(d) if !@columns_sqlhelper_args
304
+ self.load_columns(d) if !@columns_sqlhelper_args
207
305
  return d.ob.sqlhelper(d.args, @columns_sqlhelper_args)
208
306
  end
209
307
 
@@ -213,6 +311,7 @@ class Knj::Datarow
213
311
 
214
312
  def initialize(d)
215
313
  @ob = d.ob
314
+ @db = d.ob.db
216
315
  raise "No ob given." if !@ob
217
316
 
218
317
  if d.data.is_a?(Hash)
@@ -225,12 +324,8 @@ class Knj::Datarow
225
324
  end
226
325
  end
227
326
 
228
- def db
229
- return @ob.db
230
- end
231
-
232
327
  def reload
233
- data = self.db.single(self.table, {:id => @data[:id]})
328
+ data = @db.single(self.table, {:id => @data[:id]})
234
329
  if !data
235
330
  raise Knj::Errors::NotFound, "Could not find any data for the object with ID: '#{@data[:id]}' in the table '#{self.table}'."
236
331
  end
@@ -239,27 +334,32 @@ class Knj::Datarow
239
334
  end
240
335
 
241
336
  def update(newdata)
242
- self.db.update(self.table, newdata, {:id => @data[:id]})
337
+ @db.update(self.table, newdata, {:id => @data[:id]})
243
338
  self.reload
244
339
 
245
- if self.ob
246
- self.ob.call("object" => self, "signal" => "update")
340
+ if @ob
341
+ @ob.call("object" => self, "signal" => "update")
247
342
  end
248
343
  end
249
344
 
250
345
  def destroy
251
346
  @ob = nil
347
+ @db = nil
252
348
  @data = nil
253
349
  end
254
350
 
255
351
  def has_key?(key)
256
- return @data.has_key?(key.to_sym)
352
+ return @data.key?(key.to_sym)
353
+ end
354
+
355
+ def key?(key)
356
+ return @data.key?(key.to_sym)
257
357
  end
258
358
 
259
359
  def [](key)
260
360
  raise "No valid key given." if !key.is_a?(Symbol)
261
361
  raise "No data was loaded on the object? Maybe you are trying to call a deleted object?" if !@data
262
- return @data[key] if @data.has_key?(key)
362
+ return @data[key] if @data.key?(key)
263
363
  raise "No such key: #{key}."
264
364
  end
265
365
 
@@ -274,9 +374,9 @@ class Knj::Datarow
274
374
  end
275
375
 
276
376
  def name
277
- if @data.has_key?(:title)
377
+ if @data.key?(:title)
278
378
  return @data[:title]
279
- elsif @data.has_key?(:name)
379
+ elsif @data.key?(:name)
280
380
  return @data[:name]
281
381
  end
282
382
 
@@ -50,11 +50,11 @@ class Knj::Datestamp
50
50
 
51
51
  str = ""
52
52
 
53
- if !args.has_key?(:date) or args[:date] == true
53
+ if !args.key?(:date) or args[:date] == true
54
54
  str += "%02d" % time.day.to_s + "/" + "%02d" % time.month.to_s + " " + "%04d" % time.year.to_s
55
55
  end
56
56
 
57
- if !args.has_key?(:time) or args[:time] == true
57
+ if !args.key?(:time) or args[:time] == true
58
58
  str += " " + "%02d" % time.hour.to_s + ":" + "%02d" % time.min.to_s
59
59
  end
60
60
 
@@ -1,3 +1,5 @@
1
+ require "time"
2
+
1
3
  class Knj::Datet
2
4
  attr_accessor :time
3
5
 
@@ -126,6 +128,8 @@ class Knj::Datet
126
128
 
127
129
  #Returns the number of days in the current month.
128
130
  def days_in_month
131
+ return 29 if month == 2 and Date.gregorian_leap?(self.year)
132
+
129
133
  #Thanks to ActiveSupport: http://rubydoc.info/docs/rails/2.3.8/ActiveSupport/CoreExtensions/Time/Calculations
130
134
  days_in_months = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
131
135
  return days_in_months[@time.month]
@@ -245,9 +249,9 @@ class Knj::Datet
245
249
  secs = arg_to_time(timeobj).to_i
246
250
 
247
251
  if secs > @time.to_i
248
- return 1
249
- elsif secs < @time.to_i
250
252
  return -1
253
+ elsif secs < @time.to_i
254
+ return 1
251
255
  else
252
256
  return 0
253
257
  end
@@ -299,17 +303,23 @@ class Knj::Datet
299
303
  vars[key.to_sym] = value.to_i if key != :datet
300
304
  end
301
305
 
302
- time = Time.gm(vars[:year], vars[:month], vars[:day], vars[:hour], vars[:min], vars[:sec])
306
+ time = Time.local(vars[:year], vars[:month], vars[:day], vars[:hour], vars[:min], vars[:sec])
303
307
 
304
- if !args.has_key?(:datet) or args[:datet]
308
+ if !args.key?(:datet) or args[:datet]
305
309
  return Knj::Datet.new(time)
306
310
  end
307
311
 
308
312
  return time
309
313
  end
310
314
 
311
- def dbstr
312
- return "%04d" % @time.year.to_s + "-" + "%02d" % @time.month.to_s + "-" + "%02d" % @time.day.to_s + " " + "%02d" % @time.hour.to_s + ":" + "%02d" % @time.min.to_s + ":" + "%02d" % @time.sec.to_s
315
+ def dbstr(args = {})
316
+ str = "%04d" % @time.year.to_s + "-" + "%02d" % @time.month.to_s + "-" + "%02d" % @time.day.to_s
317
+
318
+ if !args.key?(:time) or args[:time]
319
+ str += " " + "%02d" % @time.hour.to_s + ":" + "%02d" % @time.min.to_s + ":" + "%02d" % @time.sec.to_s
320
+ end
321
+
322
+ return str
313
323
  end
314
324
 
315
325
  def self.from_dbstr(date_string)
@@ -337,16 +347,16 @@ class Knj::Datet
337
347
  date_shown = false
338
348
  time_shown = false
339
349
 
340
- if !args.has_key?(:date) or args[:date]
350
+ if !args.key?(:date) or args[:date]
341
351
  date_shown = true
342
352
  str += "%02d" % @time.day.to_s + "/" + "%02d" % @time.month.to_s
343
353
 
344
- if !args.has_key?(:year) or args[:year]
354
+ if !args.key?(:year) or args[:year]
345
355
  str += " " + "%04d" % @time.year.to_s
346
356
  end
347
357
  end
348
358
 
349
- if !args.has_key?(:time) or args[:time]
359
+ if !args.key?(:time) or args[:time]
350
360
  time_shown = true
351
361
  str += " - " if date_shown
352
362
  str += "%02d" % @time.hour.to_s + ":" + "%02d" % @time.min.to_s
@@ -380,24 +390,31 @@ class Knj::Datet
380
390
  minute = match[2]
381
391
  end
382
392
 
383
- return Knj::Datet.new(Time.gm(year, month, date, hour, minute))
393
+ return Knj::Datet.new(Time.local(year, month, date, hour, minute))
384
394
  elsif match = timestr.to_s.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/)
385
- return Knj::Datet.new(Time.gm(match[3], match[2], match[1]))
386
- elsif match = timestr.to_s.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{5})$/)
395
+ return Knj::Datet.new(Time.local(match[3], match[2], match[1]))
396
+ elsif match = timestr.to_s.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{5,6})$/)
387
397
  #Datet.code format
388
- return Knj::Datet.new(Time.gm(match[1], match[2], match[3], match[4], match[5], match[6], match[7]))
398
+ return Knj::Datet.new(Time.local(match[1], match[2], match[3], match[4], match[5], match[6], match[7]))
389
399
  elsif match = timestr.to_s.match(/^\s*(\d{4})-(\d{1,2})-(\d{1,2})(|\s+(\d{2}):(\d{2}):(\d{2})(|\.\d+)\s*)(|\s+(UTC))(|\s+(\+|\-)(\d{2})(\d{2}))$/)
390
400
  #Database date format (with possibility of .0 in the end - miliseconds? -knj.
391
401
 
392
- if match[11]
393
- utc_str = "+#{match[13]}:#{match[14]}"
402
+ if match[11] and match[13] and match[14]
403
+ if match[12] == "+" or match[12] == "-"
404
+ sign = match[12]
405
+ else
406
+ sign = "+"
407
+ end
408
+
409
+ utc_str = "#{sign}#{match[13]}:#{match[14]}"
394
410
  elsif match[8]
395
411
  utc_str = match[8].to_i
396
412
  else
397
413
  utc_str = nil
398
414
  end
399
-
400
- return Knj::Datet.new(Time.gm(match[1].to_i, match[2].to_i, match[3].to_i, match[5].to_i, match[6].to_i, match[7].to_i,utc_str))
415
+
416
+ time = Time.local(match[1].to_i, match[2].to_i, match[3].to_i, match[5].to_i, match[6].to_i, match[7].to_i, utc_str)
417
+ return Knj::Datet.new(time)
401
418
  end
402
419
 
403
420
  raise Knj::Errors::InvalidData.new("Wrong format: '#{timestr}', class: '#{timestr.class.name}'")
@@ -457,4 +474,42 @@ class Knj::Datet
457
474
  end
458
475
 
459
476
  alias :to_i :unixt
477
+
478
+ def httpdate
479
+ require "time"
480
+ return @time.httpdate
481
+ end
482
+
483
+ def offset_info
484
+ offset_secs = @time.gmt_offset
485
+
486
+ offset_hours = (offset_secs.to_f / 3600.0).floor
487
+ offset_secs -= offset_hours * 3600
488
+
489
+ offset_minutes = (offset_secs.to_f / 60.0).floor
490
+ offset_secs -= offset_minutes * 60
491
+
492
+ if offset_hours > 0
493
+ sign = "+"
494
+ else
495
+ sign = ""
496
+ end
497
+
498
+ return {
499
+ :sign => sign,
500
+ :hours => offset_hours,
501
+ :mins => offset_minutes,
502
+ :secs => offset_secs
503
+ }
504
+ end
505
+
506
+ def offset_str
507
+ offset_info_data = self.offset_info
508
+ return "#{offset_info_data[:sign]}#{"%02d" % offset_info_data[:hours]}#{"%02d" % offset_info_data[:mins]}"
509
+ end
510
+
511
+ #Returns 'localtime' as of 1.9 - even in 1.8 which does it different.
512
+ def localtime_str
513
+ return "#{"%04d" % @time.year}-#{"%02d" % @time.month}-#{"%02d" % @time.day} #{"%02d" % @time.hour}:#{"%02d" % @time.min}:#{"%02d" % @time.sec} #{self.offset_str}"
514
+ end
460
515
  end