Mercurial > getan
comparison getan.py @ 23:9c4e8ba3c4fa
Added a new implementation of 'getan' based on urwid, a python console user interface library.
author | Ingo Weinzierl <ingo_weinzierl@web.de> |
---|---|
date | Sat, 28 Aug 2010 20:16:58 +0200 |
parents | |
children | 155b23da504b |
comparison
equal
deleted
inserted
replaced
22:2dc893ca5072 | 23:9c4e8ba3c4fa |
---|---|
1 #!/usr/bin/env python | |
2 # -*- coding: utf-8 -*- | |
3 # | |
4 # (c) 2010 by Ingo Weinzierl <ingo.weinzierl@intevation.de> | |
5 # | |
6 # A python worklog-alike to log what you have 'getan' (done). | |
7 # | |
8 # This is Free Software licensed under the terms of GPLv3 or later. | |
9 # For details see LICENSE coming with the source of 'getan'. | |
10 # | |
11 | |
12 import logging | |
13 import sys | |
14 from datetime import datetime | |
15 | |
16 import getan.config as config | |
17 from getan.backend import * | |
18 from getan.view import * | |
19 from getan.utils import format_time | |
20 | |
21 logger = logging.getLogger() | |
22 | |
23 class GetanController: | |
24 def __init__(self, backend, pv_class, ev_class): | |
25 self.ev_class = ev_class | |
26 self.pv_class = pv_class | |
27 | |
28 self.projects = backend.load_projects() | |
29 entries = backend.load_entries(self.projects[0].id) | |
30 self.running = [] | |
31 | |
32 self.backend = backend | |
33 self.project_view = pv_class(self, self.projects) | |
34 self.entries_view = ev_class(entries) | |
35 | |
36 self.view = GetanView(self, self.project_view, self.entries_view) | |
37 self.state = PausedProjectsState(self, self.project_view) | |
38 | |
39 def main(self): | |
40 self.view.run() | |
41 | |
42 def unhandled_keypress(self, key): | |
43 self.state = self.state.keypress(key) | |
44 | |
45 def input_filter(self, input, raw_input): | |
46 self.state = self.state.keypress(input) | |
47 | |
48 def update_entries(self, project): | |
49 logger.debug("GetanController: update entries.") | |
50 self.entries_view.set_rows(self.backend.load_entries(project.id)) | |
51 self.view.update_view() | |
52 | |
53 def move_selected_entries(self, project): | |
54 old_project = None | |
55 entries = [] | |
56 try: | |
57 while True: | |
58 node = self.entries_view.selection.pop() | |
59 if node.selected: node.select() | |
60 entries.append(node.entry) | |
61 logger.info("GetanController: move entry '%s' (id = %d, "\ | |
62 "project id = %d) to project '%s'" | |
63 % (node.entry.desc, node.entry.id, | |
64 node.entry.project_id, project.desc)) | |
65 | |
66 if not old_project: | |
67 old_project = self.project_by_id(node.entry.project_id) | |
68 except IndexError, err: | |
69 pass | |
70 finally: | |
71 self.backend.move_entries(entries, project.id) | |
72 if not old_project: return | |
73 project.entries = self.backend.load_entries(project.id) | |
74 old_project.entries = self.backend.load_entries(old_project.id) | |
75 self.update_entries(old_project) | |
76 self.project_view.update_all() | |
77 | |
78 def delete_entries(self, entry_nodes): | |
79 if not entry_nodes: return | |
80 proj = None | |
81 entries = [] | |
82 try: | |
83 while True: | |
84 node = self.entries_view.selection.pop() | |
85 if node.selected: node.select() | |
86 entries.append(node.entry) | |
87 logger.info("GetanController: delete entry '%s' (id = %d, "\ | |
88 "project id = %d)" | |
89 % (node.entry.desc, node.entry.id, | |
90 node.entry.project_id)) | |
91 | |
92 if proj is None: | |
93 proj = self.project_by_id(node.entry.project_id) | |
94 except IndexError, err: | |
95 pass | |
96 finally: | |
97 self.backend.delete_entries(entries) | |
98 proj.entries = self.backend.load_entries(proj.id) | |
99 self.update_entries(proj) | |
100 self.project_view.update() | |
101 | |
102 def update_project_list(self): | |
103 self.project_view.update() | |
104 self.view.update_view() | |
105 | |
106 def exit(self): | |
107 self.view.exit() | |
108 | |
109 def project_by_key(self, key): | |
110 for proj in self.projects: | |
111 if proj.key == key: | |
112 return proj | |
113 return None | |
114 | |
115 def project_by_id(self, id): | |
116 for proj in self.projects: | |
117 if proj.id == id: | |
118 return proj | |
119 return None | |
120 | |
121 def start_project(self, project): | |
122 self.running.append(project) | |
123 project.start = datetime.now() | |
124 logger.info("Start project '%s' at %s." | |
125 % (project.desc, format_time(datetime.now()))) | |
126 self.view.set_footer_text(" Running on '%s'" % project.desc, 'running') | |
127 logger.debug('All running projects: %r' % self.running) | |
128 | |
129 def stop_project(self): | |
130 project = self.running.pop() | |
131 desc = self.view.get_frame().get_footer().get_edit_text() | |
132 logger.info("Stop project '%s' at %s." | |
133 % (project.desc, format_time(datetime.now()))) | |
134 project.stop = datetime.now() | |
135 self.backend.insert_project_entry(project, datetime.now(), desc) | |
136 self.update_entries(project) | |
137 self.update_project_list() | |
138 logger.debug('Still running projects: %r' % self.running) | |
139 | |
140 | |
141 def main(): | |
142 config.initialize() | |
143 global logger | |
144 | |
145 if len(sys.argv) > 1: | |
146 backend = Backend(sys.argv[1]) | |
147 logging.info("Use database '%s'." % sys.argv[1]) | |
148 else: | |
149 backend = Backend() | |
150 logging.info("Use database '%s'." % DEFAULT_DATABASE) | |
151 | |
152 controller = GetanController(backend, ProjectList, EntryList) | |
153 controller.main() | |
154 | |
155 | |
156 if __name__ == '__main__': | |
157 main() |