Sat, 20 Oct 2012 22:46:24 +0200
Implemented the import functionality.
# -*- coding: utf-8 -*- # Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the time tracker object. """ import os from PyQt4.QtCore import QObject from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .TimeTrackEntry import TimeTrackEntry from .TimeTrackerWidget import TimeTrackerWidget import UI.PixmapCache class TimeTracker(QObject): """ Class implementing the time tracker object. """ FileName = "TimeTracker.txt" def __init__(self, plugin, parent=None): """ Constructor @param plugin reference to the plugin object (TimeTrackerPlugin) @param parent parent (QObject) """ QObject.__init__(self, parent) self.__plugin = plugin self.__ui = parent self.__e5project = e5App().getObject("Project") self.__widget = TimeTrackerWidget(self) self.__ui.addSideWidget(self.__ui.BottomSide, self.__widget, UI.PixmapCache.getIcon(os.path.join("TimeTracker", "icons", "clock.png")), self.tr("Time Tracker")) self.__initialize() def __initialize(self): """ Public slot to initialize some member variables. """ self.__projectPath = '' self.__trackerFilePath = '' self.__projectOpen = False self.__entries = {} # key: entry ID, value tracker entry self.__currentEntry = None self.__widget.clear() def projectOpened(self): """ Public slot to handle the projectOpened signal. """ if self.__projectOpen: self.projectClosed() self.__projectOpen = True self.__projectPath = self.__e5project.getProjectPath() self.__trackerFilePath = os.path.join( self.__e5project.getProjectManagementDir(), TimeTracker.FileName) self.__readTrackerEntries() self.__widget.showTrackerEntries(sorted(self.__entries.values(), reverse=True)) self.startTrackerEntry() def projectClosed(self): """ Public slot to handle the projectClosed signal. """ self.stopTrackerEntry() self.saveTrackerEntries() self.__initialize() def __readTrackerEntries(self): """ Private slot to read the time tracker entries from a file. """ if os.path.exists(self.__trackerFilePath): try: f = open(self.__trackerFilePath, "r", encoding="utf-8") data = f.read() f.close() except (IOError, OSError) as err: E5MessageBox.critical(self.__ui, self.trUtf8("Read Time Tracker File"), self.trUtf8("""<p>The time tracker file <b>{0}</b> could not be""" """ read.</p><p>Reason: {1}</p>""").format( self.__trackerFilePath, str(err))) return invalidCount = 0 for line in data.splitlines(): entry = TimeTrackEntry(self.__plugin) eid = entry.fromString(line.strip()) if eid > -1: self.__entries[eid] = entry else: invalidCount += 1 if invalidCount: E5MessageBox.information(self.__ui, self.trUtf8("Read Time Tracker File"), self.trUtf8("""<p>The time tracker file <b>{0}</b> contained""" """ %n invalid entries. These have been discarded.""", "", invalidCount).format(self.__trackerFilePath)) def saveTrackerEntries(self, filePath="", ids=[]): """ Public slot to save the tracker entries to a file. @keyparam filePath path and name of the file to write the entries to (string) @keyparam ids list of entry IDs to be written (list of integer) """ if not filePath: filePath = self.__trackerFilePath if ids: entriesList = [self.__entries[eid] for eid in ids if eid in self.__entries] else: entriesList = self.__entries.values() try: f = open(filePath, "w", encoding="utf-8") for entry in entriesList: if entry.isValid(): f.write(entry.toString() + "\n") f.close() except (IOError, OSError) as err: E5MessageBox.critical(self.__ui, self.trUtf8("Save Time Tracker File"), self.trUtf8("""<p>The time tracker file <b>{0}</b> could not be""" """ saved.</p><p>Reason: {1}</p>""").format( self.__trackerFilePath, str(err))) def importTrackerEntries(self, fname): """ Public slot to import tracker entries from a file. @param fname name of the file to import (string) """ try: f = open(fname, "r", encoding="utf-8") data = f.read() f.close() except (IOError, OSError) as err: E5MessageBox.critical(self.__ui, self.trUtf8("Import Time Tracker File"), self.trUtf8("""<p>The time tracker file <b>{0}</b> could not be""" """ read.</p><p>Reason: {1}</p>""").format( fname, str(err))) return invalidCount = 0 duplicateCount = 0 entries = [] for line in data.splitlines(): entry = TimeTrackEntry(self.__plugin) eid = entry.fromString(line.strip()) if eid > -1: entries.append(entry) else: invalidCount += 1 if not self.__plugin.getPreferences("AllowDuplicates"): startDateTimes = [ entry.getStartDateTime() for entry in self.__entries.values()] for entry in entries[:]: if entry.getStartDateTime() in startDateTimes: entries.remove(entry) duplicateCount += 1 if len(self.__entries.keys()): nextID = max(self.__entries.keys()) + 1 else: nextID = 0 for entry in entries: entry.setID(nextID) self.__entries[nextID] = entry nextID += 1 if invalidCount != 0 or duplicateCount != 0: if invalidCount != 0 and duplicateCount != 0: msg = self.tr("""<p>The time tracker file <b>{0}</b> contained""" """ %n invalid entries.""", "", invalidCount).format(fname) msg += " " + self.tr("""%n duplicate entries were detected.""", "", duplicateCount) elif duplicateCount != 0: msg = self.tr("""<p>The time tracker file <b>{0}</b> contained""" """ %n duplicate entries.""", "", duplicateCount).format(fname) elif invalidCount != 0: msg = self.tr("""<p>The time tracker file <b>{0}</b> contained""" """ %n invalid entries.""", "", invalidCount).format(fname) msg += " " + self.tr("""These have been ignored.""") E5MessageBox.information(self.__ui, self.trUtf8("Import Time Tracker File"), msg) def pauseTrackerEntry(self): """ Public method to pause the current tracker entry. """ self.__currentEntry.pause() def continueTrackerEntry(self): """ Public method to continue the current tracker entry. """ self.__currentEntry.continue_() def stopTrackerEntry(self): """ Public method to stop the current tracker entry. @return tuple of the ID assigned to the stopped tracker entry and the duration (integer, integer) """ duration = 0 nextID = -1 if self.__currentEntry is not None: self.__currentEntry.stop() if self.__currentEntry.isValid(): if len(self.__entries.keys()): nextID = max(self.__entries.keys()) + 1 else: nextID = 0 self.__currentEntry.setID(nextID) self.__entries[nextID] = self.__currentEntry if self.__plugin.getPreferences("AutoSave"): self.saveTrackerEntries() duration = self.__currentEntry.getDuration() self.__currentEntry = None return nextID, duration def startTrackerEntry(self): """ Public method to start a new tracker entry. """ self.__currentEntry = TimeTrackEntry(self.__plugin) self.__currentEntry.start() self.__widget.setCurrentEntry(self.__currentEntry) def getCurrentEntry(self): """ Public method to get a reference to the current tracker entry. """ return self.__currentEntry def deleteTrackerEntry(self, eid): """ Public method to delete a tracker entry given its ID. @param eid ID of the tracker entry (integer) """ if eid in self.__entries: del self.__entries[eid]