2019-08-26 22:40:15 +02:00
import json
2019-11-25 22:48:42 +01:00
import xbmc
import xbmcgui
import xbmcvfs
2019-12-04 18:31:00 +01:00
import os . path
2019-08-27 21:55:22 +02:00
from . import utils as utils
2019-08-26 22:40:15 +02:00
2019-11-26 17:43:38 +01:00
2019-08-26 22:40:15 +02:00
class BackupSetManager :
jsonFile = xbmc . translatePath ( utils . data_dir ( ) + " custom_paths.json " )
paths = None
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
def __init__ ( self ) :
self . paths = { }
2019-11-25 22:33:34 +01:00
2019-11-25 22:19:57 +01:00
# try and read in the custom file
2019-08-26 22:40:15 +02:00
self . _readFile ( )
2019-11-25 22:45:41 +01:00
def addSet ( self , aSet ) :
2019-11-26 17:49:17 +01:00
self . paths [ aSet [ ' name ' ] ] = { ' root ' : aSet [ ' root ' ] , ' dirs ' : [ { " type " : " include " , " path " : aSet [ ' root ' ] , ' recurse ' : True } ] }
2019-08-26 22:40:15 +02:00
2019-11-25 22:19:57 +01:00
# save the file
2019-08-26 22:40:15 +02:00
self . _writeFile ( )
2019-11-25 22:45:41 +01:00
def updateSet ( self , name , aSet ) :
2019-08-26 22:40:15 +02:00
self . paths [ name ] = aSet
2019-11-25 22:19:57 +01:00
# save the file
2019-08-26 22:40:15 +02:00
self . _writeFile ( )
2019-11-25 22:45:41 +01:00
def deleteSet ( self , index ) :
2019-11-25 22:19:57 +01:00
# match the index to a key
2019-08-26 22:40:15 +02:00
keys = self . getSets ( )
2019-11-25 22:19:57 +01:00
# delete this set
2019-08-26 22:40:15 +02:00
del self . paths [ keys [ index ] ]
2019-11-26 17:43:38 +01:00
# save the file
2019-08-26 22:40:15 +02:00
self . _writeFile ( )
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
def getSets ( self ) :
2019-11-25 22:19:57 +01:00
# list all current sets by name
2019-08-27 21:55:22 +02:00
keys = list ( self . paths . keys ( ) )
2019-08-26 22:40:15 +02:00
keys . sort ( )
return keys
2019-11-25 22:45:41 +01:00
def getSet ( self , index ) :
2019-11-26 17:43:38 +01:00
keys = self . getSets ( )
2019-08-26 22:40:15 +02:00
2019-11-25 22:19:57 +01:00
# return the set at this index
2019-11-26 17:43:38 +01:00
return { ' name ' : keys [ index ] , ' set ' : self . paths [ keys [ index ] ] }
2019-08-26 22:40:15 +02:00
2019-11-25 22:45:41 +01:00
def validateSetName ( self , name ) :
2019-08-26 22:40:15 +02:00
return ( name not in self . getSets ( ) )
def _writeFile ( self ) :
2019-11-25 22:19:57 +01:00
# create the custom file
2019-11-25 22:45:41 +01:00
aFile = xbmcvfs . File ( self . jsonFile , ' w ' )
2019-08-26 22:40:15 +02:00
aFile . write ( json . dumps ( self . paths ) )
aFile . close ( )
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
def _readFile ( self ) :
2019-11-26 17:49:17 +01:00
2019-08-26 22:40:15 +02:00
if ( xbmcvfs . exists ( self . jsonFile ) ) :
2019-11-25 22:19:57 +01:00
# read in the custom file
2019-08-26 22:40:15 +02:00
aFile = xbmcvfs . File ( self . jsonFile )
2019-11-25 22:19:57 +01:00
# load custom dirs
2019-08-26 22:40:15 +02:00
self . paths = json . loads ( aFile . read ( ) )
aFile . close ( )
else :
2019-11-25 22:19:57 +01:00
# write a blank file
2019-08-26 22:40:15 +02:00
self . _writeFile ( )
2019-11-26 17:49:17 +01:00
2019-08-26 22:40:15 +02:00
class AdvancedBackupEditor :
dialog = None
def __init__ ( self ) :
self . dialog = xbmcgui . Dialog ( )
2019-11-25 22:45:41 +01:00
def _cleanPath ( self , root , path ) :
2019-11-26 17:43:38 +01:00
return path [ len ( root ) - 1 : ]
2019-08-26 22:40:15 +02:00
2019-11-25 22:45:41 +01:00
def _validatePath ( self , root , path ) :
2019-08-26 22:40:15 +02:00
return path . startswith ( root )
def createSet ( self ) :
backupSet = None
2019-11-25 22:33:34 +01:00
2019-11-25 22:45:41 +01:00
name = self . dialog . input ( utils . getString ( 30110 ) , defaultt = ' Backup Set ' )
2019-08-26 22:40:15 +02:00
2019-11-26 17:43:38 +01:00
if ( name is not None ) :
2019-08-26 22:40:15 +02:00
2019-11-25 22:19:57 +01:00
# give a choice to start in home or enter a root path
2019-11-25 22:45:41 +01:00
enterHome = self . dialog . yesno ( utils . getString ( 30111 ) , line1 = utils . getString ( 30112 ) + " - " + utils . getString ( 30114 ) , line2 = utils . getString ( 30113 ) + " - " + utils . getString ( 30115 ) , nolabel = utils . getString ( 30112 ) , yeslabel = utils . getString ( 30113 ) )
2019-08-26 22:40:15 +02:00
rootFolder = ' special://home '
if ( enterHome ) :
2019-11-25 22:45:41 +01:00
rootFolder = self . dialog . input ( utils . getString ( 30116 ) , defaultt = rootFolder )
2019-08-26 22:40:15 +02:00
2019-11-25 22:19:57 +01:00
# direcotry has to end in slash
2019-08-26 22:40:15 +02:00
if ( rootFolder [ : - 1 ] != ' / ' ) :
rootFolder = rootFolder + ' / '
2019-11-25 22:19:57 +01:00
# check that this path even exists
2019-08-26 22:40:15 +02:00
if ( not xbmcvfs . exists ( xbmc . translatePath ( rootFolder ) ) ) :
2019-11-25 22:45:41 +01:00
self . dialog . ok ( utils . getString ( 30117 ) , utils . getString ( 30118 ) , rootFolder )
2019-08-26 22:40:15 +02:00
return None
else :
2019-11-25 22:19:57 +01:00
# select path to start set
2019-11-25 22:45:41 +01:00
rootFolder = self . dialog . browse ( type = 0 , heading = utils . getString ( 30119 ) , shares = ' files ' , defaultt = rootFolder )
2019-08-26 22:40:15 +02:00
2019-11-26 17:43:38 +01:00
backupSet = { ' name ' : name , ' root ' : rootFolder }
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
return backupSet
2019-11-26 17:43:38 +01:00
def editSet ( self , name , backupSet ) :
2019-08-26 22:40:15 +02:00
optionSelected = ' '
rootPath = backupSet [ ' root ' ]
2019-11-26 18:31:40 +01:00
2019-08-26 22:40:15 +02:00
while ( optionSelected != - 1 ) :
2019-11-25 22:45:41 +01:00
options = [ xbmcgui . ListItem ( utils . getString ( 30120 ) , " Exclude a specific folder from this backup set " ) , xbmcgui . ListItem ( utils . getString ( 30135 ) , " Include a specific folder to this backup set " ) , xbmcgui . ListItem ( rootPath , utils . getString ( 30121 ) ) ]
2019-08-26 22:40:15 +02:00
for aDir in backupSet [ ' dirs ' ] :
if ( aDir [ ' type ' ] == ' exclude ' ) :
2019-11-26 17:43:38 +01:00
options . append ( xbmcgui . ListItem ( self . _cleanPath ( rootPath , aDir [ ' path ' ] ) , " %s : %s " % ( " Type " , utils . getString ( 30129 ) ) ) )
2019-08-26 22:40:15 +02:00
elif ( aDir [ ' type ' ] == ' include ' ) :
2019-11-26 17:43:38 +01:00
options . append ( xbmcgui . ListItem ( self . _cleanPath ( rootPath , aDir [ ' path ' ] ) , " %s : %s | %s : %s " % ( " Type " , utils . getString ( 30134 ) , " Include Sub Folders " , str ( aDir [ ' recurse ' ] ) ) ) )
2019-08-26 22:40:15 +02:00
2019-11-26 17:49:17 +01:00
optionSelected = self . dialog . select ( utils . getString ( 30122 ) + ' ' + name , options , useDetails = True )
2019-08-26 22:40:15 +02:00
if ( optionSelected == 0 or optionSelected == 1 ) :
2019-11-25 22:19:57 +01:00
# add a folder, will equal root if cancel is hit
2019-11-25 22:45:41 +01:00
addFolder = self . dialog . browse ( type = 0 , heading = utils . getString ( 30120 ) , shares = ' files ' , defaultt = backupSet [ ' root ' ] )
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
if ( addFolder . startswith ( rootPath ) ) :
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
if ( not any ( addFolder == aDir [ ' path ' ] for aDir in backupSet [ ' dirs ' ] ) ) :
2019-11-25 22:19:57 +01:00
# cannot add root as an exclusion
2019-08-26 22:40:15 +02:00
if ( optionSelected == 0 and addFolder != backupSet [ ' root ' ] ) :
2019-11-26 17:43:38 +01:00
backupSet [ ' dirs ' ] . append ( { " path " : addFolder , " type " : " exclude " } )
2019-08-26 22:40:15 +02:00
elif ( optionSelected == 1 ) :
2019-11-25 22:19:57 +01:00
# can add root as inclusion
2019-11-26 17:43:38 +01:00
backupSet [ ' dirs ' ] . append ( { " path " : addFolder , " type " : " include " , " recurse " : True } )
2019-08-26 22:40:15 +02:00
else :
2019-11-25 22:19:57 +01:00
# this path is already part of another include/exclude rule
2019-11-25 22:45:41 +01:00
self . dialog . ok ( utils . getString ( 30117 ) , utils . getString ( 30137 ) , addFolder )
2019-08-26 22:40:15 +02:00
else :
2019-11-25 22:19:57 +01:00
# folder must be under root folder
2019-11-25 22:45:41 +01:00
self . dialog . ok ( utils . getString ( 30117 ) , utils . getString ( 30136 ) , rootPath )
2019-08-26 22:40:15 +02:00
elif ( optionSelected == 2 ) :
2019-11-25 22:45:41 +01:00
self . dialog . ok ( utils . getString ( 30121 ) , utils . getString ( 30130 ) , backupSet [ ' root ' ] )
2019-08-26 22:40:15 +02:00
elif ( optionSelected > 2 ) :
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
cOptions = [ ' Delete ' ]
if ( backupSet [ ' dirs ' ] [ optionSelected - 3 ] [ ' type ' ] == ' include ' ) :
cOptions . append ( ' Toggle Sub Folders ' )
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
contextOption = self . dialog . contextmenu ( cOptions )
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
if ( contextOption == 0 ) :
2019-11-25 22:45:41 +01:00
if ( self . dialog . yesno ( heading = utils . getString ( 30123 ) , line1 = utils . getString ( 30128 ) ) ) :
2019-11-25 22:19:57 +01:00
# remove folder
2019-08-26 22:40:15 +02:00
del backupSet [ ' dirs ' ] [ optionSelected - 3 ]
elif ( contextOption == 1 and backupSet [ ' dirs ' ] [ optionSelected - 3 ] [ ' type ' ] == ' include ' ) :
2019-11-25 22:19:57 +01:00
# toggle if this folder should be recursive
2019-08-26 22:40:15 +02:00
backupSet [ ' dirs ' ] [ optionSelected - 3 ] [ ' recurse ' ] = not backupSet [ ' dirs ' ] [ optionSelected - 3 ] [ ' recurse ' ]
return backupSet
def showMainScreen ( self ) :
exitCondition = " "
customPaths = BackupSetManager ( )
2019-11-25 22:19:57 +01:00
# show this every time
2019-11-25 22:45:41 +01:00
self . dialog . ok ( utils . getString ( 30036 ) , utils . getString ( 30037 ) )
2019-11-26 17:43:38 +01:00
2019-08-26 22:40:15 +02:00
while ( exitCondition != - 1 ) :
2019-11-25 22:19:57 +01:00
# load the custom paths
2019-11-26 18:31:40 +01:00
listItem = xbmcgui . ListItem ( utils . getString ( 30126 ) , ' ' )
2019-12-04 18:38:25 +01:00
listItem . setArt ( { ' icon ' : os . path . join ( utils . addon_dir ( ) , ' resources ' , ' images ' , ' plus-icon.png ' ) } )
2019-11-26 18:31:40 +01:00
options = [ listItem ]
2019-11-25 22:33:34 +01:00
2019-11-25 22:45:41 +01:00
for index in range ( 0 , len ( customPaths . getSets ( ) ) ) :
2019-08-26 22:40:15 +02:00
aSet = customPaths . getSet ( index )
2019-11-26 18:31:40 +01:00
listItem = xbmcgui . ListItem ( aSet [ ' name ' ] , utils . getString ( 30121 ) + ' : ' + aSet [ ' set ' ] [ ' root ' ] )
2019-12-04 18:38:25 +01:00
listItem . setArt ( { ' icon ' : os . path . join ( utils . addon_dir ( ) , ' resources ' , ' images ' , ' folder-icon.png ' ) } )
2019-11-26 18:31:40 +01:00
options . append ( listItem )
2019-11-25 22:33:34 +01:00
2019-11-25 22:19:57 +01:00
# show the gui
2019-11-25 22:45:41 +01:00
exitCondition = self . dialog . select ( utils . getString ( 30125 ) , options , useDetails = True )
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
if ( exitCondition > = 0 ) :
if ( exitCondition == 0 ) :
newSet = self . createSet ( )
2019-11-25 22:19:57 +01:00
# check that the name is unique
2019-08-26 22:40:15 +02:00
if ( customPaths . validateSetName ( newSet [ ' name ' ] ) ) :
customPaths . addSet ( newSet )
else :
2019-11-25 22:45:41 +01:00
self . dialog . ok ( utils . getString ( 30117 ) , utils . getString ( 30138 ) , newSet [ ' name ' ] )
2019-08-26 22:40:15 +02:00
else :
2019-11-25 22:19:57 +01:00
# bring up a context menu
2019-11-25 22:45:41 +01:00
menuOption = self . dialog . contextmenu ( [ utils . getString ( 30122 ) , utils . getString ( 30123 ) ] )
2019-08-26 22:40:15 +02:00
if ( menuOption == 0 ) :
2019-11-25 22:19:57 +01:00
# get the set
2019-11-26 17:43:38 +01:00
aSet = customPaths . getSet ( exitCondition - 1 )
2019-11-25 22:33:34 +01:00
2019-11-25 22:19:57 +01:00
# edit the set
2019-11-25 22:45:41 +01:00
updatedSet = self . editSet ( aSet [ ' name ' ] , aSet [ ' set ' ] )
2019-08-26 22:40:15 +02:00
2019-11-25 22:19:57 +01:00
# save it
2019-11-25 22:45:41 +01:00
customPaths . updateSet ( aSet [ ' name ' ] , updatedSet )
2019-11-25 22:33:34 +01:00
2019-08-26 22:40:15 +02:00
elif ( menuOption == 1 ) :
2019-11-25 22:45:41 +01:00
if ( self . dialog . yesno ( heading = utils . getString ( 30127 ) , line1 = utils . getString ( 30128 ) ) ) :
2019-11-25 22:19:57 +01:00
# delete this path - subtract one because of "add" item
2019-11-26 17:43:38 +01:00
customPaths . deleteSet ( exitCondition - 1 )
2019-08-26 22:40:15 +02:00
def copySimpleConfig ( self ) :
2019-11-25 22:19:57 +01:00
# disclaimer in case the user hit this on accident
2019-11-25 22:45:41 +01:00
shouldContinue = self . dialog . yesno ( utils . getString ( 30139 ) , utils . getString ( 30140 ) , utils . getString ( 30141 ) )
2019-08-26 22:40:15 +02:00
if ( shouldContinue ) :
2019-12-04 18:38:25 +01:00
source = xbmc . translatePath ( os . path . join ( utils . addon_dir ( ) , ' resources ' , ' data ' , ' default_files.json ' ) )
dest = xbmc . translatePath ( os . path . join ( utils . data_dir ( ) , ' custom_paths.json ' ) )
2019-08-26 22:40:15 +02:00
2019-11-25 22:45:41 +01:00
xbmcvfs . copy ( source , dest )