Merge pull request #198 from vkbo/backup_class

Backup Updates
This commit is contained in:
Veronica K. Berglyd Olsen
2020-05-08 20:32:41 +02:00
committed by GitHub
5 changed files with 82 additions and 111 deletions
+5 -1
View File
@@ -177,6 +177,10 @@ class GuiMainMenu(QMenuBar):
self.theParent.docEditor.revealLocation() self.theParent.docEditor.revealLocation()
return True return True
def _doBackup(self):
self.theProject.zipIt(True)
return True
## ##
# Menu Builders # Menu Builders
## ##
@@ -703,7 +707,7 @@ class GuiMainMenu(QMenuBar):
# Tools > Backup # Tools > Backup
self.aBackupProject = QAction("Backup Project", self) self.aBackupProject = QAction("Backup Project", self)
self.aBackupProject.setStatusTip("Backup Project") self.aBackupProject.setStatusTip("Backup Project")
self.aBackupProject.triggered.connect(self.theParent.backupProject) self.aBackupProject.triggered.connect(self._doBackup)
self.toolsMenu.addAction(self.aBackupProject) self.toolsMenu.addAction(self.aBackupProject)
# Tools > Settings # Tools > Settings
+2 -9
View File
@@ -45,7 +45,7 @@ from nw.gui import (
GuiConfigEditor, GuiProjectEditor, GuiItemEditor, GuiProjectOutline, GuiConfigEditor, GuiProjectEditor, GuiItemEditor, GuiProjectOutline,
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad
) )
from nw.project import NWProject, NWDoc, NWIndex, NWBackup from nw.project import NWProject, NWDoc, NWIndex
from nw.tools import countWords from nw.tools import countWords
from nw.constants import nwFiles, nwItemType, nwAlert from nw.constants import nwFiles, nwItemType, nwAlert
@@ -333,7 +333,7 @@ class GuiMain(QMainWindow):
if msgRes != QMessageBox.Yes: if msgRes != QMessageBox.Yes:
doBackup = False doBackup = False
if doBackup: if doBackup:
self.backupProject() self.theProject.zipIt(False)
else: else:
saveOK = True saveOK = True
@@ -450,13 +450,6 @@ class GuiMain(QMainWindow):
return True return True
def backupProject(self):
"""Trigger the project backup process.
"""
theBackup = NWBackup(self, self.theProject)
theBackup.zipIt()
return True
## ##
# Document Actions # Document Actions
## ##
-2
View File
@@ -1,12 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from nw.project.backup import NWBackup
from nw.project.document import NWDoc from nw.project.document import NWDoc
from nw.project.index import NWIndex from nw.project.index import NWIndex
from nw.project.project import NWProject from nw.project.project import NWProject
__all__ = [ __all__ = [
"NWBackup",
"NWDoc", "NWDoc",
"NWIndex", "NWIndex",
"NWProject", "NWProject",
-99
View File
@@ -1,99 +0,0 @@
# -*- coding: utf-8 -*-
"""novelWriter Project Backup
novelWriter Project Backup
==============================
Class handling project backups
File History:
Created: 2019-06-16 [0.1.5]
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging
import nw
from os import path
from shutil import make_archive
from datetime import datetime
from nw.constants import nwAlert
logger = logging.getLogger(__name__)
class NWBackup():
def __init__(self, theParent, theProject):
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theProject
return
def zipIt(self):
if self.mainConf.backupPath is None or self.mainConf.backupPath == "":
self.theParent.makeAlert((
"Cannot backup project because no backup path is set. "
"Please set a valid backup location in Tools > Preferences."
), nwAlert.WARN)
return False
if self.theProject.projName is None or self.theProject.projName == "":
self.theParent.makeAlert((
"Cannot backup project because no project name is set. "
"Please set a Working Title in Project > Project Settings."
), nwAlert.WARN)
return False
if not path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert((
"Cannot backup project because the backup path does not exist. "
"Please set a valid backup location in Tools > Preferences."
), nwAlert.WARN)
return False
logger.info("Backing up project")
self.theParent.statusBar.setStatus("Backing up project ...")
archName = ""
for c in self.theProject.projName:
if c.isalnum():
archName += c
else:
archName += "_"
archName = archName+"_"+datetime.now().strftime("%Y%m%d-%H%M%S")
baseName = path.join(self.mainConf.backupPath, archName)
try:
self.theProject._clearLockFile()
make_archive(baseName, "zip", self.theProject.projPath, ".")
self.theProject._writeLockFile()
logger.info("Backup written to: %s" % archName)
except Exception as e:
self.theParent.makeAlert(
["Could not write backup archive.",str(e)],
nwAlert.ERROR
)
return False
self.theParent.statusBar.setStatus("Project backup complete")
return True
# END Class NWBackup
+75
View File
@@ -38,6 +38,7 @@ from lxml import etree
from hashlib import sha256 from hashlib import sha256
from datetime import datetime from datetime import datetime
from time import time from time import time
from shutil import make_archive
from nw.tools import projectMaintenance, OptionState from nw.tools import projectMaintenance, OptionState
from nw.common import checkString, checkBool, checkInt from nw.common import checkString, checkBool, checkInt
@@ -478,6 +479,80 @@ class NWProject():
self.lockedBy = None self.lockedBy = None
return True return True
##
# Backup Project
##
def zipIt(self, doNotify):
"""Create a zip file of the entire project.
"""
logger.info("Backing up project")
self.theParent.statusBar.setStatus("Backing up project ...")
if self.mainConf.backupPath is None or self.mainConf.backupPath == "":
self.theParent.makeAlert((
"Cannot backup project because no backup path is set. "
"Please set a valid backup location in Tools > Preferences."
), nwAlert.WARN)
return False
if self.projName is None or self.projName == "":
self.theParent.makeAlert((
"Cannot backup project because no project name is set. "
"Please set a Working Title in Project > Project Settings."
), nwAlert.WARN)
return False
if not path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert((
"Cannot backup project because the backup path does not exist. "
"Please set a valid backup location in Tools > Preferences."
), nwAlert.WARN)
return False
cleanName = ""
for c in self.projName.strip():
if c.isalpha() or c.isdigit() or c == " ":
cleanName += c
baseDir = path.join(self.mainConf.backupPath, cleanName)
if not path.isdir(baseDir):
try:
mkdir(baseDir)
logger.debug("Created folder %s" % baseDir)
except Exception as e:
self.theParent.makeAlert(
["Could not create backup folder.",str(e)],
nwAlert.ERROR
)
return False
archName = "Backup on %s" % datetime.now().strftime("%Y-%m-%d at %H.%M.%S")
baseName = path.join(baseDir, archName)
try:
self._clearLockFile()
make_archive(baseName, "zip", self.projPath, ".")
self._writeLockFile()
if doNotify:
self.theParent.makeAlert(
"Backup archive file written to: '%s.zip'" % path.join(cleanName, archName),
nwAlert.INFO
)
else:
logger.info("Backup written to: %s" % archName)
except Exception as e:
self.theParent.makeAlert(
["Could not write backup archive.",str(e)],
nwAlert.ERROR
)
return False
self.theParent.statusBar.setStatus("Project backed up to '%s.zip'" % baseName)
return True
## ##
# Setters # Setters
## ##