mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-05-11 03:45:07 +00:00
Change most string occurrences of Emby to Jellyfin (case sensitive)
This commit is contained in:
parent
168bab2b01
commit
59c1dd42e3
79 changed files with 833 additions and 832 deletions
|
@ -15,7 +15,7 @@ from helper.utils import create_id
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -71,13 +71,13 @@ def get_device_name():
|
|||
def get_device_id(reset=False):
|
||||
|
||||
''' Return the device_id if already loaded.
|
||||
It will load from emby_guid file. If it's a fresh
|
||||
It will load from jellyfin_guid file. If it's a fresh
|
||||
setup, it will generate a new GUID to uniquely
|
||||
identify the setup for all users.
|
||||
|
||||
window prop: emby_deviceId
|
||||
window prop: jellyfin_deviceId
|
||||
'''
|
||||
client_id = window('emby_deviceId')
|
||||
client_id = window('jellyfin_deviceId')
|
||||
|
||||
if client_id:
|
||||
return client_id
|
||||
|
@ -87,29 +87,29 @@ def get_device_id(reset=False):
|
|||
if not xbmcvfs.exists(directory):
|
||||
xbmcvfs.mkdir(directory)
|
||||
|
||||
emby_guid = os.path.join(directory, "emby_guid")
|
||||
file_guid = xbmcvfs.File(emby_guid)
|
||||
jellyfin_guid = os.path.join(directory, "jellyfin_guid")
|
||||
file_guid = xbmcvfs.File(jellyfin_guid)
|
||||
client_id = file_guid.read()
|
||||
|
||||
if not client_id or reset:
|
||||
LOG.info("Generating a new GUID.")
|
||||
|
||||
client_id = str("%012X" % create_id())
|
||||
file_guid = xbmcvfs.File(emby_guid, 'w')
|
||||
file_guid = xbmcvfs.File(jellyfin_guid, 'w')
|
||||
file_guid.write(client_id)
|
||||
|
||||
file_guid.close()
|
||||
|
||||
LOG.info("DeviceId loaded: %s", client_id)
|
||||
window('emby_deviceId', value=client_id)
|
||||
window('jellyfin_deviceId', value=client_id)
|
||||
|
||||
return client_id
|
||||
|
||||
def reset_device_id():
|
||||
|
||||
window('emby_deviceId', clear=True)
|
||||
window('jellyfin_deviceId', clear=True)
|
||||
get_device_id(True)
|
||||
dialog("ok", heading="{emby}", line1=_(33033))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33033))
|
||||
xbmc.executebuiltin('RestartApp')
|
||||
|
||||
def get_info():
|
||||
|
|
|
@ -20,7 +20,7 @@ from emby.core.exceptions import HTTPException
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
XML_PATH = (xbmcaddon.Addon(addon_id()).getAddonInfo('path'), "default", "1080i")
|
||||
|
||||
##################################################################################################
|
||||
|
@ -78,11 +78,11 @@ class Connect(object):
|
|||
|
||||
def get_client(self, server_id=None):
|
||||
|
||||
''' Get Emby client.
|
||||
''' Get Jellyfin client.
|
||||
'''
|
||||
client = Emby(server_id)
|
||||
client['config/app']("Kodi", self.info['Version'], self.info['DeviceName'], self.info['DeviceId'])
|
||||
client['config']['http.user_agent'] = "Emby-Kodi/%s" % self.info['Version']
|
||||
client['config']['http.user_agent'] = "Jellyfin-Kodi/%s" % self.info['Version']
|
||||
client['config']['auth.ssl'] = self.get_ssl()
|
||||
|
||||
return client
|
||||
|
@ -152,20 +152,20 @@ class Connect(object):
|
|||
settings('username', self.user['Name'])
|
||||
|
||||
if 'PrimaryImageTag' in self.user:
|
||||
window('EmbyUserImage', api.API(self.user, client['auth/server-address']).get_user_artwork(self.user['Id']))
|
||||
window('JellyfinUserImage', api.API(self.user, client['auth/server-address']).get_user_artwork(self.user['Id']))
|
||||
|
||||
def select_servers(self, state=None):
|
||||
|
||||
state = state or self.connect_manager.connect({'enableAutoLogin': False})
|
||||
user = state.get('ConnectUser') or {}
|
||||
|
||||
dialog = ServerConnect("script-emby-connect-server.xml", *XML_PATH)
|
||||
dialog = ServerConnect("script-jellyfin-connect-server.xml", *XML_PATH)
|
||||
dialog.set_args(**{
|
||||
'connect_manager': self.connect_manager,
|
||||
'username': user.get('DisplayName', ""),
|
||||
'user_image': user.get('ImageUrl'),
|
||||
'servers': state.get('Servers', []),
|
||||
'emby_connect': False if user else True
|
||||
'jellyfin_connect': False if user else True
|
||||
})
|
||||
dialog.doModal()
|
||||
|
||||
|
@ -174,7 +174,7 @@ class Connect(object):
|
|||
return
|
||||
|
||||
elif dialog.is_connect_login():
|
||||
LOG.debug("Login with emby connect")
|
||||
LOG.debug("Login with jellyfin connect")
|
||||
try:
|
||||
self.login_connect()
|
||||
except RuntimeError: pass
|
||||
|
@ -209,7 +209,7 @@ class Connect(object):
|
|||
|
||||
''' Return server or raise error.
|
||||
'''
|
||||
dialog = ServerManual("script-emby-connect-server-manual.xml", *XML_PATH)
|
||||
dialog = ServerManual("script-jellyfin-connect-server-manual.xml", *XML_PATH)
|
||||
dialog.set_args(**{'connect_manager': manager or self.connect_manager})
|
||||
dialog.doModal()
|
||||
|
||||
|
@ -220,7 +220,7 @@ class Connect(object):
|
|||
|
||||
def setup_login_connect(self):
|
||||
|
||||
''' Setup emby connect by itself.
|
||||
''' Setup jellyfin connect by itself.
|
||||
'''
|
||||
client = self.get_client()
|
||||
client.set_credentials(get_credentials())
|
||||
|
@ -238,7 +238,7 @@ class Connect(object):
|
|||
|
||||
''' Return connect user or raise error.
|
||||
'''
|
||||
dialog = LoginConnect("script-emby-connect-login.xml", *XML_PATH)
|
||||
dialog = LoginConnect("script-jellyfin-connect-login.xml", *XML_PATH)
|
||||
dialog.set_args(**{'connect_manager': manager or self.connect_manager})
|
||||
dialog.doModal()
|
||||
|
||||
|
@ -258,7 +258,7 @@ class Connect(object):
|
|||
except RuntimeError:
|
||||
raise RuntimeError("No user selected")
|
||||
|
||||
dialog = UsersConnect("script-emby-connect-users.xml", *XML_PATH)
|
||||
dialog = UsersConnect("script-jellyfin-connect-users.xml", *XML_PATH)
|
||||
dialog.set_args(**{'server': server, 'users': users})
|
||||
dialog.doModal()
|
||||
|
||||
|
@ -303,7 +303,7 @@ class Connect(object):
|
|||
|
||||
''' Return manual login user authenticated or raise error.
|
||||
'''
|
||||
dialog = LoginManual("script-emby-connect-login-manual.xml", *XML_PATH)
|
||||
dialog = LoginManual("script-jellyfin-connect-login-manual.xml", *XML_PATH)
|
||||
dialog.set_args(**{'connect_manager': manager or self.connect_manager, 'username': user or {}})
|
||||
dialog.doModal()
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ from objects import obj
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -26,7 +26,7 @@ LOG = logging.getLogger("EMBY."+__name__)
|
|||
class Database(object):
|
||||
|
||||
''' This should be called like a context.
|
||||
i.e. with Database('emby') as db:
|
||||
i.e. with Database('jellyfin') as db:
|
||||
db.cursor
|
||||
db.conn.commit()
|
||||
'''
|
||||
|
@ -36,7 +36,7 @@ class Database(object):
|
|||
|
||||
def __init__(self, file=None, commit_close=True):
|
||||
|
||||
''' file: emby, texture, music, video, :memory: or path to file
|
||||
''' file: jellyfin, texture, music, video, :memory: or path to file
|
||||
'''
|
||||
self.db_file = file or "video"
|
||||
self.commit_close = commit_close
|
||||
|
@ -50,14 +50,14 @@ class Database(object):
|
|||
self.conn = sqlite3.connect(self.path, timeout=self.timeout)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
if self.db_file in ('video', 'music', 'texture', 'emby'):
|
||||
if self.db_file in ('video', 'music', 'texture', 'jellyfin'):
|
||||
self.conn.execute("PRAGMA journal_mode=WAL") # to avoid writing conflict with kodi
|
||||
|
||||
LOG.debug("--->[ database: %s ] %s", self.db_file, id(self.conn))
|
||||
|
||||
if not window('emby_db_check.bool') and self.db_file == 'emby':
|
||||
if not window('jellyfin_db_check.bool') and self.db_file == 'jellyfin':
|
||||
|
||||
window('emby_db_check.bool', True)
|
||||
window('jellyfin_db_check.bool', True)
|
||||
emby_tables(self.cursor)
|
||||
self.conn.commit()
|
||||
|
||||
|
@ -185,45 +185,45 @@ class Database(object):
|
|||
|
||||
def emby_tables(cursor):
|
||||
|
||||
''' Create the tables for the emby database.
|
||||
emby, view, version
|
||||
''' Create the tables for the jellyfin database.
|
||||
jellyfin, view, version
|
||||
'''
|
||||
cursor.execute(
|
||||
"""CREATE TABLE IF NOT EXISTS emby(
|
||||
emby_id TEXT UNIQUE, media_folder TEXT, emby_type TEXT, media_type TEXT,
|
||||
"""CREATE TABLE IF NOT EXISTS jellyfin(
|
||||
jellyfin_id TEXT UNIQUE, media_folder TEXT, jellyfin_type TEXT, media_type TEXT,
|
||||
kodi_id INTEGER, kodi_fileid INTEGER, kodi_pathid INTEGER, parent_id INTEGER,
|
||||
checksum INTEGER, emby_parent_id TEXT)""")
|
||||
checksum INTEGER, jellyfin_parent_id TEXT)""")
|
||||
cursor.execute(
|
||||
"""CREATE TABLE IF NOT EXISTS view(
|
||||
view_id TEXT UNIQUE, view_name TEXT, media_type TEXT)""")
|
||||
cursor.execute("CREATE TABLE IF NOT EXISTS version(idVersion TEXT)")
|
||||
|
||||
columns = cursor.execute("SELECT * FROM emby")
|
||||
if 'emby_parent_id' not in [description[0] for description in columns.description]:
|
||||
columns = cursor.execute("SELECT * FROM jellyfin")
|
||||
if 'jellyfin_parent_id' not in [description[0] for description in columns.description]:
|
||||
|
||||
LOG.info("Add missing column emby_parent_id")
|
||||
cursor.execute("ALTER TABLE emby ADD COLUMN emby_parent_id 'TEXT'")
|
||||
LOG.info("Add missing column jellyfin_parent_id")
|
||||
cursor.execute("ALTER TABLE jellyfin ADD COLUMN jellyfin_parent_id 'TEXT'")
|
||||
|
||||
def reset():
|
||||
|
||||
''' Reset both the emby database and the kodi database.
|
||||
''' Reset both the jellyfin database and the kodi database.
|
||||
'''
|
||||
from views import Views
|
||||
views = Views()
|
||||
|
||||
if not dialog("yesno", heading="{emby}", line1=_(33074)):
|
||||
if not dialog("yesno", heading="{jellyfin}", line1=_(33074)):
|
||||
return
|
||||
|
||||
window('emby_should_stop.bool', True)
|
||||
window('jellyfin_should_stop.bool', True)
|
||||
count = 10
|
||||
|
||||
while window('emby_sync.bool'):
|
||||
while window('jellyfin_sync.bool'):
|
||||
|
||||
LOG.info("Sync is running...")
|
||||
count -= 1
|
||||
|
||||
if not count:
|
||||
dialog("ok", heading="{emby}", line1=_(33085))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33085))
|
||||
|
||||
return
|
||||
|
||||
|
@ -235,12 +235,12 @@ def reset():
|
|||
views.delete_playlists()
|
||||
views.delete_nodes()
|
||||
|
||||
if dialog("yesno", heading="{emby}", line1=_(33086)):
|
||||
if dialog("yesno", heading="{jellyfin}", line1=_(33086)):
|
||||
reset_artwork()
|
||||
|
||||
addon_data = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8')
|
||||
|
||||
if dialog("yesno", heading="{emby}", line1=_(33087)):
|
||||
if dialog("yesno", heading="{jellyfin}", line1=_(33087)):
|
||||
|
||||
xbmcvfs.delete(os.path.join(addon_data, "settings.xml"))
|
||||
xbmcvfs.delete(os.path.join(addon_data, "data.json"))
|
||||
|
@ -253,7 +253,7 @@ def reset():
|
|||
settings('MinimumSetup', "")
|
||||
settings('MusicRescan.bool', False)
|
||||
settings('SyncInstallRunDone.bool', False)
|
||||
dialog("ok", heading="{emby}", line1=_(33088))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33088))
|
||||
xbmc.executebuiltin('RestartApp')
|
||||
|
||||
def reset_kodi():
|
||||
|
@ -267,7 +267,7 @@ def reset_kodi():
|
|||
if name != 'version':
|
||||
videodb.cursor.execute("DELETE FROM " + name)
|
||||
|
||||
if settings('enableMusic.bool') or dialog("yesno", heading="{emby}", line1=_(33162)):
|
||||
if settings('enableMusic.bool') or dialog("yesno", heading="{jellyfin}", line1=_(33162)):
|
||||
|
||||
with Database('music') as musicdb:
|
||||
musicdb.cursor.execute("SELECT tbl_name FROM sqlite_master WHERE type='table'")
|
||||
|
@ -282,7 +282,7 @@ def reset_kodi():
|
|||
|
||||
def reset_emby():
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
embydb.cursor.execute("SELECT tbl_name FROM sqlite_master WHERE type='table'")
|
||||
|
||||
for table in embydb.cursor.fetchall():
|
||||
|
@ -291,11 +291,11 @@ def reset_emby():
|
|||
if name not in ('version', 'view'):
|
||||
embydb.cursor.execute("DELETE FROM " + name)
|
||||
|
||||
embydb.cursor.execute("DROP table IF EXISTS emby")
|
||||
embydb.cursor.execute("DROP table IF EXISTS jellyfin")
|
||||
embydb.cursor.execute("DROP table IF EXISTS view")
|
||||
embydb.cursor.execute("DROP table IF EXISTS version")
|
||||
|
||||
LOG.warn("[ reset emby ]")
|
||||
LOG.warn("[ reset jellyfin ]")
|
||||
|
||||
def reset_artwork():
|
||||
|
||||
|
@ -382,7 +382,6 @@ def get_credentials():
|
|||
return credentials
|
||||
|
||||
def save_credentials(credentials):
|
||||
|
||||
credentials = credentials or {}
|
||||
path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8')
|
||||
|
||||
|
@ -394,13 +393,13 @@ def save_credentials(credentials):
|
|||
|
||||
def get_item(kodi_id, media):
|
||||
|
||||
''' Get emby item based on kodi id and media.
|
||||
''' Get jellyfin item based on kodi id and media.
|
||||
'''
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as jellyfindb:
|
||||
item = emby_db.EmbyDatabase(embydb.cursor).get_full_item_by_kodi_id(kodi_id, media)
|
||||
|
||||
if not item:
|
||||
LOG.debug("Not an emby item")
|
||||
LOG.debug("Not an jellyfin item")
|
||||
|
||||
return
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import queries as QU
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
get_item = """ SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id, media_type,
|
||||
emby_type, media_folder, emby_parent_id
|
||||
FROM emby
|
||||
WHERE emby_id = ?
|
||||
jellyfin_type, media_folder, jellyfin_parent_id
|
||||
FROM jellyfin
|
||||
WHERE jellyfin_id = ?
|
||||
"""
|
||||
get_item_obj = [ "{Id}"
|
||||
]
|
||||
|
@ -10,20 +10,20 @@ get_item_series_obj = [ "{SeriesId}"
|
|||
]
|
||||
get_item_song_obj = [ "{SongAlbumId}"
|
||||
]
|
||||
get_item_id_by_parent = """ SELECT emby_id, kodi_id
|
||||
FROM emby
|
||||
get_item_id_by_parent = """ SELECT jellyfin_id, kodi_id
|
||||
FROM jellyfin
|
||||
WHERE parent_id = ?
|
||||
AND media_type = ?
|
||||
"""
|
||||
get_item_id_by_parent_boxset_obj = [ "{SetId}","movie"
|
||||
]
|
||||
get_item_by_parent = """ SELECT emby_id, kodi_id, kodi_fileid
|
||||
FROM emby
|
||||
get_item_by_parent = """ SELECT jellyfin_id, kodi_id, kodi_fileid
|
||||
FROM jellyfin
|
||||
WHERE parent_id = ?
|
||||
AND media_type = ?
|
||||
"""
|
||||
get_item_by_media_folder = """ SELECT emby_id, emby_type
|
||||
FROM emby
|
||||
get_item_by_media_folder = """ SELECT jellyfin_id, jellyfin_type
|
||||
FROM jellyfin
|
||||
WHERE media_folder = ?
|
||||
"""
|
||||
get_item_by_parent_movie_obj = [ "{KodiId}","movie"
|
||||
|
@ -39,31 +39,31 @@ get_item_by_parent_album_obj = [ "{ParentId}","album"
|
|||
get_item_by_parent_song_obj = [ "{ParentId}","song"
|
||||
]
|
||||
get_item_by_wild = """ SELECT kodi_id, media_type
|
||||
FROM emby
|
||||
WHERE emby_id LIKE ?
|
||||
FROM jellyfin
|
||||
WHERE jellyfin_id LIKE ?
|
||||
"""
|
||||
get_item_by_wild_obj = [ "{Id}"
|
||||
]
|
||||
get_item_by_kodi = """ SELECT emby_id, parent_id, media_folder, emby_type, checksum
|
||||
FROM emby
|
||||
get_item_by_kodi = """ SELECT jellyfin_id, parent_id, media_folder, jellyfin_type, checksum
|
||||
FROM jellyfin
|
||||
WHERE kodi_id = ?
|
||||
AND media_type = ?
|
||||
"""
|
||||
get_checksum = """ SELECT emby_id, checksum
|
||||
FROM emby
|
||||
WHERE emby_type = ?
|
||||
get_checksum = """ SELECT jellyfin_id, checksum
|
||||
FROM jellyfin
|
||||
WHERE jellyfin_type = ?
|
||||
"""
|
||||
get_view_name = """ SELECT view_name
|
||||
FROM view
|
||||
WHERE view_id = ?
|
||||
"""
|
||||
get_media_by_id = """ SELECT emby_type
|
||||
FROM emby
|
||||
WHERE emby_id = ?
|
||||
get_media_by_id = """ SELECT jellyfin_type
|
||||
FROM jellyfin
|
||||
WHERE jellyfin_id = ?
|
||||
"""
|
||||
get_media_by_parent_id = """ SELECT emby_id, emby_type, kodi_id, kodi_fileid
|
||||
FROM emby
|
||||
WHERE emby_parent_id = ?
|
||||
get_media_by_parent_id = """ SELECT jellyfin_id, jellyfin_type, kodi_id, kodi_fileid
|
||||
FROM jellyfin
|
||||
WHERE jellyfin_parent_id = ?
|
||||
"""
|
||||
get_view = """ SELECT view_name, media_type
|
||||
FROM view
|
||||
|
@ -76,8 +76,8 @@ get_views_by_media = """ SELECT *
|
|||
FROM view
|
||||
WHERE media_type = ?
|
||||
"""
|
||||
get_items_by_media = """ SELECT emby_id
|
||||
FROM emby
|
||||
get_items_by_media = """ SELECT jellyfin_id
|
||||
FROM jellyfin
|
||||
WHERE media_type = ?
|
||||
"""
|
||||
get_version = """ SELECT idVersion
|
||||
|
@ -86,36 +86,36 @@ get_version = """ SELECT idVersion
|
|||
|
||||
|
||||
|
||||
add_reference = """ INSERT OR REPLACE INTO emby(emby_id, kodi_id, kodi_fileid, kodi_pathid, emby_type,
|
||||
media_type, parent_id, checksum, media_folder, emby_parent_id)
|
||||
add_reference = """ INSERT OR REPLACE INTO jellyfin(jellyfin_id, kodi_id, kodi_fileid, kodi_pathid, jellyfin_type,
|
||||
media_type, parent_id, checksum, media_folder, jellyfin_parent_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"""
|
||||
add_reference_movie_obj = [ "{Id}","{MovieId}","{FileId}","{PathId}","Movie","movie", None,"{Checksum}","{LibraryId}",
|
||||
"{EmbyParentId}"
|
||||
"{JellyfinParentId}"
|
||||
]
|
||||
add_reference_boxset_obj = [ "{Id}","{SetId}",None,None,"BoxSet","set",None,"{Checksum}",None,None
|
||||
]
|
||||
add_reference_tvshow_obj = [ "{Id}","{ShowId}",None,"{PathId}","Series","tvshow",None,"{Checksum}","{LibraryId}",
|
||||
"{EmbyParentId}"
|
||||
"{JellyfinParentId}"
|
||||
]
|
||||
add_reference_season_obj = [ "{Id}","{SeasonId}",None,None,"Season","season","{ShowId}",None,None,None
|
||||
]
|
||||
add_reference_pool_obj = [ "{SeriesId}","{ShowId}",None,"{PathId}","Series","tvshow",None,"{Checksum}","{LibraryId}",None
|
||||
]
|
||||
add_reference_episode_obj = [ "{Id}","{EpisodeId}","{FileId}","{PathId}","Episode","episode","{SeasonId}","{Checksum}",
|
||||
None,"{EmbyParentId}"
|
||||
None,"{JellyfinParentId}"
|
||||
]
|
||||
add_reference_mvideo_obj = [ "{Id}","{MvideoId}","{FileId}","{PathId}","MusicVideo","musicvideo",None,"{Checksum}",
|
||||
"{LibraryId}","{EmbyParentId}"
|
||||
"{LibraryId}","{JellyfinParentId}"
|
||||
]
|
||||
add_reference_artist_obj = [ "{Id}","{ArtistId}",None,None,"{ArtistType}","artist",None,"{Checksum}","{LibraryId}",
|
||||
"{EmbyParentId}"
|
||||
"{JellyfinParentId}"
|
||||
]
|
||||
add_reference_album_obj = [ "{Id}","{AlbumId}",None,None,"MusicAlbum","album",None,"{Checksum}",None,"{EmbyParentId}"
|
||||
add_reference_album_obj = [ "{Id}","{AlbumId}",None,None,"MusicAlbum","album",None,"{Checksum}",None,"{JellyfinParentId}"
|
||||
]
|
||||
add_reference_song_obj = [ "{Id}","{SongId}",None,"{PathId}","Audio","song","{AlbumId}","{Checksum}",
|
||||
None,"{EmbyParentId}"
|
||||
]
|
||||
None,"{JellyfinParentId}"
|
||||
]
|
||||
add_view = """ INSERT OR REPLACE INTO view(view_id, view_name, media_type)
|
||||
VALUES (?, ?, ?)
|
||||
"""
|
||||
|
@ -124,15 +124,15 @@ add_version = """ INSERT OR REPLACE INTO version(idVersion)
|
|||
"""
|
||||
|
||||
|
||||
update_reference = """ UPDATE emby
|
||||
update_reference = """ UPDATE jellyfin
|
||||
SET checksum = ?
|
||||
WHERE emby_id = ?
|
||||
WHERE jellyfin_id = ?
|
||||
"""
|
||||
update_reference_obj = [ "{Checksum}", "{Id}"
|
||||
]
|
||||
update_parent = """ UPDATE emby
|
||||
update_parent = """ UPDATE jellyfin
|
||||
SET parent_id = ?
|
||||
WHERE emby_id = ?
|
||||
WHERE jellyfin_id = ?
|
||||
"""
|
||||
update_parent_movie_obj = [ "{SetId}","{Id}"
|
||||
]
|
||||
|
@ -142,12 +142,12 @@ update_parent_album_obj = [ "{ArtistId}","{AlbumId}"]
|
|||
|
||||
|
||||
|
||||
delete_item = """ DELETE FROM emby
|
||||
WHERE emby_id = ?
|
||||
delete_item = """ DELETE FROM jellyfin
|
||||
WHERE jellyfin_id = ?
|
||||
"""
|
||||
delete_item_obj = [ "{Id}"
|
||||
]
|
||||
delete_item_by_parent = """ DELETE FROM emby
|
||||
delete_item_by_parent = """ DELETE FROM jellyfin
|
||||
WHERE parent_id = ?
|
||||
AND media_type = ?
|
||||
"""
|
||||
|
@ -163,20 +163,20 @@ delete_item_by_parent_artist_obj = [ "{ParentId}","artist"
|
|||
]
|
||||
delete_item_by_parent_album_obj = [ "{KodiId}","album"
|
||||
]
|
||||
delete_item_by_kodi = """ DELETE FROM emby
|
||||
delete_item_by_kodi = """ DELETE FROM jellyfin
|
||||
WHERE kodi_id = ?
|
||||
AND media_type = ?
|
||||
"""
|
||||
delete_item_by_wild = """ DELETE FROM emby
|
||||
WHERE emby_id LIKE ?
|
||||
delete_item_by_wild = """ DELETE FROM jellyfin
|
||||
WHERE jellyfin_id LIKE ?
|
||||
"""
|
||||
delete_view = """ DELETE FROM view
|
||||
WHERE view_id = ?
|
||||
"""
|
||||
delete_parent_boxset_obj = [ None, "{Movie}"
|
||||
]
|
||||
delete_media_by_parent_id = """ DELETE FROM emby
|
||||
WHERE emby_parent_id = ?
|
||||
delete_media_by_parent_id = """ DELETE FROM jellyfin
|
||||
WHERE jellyfin_parent_id = ?
|
||||
"""
|
||||
delete_version = """ DELETE FROM version
|
||||
"""
|
||||
|
|
|
@ -12,7 +12,7 @@ from helper import window, addon_id
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
ACTION_PARENT_DIR = 9
|
||||
ACTION_PREVIOUS_MENU = 10
|
||||
ACTION_BACK = 92
|
||||
|
@ -45,8 +45,8 @@ class ContextMenu(xbmcgui.WindowXMLDialog):
|
|||
|
||||
def onInit(self):
|
||||
|
||||
if window('EmbyUserImage'):
|
||||
self.getControl(USER_IMAGE).setImage(window('EmbyUserImage'))
|
||||
if window('JellyfinUserImage'):
|
||||
self.getControl(USER_IMAGE).setImage(window('JellyfinUserImage'))
|
||||
|
||||
height = 479 + (len(self._options) * 55)
|
||||
LOG.info("options: %s", self._options)
|
||||
|
|
|
@ -12,7 +12,7 @@ from helper import _, addon_id, settings, dialog
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
ACTION_PARENT_DIR = 9
|
||||
ACTION_PREVIOUS_MENU = 10
|
||||
ACTION_BACK = 92
|
||||
|
@ -39,7 +39,7 @@ class LoginConnect(xbmcgui.WindowXMLDialog):
|
|||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
|
||||
def set_args(self, **kwargs):
|
||||
# connect_manager, user_image, servers, emby_connect
|
||||
# connect_manager, user_image, servers, jellyfin_connect
|
||||
for key, value in kwargs.iteritems():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
@ -70,7 +70,7 @@ class LoginConnect(xbmcgui.WindowXMLDialog):
|
|||
def onClick(self, control):
|
||||
|
||||
if control == SIGN_IN:
|
||||
# Sign in to emby connect
|
||||
# Sign in to jellyfin connect
|
||||
self._disable_error()
|
||||
|
||||
user = self.user_field.getText()
|
||||
|
@ -128,8 +128,8 @@ class LoginConnect(xbmcgui.WindowXMLDialog):
|
|||
settings('connectUsername', value=username)
|
||||
settings('idMethod', value="1")
|
||||
|
||||
dialog("notification", heading="{emby}", message="%s %s" % (_(33000), username.decode('utf-8')),
|
||||
icon=result['User'].get('ImageUrl') or "{emby}",
|
||||
dialog("notification", heading="{jellyfin}", message="%s %s" % (_(33000), username.decode('utf-8')),
|
||||
icon=result['User'].get('ImageUrl') or "{jellyfin}",
|
||||
time=2000,
|
||||
sound=False)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ from helper import _, addon_id
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
ACTION_PARENT_DIR = 9
|
||||
ACTION_PREVIOUS_MENU = 10
|
||||
ACTION_BACK = 92
|
||||
|
|
|
@ -10,7 +10,7 @@ import xbmcaddon
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
ACTION_PARENT_DIR = 9
|
||||
ACTION_PREVIOUS_MENU = 10
|
||||
ACTION_BACK = 92
|
||||
|
|
|
@ -12,7 +12,7 @@ from emby.core.connection_manager import CONNECTION_STATE
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
ACTION_PARENT_DIR = 9
|
||||
ACTION_PREVIOUS_MENU = 10
|
||||
ACTION_BACK = 92
|
||||
|
@ -45,7 +45,7 @@ class ServerConnect(xbmcgui.WindowXMLDialog):
|
|||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
|
||||
def set_args(self, **kwargs):
|
||||
# connect_manager, user_image, servers, emby_connect
|
||||
# connect_manager, user_image, servers, jellyfin_connect
|
||||
for key, value in kwargs.iteritems():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
@ -76,7 +76,7 @@ class ServerConnect(xbmcgui.WindowXMLDialog):
|
|||
if self.user_image is not None:
|
||||
self.getControl(USER_IMAGE).setImage(self.user_image)
|
||||
|
||||
if not self.emby_connect: # Change connect user
|
||||
if not self.jellyfin_connect: # Change connect user
|
||||
self.getControl(EMBY_CONNECT).setLabel("[B]%s[/B]" % _(30618))
|
||||
|
||||
if self.servers:
|
||||
|
|
|
@ -13,7 +13,7 @@ from emby.core.connection_manager import CONNECTION_STATE
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
ACTION_PARENT_DIR = 9
|
||||
ACTION_PREVIOUS_MENU = 10
|
||||
ACTION_BACK = 92
|
||||
|
@ -40,7 +40,7 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
|||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
|
||||
def set_args(self, **kwargs):
|
||||
# connect_manager, user_image, servers, emby_connect
|
||||
# connect_manager, user_image, servers, jellyfin_connect
|
||||
for key, value in kwargs.iteritems():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
@ -72,7 +72,7 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
|||
def onClick(self, control):
|
||||
|
||||
if control == CONNECT:
|
||||
# Sign in to emby connect
|
||||
# Sign in to jellyfin connect
|
||||
self._disable_error()
|
||||
|
||||
server = self.host_field.getText()
|
||||
|
|
|
@ -9,7 +9,7 @@ import xbmcgui
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
ACTION_PARENT_DIR = 9
|
||||
ACTION_PREVIOUS_MENU = 10
|
||||
ACTION_BACK = 92
|
||||
|
@ -34,7 +34,7 @@ class UsersConnect(xbmcgui.WindowXMLDialog):
|
|||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
|
||||
def set_args(self, **kwargs):
|
||||
# connect_manager, user_image, servers, emby_connect
|
||||
# connect_manager, user_image, servers, jellyfin_connect
|
||||
for key, value in kwargs.iteritems():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ from emby.core.exceptions import HTTPException
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
LIMIT = min(int(settings('limitIndex') or 50), 50)
|
||||
CACHE = xbmc.translatePath(os.path.join(xbmcaddon.Addon(id='plugin.video.jellyfin').getAddonInfo('profile').decode('utf-8'), 'emby')).decode('utf-8')
|
||||
CACHE = xbmc.translatePath(os.path.join(xbmcaddon.Addon(id='plugin.video.jellyfin').getAddonInfo('profile').decode('utf-8'), 'jellyfin')).decode('utf-8')
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -317,7 +317,7 @@ class GetItemWorker(threading.Thread):
|
|||
|
||||
self.queue.task_done()
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
break
|
||||
|
||||
class TheVoid(object):
|
||||
|
@ -342,16 +342,16 @@ class TheVoid(object):
|
|||
|
||||
while True:
|
||||
|
||||
response = window('emby_%s.json' % self.data['VoidName'])
|
||||
response = window('jellyfin_%s.json' % self.data['VoidName'])
|
||||
|
||||
if response != "":
|
||||
|
||||
LOG.debug("--<[ nostromo/emby_%s.json ]", self.data['VoidName'])
|
||||
window('emby_%s' % self.data['VoidName'], clear=True)
|
||||
LOG.debug("--<[ nostromo/jellyfin_%s.json ]", self.data['VoidName'])
|
||||
window('jellyfin_%s' % self.data['VoidName'], clear=True)
|
||||
|
||||
return response
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
LOG.info("Abandon mission! A black hole just swallowed [ %s/%s ]", self.method, self.data['VoidName'])
|
||||
|
||||
return
|
||||
|
|
|
@ -14,13 +14,13 @@ class NullHandler(logging.Handler):
|
|||
print(self.format(record))
|
||||
|
||||
loghandler = NullHandler
|
||||
LOG = logging.getLogger('Emby')
|
||||
LOG = logging.getLogger('Jellyfin')
|
||||
|
||||
#################################################################################################
|
||||
|
||||
def config(level=logging.INFO):
|
||||
|
||||
logger = logging.getLogger('Emby')
|
||||
logger = logging.getLogger('Jellyfin')
|
||||
logger.addHandler(Emby.loghandler())
|
||||
logger.setLevel(level)
|
||||
|
||||
|
@ -40,15 +40,15 @@ def ensure_client():
|
|||
|
||||
class Emby(object):
|
||||
|
||||
''' This is your Embyclient, you can create more than one. The server_id is only a temporary thing
|
||||
to communicate with the EmbyClient().
|
||||
''' This is your Jellyfinclient, you can create more than one. The server_id is only a temporary thing
|
||||
to communicate with the JellyfinClient().
|
||||
|
||||
from emby import Emby
|
||||
from jellyfin import Jellyfin
|
||||
|
||||
Emby('123456')['config/app']
|
||||
Jellyfin('123456')['config/app']
|
||||
|
||||
# Permanent client reference
|
||||
client = Emby('123456').get_client()
|
||||
client = Jellyfin('123456').get_client()
|
||||
client['config/app']
|
||||
'''
|
||||
|
||||
|
@ -68,9 +68,9 @@ class Emby(object):
|
|||
@classmethod
|
||||
def set_loghandler(cls, func=loghandler, level=logging.INFO):
|
||||
|
||||
for handler in logging.getLogger('Emby').handlers:
|
||||
for handler in logging.getLogger('Jellyfin').handlers:
|
||||
if isinstance(handler, cls.loghandler):
|
||||
logging.getLogger('Emby').removeHandler(handler)
|
||||
logging.getLogger('Jellyfin').removeHandler(handler)
|
||||
|
||||
cls.loghandler = func
|
||||
config(level)
|
||||
|
@ -83,7 +83,7 @@ class Emby(object):
|
|||
self.client[self.server_id].stop()
|
||||
self.client.pop(self.server_id, None)
|
||||
|
||||
LOG.info("---[ STOPPED EMBYCLIENT: %s ]---", self.server_id)
|
||||
LOG.info("---[ STOPPED JELLYFINCLIENT: %s ]---", self.server_id)
|
||||
|
||||
@classmethod
|
||||
def close_all(cls):
|
||||
|
@ -92,7 +92,7 @@ class Emby(object):
|
|||
cls.client[client].stop()
|
||||
|
||||
cls.client = {}
|
||||
LOG.info("---[ STOPPED ALL EMBYCLIENTS ]---")
|
||||
LOG.info("---[ STOPPED ALL JELLYFINCLIENT ]---")
|
||||
|
||||
@classmethod
|
||||
def get_active_clients(cls):
|
||||
|
@ -119,8 +119,8 @@ class Emby(object):
|
|||
self.client[self.server_id] = EmbyClient()
|
||||
|
||||
if self.server_id == 'default':
|
||||
LOG.info("---[ START EMBYCLIENT ]---")
|
||||
LOG.info("---[ START JELLYFINCLIENT ]---")
|
||||
else:
|
||||
LOG.info("---[ START EMBYCLIENT: %s ]---", self.server_id)
|
||||
LOG.info("---[ START JELLYFINCLIENT: %s ]---", self.server_id)
|
||||
|
||||
config()
|
|
@ -12,7 +12,7 @@ from core.connection_manager import ConnectionManager, CONNECTION_STATE
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger('Emby.'+__name__)
|
||||
LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -30,7 +30,7 @@ class EmbyClient(object):
|
|||
logged_in = False
|
||||
|
||||
def __init__(self):
|
||||
LOG.debug("EmbyClient initializing...")
|
||||
LOG.debug("JellyfinClient initializing...")
|
||||
|
||||
self.config = Config()
|
||||
self.http = HTTP(self)
|
||||
|
|
|
@ -50,7 +50,7 @@ class API(object):
|
|||
|
||||
#################################################################################################
|
||||
|
||||
# Bigger section of the Emby api
|
||||
# Bigger section of the Jellyfin api
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import logging
|
|||
|
||||
DEFAULT_HTTP_MAX_RETRIES = 3
|
||||
DEFAULT_HTTP_TIMEOUT = 30
|
||||
LOG = logging.getLogger('Emby.'+__name__)
|
||||
LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from http import HTTP
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger('Emby.'+__name__)
|
||||
LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||
CONNECTION_STATE = {
|
||||
'Unavailable': 0,
|
||||
'ServerSelection': 1,
|
||||
|
@ -516,7 +516,7 @@ class ConnectionManager(object):
|
|||
def _server_discovery(self):
|
||||
|
||||
MULTI_GROUP = ("<broadcast>", 7359)
|
||||
MESSAGE = "who is EmbyServer?"
|
||||
MESSAGE = "who is JellyfinServer?"
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.settimeout(1.0) # This controls the socket.timeout exception
|
||||
|
|
|
@ -10,7 +10,7 @@ from datetime import datetime
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger('Emby.'+__name__)
|
||||
LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#################################################################################################
|
||||
|
||||
class HTTPException(Exception):
|
||||
# Emby HTTP exception
|
||||
# Jellyfin HTTP exception
|
||||
def __init__(self, status, message):
|
||||
self.status = status
|
||||
self.message = message
|
||||
|
|
|
@ -11,7 +11,7 @@ from exceptions import HTTPException
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger('Emby.'+__name__)
|
||||
LOG = logging.getLogger('Jellyfin.'+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -69,7 +69,7 @@ class HTTP(object):
|
|||
|
||||
def request(self, data, session=None):
|
||||
|
||||
''' Give a chance to retry the connection. Emby sometimes can be slow to answer back
|
||||
''' Give a chance to retry the connection. Jellyfin sometimes can be slow to answer back
|
||||
data dictionary can contain:
|
||||
type: GET, POST, etc.
|
||||
url: (optional)
|
||||
|
|
|
@ -13,7 +13,7 @@ from ..resources import websocket
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger('Emby.'+__name__)
|
||||
LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ from uuid import uuid4
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger('Emby.'+__name__)
|
||||
LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ from emby import Emby
|
|||
Emby.set_loghandler(loghandler.LogHandler, logging.DEBUG)
|
||||
loghandler.reset()
|
||||
loghandler.config()
|
||||
LOG = logging.getLogger('EMBY.entrypoint')
|
||||
LOG = logging.getLogger('JELLYFIN.entrypoint')
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ from objects import Actions
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
XML_PATH = (xbmcaddon.Addon('plugin.video.jellyfin').getAddonInfo('path'), "default", "1080i")
|
||||
OPTIONS = {
|
||||
'Refresh': _(30410),
|
||||
|
@ -40,13 +40,13 @@ class Context(object):
|
|||
try:
|
||||
self.kodi_id = sys.listitem.getVideoInfoTag().getDbId() or None
|
||||
self.media = self.get_media_type()
|
||||
self.server = sys.listitem.getProperty('embyserver') or None
|
||||
item_id = sys.listitem.getProperty('embyid')
|
||||
self.server = sys.listitem.getProperty('jellyfinserver') or None
|
||||
item_id = sys.listitem.getProperty('jellyfinid')
|
||||
except AttributeError:
|
||||
self.server = None
|
||||
|
||||
if xbmc.getInfoLabel('ListItem.Property(embyid)'):
|
||||
item_id = xbmc.getInfoLabel('ListItem.Property(embyid)')
|
||||
if xbmc.getInfoLabel('ListItem.Property(jellyfinid)'):
|
||||
item_id = xbmc.getInfoLabel('ListItem.Property(jellyfinid)')
|
||||
else:
|
||||
self.kodi_id = xbmc.getInfoLabel('ListItem.DBID')
|
||||
self.media = xbmc.getInfoLabel('ListItem.DBTYPE')
|
||||
|
@ -96,7 +96,7 @@ class Context(object):
|
|||
|
||||
def get_item_id(self):
|
||||
|
||||
''' Get synced item from embydb.
|
||||
''' Get synced item from jellyfindb.
|
||||
'''
|
||||
item = database.get_item(self.kodi_id, self.media)
|
||||
|
||||
|
@ -130,7 +130,7 @@ class Context(object):
|
|||
|
||||
options.append(OPTIONS['Addon'])
|
||||
|
||||
context_menu = context.ContextMenu("script-emby-context.xml", *XML_PATH)
|
||||
context_menu = context.ContextMenu("script-jellyfin-context.xml", *XML_PATH)
|
||||
context_menu.set_options(options)
|
||||
context_menu.doModal()
|
||||
|
||||
|
@ -164,7 +164,7 @@ class Context(object):
|
|||
|
||||
if not settings('skipContextMenu.bool'):
|
||||
|
||||
if not dialog("yesno", heading="{emby}", line1=_(33015)):
|
||||
if not dialog("yesno", heading="{jellyfin}", line1=_(33015)):
|
||||
delete = False
|
||||
|
||||
if delete:
|
||||
|
|
|
@ -24,7 +24,7 @@ from helper import _, event, settings, window, dialog, api, JSONRPC
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -55,15 +55,15 @@ class Events(object):
|
|||
|
||||
if '/extrafanart' in base_url:
|
||||
|
||||
emby_path = path[1:]
|
||||
emby_id = params.get('id')
|
||||
get_fanart(emby_id, emby_path, server)
|
||||
jellyfin_path = path[1:]
|
||||
jellyfin_id = params.get('id')
|
||||
get_fanart(jellyfin_id, jellyfin_path, server)
|
||||
|
||||
elif '/Extras' in base_url or '/VideoFiles' in base_url:
|
||||
|
||||
emby_path = path[1:]
|
||||
emby_id = params.get('id')
|
||||
get_video_extras(emby_id, emby_path, server)
|
||||
jellyfin_path = path[1:]
|
||||
jellyfin_id = params.get('id')
|
||||
get_video_extras(jellyfin_id, jellyfin_path, server)
|
||||
|
||||
elif mode =='play':
|
||||
|
||||
|
@ -101,7 +101,7 @@ class Events(object):
|
|||
elif mode == 'addlibs':
|
||||
event('AddLibrarySelection')
|
||||
elif mode == 'connect':
|
||||
event('EmbyConnect')
|
||||
event('jellyfinConnect')
|
||||
elif mode == 'addserver':
|
||||
event('AddServer')
|
||||
elif mode == 'login':
|
||||
|
@ -123,14 +123,14 @@ class Events(object):
|
|||
elif mode == 'backup':
|
||||
backup()
|
||||
elif mode == 'restartservice':
|
||||
window('emby.restart.bool', True)
|
||||
window('jellyfin.restart.bool', True)
|
||||
else:
|
||||
listing()
|
||||
|
||||
|
||||
def listing():
|
||||
|
||||
''' Display all emby nodes and dynamic entries when appropriate.
|
||||
''' Display all jellyfin nodes and dynamic entries when appropriate.
|
||||
'''
|
||||
total = int(window('Emby.nodes.total') or 0)
|
||||
sync = get_sync()
|
||||
|
@ -240,12 +240,12 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
'''
|
||||
LOG.info("--[ v:%s/%s ] %s", view_id, media, folder)
|
||||
|
||||
if not window('emby_online.bool') and server_id is None:
|
||||
if not window('jellyfin_online.bool') and server_id is None:
|
||||
|
||||
monitor = xbmc.Monitor()
|
||||
|
||||
for i in range(300):
|
||||
if window('emby_online.bool'):
|
||||
if window('jellyfin_online.bool'):
|
||||
break
|
||||
elif monitor.waitForAbort(0.1):
|
||||
return
|
||||
|
@ -330,8 +330,8 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
for item in listing:
|
||||
|
||||
li = xbmcgui.ListItem()
|
||||
li.setProperty('embyid', item['Id'])
|
||||
li.setProperty('embyserver', server_id)
|
||||
li.setProperty('jellyfinid', item['Id'])
|
||||
li.setProperty('jellyfinserver', server_id)
|
||||
actions.set_listitem(item, li)
|
||||
|
||||
if item.get('IsFolder'):
|
||||
|
@ -402,7 +402,7 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
|
||||
def browse_subfolders(media, view_id, server_id=None):
|
||||
|
||||
''' Display submenus for emby views.
|
||||
''' Display submenus for jellyfin views.
|
||||
'''
|
||||
from views import DYNNODES
|
||||
|
||||
|
@ -498,7 +498,7 @@ def get_fanart(item_id, path, server_id=None):
|
|||
LOG.info("[ extra fanart ] %s", item_id)
|
||||
objects = Objects()
|
||||
list_li = []
|
||||
directory = xbmc.translatePath("special://thumbnails/emby/%s/" % item_id).decode('utf-8')
|
||||
directory = xbmc.translatePath("special://thumbnails/jellyfin/%s/" % item_id).decode('utf-8')
|
||||
server = TheVoid('GetServerAddress', {'ServerId': server_id}).get()
|
||||
|
||||
if not xbmcvfs.exists(directory):
|
||||
|
@ -543,7 +543,7 @@ def get_video_extras(item_id, path, server_id=None):
|
|||
# TODO
|
||||
|
||||
"""
|
||||
def getVideoFiles(embyId,embyPath):
|
||||
def getVideoFiles(jellyfinId,jellyfinPath):
|
||||
#returns the video files for the item as plugin listing, can be used for browsing the actual files or videoextras etc.
|
||||
emby = embyserver.Read_EmbyServer()
|
||||
if not embyId:
|
||||
|
@ -573,7 +573,7 @@ def get_next_episodes(item_id, limit):
|
|||
|
||||
''' Only for synced content.
|
||||
'''
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
db = emby_db.EmbyDatabase(embydb.cursor)
|
||||
library = db.get_view_name(item_id)
|
||||
|
@ -730,7 +730,7 @@ def add_user():
|
|||
|
||||
''' Add or remove users from the default server session.
|
||||
'''
|
||||
if not window('emby_online.bool'):
|
||||
if not window('jellyfin_online.bool'):
|
||||
return
|
||||
|
||||
session = TheVoid('GetSession', {}).get()
|
||||
|
@ -782,11 +782,11 @@ def get_themes():
|
|||
tvtunes.setSetting('custom_path', library)
|
||||
LOG.info("TV Tunes custom path is enabled and set.")
|
||||
else:
|
||||
dialog("ok", heading="{emby}", line1=_(33152))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33152))
|
||||
|
||||
return
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
all_views = emby_db.EmbyDatabase(embydb.cursor).get_views()
|
||||
views = [x[0] for x in all_views if x[2] in ('movies', 'tvshows', 'mixed')]
|
||||
|
||||
|
@ -831,7 +831,7 @@ def get_themes():
|
|||
|
||||
tvtunes_nfo(nfo_file, paths)
|
||||
|
||||
dialog("notification", heading="{emby}", message=_(33153), icon="{emby}", time=1000, sound=False)
|
||||
dialog("notification", heading="{jellyfin}", message=_(33153), icon="{jellyfin}", time=1000, sound=False)
|
||||
|
||||
def delete_item():
|
||||
|
||||
|
@ -843,7 +843,7 @@ def delete_item():
|
|||
|
||||
def backup():
|
||||
|
||||
''' Emby backup.
|
||||
''' Jellyfin backup.
|
||||
'''
|
||||
from helper.utils import delete_folder, copytree
|
||||
|
||||
|
@ -857,7 +857,7 @@ def backup():
|
|||
backup = os.path.join(path, folder_name)
|
||||
|
||||
if xbmcvfs.exists(backup + '/'):
|
||||
if not dialog("yesno", heading="{emby}", line1=_(33090)):
|
||||
if not dialog("yesno", heading="{jellyfin}", line1=_(33090)):
|
||||
|
||||
return backup()
|
||||
|
||||
|
@ -870,7 +870,7 @@ def backup():
|
|||
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)
|
||||
dialog("notification", heading="{jellyfin}", icon="{jellyfin}", message=_(33165), sound=False)
|
||||
|
||||
return
|
||||
|
||||
|
@ -878,9 +878,9 @@ def backup():
|
|||
|
||||
databases = Objects().objects
|
||||
|
||||
db = xbmc.translatePath(databases['emby']).decode('utf-8')
|
||||
db = xbmc.translatePath(databases['jellyfin']).decode('utf-8')
|
||||
xbmcvfs.copy(db, os.path.join(destination_databases, db.rsplit('\\', 1)[1]))
|
||||
LOG.info("copied emby.db")
|
||||
LOG.info("copied jellyfin.db")
|
||||
|
||||
db = xbmc.translatePath(databases['video']).decode('utf-8')
|
||||
filename = db.rsplit('\\', 1)[1]
|
||||
|
@ -895,4 +895,4 @@ def backup():
|
|||
LOG.info("copied %s", filename)
|
||||
|
||||
LOG.info("backup completed")
|
||||
dialog("ok", heading="{emby}", line1="%s %s" % (_(33091), backup))
|
||||
dialog("ok", heading="{jellyfin}", line1="%s %s" % (_(33091), backup))
|
||||
|
|
|
@ -26,7 +26,7 @@ from database import Database, emby_db, reset
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -43,7 +43,7 @@ class Service(xbmc.Monitor):
|
|||
|
||||
def __init__(self):
|
||||
|
||||
window('emby_should_stop', clear=True)
|
||||
window('jellyfin_should_stop', clear=True)
|
||||
|
||||
self.settings['addon_version'] = client.get_version()
|
||||
self.settings['profile'] = xbmc.translatePath('special://profile')
|
||||
|
@ -53,14 +53,14 @@ class Service(xbmc.Monitor):
|
|||
self.settings['enable_context'] = settings('enableContext.bool')
|
||||
self.settings['enable_context_transcode'] = settings('enableContextTranscode.bool')
|
||||
self.settings['kodi_companion'] = settings('kodiCompanion.bool')
|
||||
window('emby_logLevel', value=str(self.settings['log_level']))
|
||||
window('emby_kodiProfile', value=self.settings['profile'])
|
||||
window('jellyfin_logLevel', value=str(self.settings['log_level']))
|
||||
window('jellyfin_kodiProfile', value=self.settings['profile'])
|
||||
settings('platformDetected', client.get_platform())
|
||||
|
||||
if self.settings['enable_context']:
|
||||
window('emby_context.bool', True)
|
||||
window('jellyfin_context.bool', True)
|
||||
if self.settings['enable_context_transcode']:
|
||||
window('emby_context_transcode.bool', True)
|
||||
window('jellyfin_context_transcode.bool', True)
|
||||
|
||||
LOG.warn("--->>>[ %s ]", client.get_addon_name())
|
||||
LOG.warn("Version: %s", client.get_version())
|
||||
|
@ -78,7 +78,7 @@ class Service(xbmc.Monitor):
|
|||
except Exception as error:
|
||||
LOG.error(error)
|
||||
|
||||
window('emby.connected.bool', True)
|
||||
window('jellyfin.connected.bool', True)
|
||||
self.check_update()
|
||||
settings('groupedSets.bool', objects.utils.get_grouped_set())
|
||||
xbmc.Monitor.__init__(self)
|
||||
|
@ -99,9 +99,9 @@ class Service(xbmc.Monitor):
|
|||
self.settings['mode'] = settings('useDirectPaths')
|
||||
|
||||
while self.running:
|
||||
if window('emby_online.bool'):
|
||||
if window('jellyfin_online.bool'):
|
||||
|
||||
if self.settings['profile'] != window('emby_kodiProfile'):
|
||||
if self.settings['profile'] != window('jellyfin_kodiProfile'):
|
||||
LOG.info("[ profile switch ] %s", self.settings['profile'])
|
||||
|
||||
break
|
||||
|
@ -118,10 +118,10 @@ class Service(xbmc.Monitor):
|
|||
if update:
|
||||
self.settings['last_progress_report'] = datetime.today()
|
||||
|
||||
if window('emby.restart.bool'):
|
||||
if window('jellyfin.restart.bool'):
|
||||
|
||||
window('emby.restart', clear=True)
|
||||
dialog("notification", heading="{emby}", message=_(33193), icon="{emby}", time=1000, sound=False)
|
||||
window('jellyfin.restart', clear=True)
|
||||
dialog("notification", heading="{jellyfin}", message=_(33193), icon="{jellyfin}", time=1000, sound=False)
|
||||
|
||||
raise Exception('RestartService')
|
||||
|
||||
|
@ -142,7 +142,7 @@ class Service(xbmc.Monitor):
|
|||
|
||||
def stop_default(self):
|
||||
|
||||
window('emby_online', clear=True)
|
||||
window('jellyfin_online', clear=True)
|
||||
Emby().close()
|
||||
|
||||
if self.library_thread is not None:
|
||||
|
@ -154,7 +154,7 @@ class Service(xbmc.Monitor):
|
|||
|
||||
''' Check the database version to ensure we do not need to do a reset.
|
||||
'''
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
version = emby_db.EmbyDatabase(embydb.cursor).get_version()
|
||||
LOG.info("---[ db/%s ]", version)
|
||||
|
@ -202,12 +202,12 @@ class Service(xbmc.Monitor):
|
|||
get_objects(zipfile, label + '.zip')
|
||||
self.reload_objects()
|
||||
|
||||
dialog("notification", heading="{emby}", message=_(33156), icon="{emby}")
|
||||
dialog("notification", heading="{jellyfin}", message=_(33156), icon="{jellyfin}")
|
||||
LOG.info("--[ new objects/%s ]", objects.version)
|
||||
|
||||
try:
|
||||
if compare_version(self.settings['addon_version'], objects.embyversion) < 0:
|
||||
dialog("ok", heading="{emby}", line1="%s %s" % (_(33160), objects.embyversion))
|
||||
dialog("ok", heading="{jellyfin}", line1="%s %s" % (_(33160), objects.embyversion))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
@ -229,7 +229,7 @@ class Service(xbmc.Monitor):
|
|||
|
||||
if method not in ('ServerUnreachable', 'ServerShuttingDown', 'UserDataChanged', 'ServerConnect',
|
||||
'LibraryChanged', 'ServerOnline', 'SyncLibrary', 'RepairLibrary', 'RemoveLibrary',
|
||||
'EmbyConnect', 'SyncLibrarySelection', 'RepairLibrarySelection', 'AddServer',
|
||||
'JellyfinConnect', 'SyncLibrarySelection', 'RepairLibrarySelection', 'AddServer',
|
||||
'Unauthorized', 'UpdateServer', 'UserConfigurationUpdated', 'ServerRestarting',
|
||||
'RemoveServer', 'AddLibrarySelection', 'CheckUpdate', 'RemoveLibrarySelection'):
|
||||
return
|
||||
|
@ -246,7 +246,7 @@ class Service(xbmc.Monitor):
|
|||
if method == 'ServerOnline':
|
||||
if data.get('ServerId') is None:
|
||||
|
||||
window('emby_online.bool', True)
|
||||
window('jellyfin_online.bool', True)
|
||||
self.settings['auth_check'] = True
|
||||
self.warn = True
|
||||
|
||||
|
@ -254,8 +254,8 @@ class Service(xbmc.Monitor):
|
|||
|
||||
users = [user for user in (settings('additionalUsers') or "").decode('utf-8').split(',') if user]
|
||||
users.insert(0, settings('username').decode('utf-8'))
|
||||
dialog("notification", heading="{emby}", message="%s %s" % (_(33000), ", ".join(users)),
|
||||
icon="{emby}", time=1500, sound=False)
|
||||
dialog("notification", heading="{jellyfin}", message="%s %s" % (_(33000), ", ".join(users)),
|
||||
icon="{jellyfin}", time=1500, sound=False)
|
||||
|
||||
if self.library_thread is None:
|
||||
|
||||
|
@ -267,7 +267,7 @@ class Service(xbmc.Monitor):
|
|||
if self.warn or data.get('ServerId'):
|
||||
|
||||
self.warn = data.get('ServerId') is not None
|
||||
dialog("notification", heading="{emby}", message=_(33146) if data.get('ServerId') is None else _(33149), icon=xbmcgui.NOTIFICATION_ERROR)
|
||||
dialog("notification", heading="{jellyfin}", message=_(33146) if data.get('ServerId') is None else _(33149), icon=xbmcgui.NOTIFICATION_ERROR)
|
||||
|
||||
if data.get('ServerId') is None:
|
||||
self.stop_default()
|
||||
|
@ -278,7 +278,7 @@ class Service(xbmc.Monitor):
|
|||
self.start_default()
|
||||
|
||||
elif method == 'Unauthorized':
|
||||
dialog("notification", heading="{emby}", message=_(33147) if data['ServerId'] is None else _(33148), icon=xbmcgui.NOTIFICATION_ERROR)
|
||||
dialog("notification", heading="{jellyfin}", message=_(33147) if data['ServerId'] is None else _(33148), icon=xbmcgui.NOTIFICATION_ERROR)
|
||||
|
||||
if data.get('ServerId') is None and self.settings['auth_check']:
|
||||
|
||||
|
@ -295,7 +295,7 @@ class Service(xbmc.Monitor):
|
|||
return
|
||||
|
||||
if settings('restartMsg.bool'):
|
||||
dialog("notification", heading="{emby}", message=_(33006), icon="{emby}")
|
||||
dialog("notification", heading="{jellyfin}", message=_(33006), icon="{jellyfin}")
|
||||
|
||||
self.stop_default()
|
||||
|
||||
|
@ -308,7 +308,7 @@ class Service(xbmc.Monitor):
|
|||
self.connect.register(data['Id'])
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
|
||||
elif method == 'EmbyConnect':
|
||||
elif method == 'JellyfinConnect':
|
||||
self.connect.setup_login_connect()
|
||||
|
||||
elif method == 'AddServer':
|
||||
|
@ -323,18 +323,18 @@ class Service(xbmc.Monitor):
|
|||
|
||||
elif method == 'UpdateServer':
|
||||
|
||||
dialog("ok", heading="{emby}", line1=_(33151))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33151))
|
||||
self.connect.setup_manual_server()
|
||||
|
||||
elif method == 'UserDataChanged' and self.library_thread:
|
||||
if data.get('ServerId') or not window('emby_startup.bool'):
|
||||
if data.get('ServerId') or not window('jellyfin_startup.bool'):
|
||||
return
|
||||
|
||||
LOG.info("[ UserDataChanged ] %s", data)
|
||||
self.library_thread.userdata(data['UserDataList'])
|
||||
|
||||
elif method == 'LibraryChanged' and self.library_thread:
|
||||
if data.get('ServerId') or not window('emby_startup.bool'):
|
||||
if data.get('ServerId') or not window('jellyfin_startup.bool'):
|
||||
return
|
||||
|
||||
LOG.info("[ LibraryChanged ] %s", data)
|
||||
|
@ -342,7 +342,7 @@ class Service(xbmc.Monitor):
|
|||
self.library_thread.removed(data['ItemsRemoved'])
|
||||
|
||||
elif method == 'System.OnQuit':
|
||||
window('emby_should_stop.bool', True)
|
||||
window('jellyfin_should_stop.bool', True)
|
||||
self.running = False
|
||||
|
||||
elif method in ('SyncLibrarySelection', 'RepairLibrarySelection', 'AddLibrarySelection', 'RemoveLibrarySelection'):
|
||||
|
@ -382,7 +382,7 @@ class Service(xbmc.Monitor):
|
|||
elif method == 'System.OnSleep':
|
||||
|
||||
LOG.info("-->[ sleep ]")
|
||||
window('emby_should_stop.bool', True)
|
||||
window('jellyfin_should_stop.bool', True)
|
||||
|
||||
if self.library_thread is not None:
|
||||
|
||||
|
@ -403,7 +403,7 @@ class Service(xbmc.Monitor):
|
|||
LOG.info("--<[ sleep ]")
|
||||
xbmc.sleep(10000)# Allow network to wake up
|
||||
self.monitor.sleep = False
|
||||
window('emby_should_stop', clear=True)
|
||||
window('jellyfin_should_stop', clear=True)
|
||||
|
||||
try:
|
||||
self.connect.register()
|
||||
|
@ -426,34 +426,34 @@ class Service(xbmc.Monitor):
|
|||
elif method == 'CheckUpdate':
|
||||
|
||||
if not self.check_update(True):
|
||||
dialog("notification", heading="{emby}", message=_(21341), icon="{emby}", sound=False)
|
||||
dialog("notification", heading="{jellyfin}", message=_(21341), icon="{jellyfin}", sound=False)
|
||||
else:
|
||||
dialog("notification", heading="{emby}", message=_(33181), icon="{emby}", sound=False)
|
||||
window('emby.restart.bool', True)
|
||||
dialog("notification", heading="{jellyfin}", message=_(33181), icon="{jellyfin}", sound=False)
|
||||
window('jellyfin.restart.bool', True)
|
||||
|
||||
def onSettingsChanged(self):
|
||||
|
||||
''' React to setting changes that impact window values.
|
||||
'''
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
return
|
||||
|
||||
if settings('logLevel') != self.settings['log_level']:
|
||||
|
||||
log_level = settings('logLevel')
|
||||
window('emby_logLevel', str(log_level))
|
||||
window('jellyfin_logLevel', str(log_level))
|
||||
self.settings['logLevel'] = log_level
|
||||
LOG.warn("New log level: %s", log_level)
|
||||
|
||||
if settings('enableContext.bool') != self.settings['enable_context']:
|
||||
|
||||
window('emby_context', settings('enableContext'))
|
||||
window('jellyfin_context', settings('enableContext'))
|
||||
self.settings['enable_context'] = settings('enableContext.bool')
|
||||
LOG.warn("New context setting: %s", self.settings['enable_context'])
|
||||
|
||||
if settings('enableContextTranscode.bool') != self.settings['enable_context_transcode']:
|
||||
|
||||
window('emby_context_transcode', settings('enableContextTranscode'))
|
||||
window('jellyfin_context_transcode', settings('enableContextTranscode'))
|
||||
self.settings['enable_context_transcode'] = settings('enableContextTranscode.bool')
|
||||
LOG.warn("New context transcode setting: %s", self.settings['enable_context_transcode'])
|
||||
|
||||
|
@ -465,13 +465,13 @@ class Service(xbmc.Monitor):
|
|||
if not self.settings.get('mode_warn'):
|
||||
|
||||
self.settings['mode_warn'] = True
|
||||
dialog("yesno", heading="{emby}", line1=_(33118))
|
||||
dialog("yesno", heading="{jellyfin}", line1=_(33118))
|
||||
|
||||
if settings('kodiCompanion.bool') != self.settings['kodi_companion']:
|
||||
self.settings['kodi_companion'] = settings('kodiCompanion.bool')
|
||||
|
||||
if not self.settings['kodi_companion']:
|
||||
dialog("ok", heading="{emby}", line1=_(33138))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33138))
|
||||
|
||||
def reload_objects(self):
|
||||
|
||||
|
@ -497,14 +497,14 @@ class Service(xbmc.Monitor):
|
|||
def shutdown(self):
|
||||
|
||||
LOG.warn("---<[ EXITING ]")
|
||||
window('emby_should_stop.bool', True)
|
||||
window('jellyfin_should_stop.bool', True)
|
||||
|
||||
properties = [ # TODO: review
|
||||
"emby_state", "emby_serverStatus", "emby_currUser",
|
||||
"jellyfin_state", "jellyfin_serverStatus", "jellyfin_currUser",
|
||||
|
||||
"emby_play", "emby_online", "emby.connected", "emby.resume", "emby_startup",
|
||||
"emby.external", "emby.external_check", "emby_deviceId", "emby_db_check", "emby_pathverified",
|
||||
"emby_sync"
|
||||
"jellyfin_play", "jellyfin_online", "jellyfin.connected", "jellyfin.resume", "jellyfin_startup",
|
||||
"jellyfin.external", "jellyfin.external_check", "jellyfin_deviceId", "jellyfin_db_check", "jellyfin_pathverified",
|
||||
"jellyfin_sync"
|
||||
]
|
||||
for prop in properties:
|
||||
window(prop, clear=True)
|
||||
|
|
|
@ -19,7 +19,7 @@ from views import Views
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -27,7 +27,7 @@ LOG = logging.getLogger("EMBY."+__name__)
|
|||
class FullSync(object):
|
||||
|
||||
''' This should be called like a context.
|
||||
i.e. with FullSync('emby') as sync:
|
||||
i.e. with FullSync('jellyfin') as sync:
|
||||
sync.libraries()
|
||||
'''
|
||||
# Borg - multiple instances, shared state
|
||||
|
@ -45,7 +45,7 @@ class FullSync(object):
|
|||
self.__dict__ = self._shared_state
|
||||
|
||||
if self.running:
|
||||
dialog("ok", heading="{emby}", line1=_(33197))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33197))
|
||||
|
||||
raise Exception("Sync is already running.")
|
||||
|
||||
|
@ -65,7 +65,7 @@ class FullSync(object):
|
|||
set_screensaver(value="")
|
||||
|
||||
self.running = True
|
||||
window('emby_sync.bool', True)
|
||||
window('jellyfin_sync.bool', True)
|
||||
|
||||
return self
|
||||
|
||||
|
@ -104,7 +104,7 @@ class FullSync(object):
|
|||
|
||||
def get_libraries(self, library_id=None):
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
if library_id is None:
|
||||
return emby_db.EmbyDatabase(embydb.cursor).get_views()
|
||||
else:
|
||||
|
@ -117,10 +117,10 @@ class FullSync(object):
|
|||
'''
|
||||
if self.sync['Libraries']:
|
||||
|
||||
if not dialog("yesno", heading="{emby}", line1=_(33102)):
|
||||
if not dialog("yesno", heading="{jellyfin}", line1=_(33102)):
|
||||
|
||||
if not dialog("yesno", heading="{emby}", line1=_(33173)):
|
||||
dialog("ok", heading="{emby}", line1=_(33122))
|
||||
if not dialog("yesno", heading="{jellyfin}", line1=_(33173)):
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33122))
|
||||
|
||||
raise LibraryException("ProgressStopped")
|
||||
else:
|
||||
|
@ -146,7 +146,7 @@ class FullSync(object):
|
|||
|
||||
''' Select all or certain libraries to be whitelisted.
|
||||
'''
|
||||
if dialog("yesno", heading="{emby}", line1=_(33125), nolabel=_(33127), yeslabel=_(33126)):
|
||||
if dialog("yesno", heading="{jellyfin}", line1=_(33125), nolabel=_(33127), yeslabel=_(33126)):
|
||||
LOG.info("Selected sync later.")
|
||||
|
||||
raise LibraryException('SyncLibraryLater')
|
||||
|
@ -204,8 +204,8 @@ class FullSync(object):
|
|||
save_sync(self.sync)
|
||||
|
||||
xbmc.executebuiltin('UpdateLibrary(video)')
|
||||
dialog("notification", heading="{emby}", message="%s %s" % (_(33025), str(elapsed).split('.')[0]),
|
||||
icon="{emby}", sound=False)
|
||||
dialog("notification", heading="{jellyfin}", message="%s %s" % (_(33025), str(elapsed).split('.')[0]),
|
||||
icon="{jellyfin}", sound=False)
|
||||
LOG.info("Full sync completed in: %s", str(elapsed).split('.')[0])
|
||||
|
||||
def process_library(self, library_id):
|
||||
|
@ -251,7 +251,7 @@ class FullSync(object):
|
|||
|
||||
if not 'Failed to validate path' in error:
|
||||
|
||||
dialog("ok", heading="{emby}", line1=_(33119))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33119))
|
||||
LOG.error("full sync exited unexpectedly")
|
||||
save_sync(self.sync)
|
||||
|
||||
|
@ -266,7 +266,7 @@ class FullSync(object):
|
|||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
obj = Movies(self.server, embydb, videodb, self.direct_path)
|
||||
|
||||
|
@ -287,7 +287,7 @@ class FullSync(object):
|
|||
|
||||
def movies_compare(self, library, obj, embydb):
|
||||
|
||||
''' Compare entries from library to what's in the embydb. Remove surplus
|
||||
''' Compare entries from library to what's in the jellyfindb. Remove surplus
|
||||
'''
|
||||
db = emby_db.EmbyDatabase(embydb.cursor)
|
||||
|
||||
|
@ -307,7 +307,7 @@ class FullSync(object):
|
|||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
obj = TVShows(self.server, embydb, videodb, self.direct_path, True)
|
||||
|
||||
for items in server.get_items(library['Id'], "Series", False, self.sync['RestorePoint'].get('params')):
|
||||
|
@ -357,7 +357,7 @@ class FullSync(object):
|
|||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
obj = MusicVideos(self.server, embydb, videodb, self.direct_path)
|
||||
|
||||
for items in server.get_items(library['Id'], "MusicVideo", False, self.sync['RestorePoint'].get('params')):
|
||||
|
@ -397,7 +397,7 @@ class FullSync(object):
|
|||
|
||||
with self.library.music_database_lock:
|
||||
with Database('music') as musicdb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
obj = Music(self.server, embydb, musicdb, self.direct_path)
|
||||
|
||||
for items in server.get_artists(library['Id'], False, self.sync['RestorePoint'].get('params')):
|
||||
|
@ -459,7 +459,7 @@ class FullSync(object):
|
|||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
obj = Movies(self.server, embydb, videodb, self.direct_path)
|
||||
|
||||
for items in server.get_items(library_id, "BoxSet", False, self.sync['RestorePoint'].get('params')):
|
||||
|
@ -482,7 +482,7 @@ class FullSync(object):
|
|||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
obj = Movies(self.server, embydb, videodb, self.direct_path)
|
||||
obj.boxsets_reset()
|
||||
|
@ -497,7 +497,7 @@ class FullSync(object):
|
|||
MEDIA = self.library.MEDIA
|
||||
direct_path = self.library.direct_path
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
db = emby_db.EmbyDatabase(embydb.cursor)
|
||||
library = db.get_view(library_id.replace('Mixed:', ""))
|
||||
|
@ -558,7 +558,7 @@ class FullSync(object):
|
|||
''' Exiting sync
|
||||
'''
|
||||
self.running = False
|
||||
window('emby_sync', clear=True)
|
||||
window('jellyfin_sync', clear=True)
|
||||
|
||||
if not settings('dbSyncScreensaver.bool') and self.screensaver is not None:
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from . import settings
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -28,7 +28,7 @@ class API(object):
|
|||
|
||||
def get_playcount(self, played, playcount):
|
||||
|
||||
''' Convert Emby played/playcount into
|
||||
''' Convert Jellyfin played/playcount into
|
||||
the Kodi equivalent. The playcount is tied to the watch status.
|
||||
'''
|
||||
return (playcount or 1) if played else None
|
||||
|
@ -231,7 +231,7 @@ class API(object):
|
|||
|
||||
def get_user_artwork(self, user_id):
|
||||
|
||||
''' Get emby user profile picture.
|
||||
''' Get jellyfin user profile picture.
|
||||
'''
|
||||
return "%s/emby/Users/%s/Images/Primary?Format=original" % (self.server, user_id)
|
||||
|
||||
|
@ -302,7 +302,7 @@ class API(object):
|
|||
|
||||
def get_backdrops(self, item_id, tags, query=None):
|
||||
|
||||
''' Get backdrops based of "BackdropImageTags" in the emby object.
|
||||
''' Get backdrops based of "BackdropImageTags" in the jellyfin object.
|
||||
'''
|
||||
backdrops = []
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#################################################################################################
|
||||
|
||||
class LibraryException(Exception):
|
||||
# Emby library sync exception
|
||||
# Jellyfin library sync exception
|
||||
def __init__(self, status):
|
||||
self.status = status
|
||||
|
||||
|
|
|
@ -14,14 +14,14 @@ from . import window, settings
|
|||
|
||||
def config():
|
||||
|
||||
logger = logging.getLogger('EMBY')
|
||||
logger = logging.getLogger('JELLYFIN')
|
||||
logger.addHandler(LogHandler())
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
def reset():
|
||||
|
||||
for handler in logging.getLogger('EMBY').handlers:
|
||||
logging.getLogger('EMBY').removeHandler(handler)
|
||||
for handler in logging.getLogger('JELLYFIN').handlers:
|
||||
logging.getLogger('JELLYFIN').removeHandler(handler)
|
||||
|
||||
|
||||
class LogHandler(logging.StreamHandler):
|
||||
|
@ -56,10 +56,10 @@ class LogHandler(logging.StreamHandler):
|
|||
|
||||
if self.mask_info:
|
||||
for server in self.sensitive['Server']:
|
||||
string = string.replace(server.encode('utf-8') or "{server}", "{emby-server}")
|
||||
string = string.replace(server.encode('utf-8') or "{server}", "{jellyfin-server}")
|
||||
|
||||
for token in self.sensitive['Token']:
|
||||
string = string.replace(token.encode('utf-8') or "{token}", "{emby-token}")
|
||||
string = string.replace(token.encode('utf-8') or "{token}", "{jellyfin-token}")
|
||||
|
||||
try:
|
||||
xbmc.log(string, level=xbmc.LOGNOTICE)
|
||||
|
@ -76,7 +76,7 @@ class LogHandler(logging.StreamHandler):
|
|||
logging.DEBUG: 2
|
||||
}
|
||||
try:
|
||||
log_level = int(window('emby_logLevel'))
|
||||
log_level = int(window('jellyfin_logLevel'))
|
||||
except ValueError:
|
||||
log_level = 0
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from emby import Emby
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -32,7 +32,7 @@ def set_properties(item, method, server_id=None):
|
|||
'''
|
||||
info = item.get('PlaybackInfo') or {}
|
||||
|
||||
current = window('emby_play.json') or []
|
||||
current = window('jellyfin_play.json') or []
|
||||
current.append({
|
||||
'Type': item['Type'],
|
||||
'Id': item['Id'],
|
||||
|
@ -51,7 +51,7 @@ def set_properties(item, method, server_id=None):
|
|||
'CurrentEpisode': info.get('CurrentEpisode')
|
||||
})
|
||||
|
||||
window('emby_play.json', current)
|
||||
window('jellyfin_play.json', current)
|
||||
|
||||
class PlayUtils(object):
|
||||
|
||||
|
@ -178,7 +178,7 @@ class PlayUtils(object):
|
|||
def get(self, source, audio=None, subtitle=None):
|
||||
|
||||
''' The server returns sources based on the MaxStreamingBitrate value and other filters.
|
||||
prop: embyfilename for ?? I thought it was to pass the real path to subtitle add-ons but it's not working?
|
||||
prop: jellyfinfilename for ?? I thought it was to pass the real path to subtitle add-ons but it's not working?
|
||||
'''
|
||||
self.info['MediaSourceId'] = source['Id']
|
||||
|
||||
|
@ -214,7 +214,7 @@ class PlayUtils(object):
|
|||
self.item['PlaybackInfo'].update(self.info)
|
||||
|
||||
API = api.API(self.item, self.info['ServerAddress'])
|
||||
window('embyfilename', value=API.get_file_path(source.get('Path')).encode('utf-8'))
|
||||
window('jellyfinfilename', value=API.get_file_path(source.get('Path')).encode('utf-8'))
|
||||
|
||||
def live_stream(self, source):
|
||||
|
||||
|
@ -454,7 +454,7 @@ class PlayUtils(object):
|
|||
def set_external_subs(self, source, listitem):
|
||||
|
||||
''' Try to download external subs locally so we can label them.
|
||||
Since Emby returns all possible tracks together, sort them.
|
||||
Since Jellyfin returns all possible tracks together, sort them.
|
||||
IsTextSubtitleStream if true, is available to download from server.
|
||||
'''
|
||||
if not settings('enableExternalSubs.bool') or not source['MediaStreams']:
|
||||
|
@ -528,7 +528,7 @@ class PlayUtils(object):
|
|||
''' For transcoding only
|
||||
Present the list of audio/subs to select from, before playback starts.
|
||||
|
||||
Since Emby returns all possible tracks together, sort them.
|
||||
Since Jellyfin returns all possible tracks together, sort them.
|
||||
IsTextSubtitleStream if true, is available to download from server.
|
||||
'''
|
||||
prefs = ""
|
||||
|
|
|
@ -11,7 +11,7 @@ import xbmcaddon
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger('EMBY.'+__name__)
|
||||
LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from dateutil import tz, parser
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -149,10 +149,10 @@ def dialog(dialog_type, *args, **kwargs):
|
|||
d = xbmcgui.Dialog()
|
||||
|
||||
if "icon" in kwargs:
|
||||
kwargs['icon'] = kwargs['icon'].replace("{emby}",
|
||||
kwargs['icon'] = kwargs['icon'].replace("{jellyfin}",
|
||||
"special://home/addons/plugin.video.jellyfin/icon.png")
|
||||
if "heading" in kwargs:
|
||||
kwargs['heading'] = kwargs['heading'].replace("{emby}", _('addon_name'))
|
||||
kwargs['heading'] = kwargs['heading'].replace("{jellyfin}", _('addon_name'))
|
||||
|
||||
types = {
|
||||
'yesno': d.yesno,
|
||||
|
@ -172,11 +172,11 @@ def should_stop():
|
|||
if xbmc.Monitor().waitForAbort(0.00001):
|
||||
return True
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
LOG.info("exiiiiitttinggg")
|
||||
return True
|
||||
|
||||
if not window('emby_online.bool'):
|
||||
if not window('jellyfin_online.bool'):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
@ -235,7 +235,7 @@ def validate(path):
|
|||
|
||||
''' Verify if path is accessible.
|
||||
'''
|
||||
if window('emby_pathverified.bool'):
|
||||
if window('jellyfin_pathverified.bool'):
|
||||
return True
|
||||
|
||||
path = path if os.path.supports_unicode_filenames else path.encode('utf-8')
|
||||
|
@ -243,11 +243,11 @@ def validate(path):
|
|||
if not xbmcvfs.exists(path):
|
||||
LOG.info("Could not find %s", path)
|
||||
|
||||
if dialog("yesno", heading="{emby}", line1="%s %s. %s" % (_(33047), path, _(33048))):
|
||||
if dialog("yesno", heading="{jellyfin}", line1="%s %s. %s" % (_(33047), path, _(33048))):
|
||||
|
||||
return False
|
||||
|
||||
window('emby_pathverified.bool', True)
|
||||
window('jellyfin_pathverified.bool', True)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -292,7 +292,7 @@ def delete_folder(path=None):
|
|||
'''
|
||||
LOG.debug("--[ delete folder ]")
|
||||
delete_path = path is not None
|
||||
path = path or xbmc.translatePath('special://temp/emby').decode('utf-8')
|
||||
path = path or xbmc.translatePath('special://temp/jellyfin').decode('utf-8')
|
||||
dirs, files = xbmcvfs.listdir(path)
|
||||
|
||||
delete_recursive(path, dirs)
|
||||
|
|
|
@ -11,7 +11,7 @@ from utils import should_stop
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -101,7 +101,7 @@ def stop(default=None):
|
|||
|
||||
def emby_item():
|
||||
|
||||
''' Wrapper to retrieve the emby_db item.
|
||||
''' Wrapper to retrieve the jellyfin_db item.
|
||||
'''
|
||||
def decorator(func):
|
||||
def wrapper(self, item, *args, **kwargs):
|
||||
|
|
|
@ -13,14 +13,14 @@ from . import _, indent, write_xml, dialog, settings
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
def sources():
|
||||
|
||||
''' Create master lock compatible sources.
|
||||
Also add the kodi.emby.media source.
|
||||
Also add the kodi.jellyfin.media source.
|
||||
'''
|
||||
path = xbmc.translatePath("special://profile/").decode('utf-8')
|
||||
file = os.path.join(path, 'sources.xml')
|
||||
|
@ -52,7 +52,7 @@ def sources():
|
|||
if (protocol == 'smb://' and count_smb > 0) or (protocol == 'http://' and count_http > 0):
|
||||
|
||||
source = etree.SubElement(video, 'source')
|
||||
etree.SubElement(source, 'name').text = "Emby"
|
||||
etree.SubElement(source, 'name').text = "Jellyfin"
|
||||
etree.SubElement(source, 'path', attrib={'pathversion': "1"}).text = protocol
|
||||
etree.SubElement(source, 'allowsharing').text = "true"
|
||||
|
||||
|
@ -63,12 +63,13 @@ def sources():
|
|||
files = etree.SubElement(xml, 'files')
|
||||
|
||||
for source in xml.findall('.//path'):
|
||||
if source.text == 'http://kodi.emby.media':
|
||||
# TODO get a repo url
|
||||
if source.text == 'http://kodi.jellyfin.media':
|
||||
break
|
||||
else:
|
||||
source = etree.SubElement(files, 'source')
|
||||
etree.SubElement(source, 'name').text = "kodi.emby.media"
|
||||
etree.SubElement(source, 'path', attrib={'pathversion': "1"}).text = "http://kodi.emby.media"
|
||||
etree.SubElement(source, 'name').text = "kodi.jellyfin.media"
|
||||
etree.SubElement(source, 'path', attrib={'pathversion': "1"}).text = "http://kodi.jellyfin.media"
|
||||
etree.SubElement(source, 'allowsharing').text = "true"
|
||||
except Exception as error:
|
||||
LOG.exception(error)
|
||||
|
@ -124,7 +125,7 @@ def advanced_settings():
|
|||
indent(xml)
|
||||
write_xml(etree.tostring(xml, 'UTF-8'), path)
|
||||
|
||||
dialog("ok", heading="{emby}", line1=_(33097))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33097))
|
||||
xbmc.executebuiltin('RestartApp')
|
||||
|
||||
return True
|
||||
|
|
|
@ -22,7 +22,7 @@ from emby import Emby
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
LIMIT = min(int(settings('limitIndex') or 50), 50)
|
||||
DTHREADS = int(settings('limitThreads') or 3)
|
||||
MEDIA = {
|
||||
|
@ -101,7 +101,7 @@ class Library(threading.Thread):
|
|||
if not self.startup():
|
||||
self.stop_client()
|
||||
|
||||
window('emby_startup.bool', True)
|
||||
window('jellyfin_startup.bool', True)
|
||||
|
||||
while not self.stop_thread:
|
||||
|
||||
|
@ -151,7 +151,7 @@ class Library(threading.Thread):
|
|||
self.worker_notify()
|
||||
|
||||
if self.pending_refresh:
|
||||
window('emby_sync.bool', True)
|
||||
window('jellyfin_sync.bool', True)
|
||||
|
||||
if self.total_updates > self.progress_display:
|
||||
queue_size = self.worker_queue_size()
|
||||
|
@ -177,7 +177,7 @@ class Library(threading.Thread):
|
|||
self.pending_refresh = False
|
||||
self.save_last_sync()
|
||||
self.total_updates = 0
|
||||
window('emby_sync', clear=True)
|
||||
window('jellyfin_sync', clear=True)
|
||||
|
||||
if self.progress_updates:
|
||||
|
||||
|
@ -206,7 +206,7 @@ class Library(threading.Thread):
|
|||
''' When there's an active thread. Let the main thread know.
|
||||
'''
|
||||
self.pending_refresh = True
|
||||
window('emby_sync.bool', True)
|
||||
window('jellyfin_sync.bool', True)
|
||||
|
||||
def worker_queue_size(self):
|
||||
|
||||
|
@ -227,7 +227,7 @@ class Library(threading.Thread):
|
|||
|
||||
def worker_downloads(self):
|
||||
|
||||
''' Get items from emby and place them in the appropriate queues.
|
||||
''' Get items from jellyfin and place them in the appropriate queues.
|
||||
'''
|
||||
for queue in ((self.updated_queue, self.updated_output), (self.userdata_queue, self.userdata_output)):
|
||||
if queue[0].qsize() and len(self.download_threads) < DTHREADS:
|
||||
|
@ -238,7 +238,7 @@ class Library(threading.Thread):
|
|||
|
||||
def worker_sort(self):
|
||||
|
||||
''' Get items based on the local emby database and place item in appropriate queues.
|
||||
''' Get items based on the local jellyfin database and place item in appropriate queues.
|
||||
'''
|
||||
if self.removed_queue.qsize() and len(self.emby_threads) < 2:
|
||||
|
||||
|
@ -350,10 +350,10 @@ class Library(threading.Thread):
|
|||
if settings('kodiCompanion.bool'):
|
||||
|
||||
for plugin in self.server['api'].get_plugins():
|
||||
if plugin['Name'] in ("Emby.Kodi Sync Queue", "Kodi companion"):
|
||||
if plugin['Name'] in ("Jellyfin.Kodi Sync Queue", "Kodi companion"):
|
||||
|
||||
if not self.fast_sync():
|
||||
dialog("ok", heading="{emby}", line1=_(33128))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33128))
|
||||
|
||||
raise Exception("Failed to retrieve latest updates")
|
||||
|
||||
|
@ -369,7 +369,7 @@ class Library(threading.Thread):
|
|||
|
||||
if error.status in 'SyncLibraryLater':
|
||||
|
||||
dialog("ok", heading="{emby}", line1=_(33129))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33129))
|
||||
settings('SyncInstallRunDone.bool', True)
|
||||
sync = get_sync()
|
||||
sync['Libraries'] = []
|
||||
|
@ -379,7 +379,7 @@ class Library(threading.Thread):
|
|||
|
||||
elif error.status == 'CompanionMissing':
|
||||
|
||||
dialog("ok", heading="{emby}", line1=_(33099))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33099))
|
||||
settings('kodiCompanion.bool', False)
|
||||
|
||||
return True
|
||||
|
@ -422,7 +422,7 @@ class Library(threading.Thread):
|
|||
|
||||
''' Inverse yes no, in case the dialog is forced closed by Kodi.
|
||||
'''
|
||||
if dialog("yesno", heading="{emby}", line1=_(33172).replace('{number}', str(total)), nolabel=_(107), yeslabel=_(106)):
|
||||
if dialog("yesno", heading="{jellyfin}", line1=_(33172).replace('{number}', str(total)), nolabel=_(107), yeslabel=_(106)):
|
||||
LOG.warn("Large updates skipped.")
|
||||
|
||||
return True
|
||||
|
@ -482,7 +482,7 @@ class Library(threading.Thread):
|
|||
whitelist = [x.replace('Mixed:', "") for x in sync['Whitelist']]
|
||||
libraries = []
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
db = emby_db.EmbyDatabase(embydb.cursor)
|
||||
|
||||
if mode in ('SyncLibrarySelection', 'RepairLibrarySelection', 'RemoveLibrarySelection'):
|
||||
|
@ -614,7 +614,7 @@ class UpdatedWorker(threading.Thread):
|
|||
|
||||
with self.lock:
|
||||
with self.database as kodidb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
while True:
|
||||
|
||||
|
@ -636,7 +636,7 @@ class UpdatedWorker(threading.Thread):
|
|||
|
||||
self.queue.task_done()
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
break
|
||||
|
||||
LOG.info("--<[ q:updated/%s ]", id(self))
|
||||
|
@ -658,7 +658,7 @@ class UserDataWorker(threading.Thread):
|
|||
|
||||
with self.lock:
|
||||
with self.database as kodidb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
while True:
|
||||
|
||||
|
@ -679,7 +679,7 @@ class UserDataWorker(threading.Thread):
|
|||
|
||||
self.queue.task_done()
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
break
|
||||
|
||||
LOG.info("--<[ q:userdata/%s ]", id(self))
|
||||
|
@ -698,7 +698,7 @@ class SortWorker(threading.Thread):
|
|||
|
||||
def run(self):
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
database = emby_db.EmbyDatabase(embydb.cursor)
|
||||
|
||||
while True:
|
||||
|
@ -715,14 +715,14 @@ class SortWorker(threading.Thread):
|
|||
items = database.get_media_by_parent_id(item_id)
|
||||
|
||||
if not items:
|
||||
LOG.info("Could not find media %s in the emby database.", item_id)
|
||||
LOG.info("Could not find media %s in the jellyfin database.", item_id)
|
||||
else:
|
||||
for item in items:
|
||||
self.output[item[1]].put({'Id': item[0], 'Type': item[1]})
|
||||
|
||||
self.queue.task_done()
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
break
|
||||
|
||||
LOG.info("--<[ q:sort/%s ]", id(self))
|
||||
|
@ -744,7 +744,7 @@ class RemovedWorker(threading.Thread):
|
|||
|
||||
with self.lock:
|
||||
with self.database as kodidb:
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
while True:
|
||||
|
||||
|
@ -765,7 +765,7 @@ class RemovedWorker(threading.Thread):
|
|||
|
||||
self.queue.task_done()
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
break
|
||||
|
||||
LOG.info("--<[ q:removed/%s ]", id(self))
|
||||
|
@ -796,11 +796,11 @@ class NotifyWorker(threading.Thread):
|
|||
|
||||
if time and (not self.player.isPlayingVideo() or xbmc.getCondVisibility('VideoPlayer.Content(livetv)')):
|
||||
dialog("notification", heading="%s %s" % (_(33049), item[0]), message=item[1],
|
||||
icon="{emby}", time=time, sound=False)
|
||||
icon="{jellyfin}", time=time, sound=False)
|
||||
|
||||
self.queue.task_done()
|
||||
|
||||
if window('emby_should_stop.bool'):
|
||||
if window('jellyfin_should_stop.bool'):
|
||||
break
|
||||
|
||||
LOG.info("--<[ q:notify/%s ]", id(self))
|
||||
|
|
|
@ -22,7 +22,7 @@ from webservice import WebService
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -114,7 +114,7 @@ class Monitor(xbmc.Monitor):
|
|||
except Exception as error:
|
||||
|
||||
LOG.error(error)
|
||||
dialog("ok", heading="{emby}", line1=_(33142))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33142))
|
||||
|
||||
return
|
||||
|
||||
|
@ -272,8 +272,8 @@ class Monitor(xbmc.Monitor):
|
|||
|
||||
def void_responder(self, data, result):
|
||||
|
||||
window('emby_%s.json' % data['VoidName'], result)
|
||||
LOG.debug("--->[ nostromo/emby_%s.json ] sent", data['VoidName'])
|
||||
window('jellyfin_%s.json' % data['VoidName'], result)
|
||||
LOG.debug("--->[ nostromo/jellyfin_%s.json ] sent", data['VoidName'])
|
||||
|
||||
def server_instance(self, server_id=None):
|
||||
|
||||
|
@ -323,7 +323,7 @@ class Monitor(xbmc.Monitor):
|
|||
''' Setup additional users images.
|
||||
'''
|
||||
for i in range(10):
|
||||
window('EmbyAdditionalUserImage.%s' % i, clear=True)
|
||||
window('JellyfinAdditionalUserImage.%s' % i, clear=True)
|
||||
|
||||
try:
|
||||
session = server['api'].get_device(self.device_id)
|
||||
|
@ -336,12 +336,12 @@ class Monitor(xbmc.Monitor):
|
|||
|
||||
info = server['api'].get_user(user['UserId'])
|
||||
image = api.API(info, server['config/auth.server']).get_user_artwork(user['UserId'])
|
||||
window('EmbyAdditionalUserImage.%s' % index, image)
|
||||
window('EmbyAdditionalUserPosition.%s' % user['UserId'], str(index))
|
||||
window('JellyfinAdditionalUserImage.%s' % index, image)
|
||||
window('JellyfinAdditionalUserPosition.%s' % user['UserId'], str(index))
|
||||
|
||||
def playstate(self, data):
|
||||
|
||||
''' Emby playstate updates.
|
||||
''' Jellyfin playstate updates.
|
||||
'''
|
||||
command = data['Command']
|
||||
actions = {
|
||||
|
@ -367,7 +367,7 @@ class Monitor(xbmc.Monitor):
|
|||
|
||||
def general_commands(self, data):
|
||||
|
||||
''' General commands from Emby to control the Kodi interface.
|
||||
''' General commands from Jellyfin to control the Kodi interface.
|
||||
'''
|
||||
command = data['Name']
|
||||
args = data['Arguments']
|
||||
|
@ -392,7 +392,7 @@ class Monitor(xbmc.Monitor):
|
|||
|
||||
elif command == 'DisplayMessage':
|
||||
dialog("notification", heading=args['Header'], message=args['Text'],
|
||||
icon="{emby}", time=int(settings('displayMessage'))*1000)
|
||||
icon="{jellyfin}", time=int(settings('displayMessage'))*1000)
|
||||
|
||||
elif command == 'SendString':
|
||||
JSONRPC('Input.SendText').execute({'text': args['String'], 'done': False})
|
||||
|
|
|
@ -23,7 +23,7 @@ from utils import get_play_action
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -89,8 +89,8 @@ class Actions(object):
|
|||
Detect the seektime for video type content.
|
||||
Verify the default video action set in Kodi for accurate resume behavior.
|
||||
'''
|
||||
seektime = window('emby.resume.bool')
|
||||
window('emby.resume', clear=True)
|
||||
seektime = window('jellyfin.resume.bool')
|
||||
window('jellyfin.resume', clear=True)
|
||||
|
||||
if item['MediaType'] in ('Video', 'Audio'):
|
||||
resume = item['UserData'].get('PlaybackPositionTicks')
|
||||
|
@ -128,7 +128,7 @@ class Actions(object):
|
|||
|
||||
if settings('askCinema') == "true":
|
||||
|
||||
resp = dialog("yesno", heading="{emby}", line1=_(33016))
|
||||
resp = dialog("yesno", heading="{jellyfin}", line1=_(33016))
|
||||
if not resp:
|
||||
|
||||
enabled = False
|
||||
|
@ -148,7 +148,7 @@ class Actions(object):
|
|||
|
||||
self.stack.append([intro['PlaybackInfo']['Path'], listitem])
|
||||
|
||||
window('emby.skip.%s' % intro['Id'], value="true")
|
||||
window('jellyfin.skip.%s' % intro['Id'], value="true")
|
||||
|
||||
def _set_additional_parts(self, item_id):
|
||||
|
||||
|
@ -659,7 +659,7 @@ class Actions(object):
|
|||
LOG.info("Resume dialog called.")
|
||||
XML_PATH = (xbmcaddon.Addon('plugin.video.jellyfin').getAddonInfo('path'), "default", "1080i")
|
||||
|
||||
dialog = resume.ResumeDialog("script-emby-resume.xml", *XML_PATH)
|
||||
dialog = resume.ResumeDialog("script-jellyfin-resume.xml", *XML_PATH)
|
||||
dialog.set_resume_point("Resume from %s" % str(timedelta(seconds=seektime)).split(".")[0])
|
||||
dialog.doModal()
|
||||
|
||||
|
@ -721,14 +721,14 @@ def on_update(data, server):
|
|||
|
||||
if item:
|
||||
|
||||
if not window('emby.skip.%s.bool' % item[0]):
|
||||
if not window('jellyfin.skip.%s.bool' % item[0]):
|
||||
server['api'].item_played(item[0], playcount)
|
||||
|
||||
window('emby.skip.%s' % item[0], clear=True)
|
||||
window('jellyfin.skip.%s' % item[0], clear=True)
|
||||
|
||||
def on_play(data, server):
|
||||
|
||||
''' Setup progress for emby playback.
|
||||
''' Setup progress for jellyfin playback.
|
||||
'''
|
||||
player = xbmc.Player()
|
||||
|
||||
|
@ -781,7 +781,7 @@ def special_listener():
|
|||
'''
|
||||
player = xbmc.Player()
|
||||
isPlaying = player.isPlaying()
|
||||
count = int(window('emby.external_count') or 0)
|
||||
count = int(window('jellyfin.external_count') or 0)
|
||||
|
||||
if (not isPlaying and xbmc.getCondVisibility('Window.IsVisible(DialogContextMenu.xml)') and
|
||||
xbmc.getInfoLabel('Control.GetLabel(1002)') == xbmc.getLocalizedString(12021)):
|
||||
|
@ -791,24 +791,24 @@ def special_listener():
|
|||
if control == 1002: # Start from beginning
|
||||
|
||||
LOG.info("Resume dialog: Start from beginning selected.")
|
||||
window('emby.resume.bool', False)
|
||||
window('jellyfin.resume.bool', False)
|
||||
else:
|
||||
LOG.info("Resume dialog: Resume selected.")
|
||||
window('emby.resume.bool', True)
|
||||
window('jellyfin.resume.bool', True)
|
||||
|
||||
elif isPlaying and not window('emby.external_check'):
|
||||
elif isPlaying and not window('jellyfin.external_check'):
|
||||
time = player.getTime()
|
||||
|
||||
if time > 1: # Not external player.
|
||||
|
||||
window('emby.external_check', value="true")
|
||||
window('emby.external_count', value="0")
|
||||
window('jellyfin.external_check', value="true")
|
||||
window('jellyfin.external_count', value="0")
|
||||
elif count == 120:
|
||||
|
||||
LOG.info("External player detected.")
|
||||
window('emby.external.bool', True)
|
||||
window('emby.external_check.bool', True)
|
||||
window('emby.external_count', value="0")
|
||||
window('jellyfin.external.bool', True)
|
||||
window('jellyfin.external_check.bool', True)
|
||||
window('jellyfin.external_count', value="0")
|
||||
|
||||
elif time == 0:
|
||||
window('emby.external_count', value=str(count + 1))
|
||||
window('jellyfin.external_count', value=str(count + 1))
|
||||
|
|
|
@ -17,7 +17,7 @@ import requests
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -247,7 +247,7 @@ from __objs__ import QU
|
|||
|
||||
##################################################################################################
|
||||
|
||||
log = logging.getLogger("EMBY."+__name__)
|
||||
log = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -278,7 +278,7 @@ class Artwork(object):
|
|||
# This method will sync all Kodi artwork to textures13.db
|
||||
# and cache them locally. This takes diskspace!
|
||||
if not dialog(type_="yesno",
|
||||
heading="{emby}",
|
||||
heading="{jellyfin}",
|
||||
line1=_(33042)):
|
||||
return
|
||||
|
||||
|
@ -288,7 +288,7 @@ class Artwork(object):
|
|||
pdialog.create(_(29999), _(33043))
|
||||
|
||||
# ask to rest all existing or not
|
||||
if dialog(type_="yesno", heading="{emby}", line1=_(33044)):
|
||||
if dialog(type_="yesno", heading="{jellyfin}", line1=_(33044)):
|
||||
log.info("Resetting all cache data first")
|
||||
self.delete_cache()
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ from helper import values
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import queries as QU
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from kodi import Kodi
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from kodi import Kodi
|
|||
|
||||
##################################################################################################
|
||||
|
||||
log = logging.getLogger("EMBY."+__name__)
|
||||
log = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
''' Queries for the Kodi database. obj reflect key/value to retrieve from emby items.
|
||||
''' Queries for the Kodi database. obj reflect key/value to retrieve from jellyfin items.
|
||||
Some functions require additional information, therefore obj do not always reflect
|
||||
the Kodi database query values.
|
||||
'''
|
||||
|
|
|
@ -9,7 +9,7 @@ from kodi import Kodi
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from helper import api, catch, stop, validate, emby_item, library_check, values,
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -320,7 +320,7 @@ class Movies(KodiDb):
|
|||
@emby_item()
|
||||
def remove(self, item_id, e_item):
|
||||
|
||||
''' Remove movieid, fileid, emby reference.
|
||||
''' Remove movieid, fileid, jellyfin reference.
|
||||
Remove artwork, boxset
|
||||
'''
|
||||
obj = {'Id': item_id}
|
||||
|
|
|
@ -14,7 +14,7 @@ from helper import api, catch, stop, validate, emby_item, values, library_check,
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -103,7 +103,7 @@ class Music(KodiDb):
|
|||
|
||||
''' Add object to kodi.
|
||||
|
||||
safety checks: It looks like Emby supports the same artist multiple times.
|
||||
safety checks: It looks like Jellyfin supports the same artist multiple times.
|
||||
Kodi doesn't allow that. In case that happens we just merge the artist entries.
|
||||
'''
|
||||
obj['ArtistId'] = self.get(*values(obj, QU.get_artist_obj))
|
||||
|
@ -203,7 +203,7 @@ class Music(KodiDb):
|
|||
def artist_link(self, obj):
|
||||
|
||||
''' Assign main artists to album.
|
||||
Artist does not exist in emby database, create the reference.
|
||||
Artist does not exist in jellyfin database, create the reference.
|
||||
'''
|
||||
for artist in (obj['AlbumArtists'] or []):
|
||||
|
||||
|
@ -392,7 +392,7 @@ class Music(KodiDb):
|
|||
def song_artist_link(self, obj):
|
||||
|
||||
''' Assign main artists to song.
|
||||
Artist does not exist in emby database, create the reference.
|
||||
Artist does not exist in jellyfin database, create the reference.
|
||||
'''
|
||||
for index, artist in enumerate(obj['ArtistItems'] or []):
|
||||
|
||||
|
@ -533,7 +533,7 @@ class Music(KodiDb):
|
|||
@emby_item()
|
||||
def get_child(self, item_id, e_item):
|
||||
|
||||
''' Get all child elements from tv show emby id.
|
||||
''' Get all child elements from tv show jellyfin id.
|
||||
'''
|
||||
obj = {'Id': item_id}
|
||||
child = []
|
||||
|
|
|
@ -14,7 +14,7 @@ from helper import api, catch, stop, validate, library_check, emby_item, values,
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -51,7 +51,7 @@ class MusicVideos(KodiDb):
|
|||
''' If item does not exist, entry will be added.
|
||||
If item exists, entry will be updated.
|
||||
|
||||
If we don't get the track number from Emby, see if we can infer it
|
||||
If we don't get the track number from Jellyfin, see if we can infer it
|
||||
from the sortname attribute.
|
||||
'''
|
||||
API = api.API(item, self.server['auth/server-address'])
|
||||
|
@ -220,7 +220,7 @@ class MusicVideos(KodiDb):
|
|||
@emby_item()
|
||||
def remove(self, item_id, e_item):
|
||||
|
||||
''' Remove mvideoid, fileid, pathid, emby reference.
|
||||
''' Remove mvideoid, fileid, pathid, jellyfin reference.
|
||||
'''
|
||||
obj = {'Id': item_id}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import os
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -37,7 +37,7 @@ class Objects(object):
|
|||
''' Syntax to traverse the item dictionary.
|
||||
This of the query almost as a url.
|
||||
|
||||
Item is the Emby item json object structure
|
||||
Item is the Jellyfin item json object structure
|
||||
|
||||
",": each element will be used as a fallback until a value is found.
|
||||
"?": split filters and key name from the query part, i.e. MediaSources/0?$Name
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"video": "special://database/MyVideos107.db",
|
||||
"music": "special://database/MyMusic60.db",
|
||||
"texture": "special://database/Textures13.db",
|
||||
"emby": "special://database/emby.db",
|
||||
"jellyfin": "special://database/jellyfin.db",
|
||||
"MovieProviderName": "imdb",
|
||||
"Movie": {
|
||||
"Id": "Id",
|
||||
|
@ -40,7 +40,7 @@
|
|||
"Audio": "MediaSources/0/MediaStreams:?Type=Audio",
|
||||
"Video": "MediaSources/0/MediaStreams:?Type=Video",
|
||||
"Container": "MediaSources/0/Container",
|
||||
"EmbyParentId": "ParentId",
|
||||
"JellyfinParentId": "ParentId",
|
||||
"CriticRating": "CriticRating"
|
||||
},
|
||||
"MovieUserData": {
|
||||
|
@ -77,7 +77,7 @@
|
|||
"Tags": "Tags",
|
||||
"Favorite": "UserData/IsFavorite",
|
||||
"RecursiveCount": "RecursiveItemCount",
|
||||
"EmbyParentId": "ParentId",
|
||||
"JellyfinParentId": "ParentId",
|
||||
"Status": "Status"
|
||||
},
|
||||
"Season": {
|
||||
|
@ -119,7 +119,7 @@
|
|||
"Video": "MediaSources/0/MediaStreams:?Type=Video",
|
||||
"Container": "MediaSources/0/Container",
|
||||
"Location": "LocationType",
|
||||
"EmbyParentId": "SeriesId,ParentId"
|
||||
"JellyfinParentId": "SeriesId,ParentId"
|
||||
},
|
||||
"EpisodeUserData": {
|
||||
"Id": "Id",
|
||||
|
@ -160,7 +160,7 @@
|
|||
"Played": "UserData/Played",
|
||||
"Favorite": "UserData/IsFavorite",
|
||||
"Directors": "People:?Type=Director$Name",
|
||||
"EmbyParentId": "ParentId"
|
||||
"JellyfinParentId": "ParentId"
|
||||
},
|
||||
"MusicVideoUserData": {
|
||||
"Id": "Id",
|
||||
|
@ -178,7 +178,7 @@
|
|||
"UniqueId": "ProviderIds/MusicBrainzArtist",
|
||||
"Genres": "Genres",
|
||||
"Bio": "Overview",
|
||||
"EmbyParentId": "ParentId"
|
||||
"JellyfinParentId": "ParentId"
|
||||
},
|
||||
"Album": {
|
||||
"Id": "Id",
|
||||
|
@ -190,7 +190,7 @@
|
|||
"AlbumArtists": "AlbumArtists",
|
||||
"Artists": "AlbumArtists:?$Name",
|
||||
"ArtistItems": "ArtistItems",
|
||||
"EmbyParentId": "ParentId"
|
||||
"JellyfinParentId": "ParentId"
|
||||
},
|
||||
"Song": {
|
||||
"Id": "Id",
|
||||
|
@ -213,7 +213,7 @@
|
|||
"Album": "Album",
|
||||
"SongAlbumId": "AlbumId",
|
||||
"Container": "MediaSources/0/Container",
|
||||
"EmbyParentId": "ParentId"
|
||||
"JellyfinParentId": "ParentId"
|
||||
},
|
||||
"SongUserData": {
|
||||
"Id": "Id",
|
||||
|
|
|
@ -16,7 +16,7 @@ from helper import api, catch, stop, validate, emby_item, library_check, setting
|
|||
|
||||
##################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -512,7 +512,7 @@ class TVShows(KodiDb):
|
|||
@emby_item()
|
||||
def remove(self, item_id, e_item):
|
||||
|
||||
''' Remove showid, fileid, pathid, emby reference.
|
||||
''' Remove showid, fileid, pathid, jellyfin reference.
|
||||
There's no episodes left, delete show and any possible remaining seasons
|
||||
'''
|
||||
obj = {'Id': item_id}
|
||||
|
@ -614,7 +614,7 @@ class TVShows(KodiDb):
|
|||
@emby_item()
|
||||
def get_child(self, item_id, e_item):
|
||||
|
||||
''' Get all child elements from tv show emby id.
|
||||
''' Get all child elements from tv show jellyfin id.
|
||||
'''
|
||||
obj = {'Id': item_id}
|
||||
child = []
|
||||
|
|
|
@ -8,7 +8,7 @@ from helper import JSONRPC
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ from emby import Emby
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -43,7 +43,7 @@ class Player(xbmc.Player):
|
|||
|
||||
''' We may need to wait for info to be set in kodi monitor.
|
||||
Accounts for scenario where Kodi starts playback and exits immediately.
|
||||
First, ensure previous playback terminated correctly in Emby.
|
||||
First, ensure previous playback terminated correctly in Jellyfin.
|
||||
'''
|
||||
self.stop_playback()
|
||||
self.up_next = False
|
||||
|
@ -69,7 +69,7 @@ class Player(xbmc.Player):
|
|||
|
||||
return
|
||||
|
||||
items = window('emby_play.json')
|
||||
items = window('jellyfin_play.json')
|
||||
item = None
|
||||
|
||||
while not items:
|
||||
|
@ -77,11 +77,11 @@ class Player(xbmc.Player):
|
|||
if monitor.waitForAbort(2):
|
||||
return
|
||||
|
||||
items = window('emby_play.json')
|
||||
items = window('jellyfin_play.json')
|
||||
count += 1
|
||||
|
||||
if count == 20:
|
||||
LOG.info("Could not find emby prop...")
|
||||
LOG.info("Could not find jellyfin prop...")
|
||||
|
||||
return
|
||||
|
||||
|
@ -93,7 +93,7 @@ class Player(xbmc.Player):
|
|||
else:
|
||||
item = items.pop(0)
|
||||
|
||||
window('emby_play.json', items)
|
||||
window('jellyfin_play.json', items)
|
||||
|
||||
self.set_item(current_file, item)
|
||||
data = {
|
||||
|
@ -111,7 +111,7 @@ class Player(xbmc.Player):
|
|||
'SubtitleStreamIndex': item['SubtitleStreamIndex']
|
||||
}
|
||||
item['Server']['api'].session_playing(data)
|
||||
window('emby.skip.%s.bool' % item['Id'], True)
|
||||
window('jellyfin.skip.%s.bool' % item['Id'], True)
|
||||
|
||||
if monitor.waitForAbort(2):
|
||||
return
|
||||
|
@ -302,7 +302,7 @@ class Player(xbmc.Player):
|
|||
|
||||
def report_playback(self, report=True):
|
||||
|
||||
''' Report playback progress to emby server.
|
||||
''' Report playback progress to jellyfin server.
|
||||
Check if the user seek.
|
||||
'''
|
||||
current_file = self.get_playing_file()
|
||||
|
@ -312,7 +312,7 @@ class Player(xbmc.Player):
|
|||
|
||||
item = self.get_file_info(current_file)
|
||||
|
||||
if window('emby.external.bool'):
|
||||
if window('jellyfin.external.bool'):
|
||||
return
|
||||
|
||||
if not report:
|
||||
|
@ -365,7 +365,7 @@ class Player(xbmc.Player):
|
|||
|
||||
''' Will be called when user stops playing a file.
|
||||
'''
|
||||
window('emby_play', clear=True)
|
||||
window('jellyfin_play', clear=True)
|
||||
self.stop_playback()
|
||||
LOG.info("--<[ playback ]")
|
||||
|
||||
|
@ -388,10 +388,10 @@ class Player(xbmc.Player):
|
|||
for file in self.played:
|
||||
item = self.get_file_info(file)
|
||||
|
||||
window('emby.skip.%s.bool' % item['Id'], True)
|
||||
window('jellyfin.skip.%s.bool' % item['Id'], True)
|
||||
|
||||
if window('emby.external.bool'):
|
||||
window('emby.external', clear=True)
|
||||
if window('jellyfin.external.bool'):
|
||||
window('jellyfin.external', clear=True)
|
||||
|
||||
if int(item['CurrentPosition']) == 1:
|
||||
item['CurrentPosition'] = int(item['Runtime'])
|
||||
|
@ -442,6 +442,6 @@ class Player(xbmc.Player):
|
|||
if dialog("yesno", heading=_(30091), line1=_(33015), autoclose=120000):
|
||||
item['Server']['api'].delete_item(item['Id'])
|
||||
|
||||
window('emby.external_check', clear=True)
|
||||
window('jellyfin.external_check', clear=True)
|
||||
|
||||
self.played.clear()
|
||||
|
|
|
@ -10,7 +10,7 @@ from helper import _, settings, dialog, JSONRPC, compare_version
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -42,7 +42,7 @@ class Setup(object):
|
|||
if not self.get_web_server():
|
||||
|
||||
settings('enableTextureCache.bool', False)
|
||||
dialog("ok", heading="{emby}", line1=_(33103))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33103))
|
||||
|
||||
return
|
||||
|
||||
|
@ -105,24 +105,24 @@ class Setup(object):
|
|||
settings('useDirectPaths', value="1" if value else "0")
|
||||
|
||||
if value:
|
||||
dialog("ok", heading="{emby}", line1=_(33145))
|
||||
dialog("ok", heading="{jellyfin}", line1=_(33145))
|
||||
|
||||
def _is_artwork_caching(self):
|
||||
|
||||
value = dialog("yesno", heading="{emby}", line1=_(33117))
|
||||
value = dialog("yesno", heading="{jellyfin}", line1=_(33117))
|
||||
settings('enableTextureCache.bool', value)
|
||||
|
||||
def _is_empty_shows(self):
|
||||
|
||||
value = dialog("yesno", heading="{emby}", line1=_(33100))
|
||||
value = dialog("yesno", heading="{jellyfin}", line1=_(33100))
|
||||
settings('syncEmptyShows.bool', value)
|
||||
|
||||
def _is_rotten_tomatoes(self):
|
||||
|
||||
value = dialog("yesno", heading="{emby}", line1=_(33188))
|
||||
value = dialog("yesno", heading="{jellyfin}", line1=_(33188))
|
||||
settings('syncRottenTomatoes.bool', value)
|
||||
|
||||
def _is_music(self):
|
||||
|
||||
value = dialog("yesno", heading="{emby}", line1=_(33039))
|
||||
value = dialog("yesno", heading="{jellyfin}", line1=_(33039))
|
||||
settings('enableMusic.bool', value=value)
|
||||
|
|
|
@ -19,7 +19,7 @@ from emby import Emby
|
|||
|
||||
#################################################################################################
|
||||
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
NODES = {
|
||||
'tvshows': [
|
||||
('all', None),
|
||||
|
@ -148,16 +148,16 @@ class Views(object):
|
|||
|
||||
def add_library(self, view):
|
||||
|
||||
''' Add entry to view table in emby database.
|
||||
''' Add entry to view table in jellyfin database.
|
||||
'''
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
emby_db.EmbyDatabase(embydb.cursor).add_view(view['Id'], view['Name'], view['Media'])
|
||||
|
||||
def remove_library(self, view_id):
|
||||
|
||||
''' Remove entry from view table in emby database.
|
||||
''' Remove entry from view table in jellyfin database.
|
||||
'''
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
emby_db.EmbyDatabase(embydb.cursor).remove_view(view_id)
|
||||
|
||||
self.delete_playlist_by_id(view_id)
|
||||
|
@ -203,7 +203,7 @@ class Views(object):
|
|||
|
||||
self.add_library(library)
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
|
||||
views = emby_db.EmbyDatabase(embydb.cursor).get_views()
|
||||
removed = []
|
||||
|
@ -226,7 +226,7 @@ class Views(object):
|
|||
playlist_path = xbmc.translatePath("special://profile/playlists/video").decode('utf-8')
|
||||
index = 0
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
db = emby_db.EmbyDatabase(embydb.cursor)
|
||||
|
||||
for library in self.sync['Whitelist']:
|
||||
|
@ -268,7 +268,7 @@ class Views(object):
|
|||
|
||||
''' Create or update the xps file.
|
||||
'''
|
||||
file = os.path.join(path, "emby%s%s.xsp" % (view['Media'], view['Id']))
|
||||
file = os.path.join(path, "jellyfin%s%s.xsp" % (view['Media'], view['Id']))
|
||||
|
||||
try:
|
||||
xml = etree.parse(file).getroot()
|
||||
|
@ -297,7 +297,7 @@ class Views(object):
|
|||
|
||||
''' Create or update the video node file.
|
||||
'''
|
||||
folder = os.path.join(path, "emby%s%s" % (view['Media'], view['Id']))
|
||||
folder = os.path.join(path, "jellyfin%s%s" % (view['Media'], view['Id']))
|
||||
|
||||
if not xbmcvfs.exists(folder):
|
||||
xbmcvfs.mkdir(folder)
|
||||
|
@ -311,7 +311,7 @@ class Views(object):
|
|||
|
||||
def add_single_node(self, path, index, item_type, view):
|
||||
|
||||
file = os.path.join(path, "emby_%s.xml" % view['Tag'].replace(" ", ""))
|
||||
file = os.path.join(path, "jellyfin_%s.xml" % view['Tag'].replace(" ", ""))
|
||||
|
||||
try:
|
||||
xml = etree.parse(file).getroot()
|
||||
|
@ -657,7 +657,7 @@ class Views(object):
|
|||
|
||||
def order_media_folders(self, folders):
|
||||
|
||||
''' Returns a list of sorted media folders based on the Emby views.
|
||||
''' Returns a list of sorted media folders based on the Jellyfin views.
|
||||
Insert them in SortedViews and remove Views that are not in media folders.
|
||||
'''
|
||||
if not folders:
|
||||
|
@ -677,12 +677,12 @@ class Views(object):
|
|||
def window_nodes(self):
|
||||
|
||||
''' Just read from the database and populate based on SortedViews
|
||||
Setup the window properties that reflect the emby server views and more.
|
||||
Setup the window properties that reflect the jellyfin server views and more.
|
||||
'''
|
||||
self.window_clear()
|
||||
self.window_clear('Emby.wnodes')
|
||||
self.window_clear('Jellyfin.wnodes')
|
||||
|
||||
with Database('emby') as embydb:
|
||||
with Database('jellyfin') as embydb:
|
||||
libraries = emby_db.EmbyDatabase(embydb.cursor).get_views()
|
||||
|
||||
libraries = self.order_media_folders(libraries or [])
|
||||
|
@ -743,8 +743,8 @@ class Views(object):
|
|||
self.window_single_node(index, "favorites", single)
|
||||
index += 1
|
||||
|
||||
window('Emby.nodes.total', str(index))
|
||||
window('Emby.wnodes.total', str(windex))
|
||||
window('Jellyfin.nodes.total', str(index))
|
||||
window('Jellyfin.wnodes.total', str(windex))
|
||||
|
||||
def window_node(self, index, view, node=None, node_label=None):
|
||||
|
||||
|
@ -773,17 +773,17 @@ class Views(object):
|
|||
|
||||
if node in ('all', 'music'):
|
||||
|
||||
window_prop = "Emby.nodes.%s" % index
|
||||
window_prop = "Jellyfin.nodes.%s" % index
|
||||
window('%s.index' % window_prop, path.replace('all.xml', "")) # dir
|
||||
window('%s.title' % window_prop, view['Name'].encode('utf-8'))
|
||||
window('%s.content' % window_prop, path)
|
||||
|
||||
elif node == 'browse':
|
||||
|
||||
window_prop = "Emby.nodes.%s" % index
|
||||
window_prop = "Jellyfin.nodes.%s" % index
|
||||
window('%s.title' % window_prop, view['Name'].encode('utf-8'))
|
||||
else:
|
||||
window_prop = "Emby.nodes.%s.%s" % (index, node)
|
||||
window_prop = "Jellyfin.nodes.%s.%s" % (index, node)
|
||||
window('%s.title' % window_prop, node_label.encode('utf-8'))
|
||||
window('%s.content' % window_prop, path)
|
||||
|
||||
|
@ -796,10 +796,10 @@ class Views(object):
|
|||
|
||||
''' Single destination node.
|
||||
'''
|
||||
path = "library://video/emby_%s.xml" % view['Tag'].replace(" ", "")
|
||||
path = "library://video/jellyfin_%s.xml" % view['Tag'].replace(" ", "")
|
||||
window_path = "ActivateWindow(Videos,%s,return)" % path
|
||||
|
||||
window_prop = "Emby.nodes.%s" % index
|
||||
window_prop = "Jellyfin.nodes.%s" % index
|
||||
window('%s.title' % window_prop, view['Name'])
|
||||
window('%s.path' % window_prop, window_path)
|
||||
window('%s.content' % window_prop, path)
|
||||
|
@ -825,18 +825,18 @@ class Views(object):
|
|||
|
||||
if node == 'all':
|
||||
|
||||
window_prop = "Emby.wnodes.%s" % index
|
||||
window_prop = "Jellyfin.wnodes.%s" % index
|
||||
window('%s.index' % window_prop, path.replace('all.xml', "")) # dir
|
||||
window('%s.title' % window_prop, view['Name'].encode('utf-8'))
|
||||
window('%s.content' % window_prop, path)
|
||||
|
||||
elif node == 'browse':
|
||||
|
||||
window_prop = "Emby.wnodes.%s" % index
|
||||
window_prop = "Jellyfin.wnodes.%s" % index
|
||||
window('%s.title' % window_prop, view['Name'].encode('utf-8'))
|
||||
window('%s.content' % window_prop, path)
|
||||
else:
|
||||
window_prop = "Emby.wnodes.%s.%s" % (index, node)
|
||||
window_prop = "Jellyfin.wnodes.%s.%s" % (index, node)
|
||||
window('%s.title' % window_prop, node_label.encode('utf-8'))
|
||||
window('%s.content' % window_prop, path)
|
||||
|
||||
|
@ -865,7 +865,7 @@ class Views(object):
|
|||
window('%s.artwork' % prop, clear=True)
|
||||
|
||||
def window_path(self, view, node):
|
||||
return "library://video/emby%s%s/%s.xml" % (view['Media'], view['Id'], node)
|
||||
return "library://video/jellyfin%s%s/%s.xml" % (view['Media'], view['Id'], node)
|
||||
|
||||
def window_music(self, view):
|
||||
return "library://music/"
|
||||
|
@ -898,7 +898,7 @@ class Views(object):
|
|||
|
||||
''' Clearing window prop setup for Views.
|
||||
'''
|
||||
total = int(window((name or 'Emby.nodes') + '.total') or 0)
|
||||
total = int(window((name or 'Jellyfin.nodes') + '.total') or 0)
|
||||
props = [
|
||||
|
||||
"index","id","path","artwork","title","content","type"
|
||||
|
@ -914,10 +914,10 @@ class Views(object):
|
|||
]
|
||||
for i in range(total):
|
||||
for prop in props:
|
||||
window('Emby.nodes.%s.%s' % (str(i), prop), clear=True)
|
||||
window('Jellyfin.nodes.%s.%s' % (str(i), prop), clear=True)
|
||||
|
||||
for prop in props:
|
||||
window('Emby.nodes.%s' % prop, clear=True)
|
||||
window('Jellyfin.nodes.%s' % prop, clear=True)
|
||||
|
||||
def delete_playlist(self, path):
|
||||
|
||||
|
@ -926,12 +926,12 @@ class Views(object):
|
|||
|
||||
def delete_playlists(self):
|
||||
|
||||
''' Remove all emby playlists.
|
||||
''' Remove all jellyfin playlists.
|
||||
'''
|
||||
path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8')
|
||||
_, files = xbmcvfs.listdir(path)
|
||||
for file in files:
|
||||
if file.decode('utf-8').startswith('emby'):
|
||||
if file.decode('utf-8').startswith('jellyfin'):
|
||||
self.delete_playlist(os.path.join(path, file.decode('utf-8')))
|
||||
|
||||
def delete_playlist_by_id(self, view_id):
|
||||
|
@ -943,7 +943,7 @@ class Views(object):
|
|||
for file in files:
|
||||
file = file.decode('utf-8')
|
||||
|
||||
if file.startswith('emby') and file.endswith('%s.xsp' % view_id):
|
||||
if file.startswith('jellyfin') and file.endswith('%s.xsp' % view_id):
|
||||
self.delete_playlist(os.path.join(path, file.decode('utf-8')))
|
||||
|
||||
def delete_node(self, path):
|
||||
|
@ -960,12 +960,12 @@ class Views(object):
|
|||
|
||||
for file in files:
|
||||
|
||||
if file.startswith('emby'):
|
||||
if file.startswith('jellyfin'):
|
||||
self.delete_node(os.path.join(path, file.decode('utf-8')))
|
||||
|
||||
for directory in dirs:
|
||||
|
||||
if directory.startswith('emby'):
|
||||
if directory.startswith('jellyfin'):
|
||||
_, files = xbmcvfs.listdir(os.path.join(path, directory.decode('utf-8')))
|
||||
|
||||
for file in files:
|
||||
|
@ -982,7 +982,7 @@ class Views(object):
|
|||
|
||||
for directory in dirs:
|
||||
|
||||
if directory.startswith('emby') and directory.endswith(view_id):
|
||||
if directory.startswith('jellyfin') and directory.endswith(view_id):
|
||||
_, files = xbmcvfs.listdir(os.path.join(path, directory.decode('utf-8')))
|
||||
|
||||
for file in files:
|
||||
|
|
|
@ -13,7 +13,7 @@ import xbmc
|
|||
#################################################################################################
|
||||
|
||||
PORT = 57578
|
||||
LOG = logging.getLogger("EMBY."+__name__)
|
||||
LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue