Created
December 30, 2013 15:36
-
-
Save chesster/8183542 to your computer and use it in GitHub Desktop.
TaskWarrior for Conky
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from taskw import TaskWarrior | |
import os.path, time | |
class TConky (object): | |
NONE = "--- \n" | |
CONKY_HEADER = """ | |
alignment top_left | |
background yes | |
cpu_avg_samples 2 | |
default_color 656667 | |
default_outline_color 828282 | |
default_shade_color 000000 | |
double_buffer yes | |
draw_borders no | |
draw_graph_borders no | |
draw_outline no | |
draw_shades no | |
gap_x 5 | |
gap_y 5 | |
maximum_width 500 | |
minimum_size 300 350 | |
no_buffers yes | |
override_utf8_locale yes | |
own_window yes | |
own_window_argb_visual no | |
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager | |
own_window_transparent yes | |
own_window_type override | |
total_run_times 0 | |
update_interval 1.0 | |
use_xft yes | |
xftalpha 0.1 | |
xftfont Monospace:size=9 | |
monitor 1 | |
default_outline_color 505050 | |
default_color 505050 | |
#color0 414141 | |
#color1 9dad9c | |
#color2 677166 | |
color0 414141 | |
color1 a0a0a0 | |
color2 717171 | |
TEXT | |
${execi 5 /home/chstr/.task/tconky.py} | |
""" | |
COLORS = { | |
'H' : { | |
'even': '#d00303', | |
'odd' : '#8c0505', | |
}, | |
'M' : { | |
'even': 'color1', | |
'odd' : 'color2', | |
}, | |
'L' : { | |
'even': 'color0', | |
'odd' : 'color', | |
}, | |
} | |
def __init__(self): | |
warrior = TaskWarrior() | |
tasks = warrior.load_tasks() | |
self.tasks = TConky.preprocess_tasks(tasks) | |
self.display_string = self.get_display_string() | |
@staticmethod | |
def preprocess_tasks(tasks): | |
return { | |
'pending' : TConky.preprocess_task_list(tasks['pending']), | |
'completed': TConky.preprocess_task_list(tasks['completed']) | |
} | |
@staticmethod | |
def preprocess_task_list(tasks): | |
""" | |
completed : [tag] / [project] | |
pending : | |
""" | |
projects = {} | |
tags = {} | |
id = 0 | |
for task in tasks: | |
# ID | |
id += 1 | |
task['id'] = '%0*d' % (2, id) | |
# DATE FORMAT: | |
due = task.get('due') | |
if due: | |
import datetime | |
task['formated_date'] = (datetime.datetime.fromtimestamp(int(due)).strftime('%d/%m')) | |
else: | |
task['formated_date'] = None | |
#PROJECTS: | |
projects['other'] = {} | |
if task.get('project'): | |
if not projects.get(task.get('project')): | |
projects[task['project']] = {} | |
projects[task['project']][TConky.task_to_key(task)] = task | |
else: | |
projects['other'][TConky.task_to_key(task)] = task | |
#TAGS: | |
task['tags_list'] = [] | |
if task.get('tags'): | |
for tag in task['tags']: | |
task['tags_list'].append(tag) | |
if not tags.get(tag): | |
tags[tag] = {} | |
tags[tag][TConky.task_to_key(task)] = task | |
return { | |
'projects': projects, | |
'tags' : tags | |
} | |
@staticmethod | |
def task_to_key(task): | |
prio_trans = { | |
'L' : '3', | |
'M' : '2', | |
'H' : '1' | |
} | |
prio = prio_trans.get(task.get('priority')) if prio_trans.get(task.get('priority')) else '4' | |
date = prio_trans.get(task.get('due')) if prio_trans.get(task.get('due')) else '9999999999' | |
desc = (task['description'].replace(' ',''))[:25] | |
return "%s%s%s%s" % (date, prio, desc, task['entry']) | |
@staticmethod | |
def write_string_to_file(string, file): | |
string = string.encode('utf-8') | |
f = open(file, 'w') | |
f.write('%s\n' % string) | |
f.close() | |
@staticmethod | |
def key_in_list(needles, heystack): | |
return any([n in heystack for n in needles]) | |
@staticmethod | |
def display_task_list(task_list, skip_tag=(), skip_id=False, skip_date=False): | |
return_string = '' | |
tkeys = sorted( task_list.keys()) | |
even = False | |
for task_key in tkeys: | |
task = task_list[task_key] | |
if not TConky.key_in_list(task['tags_list'], skip_tag): | |
even = not even | |
return_string += TConky.display_task(task, even, skip_id, skip_date) | |
return_string += "\n" | |
return return_string | |
def display_tag(self, tag, header=None, skip_tag=(), done=False, skip_id=False, skip_date=False): | |
return self.display_stuff('tags', tag, header, skip_tag, done, skip_id, skip_date) | |
def display_project(self, projects, header=None, skip_tag=(), done=False, skip_id=False, skip_date=False): | |
return self.display_stuff('projects', projects, header, skip_tag, done, skip_id, skip_date) | |
def display_stuff(self, type, stuff, header=None, skip_tag=(), done=False, skip_id=False, skip_date=False): | |
tasks = self.tasks['pending' if not done else 'completed'][type].get(stuff) | |
if not tasks: | |
return '' | |
tstring = '' | |
if not len(tasks): | |
return '' | |
try: | |
tstring += TConky.display_task_list(tasks, skip_tag, skip_id, skip_date) | |
except KeyError: | |
tstring += TConky.NONE | |
if len(tstring.strip()) > 0: | |
return TConky.print_headline(header if header else TConky.titelize(stuff)) + tstring | |
return '' | |
@staticmethod | |
def titelize(string): | |
return string[0].upper() + string[1:] if len(string) > 1 else string.upper() | |
@staticmethod | |
def update(conky_file, shadow_file): | |
conky_file_time = time.ctime(os.path.getmtime(conky_file)) | |
shadow_file_time = time.ctime(os.path.getmtime(shadow_file)) | |
return conky_file_time < shadow_file_time | |
## | |
# CHANGE THIS | |
## | |
@staticmethod | |
def display_task(task, even=False, skip_id=False, skip_date=False): | |
color = TConky.COLORS[task.get('priority') if task.get('priority') else 'L']['even' if even else 'odd'] | |
date = '' if skip_date else task['formated_date'] if task['formated_date'] else '${#212121}infty${%s}' % color | |
task_string = " ${%(color)s}[%(id)s] %(desc)s $alignr %(date)s $color\n" if not skip_id else " ${%(color)s}%(desc)s $alignr %(date)s $color\n" | |
return task_string % { | |
'color': color, | |
'id' : task['id'], | |
'date' : date, | |
'desc' : task['description'].replace('#','\#')[:35] | |
} | |
@staticmethod | |
def print_headline(headline): | |
return "${color1}%s: $color\n${voffset -8}${#212121}${hr}$color\n" % headline | |
def get_display_string(self): | |
tstring = TConky.CONKY_HEADER | |
# TODAY: | |
tstring += self.display_tag('today', '[TAG] Today') | |
# PROJECTS (ALL) | |
skip = ('',) | |
tkeys = sorted(self.tasks['pending']['projects'].keys()) | |
for tasks_key in tkeys: | |
if tasks_key not in skip: | |
tstring += self.display_project(tasks_key, "[PRO] " + TConky.titelize(tasks_key), ('today')) | |
# PROJECTS (PERTICULAR) | |
# tstring += self.display_project('projects', "[PRO] Projects", ('today')) | |
return tstring | |
if __name__ == '__main__': | |
conky_file = 'conky' | |
shadow_file = 'shadow.txt' | |
from optparse import OptionParser | |
parser = OptionParser('usage: %prog -f FILE') | |
parser.add_option("-f", "--file", dest="file") | |
(opt, args) = parser.parse_args() | |
if opt.file or TConky.update(conky_file, shadow_file): | |
import os | |
os.system('task > /dev/null') | |
tc = TConky() | |
TConky.write_string_to_file(tc.display_string, conky_file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment