10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 |
11 |
12 import os |
12 import os |
13 import json |
13 import json |
14 |
14 |
15 from PyQt5.QtCore import pyqtSlot, QObject, QTimer, QDir |
15 from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QTimer, QDir, QFile, \ |
|
16 QFileInfo, QFileSystemWatcher |
16 |
17 |
17 import Utilities |
18 import Utilities |
18 import Preferences |
19 import Preferences |
|
20 |
|
21 |
|
22 class SessionMetaData(object): |
|
23 """ |
|
24 Class implementing a data structure to store meta data for a session. |
|
25 """ |
|
26 def __init__(self): |
|
27 """ |
|
28 Constructor |
|
29 """ |
|
30 self.name = "" |
|
31 self.filePath = "" |
|
32 self.isActive = False |
|
33 self.isDefault = False |
|
34 self.isBackup = False |
19 |
35 |
20 |
36 |
21 class SessionManager(QObject): |
37 class SessionManager(QObject): |
22 """ |
38 """ |
23 Class implementing the session manager. |
39 Class implementing the session manager. |
|
40 |
|
41 @signal sessionsMetaDataChanged() emitted to indicate a change of the |
|
42 list of session meta data |
24 """ |
43 """ |
|
44 sessionsMetaDataChanged = pyqtSignal() |
|
45 |
|
46 SwitchSession = 1 |
|
47 CloneSession = 2 |
|
48 ReplaceSession = SwitchSession | 4 |
|
49 |
25 def __init__(self, parent=None): |
50 def __init__(self, parent=None): |
26 """ |
51 """ |
27 Constructor |
52 Constructor |
28 |
53 |
29 @param parent reference to the parent object |
54 @param parent reference to the parent object |
30 @type QObject |
55 @type QObject |
31 """ |
56 """ |
32 super(SessionManager, self).__init__(parent) |
57 super(SessionManager, self).__init__(parent) |
33 |
58 |
34 sessionsDir = QDir(self.getSessionsDirectory()) |
59 sessionsDirName = self.getSessionsDirectory() |
|
60 sessionsDir = QDir(sessionsDirName) |
35 if not sessionsDir.exists(): |
61 if not sessionsDir.exists(): |
36 sessionsDir.mkpath(self.getSessionsDirectory()) |
62 sessionsDir.mkpath(sessionsDirName) |
|
63 |
|
64 self.__sessionMetaData = [] |
|
65 # list containing meta data about saved sessions |
|
66 |
|
67 self.__sessionDefault = os.path.join(sessionsDirName, "session.json") |
|
68 self.__sessionBackup1 = os.path.join(sessionsDirName, |
|
69 "session.json.old") |
|
70 self.__sessionBackup2 = os.path.join(sessionsDirName, |
|
71 "session.json.old1") |
|
72 |
|
73 self.__lastActiveSession = Preferences.getWebBrowser( |
|
74 "SessionLastActivePath") |
|
75 if not QFile.exists(self.__lastActiveSession): |
|
76 self.__lastActiveSession = self.__sessionDefault |
|
77 |
|
78 self.__sessionsDirectoryWatcher = \ |
|
79 QFileSystemWatcher([self.getSessionsDirectory()], self) |
|
80 self.__sessionsDirectoryWatcher.directoryChanged.connect( |
|
81 self.__sessionDirectoryChanged) |
|
82 |
|
83 self.__backupSavedSession() |
37 |
84 |
38 self.__autoSaveTimer = QTimer() |
85 self.__autoSaveTimer = QTimer() |
39 self.__autoSaveTimer.setSingleShot(True) |
86 self.__autoSaveTimer.setSingleShot(True) |
40 self.__autoSaveTimer.timeout.connect(self.__autoSaveSession) |
87 self.__autoSaveTimer.timeout.connect(self.__autoSaveSession) |
41 self.__initSessionSaveTimer() |
88 self.__initSessionSaveTimer() |
78 self.__autoSaveTimer.start(self.__autoSaveInterval) |
141 self.__autoSaveTimer.start(self.__autoSaveInterval) |
79 else: |
142 else: |
80 self.__autoSaveTimer.stop() |
143 self.__autoSaveTimer.stop() |
81 |
144 |
82 @pyqtSlot() |
145 @pyqtSlot() |
83 def __autoSaveSession(self): |
146 def __autoSaveSession(self, startTimer=True): |
84 """ |
147 """ |
85 Private slot to save the current session state. |
148 Private slot to save the current session state. |
|
149 |
|
150 @param startTimer flag indicating to restart the timer |
|
151 @type bool |
86 """ |
152 """ |
87 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
153 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
88 |
154 |
89 if not WebBrowserWindow.isPrivate(): |
155 if not WebBrowserWindow.isPrivate(): |
90 self.writeCurrentSession(self.defaultSessionFile()) |
156 Preferences.setWebBrowser("SessionLastActivePath", |
91 |
157 self.__lastActiveSession) |
92 self.__autoSaveTimer.start(self.__autoSaveInterval) |
158 self.writeCurrentSession(self.__lastActiveSession) |
|
159 |
|
160 if startTimer: |
|
161 self.__autoSaveTimer.start(self.__autoSaveInterval) |
93 |
162 |
94 def writeCurrentSession(self, sessionFileName): |
163 def writeCurrentSession(self, sessionFileName): |
95 """ |
164 """ |
96 Public method to write the current session to the given file name. |
165 Public method to write the current session to the given file name. |
97 |
166 |
108 # add window geometry |
177 # add window geometry |
109 geometry = window.saveGeometry() |
178 geometry = window.saveGeometry() |
110 data["WindowGeometry"] = bytes(geometry.toBase64()).decode("ascii") |
179 data["WindowGeometry"] = bytes(geometry.toBase64()).decode("ascii") |
111 |
180 |
112 sessionData["Windows"].append(data) |
181 sessionData["Windows"].append(data) |
|
182 else: |
|
183 return |
113 |
184 |
114 sessionFile = open(sessionFileName, "w") |
185 sessionFile = open(sessionFileName, "w") |
115 json.dump(sessionData, sessionFile, indent=2) |
186 json.dump(sessionData, sessionFile, indent=2) |
116 sessionFile.close() |
187 sessionFile.close() |
|
188 |
|
189 def __backupSavedSession(self): |
|
190 """ |
|
191 Private method to backup the most recently saved session. |
|
192 """ |
|
193 if QFile.exists(self.__lastActiveSession): |
|
194 |
|
195 if QFile.exists(self.__sessionBackup1): |
|
196 QFile.remove(self.__sessionBackup2) |
|
197 QFile.copy(self.__sessionBackup1, self.__sessionBackup2) |
|
198 |
|
199 QFile.remove(self.__sessionBackup1) |
|
200 QFile.copy(self.__lastActiveSession, self.__sessionBackup1) |
|
201 |
|
202 def sessionMetaData(self, includeBackups=False): |
|
203 """ |
|
204 Public method to get the sessions meta data. |
|
205 |
|
206 @param includeBackups flag indicating to include backup sessions |
|
207 @type bool |
|
208 @return list of session meta data |
|
209 @rtype list of SessionMetaData |
|
210 """ |
|
211 self.__fillMetaDataList() |
|
212 |
|
213 metaDataList = self.__sessionMetaData[:] |
|
214 |
|
215 if includeBackups and QFile.exists(self.__sessionBackup1): |
|
216 data = SessionMetaData() |
|
217 data.name = self.tr("Backup 1") |
|
218 data.filePath = self.__sessionBackup1 |
|
219 data.isBackup = True |
|
220 metaDataList.append(data) |
|
221 |
|
222 if includeBackups and QFile.exists(self.__sessionBackup2): |
|
223 data = SessionMetaData() |
|
224 data.name = self.tr("Backup 2") |
|
225 data.filePath = self.__sessionBackup2 |
|
226 data.isBackup = True |
|
227 metaDataList.append(data) |
|
228 |
|
229 return metaDataList |
|
230 |
|
231 def __fillMetaDataList(self): |
|
232 """ |
|
233 Private method to fill the sessions meta data list. |
|
234 |
|
235 The sessions meta data list is only populated, if the variable holding |
|
236 it is empty (i.e. it is populated on demand). |
|
237 """ |
|
238 if self.__sessionMetaData: |
|
239 return |
|
240 |
|
241 sessionFilesInfoList = QDir(self.getSessionsDirectory()).entryInfoList( |
|
242 QDir.Files, QDir.Time) |
|
243 for sessionFileInfo in sessionFilesInfoList: |
|
244 data = SessionMetaData() |
|
245 data.name = sessionFileInfo.baseName() |
|
246 data.filePath = sessionFileInfo.canonicalFilePath() |
|
247 |
|
248 if sessionFileInfo == QFileInfo(self.defaultSessionFile()): |
|
249 data.name = self.tr("Default Session") |
|
250 data.isDefault = True |
|
251 |
|
252 if self.__isActive(sessionFileInfo): |
|
253 data.isActive = True |
|
254 |
|
255 self.__sessionMetaData.append(data) |
|
256 |
|
257 def __isActive(self, filePath): |
|
258 """ |
|
259 Private method to check, if a given file is the active one. |
|
260 |
|
261 @param filePath path of the session file to be checked |
|
262 @type str or QFileInfo |
|
263 @return flag indicating the active file |
|
264 @rtype bool |
|
265 """ |
|
266 return QFileInfo(filePath) == QFileInfo(self.__lastActiveSession) |
|
267 |
|
268 @pyqtSlot() |
|
269 def __sessionDirectoryChanged(self): |
|
270 """ |
|
271 Private slot handling changes of the sessions directory. |
|
272 """ |
|
273 self.__sessionMetaData = [] |
|
274 |
|
275 self.sessionsMetaDataChanged.emit() |
|
276 |
|
277 def openSession(self, sessionFilePath="", flags=None): |
|
278 # TODO: implement this |
|
279 pass |
|
280 |
|
281 def renameSession(self, sessionFilePath="", flags=None): |
|
282 # TODO: implement this |
|
283 pass |
|
284 |
|
285 def saveSession(self): |
|
286 # TODO: implement this |
|
287 pass |
|
288 |
|
289 def __replaceSession(self, sessionFilePath): |
|
290 # TODO: implement this |
|
291 pass |
|
292 |
|
293 def __switchToSession(self, sessionFilePath): |
|
294 # TODO: implement this |
|
295 pass |
|
296 |
|
297 def __cloneSession(self, sessionFilePath): |
|
298 # TODO: implement this |
|
299 pass |
|
300 |
|
301 def __deleteSession(self, sessionFilePath): |
|
302 # TODO: implement this |
|
303 pass |
|
304 |
|
305 def __newSession(self): |
|
306 # TODO: implement this |
|
307 pass |
|
308 |
|
309 def openSessionManagerDialog(self): |
|
310 # TODO: implement this |
|
311 pass |