-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbeelist.py
More file actions
executable file
·95 lines (82 loc) · 2.77 KB
/
Copy pathbeelist.py
File metadata and controls
executable file
·95 lines (82 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/python3
'''Create a basic todo list based on Beeminder goals,
sorted by how close they are to derailing.'''
import configparser
import itertools
import os
import time
import beeminder
TYPES = {'biker', 'hustler'}
SECONDS_PER_DAY = 24 * 60 * 60
IDEAL_DAYS_LEFT = 3
def get_config():
config = configparser.ConfigParser(defaults=dict(ideal=IDEAL_DAYS_LEFT),
default_section='default',
interpolation=None)
config.read(os.path.expanduser('~/.beelistrc'))
return config
class Beelist:
def __init__(self, config, format='{slug}: {limsum} ({mostrecent}: {curval})'):
self.format = format
self._list = None
self.now = time.time()
self.today = time.strftime('%Y-%m-%d', time.localtime(self.now))
self.config = config
self.auth_token = config.get('common', 'auth_token')
self.bm = beeminder.Beeminder(self.auth_token)
def groupkey(self, goal):
slug = goal['slug']
losedate = goal['losedate']
if slug not in self.config:
self.config.add_section(slug)
ideal = self.config.getint(slug, 'ideal')
daysleft = int((losedate - self.now) / SECONDS_PER_DAY)
if not daysleft:
return daysleft
normideal = daysleft / ideal
if normideal > 1:
return float('inf')
default_ideal = self.config.getint('default', 'ideal')
return int(normideal * default_ideal) or 1
def test(self, goal):
goal_type = goal['goal_type']
lastday = goal['lastday']
frozen = goal['frozen']
slug = goal['slug']
mostrecent = goal['mostrecent']
if slug not in self.config:
self.config.add_section(slug)
isdaily = self.config.getboolean(slug, 'daily')
#print('{}, curday is {}'.format(slug, curday), self.now - curday > SECONDS_PER_DAY, isdaily)
return (goal_type in TYPES and not frozen and
(not isdaily or self.today != mostrecent))
@property
def goals(self):
values = self.bm.goals.values()
for goal in values:
goal['mostrecent'] = time.strftime('%Y-%m-%d',
time.localtime(goal['lastday']))
return values
@property
def list(self):
if self._list is None:
goals = sorted((goal for goal in self.goals if self.test(goal)),
key=lambda goal: (self.groupkey(goal), goal['losedate']))
groups = itertools.groupby(goals, self.groupkey)
self._list = {key: [self.format.format(**goal) for goal in group] for (key, group) in groups}
return self._list
def __str__(self):
list = self.list
keys = sorted(list.keys())
result = []
result.append(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
for key in keys:
result.append('== Priority {} =='.format(key))
result.extend(list[key])
result.append('')
return '\n'.join(result)
def main():
config = get_config()
print(Beelist(config))
if __name__ == '__main__':
main()