view getan.py @ 100:8f433e3c2f21

Allow to pass entries to the DeleteEntryState By default DeleteEntryState uses the selected entries if no entry is passes to the constructor. This allows to reuse the state class for single entry deletion
author Björn Ricks <bjoern.ricks@intevation.de>
date Mon, 12 Sep 2011 14:05:34 +0200
parents 4912568f9048
children a23e8191c6bc
line wrap: on
line source
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# (c) 2010 by Ingo Weinzierl <ingo.weinzierl@intevation.de>
# (c) 2011 by Björn Ricks <bjoern.ricks@intevation.de>
#
# A python worklog-alike to log what you have 'getan' (done).
#
# This is Free Software licensed under the terms of GPLv3 or later.
# For details see LICENSE coming with the source of 'getan'.
#

import logging
import sys
from   datetime import datetime
from optparse import OptionParser

import getan.config  as config
from   getan.backend import *
from   getan.view    import *
from   getan.utils   import format_time

logger = logging.getLogger()

class GetanController:
    def __init__(self, backend, pv_class, ev_class):
        self.ev_class = ev_class
        self.pv_class = pv_class

        self.projects = backend.load_projects()
        if self.projects:
            entries = backend.load_entries(self.projects[0].id)
        else:
            entries = []
        self.running  = []

        self.backend      = backend
        self.project_view = pv_class(self, self.projects)
        self.entries_view = ev_class(entries)

        self.view  = GetanView(self, self.project_view, self.entries_view)
        self.state = PausedProjectsState(self, self.project_view)

    def main(self):
        self.view.run()

    def unhandled_keypress(self, key):
        self.state = self.state.keypress(key)

    def input_filter(self, input, raw_input):
        if 'window resize' in input:
            self.view.loop.screen_size = None
            self.view.loop.draw_screen()
        else:
            self.state = self.state.keypress(input)

    def update_entries(self, project):
        logger.debug("GetanController: update entries.")
        if project: entries = self.backend.load_entries(project.id)
        else:       entries = []
        self.entries_view.set_rows(entries)
        self.view.update_view()

    def move_selected_entries(self, project):
        old_project = None
        entries = []
        try:
            while self.entries_view.selection:
                node = self.entries_view.selection.pop()
                if node.selected: node.select()
                entries.append(node.item)
                logger.info("GetanController: move entry '%s' (id = %d, "\
                            "project id = %d) to project '%s'"
                            % (node.item.desc, node.item.id,
                               node.item.project_id, project.desc))

                if not old_project:
                    old_project = self.project_by_id(node.item.project_id)
        finally:
            self.backend.move_entries(entries, project.id)
            if not old_project: return
            project.entries     = self.backend.load_entries(project.id)
            old_project.entries = self.backend.load_entries(old_project.id)
            self.update_entries(old_project)
            self.project_view.update_all()

    def delete_entries(self, entry_nodes):
        if not entry_nodes:
            return
        proj    = self.project_by_id(entry_nodes[0].project_id)
        entries = entry_nodes
        self.backend.delete_entries(entries)
        proj.entries = self.backend.load_entries(proj.id)
        self.update_entries(proj)
        self.project_view.update()

    def update_project_list(self):
        self.project_view.update()
        self.view.update_view()

    def exit(self):
        self.view.exit()

    def project_by_key(self, key):
        for proj in self.projects:
            if proj.key == key:
                return proj
        return None

    def project_by_id(self, id):
        for proj in self.projects:
            if proj.id == id:
                return proj
        return None

    def start_project(self, project):
        if not project: return
        self.running.append(project)
        project.start = datetime.now()
        logger.info("Start project '%s' at %s."
                    % (project.desc, format_time(datetime.now())))
        self.view.set_footer_text(" Running on '%s'" % project.desc, 'running')
        logger.debug('All running projects: %r' % self.running)

    def stop_project(self, desc='-no description-', display=True):
        if not self.running: return
        project = self.running.pop()
        if not project: return
        logger.info("Stop project '%s' at %s."
                    % (project.desc, format_time(datetime.now())))
        project.stop = datetime.now()
        self.backend.insert_project_entry(project, datetime.now(), desc)
        if display:
            self.update_entries(project)
            self.update_project_list()
        logger.debug('Still running projects: %r' % self.running)

    def add_project(self, key, description):
        if not key or not description:
            return
        self.backend.insert_project(key, description)
        self.update_project_list()

    def update_entry(self, entry):
        self.backend.update_entry(entry)

    def shutdown(self):
        for project in self.running:
            self.stop_project(display=False)


def main():

    usage = "usage: %prog [options] [databasefile (default: " + \
             DEFAULT_DATABASE + ")]"
    parser = OptionParser(usage=usage)
    parser.add_option("-d", "--debug", action="store_true", dest="debug",
                      help="Set verbosity to debug")
    parser.add_option("-l", "--logfile", dest="logfile", metavar="FILE",
                      help="Write log information to FILE [default: %default]",
                      default="getan.log")
    (options, args) = parser.parse_args()
    logargs = dict()
    if options.debug:
        logargs["level"] = logging.DEBUG
    if options.logfile:
        logargs["filename"] = options.logfile
    config.initialize(**logargs)
    global logger

    if len(args) > 0:
        backend = Backend(args[0])
        logging.info("Use database '%s'." % args[0])
    else:
        backend = Backend()
        logging.info("Use database '%s'." % DEFAULT_DATABASE)

    controller = GetanController(backend, ProjectList, EntryList)

    try:
        controller.main()
    except KeyboardInterrupt:
        pass
    finally:
        controller.shutdown()


if __name__ == '__main__':
    main()
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)