Add backup option

This commit is contained in:
angelblue05 2018-09-18 02:49:08 -05:00
parent 605472f983
commit a7ba5aeba5
4 changed files with 127 additions and 11 deletions

View file

@ -518,6 +518,18 @@ msgctxt "#33088"
msgid "Database reset has completed, Kodi will now restart to apply the changes." msgid "Database reset has completed, Kodi will now restart to apply the changes."
msgstr "" msgstr ""
msgctxt "#33089"
msgid "Enter folder name for backup"
msgstr ""
msgctxt "#33090"
msgid "Replace existing backup?"
msgstr ""
msgctxt "#33091"
msgid "Created backup at:"
msgstr ""
msgctxt "#33092" msgctxt "#33092"
msgid "Create a backup" msgid "Create a backup"
msgstr "" msgstr ""
@ -797,3 +809,7 @@ msgstr ""
msgctxt "#33164" msgctxt "#33164"
msgid "Mask sensitive information in log (does not apply to kodi logging)" msgid "Mask sensitive information in log (does not apply to kodi logging)"
msgstr "" msgstr ""
msgctxt "#33165"
msgid "Failed to create backup"
msgstr ""

View file

@ -159,6 +159,7 @@ def reset():
if xbmcvfs.exists(os.path.join(addon_data, "sync.json")): if xbmcvfs.exists(os.path.join(addon_data, "sync.json")):
xbmcvfs.delete(os.path.join(addon_data, "sync.json")) xbmcvfs.delete(os.path.join(addon_data, "sync.json"))
settings('enableMusic.bool', False)
settings('MinimumSetup.bool', False) settings('MinimumSetup.bool', False)
settings('MusicRescan.bool', False) settings('MusicRescan.bool', False)
settings('SyncInstallRunDone.bool', False) settings('SyncInstallRunDone.bool', False)

View file

@ -115,6 +115,8 @@ class Events(object):
event('UpdateServer') event('UpdateServer')
elif mode == 'thememedia': elif mode == 'thememedia':
get_themes() get_themes()
elif mode == 'backup':
backup()
else: else:
listing() listing()
@ -143,13 +145,13 @@ def listing():
context = [] context = []
if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id not in whitelist: if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id not in whitelist:
context.append((_(33123), "RunPlugin(plugin://plugin.video.emby?mode=synclib&id=%s)" % view_id)) context.append((_(33123), "RunPlugin(plugin://plugin.video.emby/?mode=synclib&id=%s)" % view_id))
if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id in whitelist: if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id in whitelist:
context.append((_(33136), "RunPlugin(plugin://plugin.video.emby?mode=synclib&id=%s)" % view_id)) context.append((_(33136), "RunPlugin(plugin://plugin.video.emby/?mode=synclib&id=%s)" % view_id))
context.append((_(33132), "RunPlugin(plugin://plugin.video.emby?mode=repairlib&id=%s)" % view_id)) context.append((_(33132), "RunPlugin(plugin://plugin.video.emby/?mode=repairlib&id=%s)" % view_id))
context.append((_(33133), "RunPlugin(plugin://plugin.video.emby?mode=removelib&id=%s)" % view_id)) context.append((_(33133), "RunPlugin(plugin://plugin.video.emby/?mode=removelib&id=%s)" % view_id))
LOG.debug("--[ listing/%s/%s ] %s", node, label, path) LOG.debug("--[ listing/%s/%s ] %s", node, label, path)
@ -184,6 +186,10 @@ def listing():
directory(_(33140), "plugin://plugin.video.emby/?mode=repairlibs", False) directory(_(33140), "plugin://plugin.video.emby/?mode=repairlibs", False)
directory(_(33060), "plugin://plugin.video.emby/?mode=thememedia", False) directory(_(33060), "plugin://plugin.video.emby/?mode=thememedia", False)
directory(_(33058), "plugin://plugin.video.emby/?mode=reset", False) directory(_(33058), "plugin://plugin.video.emby/?mode=reset", False)
if settings('backupPath'):
directory(_(33092), "plugin://plugin.video.emby/?mode=backup", False)
directory(_(33163), None, False, artwork="special://home/addons/plugin.video.emby/donations.png") directory(_(33163), None, False, artwork="special://home/addons/plugin.video.emby/donations.png")
xbmcplugin.setContent(int(sys.argv[1]), 'files') xbmcplugin.setContent(int(sys.argv[1]), 'files')
@ -275,12 +281,12 @@ def browse(media, view_id=None, folder=None, server_id=None):
context = [] context = []
if item['Type'] in ('Series', 'Season', 'Playlist'): if item['Type'] in ('Series', 'Season', 'Playlist'):
context.append(("Play", "RunPlugin(plugin://plugin.video.emby?mode=playlist&id=%s&server=%s)" % (item['Id'], server_id))) context.append(("Play", "RunPlugin(plugin://plugin.video.emby/?mode=playlist&id=%s&server=%s)" % (item['Id'], server_id)))
if item['UserData']['Played']: if item['UserData']['Played']:
context.append((_(16104), "RunPlugin(plugin://plugin.video.emby?mode=unwatched&id=%s&server=%s)" % (item['Id'], server_id))) context.append((_(16104), "RunPlugin(plugin://plugin.video.emby/?mode=unwatched&id=%s&server=%s)" % (item['Id'], server_id)))
else: else:
context.append((_(16103), "RunPlugin(plugin://plugin.video.emby?mode=watched&id=%s&server=%s)" % (item['Id'], server_id))) context.append((_(16103), "RunPlugin(plugin://plugin.video.emby/?mode=watched&id=%s&server=%s)" % (item['Id'], server_id)))
li.addContextMenuItems(context) li.addContextMenuItems(context)
list_li.append((path, li, True)) list_li.append((path, li, True))
@ -293,12 +299,12 @@ def browse(media, view_id=None, folder=None, server_id=None):
} }
path = "%s?%s" % ("plugin://plugin.video.emby", urllib.urlencode(params)) path = "%s?%s" % ("plugin://plugin.video.emby", urllib.urlencode(params))
li.setProperty('path', path) li.setProperty('path', path)
context = [(_(13412), "RunPlugin(plugin://plugin.video.emby?mode=playlist&id=%s&server=%s)" % (item['Id'], server_id))] context = [(_(13412), "RunPlugin(plugin://plugin.video.emby/?mode=playlist&id=%s&server=%s)" % (item['Id'], server_id))]
if item['UserData']['Played']: if item['UserData']['Played']:
context.append((_(16104), "RunPlugin(plugin://plugin.video.emby?mode=unwatched&id=%s&server=%s)" % (item['Id'], server_id))) context.append((_(16104), "RunPlugin(plugin://plugin.video.emby/?mode=unwatched&id=%s&server=%s)" % (item['Id'], server_id)))
else: else:
context.append((_(16103), "RunPlugin(plugin://plugin.video.emby?mode=watched&id=%s&server=%s)" % (item['Id'], server_id))) context.append((_(16103), "RunPlugin(plugin://plugin.video.emby/?mode=watched&id=%s&server=%s)" % (item['Id'], server_id)))
li.addContextMenuItems(context) li.addContextMenuItems(context)
@ -688,3 +694,59 @@ def delete_item():
import context import context
context.Context(delete=True) context.Context(delete=True)
def backup():
''' Emby backup.
'''
from helper.utils import delete_folder, copytree
path = settings('backupPath')
folder_name = "Kodi%s.%s" % (xbmc.getInfoLabel('System.BuildVersion')[:2], xbmc.getInfoLabel('System.Date(dd-mm-yy)'))
folder_name = dialog("input", heading=_(33089), defaultt=folder_name)
if not folder_name:
return
backup = os.path.join(path, folder_name)
if xbmcvfs.exists(backup + '/'):
if not dialog("yesno", heading="{emby}", line1=_(33090)):
return backup()
delete_folder(backup)
addon_data = xbmc.translatePath("special://profile/addon_data/plugin.video.emby").decode('utf-8')
destination_data = os.path.join(backup, "addon_data", "plugin.video.emby")
destination_databases = os.path.join(backup, "Database")
if not xbmcvfs.mkdirs(path) or not xbmcvfs.mkdirs(destination_databases):
LOG.info("Unable to create all directories")
dialog("notification", heading="{emby}", icon="{emby}", message=_(33165), sound=False)
return
copytree(addon_data, destination_data)
databases = Objects().objects
db = xbmc.translatePath(databases['emby']).decode('utf-8')
xbmcvfs.copy(db, os.path.join(destination_databases, db.rsplit('\\', 1)[1]))
LOG.info("copied emby.db")
db = xbmc.translatePath(databases['video']).decode('utf-8')
filename = db.rsplit('\\', 1)[1]
xbmcvfs.copy(db, os.path.join(destination_databases, filename))
LOG.info("copied %s", filename)
if settings('enableMusic.bool'):
db = xbmc.translatePath(databases['music']).decode('utf-8')
filename = db.rsplit('\\', 1)[1]
xbmcvfs.copy(db, os.path.join(destination_databases, filename))
LOG.info("copied %s", filename)
LOG.info("backup completed")
dialog("ok", heading="{emby}", line1="%s %s" % (_(33091), backup))

View file

@ -289,7 +289,7 @@ def delete_recursive(path, dirs):
def unzip(path, dest, folder=None): def unzip(path, dest, folder=None):
''' Unzip file. zipfile module seems to fail on android. ''' Unzip file. zipfile module seems to fail on android with badziperror.
''' '''
path = urllib.quote_plus(path) path = urllib.quote_plus(path)
root = "zip://" + path + '/' root = "zip://" + path + '/'
@ -345,6 +345,43 @@ def get_zip_directory(path, folder):
if result: if result:
return result return result
def copytree(path, dest):
''' Copy folder content from one to another.
'''
dirs, files = xbmcvfs.listdir(path)
if dirs:
copy_recursive(path, dirs, dest)
for file in files:
copy_file(os.path.join(path, file.decode('utf-8')), os.path.join(dest, file.decode('utf-8')))
LOG.info("Copied %s", path)
def copy_recursive(path, dirs, dest):
for directory in dirs:
dirs_dir = os.path.join(path, directory.decode('utf-8'))
dest_dir = os.path.join(dest, directory.decode('utf-8'))
xbmcvfs.mkdir(dest_dir)
dirs2, files = xbmcvfs.listdir(dirs_dir)
if dirs2:
copy_recursive(dirs_dir, dirs2, dest_dir)
for file in files:
copy_file(os.path.join(dirs_dir, file.decode('utf-8')), os.path.join(dest_dir, file.decode('utf-8')))
def copy_file(path, dest):
''' Copy specific file.
'''
xbmcvfs.copy(path, dest)
LOG.debug("copy: %s to %s", path, dest)
def normalize_string(text): def normalize_string(text):
''' For theme media, do not modify unless ''' For theme media, do not modify unless