Skip to content

Instantly share code, notes, and snippets.

@chesster
Created December 30, 2013 15:36
Show Gist options
  • Save chesster/8183542 to your computer and use it in GitHub Desktop.
Save chesster/8183542 to your computer and use it in GitHub Desktop.
TaskWarrior for Conky
#!/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