nowfocus 0.5.7__tar.gz → 0.5.9__tar.gz
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.
- {nowfocus-0.5.7/src/nowfocus.egg-info → nowfocus-0.5.9}/PKG-INFO +2 -7
- {nowfocus-0.5.7 → nowfocus-0.5.9}/README.md +1 -6
- {nowfocus-0.5.7 → nowfocus-0.5.9}/pyproject.toml +1 -1
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/__main__.py +41 -25
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/conf.py +2 -2
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/taskwarrior.py +7 -0
- nowfocus-0.5.9/src/nowfocus/error_dialog.py +69 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/new_task_dialog.py +5 -2
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/session_edit_dialog.py +2 -4
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/settings.py +44 -32
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/task_window.py +3 -3
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/upgrade.py +14 -7
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/utils.py +50 -26
- {nowfocus-0.5.7 → nowfocus-0.5.9/src/nowfocus.egg-info}/PKG-INFO +2 -7
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus.egg-info/SOURCES.txt +1 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/LICENSE +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/setup.cfg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/__init__.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/activitywatch.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/caldav.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/csv.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/psc_timetracker.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/timewarrior.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/todo_template.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/todotxt.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/trello.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/txt.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/connectors/vikunja.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/desktop-extras/nowfocus.desktop +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/desktop-extras/nowfocus.png +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/desktop-extras/nowfocus.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/example-todo.txt +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/cancel.png +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/cancel.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/edit.png +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/edit.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-0.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-1.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-2.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-3.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-4.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-5.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-6.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-7.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-8.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-9.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon-red.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/icon.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/mark-done.png +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/mark-done.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/pause.png +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/pause.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/settings.png +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/icon/settings.svg +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/install.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/session_options.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/sessions.csv +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/sound/bell-xylophone-g.mp3 +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/sound/dinner-bell.mp3 +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/sound/xylophone-chord.mp3 +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/styles.css +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus/user_idle_time.py +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus.egg-info/dependency_links.txt +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus.egg-info/entry_points.txt +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus.egg-info/requires.txt +0 -0
- {nowfocus-0.5.7 → nowfocus-0.5.9}/src/nowfocus.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nowfocus
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.9
|
|
4
4
|
Summary: nowfocus: the open source task-tracking self-control panel.
|
|
5
5
|
Author: AltruistEnterprises
|
|
6
6
|
Project-URL: Homepage, https://www.nowfocus.org
|
|
@@ -121,12 +121,7 @@ nowfocus is a clean, keyboard-driven time management dashboard that flexibly con
|
|
|
121
121
|
```
|
|
122
122
|
bash -c "echo 'open_task_window' > /tmp/nowfocus-pipe"
|
|
123
123
|
```
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
3. Add the following command to your startup applications:
|
|
127
|
-
```
|
|
128
|
-
nowfocus --force
|
|
129
|
-
```
|
|
124
|
+
|
|
130
125
|
|
|
131
126
|
|
|
132
127
|
|
|
@@ -78,12 +78,7 @@ nowfocus is a clean, keyboard-driven time management dashboard that flexibly con
|
|
|
78
78
|
```
|
|
79
79
|
bash -c "echo 'open_task_window' > /tmp/nowfocus-pipe"
|
|
80
80
|
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
3. Add the following command to your startup applications:
|
|
84
|
-
```
|
|
85
|
-
nowfocus --force
|
|
86
|
-
```
|
|
81
|
+
|
|
87
82
|
|
|
88
83
|
|
|
89
84
|
|
|
@@ -5,6 +5,7 @@ import json
|
|
|
5
5
|
import time
|
|
6
6
|
from datetime import datetime, timezone, timedelta
|
|
7
7
|
import importlib
|
|
8
|
+
from importlib.metadata import version
|
|
8
9
|
from urllib.request import urlopen
|
|
9
10
|
import requests
|
|
10
11
|
import threading
|
|
@@ -63,7 +64,7 @@ class Application(Gtk.Application):
|
|
|
63
64
|
try:
|
|
64
65
|
|
|
65
66
|
# self.window = None # Think this is unused
|
|
66
|
-
|
|
67
|
+
|
|
67
68
|
self.is_running = False
|
|
68
69
|
self.device_in_use = True
|
|
69
70
|
self.UserIdleTime = UserIdleTime()
|
|
@@ -84,10 +85,10 @@ class Application(Gtk.Application):
|
|
|
84
85
|
install.run_first_load_actions()
|
|
85
86
|
|
|
86
87
|
try:
|
|
87
|
-
self.version =
|
|
88
|
+
self.version = version(conf.app_id)
|
|
88
89
|
print('nowfocus version', self.version)
|
|
89
90
|
except Exception as e:
|
|
90
|
-
|
|
91
|
+
dbg(e=e,l=0)
|
|
91
92
|
|
|
92
93
|
if get_system_db_value('db_schema_version') != self.version:
|
|
93
94
|
|
|
@@ -106,24 +107,35 @@ class Application(Gtk.Application):
|
|
|
106
107
|
self.start_pipe()
|
|
107
108
|
self.open_task_window()
|
|
108
109
|
|
|
110
|
+
|
|
111
|
+
# Have an error
|
|
112
|
+
# 1/0
|
|
113
|
+
|
|
109
114
|
# Testing
|
|
110
115
|
# TODO: enable these automatically with dbg system
|
|
111
116
|
# self.open_session_options_dialog('test_param')
|
|
112
|
-
|
|
117
|
+
self.open_settings_window(page_number=3) #for testing
|
|
113
118
|
# self.open_new_task_dialog() #for testing
|
|
114
119
|
# self.print_time_totals()
|
|
115
120
|
# self.new_task_dialog()
|
|
116
121
|
|
|
122
|
+
# error_dialog_inst = ErrorDialog(None,"test\n TEst")
|
|
123
|
+
# error_dialog_inst.show_all()
|
|
124
|
+
|
|
117
125
|
signal.signal(signal.SIGINT, self.quit)
|
|
118
126
|
signal.signal(signal.SIGUSR1, self.signal_handler)
|
|
119
127
|
signal.signal(signal.SIGUSR2, self.signal_handler)
|
|
120
128
|
|
|
121
129
|
Gtk.main()
|
|
130
|
+
|
|
122
131
|
except Exception as e:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
132
|
+
|
|
133
|
+
dbg(notification='Total error happened', e=e, l=0)
|
|
134
|
+
pass
|
|
135
|
+
# print(conf.app_name +' had a pretty bad error. Please submit the following trace as an issue on the git repo or email it to the developers ')
|
|
136
|
+
# print(e)
|
|
137
|
+
# traceback.print_tb(e.__traceback__)
|
|
138
|
+
# self.quit()
|
|
127
139
|
|
|
128
140
|
|
|
129
141
|
def print_time_totals(self = None, widget = None):
|
|
@@ -157,7 +169,7 @@ class Application(Gtk.Application):
|
|
|
157
169
|
try:
|
|
158
170
|
os.remove(conf.pipe)
|
|
159
171
|
except Exception as e:
|
|
160
|
-
|
|
172
|
+
dbg("Error removing conf.pipe in quit",e=e)
|
|
161
173
|
|
|
162
174
|
notify.uninit()
|
|
163
175
|
Gtk.main_quit()
|
|
@@ -374,7 +386,7 @@ class Application(Gtk.Application):
|
|
|
374
386
|
self.is_running = True
|
|
375
387
|
dbg("resuming session",s['label'],l=2, s='session')
|
|
376
388
|
except Exception as e:
|
|
377
|
-
dbg("Error resuming session",e,l=1)
|
|
389
|
+
dbg("Error resuming session",e=e ,l=1)
|
|
378
390
|
|
|
379
391
|
|
|
380
392
|
def start_task(self, w = None, task_data_or_id = None, transfer_current_session_time = False):
|
|
@@ -445,7 +457,8 @@ class Application(Gtk.Application):
|
|
|
445
457
|
self.task_running_menu_additions()
|
|
446
458
|
|
|
447
459
|
self.menu.show_all()
|
|
448
|
-
dbg("Starting",task_data['extended_label'])
|
|
460
|
+
dbg("Starting",task_data['extended_label'],l=-1)
|
|
461
|
+
dbg("new session task priority:", s['task']['priority'], l=-1)
|
|
449
462
|
|
|
450
463
|
if task_data['id'] in conf.user['task_commands']:
|
|
451
464
|
command_data = conf.user['task_commands'][task_data['id']]
|
|
@@ -464,7 +477,7 @@ class Application(Gtk.Application):
|
|
|
464
477
|
process = None
|
|
465
478
|
for proc in psutil.process_iter():
|
|
466
479
|
pinfo = proc.as_dict(attrs=['pid', 'name'])
|
|
467
|
-
|
|
480
|
+
dbg("Check process", pinfo['name'], s='commands', l=3)
|
|
468
481
|
if pinfo['name'] == command:
|
|
469
482
|
process = proc
|
|
470
483
|
break
|
|
@@ -472,16 +485,18 @@ class Application(Gtk.Application):
|
|
|
472
485
|
continue
|
|
473
486
|
|
|
474
487
|
if process:
|
|
475
|
-
|
|
488
|
+
dbg("waiting for already running command with psutils", command, s='commands')
|
|
476
489
|
# subprocess.run('wmctrl', '-a', command) # Doesn't work on wayland
|
|
477
490
|
process.wait()
|
|
478
491
|
else:
|
|
479
|
-
|
|
492
|
+
dbg("Launching command with subprocess.run", command, s='commands')
|
|
480
493
|
subprocess.run(command,shell=True)
|
|
481
494
|
|
|
482
|
-
|
|
495
|
+
dbg("running task command complete:", command, s='commands')
|
|
496
|
+
|
|
497
|
+
# stop timer on command completion if duration is more an 3 seconds and session is still the same task
|
|
483
498
|
|
|
484
|
-
if self.session['label'] == self.running_command_task_label:
|
|
499
|
+
if self.session['duration'] > 3 and self.session['label'] == self.running_command_task_label:
|
|
485
500
|
GLib.idle_add(self.stop_task)
|
|
486
501
|
GLib.idle_add(self.open_task_window)
|
|
487
502
|
|
|
@@ -510,7 +525,7 @@ class Application(Gtk.Application):
|
|
|
510
525
|
playsound('sound/xylophone-chord.mp3',False)
|
|
511
526
|
|
|
512
527
|
except Exception as e:
|
|
513
|
-
|
|
528
|
+
dbg(notification="Marking "+ task['label']+" as done in "+todolist_conf['label']+" had a serious failure", e=e,l=0 )
|
|
514
529
|
|
|
515
530
|
|
|
516
531
|
|
|
@@ -532,16 +547,16 @@ class Application(Gtk.Application):
|
|
|
532
547
|
# Get time tracker for this tasks todolist
|
|
533
548
|
todolist_conf = conf.user['todolists'][task['todolist']]
|
|
534
549
|
|
|
535
|
-
if 'timetracker'
|
|
550
|
+
if todolist_conf['timetracker']:
|
|
536
551
|
|
|
537
|
-
dbg("Save Session to "+ todolist_conf['timetracker'])
|
|
552
|
+
dbg("Save Session to "+ str(todolist_conf['timetracker']))
|
|
538
553
|
try:
|
|
539
554
|
|
|
540
555
|
timetracker_conf = conf.user['timetrackers'][todolist_conf['timetracker']]
|
|
541
556
|
save_thread = threading.Thread(target=conf.timetracker_connectors[timetracker_conf['type']].save_session, args=(session,timetracker_conf) )
|
|
542
557
|
save_thread.start()
|
|
543
558
|
except Exception as e:
|
|
544
|
-
|
|
559
|
+
dbg('Error Saving Time Data',notification="Recording timetracking for "+ task['label']+" in "+timetracker_conf['label']+" had a serious failure",e=e ,l=0 )
|
|
545
560
|
|
|
546
561
|
session['timetracker'] = todolist_conf['timetracker']
|
|
547
562
|
|
|
@@ -665,8 +680,9 @@ class Application(Gtk.Application):
|
|
|
665
680
|
list_menus['recent'].append(i)
|
|
666
681
|
|
|
667
682
|
except Exception as e:
|
|
683
|
+
pass
|
|
668
684
|
# Because a key error if the task has was completed or todolist removed
|
|
669
|
-
|
|
685
|
+
dbg('recent_tasks error', e=e)
|
|
670
686
|
menu.append(Gtk.SeparatorMenuItem.new())
|
|
671
687
|
|
|
672
688
|
|
|
@@ -738,12 +754,12 @@ class Application(Gtk.Application):
|
|
|
738
754
|
self.session_options_dialog.show_all()
|
|
739
755
|
|
|
740
756
|
|
|
741
|
-
def open_settings_window(self, w = None, **kwargs):
|
|
757
|
+
def open_settings_window(self, w = None, page_number=0, **kwargs):
|
|
742
758
|
|
|
743
759
|
if hasattr(self, 'settings_window'):
|
|
744
760
|
self.settings_window.present()
|
|
745
761
|
else:
|
|
746
|
-
self.settings_window = SettingsWindow(self
|
|
762
|
+
self.settings_window = SettingsWindow(self, page_number, **kwargs)
|
|
747
763
|
self.settings_window.show_all()
|
|
748
764
|
|
|
749
765
|
|
|
@@ -811,7 +827,7 @@ class Application(Gtk.Application):
|
|
|
811
827
|
error_notice('Commandline Task failed','Could not find a task matching argument '+str(data))
|
|
812
828
|
|
|
813
829
|
except FileNotFoundError as e:
|
|
814
|
-
|
|
830
|
+
dbg(notification="Error starting pip listener, CLI will not work",e=e,l=0)
|
|
815
831
|
|
|
816
832
|
# keep listening
|
|
817
833
|
self.check_pipe()
|
|
@@ -883,7 +899,7 @@ def startup():
|
|
|
883
899
|
|
|
884
900
|
|
|
885
901
|
except Exception as e:
|
|
886
|
-
|
|
902
|
+
dbg("Named pipe creation failed",e=e,l=0)
|
|
887
903
|
|
|
888
904
|
|
|
889
905
|
if __name__ == "__main__":
|
|
@@ -22,6 +22,7 @@ user_settings_dir = GLib.get_user_config_dir()+"/"+app_id
|
|
|
22
22
|
|
|
23
23
|
db_file = user_data_dir+"/data.db"
|
|
24
24
|
settings_file = user_data_dir+"/nowfocus-settings.json"
|
|
25
|
+
error_log_file = user_data_dir+"/error.log"
|
|
25
26
|
debug_level = 1 # dev value
|
|
26
27
|
debug_systems = []
|
|
27
28
|
pipe = "/tmp/"+app_id+"-pipe"
|
|
@@ -71,7 +72,7 @@ prototype_settings = {
|
|
|
71
72
|
'max_top_level_menu_items':10,
|
|
72
73
|
'hours_search_timeframe':'this year',
|
|
73
74
|
'invoice_hourly_rate':0,
|
|
74
|
-
'default_list_for_new_tasks':'
|
|
75
|
+
'default_list_for_new_tasks':'List that was last added to',
|
|
75
76
|
|
|
76
77
|
"custom_pomodoro_intervals": {
|
|
77
78
|
"email":7 #minutes
|
|
@@ -162,7 +163,6 @@ for key, val in prototype_settings.items():
|
|
|
162
163
|
# print(json.dumps(user, indent=4))
|
|
163
164
|
# print(json.dumps(connectors['todolists'], indent=4))
|
|
164
165
|
|
|
165
|
-
|
|
166
166
|
with open(settings_file,"w") as file:
|
|
167
167
|
json.dump(user, file)
|
|
168
168
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import conf
|
|
3
3
|
import utils
|
|
4
|
+
import subprocess
|
|
4
5
|
from taskw import TaskWarrior
|
|
5
6
|
|
|
6
7
|
# lists and tasks are each a dicts of dicts with following shape
|
|
@@ -115,5 +116,11 @@ def get_todos(user_conf):
|
|
|
115
116
|
todos = {'lists':lists,'tasks':tasks}
|
|
116
117
|
return todos
|
|
117
118
|
|
|
119
|
+
def launch(user_conf):
|
|
120
|
+
subprocess.Popen(['x-terminal-emulator'])
|
|
121
|
+
# subprocess.call(['x-terminal-emulator', '-e', 'task']) # Supposed to work but doesn't
|
|
122
|
+
# subprocess.call(['gnome-terminal', '-x', 'task']) # Me too!
|
|
123
|
+
|
|
124
|
+
|
|
118
125
|
# testing
|
|
119
126
|
# print(get_todos())
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import gi
|
|
2
|
+
gi.require_version('Gtk', '3.0')
|
|
3
|
+
from gi.repository import Gtk, GLib, Gdk
|
|
4
|
+
import conf
|
|
5
|
+
import utils
|
|
6
|
+
from utils import *
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ErrorDialog(Gtk.Dialog):
|
|
10
|
+
|
|
11
|
+
def __init__(self, parent, error_details_str, system = ''):
|
|
12
|
+
|
|
13
|
+
super().__init__(title=conf.app_name + " Error ", transient_for=parent, flags=0)
|
|
14
|
+
self.error_details = str(error_details_str)
|
|
15
|
+
|
|
16
|
+
print("error dialog init")
|
|
17
|
+
|
|
18
|
+
# self.app = parent.app
|
|
19
|
+
self.set_default_size(600,400)
|
|
20
|
+
|
|
21
|
+
self.set_border_width(15)
|
|
22
|
+
|
|
23
|
+
dialog = self.get_content_area()
|
|
24
|
+
|
|
25
|
+
dialog.set_spacing(15)
|
|
26
|
+
|
|
27
|
+
intro_text = conf.app_name+" "+system+" has hit a bump in the road..."
|
|
28
|
+
|
|
29
|
+
intro = Gtk.Label(intro_text)
|
|
30
|
+
|
|
31
|
+
dialog.add(intro)
|
|
32
|
+
|
|
33
|
+
box = Gtk.Box()
|
|
34
|
+
error_label = Gtk.Label(self.error_details)
|
|
35
|
+
box.add(error_label)
|
|
36
|
+
|
|
37
|
+
scrolled_window = Gtk.ScrolledWindow()
|
|
38
|
+
scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
|
39
|
+
# scrolled_window.set_size_request(-1, 350)
|
|
40
|
+
|
|
41
|
+
scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
|
|
42
|
+
scrolled_window.add(box)
|
|
43
|
+
|
|
44
|
+
dialog.pack_end(scrolled_window,1,1,True)
|
|
45
|
+
|
|
46
|
+
# dialog.add(Gtk.Box(border_width=10)) #spacer
|
|
47
|
+
|
|
48
|
+
self.add_button("Okay Whatever", 1)
|
|
49
|
+
|
|
50
|
+
self.add_button("Send to developers", 2)
|
|
51
|
+
|
|
52
|
+
self.set_default_response(2)
|
|
53
|
+
|
|
54
|
+
self.show_all()
|
|
55
|
+
self.connect("response", self.on_response,)
|
|
56
|
+
|
|
57
|
+
def on_response(self, widget, response):
|
|
58
|
+
if response == 2:
|
|
59
|
+
|
|
60
|
+
import subprocess
|
|
61
|
+
|
|
62
|
+
subprocess.run([
|
|
63
|
+
"xdg-email",
|
|
64
|
+
"--subject", conf.app_name+" Error Report",
|
|
65
|
+
"--body", self.error_details,
|
|
66
|
+
# "recipient@example.com"
|
|
67
|
+
])
|
|
68
|
+
|
|
69
|
+
self.destroy()
|
|
@@ -43,7 +43,7 @@ class NewTaskWDialog(Gtk.Dialog):
|
|
|
43
43
|
|
|
44
44
|
box.add(Gtk.Box(border_width=10)) #spacer
|
|
45
45
|
|
|
46
|
-
default_list =
|
|
46
|
+
default_list = get_default_list_for_new_tasks()
|
|
47
47
|
|
|
48
48
|
box.add(choose_from_lists(self.select_list, default_list['id']))
|
|
49
49
|
self.selected_list = default_list
|
|
@@ -97,6 +97,9 @@ class NewTaskWDialog(Gtk.Dialog):
|
|
|
97
97
|
# add it to the database
|
|
98
98
|
db_set_item(task)
|
|
99
99
|
|
|
100
|
+
# Add list and last appended to list in system db
|
|
101
|
+
set_system_db_value('last_added_to_list_id',self.selected_list['id'])
|
|
102
|
+
|
|
100
103
|
# add it to the menu
|
|
101
104
|
menu_tasks[task['id']] = Gtk.MenuItem.new_with_label(task['label'])
|
|
102
105
|
menu_tasks[task['id']].connect("activate", self.app.start_task, task)
|
|
@@ -122,7 +125,7 @@ class NewTaskWDialog(Gtk.Dialog):
|
|
|
122
125
|
if conf.debug_level > 1:
|
|
123
126
|
raise e
|
|
124
127
|
|
|
125
|
-
|
|
128
|
+
dbg(notification="Error adding tasks "+str(task_label)+" to "+todolist_conf['label'], e=e,l=0)
|
|
126
129
|
|
|
127
130
|
|
|
128
131
|
elif response == Gtk.ResponseType.CANCEL:
|
|
@@ -32,9 +32,10 @@ class SessionEditDialog(Gtk.Dialog):
|
|
|
32
32
|
else:
|
|
33
33
|
error_notice("Error: SessionEditDialog called without session data")
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
dbg('SessionEditDialog target_session',target_session,l=-1)
|
|
36
36
|
|
|
37
37
|
self.s['task'] = db_get_item_by_id(self.s['task_id'])
|
|
38
|
+
|
|
38
39
|
# Used to identify and remove old session
|
|
39
40
|
self.session_id = {
|
|
40
41
|
'extended_label':self.s['extended_label'], 'start_time': self.s['start_time']
|
|
@@ -47,7 +48,6 @@ class SessionEditDialog(Gtk.Dialog):
|
|
|
47
48
|
|
|
48
49
|
box = self.get_content_area()
|
|
49
50
|
|
|
50
|
-
|
|
51
51
|
# label = Gtk.Label()
|
|
52
52
|
# label.set_markup("<b>"+self.s['extended_label']+"</b> ")
|
|
53
53
|
# box.add(label)
|
|
@@ -160,8 +160,6 @@ class SessionEditDialog(Gtk.Dialog):
|
|
|
160
160
|
if response == 2:
|
|
161
161
|
db_query("DELETE FROM sessions WHERE extended_label = ? AND start_time = ? LIMIT 1",(self.session_id['extended_label'],self.session_id['start_time']))
|
|
162
162
|
|
|
163
|
-
error_notice('Session Deleted','')
|
|
164
|
-
|
|
165
163
|
if response == 3:
|
|
166
164
|
|
|
167
165
|
if self.notes_text_buffer.get_modified():
|
|
@@ -94,11 +94,13 @@ class SettingsWindow(Gtk.Window):
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
def __init__(self, parent=None, **kwargs):
|
|
97
|
+
def __init__(self, parent=None, page_number=0, **kwargs):
|
|
98
98
|
self.app = parent #NOTE: This doesn't look like it will work when called from task_window...
|
|
99
99
|
Gtk.Window.__init__(self, title="Settings")
|
|
100
|
-
self.set_border_width(
|
|
100
|
+
self.set_border_width(0)
|
|
101
101
|
self.set_position(position=1)
|
|
102
|
+
self.set_default_size(-1,800)
|
|
103
|
+
|
|
102
104
|
self.connect("destroy", self.on_close)
|
|
103
105
|
|
|
104
106
|
self.notebook = Gtk.Notebook()
|
|
@@ -106,15 +108,17 @@ class SettingsWindow(Gtk.Window):
|
|
|
106
108
|
|
|
107
109
|
|
|
108
110
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
# Settings
|
|
111
|
+
# Settings page
|
|
112
112
|
row = 0
|
|
113
113
|
grid = Gtk.Grid()
|
|
114
114
|
grid.set_row_spacing(10)
|
|
115
115
|
grid.set_column_spacing(10)
|
|
116
|
-
|
|
116
|
+
grid.set_border_width(15)
|
|
117
|
+
settings_page = Gtk.Box()
|
|
118
|
+
settings_scroller = self.scroll_box(settings_page)
|
|
119
|
+
settings_scroller.add(grid)
|
|
117
120
|
|
|
121
|
+
self.notebook.append_page(settings_page,Gtk.Label('Settings'))
|
|
118
122
|
|
|
119
123
|
grid.attach(Gtk.Box(border_width=10),0,(row:=row+1),5,1) # Spacer
|
|
120
124
|
|
|
@@ -129,9 +133,11 @@ class SettingsWindow(Gtk.Window):
|
|
|
129
133
|
|
|
130
134
|
grid.attach(self.settings_updater('todolist_refresh_interval', 3, 'SpinButton',"(hours)"),0,(row:=row+1),5,1)
|
|
131
135
|
|
|
132
|
-
|
|
133
136
|
# grid.attach(self.settings_updater('invoice_hourly_rate', 33, 'SpinButton',""),0,(row:=row+1),5,1)
|
|
134
137
|
|
|
138
|
+
grid.attach(self.settings_updater('default_list_for_new_tasks', 'List that was last added to', 'ComboBoxText',"", options = ['List that was last added to','Most recently used list']),0,(row:=row+1),5,1)
|
|
139
|
+
|
|
140
|
+
|
|
135
141
|
grid.attach(self.settings_updater('hours_search_timeframe', 'auto', 'ComboBoxText',"\nDefault timetracking range for hours shown in main window and invoicing", options = list(hours_search_timeframes().keys())),0,(row:=row+1),5,1)
|
|
136
142
|
|
|
137
143
|
grid.attach(self.settings_updater('prompts', None, 'TextView',""),0,(row:=row+1),5,1)
|
|
@@ -143,13 +149,18 @@ class SettingsWindow(Gtk.Window):
|
|
|
143
149
|
|
|
144
150
|
|
|
145
151
|
|
|
152
|
+
|
|
153
|
+
connectors_page = Gtk.Box()
|
|
154
|
+
self.notebook.append_page(connectors_page,Gtk.Label('Todolists and Time Trackers'))
|
|
155
|
+
connectors_scroller = self.scroll_box(connectors_page)
|
|
156
|
+
|
|
157
|
+
# TODO: perhaps use a scroller for each connector category instead of one big one
|
|
146
158
|
row = 0
|
|
147
159
|
grid = Gtk.Grid()
|
|
160
|
+
connectors_scroller.add(grid)
|
|
148
161
|
grid.set_row_spacing(10)
|
|
149
162
|
grid.set_column_spacing(10)
|
|
150
|
-
grid.set_border_width(
|
|
151
|
-
|
|
152
|
-
self.notebook.append_page(grid,Gtk.Label('Todolists and Time Trackers'))
|
|
163
|
+
grid.set_border_width(15)
|
|
153
164
|
|
|
154
165
|
sub_head = Gtk.Label()
|
|
155
166
|
sub_head.set_markup("<b>Todo Lists</b>")
|
|
@@ -227,11 +238,13 @@ class SettingsWindow(Gtk.Window):
|
|
|
227
238
|
|
|
228
239
|
|
|
229
240
|
# Task Commands notebook page
|
|
230
|
-
self.
|
|
231
|
-
self.notebook.append_page(self.
|
|
241
|
+
self.task_commands_page = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
242
|
+
self.notebook.append_page(self.task_commands_page,Gtk.Label('Task Commands'))
|
|
243
|
+
|
|
244
|
+
self.task_commands_box = self.scroll_box(self.task_commands_page)
|
|
245
|
+
self.task_commands_box.set_border_width(15)
|
|
232
246
|
|
|
233
247
|
self.boxes['task_commands_outer'] = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
234
|
-
# self.boxes['task_commands_outer'] = self.scroll_box()
|
|
235
248
|
self.task_commands_box.add(self.boxes['task_commands_outer'])
|
|
236
249
|
|
|
237
250
|
# Gets replaced when commands are loaded
|
|
@@ -248,19 +261,22 @@ class SettingsWindow(Gtk.Window):
|
|
|
248
261
|
|
|
249
262
|
|
|
250
263
|
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
251
267
|
# Time Targets notebook page
|
|
252
|
-
self.
|
|
253
|
-
self.notebook.append_page(self.targets_box, Gtk.Label('Time Targets'))
|
|
268
|
+
self.targets_page = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
254
269
|
|
|
255
|
-
self.
|
|
256
|
-
# self.targets_box.add(self.boxes['lists_time_targets_outer'])
|
|
270
|
+
self.notebook.append_page(self.targets_page, Gtk.Label('Time Targets'))
|
|
257
271
|
|
|
258
|
-
|
|
259
|
-
# self.boxes['test'] = self.scroll_box(None ,300)
|
|
260
|
-
# self.targets_box.add(self.boxes['test'])
|
|
272
|
+
self.targets_scroller = self.scroll_box(self.targets_page ,300)
|
|
261
273
|
|
|
262
|
-
|
|
274
|
+
self.targets_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
275
|
+
self.targets_box.set_border_width(15)
|
|
276
|
+
|
|
277
|
+
self.targets_scroller.add(self.targets_box)
|
|
263
278
|
|
|
279
|
+
self.boxes['lists_time_targets_outer'] = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
264
280
|
|
|
265
281
|
self.targets_box.add(self.boxes['lists_time_targets_outer'])
|
|
266
282
|
|
|
@@ -268,13 +284,6 @@ class SettingsWindow(Gtk.Window):
|
|
|
268
284
|
# Gets replaced when targets are loaded
|
|
269
285
|
self.boxes['lists_time_targets_inner'] = Gtk.Box()
|
|
270
286
|
self.boxes['lists_time_targets_outer'].add(self.boxes['lists_time_targets_inner'])
|
|
271
|
-
|
|
272
|
-
# separator = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
|
|
273
|
-
# self.boxes['lists_time_targets_outer'].pack_start(separator, True, True, 0)
|
|
274
|
-
|
|
275
|
-
# test_button = Gtk.Button(label="test")
|
|
276
|
-
# self.boxes['lists_time_targets_inner'].add(test_button)
|
|
277
|
-
|
|
278
287
|
|
|
279
288
|
self.show_time_targets('lists')
|
|
280
289
|
|
|
@@ -286,6 +295,7 @@ class SettingsWindow(Gtk.Window):
|
|
|
286
295
|
|
|
287
296
|
self.boxes['tasks_time_targets_outer'] = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
288
297
|
self.targets_box.add(self.boxes['tasks_time_targets_outer'])
|
|
298
|
+
|
|
289
299
|
# Gets replaced when targets are loaded
|
|
290
300
|
self.boxes['tasks_time_targets_inner'] = Gtk.Box()
|
|
291
301
|
self.boxes['tasks_time_targets_outer'].add(self.boxes['tasks_time_targets_inner'])
|
|
@@ -308,6 +318,7 @@ class SettingsWindow(Gtk.Window):
|
|
|
308
318
|
|
|
309
319
|
# Sessions notebook page
|
|
310
320
|
self.sessions_page = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
321
|
+
self.sessions_page.set_border_width(15)
|
|
311
322
|
|
|
312
323
|
self.notebook.append_page(self.sessions_page,Gtk.Label('Sessions'))
|
|
313
324
|
|
|
@@ -336,8 +347,9 @@ class SettingsWindow(Gtk.Window):
|
|
|
336
347
|
|
|
337
348
|
self.SessionEditDialog = SessionEditDialog # passed to show_sessions
|
|
338
349
|
|
|
339
|
-
|
|
350
|
+
print('set_current_page',page_number)
|
|
340
351
|
self.show_all()
|
|
352
|
+
self.notebook.set_current_page(page_number)
|
|
341
353
|
|
|
342
354
|
|
|
343
355
|
|
|
@@ -434,7 +446,7 @@ class SettingsWindow(Gtk.Window):
|
|
|
434
446
|
checkbutton.set_label("Error: '"+str(id)+"' didn't match anything " )
|
|
435
447
|
else:
|
|
436
448
|
# print('Show time target',item_data)
|
|
437
|
-
checkbutton.set_label(item_data['label']+"
|
|
449
|
+
checkbutton.set_label(item_data['label']+" \n"+str(data['type'])+ " "+str(data['value'])+" minutes per "+str(data['within_value'])+" "+str(data['within_unit']) )
|
|
438
450
|
checkbutton.set_active(data['status'])
|
|
439
451
|
|
|
440
452
|
# checkbutton.connect("toggled", print, checkbutton.get_active())
|
|
@@ -476,9 +488,9 @@ class SettingsWindow(Gtk.Window):
|
|
|
476
488
|
|
|
477
489
|
task_data = db_get_item_by_id(id,"tasks")
|
|
478
490
|
if not task_data:
|
|
479
|
-
checkbutton.set_label("Error: '"+str(id)+"' task missing "+str(command_data['command']))
|
|
491
|
+
checkbutton.set_label("Error: '"+str(id)+"' task missing \n"+str(command_data['command']))
|
|
480
492
|
else:
|
|
481
|
-
checkbutton.set_label(task_data['extended_label']+" "+str(command_data['command']) )
|
|
493
|
+
checkbutton.set_label(task_data['extended_label']+" \n"+str(command_data['command']) )
|
|
482
494
|
checkbutton.set_active(command_data['status'])
|
|
483
495
|
|
|
484
496
|
checkbutton.connect("toggled", update_user_setting, conf.user['task_commands'][id], 'status', checkbutton.get_active)
|
|
@@ -36,7 +36,7 @@ class TaskWindow(Gtk.Window):
|
|
|
36
36
|
# TaskWindow._instance.present()
|
|
37
37
|
# return None
|
|
38
38
|
except Exception as e:
|
|
39
|
-
dbg("TaskWindow._instance exception",e,s='taskwindow')
|
|
39
|
+
dbg("TaskWindow._instance exception",e=e ,s='taskwindow')
|
|
40
40
|
|
|
41
41
|
TaskWindow._instance = self
|
|
42
42
|
|
|
@@ -197,7 +197,7 @@ class TaskWindow(Gtk.Window):
|
|
|
197
197
|
self.buttons_box.add(openable_button)
|
|
198
198
|
|
|
199
199
|
except Exception as e:
|
|
200
|
-
dbg("error adding todo connector open() to task window ",e, s='taskwindow')
|
|
200
|
+
dbg("error adding todo connector open() to task window ",e=e , s='taskwindow')
|
|
201
201
|
|
|
202
202
|
self.new_task_button = Gtk.Button(label="New Task")
|
|
203
203
|
self.new_task_button.set_property("tooltip-text","Add a new task (Ctrl + N)")
|
|
@@ -521,7 +521,7 @@ class TaskWindow(Gtk.Window):
|
|
|
521
521
|
|
|
522
522
|
|
|
523
523
|
except Exception as e:
|
|
524
|
-
utils.dbg("Error adding task to list"+ str(t['extended_label']), t, e, l=0, s='taskwindow')
|
|
524
|
+
utils.dbg("Error adding task to list"+ str(t['extended_label']), t, e=e, l=0, s='taskwindow')
|
|
525
525
|
return False
|
|
526
526
|
|
|
527
527
|
|
|
@@ -37,14 +37,7 @@ def do_upgrades(app):
|
|
|
37
37
|
|
|
38
38
|
db_query("ALTER TABLE sessions ADD COLUMN priority INTEGER DEFAULT 0")
|
|
39
39
|
|
|
40
|
-
for session in db_query("SELECT DISTINCT task_id, extended_label FROM sessions"):
|
|
41
|
-
t = db_get_item_by_id(session['task_id'],dgb_error_level_for_failure=3)
|
|
42
|
-
if t and t['priority'] > 0:
|
|
43
|
-
print("setting",session['extended_label']," session priority to ",t['priority'] )
|
|
44
40
|
|
|
45
|
-
db_query("UPDATE sessions SET priority = ? WHERE task_id = ?",(t['priority'],session['task_id']))
|
|
46
|
-
|
|
47
|
-
print("Total hours priority sessions",round(divide(db_query("SELECT SUM(duration) as total FROM sessions WHERE priority > 0")[0]['total'],3600),2))
|
|
48
41
|
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.5')")
|
|
49
42
|
|
|
50
43
|
db_schema_version = '0.5'
|
|
@@ -58,6 +51,20 @@ def do_upgrades(app):
|
|
|
58
51
|
db_schema_version = "0.5.6"
|
|
59
52
|
set_system_db_value("db_schema_version",db_schema_version)
|
|
60
53
|
|
|
54
|
+
if db_schema_version == '0.5.6':
|
|
55
|
+
dbg('Schema Update from', db_schema_version, 'to 0.5.9',l=-1)
|
|
56
|
+
|
|
57
|
+
for session in db_query("SELECT DISTINCT task_id, extended_label FROM sessions"):
|
|
58
|
+
t = db_get_item_by_id(session['task_id'],dgb_error_level_for_failure=3)
|
|
59
|
+
if t and t['priority'] > 0:
|
|
60
|
+
print("setting",session['extended_label']," session priority to ",t['priority'] )
|
|
61
|
+
|
|
62
|
+
db_query("UPDATE sessions SET priority = ? WHERE task_id = ?",(t['priority'],session['task_id']))
|
|
63
|
+
|
|
64
|
+
print("Total hours priority sessions",round(divide(db_query("SELECT SUM(duration) as total FROM sessions WHERE priority > 0")[0]['total'],3600),2))
|
|
65
|
+
|
|
66
|
+
db_schema_version = "0.5.9"
|
|
67
|
+
set_system_db_value("db_schema_version",db_schema_version)
|
|
61
68
|
# if db_schema_version == 0.5:
|
|
62
69
|
# db_query("ALTER TABLE tasks ADD COLUMN tags TEXT DEFAULT '{}'")
|
|
63
70
|
# db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.5')")
|
|
@@ -26,6 +26,8 @@ import traceback
|
|
|
26
26
|
import conf
|
|
27
27
|
notify.init(conf.app_name)
|
|
28
28
|
|
|
29
|
+
from error_dialog import ErrorDialog
|
|
30
|
+
|
|
29
31
|
lists = {}
|
|
30
32
|
|
|
31
33
|
|
|
@@ -66,8 +68,24 @@ def dbg(*data, s="", l=2, e=None, notification=None):
|
|
|
66
68
|
# pretty_print(data)
|
|
67
69
|
|
|
68
70
|
if e and isinstance(e,Exception):
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
|
|
72
|
+
error_report = str(e) + '\n' + traceback.format_exc()
|
|
73
|
+
|
|
74
|
+
print(error_report)
|
|
75
|
+
|
|
76
|
+
if data:
|
|
77
|
+
error_report = json.dumps(data,indent=2) + error_report
|
|
78
|
+
|
|
79
|
+
print("show ErrorDialog")
|
|
80
|
+
error_dialog_inst = ErrorDialog(None, error_report)
|
|
81
|
+
error_dialog_inst.show_all()
|
|
82
|
+
|
|
83
|
+
# if level == 0:
|
|
84
|
+
# with open(conf.error_log_file,'a') as error_log:
|
|
85
|
+
# error_log.write(str(e))
|
|
86
|
+
# error_log.write(traceback.format_exc())
|
|
87
|
+
|
|
88
|
+
|
|
71
89
|
|
|
72
90
|
def error_notice(title, details = None, e = None):
|
|
73
91
|
print('ERROR',title,details,e)
|
|
@@ -134,7 +152,7 @@ def sec_to_time(sec):
|
|
|
134
152
|
try:
|
|
135
153
|
int(sec)
|
|
136
154
|
except Exception as e:
|
|
137
|
-
|
|
155
|
+
dbg("sec to time error", e=e, l=0)
|
|
138
156
|
sec = 0
|
|
139
157
|
|
|
140
158
|
time = str("{:02d}".format(int(sec // 3600))) + ':' + str("{:02d}".format(int((sec % 3600) // 60))) + ':' + str("{:02d}".format(int(sec % 60)))
|
|
@@ -169,7 +187,7 @@ def validate_start_time_str(start_time_string):
|
|
|
169
187
|
return datetime.strptime(start_time_string,'%Y-%m-%d %H:%M:%S')
|
|
170
188
|
|
|
171
189
|
except Exception as e:
|
|
172
|
-
|
|
190
|
+
dbg('Incorrect Start Time Format', start_time_string+" does no match %Y-%m-%d %H:%M:%S", e=e, l=0)
|
|
173
191
|
return False
|
|
174
192
|
|
|
175
193
|
|
|
@@ -185,7 +203,7 @@ def open_todo(w=None, i=None, item_type = 'tasks'):
|
|
|
185
203
|
|
|
186
204
|
except Exception as e:
|
|
187
205
|
# error_notice('Bonk', "error with "+ c['type']+ " open function ")
|
|
188
|
-
dbg('open_todo
|
|
206
|
+
dbg('open_todo exception, falling back to get_connector_openable ',e=e ,s=todo['type'],l=1)
|
|
189
207
|
|
|
190
208
|
get_connector_openable(None,todo)
|
|
191
209
|
|
|
@@ -266,7 +284,7 @@ def extended_label(i):
|
|
|
266
284
|
o = ' > '.join(l)
|
|
267
285
|
return o
|
|
268
286
|
|
|
269
|
-
|
|
287
|
+
|
|
270
288
|
def lists_cache(new_lists = None, reset = False):
|
|
271
289
|
'''Set or get a dict of (all) lists. If new_lists is supplied it will exclusively use that (until it is replaced or the global lists var is emptied) This is useful (because it can be used wih input when the values are not yet available in the databse) but wonky. '''
|
|
272
290
|
|
|
@@ -366,8 +384,7 @@ def reindex_all():
|
|
|
366
384
|
|
|
367
385
|
|
|
368
386
|
set_system_db_value('taskindex_update_time', now().strftime("%Y-%m-%d %H:%M:%S"))
|
|
369
|
-
|
|
370
|
-
# print('reindex done')
|
|
387
|
+
|
|
371
388
|
timeit()
|
|
372
389
|
|
|
373
390
|
return True
|
|
@@ -384,8 +401,7 @@ def reindex_one(t):
|
|
|
384
401
|
db_query("INSERT INTO taskindex(id, extended_label, priority, status) SELECT id, extended_label, ?, status FROM tasks WHERE id = ? ",(time_target_priority(t),t['id'],))
|
|
385
402
|
|
|
386
403
|
dbg("reindexed",t['label'])
|
|
387
|
-
|
|
388
|
-
# db_query("REPLACE INTO system(field, value) VALUES(?,?)",('taskindex_update_time',now().strftime("%Y-%m-%d %H:%M:%S")))
|
|
404
|
+
|
|
389
405
|
set_system_db_value('taskindex_update_time', now().strftime("%Y-%m-%d %H:%M:%S"))
|
|
390
406
|
|
|
391
407
|
return True
|
|
@@ -393,10 +409,10 @@ def reindex_one(t):
|
|
|
393
409
|
|
|
394
410
|
def taskindex_updated_time():
|
|
395
411
|
''' returns system db taskindex_update_time string formatted as %Y-%m-%d %H:%M:%S '''
|
|
396
|
-
get_system_db_value('taskindex_update_time')
|
|
397
|
-
|
|
398
|
-
update_time = db_query("SELECT value FROM system WHERE field = 'taskindex_update_time'")[0]['value']
|
|
399
412
|
|
|
413
|
+
update_time = get_system_db_value('taskindex_update_time')
|
|
414
|
+
|
|
415
|
+
|
|
400
416
|
# print('taskindex_updated_time',update_time)
|
|
401
417
|
# return datetime.strptime(update_time,'%Y-%m-%d %H:%M:%S')
|
|
402
418
|
return update_time
|
|
@@ -654,7 +670,9 @@ def db_get_item_by_id(id, table = 'tasks',dgb_error_level_for_failure=0):
|
|
|
654
670
|
return {}
|
|
655
671
|
|
|
656
672
|
except Exception as e:
|
|
657
|
-
dbg('db_get_item_by_id failed',e,l=dgb_error_level_for_failure)
|
|
673
|
+
dbg('db_get_item_by_id failed',e=e ,l=dgb_error_level_for_failure)
|
|
674
|
+
return {}
|
|
675
|
+
|
|
658
676
|
|
|
659
677
|
|
|
660
678
|
def get_todo_by_id(todo_or_todo_id = None):
|
|
@@ -704,8 +722,12 @@ def db_save_session(session):
|
|
|
704
722
|
'priority': "0",
|
|
705
723
|
}
|
|
706
724
|
|
|
725
|
+
# dbg('task in db_save_session', session['task'],l=3)
|
|
726
|
+
|
|
707
727
|
if 'priority' in session['task']:
|
|
708
|
-
prepared_session['priority']
|
|
728
|
+
prepared_session['priority'] = str(session['task']['priority'])
|
|
729
|
+
|
|
730
|
+
dbg('db_save_session data:',prepared_session)
|
|
709
731
|
|
|
710
732
|
db_query("INSERT INTO sessions(start_time, duration, task_id, parent_id, todolist, extended_label,timetracker, notes, priority) VALUES(:start_time, :duration, :task_id, :parent_id, :todolist, :extended_label, :timetracker, :notes, :priority )",prepared_session)
|
|
711
733
|
|
|
@@ -792,7 +814,6 @@ def db_set_session_cache(s):
|
|
|
792
814
|
''' Add active session to system db table. Not to be confused with db_save_session '''
|
|
793
815
|
db_session = copy.deepcopy(s)
|
|
794
816
|
db_session['start_time'] = db_session['start_time'].strftime("%Y-%m-%d %H:%M:%S.%f%z")
|
|
795
|
-
|
|
796
817
|
set_system_db_value('session', json.dumps(db_session))
|
|
797
818
|
|
|
798
819
|
|
|
@@ -995,7 +1016,7 @@ def refresh_todolist(todo, catch_errors = False):
|
|
|
995
1016
|
|
|
996
1017
|
except Exception as e:
|
|
997
1018
|
if catch_errors:
|
|
998
|
-
|
|
1019
|
+
dbg(notification='Error Loading '+todo['label']+' i refresh_todolist',e=e,l=0)
|
|
999
1020
|
todos = {'lists': {}, 'tasks':{}}
|
|
1000
1021
|
|
|
1001
1022
|
else:
|
|
@@ -1016,13 +1037,13 @@ def handle_todo_read_error(todo_conf,e):
|
|
|
1016
1037
|
if isinstance(e, (FileExistsError, FileNotFoundError, PermissionError)):
|
|
1017
1038
|
handle_todo_file_access_error(todo_conf,e)
|
|
1018
1039
|
|
|
1019
|
-
dbg(todo_conf['label']+ " Access Error",e,l=0
|
|
1040
|
+
dbg(notification=todo_conf['label']+ " Access Error",e=e ,l=0)
|
|
1020
1041
|
|
|
1021
1042
|
|
|
1022
1043
|
def handle_todo_file_read_error(todo_conf,e):
|
|
1023
1044
|
conf.user['todolists'][todo_conf['id']]['status'] = False
|
|
1024
1045
|
save_user_settings()
|
|
1025
|
-
dbg(todo_conf['label']+ " Deactivated",e,l=-1
|
|
1046
|
+
dbg(notification=todo_conf['label']+ " Deactivated",e=e ,l=-1)
|
|
1026
1047
|
|
|
1027
1048
|
|
|
1028
1049
|
def get_todolists(use_db_cache = False):
|
|
@@ -1058,7 +1079,7 @@ def get_todolists(use_db_cache = False):
|
|
|
1058
1079
|
try:
|
|
1059
1080
|
todos = db_get_todolist(todo['id'])
|
|
1060
1081
|
except Exception as e:
|
|
1061
|
-
|
|
1082
|
+
dbg('Also Failed to load '+todo['label']+' From cache' ,e=e,l=0)
|
|
1062
1083
|
todos = {'lists': {}, 'tasks':{}}
|
|
1063
1084
|
|
|
1064
1085
|
tasks.update(todos['tasks'])
|
|
@@ -1087,7 +1108,7 @@ def get_system_db_value(field, json = False):
|
|
|
1087
1108
|
o = json.loads(o)
|
|
1088
1109
|
return o
|
|
1089
1110
|
except Exception as e:
|
|
1090
|
-
dbg("Error getting",field, 'from system db',e,l=0)
|
|
1111
|
+
dbg("Error getting",field, 'from system db',e=e ,l=0)
|
|
1091
1112
|
|
|
1092
1113
|
|
|
1093
1114
|
def set_system_db_value(field, value, json = False):
|
|
@@ -1098,7 +1119,7 @@ def set_system_db_value(field, value, json = False):
|
|
|
1098
1119
|
db_query("REPLACE INTO system(field, value) VALUES(:field, :value)", {'field':field,'value':value})
|
|
1099
1120
|
|
|
1100
1121
|
except Exception as e:
|
|
1101
|
-
dbg("Error setting", field, value, 'in system db',e,l=0)
|
|
1122
|
+
dbg("Error setting", field, value, 'in system db',e=e ,l=0)
|
|
1102
1123
|
|
|
1103
1124
|
|
|
1104
1125
|
def get_session_from_system_db():
|
|
@@ -1110,7 +1131,7 @@ def get_session_from_system_db():
|
|
|
1110
1131
|
s['start_time'] = datetime.strptime(s['start_time'],'%Y-%m-%d %H:%M:%S.%f')
|
|
1111
1132
|
return s
|
|
1112
1133
|
except Exception as e:
|
|
1113
|
-
dbg("Error in get_session_from_system_db session",e,l=1)
|
|
1134
|
+
dbg("Error in get_session_from_system_db session",e=e ,l=1)
|
|
1114
1135
|
|
|
1115
1136
|
|
|
1116
1137
|
def get_most_recent_list(session = None):
|
|
@@ -1139,11 +1160,14 @@ def get_most_recent_list(session = None):
|
|
|
1139
1160
|
|
|
1140
1161
|
|
|
1141
1162
|
def get_default_list_for_new_tasks():
|
|
1142
|
-
# if conf.user['default_list_for_new_tasks'] != 'Most recently used list':
|
|
1143
|
-
# try:
|
|
1144
1163
|
|
|
1145
|
-
|
|
1164
|
+
if conf.user['default_list_for_new_tasks'] == 'List that was last added to':
|
|
1165
|
+
|
|
1166
|
+
id = get_system_db_value('last_added_to_list_id')
|
|
1167
|
+
if id and id in lists_cache():
|
|
1168
|
+
return lists_cache()[id]
|
|
1146
1169
|
|
|
1170
|
+
# if conf.user['default_list_for_new_tasks'] == 'Most recently used list':
|
|
1147
1171
|
return get_most_recent_list()
|
|
1148
1172
|
|
|
1149
1173
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nowfocus
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.9
|
|
4
4
|
Summary: nowfocus: the open source task-tracking self-control panel.
|
|
5
5
|
Author: AltruistEnterprises
|
|
6
6
|
Project-URL: Homepage, https://www.nowfocus.org
|
|
@@ -121,12 +121,7 @@ nowfocus is a clean, keyboard-driven time management dashboard that flexibly con
|
|
|
121
121
|
```
|
|
122
122
|
bash -c "echo 'open_task_window' > /tmp/nowfocus-pipe"
|
|
123
123
|
```
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
3. Add the following command to your startup applications:
|
|
127
|
-
```
|
|
128
|
-
nowfocus --force
|
|
129
|
-
```
|
|
124
|
+
|
|
130
125
|
|
|
131
126
|
|
|
132
127
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|