def doBackup(self): libDir = getSettingStr("Paths/Library") bkupPaths = getSettingStr("Paths/Backup") if libDir in (None, ''): QMessageBox.warning(self, "Backup Failed", "You need to specify a library directory in your settings") return if not os.path.exists(libDir) or os.path.isfile(libDir): QMessageBox.warning(self, "Backup Failed", "The library directory in your settings either doesn't exist, or its not a directory") return if bkupPaths in (None, ''): QMessageBox.warning(self, "Backup Failed", "You need to specify at least one backup directory in your settings") return dt = datetime.date.today() bkupDirName = str(dt.year) + str(dt.month) + str(dt.day) for path in bkupPaths.split(","): if not os.path.exists(path.strip()) or os.path.isfile(path.strip()): QMessageBox.warning(self, "Backup Failed", "The backup directory <%s> in your settings either doesn't exist, or its not a directory" % (path)) return if os.path.exists(path.strip() + os.sep + bkupDirName): QMessageBox.warning(self, "Backup Failed", "There is already a backup for today in a backup directory <%s>" % (path.strip())) return for path in bkupPaths.split(","): shutil.copytree(libDir, path.strip() + os.sep + bkupDirName) QMessageBox.information(self, "Backup", "Backup completed!")
def doSettings(self): libPath = getSettingStr("Paths/Library", "") backupPaths = getSettingStr("Paths/Backup", "") fileExt = getSettingStr("FileExtensions", "jpg, CR2") fileExtOther = getSettingStr("FileExtensionsOther", "mov, avi") dialog = SettingsDialog(self, libPath, backupPaths, fileExt, fileExtOther) if dialog.exec_(): saveSetting("Paths/Library", dialog.libPathEdit.text()) saveSetting("Paths/Backup", dialog.backupPathsEdit.text()) saveSetting("FileExtensions", dialog.fileExtensionEdit.text()) saveSetting("FileExtensionsOther", dialog.fileExtensionOtherEdit.text()) self.status.showMessage("Settings updated", 5000)
def isOtherManagedFile(self, filepath): #TODO Implement list of other files to import into lib folders and to backup extensionList = unicode(getSettingStr("FileExtensionsOther")).split(",") for extension in extensionList: if unicode(filepath).upper().endswith(unicode(extension).upper()): return True return False
def loadLibrary(self): self.status.showMessage("Loading Photo Library") self.rootAlbum = self.loadAlbum(getSettingStr("Paths/Library"), "Library") if self.rootAlbum == None: self.rootAlbum = Album(name="Library") self.refreshTree() self.status.showMessage("Library successfully loaded", 5000)
def isImageFile(self, filepath): extensionList = unicode(getSettingStr("FileExtensions")).split(",") for extension in extensionList: if unicode(filepath).upper().endswith(unicode(extension).upper()): return True return False
def buildLibPath(self, importFrom, path, albumpath): relPath = path[len(importFrom):] libPath = getSettingStr("Paths/Library") + os.sep + albumpath + relPath return libPath
def doImport(self): libPath = getSettingStr("Paths/Library") fileExt = getSettingStr("FileExtensions") if libPath in (None, ''): QMessageBox.warning(self, "Import Failed", "You need to specify a library directory in your settings") return if not os.path.exists(libPath) or os.path.isfile(libPath): QMessageBox.warning(self, "Import Failed", "The library directory in your settings either doesn't exist, or its not a directory") return if not fileExt or fileExt in (None, ''): QMessageBox.warning(self, "Import Failed", "You need to specify file extensions to manage in your settings") return lastImport = getSettingStr("Paths/LastImport") importFrom = QFileDialog.getExistingDirectory(self, "Choose a Path to Import From", lastImport) if importFrom in (None, ''): return if not os.path.exists(importFrom) or os.path.isfile(importFrom): QMessageBox.warning(self, "Import Failed", "The import directory either doesn't exist, or is not a directory") return if importFrom == libPath: QMessageBox.warning(self, "Import Failed", "Your import directory and library directory can not be the same") return imd = ImportMetadataDialog(self) if imd.exec_(): album = imd.albumEdit.text() comments = imd.commentsEdit.text() keywords = imd.keywordsEdit.text() if album and album not in (None, ''): albumpath = album + os.sep else: album = None albumpath = "" if not keywords or keywords in (None, ''): keywords = "" if not comments or comments in (None, ''): comments = "" paths = self.buildFileList(importFrom) numTotal = len(paths) nonDupes = self.removeDuplicates(paths, importFrom, albumpath) numDuplicates = numTotal - len(nonDupes) if QMessageBox.question(self, "Import", "Out of %d files found, %d look to be duplicates. Continue with import?" % (numTotal, numDuplicates), QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes: saveSetting("Paths/LastImport", importFrom) for path in nonDupes: dest = self.buildLibPath(importFrom, path, albumpath) copyFileIncludingDirectories(path, dest) # TODO Handle copy failure exceptions! if not os.path.exists(dest): QMessageBox.warming(self, "Import Failed", "The file <%s> was not imported properly, aborting import" % (path)) return if self.isImageFile(path): exif = loadExif(unicode(path), EXIF_TAGS) ph = Photo() ph.path = dest ph.srcPath = path ph.comment = comments ph.keywords = keywords ph.setExif(exif) ph.save(dest) #Create Thumbnail createThumbnail(unicode(ph.path)) QMessageBox.information(self, "Import", "Import completed") self.loadLibrary()
def __init__(self, parent=None): super(NPhotoMainWindow, self).__init__(parent) self.image = None self.status = self.statusBar() self.status.setSizeGripEnabled(False) fileMenu = self.menuBar().addMenu("&File") fileEditAction = createAction(self, "&Edit", self.doEdit, "Ctrl-E", "fileedit", "Edit photo details") fileDeleteAction = createAction(self, "&Delete", self.doDelete, "Ctrl-D", "filedelete", "Delete selected file(s)") fileImportAction = createAction(self, "&Import", self.doImport, "Ctrl-I", "fileimport", "Import photos into your library") fileRescanLibraryAction = createAction(self, "&Rescan", self.doRescan, "Ctrl-R", "filerescan", "Rescan library folder and update sidecar files, and thumbnails") fileBackupAction = createAction(self, "&Backup", self.doBackup, "Ctrl-B", "filebkup", "Backup your library") fileSettingsAction = createAction(self, "&Settings", self.doSettings, "Ctrl-S", "filesettings", "Settings") fileQuitAction = createAction(self, "&Quit", self.close, "Ctrl+Q", "filequit", "Close the application") helpMenu = self.menuBar().addMenu("&Help") helpAboutAction = createAction(self, "&About", self.doAbout, None, "helpabout", "About nPhoto") addActions(fileMenu, (fileEditAction, fileDeleteAction, None, fileImportAction, fileRescanLibraryAction, fileBackupAction, fileSettingsAction, None, fileQuitAction)) addActions(helpMenu, (helpAboutAction,)) size = getSettingQVar("MainWindow/Size", QSize(600,500)).toSize() self.resize(size) position = getSettingQVar("MainWindow/Position", QPoint(0,0)).toPoint() self.move(position) self.restoreState(getSettingQVar("MainWindow/State").toByteArray()) self.setWindowTitle("nPhoto") self.controlFrame = QFrame() self.controlLayout = QBoxLayout(QBoxLayout.TopToBottom) #TODO Make this a combo box that populates the tree by date or by folder self.viewByCombo = QLabel("PLACEHOLDER") self.tree = QTreeWidget() self.tree.setColumnCount(1) self.tree.setHeaderLabels(["Album"]) self.tree.setItemsExpandable(True) self.connect(self.tree, SIGNAL("itemSelectionChanged()"), self.treeSelection) self.controlLayout.addWidget(self.viewByCombo) self.controlLayout.addWidget(self.tree) self.controlFrame.setLayout(self.controlLayout) self.browserFrame = QFrame() self.browserGrid = QGridLayout() self.imageLabels = [] for row in range(0,BROWSER_GRID_HEIGHT): self.imageLabels.append([]) for col in range(0,BROWSER_GRID_WIDTH): self.imageLabels[row].append(QLabel()) self.imageLabels[row][col].setBackgroundRole(QPalette.Base) self.imageLabels[row][col].setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imageLabels[row][col].setScaledContents = True self.imageLabels[row][col].setAlignment(Qt.AlignCenter) self.imageLabels[row][col].setStyleSheet("border:2px solid #000") dbl = functools.partial(self.imgDoubleClick, row, col) click = functools.partial(self.imgMouseRelease, row, col) self.imageLabels[row][col].mouseDoubleClickEvent = dbl self.imageLabels[row][col].mouseReleaseEvent = click self.browserGrid.addWidget(self.imageLabels[row][col],row,col) self.prevPage = QPushButton("Prev") self.pageInfoLabel = QLabel("Page 0 of 0") self.pageInfoLabel.setAlignment(Qt.AlignCenter) self.nextPage = QPushButton("Next") self.prevPage.clicked.connect(self.goPreviousPage) self.nextPage.clicked.connect(self.goNextPage) self.browserGrid.addWidget(self.prevPage, row+1, 0) self.browserGrid.addWidget(self.pageInfoLabel, row+1, 1) self.browserGrid.addWidget(self.nextPage, row+1, 2) self.browserFrame.setLayout(self.browserGrid) self.mainSplitter = QSplitter(Qt.Horizontal) self.mainSplitter.addWidget(self.controlFrame) self.mainSplitter.addWidget(self.browserFrame) self.mainSplitter.setStretchFactor(1,4) self.setCentralWidget(self.mainSplitter) self.mainSplitter.restoreState(getSettingQVar("MainWindow/Splitter").toByteArray()) if getSettingStr("Paths/Library") not in (None, ''): QTimer.singleShot(0, self.loadLibrary) else: self.status.showMessage("No Library Path in settings", 10000)