openall_time_applet 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +9 -5
- data/VERSION +1 -1
- data/conf/db_schema.rb +3 -1
- data/glade/win_main.glade +43 -117
- data/gui/trayicon.rb +3 -3
- data/gui/win_main.rb +15 -15
- data/lib/openall_time_applet.rb +29 -25
- data/models/timelog.rb +23 -4
- data/models/timelog_logged_time.rb +1 -1
- data/openall_time_applet.gemspec +2 -2
- data/spec/openall_time_applet_spec.rb +41 -1
- metadata +3 -3
data/Gemfile.lock
CHANGED
@@ -3,12 +3,12 @@ GEM
|
|
3
3
|
specs:
|
4
4
|
atk (1.1.3)
|
5
5
|
glib2 (>= 1.1.3)
|
6
|
-
cairo (1.12.
|
6
|
+
cairo (1.12.2)
|
7
7
|
pkg-config
|
8
8
|
diff-lcs (1.1.3)
|
9
9
|
gdk_pixbuf2 (1.1.3)
|
10
10
|
glib2 (>= 1.1.3)
|
11
|
-
gettext (2.2.
|
11
|
+
gettext (2.2.1)
|
12
12
|
locale
|
13
13
|
git (1.2.5)
|
14
14
|
glib2 (1.1.3)
|
@@ -17,13 +17,15 @@ GEM
|
|
17
17
|
atk (>= 1.1.3)
|
18
18
|
gdk_pixbuf2 (>= 1.1.3)
|
19
19
|
pango (>= 1.1.3)
|
20
|
-
jeweler (1.8.
|
20
|
+
jeweler (1.8.4)
|
21
21
|
bundler (~> 1.0)
|
22
22
|
git (>= 1.2.5)
|
23
23
|
rake
|
24
24
|
rdoc
|
25
|
-
json (1.7.
|
26
|
-
knjrbfw (0.0.
|
25
|
+
json (1.7.3)
|
26
|
+
knjrbfw (0.0.55)
|
27
|
+
tsafe
|
28
|
+
wref
|
27
29
|
locale (2.0.5)
|
28
30
|
pango (1.1.3)
|
29
31
|
cairo (>= 1.10.0)
|
@@ -43,6 +45,8 @@ GEM
|
|
43
45
|
diff-lcs (~> 1.1.2)
|
44
46
|
rspec-mocks (2.8.0)
|
45
47
|
sqlite3 (1.3.6)
|
48
|
+
tsafe (0.0.1)
|
49
|
+
wref (0.0.4)
|
46
50
|
|
47
51
|
PLATFORMS
|
48
52
|
ruby
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.19
|
data/conf/db_schema.rb
CHANGED
@@ -33,6 +33,7 @@ Openall_time_applet::DB_SCHEMA = {
|
|
33
33
|
"columns" => [
|
34
34
|
{"name" => "id", "type" => "int", "autoincr" => true, "primarykey" => true},
|
35
35
|
{"name" => "task_id", "type" => "int"},
|
36
|
+
{"name" => "parent_timelog_id", "type" => "int", "null" => false},
|
36
37
|
{"name" => "timestamp", "type" => "datetime"},
|
37
38
|
{"name" => "time", "type" => "int"},
|
38
39
|
{"name" => "time_sync", "type" => "varchar"},
|
@@ -48,7 +49,8 @@ Openall_time_applet::DB_SCHEMA = {
|
|
48
49
|
{"name" => "sync_last", "type" => "datetime"}
|
49
50
|
],
|
50
51
|
"indexes" => [
|
51
|
-
"task_id"
|
52
|
+
"task_id",
|
53
|
+
"parent_timelog_id"
|
52
54
|
]
|
53
55
|
},
|
54
56
|
"Timelog_logged_time" => {
|
data/glade/win_main.glade
CHANGED
@@ -145,6 +145,47 @@
|
|
145
145
|
<property name="position">1</property>
|
146
146
|
</packing>
|
147
147
|
</child>
|
148
|
+
<child>
|
149
|
+
<object class="GtkTable" id="tableRunning">
|
150
|
+
<property name="visible">True</property>
|
151
|
+
<property name="can_focus">False</property>
|
152
|
+
<property name="n_columns">3</property>
|
153
|
+
<child>
|
154
|
+
<object class="GtkLabel" id="labRunningTimelog">
|
155
|
+
<property name="visible">True</property>
|
156
|
+
<property name="can_focus">False</property>
|
157
|
+
<property name="xalign">0</property>
|
158
|
+
</object>
|
159
|
+
</child>
|
160
|
+
<child>
|
161
|
+
<object class="GtkLabel" id="labRunningTask">
|
162
|
+
<property name="visible">True</property>
|
163
|
+
<property name="can_focus">False</property>
|
164
|
+
<property name="xalign">0</property>
|
165
|
+
</object>
|
166
|
+
<packing>
|
167
|
+
<property name="left_attach">1</property>
|
168
|
+
<property name="right_attach">2</property>
|
169
|
+
</packing>
|
170
|
+
</child>
|
171
|
+
<child>
|
172
|
+
<object class="GtkLabel" id="labRunningTime">
|
173
|
+
<property name="visible">True</property>
|
174
|
+
<property name="can_focus">False</property>
|
175
|
+
<property name="xalign">0</property>
|
176
|
+
</object>
|
177
|
+
<packing>
|
178
|
+
<property name="left_attach">2</property>
|
179
|
+
<property name="right_attach">3</property>
|
180
|
+
</packing>
|
181
|
+
</child>
|
182
|
+
</object>
|
183
|
+
<packing>
|
184
|
+
<property name="expand">True</property>
|
185
|
+
<property name="fill">True</property>
|
186
|
+
<property name="position">2</property>
|
187
|
+
</packing>
|
188
|
+
</child>
|
148
189
|
<child>
|
149
190
|
<object class="GtkButton" id="btnSwitch">
|
150
191
|
<property name="label" translatable="yes">Switch</property>
|
@@ -157,7 +198,7 @@
|
|
157
198
|
<packing>
|
158
199
|
<property name="expand">False</property>
|
159
200
|
<property name="fill">True</property>
|
160
|
-
<property name="position">
|
201
|
+
<property name="position">3</property>
|
161
202
|
</packing>
|
162
203
|
</child>
|
163
204
|
</object>
|
@@ -308,121 +349,6 @@
|
|
308
349
|
<property name="position">2</property>
|
309
350
|
</packing>
|
310
351
|
</child>
|
311
|
-
<child>
|
312
|
-
<object class="GtkFrame" id="frameTimelogInfo">
|
313
|
-
<property name="visible">True</property>
|
314
|
-
<property name="can_focus">False</property>
|
315
|
-
<property name="label_xalign">0</property>
|
316
|
-
<property name="shadow_type">none</property>
|
317
|
-
<child>
|
318
|
-
<object class="GtkAlignment" id="alignment3">
|
319
|
-
<property name="visible">True</property>
|
320
|
-
<property name="can_focus">False</property>
|
321
|
-
<property name="left_padding">12</property>
|
322
|
-
<child>
|
323
|
-
<object class="GtkTable" id="table1">
|
324
|
-
<property name="visible">True</property>
|
325
|
-
<property name="can_focus">False</property>
|
326
|
-
<property name="n_rows">3</property>
|
327
|
-
<property name="n_columns">2</property>
|
328
|
-
<property name="column_spacing">3</property>
|
329
|
-
<property name="row_spacing">3</property>
|
330
|
-
<child>
|
331
|
-
<object class="GtkLabel" id="label4">
|
332
|
-
<property name="visible">True</property>
|
333
|
-
<property name="can_focus">False</property>
|
334
|
-
<property name="xalign">0</property>
|
335
|
-
<property name="label" translatable="yes">Description</property>
|
336
|
-
</object>
|
337
|
-
<packing>
|
338
|
-
<property name="x_options">GTK_FILL</property>
|
339
|
-
<property name="y_options">GTK_FILL</property>
|
340
|
-
</packing>
|
341
|
-
</child>
|
342
|
-
<child>
|
343
|
-
<object class="GtkLabel" id="label5">
|
344
|
-
<property name="visible">True</property>
|
345
|
-
<property name="can_focus">False</property>
|
346
|
-
<property name="xalign">0</property>
|
347
|
-
<property name="label" translatable="yes">Task</property>
|
348
|
-
</object>
|
349
|
-
<packing>
|
350
|
-
<property name="top_attach">1</property>
|
351
|
-
<property name="bottom_attach">2</property>
|
352
|
-
<property name="x_options">GTK_FILL</property>
|
353
|
-
<property name="y_options">GTK_FILL</property>
|
354
|
-
</packing>
|
355
|
-
</child>
|
356
|
-
<child>
|
357
|
-
<object class="GtkLabel" id="label6">
|
358
|
-
<property name="visible">True</property>
|
359
|
-
<property name="can_focus">False</property>
|
360
|
-
<property name="xalign">0</property>
|
361
|
-
<property name="label" translatable="yes">Time</property>
|
362
|
-
</object>
|
363
|
-
<packing>
|
364
|
-
<property name="top_attach">2</property>
|
365
|
-
<property name="bottom_attach">3</property>
|
366
|
-
<property name="x_options">GTK_FILL</property>
|
367
|
-
<property name="y_options">GTK_FILL</property>
|
368
|
-
</packing>
|
369
|
-
</child>
|
370
|
-
<child>
|
371
|
-
<object class="GtkLabel" id="labTimelogInfoDescr">
|
372
|
-
<property name="visible">True</property>
|
373
|
-
<property name="can_focus">False</property>
|
374
|
-
<property name="xalign">0</property>
|
375
|
-
</object>
|
376
|
-
<packing>
|
377
|
-
<property name="left_attach">1</property>
|
378
|
-
<property name="right_attach">2</property>
|
379
|
-
</packing>
|
380
|
-
</child>
|
381
|
-
<child>
|
382
|
-
<object class="GtkLabel" id="labTimelogInfoTask">
|
383
|
-
<property name="visible">True</property>
|
384
|
-
<property name="can_focus">False</property>
|
385
|
-
<property name="xalign">0</property>
|
386
|
-
</object>
|
387
|
-
<packing>
|
388
|
-
<property name="left_attach">1</property>
|
389
|
-
<property name="right_attach">2</property>
|
390
|
-
<property name="top_attach">1</property>
|
391
|
-
<property name="bottom_attach">2</property>
|
392
|
-
</packing>
|
393
|
-
</child>
|
394
|
-
<child>
|
395
|
-
<object class="GtkLabel" id="labTimelogInfoTime">
|
396
|
-
<property name="visible">True</property>
|
397
|
-
<property name="can_focus">False</property>
|
398
|
-
<property name="xalign">0</property>
|
399
|
-
</object>
|
400
|
-
<packing>
|
401
|
-
<property name="left_attach">1</property>
|
402
|
-
<property name="right_attach">2</property>
|
403
|
-
<property name="top_attach">2</property>
|
404
|
-
<property name="bottom_attach">3</property>
|
405
|
-
</packing>
|
406
|
-
</child>
|
407
|
-
</object>
|
408
|
-
</child>
|
409
|
-
</object>
|
410
|
-
</child>
|
411
|
-
<child type="label">
|
412
|
-
<object class="GtkLabel" id="label3">
|
413
|
-
<property name="visible">True</property>
|
414
|
-
<property name="can_focus">False</property>
|
415
|
-
<property name="label" translatable="yes"><b>Timelog info</b></property>
|
416
|
-
<property name="use_markup">True</property>
|
417
|
-
</object>
|
418
|
-
</child>
|
419
|
-
</object>
|
420
|
-
<packing>
|
421
|
-
<property name="expand">False</property>
|
422
|
-
<property name="fill">True</property>
|
423
|
-
<property name="position">3</property>
|
424
|
-
</packing>
|
425
|
-
</child>
|
426
352
|
<child>
|
427
353
|
<object class="GtkStatusbar" id="statusbar">
|
428
354
|
<property name="visible">True</property>
|
@@ -432,7 +358,7 @@
|
|
432
358
|
<packing>
|
433
359
|
<property name="expand">False</property>
|
434
360
|
<property name="fill">True</property>
|
435
|
-
<property name="position">
|
361
|
+
<property name="position">3</property>
|
436
362
|
</packing>
|
437
363
|
</child>
|
438
364
|
</object>
|
data/gui/trayicon.rb
CHANGED
@@ -38,7 +38,7 @@ class Openall_time_applet::Gui::Trayicon
|
|
38
38
|
end
|
39
39
|
|
40
40
|
#Calculate minutes tracked and generate variables.
|
41
|
-
secs = Time.now.to_i - @args[:oata].timelog_active_time.to_i
|
41
|
+
secs = Time.now.to_i - @args[:oata].timelog_active_time.to_i + @args[:oata].timelog_active.time_total
|
42
42
|
mins = (secs.to_f / 60.0)
|
43
43
|
|
44
44
|
if mins >= 60
|
@@ -88,14 +88,14 @@ class Openall_time_applet::Gui::Trayicon
|
|
88
88
|
menu = Gtk::Menu.new
|
89
89
|
|
90
90
|
#Make a list of all timelogs in the menu.
|
91
|
-
@args[:oata].ob.list(:Timelog,
|
91
|
+
@args[:oata].ob.list(:Timelog, "parent_timelog_id" => 0, "orderby" => "id") do |timelog|
|
92
92
|
label = timelog.descr_short
|
93
93
|
|
94
94
|
#If this is the active timelog, make the label bold, by getting the label-child and using HTML-markup on it.
|
95
95
|
if @args[:oata].timelog_active and @args[:oata].timelog_active.id == timelog.id
|
96
96
|
mi = Gtk::ImageMenuItem.new(Gtk::Stock::MEDIA_RECORD)
|
97
97
|
|
98
|
-
secs = Time.now.to_i - @args[:oata].timelog_active_time.to_i
|
98
|
+
secs = Time.now.to_i - @args[:oata].timelog_active_time.to_i + timelog.time_total
|
99
99
|
mins = (secs.to_f / 60.0).round(0)
|
100
100
|
|
101
101
|
mi.children[0].markup = "<b>#{Knj::Web.html(label)} (#{mins})</b>"
|
data/gui/win_main.rb
CHANGED
@@ -226,7 +226,7 @@ class Openall_time_applet::Gui::Win_main
|
|
226
226
|
def reload_timelogs
|
227
227
|
return nil if @dont_reload or @gui["tvTimelogs"].destroyed?
|
228
228
|
@gui["tvTimelogs"].model.clear
|
229
|
-
@args[:oata].ob.list(:Timelog,
|
229
|
+
@args[:oata].ob.list(:Timelog, "parent_timelog_id" => 0, "orderby" => [["timestamp", "desc"]]) do |timelog|
|
230
230
|
begin
|
231
231
|
tstamp_str = timelog.timestamp_str
|
232
232
|
rescue => e
|
@@ -259,7 +259,7 @@ class Openall_time_applet::Gui::Win_main
|
|
259
259
|
do_destroy = true
|
260
260
|
|
261
261
|
@args[:oata].ob.list(:Timelog) do |timelog|
|
262
|
-
if timelog
|
262
|
+
if timelog.time_total > 0 or timelog.time_total(:transport => true) > 0 or timelog[:sync_need].to_i == 1
|
263
263
|
timelog_found = timelog
|
264
264
|
break
|
265
265
|
end
|
@@ -305,9 +305,7 @@ class Openall_time_applet::Gui::Win_main
|
|
305
305
|
|
306
306
|
#This method handles the "Timelog info"-frame. Hides, shows and updates the info in it.
|
307
307
|
def timelog_info_trigger
|
308
|
-
if
|
309
|
-
@gui["labTimelogInfoDescr"].markup = "<b>#{Knj::Web.html(tlog[:descr])}</b>"
|
310
|
-
|
308
|
+
if tlog = @args[:oata].timelog_active
|
311
309
|
task = tlog.task
|
312
310
|
if !task
|
313
311
|
task_text = "[#{_("no task sat on the timelog")}]"
|
@@ -315,18 +313,20 @@ class Openall_time_applet::Gui::Win_main
|
|
315
313
|
task_text = task.name
|
316
314
|
end
|
317
315
|
|
318
|
-
@gui["
|
316
|
+
@gui["labRunningTimelog"].label = tlog[:descr]
|
317
|
+
@gui["labRunningTask"].label = task_text
|
319
318
|
|
320
|
-
time_tracked = Knj::Strings.secs_to_human_time_str(@args[:oata].timelog_active_time_tracked + tlog
|
321
|
-
@gui["labTimelogInfoTime"].markup = "<b>#{Knj::Web.html(time_tracked)}</b>"
|
319
|
+
time_tracked = Knj::Strings.secs_to_human_time_str(@args[:oata].timelog_active_time_tracked + tlog.time_total)
|
322
320
|
|
323
|
-
@gui["
|
324
|
-
else
|
325
|
-
visible = @gui["frameTimelogInfo"].visible?
|
326
|
-
@gui["frameTimelogInfo"].hide
|
321
|
+
@gui["labRunningTime"].label = time_tracked
|
327
322
|
|
328
|
-
|
329
|
-
@gui["
|
323
|
+
@gui["txtDescr"].hide
|
324
|
+
@gui["cbTask"].hide
|
325
|
+
@gui["tableRunning"].show_all
|
326
|
+
else
|
327
|
+
@gui["txtDescr"].show
|
328
|
+
@gui["cbTask"].show
|
329
|
+
@gui["tableRunning"].hide
|
330
330
|
end
|
331
331
|
end
|
332
332
|
|
@@ -387,7 +387,7 @@ class Openall_time_applet::Gui::Win_main
|
|
387
387
|
|
388
388
|
#Update time tracked.
|
389
389
|
if timelog_id == act_timelog_id
|
390
|
-
secs = act_timelog
|
390
|
+
secs = act_timelog.time_total + @args[:oata].timelog_active_time_tracked
|
391
391
|
iter[3] = "<b>#{Knj::Strings.secs_to_human_time_str(secs)}</b>"
|
392
392
|
bold = true
|
393
393
|
end
|
data/lib/openall_time_applet.rb
CHANGED
@@ -24,7 +24,7 @@ class Openall_time_applet
|
|
24
24
|
class Models
|
25
25
|
#Autoloader for subclasses.
|
26
26
|
def self.const_missing(name)
|
27
|
-
require "
|
27
|
+
require "#{File.dirname(__FILE__)}/../models/#{name.to_s.downcase}.rb"
|
28
28
|
return Openall_time_applet::Models.const_get(name)
|
29
29
|
end
|
30
30
|
end
|
@@ -33,7 +33,7 @@ class Openall_time_applet
|
|
33
33
|
class Gui
|
34
34
|
#Autoloader for subclasses.
|
35
35
|
def self.const_missing(name)
|
36
|
-
require "
|
36
|
+
require "#{File.dirname(__FILE__)}/../gui/#{name.to_s.downcase}.rb"
|
37
37
|
return Openall_time_applet::Gui.const_get(name)
|
38
38
|
end
|
39
39
|
end
|
@@ -42,7 +42,7 @@ class Openall_time_applet
|
|
42
42
|
def self.const_missing(name)
|
43
43
|
namel = name.to_s.downcase
|
44
44
|
tries = [
|
45
|
-
"
|
45
|
+
"#{File.dirname(__FILE__)}/../classes/#{namel}.rb"
|
46
46
|
]
|
47
47
|
tries.each do |try|
|
48
48
|
if File.exists?(try)
|
@@ -89,7 +89,7 @@ class Openall_time_applet
|
|
89
89
|
@ob = Knj::Objects.new(
|
90
90
|
:datarow => true,
|
91
91
|
:db => @db,
|
92
|
-
:class_path => "
|
92
|
+
:class_path => "#{File.dirname(__FILE__)}/../models",
|
93
93
|
:class_pre => "",
|
94
94
|
:module => Openall_time_applet::Models
|
95
95
|
)
|
@@ -175,7 +175,7 @@ class Openall_time_applet
|
|
175
175
|
|
176
176
|
#Updates the database according to the db-schema.
|
177
177
|
def update_db
|
178
|
-
require "
|
178
|
+
require "#{File.dirname(__FILE__)}/../conf/db_schema.rb"
|
179
179
|
Knj::Db::Revision.new.init_db("debug" => false, "db" => @db, "schema" => Openall_time_applet::DB_SCHEMA)
|
180
180
|
end
|
181
181
|
|
@@ -343,8 +343,30 @@ class Openall_time_applet
|
|
343
343
|
def timelog_stop_tracking
|
344
344
|
if @timelog_active
|
345
345
|
secs_passed = Time.now.to_i - @timelog_active_time.to_i
|
346
|
-
|
347
|
-
|
346
|
+
|
347
|
+
#Check if there has been logged time another day - if so, clone it and begin log on the clone instead.
|
348
|
+
if @timelog_active.timestamp.time.strftime("%Y-%m-%d") != Time.now.strftime("%Y-%m-%d")
|
349
|
+
timelog_use = @ob.get_by(:Timelog, {
|
350
|
+
"parent_timelog" => @timelog_active,
|
351
|
+
"timestamp_day" => Time.now
|
352
|
+
})
|
353
|
+
if !timelog_use
|
354
|
+
timelog_use = @ob.add(:Timelog, {
|
355
|
+
:task_id => @timelog_active[:task_id],
|
356
|
+
:parent_timelog_id => @timelog_active.id,
|
357
|
+
:timestamp => Time.now,
|
358
|
+
:descr => @timelog_active[:descr],
|
359
|
+
:transportdescription => @timelog_active[:transportdescription],
|
360
|
+
:workinternal => @timelog_active[:workinternal],
|
361
|
+
:timetype => @timelog_active[:timetype]
|
362
|
+
})
|
363
|
+
end
|
364
|
+
else
|
365
|
+
timelog_use = @timelog_active
|
366
|
+
end
|
367
|
+
|
368
|
+
timelog_use.update(
|
369
|
+
:time => timelog_use[:time].to_i + secs_passed,
|
348
370
|
:sync_need => 1
|
349
371
|
)
|
350
372
|
@timelog_logged_time[:timestamp_end] = Time.now
|
@@ -359,24 +381,6 @@ class Openall_time_applet
|
|
359
381
|
#Sets a new timelog to track. Stops tracking of previous timelog if already tracking.
|
360
382
|
def timelog_active=(timelog)
|
361
383
|
begin
|
362
|
-
#Check if there has been logged time another day - if so, clone it and begin logging on the clone instead.
|
363
|
-
tlt = @ob.list(:Timelog_logged_time, {
|
364
|
-
"timelog" => timelog,
|
365
|
-
"timestamp_start_day_not" => Time.now,
|
366
|
-
"limit" => 1
|
367
|
-
})
|
368
|
-
if !tlt.empty?
|
369
|
-
timelog = @ob.add(:Timelog, {
|
370
|
-
:task_id => timelog[:task_id],
|
371
|
-
:timestamp => Time.now,
|
372
|
-
:descr => timelog[:descr],
|
373
|
-
:transportdescription => timelog[:transportdescription],
|
374
|
-
:workinternal => timelog[:workinternal],
|
375
|
-
:timetype => timelog[:timetype]
|
376
|
-
})
|
377
|
-
#raise sprintf(_("You have already logged on this timelog on %s"), tlt.first.timestamp_start.out)
|
378
|
-
end
|
379
|
-
|
380
384
|
self.timelog_stop_tracking
|
381
385
|
@timelog_logged_time = @ob.add(:Timelog_logged_time, {:timelog_id => timelog.id})
|
382
386
|
@timelog_active = timelog
|
data/models/timelog.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
class Openall_time_applet::Models::Timelog < Knj::Datarow
|
2
2
|
has_one [
|
3
|
-
:Task
|
3
|
+
:Task,
|
4
|
+
[:Timelog, :parent_timelog_id, :parent_timelog]
|
4
5
|
]
|
5
6
|
|
6
7
|
has_many [
|
7
|
-
{:class => :Timelog_logged_time, :col => :timelog_id, :method => :logged_times, :autodelete => true}
|
8
|
+
{:class => :Timelog_logged_time, :col => :timelog_id, :method => :logged_times, :autodelete => true},
|
9
|
+
{:class => :Timelog, :col => :parent_timelog_id, :method => :child_timelogs, :autodelete => true}
|
8
10
|
]
|
9
11
|
|
10
12
|
def initialize(*args, &block)
|
@@ -19,6 +21,7 @@ class Openall_time_applet::Models::Timelog < Knj::Datarow
|
|
19
21
|
def self.add(d)
|
20
22
|
d.data[:time] = 0 if d.data[:time].to_s.strip.length <= 0
|
21
23
|
d.data[:time_transport] = 0 if d.data[:time_transport].to_s.strip.length <= 0
|
24
|
+
d.data[:parent_timelog_id] = 0 if !d.data.key?(:parent_timelog_id)
|
22
25
|
end
|
23
26
|
|
24
27
|
#Pushes timelogs and time to OpenAll.
|
@@ -69,13 +72,29 @@ class Openall_time_applet::Models::Timelog < Knj::Datarow
|
|
69
72
|
return descr
|
70
73
|
end
|
71
74
|
|
75
|
+
#Returns the total amount of seconds for this timelog (and any sub-timelogs).
|
76
|
+
def time_total(args = {})
|
77
|
+
if args[:transport]
|
78
|
+
col = :time_transport
|
79
|
+
else
|
80
|
+
col = :time
|
81
|
+
end
|
82
|
+
|
83
|
+
time = self[col].to_i
|
84
|
+
self.ob.list(:Timelog, "parent_timelog" => self) do |tlog|
|
85
|
+
time += tlog[col].to_i
|
86
|
+
end
|
87
|
+
|
88
|
+
return time
|
89
|
+
end
|
90
|
+
|
72
91
|
#Returns the time as a human readable format.
|
73
92
|
def time_as_human
|
74
|
-
return Knj::Strings.secs_to_human_time_str(self
|
93
|
+
return Knj::Strings.secs_to_human_time_str(self.time_total)
|
75
94
|
end
|
76
95
|
|
77
96
|
#Returns the transport-time as a human readable format.
|
78
97
|
def time_transport_as_human
|
79
|
-
return Knj::Strings.secs_to_human_time_str(self
|
98
|
+
return Knj::Strings.secs_to_human_time_str(self.time_total(:transport => true))
|
80
99
|
end
|
81
100
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Openall_time_applet::Models::Timelog_logged_time < Knj::Datarow
|
2
2
|
has_one [
|
3
|
-
{:class => :Timelog, :col => :timelog_id, :method => :timelog, :
|
3
|
+
{:class => :Timelog, :col => :timelog_id, :method => :timelog, :required => true}
|
4
4
|
]
|
5
5
|
|
6
6
|
def self.add(d)
|
data/openall_time_applet.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{openall_time_applet}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.19"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kasper Johansen"]
|
12
|
-
s.date = %q{2012-07-
|
12
|
+
s.date = %q{2012-07-10}
|
13
13
|
s.description = %q{Off-line time-tracking for OpenAll with syncing when online.}
|
14
14
|
s.email = %q{k@spernj.org}
|
15
15
|
s.executables = ["OpenAll Timelogging", "openall_time_applet.rb"]
|
@@ -1,7 +1,47 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe "OpenallTimeApplet" do
|
4
|
-
it "should
|
4
|
+
it "should be able to start" do
|
5
|
+
$tmp_path = "/tmp/openall_spec.sqlite3"
|
6
|
+
Openall_time_applet::CONFIG[:db_path] = $tmp_path
|
7
|
+
$oata = Openall_time_applet.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be able to clone timelogs" do
|
11
|
+
date = Knj::Datet.new
|
12
|
+
date.days - 1
|
13
|
+
|
14
|
+
timelog = $oata.ob.add(:Timelog, {
|
15
|
+
:descr => "Test 1",
|
16
|
+
:timestamp => date
|
17
|
+
})
|
18
|
+
|
19
|
+
$oata.timelog_active = timelog
|
20
|
+
sleep 0.5
|
21
|
+
$oata.timelog_stop_tracking
|
22
|
+
|
23
|
+
timelogs = $oata.ob.list(:Timelog, "orderby" => "timestamp").to_a
|
24
|
+
raise "Expected amount of timelogs to be 2 but it wasnt: #{timelogs.length}" if timelogs.length != 2
|
5
25
|
|
26
|
+
cloned = timelogs.last
|
27
|
+
raise "Expected date to be today but it wasnt: #{cloned.timestamp}" if cloned.timestamp.time.strftime("%Y-%m-%d") != Time.now.strftime("%Y-%m-%d")
|
28
|
+
|
29
|
+
$oata.timelog_active = timelog
|
30
|
+
sleep 0.5
|
31
|
+
$oata.timelog_stop_tracking
|
32
|
+
|
33
|
+
timelogs = $oata.ob.list(:Timelog, "orderby" => "timestamp").to_a
|
34
|
+
raise "Expected amount of timelogs to be 2 but it wasnt: #{timelogs.length}" if timelogs.length != 2
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should automatically delete sub-timelogs" do
|
38
|
+
main = $oata.ob.get_by(:Timelog, "parent_timelog_id" => 0)
|
39
|
+
$oata.ob.delete(main)
|
40
|
+
timelogs = $oata.ob.list(:Timelog, "orderby" => "timestamp").to_a
|
41
|
+
raise "Expected amount of timelogs to be 0 but it wasnt: #{timelogs.length}" if timelogs.length != 0
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should remove the temp db" do
|
45
|
+
File.unlink($tmp_path) if File.exists?($tmp_path)
|
6
46
|
end
|
7
47
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: openall_time_applet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.19
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Kasper Johansen
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-07-
|
13
|
+
date: 2012-07-10 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -198,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
198
198
|
requirements:
|
199
199
|
- - ">="
|
200
200
|
- !ruby/object:Gem::Version
|
201
|
-
hash:
|
201
|
+
hash: 4278837870597211102
|
202
202
|
segments:
|
203
203
|
- 0
|
204
204
|
version: "0"
|