Skip to content

Commit 017b4ad

Browse files
committed
Update to v0.10.0
Remove "colorize" functionality everywhere except `utils.colorize()`
1 parent e0ad4e4 commit 017b4ad

File tree

6 files changed

+87
-54
lines changed

6 files changed

+87
-54
lines changed

NEWS.org

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* v0.10.0 -- <2021-03-02 Tue>
2+
** Move all "colorizing" functionality into =utils.colorize=
13
* v0.9.0 -- <2021-02-28 Sun>
24
** Properly handle the opening of files (using =with=)
35
* v0.8.0 -- <2021-02-27 Sat>

example/example.org

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,24 @@
55
:CATEGORY: pets
66
:END:
77
** WAIT Refill medicine :followup:
8-
SCHEDULED: <2021-03-05 Fri>
8+
SCHEDULED: <2021-03-08 Mon>
99
** TODO Vaccinations [1/2] :urgent:
10-
DEADLINE: <2021-03-05 Fri>
10+
DEADLINE: <2021-03-08 Mon>
1111
- [X] DAPP
1212
- [ ] Rabies
1313
* Bills
1414
:PROPERTIES:
1515
:CATEGORY: bills
1616
:END:
1717
** DOING Pay rent
18-
DEADLINE: <2021-03-01 Mon>
18+
DEADLINE: <2021-03-04 Thu>
1919
** TODO Electric bill
20-
DEADLINE: <2021-03-01 Mon>
20+
DEADLINE: <2021-03-04 Thu>
2121
* Household
2222
:PROPERTIES:
2323
:CATEGORY: house
2424
:END:
2525
** DOING Paint living room
26-
DEADLINE: <2021-02-20 Sat>
26+
DEADLINE: <2021-02-23 Tue>
2727
** TODO Clean stove
28-
DEADLINE: <2021-02-27 Sat>
28+
DEADLINE: <2021-03-02 Tue>

orgpy/const.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,22 @@
1010
today_date = '<' + today.strftime('%Y-%m-%d %a') + '>'
1111

1212
styles = {
13+
# Basic styles
1314
'normal': Fore.WHITE + Back.BLACK + Style.NORMAL,
1415
'bright': Fore.WHITE + Back.BLACK + Style.BRIGHT,
16+
# todo-state styles
1517
'todo': Fore.WHITE + Back.RED,
1618
'doing': Fore.WHITE + Back.BLUE,
1719
'wait': Fore.BLACK + Back.YELLOW,
20+
# "date_two" styles
1821
'deadline': Fore.RED + Back.BLACK + Style.BRIGHT,
1922
'deadline_two': Fore.YELLOW + Back.BLACK + Style.BRIGHT,
2023
'scheduled': Fore.CYAN + Back.BLACK + Style.BRIGHT,
24+
# "date_one" styles (and "category" for overdue tasks)
2125
'late': Fore.RED + Back.BLACK + Style.BRIGHT,
2226
'today': Fore.GREEN + Back.BLACK + Style.BRIGHT,
2327
'later': Fore.BLUE + Back.BLACK + Style.BRIGHT,
28+
# Other styles
2429
'checkbox': Fore.MAGENTA + Back.BLACK + Style.BRIGHT,
2530
'code': Fore.GREEN + Style.BRIGHT,
2631
'category': Fore.MAGENTA + Style.BRIGHT,

orgpy/tree.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,20 +294,17 @@ def orgTreeFromFile(**kwargs):
294294
org = OrgTree(f, todostates, **kwargs)
295295
todolist += org.active
296296

297-
# Colorize all tasks
298-
if kwargs['colors']:
299-
colored = []
300-
for x in todolist:
301-
colored.append(utils.colorize(x))
302-
303-
todolist = colored
304-
305297
# Add dates even if there are no tasks, and add future deadlines for "today"
306298
if kwargs['agenda']:
307299
todolist = utils.update_agenda(todolist, **kwargs)
308300
else:
309301
todolist = sorted(todolist, key=lambda d: d['days'])
310302

303+
# Colorize all tasks
304+
if kwargs['colors']:
305+
for d in todolist:
306+
utils.colorize(d, **kwargs)
307+
311308
# Remove repeating dates
312309
repeats = []
313310
for i, d in enumerate(todolist):

orgpy/utils.py

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from math import ceil
55
from datetime import datetime, timedelta
66

7+
from colorama import Style
8+
79
from . import const
810

911
def get_org_files(rcfile):
@@ -110,27 +112,49 @@ def format_inline(str_, reset='normal'):
110112

111113
return str_
112114

115+
#===============================================================================
113116
# Main function applying styles to a line's dict object
114-
#---------------------------------------
115-
def colorize(dict_):
117+
#===============================================================================
118+
def colorize(dict_, **kwargs):
116119
"""Apply ANSI sequences to specific dictionary entries.
117120
118-
The input dictionary should be of the same format as those returned by
119-
'tree.OrgNode.parse()'.
121+
The input dictionary should have the following keys:
122+
- level (not affected)
123+
- todostate (TODO, DONE, etc.)
124+
- text
125+
- num_tasks
126+
- date_one ('%A %d %b' for "agenda" mode, '<%Y-%m-%d %a>' otherwise)
127+
- tag
128+
- date_two ('Scheduled:', 'Deadline:', or 'In X d.:' for "agenda")
129+
- category
130+
- days (int.; the # of days from today to duedate)
120131
"""
121132
styles = const.styles
122133
tagtype = 'tag'
123134
if re.search('urgent', dict_['tag'], re.IGNORECASE):
124135
tagtype = 'urgent'
125136

126-
# Different styles for different todo states
137+
# Update "todostate" (2) element
138+
#-------------------------------------------------------
127139
state = dict_['todostate'].strip().lower()
128-
dict_.update(todostate=styles[state] + dict_['todostate'].strip() + styles['normal'])
140+
if state != '':
141+
dict_.update(todostate=styles[state] + dict_['todostate'].strip() + styles['normal'])
142+
if dict_['days'] <= 0:
143+
dict_.update(todostate=Style.BRIGHT + dict_['todostate'])
129144

145+
# Update "date_two" (7) element
146+
#-------------------------------------------------------
130147
# Scheduled vs Deadline
131148
dtype = dict_['date_two'].strip(': ').lower()
132-
if dtype != '':
149+
if dtype in ['scheduled', 'deadline']:
133150
dict_.update(date_two=styles[dtype] + dict_['date_two'] + styles['normal'])
151+
elif dtype != '':
152+
# This branch only occurs with "agenda" mode
153+
dtype = 'deadline'
154+
if dict_['days'] >= ceil(kwargs['num_days'] / 2):
155+
dict_.update(date_two=styles['deadline_two'] + dict_['date_two'] + styles['normal'])
156+
else:
157+
dict_.update(date_two=styles['deadline'] + dict_['date_two'] + styles['normal'])
134158
else:
135159
dtype = 'normal'
136160

@@ -141,73 +165,78 @@ def colorize(dict_):
141165
duedate = 'today'
142166
else:
143167
duedate = 'later'
168+
169+
# Update "num_tasks" (4), "date_one" (5), and "tag" (6) elements
170+
#-------------------------------------------------------
171+
# For blank dates (in agenda mode), date strings should be bold white
172+
if dict_['text'] == '':
173+
dict_.update(date_one=styles['bright'] + dict_['date_one'])
174+
144175
dict_.update(tag=styles[tagtype] + dict_['tag'] + styles['normal'],
145176
num_tasks=styles['checkbox'] + dict_['num_tasks'] + styles['normal'],
146177
date_one=styles[duedate] + dict_['date_one'] + styles['normal'])
147178

179+
# Update "category" (8) and "text" (3) elements
180+
#-------------------------------------------------------
148181
if dict_['days'] > 0:
149-
dict_.update(category=styles['category'] + dict_['category'] + styles['normal'],
150-
text=format_inline(dict_['text']) + styles['normal'])
182+
dict_.update(category=styles['category'] + dict_['category'],
183+
text=format_inline(dict_['text']))
151184
else:
152-
dict_.update(text=styles[dtype] + format_inline(dict_['text'], dtype) + styles['normal'],
185+
dict_.update(text=styles[duedate] + format_inline(dict_['text'], dtype),
153186
category=styles[duedate] + dict_['category'])
154187

155-
return dict_
156-
188+
#===============================================================================
157189
# Function to update the line's dict for 'agenda' mode
158-
#---------------------------------------
190+
#===============================================================================
159191
def update_agenda(list_, **kwargs):
160-
"""Update entries if 'agenda' view is chosen."""
161-
styles = const.styles
162-
num_days = int(kwargs['num_days'])
192+
"""Update entries if 'agenda' view is chosen.
193+
194+
For days in which no task is due, a blank entry is added to the list.
195+
Furthermore, dates with a future Deadline are repeated so that they
196+
appear with the current date's tasks (if any).
197+
"""
198+
num_days = kwargs['num_days']
163199
todolist = copy.deepcopy(list_)
164-
dates_agenda = []
165-
for i in range(num_days):
166-
dates_agenda.append((const.today + timedelta(i)).strftime('<%Y-%m-%d %a>'))
167-
168-
repeat_tasks = []; deadline = []
169-
for d in todolist:
170-
if kwargs['colors']:
171-
if d['days'] > ceil(num_days / 2):
172-
deadline.append(styles['deadline_two'])
173-
else:
174-
deadline.append(styles['deadline'])
175-
else:
176-
deadline.append('')
177200

178201
# Pad output if there are late tasks or larger 'num_days' is requested
202+
repeat_tasks = []
179203
max_days = max([len(str(x['days'])) for x in todolist])
180204
for i, d in enumerate(todolist):
181205
if re.search('Deadline', d['date_two']):
206+
day_str = str(d['days']).rjust(max_days+1)
182207
if 0 < d['days'] < num_days:
183-
day_str = str(d['days']).rjust(max_days+1)
184208
d_copy = dict(d)
185209
d_copy['date_one'] = const.regex['date'].sub(const.today_date, d['date_one'])
186-
d_copy['date_two'] = deadline[i] + ' In' + day_str + ' d.:' + styles['normal']
210+
d_copy['date_two'] = ' In' + day_str + ' d.:'
187211
repeat_tasks.append(d_copy)
188212
elif d['days'] < 0:
189-
day_str = str(d['days']).rjust(max_days)
190-
todolist[i].update(date_one=styles['late'] + const.today_date + '\n',
191-
date_two=deadline[i] + ' In ' + day_str + ' d.:' + styles['bright'])
213+
todolist[i].update(date_one=const.today_date + '\n',
214+
date_two=' In' + day_str + ' d.:')
192215

193216
todolist = todolist + repeat_tasks
194217

195218
# Add a blank entry for dates with no active tasks
196-
for d in dates_agenda:
219+
for n in range(num_days):
220+
d = (const.today + timedelta(n)).strftime('<%Y-%m-%d %a>')
197221
if not any(re.search(d, item) for item in [x['date_one'] for x in todolist]):
198222
blank_dict = {
199-
'date_one': styles['bright'] + d,
223+
'date_one': d,
200224
'date_two': '', 'category': '', 'text': '', 'level': '',
201225
'num_tasks': '', 'tag': '', 'todostate': '', 'days': days_until_due(d)
202226
}
203227
todolist.append(blank_dict)
204228

205-
todolist = sorted(todolist, key=lambda d: (const.regex['ansicolors'].sub('', d['date_one']), d['days']))
229+
todolist = sorted(todolist, key=lambda d: (d['date_one'], d['days']))
206230

207231
# Change '<%Y-%m-%d %a>' to '%A %d %b' for all entries
208232
for i, d in enumerate(todolist):
209233
todolist[i]['date_one'] = day_names(d['date_one'])
210234

235+
# Don't show a date for overdue tasks
236+
for i, d in enumerate(todolist):
237+
if d['date_two'] != 'Scheduled:' and d['days'] < 0:
238+
d.update(date_one='Overdue\n')
239+
211240
return todolist
212241

213242
#-------------------------------------------------------------------------------
@@ -253,9 +282,9 @@ def get_parse_string(todostates):
253282

254283
return pattern_line
255284

256-
#-------------------------------------------------------------------------------
285+
#===============================================================================
257286
# Print functions
258-
#-------------------------------------------------------------------------------
287+
#===============================================================================
259288
def print_delim(n=30):
260289
"""Print a line of blue '#' symbols."""
261290
print('\t\t' + const.styles['url'] + n*'#')

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name = 'orgpy',
8-
version = '0.9.0',
8+
version = '0.10.0',
99
author = 'Christopher G. Watson',
1010
author_email = '[email protected]',
1111
description = 'Python package to get important information from org-mode files',

0 commit comments

Comments
 (0)