# HG changeset patch # User Magnus Schieder # Date 1537209688 -7200 # Node ID f751499d3f8d08d458f15a19d1e22b944ebab6bf # Parent 1648ae282b7e3d0e00f5061ad13e53fe6a6e4fd2# Parent 199b3e3657aab7380e40f0dda9a7ba6940409f30 merged, Updated TODO, CHANGES diff -r 1648ae282b7e -r f751499d3f8d CHANGES --- a/CHANGES Mon Aug 06 15:30:05 2018 +0200 +++ b/CHANGES Mon Sep 17 20:41:28 2018 +0200 @@ -1,3 +1,9 @@ +3.x 20xx-xx-xx UNRELEASED + * The time of the currently running entry is cached every minute and after a + program crash the entry has the description "-no description-". + information can be found in /doc/old_issues.txt 20180806 Magnus Schieder + Patch by Magnus Schieder + 3.1 2018-06-29 * getan-report (before getan-eval.py) and getan-daily-report (before diff -r 1648ae282b7e -r f751499d3f8d TODO --- a/TODO Mon Aug 06 15:30:05 2018 +0200 +++ b/TODO Mon Sep 17 20:41:28 2018 +0200 @@ -1,7 +1,3 @@ -20180806 Magnus Schieder - Save running entry if console is closed unexpectedly. - (e.g. when shutting down the computer) - 20180806 Magnus Schieder The break can be assigned to a project. diff -r 1648ae282b7e -r f751499d3f8d doc/old_issues.txt --- a/doc/old_issues.txt Mon Aug 06 15:30:05 2018 +0200 +++ b/doc/old_issues.txt Mon Sep 17 20:41:28 2018 +0200 @@ -1,3 +1,7 @@ +20180806 Magnus Schieder + Save running entry if console is closed unexpectedly. + (e.g. when shutting down the computer) + 20170709 BER: Give scripts/getan-eval.py a more specific name and add it as a script to be installed. diff -r 1648ae282b7e -r f751499d3f8d getan/backend.py --- a/getan/backend.py Mon Aug 06 15:30:05 2018 +0200 +++ b/getan/backend.py Mon Sep 17 20:41:28 2018 +0200 @@ -40,6 +40,17 @@ CHECK (strftime('%s', start_time) <= strftime('%s', stop_time)) ) +""", + """ +CREATE TABLE recover( + id INTEGER PRIMARY KEY, + project_id INTEGER REFERENCES projects(id), + start_time TIMESTAMP NOT NULL, + stop_time TIMESTAMP NOT NULL, + description VARCHAR(256), + + CHECK (strftime('%s', start_time) <= strftime('%s', stop_time)) +) """ ] @@ -144,6 +155,26 @@ VALUES(?,?,?,?) ''' +INSERT_RECOVER= ''' +INSERT OR REPLACE INTO recover(id, project_id, start_time, stop_time, description) +VALUES(1,?,?,?,?) +''' + +LOAD_RECOVER= ''' +SELECT + id, + project_id, + start_time as "[timestamp]", + stop_time as "[timestamp]", + description +FROM + recover +WHERE + id = 1 +''' + +DELETE_RECOVER= "DELETE FROM recover" + INSERT_PROJECT = ''' INSERT INTO projects (key, description, active) VALUES (?,?,1) ''' @@ -226,6 +257,24 @@ finally: close(cur) + def load_recover(self): + cor = None + try: + cur = self.con.cursor() + cur.execute(LOAD_RECOVER) + recover = cur.fetchone() + if not recover: + return + + _, project_id, start_time, stop_time, desc = recover + + cur.execute(INSERT_PROJECT_ENTRY, ( + project_id, start_time, stop_time, desc)) + cur.execute(DELETE_RECOVER) + self.con.commit() + finally: + close(cur) + def load_project(self, key): logger.debug("load active projects from database.") cur = None @@ -290,6 +339,7 @@ cur = self.con.cursor() cur.execute(INSERT_PROJECT_ENTRY, ( project.id, project.start, stop_time, desc)) + cur.execute(DELETE_RECOVER) self.con.commit() logger.debug("Added new entry '%s' of project '%s' into db" % (desc, project.desc)) @@ -298,6 +348,18 @@ finally: close(cur) + def insert_recover(self, project, stop_time, desc): + if project is None: + return + cur = None + try: + cur = self.con.cursor() + cur.execute(INSERT_RECOVER, ( + project.id, project.start, stop_time, desc)) + self.con.commit() + finally: + close(cur) + def insert_project(self, key, description): if key is None or description is None: return diff -r 1648ae282b7e -r f751499d3f8d getan/controller.py --- a/getan/controller.py Mon Aug 06 15:30:05 2018 +0200 +++ b/getan/controller.py Mon Sep 17 20:41:28 2018 +0200 @@ -32,9 +32,11 @@ self.backend = backend projects, entries = self.load_projects() + self.load_recover() self.projects = projects self.running = [] + self.view = None self.entries_view = EntryList(entries) self.project_view = ProjectList(self, self.projects) @@ -73,6 +75,9 @@ entries = [] return (projects, entries) + def load_recover(self): + self.backend.load_recover() + def update_entries(self, project): logger.debug("GetanController: update entries for project %s." % project.id) @@ -145,6 +150,16 @@ self.update_entries(project) logger.debug('Still running projects: %r' % self.running) + def save_recovery_data(self): + desc = '-no description-' + if not self.running: + return + project = self.running[-1] + if not project: + return + project.stop = datetime.now() + self.backend.insert_recover(project, datetime.now(), desc) + def add_project(self, key, description): if not key or not description: return diff -r 1648ae282b7e -r f751499d3f8d getan/states.py --- a/getan/states.py Mon Aug 06 15:30:05 2018 +0200 +++ b/getan/states.py Mon Sep 17 20:41:28 2018 +0200 @@ -281,6 +281,8 @@ 'running') self.controller.loop.draw_screen() self.sec = self.sec + 1 + if self.sec % 60 == 0: + self.controller.save_recovery_data() else: self.view.set_footer_text( self.msg('paused') % diff -r 1648ae282b7e -r f751499d3f8d test_data/getan_test_data.py --- a/test_data/getan_test_data.py Mon Aug 06 15:30:05 2018 +0200 +++ b/test_data/getan_test_data.py Mon Sep 17 20:41:28 2018 +0200 @@ -38,6 +38,16 @@ CHECK (strftime('%s', start_time) <= strftime('%s', stop_time))) ''') + db.execute('''CREATE TABLE recover ( + id INTEGER PRIMARY KEY, + project_id INTEGER REFERENCES projects(id), + start_time TIMESTAMP NOT NULL, + stop_time TIMESTAMP NOT NULL, + description VARCHAR(256), + + CHECK (strftime('%s', start_time) <= strftime('%s', stop_time))) + ''') + # List of projects. # (key, 'description') pro = [