mirror of
https://github.com/robweber/xbmcbackup.git
synced 2024-11-15 04:45:49 +01:00
Show File Transfer Size (#160)
adds file transfer size to progress bar - closes #157
This commit is contained in:
parent
23a14d67c4
commit
5d398836ba
16
changelog.md
16
changelog.md
@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
|
|
||||||
|
## [Unreleased](https://github.com/robweber/xbmcbackup/compare/matrix-1.6.0...HEAD)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- added method to get size of a file from the VFS
|
||||||
|
- added total transfer size information to progress bar with appropriate precision (KB, MB, etc)
|
||||||
|
- show file size of zip files in the restore selection dialog
|
||||||
|
- added getSettingInt and getSettingBool to utils.py class
|
||||||
|
- added verbose logging setting and tied it to logging related to file paths added/written, this will significantly reduce the debug log size (thanks CastagnaIT)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- display every file transfered in progress bar, not just directory
|
||||||
|
- base progress bar percent on transfer size, not total files
|
||||||
|
- changed getSettings where needed to getSettingBool and getSettingInt
|
||||||
|
|
||||||
## [Version 1.6.0](https://github.com/robweber/xbmcbackup/compare/krypton-1.5.2...robweber:matrix-1.6.0) - 2019-11-26
|
## [Version 1.6.0](https://github.com/robweber/xbmcbackup/compare/krypton-1.5.2...robweber:matrix-1.6.0) - 2019-11-26
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -556,3 +556,7 @@ msgstr ""
|
|||||||
msgctxt "#30141"
|
msgctxt "#30141"
|
||||||
msgid "This will erase any current Advanced Editor settings"
|
msgid "This will erase any current Advanced Editor settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgctxt "#30142"
|
||||||
|
msgid "Enable Verbose Logging"
|
||||||
|
msgstr ""
|
@ -4,6 +4,7 @@ import json
|
|||||||
import xbmc
|
import xbmc
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmcvfs
|
import xbmcvfs
|
||||||
|
import os.path
|
||||||
from . import utils as utils
|
from . import utils as utils
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from . vfs import XBMCFileSystem, DropboxFileSystem, ZipFileSystem
|
from . vfs import XBMCFileSystem, DropboxFileSystem, ZipFileSystem
|
||||||
@ -39,8 +40,8 @@ class XbmcBackup:
|
|||||||
|
|
||||||
# for the progress bar
|
# for the progress bar
|
||||||
progressBar = None
|
progressBar = None
|
||||||
filesLeft = 0
|
transferSize = 0
|
||||||
filesTotal = 1
|
transferLeft = 0
|
||||||
|
|
||||||
restore_point = None
|
restore_point = None
|
||||||
skip_advanced = False # if we should check for the existance of advancedsettings in the restore
|
skip_advanced = False # if we should check for the existance of advancedsettings in the restore
|
||||||
@ -92,8 +93,8 @@ class XbmcBackup:
|
|||||||
|
|
||||||
if(file_ext == 'zip' and len(folderName) == 12 and folderName.isdigit()):
|
if(file_ext == 'zip' and len(folderName) == 12 and folderName.isdigit()):
|
||||||
|
|
||||||
# format the name according to regional settings
|
# format the name according to regional settings and display the file size
|
||||||
folderName = self._dateFormat(folderName)
|
folderName = "%s - %s" % (self._dateFormat(folderName), utils.diskString(self.remote_vfs.fileSize(self.remote_base_path + aFile)))
|
||||||
|
|
||||||
result.append((aFile, folderName))
|
result.append((aFile, folderName))
|
||||||
|
|
||||||
@ -162,7 +163,7 @@ class XbmcBackup:
|
|||||||
orig_base_path = self.remote_vfs.root_path
|
orig_base_path = self.remote_vfs.root_path
|
||||||
|
|
||||||
# backup all the files
|
# backup all the files
|
||||||
self.filesLeft = self.filesTotal
|
self.transferLeft = self.transferSize
|
||||||
for fileGroup in allFiles:
|
for fileGroup in allFiles:
|
||||||
self.xbmc_vfs.set_root(xbmc.translatePath(fileGroup['source']))
|
self.xbmc_vfs.set_root(xbmc.translatePath(fileGroup['source']))
|
||||||
self.remote_vfs.set_root(fileGroup['dest'] + fileGroup['name'])
|
self.remote_vfs.set_root(fileGroup['dest'] + fileGroup['name'])
|
||||||
@ -185,11 +186,13 @@ class XbmcBackup:
|
|||||||
self.xbmc_vfs.rename(xbmc.translatePath("special://temp/xbmc_backup_temp.zip"), xbmc.translatePath("special://temp/" + zip_name))
|
self.xbmc_vfs.rename(xbmc.translatePath("special://temp/xbmc_backup_temp.zip"), xbmc.translatePath("special://temp/" + zip_name))
|
||||||
fileManager.addFile(xbmc.translatePath("special://temp/" + zip_name))
|
fileManager.addFile(xbmc.translatePath("special://temp/" + zip_name))
|
||||||
|
|
||||||
# set root to data dir home
|
# set root to data dir home and reset remote
|
||||||
self.xbmc_vfs.set_root(xbmc.translatePath("special://temp/"))
|
self.xbmc_vfs.set_root(xbmc.translatePath("special://temp/"))
|
||||||
|
|
||||||
self.remote_vfs = self.saved_remote_vfs
|
self.remote_vfs = self.saved_remote_vfs
|
||||||
self.progressBar.updateProgress(98, utils.getString(30088))
|
|
||||||
|
# update the amount to transfer
|
||||||
|
self.transferSize = fileManager.fileSize()
|
||||||
|
self.transferLeft = self.transferSize
|
||||||
fileCopied = self._copyFiles(fileManager.getFiles(), self.xbmc_vfs, self.remote_vfs)
|
fileCopied = self._copyFiles(fileManager.getFiles(), self.xbmc_vfs, self.remote_vfs)
|
||||||
|
|
||||||
if(not fileCopied):
|
if(not fileCopied):
|
||||||
@ -221,9 +224,12 @@ class XbmcBackup:
|
|||||||
|
|
||||||
if(not self.xbmc_vfs.exists(xbmc.translatePath("special://temp/" + self.restore_point))):
|
if(not self.xbmc_vfs.exists(xbmc.translatePath("special://temp/" + self.restore_point))):
|
||||||
# copy just this file from the remote vfs
|
# copy just this file from the remote vfs
|
||||||
|
self.transferSize = self.remote_vfs.fileSize(self.remote_base_path + self.restore_point)
|
||||||
zipFile = []
|
zipFile = []
|
||||||
zipFile.append(self.remote_base_path + self.restore_point)
|
zipFile.append({'file': self.remote_base_path + self.restore_point, 'size': self.transferSize})
|
||||||
|
|
||||||
|
# set transfer size
|
||||||
|
self.transferLeft = self.transferSize
|
||||||
self._copyFiles(zipFile, self.remote_vfs, self.xbmc_vfs)
|
self._copyFiles(zipFile, self.remote_vfs, self.xbmc_vfs)
|
||||||
else:
|
else:
|
||||||
utils.log("zip file exists already")
|
utils.log("zip file exists already")
|
||||||
@ -298,14 +304,15 @@ class XbmcBackup:
|
|||||||
if(self.remote_vfs.exists(self.remote_vfs.root_path + aDir['name'] + '/')):
|
if(self.remote_vfs.exists(self.remote_vfs.root_path + aDir['name'] + '/')):
|
||||||
# walk the directory
|
# walk the directory
|
||||||
fileManager.walkTree(self.remote_vfs.root_path + aDir['name'] + '/')
|
fileManager.walkTree(self.remote_vfs.root_path + aDir['name'] + '/')
|
||||||
self.filesTotal = self.filesTotal + fileManager.size()
|
self.transferSize = self.transferSize + fileManager.fileSize()
|
||||||
|
|
||||||
allFiles.append({"source": self.remote_vfs.root_path + aDir['name'], "dest": self.xbmc_vfs.root_path, "files": fileManager.getFiles()})
|
allFiles.append({"source": self.remote_vfs.root_path + aDir['name'], "dest": self.xbmc_vfs.root_path, "files": fileManager.getFiles()})
|
||||||
else:
|
else:
|
||||||
utils.log("error path not found: " + self.remote_vfs.root_path + aDir['name'])
|
utils.log("error path not found: " + self.remote_vfs.root_path + aDir['name'])
|
||||||
xbmcgui.Dialog().ok(utils.getString(30010), utils.getString(30045), self.remote_vfs.root_path + aDir['name'])
|
xbmcgui.Dialog().ok(utils.getString(30010), utils.getString(30045), self.remote_vfs.root_path + aDir['name'])
|
||||||
|
|
||||||
# restore all the files
|
# restore all the files
|
||||||
self.filesLeft = self.filesTotal
|
self.transferLeft = self.transferSize
|
||||||
for fileGroup in allFiles:
|
for fileGroup in allFiles:
|
||||||
self.remote_vfs.set_root(fileGroup['source'])
|
self.remote_vfs.set_root(fileGroup['source'])
|
||||||
self.xbmc_vfs.set_root(fileGroup['dest'])
|
self.xbmc_vfs.set_root(fileGroup['dest'])
|
||||||
@ -379,7 +386,7 @@ class XbmcBackup:
|
|||||||
result = True
|
result = True
|
||||||
|
|
||||||
utils.log("Source: " + source.root_path)
|
utils.log("Source: " + source.root_path)
|
||||||
utils.log("Desintation: " + dest.root_path)
|
utils.log("Destination: " + dest.root_path)
|
||||||
|
|
||||||
# make sure the dest folder exists - can cause write errors if the full path doesn't exist
|
# make sure the dest folder exists - can cause write errors if the full path doesn't exist
|
||||||
if(not dest.exists(dest.root_path)):
|
if(not dest.exists(dest.root_path)):
|
||||||
@ -390,20 +397,21 @@ class XbmcBackup:
|
|||||||
if(utils.getSettingBool('verbose_logging')):
|
if(utils.getSettingBool('verbose_logging')):
|
||||||
utils.log('Writing file: ' + aFile)
|
utils.log('Writing file: ' + aFile)
|
||||||
|
|
||||||
if(aFile.startswith("-")):
|
if(aFile['file'].startswith("-")):
|
||||||
self._updateProgress(aFile[len(source.root_path) + 1:])
|
self._updateProgress('%s remaining, writing %s' % (utils.diskString(self.transferLeft), os.path.basename(aFile['file'][len(source.root_path):]) + "/"))
|
||||||
dest.mkdir(dest.root_path + aFile[len(source.root_path) + 1:])
|
dest.mkdir(dest.root_path + aFile['file'][len(source.root_path) + 1:])
|
||||||
else:
|
else:
|
||||||
self._updateProgress()
|
self._updateProgress('%s remaining, writing %s' % (utils.diskString(self.transferLeft), os.path.basename(aFile['file'][len(source.root_path):])))
|
||||||
|
self.transferLeft = self.transferLeft - aFile['size']
|
||||||
|
|
||||||
wroteFile = True
|
wroteFile = True
|
||||||
destFile = dest.root_path + aFile[len(source.root_path):]
|
destFile = dest.root_path + aFile['file'][len(source.root_path):]
|
||||||
if(isinstance(source, DropboxFileSystem)):
|
if(isinstance(source, DropboxFileSystem)):
|
||||||
# if copying from cloud storage we need the file handle, use get_file
|
# if copying from cloud storage we need the file handle, use get_file
|
||||||
wroteFile = source.get_file(aFile, destFile)
|
wroteFile = source.get_file(aFile['file'], destFile)
|
||||||
else:
|
else:
|
||||||
# copy using normal method
|
# copy using normal method
|
||||||
wroteFile = dest.put(aFile, destFile)
|
wroteFile = dest.put(aFile['file'], destFile)
|
||||||
|
|
||||||
# if result is still true but this file failed
|
# if result is still true but this file failed
|
||||||
if(not wroteFile and result):
|
if(not wroteFile and result):
|
||||||
@ -421,8 +429,9 @@ class XbmcBackup:
|
|||||||
|
|
||||||
# walk all the root trees
|
# walk all the root trees
|
||||||
fileManager.walk()
|
fileManager.walk()
|
||||||
# update total files
|
|
||||||
self.filesTotal = self.filesTotal + fileManager.size()
|
# update total size
|
||||||
|
self.transferSize = self.transferSize + fileManager.fileSize()
|
||||||
|
|
||||||
return {"name": folder_name, "source": root_path, "dest": self.remote_vfs.root_path, "files": fileManager.getFiles()}
|
return {"name": folder_name, "source": root_path, "dest": self.remote_vfs.root_path, "files": fileManager.getFiles()}
|
||||||
|
|
||||||
@ -436,8 +445,7 @@ class XbmcBackup:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def _updateProgress(self, message=None):
|
def _updateProgress(self, message=None):
|
||||||
self.filesLeft = self.filesLeft - 1
|
self.progressBar.updateProgress(int((float(self.transferSize - self.transferLeft) / float(self.transferSize)) * 100), message)
|
||||||
self.progressBar.updateProgress(int((float(self.filesTotal - self.filesLeft) / float(self.filesTotal)) * 100), message)
|
|
||||||
|
|
||||||
def _rotateBackups(self):
|
def _rotateBackups(self):
|
||||||
total_backups = utils.getSettingInt('backup_rotation')
|
total_backups = utils.getSettingInt('backup_rotation')
|
||||||
@ -449,7 +457,6 @@ class XbmcBackup:
|
|||||||
if(len(dirs) > total_backups):
|
if(len(dirs) > total_backups):
|
||||||
# remove backups to equal total wanted
|
# remove backups to equal total wanted
|
||||||
remove_num = 0
|
remove_num = 0
|
||||||
self.filesTotal = self.filesTotal + remove_num + 1
|
|
||||||
|
|
||||||
# update the progress bar if it is available
|
# update the progress bar if it is available
|
||||||
while(remove_num < (len(dirs) - total_backups) and not self.progressBar.checkCancel()):
|
while(remove_num < (len(dirs) - total_backups) and not self.progressBar.checkCancel()):
|
||||||
@ -538,6 +545,7 @@ class FileManager:
|
|||||||
exclude_dir = []
|
exclude_dir = []
|
||||||
root_dirs = []
|
root_dirs = []
|
||||||
pathSep = '/'
|
pathSep = '/'
|
||||||
|
totalSize = 0
|
||||||
|
|
||||||
def __init__(self, vfs):
|
def __init__(self, vfs):
|
||||||
self.vfs = vfs
|
self.vfs = vfs
|
||||||
@ -598,7 +606,11 @@ class FileManager:
|
|||||||
if(utils.getSettingBool('verbose_logging')):
|
if(utils.getSettingBool('verbose_logging')):
|
||||||
utils.log("Add File: " + filename)
|
utils.log("Add File: " + filename)
|
||||||
|
|
||||||
self.fileArray.append(filename)
|
# get the file size
|
||||||
|
fSize = self.vfs.fileSize(filename)
|
||||||
|
self.totalSize = self.totalSize + fSize
|
||||||
|
|
||||||
|
self.fileArray.append({'file': filename, 'size': fSize})
|
||||||
|
|
||||||
def excludeFile(self, filename):
|
def excludeFile(self, filename):
|
||||||
# remove trailing slash
|
# remove trailing slash
|
||||||
@ -614,8 +626,12 @@ class FileManager:
|
|||||||
self.fileArray = []
|
self.fileArray = []
|
||||||
self.root_dirs = []
|
self.root_dirs = []
|
||||||
self.exclude_dir = []
|
self.exclude_dir = []
|
||||||
|
self.totalSize = 0
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def size(self):
|
def totalFiles(self):
|
||||||
return len(self.fileArray)
|
return len(self.fileArray)
|
||||||
|
|
||||||
|
def fileSize(self):
|
||||||
|
return self.totalSize
|
||||||
|
@ -53,3 +53,16 @@ def getRegionalTimestamp(date_time, dateformat=['dateshort']):
|
|||||||
result = result + ("%s " % date_time.strftime(xbmc.getRegion(aFormat)))
|
result = result + ("%s " % date_time.strftime(xbmc.getRegion(aFormat)))
|
||||||
|
|
||||||
return result.strip()
|
return result.strip()
|
||||||
|
|
||||||
|
|
||||||
|
def diskString(fSize):
|
||||||
|
# convert a size in kilobytes to the best possible match and return as a string
|
||||||
|
fSize = float(fSize)
|
||||||
|
i = 0
|
||||||
|
sizeNames = ['KB', 'MB', 'GB', 'TB']
|
||||||
|
|
||||||
|
while(fSize > 1024):
|
||||||
|
fSize = fSize / 1024
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
return "%0.2f%s" % (fSize, sizeNames[i])
|
||||||
|
@ -55,6 +55,9 @@ class Vfs:
|
|||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def fileSize(self, filename):
|
||||||
|
return 0 # result should be in KB
|
||||||
|
|
||||||
|
|
||||||
class XBMCFileSystem(Vfs):
|
class XBMCFileSystem(Vfs):
|
||||||
|
|
||||||
@ -79,6 +82,13 @@ class XBMCFileSystem(Vfs):
|
|||||||
def exists(self, aFile):
|
def exists(self, aFile):
|
||||||
return xbmcvfs.exists(aFile)
|
return xbmcvfs.exists(aFile)
|
||||||
|
|
||||||
|
def fileSize(self, filename):
|
||||||
|
f = xbmcvfs.File(filename)
|
||||||
|
result = f.size() / 1024 # bytes to kilobytes
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class ZipFileSystem(Vfs):
|
class ZipFileSystem(Vfs):
|
||||||
zip = None
|
zip = None
|
||||||
@ -246,6 +256,16 @@ class DropboxFileSystem(Vfs):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def fileSize(self, filename):
|
||||||
|
result = 0
|
||||||
|
aFile = self._fix_slashes(filename)
|
||||||
|
|
||||||
|
if(self.client is not None):
|
||||||
|
metadata = self.client.files_get_metadata(aFile)
|
||||||
|
result = metadata.size / 1024 # bytes to KB
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def get_file(self, source, dest):
|
def get_file(self, source, dest):
|
||||||
if(self.client is not None):
|
if(self.client is not None):
|
||||||
# write the file locally
|
# write the file locally
|
||||||
|
Loading…
Reference in New Issue
Block a user