mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-25 10:16:11 +00:00
Add backup option
This commit is contained in:
parent
605472f983
commit
a7ba5aeba5
4 changed files with 127 additions and 11 deletions
|
@ -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 ""
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue