diff --git a/default.py b/default.py index bf88686..b767524 100644 --- a/default.py +++ b/default.py @@ -1,7 +1,7 @@ import xbmc import xbmcaddon import xbmcgui -import resources.lib.vfs as vfs +import xbmcvfs import os import time @@ -13,6 +13,7 @@ class FileManager: addonDir = '' fileArray = None verbose_log = False + not_dir = ['.zip','.xsp','.rar'] def __init__(self,path,addon_dir): self.walk_path = path @@ -29,13 +30,13 @@ class FileManager: #figure out which syncing options to run if(Addon.getSetting('backup_addons') == 'true'): self.addFile("-addons") - self.walkTree(self.walk_path + "addons/") + self.walkTree(self.walk_path + "addons") self.addFile("-userdata") if(Addon.getSetting('backup_addon_data') == 'true'): self.addFile("-userdata/addon_data") - self.walkTree(self.walk_path + "userdata/addon_data/") + self.walkTree(self.walk_path + "userdata/addon_data") if(Addon.getSetting('backup_database') == 'true'): self.addFile("-userdata/Database") @@ -57,21 +58,28 @@ class FileManager: self.walkTree(self.walk_path + "userdata/peripheral_data") #this part is an oddity - configFiles = vfs.listdir(self.walk_path + "userdata/",extra_metadata=True) + dirs,configFiles = xbmcvfs.listdir(self.walk_path + "userdata/") for aFile in configFiles: - if(aFile['file'].endswith(".xml")): - self.addFile(aFile['file'][len(self.walk_path):]) + if(aFile.endswith(".xml")): + self.addFile("userdata/" + aFile) def walkTree(self,directory): - for (path, dirs, files) in vfs.walk(directory): + dirs,files = xbmcvfs.listdir(directory) + + #create all the subdirs first + for aDir in dirs: + dirPath = xbmc.translatePath(directory + "/" + aDir) + file_ext = aDir.split('.')[-1] + + self.addFile("-" + dirPath[len(self.walk_path):].decode("UTF-8")) + #catch for "non directory" type files + if (not any(file_ext in s for s in self.not_dir)): + self.walkTree(dirPath) - #create all the subdirs first - for aDir in dirs: - self.addFile("-" + aDir[len(self.walk_path):]) - #copy all the files - for aFile in files: - filePath = aFile[len(self.walk_path):] - self.addFile(filePath) + #copy all the files + for aFile in files: + filePath = xbmc.translatePath(directory + "/" + aFile) + self.addFile(filePath[len(self.walk_path):].decode("UTF-8")) def addFile(self,filename): #write the full remote path name of this file @@ -116,6 +124,9 @@ class XbmcBackup: self.remote_path = self.remote_path + self.addon.getSetting("backup_name") + "/" else: self.remote_path = "" + + self.local_path = self.local_path.decode("UTF-8") + self.local_path = self.local_path.decode("UTF-8") log(self.addon.getLocalizedString(30046)) log(self.addon.getLocalizedString(30047) + ": " + self.local_path) @@ -132,7 +143,7 @@ class XbmcBackup: self.fileManager = FileManager(self.local_path,self.addon.getAddonInfo('profile')) #for backups check if remote path exists - if(vfs.exists(self.remote_path)): + if(xbmcvfs.exists(self.remote_path)): #this will fail - need a disclaimer here log(self.addon.getLocalizedString(30050)) @@ -141,7 +152,7 @@ class XbmcBackup: self.fileManager = FileManager(self.remote_path,self.addon.getAddonInfo('profile')) #for restores remote path must exist - if(vfs.exists(self.remote_path)): + if(xbmcvfs.exists(self.remote_path)): self.restoreFiles() else: xbmcgui.Dialog().ok(self.addon.getLocalizedString(30010),self.addon.getLocalizedString(30045)) @@ -149,7 +160,7 @@ class XbmcBackup: def syncFiles(self): #make the remote directory - vfs.mkdir(self.remote_path) + xbmcvfs.mkdir(self.remote_path) log(self.addon.getLocalizedString(30051)) self.fileManager.createFileList(self.addon) @@ -182,9 +193,9 @@ class XbmcBackup: log('Writing file: ' + source + aFile,xbmc.LOGDEBUG) self.updateProgress(aFile) if (aFile.startswith("-")): - vfs.mkdir(xbmc.makeLegalFilename(dest + aFile[1:],False)) + xbmcvfs.mkdir(xbmc.makeLegalFilename(dest + aFile[1:],False)) else: - vfs.copy(xbmc.makeLegalFilename(source + aFile),xbmc.makeLegalFilename(dest + aFile,False)) + xbmcvfs.copy(xbmc.makeLegalFilename(source + aFile),xbmc.makeLegalFilename(dest + aFile,False)) if(self.addon.getSetting('run_silent') == 'false'): self.progressBar.close() @@ -209,7 +220,8 @@ class XbmcBackup: #global functions for logging and encoding def log(message,loglevel=xbmc.LOGNOTICE): - xbmc.log(encode(__Addon.getLocalizedString(30010) + ": " + message),level=loglevel) + logM = encode(__Addon.getLocalizedString(30010) + ": " + message) + xbmc.log(logM,level=loglevel) def encode(string): return string.encode('UTF-8','replace') diff --git a/resources/__init__.py b/resources/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/resources/lib/__init__.py b/resources/lib/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/resources/lib/vfs.py b/resources/lib/vfs.py deleted file mode 100644 index 14762b6..0000000 --- a/resources/lib/vfs.py +++ /dev/null @@ -1,256 +0,0 @@ -''' - Convenience wrappers and extensions for some commonly used VFS functions - in XBMC addons. This module exposes all the functionality of xbmcvfs plus - some extra functions. - - Copyright (C) 2012 Patrick Carey - - 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 . -''' - -import json -import os -import xbmc -import xbmcvfs -import urllib - -def walk(path): - - ''' - Reimplementation of os.walk using XBMC's jsonrpc API. - - This has the nice added benefits of being able to walk remote - directories and inside compressed files such as rars/zips. - ''' - - dir_tree = [[path]] - - current_depth = 0 - - not_dir = ['.zip','.xsp','.rar'] - - while True: - - if current_depth > -1: - - try: - - current_path = dir_tree[current_depth].pop(0) - current_dirs, current_files = [], [] - - for x in listdir(current_path, extra_metadata=True): - - file_ext = x['file'].split('.')[-1] - - if x['filetype'] == 'directory' and not any(file_ext in s for s in not_dir): - - current_dirs.append(urllib.unquote(x['file'])) - - else: - - current_files.append(urllib.unquote(x['file'])) - - except IndexError: - - current_depth -= 1 - - dir_tree.pop() - - else: - - yield (current_path, current_dirs, current_files) - - if current_dirs: - - current_depth += 1 - - dir_tree.append(current_dirs) - - else: - - break - - -def listdir(path, extra_metadata=False): - - ''' - Reimplementation of os.listdir using XBMC's jsonrpc API. - - Returns a list of file/directory names from the specified path - - Accepts an optional boolean 'extra_metadata' as the second argument - which will cause the function to instead return a list of dictionaries - containing all of the metadata about each file that was retrieved from - XBMC. - ''' - - fileList = [] - - json_response = xbmc.executeJSONRPC('{ "jsonrpc" : "2.0" , "method" : "Files.GetDirectory" , "params" : { "directory" : "%s" , "sort" : { "method" : "file" } } , "id" : 1 }' % path.encode('utf-8').replace('\\', '\\\\')) - - jsonobject = json.loads(json_response) - - if jsonobject.has_key('result') and jsonobject['result']['files']: - - for item in jsonobject['result']['files']: - - if extra_metadata: - - fileList.append(item) - - else: - - fileList.append(item['file']) - - return fileList - - -def copy(source, destination): - - """ - copy(source, destination) -- Copy file to destination, returns true/false. - - source : file to copy. - destination : destination file - - example: - - success = vfs.copy(source, destination) - """ - - return xbmcvfs.copy(source, destination) - - -def delete(path): - - """ - delete(file) -- Delete file - - file : file to delete - - example: - - vfs.delete(file) - """ - - return xbmcvfs.delete(path) - - -def exists(path): - - """ - exists(path) -- Check if file exists, returns true/false. - - path : file or folder - - example: - - success = vfs.exists(path) - """ - - return xbmcvfs.exists(path) - - -def mkdir(path): - - """ - mkdir(path) -- Create a folder. - - path : folder - - example: - - success = vfs.mkdir(path) - """ - - return xbmcvfs.mkdir(path) - - -def rename(source, target): - - """ - rename(file, newFileName) -- Rename file, returns true/false. - - file : file to reaname - newFileName : new filename, including the full path - - example: - - success = vfs.rename(file, newFileName) - """ - - return xbmcvfs.rename(source, target) - - -def rmdir(path): - - """ - rmdir(path) -- Remove a folder. - - path : folder - - example: - - success = vfs.rmdir(path) - """ - - return xbmcvfs.rmdir(path) - - -def comparepathlists(list1, list2, fullpath=False): - - """ - comparepathlists(list1, list2) -- Compare two lists of paths - - list1 : list, contains paths (local or remote, absolute or relative) - list2 : list, contains paths (local or remote, absolute or relative) - fullpath : boolean, set True to compare perform straight comparison of lists - set False (default) to compare on filename portions of each list - - returns: dictionary: - common_items: list, contains paths of items common to both lists - list1_items: list, contains paths of items found only in list1 - list2_items: list, contains paths of items found only in list2 - - example: - - compare = comparepathlists(list1, list2) - """ - - # initialise dict to store results and temp data - results = {} - temp_data = {} - - if fullpath: - - temp_path = lambda x: x - - else: - - temp_path = lambda x: os.path.split(x)[1] - - for path in list1: - - temp_data['list1'].append(temp_path(path)) - - for path in list2: - - temp_data['list2'].append(temp_path(path)) - - # get items not in list 2 - results['list1_items'] = [] - gen = (i for i, x in enumerate(temp_data['list1']) if not x in temp_data['list2']) - for i in gen: - results['list1_items'].append(list1[i]) - - # get items not in list 1 - results['list2_items'] = [] - gen = (i for i, x in enumerate(temp_data['list2']) if not x in temp_data['list1']) - for i in gen: - results['list2_items'].append(list2[i]) - - return results