Fri, 30 Jun 2017 19:58:09 +0200
Continued implementing session support for the new web browser.
# -*- coding: utf-8 -*- # Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the session manager. """ from __future__ import unicode_literals import os import json from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QTimer, QDir, QFile, \ QFileInfo, QFileSystemWatcher import Utilities import Preferences class SessionMetaData(object): """ Class implementing a data structure to store meta data for a session. """ def __init__(self): """ Constructor """ self.name = "" self.filePath = "" self.isActive = False self.isDefault = False self.isBackup = False class SessionManager(QObject): """ Class implementing the session manager. @signal sessionsMetaDataChanged() emitted to indicate a change of the list of session meta data """ sessionsMetaDataChanged = pyqtSignal() SwitchSession = 1 CloneSession = 2 ReplaceSession = SwitchSession | 4 def __init__(self, parent=None): """ Constructor @param parent reference to the parent object @type QObject """ super(SessionManager, self).__init__(parent) sessionsDirName = self.getSessionsDirectory() sessionsDir = QDir(sessionsDirName) if not sessionsDir.exists(): sessionsDir.mkpath(sessionsDirName) self.__sessionMetaData = [] # list containing meta data about saved sessions self.__sessionDefault = os.path.join(sessionsDirName, "session.json") self.__sessionBackup1 = os.path.join(sessionsDirName, "session.json.old") self.__sessionBackup2 = os.path.join(sessionsDirName, "session.json.old1") self.__lastActiveSession = Preferences.getWebBrowser( "SessionLastActivePath") if not QFile.exists(self.__lastActiveSession): self.__lastActiveSession = self.__sessionDefault self.__sessionsDirectoryWatcher = \ QFileSystemWatcher([self.getSessionsDirectory()], self) self.__sessionsDirectoryWatcher.directoryChanged.connect( self.__sessionDirectoryChanged) self.__backupSavedSession() self.__autoSaveTimer = QTimer() self.__autoSaveTimer.setSingleShot(True) self.__autoSaveTimer.timeout.connect(self.__autoSaveSession) self.__initSessionSaveTimer() def preferencesChanged(self): """ Public slot to react upon changes of the settings. """ self.__initSessionSaveTimer() # TODO: implement this def getSessionsDirectory(self): """ Public method to get the directory sessions are stored in. @return name of the sessions directory @rtype str """ return os.path.join(Utilities.getConfigDir(), "web_browser", "sessions") def defaultSessionFile(self): """ Public method to get the name of the default session file. @return name of the default session file @rtype str """ return self.__sessionDefault def lastActiveSessionFile(self): """ Public method to get the name of the last active session file. @return name of the last active session file @rtype str """ return self.__lastActiveSession def shutdown(self): """ Public method to perform any shutdown actions. """ self.__autoSaveTimer.stop() self.__autoSaveSession(startTimer=False) def __initSessionSaveTimer(self): """ Private slot to initialize the auto save timer. """ self.__autoSaveInterval = Preferences.getWebBrowser( "SessionAutoSaveInterval") * 1000 if Preferences.getWebBrowser("SessionAutoSave"): if not self.__autoSaveTimer.isActive(): self.__autoSaveTimer.start(self.__autoSaveInterval) else: self.__autoSaveTimer.stop() @pyqtSlot() def __autoSaveSession(self, startTimer=True): """ Private slot to save the current session state. @param startTimer flag indicating to restart the timer @type bool """ from WebBrowser.WebBrowserWindow import WebBrowserWindow if not WebBrowserWindow.isPrivate(): Preferences.setWebBrowser("SessionLastActivePath", self.__lastActiveSession) self.writeCurrentSession(self.__lastActiveSession) if startTimer: self.__autoSaveTimer.start(self.__autoSaveInterval) def writeCurrentSession(self, sessionFileName): """ Public method to write the current session to the given file name. @param sessionFileName file name of the session @type str """ from WebBrowser.WebBrowserWindow import WebBrowserWindow sessionData = {"Windows": []} for window in WebBrowserWindow.mainWindows(): data = window.tabWidget().getSessionData() # add window geometry geometry = window.saveGeometry() data["WindowGeometry"] = bytes(geometry.toBase64()).decode("ascii") sessionData["Windows"].append(data) else: return sessionFile = open(sessionFileName, "w") json.dump(sessionData, sessionFile, indent=2) sessionFile.close() def __backupSavedSession(self): """ Private method to backup the most recently saved session. """ if QFile.exists(self.__lastActiveSession): if QFile.exists(self.__sessionBackup1): QFile.remove(self.__sessionBackup2) QFile.copy(self.__sessionBackup1, self.__sessionBackup2) QFile.remove(self.__sessionBackup1) QFile.copy(self.__lastActiveSession, self.__sessionBackup1) def sessionMetaData(self, includeBackups=False): """ Public method to get the sessions meta data. @param includeBackups flag indicating to include backup sessions @type bool @return list of session meta data @rtype list of SessionMetaData """ self.__fillMetaDataList() metaDataList = self.__sessionMetaData[:] if includeBackups and QFile.exists(self.__sessionBackup1): data = SessionMetaData() data.name = self.tr("Backup 1") data.filePath = self.__sessionBackup1 data.isBackup = True metaDataList.append(data) if includeBackups and QFile.exists(self.__sessionBackup2): data = SessionMetaData() data.name = self.tr("Backup 2") data.filePath = self.__sessionBackup2 data.isBackup = True metaDataList.append(data) return metaDataList def __fillMetaDataList(self): """ Private method to fill the sessions meta data list. The sessions meta data list is only populated, if the variable holding it is empty (i.e. it is populated on demand). """ if self.__sessionMetaData: return sessionFilesInfoList = QDir(self.getSessionsDirectory()).entryInfoList( QDir.Files, QDir.Time) for sessionFileInfo in sessionFilesInfoList: data = SessionMetaData() data.name = sessionFileInfo.baseName() data.filePath = sessionFileInfo.canonicalFilePath() if sessionFileInfo == QFileInfo(self.defaultSessionFile()): data.name = self.tr("Default Session") data.isDefault = True if self.__isActive(sessionFileInfo): data.isActive = True self.__sessionMetaData.append(data) def __isActive(self, filePath): """ Private method to check, if a given file is the active one. @param filePath path of the session file to be checked @type str or QFileInfo @return flag indicating the active file @rtype bool """ return QFileInfo(filePath) == QFileInfo(self.__lastActiveSession) @pyqtSlot() def __sessionDirectoryChanged(self): """ Private slot handling changes of the sessions directory. """ self.__sessionMetaData = [] self.sessionsMetaDataChanged.emit() def openSession(self, sessionFilePath="", flags=None): # TODO: implement this pass def renameSession(self, sessionFilePath="", flags=None): # TODO: implement this pass def saveSession(self): # TODO: implement this pass def __replaceSession(self, sessionFilePath): # TODO: implement this pass def __switchToSession(self, sessionFilePath): # TODO: implement this pass def __cloneSession(self, sessionFilePath): # TODO: implement this pass def __deleteSession(self, sessionFilePath): # TODO: implement this pass def __newSession(self): # TODO: implement this pass def openSessionManagerDialog(self): # TODO: implement this pass