nowfocus 0.5.5__py3-none-any.whl → 0.5.7__py3-none-any.whl
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/__main__.py +26 -16
- nowfocus/conf.py +1 -0
- nowfocus/connectors/vikunja.py +9 -51
- nowfocus/desktop-extras/nowfocus.desktop +1 -1
- nowfocus/install.py +0 -1
- nowfocus/new_task_dialog.py +5 -4
- nowfocus/settings.py +1 -1
- nowfocus/task_window.py +1 -7
- nowfocus/upgrade.py +99 -0
- nowfocus/utils.py +111 -131
- {nowfocus-0.5.5.dist-info → nowfocus-0.5.7.dist-info}/METADATA +2 -2
- {nowfocus-0.5.5.dist-info → nowfocus-0.5.7.dist-info}/RECORD +16 -16
- {nowfocus-0.5.5.dist-info → nowfocus-0.5.7.dist-info}/WHEEL +1 -1
- nowfocus/version_migrator.py +0 -20
- {nowfocus-0.5.5.dist-info → nowfocus-0.5.7.dist-info}/entry_points.txt +0 -0
- {nowfocus-0.5.5.dist-info → nowfocus-0.5.7.dist-info}/licenses/LICENSE +0 -0
- {nowfocus-0.5.5.dist-info → nowfocus-0.5.7.dist-info}/top_level.txt +0 -0
nowfocus/__main__.py
CHANGED
|
@@ -62,7 +62,7 @@ class Application(Gtk.Application):
|
|
|
62
62
|
|
|
63
63
|
try:
|
|
64
64
|
|
|
65
|
-
self.window = None
|
|
65
|
+
# self.window = None # Think this is unused
|
|
66
66
|
|
|
67
67
|
self.is_running = False
|
|
68
68
|
self.device_in_use = True
|
|
@@ -83,7 +83,17 @@ class Application(Gtk.Application):
|
|
|
83
83
|
import install
|
|
84
84
|
install.run_first_load_actions()
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
try:
|
|
87
|
+
self.version = importlib.metadata.version(conf.app_id)
|
|
88
|
+
print('nowfocus version', self.version)
|
|
89
|
+
except Exception as e:
|
|
90
|
+
print(e)
|
|
91
|
+
|
|
92
|
+
if get_system_db_value('db_schema_version') != self.version:
|
|
93
|
+
|
|
94
|
+
from upgrade import do_upgrades
|
|
95
|
+
do_upgrades(self)
|
|
96
|
+
|
|
87
97
|
|
|
88
98
|
self.async_refresh()
|
|
89
99
|
|
|
@@ -358,11 +368,8 @@ class Application(Gtk.Application):
|
|
|
358
368
|
|
|
359
369
|
def resume_session_from_db(self):
|
|
360
370
|
try:
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if db_session:
|
|
364
|
-
s = json.loads(db_session[0]['value'])
|
|
365
|
-
s['start_time'] = datetime.strptime(s['start_time'],'%Y-%m-%d %H:%M:%S.%f')
|
|
371
|
+
s = get_session_from_system_db()
|
|
372
|
+
if s:
|
|
366
373
|
self.session = s
|
|
367
374
|
self.is_running = True
|
|
368
375
|
dbg("resuming session",s['label'],l=2, s='session')
|
|
@@ -470,7 +477,7 @@ class Application(Gtk.Application):
|
|
|
470
477
|
process.wait()
|
|
471
478
|
else:
|
|
472
479
|
print("Launching command with subprocess.run", command)
|
|
473
|
-
subprocess.run(command)
|
|
480
|
+
subprocess.run(command,shell=True)
|
|
474
481
|
|
|
475
482
|
print("running task command complete:", command)
|
|
476
483
|
|
|
@@ -524,14 +531,17 @@ class Application(Gtk.Application):
|
|
|
524
531
|
|
|
525
532
|
# Get time tracker for this tasks todolist
|
|
526
533
|
todolist_conf = conf.user['todolists'][task['todolist']]
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
534
|
+
|
|
535
|
+
if 'timetracker' in todolist_conf:
|
|
536
|
+
|
|
537
|
+
dbg("Save Session to "+ todolist_conf['timetracker'])
|
|
538
|
+
try:
|
|
539
|
+
|
|
540
|
+
timetracker_conf = conf.user['timetrackers'][todolist_conf['timetracker']]
|
|
541
|
+
save_thread = threading.Thread(target=conf.timetracker_connectors[timetracker_conf['type']].save_session, args=(session,timetracker_conf) )
|
|
542
|
+
save_thread.start()
|
|
543
|
+
except Exception as e:
|
|
544
|
+
error_notice('Error Saving Time Data'," Recording timetracking for "+ task['label']+" in "+timetracker_conf['label']+" had a serious failure",e )
|
|
535
545
|
|
|
536
546
|
session['timetracker'] = todolist_conf['timetracker']
|
|
537
547
|
|
nowfocus/conf.py
CHANGED
nowfocus/connectors/vikunja.py
CHANGED
|
@@ -18,7 +18,7 @@ def add_new_task(user_conf,parent_list,task_label):
|
|
|
18
18
|
headers = {'content-type': 'application/json'}
|
|
19
19
|
data = {'title': task_label}
|
|
20
20
|
|
|
21
|
-
utils.dbg('
|
|
21
|
+
utils.dbg('add new task to ',parent_list, l=-1)
|
|
22
22
|
|
|
23
23
|
response = requests.put(user_conf['url']+"api/v1/projects/"+str(parent_list['data']['id'])+"/tasks",json=data, headers=head)
|
|
24
24
|
|
|
@@ -103,11 +103,17 @@ def get_todos(user_conf):
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
headers = {"Authorization": "Bearer "+user_conf['token']}
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
response = requests.get(user_conf['url']+"api/v1/projects", headers=headers)
|
|
107
|
+
# print("response.headers")
|
|
108
|
+
# print(response.headers)
|
|
109
|
+
projects_lists = response.json()
|
|
108
110
|
# print("vikunja projects")
|
|
109
111
|
# print(json.dumps(projects_lists, indent=4))
|
|
110
112
|
|
|
113
|
+
if 'message' in projects_lists:
|
|
114
|
+
# This occurs with an expired token
|
|
115
|
+
utils.dbg(projects_lists['message'], notification="Vikunja API Error: "+projects_lists['message'], s='vikunja', l=0)
|
|
116
|
+
|
|
111
117
|
# for i in projects_list:
|
|
112
118
|
for i, itemIter in enumerate(projects_lists):
|
|
113
119
|
|
|
@@ -155,54 +161,6 @@ def get_todos(user_conf):
|
|
|
155
161
|
if lists[parent_id]['status'] == -1:
|
|
156
162
|
lists[id]['status'] = -1
|
|
157
163
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# NOTE: Originally tasks where queried per list, however this no longer works well because it requires a 'view' id, which comes wih various un-predictable baked-in filters (like done=true). Using the tasks/all api endpoint avoids this but quickly hits the default maxitemsperpage limit (which could, less obviously, show up in the per list method).
|
|
161
|
-
|
|
162
|
-
# else: print('parent_project_id', p['parent_project_id'], 'not in projects_lists')
|
|
163
|
-
|
|
164
|
-
# view_id = p['views'][0]['id']
|
|
165
|
-
# utils.dbg({'view_id':view_id},'vikunja')
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
# Including 'done' tasks (Doesn't seem o includ them actually)'
|
|
169
|
-
# projects_tasks = requests.get(user_conf['url']+"api/v1/projects/"+str(p['id'])+"/views/"+str(view_id)+"/tasks?sort_by[]=position&order_by[]=asc&equalspage=1", headers=headers).json()
|
|
170
|
-
|
|
171
|
-
# Filtering out done tasks, Works
|
|
172
|
-
# projects_tasks = requests.get(user_conf['url']+"api/v1/projects/"+str(p['id'])+"/views/"+str(view_id)+"/tasks?sort_by[]=position&order_by[]=asc&filter_by[]=done&filter_value[]=false&filter_comparator[]=equals&filter_comparator[]=equalspage=1", headers=headers).json()
|
|
173
|
-
|
|
174
|
-
# projects_tasks = requests.get(user_conf['url']+"api/v1/projects/"+str(p['id'])+"/tasks", headers=headers).json()
|
|
175
|
-
|
|
176
|
-
# print("vikunja projects_tasks")
|
|
177
|
-
# print(json.dumps(projects_tasks, indent=4))
|
|
178
|
-
# utils.pretty_print(projects_tasks)
|
|
179
|
-
|
|
180
|
-
# for i, itemIter in enumerate(projects_tasks):
|
|
181
|
-
|
|
182
|
-
# t = projects_tasks[i]
|
|
183
|
-
# t['id'] = str(t['id'])
|
|
184
|
-
|
|
185
|
-
# tasks[t['id']] = {
|
|
186
|
-
# 'id':t['id'],
|
|
187
|
-
# 'label':t['title'],
|
|
188
|
-
# 'parent_id':p['id'],
|
|
189
|
-
# 'parent_label':p['title'],
|
|
190
|
-
# 'todolist':user_conf['id'],
|
|
191
|
-
# 'data':t
|
|
192
|
-
# }
|
|
193
|
-
|
|
194
|
-
# if t['done'] == True:
|
|
195
|
-
# tasks[t['id']]['status'] = False
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
# # Show favorites in main menu
|
|
199
|
-
# if t['is_favorite'] == True:
|
|
200
|
-
# tasks[t['id']]['priority'] = 1
|
|
201
|
-
# elif t['priority'] in priorities:
|
|
202
|
-
# print("Priority task", t['title'])
|
|
203
|
-
# tasks[t['id']]['priority'] = priorities[t['priority']]
|
|
204
|
-
# print(tasks[t['id']])
|
|
205
|
-
|
|
206
164
|
# beware per_page config ( generally in /opt/vikunja/config.yml) maxitemsperpage defaults to 20 so this really won't work on a default setup
|
|
207
165
|
# maxitemsperpage: 5000
|
|
208
166
|
# ?per_page=10000
|
nowfocus/install.py
CHANGED
nowfocus/new_task_dialog.py
CHANGED
|
@@ -44,10 +44,9 @@ class NewTaskWDialog(Gtk.Dialog):
|
|
|
44
44
|
box.add(Gtk.Box(border_width=10)) #spacer
|
|
45
45
|
|
|
46
46
|
default_list = get_most_recent_list(self.app.session)
|
|
47
|
-
if default_list:
|
|
48
|
-
self.selected_list = db_get_item_by_id(default_list,table='lists')
|
|
49
47
|
|
|
50
|
-
box.add(choose_from_lists(self.select_list, default_list))
|
|
48
|
+
box.add(choose_from_lists(self.select_list, default_list['id']))
|
|
49
|
+
self.selected_list = default_list
|
|
51
50
|
|
|
52
51
|
box.add(Gtk.Box(border_width=10)) #spacer
|
|
53
52
|
|
|
@@ -80,7 +79,9 @@ class NewTaskWDialog(Gtk.Dialog):
|
|
|
80
79
|
task_label = self.task_label_entry.get_text().strip()
|
|
81
80
|
|
|
82
81
|
if not task_label:
|
|
83
|
-
|
|
82
|
+
self.task_label_entry.grab_focus()
|
|
83
|
+
self.task_label_entry.set_placeholder_text('Please enter a task')
|
|
84
|
+
# error_notice("Please Enter a name before saving new task")
|
|
84
85
|
return False
|
|
85
86
|
|
|
86
87
|
parent_list = self.selected_list
|
nowfocus/settings.py
CHANGED
|
@@ -923,7 +923,7 @@ class EditAddConnectorDialog(Gtk.Dialog):
|
|
|
923
923
|
|
|
924
924
|
|
|
925
925
|
if key in ['file']:
|
|
926
|
-
self.entries[key] = Gtk.FileChooserButton(title="Select
|
|
926
|
+
self.entries[key] = Gtk.FileChooserButton(title="Select "+connector_category+" file")
|
|
927
927
|
self.entries[key].set_action(Gtk.FileChooserAction.OPEN)
|
|
928
928
|
|
|
929
929
|
else:
|
nowfocus/task_window.py
CHANGED
|
@@ -399,16 +399,10 @@ class TaskWindow(Gtk.Window):
|
|
|
399
399
|
self.r_sidebar.pack_start(self.sessions_scrolledwindow, True, True, 0)
|
|
400
400
|
|
|
401
401
|
self.sessions_box = Gtk.VBox(spacing=5)
|
|
402
|
-
# self.sessions_box.get_style_context().add_class("subtle")
|
|
403
402
|
self.sessions_scrolledwindow.add(self.sessions_box)
|
|
404
403
|
|
|
405
|
-
# self.r_sidebar.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK)
|
|
406
|
-
# self.r_sidebar.add_events(Gdk.EventMask.LEAVE_NOTIFY_MASK)
|
|
407
|
-
# self.r_sidebar.connect("enter-notify-event",self.test)
|
|
408
|
-
# session = None, accepts_tasks = True, skip_top_level_lists = False, show_todolist_headers = True, deduplicate = False, truncate_labels_to_chars = 100
|
|
409
|
-
|
|
410
404
|
self.l_sidebar.add(choose_from_lists(
|
|
411
|
-
self.select_list_callback, 'None', None, accepts_tasks=False,
|
|
405
|
+
self.select_list_callback, 'None', None, accepts_tasks=False, show_todolist_headers=True, truncate_labels_to_chars=20))
|
|
412
406
|
|
|
413
407
|
self.SessionEditDialog = SessionEditDialog # passed to show_sessions via self
|
|
414
408
|
sidebar_sessions = get_sessions(use_sessions_timeframe_setting=False)
|
nowfocus/upgrade.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import conf
|
|
2
|
+
from utils import *
|
|
3
|
+
# from pkg_resources import parse_version
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def do_upgrades(app):
|
|
7
|
+
db_schema_version = get_system_db_value('db_schema_version')
|
|
8
|
+
|
|
9
|
+
if db_schema_version == '0.2':
|
|
10
|
+
|
|
11
|
+
db_query("ALTER TABLE lists DROP COLUMN status")
|
|
12
|
+
db_query("ALTER TABLE tasks DROP COLUMN status")
|
|
13
|
+
|
|
14
|
+
db_query("ALTER TABLE lists ADD COLUMN status INTEGER DEFAULT 1")
|
|
15
|
+
db_query("ALTER TABLE tasks ADD COLUMN status INTEGER DEFAULT 1")
|
|
16
|
+
|
|
17
|
+
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.3')")
|
|
18
|
+
|
|
19
|
+
db_schema_version = '0.3'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if db_schema_version == '0.3':
|
|
23
|
+
db_query("ALTER TABLE sessions ADD COLUMN timetracker TEXT")
|
|
24
|
+
db_query("ALTER TABLE sessions ADD COLUMN notes TEXT")
|
|
25
|
+
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.4')")
|
|
26
|
+
print('adding timetracker column to session table')
|
|
27
|
+
|
|
28
|
+
for todolist_id, todo in conf.user['todolists'].items():
|
|
29
|
+
db_query("UPDATE sessions SET timetracker = ? WHERE todolist = ?",(todo['timetracker'],todolist_id) )
|
|
30
|
+
|
|
31
|
+
db_schema_version = '0.4'
|
|
32
|
+
|
|
33
|
+
if db_schema_version == '0.4':
|
|
34
|
+
dbg('Schema Update from', db_schema_version, 'to 0.5',l=-1)
|
|
35
|
+
|
|
36
|
+
print('Adding priority column to session table')
|
|
37
|
+
|
|
38
|
+
db_query("ALTER TABLE sessions ADD COLUMN priority INTEGER DEFAULT 0")
|
|
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
|
+
|
|
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
|
+
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.5')")
|
|
49
|
+
|
|
50
|
+
db_schema_version = '0.5'
|
|
51
|
+
|
|
52
|
+
if db_schema_version == '0.5':
|
|
53
|
+
dbg('Schema Update from', db_schema_version, 'to 0.5.6',l=-1)
|
|
54
|
+
|
|
55
|
+
from install import copy_desktop_integration_files
|
|
56
|
+
copy_desktop_integration_files()
|
|
57
|
+
|
|
58
|
+
db_schema_version = "0.5.6"
|
|
59
|
+
set_system_db_value("db_schema_version",db_schema_version)
|
|
60
|
+
|
|
61
|
+
# if db_schema_version == 0.5:
|
|
62
|
+
# db_query("ALTER TABLE tasks ADD COLUMN tags TEXT DEFAULT '{}'")
|
|
63
|
+
# db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.5')")
|
|
64
|
+
# db_schema_version = 0.6
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
dbg('db_schema_version updated to', db_schema_version,s='db')
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# update time_target format
|
|
82
|
+
# for id, tt in user['time_targets']['lists'].items():
|
|
83
|
+
# if 'within_value' not in tt:
|
|
84
|
+
# print("Updating time target to new format ",tt)
|
|
85
|
+
# tt['within_value'] = tt['num_days']
|
|
86
|
+
# tt['within_unit'] = 'days'
|
|
87
|
+
# print(tt)
|
|
88
|
+
# if 'status' not in tt:
|
|
89
|
+
# tt['status'] = True
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# for id, tt in user['time_targets']['tasks'].items():
|
|
93
|
+
# if 'within_value' not in tt:
|
|
94
|
+
# print("Updating time target to new format ",tt)
|
|
95
|
+
# tt['within_value'] = tt['num_days']
|
|
96
|
+
# tt['within_unit'] = 'days'
|
|
97
|
+
# print(tt)
|
|
98
|
+
# if 'status' not in tt:
|
|
99
|
+
# tt['status'] = True
|
nowfocus/utils.py
CHANGED
|
@@ -7,7 +7,6 @@ from datetime import datetime, timezone, timedelta
|
|
|
7
7
|
from dateutil.relativedelta import relativedelta
|
|
8
8
|
import copy
|
|
9
9
|
import threading
|
|
10
|
-
|
|
11
10
|
import sqlite3
|
|
12
11
|
from contextlib import closing
|
|
13
12
|
from pathlib import Path
|
|
@@ -30,11 +29,11 @@ notify.init(conf.app_name)
|
|
|
30
29
|
lists = {}
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
def dbg(*data, s="", l=2, e=None,
|
|
32
|
+
def dbg(*data, s="", l=2, e=None, notification=None):
|
|
34
33
|
''' Any number of positional args optionally
|
|
35
34
|
l: level {-1: Default output, 0:Error, 1:Warning, 2:Info, 3:Details}
|
|
36
35
|
s: system (Debuggable systems: 'taskwindow','signals','todoloading','user_settings', 'targets', 'performance')
|
|
37
|
-
|
|
36
|
+
notification: Show a notification with the content of notification.
|
|
38
37
|
e (Exception object) traceback will be printed
|
|
39
38
|
|
|
40
39
|
'''
|
|
@@ -47,8 +46,8 @@ def dbg(*data, s="", l=2, e=None, notify=None):
|
|
|
47
46
|
|
|
48
47
|
if "all" in conf.debug_systems or system in conf.debug_systems or level <= conf.debug_level:
|
|
49
48
|
|
|
50
|
-
if
|
|
51
|
-
notify.Notification.new(conf.app_name+" "+levels[level], str(
|
|
49
|
+
if notification:
|
|
50
|
+
notify.Notification.new(conf.app_name+" "+levels[level], str(notification), None).show()
|
|
52
51
|
|
|
53
52
|
filter(None,data)
|
|
54
53
|
if len(data) == 1:
|
|
@@ -68,7 +67,7 @@ def dbg(*data, s="", l=2, e=None, notify=None):
|
|
|
68
67
|
|
|
69
68
|
if e and isinstance(e,Exception):
|
|
70
69
|
traceback.print_tb(e.__traceback__)
|
|
71
|
-
print(e)
|
|
70
|
+
print(e,"\n")
|
|
72
71
|
|
|
73
72
|
def error_notice(title, details = None, e = None):
|
|
74
73
|
print('ERROR',title,details,e)
|
|
@@ -268,20 +267,20 @@ def extended_label(i):
|
|
|
268
267
|
return o
|
|
269
268
|
|
|
270
269
|
# TODO cleanup this
|
|
271
|
-
def lists_cache(new_lists = None):
|
|
272
|
-
'''Set or get a dict of (all) lists.
|
|
270
|
+
def lists_cache(new_lists = None, reset = False):
|
|
271
|
+
'''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
|
+
|
|
273
273
|
global lists
|
|
274
274
|
|
|
275
275
|
if(new_lists):
|
|
276
276
|
lists = new_lists
|
|
277
|
-
# TODO: add
|
|
277
|
+
# TODO: add a param to append to the existing lists rather than overwriting...
|
|
278
278
|
|
|
279
|
-
elif
|
|
280
|
-
lists = db_query('SELECT * FROM lists WHERE status = 1 ORDER BY extended_label DESC',None, 'id')
|
|
279
|
+
elif reset or lists == {}:
|
|
280
|
+
lists = db_query('SELECT * FROM lists WHERE status = 1 ORDER BY extended_label DESC',None, 'id')
|
|
281
281
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
lists[l['id']]['data'] = json.loads(l['data'])
|
|
282
|
+
for id, l in lists.items():
|
|
283
|
+
lists[l['id']] = proc_db_item(l,'lists')
|
|
285
284
|
|
|
286
285
|
return lists
|
|
287
286
|
|
|
@@ -336,7 +335,7 @@ def db_query(sql,parameters=None,key=None,error_handling=1):
|
|
|
336
335
|
return result
|
|
337
336
|
|
|
338
337
|
except Exception as e:
|
|
339
|
-
dbg(
|
|
338
|
+
dbg("sql",sql,'parameters',parameters,s="db",l=0,e=e)
|
|
340
339
|
if error_handling > 0:
|
|
341
340
|
error_notice("database error",str(e))
|
|
342
341
|
if error_handling > 1:
|
|
@@ -347,88 +346,6 @@ def db_query(sql,parameters=None,key=None,error_handling=1):
|
|
|
347
346
|
return []
|
|
348
347
|
|
|
349
348
|
|
|
350
|
-
def db_schema_update():
|
|
351
|
-
|
|
352
|
-
try:
|
|
353
|
-
db_schema_version = float(db_query("SELECT field, value FROM system WHERE field = 'db_schema_version' ",error_handling=2)[0]['value'])
|
|
354
|
-
except Exception as e:
|
|
355
|
-
print("Updating db_schema_version to 0.2")
|
|
356
|
-
|
|
357
|
-
db_query("CREATE TABLE system (field TEXT PRIMARY KEY NOT NULL, value TEXT)")
|
|
358
|
-
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.2')")
|
|
359
|
-
|
|
360
|
-
db_schema_version = float(db_query("SELECT field, value FROM system WHERE field = 'db_schema_version' ")[0]['value'])
|
|
361
|
-
|
|
362
|
-
db_query("ALTER TABLE lists ADD COLUMN status INTEGER DEFAULT 1")
|
|
363
|
-
db_query("ALTER TABLE tasks ADD COLUMN status INTEGER DEFAULT 1")
|
|
364
|
-
|
|
365
|
-
db_query("ALTER TABLE lists ADD COLUMN extended_label TEXT")
|
|
366
|
-
db_query("ALTER TABLE tasks ADD COLUMN extended_label TEXT")
|
|
367
|
-
|
|
368
|
-
db_query("ALTER TABLE sessions ADD COLUMN extended_label TEXT")
|
|
369
|
-
|
|
370
|
-
# Since these column are just a cache, replace instead of copying columns
|
|
371
|
-
db_query("ALTER TABLE tasks DROP COLUMN priority")
|
|
372
|
-
db_query("ALTER TABLE tasks DROP COLUMN data")
|
|
373
|
-
db_query("ALTER TABLE lists DROP COLUMN priority")
|
|
374
|
-
db_query("ALTER TABLE lists DROP COLUMN data")
|
|
375
|
-
|
|
376
|
-
db_query("ALTER TABLE lists ADD COLUMN priority INTEGER DEFAULT 0")
|
|
377
|
-
db_query("ALTER TABLE lists ADD COLUMN data TEXT DEFAULT '{}'")
|
|
378
|
-
db_query("ALTER TABLE tasks ADD COLUMN priority INTEGER DEFAULT 0")
|
|
379
|
-
db_query("ALTER TABLE tasks ADD COLUMN data TEXT DEFAULT '{}'")
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
if db_schema_version == 0.2:
|
|
383
|
-
|
|
384
|
-
db_query("ALTER TABLE lists DROP COLUMN status")
|
|
385
|
-
db_query("ALTER TABLE tasks DROP COLUMN status")
|
|
386
|
-
|
|
387
|
-
db_query("ALTER TABLE lists ADD COLUMN status INTEGER DEFAULT 1")
|
|
388
|
-
db_query("ALTER TABLE tasks ADD COLUMN status INTEGER DEFAULT 1")
|
|
389
|
-
|
|
390
|
-
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.3')")
|
|
391
|
-
|
|
392
|
-
db_schema_version = 0.3
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
if db_schema_version == 0.3:
|
|
396
|
-
db_query("ALTER TABLE sessions ADD COLUMN timetracker TEXT")
|
|
397
|
-
db_query("ALTER TABLE sessions ADD COLUMN notes TEXT")
|
|
398
|
-
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.4')")
|
|
399
|
-
print('adding timetracker column to session table')
|
|
400
|
-
|
|
401
|
-
for todolist_id, todo in conf.user['todolists'].items():
|
|
402
|
-
db_query("UPDATE sessions SET timetracker = ? WHERE todolist = ?",(todo['timetracker'],todolist_id) )
|
|
403
|
-
|
|
404
|
-
db_schema_version = 0.4
|
|
405
|
-
|
|
406
|
-
if db_schema_version == 0.4:
|
|
407
|
-
print('Adding priority column to session table')
|
|
408
|
-
|
|
409
|
-
db_query("ALTER TABLE sessions ADD COLUMN priority INTEGER DEFAULT 0")
|
|
410
|
-
|
|
411
|
-
for session in db_query("SELECT DISTINCT task_id, extended_label FROM sessions"):
|
|
412
|
-
t = db_get_item_by_id(session['task_id'],dgb_error_level_for_failure=3)
|
|
413
|
-
if t and t['priority'] > 0:
|
|
414
|
-
print("setting",session['extended_label']," session priority to ",t['priority'] )
|
|
415
|
-
|
|
416
|
-
db_query("UPDATE sessions SET priority = ? WHERE task_id = ?",(t['priority'],session['task_id']))
|
|
417
|
-
|
|
418
|
-
print("Total hours priority sessions",round(divide(db_query("SELECT SUM(duration) as total FROM sessions WHERE priority > 0")[0]['total'],3600),2))
|
|
419
|
-
db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.5')")
|
|
420
|
-
|
|
421
|
-
db_schema_version = 0.5
|
|
422
|
-
|
|
423
|
-
# if db_schema_version == 0.5:
|
|
424
|
-
# db_query("ALTER TABLE tasks ADD COLUMN tags TEXT DEFAULT '{}'")
|
|
425
|
-
# db_query("REPLACE INTO system(field, value) VALUES('db_schema_version', '0.5')")
|
|
426
|
-
# db_schema_version = 0.6
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
dbg('db_schema_version', db_schema_version,s='db')
|
|
430
|
-
|
|
431
|
-
|
|
432
349
|
def reindex(t=None):
|
|
433
350
|
if t:
|
|
434
351
|
thread = threading.Thread(target=reindex_one,args=(t,))
|
|
@@ -447,7 +364,9 @@ def reindex_all():
|
|
|
447
364
|
for tid, t in get_timetarget_priority_tasks().items():
|
|
448
365
|
db_query("UPDATE taskindex set priority = ? WHERE id = ?",(t['priority'],t['id']))
|
|
449
366
|
|
|
450
|
-
|
|
367
|
+
|
|
368
|
+
set_system_db_value('taskindex_update_time', now().strftime("%Y-%m-%d %H:%M:%S"))
|
|
369
|
+
# db_query("REPLACE INTO system(field, value) VALUES(?,?)",('taskindex_update_time',now().strftime("%Y-%m-%d %H:%M:%S")))
|
|
451
370
|
# print('reindex done')
|
|
452
371
|
timeit()
|
|
453
372
|
|
|
@@ -464,14 +383,18 @@ def reindex_one(t):
|
|
|
464
383
|
|
|
465
384
|
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'],))
|
|
466
385
|
|
|
467
|
-
|
|
386
|
+
dbg("reindexed",t['label'])
|
|
468
387
|
# print(db_query("SELECT * FROM taskindex where id = ?",(t['id'],)))
|
|
469
|
-
db_query("REPLACE INTO system(field, value) VALUES(?,?)",('taskindex_update_time',now().strftime("%Y-%m-%d %H:%M:%S")))
|
|
388
|
+
# db_query("REPLACE INTO system(field, value) VALUES(?,?)",('taskindex_update_time',now().strftime("%Y-%m-%d %H:%M:%S")))
|
|
389
|
+
set_system_db_value('taskindex_update_time', now().strftime("%Y-%m-%d %H:%M:%S"))
|
|
390
|
+
|
|
470
391
|
return True
|
|
471
392
|
|
|
472
393
|
|
|
473
394
|
def taskindex_updated_time():
|
|
474
395
|
''' returns system db taskindex_update_time string formatted as %Y-%m-%d %H:%M:%S '''
|
|
396
|
+
get_system_db_value('taskindex_update_time')
|
|
397
|
+
|
|
475
398
|
update_time = db_query("SELECT value FROM system WHERE field = 'taskindex_update_time'")[0]['value']
|
|
476
399
|
|
|
477
400
|
# print('taskindex_updated_time',update_time)
|
|
@@ -631,7 +554,7 @@ def db_set_todolist(todolist_id,lists,tasks):
|
|
|
631
554
|
insert_tasks[id] = db_prepare_item(i,'tasks')
|
|
632
555
|
|
|
633
556
|
# Clear incomplete lists cache
|
|
634
|
-
lists_cache(
|
|
557
|
+
lists_cache(reset=True)
|
|
635
558
|
|
|
636
559
|
# for testing
|
|
637
560
|
# insert_tasks = {'3':insert_tasks['3'],'294':insert_tasks['294']}
|
|
@@ -709,13 +632,17 @@ def db_cleanup(widget = None):
|
|
|
709
632
|
|
|
710
633
|
# exit()
|
|
711
634
|
|
|
712
|
-
def db_get_item_by_id(id,table = 'tasks',dgb_error_level_for_failure=0):
|
|
635
|
+
def db_get_item_by_id(id, table = 'tasks',dgb_error_level_for_failure=0):
|
|
713
636
|
|
|
714
637
|
if table in ['task','list']:
|
|
715
638
|
table = table+'s'
|
|
716
639
|
if table not in ['tasks','lists']:
|
|
717
640
|
dbg('bad table "'+str(table)+'" passed to db_get_item_by_id',id,l=0)
|
|
718
641
|
return {}
|
|
642
|
+
|
|
643
|
+
# in case an item dict was passed instead of an id
|
|
644
|
+
if isinstance(id, dict):
|
|
645
|
+
return id
|
|
719
646
|
|
|
720
647
|
try:
|
|
721
648
|
data = db_query("SELECT * FROM "+table+" WHERE id = ?",(id,))
|
|
@@ -865,7 +792,8 @@ def db_set_session_cache(s):
|
|
|
865
792
|
''' Add active session to system db table. Not to be confused with db_save_session '''
|
|
866
793
|
db_session = copy.deepcopy(s)
|
|
867
794
|
db_session['start_time'] = db_session['start_time'].strftime("%Y-%m-%d %H:%M:%S.%f%z")
|
|
868
|
-
|
|
795
|
+
|
|
796
|
+
set_system_db_value('session', json.dumps(db_session))
|
|
869
797
|
|
|
870
798
|
|
|
871
799
|
def get_total_time(id, category = 'tasks', start_time = None, end_time = None, get_minutes = None):
|
|
@@ -1057,17 +985,17 @@ def refresh_todolist(todo, catch_errors = False):
|
|
|
1057
985
|
''' Refresh a single todo. runs db_set_todolist and returns todos. Exceptions must be handled my caller '''
|
|
1058
986
|
|
|
1059
987
|
try:
|
|
1060
|
-
dbg('Refreshing '+todo['label'],l
|
|
988
|
+
dbg('Refreshing '+todo['label'],l=2)
|
|
1061
989
|
|
|
1062
990
|
todos = conf.todo_connectors[todo['type']].get_todos(todo)
|
|
1063
991
|
|
|
1064
|
-
dbg('
|
|
992
|
+
dbg('Refreshing '+todo['label'],l=-1)
|
|
1065
993
|
|
|
1066
994
|
db_set_todolist(todo['id'],todos['lists'],todos['tasks'])
|
|
1067
995
|
|
|
1068
996
|
except Exception as e:
|
|
1069
997
|
if catch_errors:
|
|
1070
|
-
|
|
998
|
+
dbb(notify='Error Loading '+todo['label']+' i refresh_todolist',e=e)
|
|
1071
999
|
todos = {'lists': {}, 'tasks':{}}
|
|
1072
1000
|
|
|
1073
1001
|
else:
|
|
@@ -1088,13 +1016,13 @@ def handle_todo_read_error(todo_conf,e):
|
|
|
1088
1016
|
if isinstance(e, (FileExistsError, FileNotFoundError, PermissionError)):
|
|
1089
1017
|
handle_todo_file_access_error(todo_conf,e)
|
|
1090
1018
|
|
|
1091
|
-
dbg(todo_conf['label']+ " Access Error",e,l=0,
|
|
1019
|
+
dbg(todo_conf['label']+ " Access Error",e,l=0,notification=True)
|
|
1092
1020
|
|
|
1093
1021
|
|
|
1094
1022
|
def handle_todo_file_read_error(todo_conf,e):
|
|
1095
1023
|
conf.user['todolists'][todo_conf['id']]['status'] = False
|
|
1096
1024
|
save_user_settings()
|
|
1097
|
-
dbg(todo_conf['label']+ " Deactivated",e,l=-1,
|
|
1025
|
+
dbg(todo_conf['label']+ " Deactivated",e,l=-1,notification=True)
|
|
1098
1026
|
|
|
1099
1027
|
|
|
1100
1028
|
def get_todolists(use_db_cache = False):
|
|
@@ -1125,12 +1053,12 @@ def get_todolists(use_db_cache = False):
|
|
|
1125
1053
|
if conf.debug_level == 3 or 'todoloading' in conf.debug_systems or todo['type'] in conf.debug_systems :
|
|
1126
1054
|
raise e
|
|
1127
1055
|
|
|
1128
|
-
|
|
1056
|
+
dbg(notification='Error refreshing '+todo['label'],e=e)
|
|
1129
1057
|
|
|
1130
1058
|
try:
|
|
1131
1059
|
todos = db_get_todolist(todo['id'])
|
|
1132
1060
|
except Exception as e:
|
|
1133
|
-
error_notice('Also Failed to load '+todo['label']+' From cache' ,e)
|
|
1061
|
+
error_notice('Also Failed to load '+todo['label']+' From cache' ,e=e)
|
|
1134
1062
|
todos = {'lists': {}, 'tasks':{}}
|
|
1135
1063
|
|
|
1136
1064
|
tasks.update(todos['tasks'])
|
|
@@ -1147,17 +1075,79 @@ def get_todolists(use_db_cache = False):
|
|
|
1147
1075
|
return o
|
|
1148
1076
|
|
|
1149
1077
|
|
|
1078
|
+
def get_system_db_value(field, json = False):
|
|
1079
|
+
try:
|
|
1080
|
+
o = db_query("SELECT value FROM system WHERE field = ? ",(field,))
|
|
1081
|
+
if o:
|
|
1082
|
+
o = o[0]['value']
|
|
1083
|
+
else:
|
|
1084
|
+
dbg('no system_db_value for', field, l=1)
|
|
1085
|
+
|
|
1086
|
+
if json:
|
|
1087
|
+
o = json.loads(o)
|
|
1088
|
+
return o
|
|
1089
|
+
except Exception as e:
|
|
1090
|
+
dbg("Error getting",field, 'from system db',e,l=0)
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
def set_system_db_value(field, value, json = False):
|
|
1094
|
+
try:
|
|
1095
|
+
if json:
|
|
1096
|
+
value = json.dumps(value)
|
|
1097
|
+
|
|
1098
|
+
db_query("REPLACE INTO system(field, value) VALUES(:field, :value)", {'field':field,'value':value})
|
|
1099
|
+
|
|
1100
|
+
except Exception as e:
|
|
1101
|
+
dbg("Error setting", field, value, 'in system db',e,l=0)
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
def get_session_from_system_db():
|
|
1105
|
+
try:
|
|
1106
|
+
db_session = db_query("SELECT value FROM system WHERE field = 'session'")
|
|
1107
|
+
|
|
1108
|
+
if db_session:
|
|
1109
|
+
s = json.loads(db_session[0]['value'])
|
|
1110
|
+
s['start_time'] = datetime.strptime(s['start_time'],'%Y-%m-%d %H:%M:%S.%f')
|
|
1111
|
+
return s
|
|
1112
|
+
except Exception as e:
|
|
1113
|
+
dbg("Error in get_session_from_system_db session",e,l=1)
|
|
1114
|
+
|
|
1115
|
+
|
|
1150
1116
|
def get_most_recent_list(session = None):
|
|
1117
|
+
''' returns a list object '''
|
|
1118
|
+
lists = lists_cache()
|
|
1119
|
+
# print(lists.keys())
|
|
1120
|
+
|
|
1121
|
+
try:
|
|
1122
|
+
return lists[session['task']['parent_id']]
|
|
1123
|
+
|
|
1124
|
+
except Exception as e:
|
|
1125
|
+
pass
|
|
1126
|
+
|
|
1127
|
+
try:
|
|
1128
|
+
return lists[get_session_from_system_db()['task']['parent_id']]
|
|
1129
|
+
|
|
1130
|
+
except Exception as e:
|
|
1131
|
+
pass
|
|
1132
|
+
|
|
1133
|
+
try:
|
|
1134
|
+
return lists[db_query("SELECT parent_id FROM sessions WHERE parent_id IN (SELECT id FROM lists WHERE status = 1) ORDER BY sessions.start_time DESC LIMIT 1")[0]['parent_id']]
|
|
1135
|
+
|
|
1136
|
+
except Exception as e:
|
|
1137
|
+
return lists.items()[0]
|
|
1151
1138
|
|
|
1152
|
-
if session and 'task' in session and 'parent_id' in session['task']:
|
|
1153
|
-
return session['task']['parent_id']
|
|
1154
1139
|
|
|
1155
|
-
last_session = db_query("SELECT parent_id FROM sessions WHERE parent_id IN (SELECT id FROM lists WHERE status = 1) ORDER BY sessions.start_time DESC LIMIT 1")
|
|
1156
|
-
if last_session:
|
|
1157
|
-
return last_session[0]['parent_id']
|
|
1158
1140
|
|
|
1141
|
+
def get_default_list_for_new_tasks():
|
|
1142
|
+
# if conf.user['default_list_for_new_tasks'] != 'Most recently used list':
|
|
1143
|
+
# try:
|
|
1159
1144
|
|
|
1160
|
-
|
|
1145
|
+
# List that was last added to
|
|
1146
|
+
|
|
1147
|
+
return get_most_recent_list()
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
def choose_from_lists(callback, selected_list_id = None, session = None, accepts_tasks = True, show_todolist_headers = True, truncate_labels_to_chars = 100):
|
|
1161
1151
|
''' Returns a Gtk.ScrolledWindow widget with radio buttons'''
|
|
1162
1152
|
|
|
1163
1153
|
# TODO: consider using TreeView https://lazka.github.io/pgi-docs/Gtk-3.0/classes/TreeView.html#Gtk.TreeView
|
|
@@ -1175,28 +1165,20 @@ def choose_from_lists(callback, selected_list_id = None, session = None, accepts
|
|
|
1175
1165
|
# scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
|
|
1176
1166
|
scrolled_window.add(box)
|
|
1177
1167
|
|
|
1178
|
-
todolist = None
|
|
1179
|
-
|
|
1180
|
-
conditions = " "
|
|
1181
|
-
|
|
1182
|
-
if skip_top_level_lists:
|
|
1183
|
-
conditions += " AND parent_label IS NOT NULL "
|
|
1184
|
-
|
|
1185
|
-
if deduplicate:
|
|
1186
|
-
conditions += " GROUP BY extended_label "
|
|
1187
|
-
|
|
1188
|
-
lists = db_query("SELECT lists.*, (SELECT start_time FROM sessions WHERE todolist = lists.todolist ORDER BY start_time DESC LIMIT 1 ) as last_session_on_todo FROM lists WHERE status = '1' "+conditions+" ORDER BY last_session_on_todo DESC, CASE WHEN parent_id IS NULL THEN 1 ELSE 2 END, extended_label ASC ", None, 'id')
|
|
1168
|
+
lists = db_query("SELECT lists.*, (SELECT start_time FROM sessions WHERE todolist = lists.todolist ORDER BY start_time DESC LIMIT 1 ) as last_session_on_todo FROM lists WHERE status = '1' ORDER BY last_session_on_todo DESC, CASE WHEN parent_id IS NULL THEN 1 ELSE 2 END, extended_label ASC ", None, 'id')
|
|
1189
1169
|
|
|
1190
1170
|
r_button = None
|
|
1191
1171
|
todolist_id = None
|
|
1192
1172
|
|
|
1193
1173
|
for id, l in lists.items():
|
|
1194
1174
|
try:
|
|
1195
|
-
l
|
|
1175
|
+
l = proc_db_item(l)
|
|
1196
1176
|
if len(l['label']) > truncate_labels_to_chars:
|
|
1197
1177
|
l['label'] = l['label'][:truncate_labels_to_chars] + '…'
|
|
1178
|
+
|
|
1179
|
+
nested_list_count = l['extended_label'].count(' > ')
|
|
1198
1180
|
|
|
1199
|
-
label = f'{" · " *
|
|
1181
|
+
label = f'{" · " * nested_list_count}' + GLib.markup_escape_text(l['label'])
|
|
1200
1182
|
|
|
1201
1183
|
if todolist_id != l['todolist']:
|
|
1202
1184
|
todolist_id = l['todolist']
|
|
@@ -1213,14 +1195,12 @@ def choose_from_lists(callback, selected_list_id = None, session = None, accepts
|
|
|
1213
1195
|
|
|
1214
1196
|
if accepts_tasks and l['data']['accepts_tasks'] == False:
|
|
1215
1197
|
label_widget.set_markup(' '+label)
|
|
1216
|
-
|
|
1217
1198
|
box.add(label_widget)
|
|
1218
1199
|
|
|
1219
1200
|
else:
|
|
1220
1201
|
r_button = Gtk.RadioButton(group=r_button)
|
|
1221
1202
|
r_button.add(label_widget)
|
|
1222
1203
|
|
|
1223
|
-
|
|
1224
1204
|
if l['id'] == selected_list_id:
|
|
1225
1205
|
r_button.set_active(True)
|
|
1226
1206
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nowfocus
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.7
|
|
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
|
|
@@ -58,7 +58,7 @@ nowfocus is a clean, keyboard-driven time management dashboard that flexibly con
|
|
|
58
58
|
- Task prioritization
|
|
59
59
|
- Infinitely nestable lists
|
|
60
60
|
- Pomodoro timer
|
|
61
|
-
- Time targets: set a minimum or maximum time for any task or list of tasks and get reminded to follow
|
|
61
|
+
- Time targets: set a minimum or maximum time for any task or list of tasks and get reminded to follow-through
|
|
62
62
|
- Randomness interrupt bell (optional) to keep you on track with tracking your time
|
|
63
63
|
- Keyboard-driven interface
|
|
64
64
|
- Offline to-do list cache
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
nowfocus/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
2
|
-
nowfocus/__main__.py,sha256=
|
|
3
|
-
nowfocus/conf.py,sha256=
|
|
2
|
+
nowfocus/__main__.py,sha256=1WffOUaxlfw0gc_qWY9K78j35AmoxoDDLePoK3wFlE0,33433
|
|
3
|
+
nowfocus/conf.py,sha256=czmeMU7r5DD5fT1cDi2kjwYa5xQSXJoQoeQYsoFMkzc,6757
|
|
4
4
|
nowfocus/example-todo.txt,sha256=o-ZRNiTlSGFbTK9jpdDIi07qHBrpvP0JhBZSk0VlpQU,246
|
|
5
|
-
nowfocus/install.py,sha256=
|
|
6
|
-
nowfocus/new_task_dialog.py,sha256=
|
|
5
|
+
nowfocus/install.py,sha256=gzjDzqUFYRP1dS_zA_MKrTZWTAB1bYqcxjRw5mBn1aQ,3039
|
|
6
|
+
nowfocus/new_task_dialog.py,sha256=LwvwNlCg_rl0tHwLPro0Jx1p4J_ukMNM2nLQ36vUJPI,4429
|
|
7
7
|
nowfocus/session_edit_dialog.py,sha256=V2QWSdNaxsQHRcG28CJBQM2sa45m5RNcu_suQF26mkM,6912
|
|
8
8
|
nowfocus/session_options.py,sha256=mOnyEM3-usKgVvBhESY0TNBcy4FTG-AHP6ETMgB1fQ4,5071
|
|
9
9
|
nowfocus/sessions.csv,sha256=kYpr06yQg_J86NQ4AiYw4RnQchcw3ouPKVYa1lYDUNo,39
|
|
10
|
-
nowfocus/settings.py,sha256=
|
|
10
|
+
nowfocus/settings.py,sha256=0d6nZw1t36TjyUr9KQ_wDwuh2SB64gUkZeHEjEV867Y,35169
|
|
11
11
|
nowfocus/styles.css,sha256=PG1SrLkwSSay8M2VKeRcE0UdK54ndsEDFnRLRkmP-9M,510
|
|
12
|
-
nowfocus/task_window.py,sha256=
|
|
12
|
+
nowfocus/task_window.py,sha256=f6eaxrFwI5POJG2tZX0H3AKFA6dGt_RH42y2ydHqosY,28875
|
|
13
|
+
nowfocus/upgrade.py,sha256=S0nyWmVLnukWY0QhC5873HFQZpcWuZ_XEPU4QTBtX3s,3379
|
|
13
14
|
nowfocus/user_idle_time.py,sha256=I44Ip-iGGzWAiHnM2_06jNqhCne9y1SbvcBI-nYBolU,2365
|
|
14
|
-
nowfocus/utils.py,sha256=
|
|
15
|
-
nowfocus/version_migrator.py,sha256=q8T1C8-DLOwUQUM5IPcMjPbVbsLTO4VsqADlAAXd9gw,628
|
|
15
|
+
nowfocus/utils.py,sha256=tVa4rJf0QKhDU5as4-BSIFvuZLMsxGScJkxGRYibtzA,49187
|
|
16
16
|
nowfocus/connectors/activitywatch.py,sha256=QbkOmjIOiVwccWc2xhhePd0Abww5vEiVpCNjeqOyYGg,921
|
|
17
17
|
nowfocus/connectors/caldav.py,sha256=PeM_9yJC8W17L8Y5AyS75o6GfzTrPoMYKIvetND8T78,5089
|
|
18
18
|
nowfocus/connectors/csv.py,sha256=FwMpHM5lPIT90HKBCQUncpaW7zqFjlHjMwKR0-XWg-4,821
|
|
@@ -23,8 +23,8 @@ nowfocus/connectors/todo_template.py,sha256=R37fA2LXo8_LpWIgqozytI5RqIUjGggFHup2
|
|
|
23
23
|
nowfocus/connectors/todotxt.py,sha256=QCZjbIhY4Lm37YD0GsKJQUqbj7s3eYmZGgRwUCndZ5w,3857
|
|
24
24
|
nowfocus/connectors/trello.py,sha256=VqwnvHGXXcljmdf6kRZcE6sfeBQYhped_KVBEBOzWXM,6072
|
|
25
25
|
nowfocus/connectors/txt.py,sha256=iskJsw3dZnI4bIeEDtZCY-aQfKRKtoGATEJ0k13npxI,8125
|
|
26
|
-
nowfocus/connectors/vikunja.py,sha256=
|
|
27
|
-
nowfocus/desktop-extras/nowfocus.desktop,sha256=
|
|
26
|
+
nowfocus/connectors/vikunja.py,sha256=sutd-loOjYT0njtEIT-E_E_EG9KTdsJfsYd1mHeqNBE,8807
|
|
27
|
+
nowfocus/desktop-extras/nowfocus.desktop,sha256=0kWsx0ZfvPbubGG1uuFSHxxYUw2GV9Ly_rtlboM1mak,294
|
|
28
28
|
nowfocus/desktop-extras/nowfocus.png,sha256=P5rn6-0EAJa2WXf4SJoaNtLRUfiV3LdsOroPKsR6GfA,15148
|
|
29
29
|
nowfocus/desktop-extras/nowfocus.svg,sha256=nps7naZzuhWWuKzQbpvxr9wLyzjmzMPzNHSBQMVetOo,2137
|
|
30
30
|
nowfocus/icon/cancel.png,sha256=Hy9A7KdO13MsXguIgoTI276mECN07rzd6hGbIqxSl7c,506
|
|
@@ -52,9 +52,9 @@ nowfocus/icon/settings.svg,sha256=fgkGJouPPtZLxZn2nr_5pEp9MdhRSRaW9mtdxhJHDuQ,39
|
|
|
52
52
|
nowfocus/sound/bell-xylophone-g.mp3,sha256=1OBcRWvD87AGNcq1uZFR8HqG0nanJykImERfVDVxHD4,53891
|
|
53
53
|
nowfocus/sound/dinner-bell.mp3,sha256=hjjO0xqA4uXpYw9KLwwlBnrVfRhVq1K5OXzwlMXhRn4,113620
|
|
54
54
|
nowfocus/sound/xylophone-chord.mp3,sha256=gwgBSqhMt5PMzT5N03Z6TvDgipQZfnkEz_o81Rq5Z1U,131806
|
|
55
|
-
nowfocus-0.5.
|
|
56
|
-
nowfocus-0.5.
|
|
57
|
-
nowfocus-0.5.
|
|
58
|
-
nowfocus-0.5.
|
|
59
|
-
nowfocus-0.5.
|
|
60
|
-
nowfocus-0.5.
|
|
55
|
+
nowfocus-0.5.7.dist-info/licenses/LICENSE,sha256=fSJzoHs1EOCwEd7FIyokFeGEma7NKmTVEdHkCr5OIV4,35127
|
|
56
|
+
nowfocus-0.5.7.dist-info/METADATA,sha256=HpS443Yz3_NPDZB03_G51VF4Yil7UNC4xtl8R1XqttA,6805
|
|
57
|
+
nowfocus-0.5.7.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
58
|
+
nowfocus-0.5.7.dist-info/entry_points.txt,sha256=RbYY19-irSoNVglNeNnL9D36cHft7aKsaEGEYoSH3pA,51
|
|
59
|
+
nowfocus-0.5.7.dist-info/top_level.txt,sha256=3uLd9BwmfarZwqVUxkSJuVwJ8qHzjThte8rt_UYG7tE,9
|
|
60
|
+
nowfocus-0.5.7.dist-info/RECORD,,
|
nowfocus/version_migrator.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
# update time_target format
|
|
3
|
-
for id, tt in user['time_targets']['lists'].items():
|
|
4
|
-
if 'within_value' not in tt:
|
|
5
|
-
print("Updating time target to new format ",tt)
|
|
6
|
-
tt['within_value'] = tt['num_days']
|
|
7
|
-
tt['within_unit'] = 'days'
|
|
8
|
-
print(tt)
|
|
9
|
-
if 'status' not in tt:
|
|
10
|
-
tt['status'] = True
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
for id, tt in user['time_targets']['tasks'].items():
|
|
14
|
-
if 'within_value' not in tt:
|
|
15
|
-
print("Updating time target to new format ",tt)
|
|
16
|
-
tt['within_value'] = tt['num_days']
|
|
17
|
-
tt['within_unit'] = 'days'
|
|
18
|
-
print(tt)
|
|
19
|
-
if 'status' not in tt:
|
|
20
|
-
tt['status'] = True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|