Most flake8 warnings corrected

This commit is contained in:
Odd Stråbø 2019-10-03 04:14:54 +02:00
parent e92d60f7c7
commit 00765c0a12
58 changed files with 1144 additions and 1262 deletions

View file

@ -19,15 +19,18 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
################################################################################################## ##################################################################################################
def get_addon_name(): def get_addon_name():
''' Used for logging. ''' Used for logging.
''' '''
return xbmcaddon.Addon(addon_id()).getAddonInfo('name').upper() return xbmcaddon.Addon(addon_id()).getAddonInfo('name').upper()
def get_version(): def get_version():
return xbmcaddon.Addon(addon_id()).getAddonInfo('version') return xbmcaddon.Addon(addon_id()).getAddonInfo('version')
def get_platform(): def get_platform():
if xbmc.getCondVisibility('system.platform.osx'): if xbmc.getCondVisibility('system.platform.osx'):
@ -53,6 +56,7 @@ def get_platform():
else: else:
return "Unknown" return "Unknown"
def get_device_name(): def get_device_name():
''' Detect the device name. If deviceNameOpt, then ''' Detect the device name. If deviceNameOpt, then
@ -68,6 +72,7 @@ def get_device_name():
return device_name return device_name
def get_device_id(reset=False): def get_device_id(reset=False):
''' Return the device_id if already loaded. ''' Return the device_id if already loaded.
@ -105,6 +110,7 @@ def get_device_id(reset=False):
return client_id return client_id
def reset_device_id(): def reset_device_id():
window('jellyfin_deviceId', clear=True) window('jellyfin_deviceId', clear=True)
@ -112,6 +118,7 @@ def reset_device_id():
dialog("ok", heading="{jellyfin}", line1=_(33033)) dialog("ok", heading="{jellyfin}", line1=_(33033))
xbmc.executebuiltin('RestartApp') xbmc.executebuiltin('RestartApp')
def get_info(): def get_info():
return { return {
'DeviceName': get_device_name(), 'DeviceName': get_device_name(),

View file

@ -115,8 +115,7 @@ class Connect(object):
return state['Credentials'] return state['Credentials']
elif (server_selection or state['State'] == CONNECTION_STATE['ServerSelection'] or elif (server_selection or state['State'] == CONNECTION_STATE['ServerSelection'] or state['State'] == CONNECTION_STATE['Unavailable'] and not settings('SyncInstallRunDone.bool')):
state['State'] == CONNECTION_STATE['Unavailable'] and not settings('SyncInstallRunDone.bool')):
self.select_servers(state) self.select_servers(state)
@ -143,7 +142,6 @@ class Connect(object):
return client.get_credentials() return client.get_credentials()
def get_user(self, client): def get_user(self, client):
''' Save user info. ''' Save user info.
@ -178,7 +176,8 @@ class Connect(object):
LOG.debug("Adding manual server") LOG.debug("Adding manual server")
try: try:
self.manual_server() self.manual_server()
except RuntimeError: pass except RuntimeError:
pass
else: else:
raise RuntimeError("No server selected") raise RuntimeError("No server selected")
@ -237,14 +236,16 @@ class Connect(object):
LOG.debug("User has password, present manual login") LOG.debug("User has password, present manual login")
try: try:
return self.login_manual(username) return self.login_manual(username)
except RuntimeError: pass except RuntimeError:
pass
else: else:
return self.connect_manager.login(server, username) return self.connect_manager.login(server, username)
elif dialog.is_manual_login(): elif dialog.is_manual_login():
try: try:
return self.login_manual() return self.login_manual()
except RuntimeError: pass except RuntimeError:
pass
else: else:
raise RuntimeError("No user selected") raise RuntimeError("No user selected")
@ -294,4 +295,3 @@ class Connect(object):
save_credentials(credentials) save_credentials(credentials)
LOG.info("[ remove server ] %s", server_id) LOG.info("[ remove server ] %s", server_id)

View file

@ -105,8 +105,7 @@ class Database(object):
for file in reversed(files): for file in reversed(files):
if (file.startswith(database) and not file.endswith('-wal') and if (file.startswith(database) and not file.endswith('-wal') and not file.endswith('-shm') and not file.endswith('db-journal')):
not file.endswith('-shm') and not file.endswith('db-journal')):
st = xbmcvfs.Stat(databases + file.decode('utf-8')) st = xbmcvfs.Stat(databases + file.decode('utf-8'))
modified_int = st.st_mtime() modified_int = st.st_mtime()
@ -184,6 +183,7 @@ class Database(object):
self.cursor.close() self.cursor.close()
self.conn.close() self.conn.close()
def jellyfin_tables(cursor): def jellyfin_tables(cursor):
''' Create the tables for the jellyfin database. ''' Create the tables for the jellyfin database.
@ -205,6 +205,7 @@ def jellyfin_tables(cursor):
LOG.info("Add missing column jellyfin_parent_id") LOG.info("Add missing column jellyfin_parent_id")
cursor.execute("ALTER TABLE jellyfin ADD COLUMN jellyfin_parent_id 'TEXT'") cursor.execute("ALTER TABLE jellyfin ADD COLUMN jellyfin_parent_id 'TEXT'")
def reset(): def reset():
''' Reset both the jellyfin database and the kodi database. ''' Reset both the jellyfin database and the kodi database.
@ -257,6 +258,7 @@ def reset():
dialog("ok", heading="{jellyfin}", line1=_(33088)) dialog("ok", heading="{jellyfin}", line1=_(33088))
xbmc.executebuiltin('RestartApp') xbmc.executebuiltin('RestartApp')
def reset_kodi(): def reset_kodi():
with Database() as videodb: with Database() as videodb:
@ -281,6 +283,7 @@ def reset_kodi():
LOG.info("[ reset kodi ]") LOG.info("[ reset kodi ]")
def reset_jellyfin(): def reset_jellyfin():
with Database('jellyfin') as jellyfindb: with Database('jellyfin') as jellyfindb:
@ -298,6 +301,7 @@ def reset_jellyfin():
LOG.info("[ reset jellyfin ]") LOG.info("[ reset jellyfin ]")
def reset_artwork(): def reset_artwork():
''' Remove all existing texture. ''' Remove all existing texture.
@ -325,6 +329,7 @@ def reset_artwork():
LOG.info("[ reset artwork ]") LOG.info("[ reset artwork ]")
def get_sync(): def get_sync():
path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8') path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8')
@ -345,6 +350,7 @@ def get_sync():
return sync return sync
def save_sync(sync): def save_sync(sync):
path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8') path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8')
@ -358,6 +364,7 @@ def save_sync(sync):
data = json.dumps(sync, sort_keys=True, indent=4, ensure_ascii=False) data = json.dumps(sync, sort_keys=True, indent=4, ensure_ascii=False)
outfile.write(unicode(data)) outfile.write(unicode(data))
def get_credentials(): def get_credentials():
path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8') path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8')
@ -383,6 +390,7 @@ def get_credentials():
return credentials return credentials
def save_credentials(credentials): def save_credentials(credentials):
credentials = credentials or {} credentials = credentials or {}
path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8') path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/").decode('utf-8')
@ -396,6 +404,7 @@ def save_credentials(credentials):
except Exception as e: except Exception as e:
LOG.error("Failed to save credentials: {}".format(e)) LOG.error("Failed to save credentials: {}".format(e))
def get_item(kodi_id, media): def get_item(kodi_id, media):
''' Get jellyfin item based on kodi id and media. ''' Get jellyfin item based on kodi id and media.
@ -409,4 +418,3 @@ def get_item(kodi_id, media):
return return
return item return item

View file

@ -4,19 +4,15 @@ get_item = """ SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id
FROM jellyfin FROM jellyfin
WHERE jellyfin_id = ? WHERE jellyfin_id = ?
""" """
get_item_obj = [ "{Id}" get_item_obj = ["{Id}"]
] get_item_series_obj = ["{SeriesId}"]
get_item_series_obj = [ "{SeriesId}" get_item_song_obj = ["{SongAlbumId}"]
]
get_item_song_obj = [ "{SongAlbumId}"
]
get_item_id_by_parent = """ SELECT jellyfin_id, kodi_id get_item_id_by_parent = """ SELECT jellyfin_id, kodi_id
FROM jellyfin FROM jellyfin
WHERE parent_id = ? WHERE parent_id = ?
AND media_type = ? AND media_type = ?
""" """
get_item_id_by_parent_boxset_obj = [ "{SetId}","movie" get_item_id_by_parent_boxset_obj = ["{SetId}", "movie"]
]
get_item_by_parent = """ SELECT jellyfin_id, kodi_id, kodi_fileid get_item_by_parent = """ SELECT jellyfin_id, kodi_id, kodi_fileid
FROM jellyfin FROM jellyfin
WHERE parent_id = ? WHERE parent_id = ?
@ -26,24 +22,17 @@ get_item_by_media_folder = """ SELECT jellyfin_id, jellyfin_type
FROM jellyfin FROM jellyfin
WHERE media_folder = ? WHERE media_folder = ?
""" """
get_item_by_parent_movie_obj = [ "{KodiId}","movie" get_item_by_parent_movie_obj = ["{KodiId}", "movie"]
] get_item_by_parent_tvshow_obj = ["{ParentId}", "tvshow"]
get_item_by_parent_tvshow_obj = [ "{ParentId}","tvshow" get_item_by_parent_season_obj = ["{ParentId}", "season"]
] get_item_by_parent_episode_obj = ["{ParentId}", "episode"]
get_item_by_parent_season_obj = [ "{ParentId}","season" get_item_by_parent_album_obj = ["{ParentId}", "album"]
] get_item_by_parent_song_obj = ["{ParentId}", "song"]
get_item_by_parent_episode_obj = [ "{ParentId}","episode"
]
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 get_item_by_wild = """ SELECT kodi_id, media_type
FROM jellyfin FROM jellyfin
WHERE jellyfin_id LIKE ? WHERE jellyfin_id LIKE ?
""" """
get_item_by_wild_obj = [ "{Id}" get_item_by_wild_obj = ["{Id}"]
]
get_item_by_kodi = """ SELECT jellyfin_id, parent_id, media_folder, jellyfin_type, checksum get_item_by_kodi = """ SELECT jellyfin_id, parent_id, media_folder, jellyfin_type, checksum
FROM jellyfin FROM jellyfin
WHERE kodi_id = ? WHERE kodi_id = ?
@ -85,37 +74,20 @@ get_version = """ SELECT idVersion
""" """
add_reference = """ INSERT OR REPLACE INTO jellyfin(jellyfin_id, kodi_id, kodi_fileid, kodi_pathid, jellyfin_type, 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) media_type, parent_id, checksum, media_folder, jellyfin_parent_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""" """
add_reference_movie_obj = [ "{Id}","{MovieId}","{FileId}","{PathId}","Movie","movie", None,"{Checksum}","{LibraryId}", add_reference_movie_obj = ["{Id}", "{MovieId}", "{FileId}", "{PathId}", "Movie", "movie", None, "{Checksum}", "{LibraryId}", "{JellyfinParentId}"]
"{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}", "{JellyfinParentId}"]
add_reference_boxset_obj = [ "{Id}","{SetId}",None,None,"BoxSet","set",None,"{Checksum}",None,None 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_tvshow_obj = [ "{Id}","{ShowId}",None,"{PathId}","Series","tvshow",None,"{Checksum}","{LibraryId}", add_reference_episode_obj = ["{Id}", "{EpisodeId}", "{FileId}", "{PathId}", "Episode", "episode", "{SeasonId}", "{Checksum}", None, "{JellyfinParentId}"]
"{JellyfinParentId}" add_reference_mvideo_obj = ["{Id}", "{MvideoId}", "{FileId}", "{PathId}", "MusicVideo", "musicvideo", None, "{Checksum}", "{LibraryId}", "{JellyfinParentId}"]
] add_reference_artist_obj = ["{Id}", "{ArtistId}", None, None, "{ArtistType}", "artist", None, "{Checksum}", "{LibraryId}", "{JellyfinParentId}"]
add_reference_season_obj = [ "{Id}","{SeasonId}",None,None,"Season","season","{ShowId}",None,None,None 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, "{JellyfinParentId}"]
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,"{JellyfinParentId}"
]
add_reference_mvideo_obj = [ "{Id}","{MvideoId}","{FileId}","{PathId}","MusicVideo","musicvideo",None,"{Checksum}",
"{LibraryId}","{JellyfinParentId}"
]
add_reference_artist_obj = [ "{Id}","{ArtistId}",None,None,"{ArtistType}","artist",None,"{Checksum}","{LibraryId}",
"{JellyfinParentId}"
]
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,"{JellyfinParentId}"
]
add_view = """ INSERT OR REPLACE INTO view(view_id, view_name, media_type) add_view = """ INSERT OR REPLACE INTO view(view_id, view_name, media_type)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
@ -128,41 +100,30 @@ update_reference = """ UPDATE jellyfin
SET checksum = ? SET checksum = ?
WHERE jellyfin_id = ? WHERE jellyfin_id = ?
""" """
update_reference_obj = [ "{Checksum}", "{Id}" update_reference_obj = ["{Checksum}", "{Id}"]
]
update_parent = """ UPDATE jellyfin update_parent = """ UPDATE jellyfin
SET parent_id = ? SET parent_id = ?
WHERE jellyfin_id = ? WHERE jellyfin_id = ?
""" """
update_parent_movie_obj = [ "{SetId}","{Id}" update_parent_movie_obj = ["{SetId}", "{Id}"]
] update_parent_episode_obj = ["{SeasonId}", "{Id}"]
update_parent_episode_obj = [ "{SeasonId}","{Id}"
]
update_parent_album_obj = ["{ArtistId}", "{AlbumId}"] update_parent_album_obj = ["{ArtistId}", "{AlbumId}"]
delete_item = """ DELETE FROM jellyfin delete_item = """ DELETE FROM jellyfin
WHERE jellyfin_id = ? WHERE jellyfin_id = ?
""" """
delete_item_obj = [ "{Id}" delete_item_obj = ["{Id}"]
]
delete_item_by_parent = """ DELETE FROM jellyfin delete_item_by_parent = """ DELETE FROM jellyfin
WHERE parent_id = ? WHERE parent_id = ?
AND media_type = ? AND media_type = ?
""" """
delete_item_by_parent_tvshow_obj = [ "{ParentId}","tvshow" delete_item_by_parent_tvshow_obj = ["{ParentId}", "tvshow"]
] delete_item_by_parent_season_obj = ["{ParentId}", "season"]
delete_item_by_parent_season_obj = [ "{ParentId}","season" delete_item_by_parent_episode_obj = ["{ParentId}", "episode"]
] delete_item_by_parent_song_obj = ["{ParentId}", "song"]
delete_item_by_parent_episode_obj = [ "{ParentId}","episode" delete_item_by_parent_artist_obj = ["{ParentId}", "artist"]
] delete_item_by_parent_album_obj = ["{KodiId}", "album"]
delete_item_by_parent_song_obj = [ "{ParentId}","song"
]
delete_item_by_parent_artist_obj = [ "{ParentId}","artist"
]
delete_item_by_parent_album_obj = [ "{KodiId}","album"
]
delete_item_by_kodi = """ DELETE FROM jellyfin delete_item_by_kodi = """ DELETE FROM jellyfin
WHERE kodi_id = ? WHERE kodi_id = ?
AND media_type = ? AND media_type = ?
@ -173,8 +134,7 @@ delete_item_by_wild = """ DELETE FROM jellyfin
delete_view = """ DELETE FROM view delete_view = """ DELETE FROM view
WHERE view_id = ? WHERE view_id = ?
""" """
delete_parent_boxset_obj = [ None, "{Movie}" delete_parent_boxset_obj = [None, "{Movie}"]
]
delete_media_by_parent_id = """ DELETE FROM jellyfin delete_media_by_parent_id = """ DELETE FROM jellyfin
WHERE jellyfin_parent_id = ? WHERE jellyfin_parent_id = ?
""" """

View file

@ -29,7 +29,6 @@ class ContextMenu(xbmcgui.WindowXMLDialog):
_options = [] _options = []
selected_option = None selected_option = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs) xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)

View file

@ -31,7 +31,6 @@ class LoginManual(xbmcgui.WindowXMLDialog):
error = None error = None
username = None username = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs) xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)

View file

@ -38,7 +38,6 @@ class ServerConnect(xbmcgui.WindowXMLDialog):
_connect_login = False _connect_login = False
_manual_server = False _manual_server = False
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs) xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)

View file

@ -34,7 +34,6 @@ class ServerManual(xbmcgui.WindowXMLDialog):
_server = None _server = None
error = None error = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs) xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)

View file

@ -27,7 +27,6 @@ class UsersConnect(xbmcgui.WindowXMLDialog):
_user = None _user = None
_manual_login = False _manual_login = False
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.kodi_version = int(xbmc.getInfoLabel('System.BuildVersion')[:2]) self.kodi_version = int(xbmc.getInfoLabel('System.BuildVersion')[:2])

View file

@ -42,6 +42,7 @@ def _http(action, url, request={}, server_id=None):
request.update({'url': url, 'type': action}) request.update({'url': url, 'type': action})
return Jellyfin(server_id).http.request(request) return Jellyfin(server_id).http.request(request)
def _get(handler, params=None, server_id=None): def _get(handler, params=None, server_id=None):
return _http("GET", get_jellyfinserver_url(handler), {'params': params}, server_id) return _http("GET", get_jellyfinserver_url(handler), {'params': params}, server_id)

View file

@ -8,7 +8,6 @@ import sys
import urlparse import urlparse
import urllib import urllib
import os import os
import sys
import xbmc import xbmc
import xbmcvfs import xbmcvfs
@ -31,7 +30,6 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
class Events(object): class Events(object):
def __init__(self): def __init__(self):
''' Parse the parameters. Reroute to our service.py ''' Parse the parameters. Reroute to our service.py
@ -180,7 +178,6 @@ def listing():
else: else:
directory(server['Name'], "plugin://plugin.video.jellyfin/?mode=browse&server=%s" % server['Id'], context=context) directory(server['Name'], "plugin://plugin.video.jellyfin/?mode=browse&server=%s" % server['Id'], context=context)
directory(_(33194), "plugin://plugin.video.jellyfin/?mode=managelibs", True) directory(_(33194), "plugin://plugin.video.jellyfin/?mode=managelibs", True)
directory(_(33134), "plugin://plugin.video.jellyfin/?mode=addserver", False) directory(_(33134), "plugin://plugin.video.jellyfin/?mode=addserver", False)
directory(_(33054), "plugin://plugin.video.jellyfin/?mode=adduser", False) directory(_(33054), "plugin://plugin.video.jellyfin/?mode=adduser", False)
@ -194,6 +191,7 @@ def listing():
xbmcplugin.setContent(int(sys.argv[1]), 'files') xbmcplugin.setContent(int(sys.argv[1]), 'files')
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def directory(label, path, folder=True, artwork=None, fanart=None, context=None): def directory(label, path, folder=True, artwork=None, fanart=None, context=None):
''' Add directory listitem. context should be a list of tuples [(label, action)*] ''' Add directory listitem. context should be a list of tuples [(label, action)*]
@ -207,6 +205,7 @@ def directory(label, path, folder=True, artwork=None, fanart=None, context=None)
return li return li
def dir_listitem(label, path, artwork=None, fanart=None): def dir_listitem(label, path, artwork=None, fanart=None):
''' Gets the icon paths for default node listings ''' Gets the icon paths for default node listings
@ -218,6 +217,7 @@ def dir_listitem(label, path, artwork=None, fanart=None):
return li return li
def manage_libraries(): def manage_libraries():
directory(_(33098), "plugin://plugin.video.jellyfin/?mode=refreshboxsets", False) directory(_(33098), "plugin://plugin.video.jellyfin/?mode=refreshboxsets", False)
@ -230,6 +230,7 @@ def manage_libraries():
xbmcplugin.setContent(int(sys.argv[1]), 'files') xbmcplugin.setContent(int(sys.argv[1]), 'files')
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def browse(media, view_id=None, folder=None, server_id=None): def browse(media, view_id=None, folder=None, server_id=None):
''' Browse content dynamically. ''' Browse content dynamically.
@ -274,7 +275,6 @@ def browse(media, view_id=None, folder=None, server_id=None):
elif media == 'music': elif media == 'music':
content_type = "artists" content_type = "artists"
if folder == 'recentlyadded': if folder == 'recentlyadded':
listing = TheVoid('RecentlyAdded', {'Id': view_id, 'ServerId': server_id}).get() listing = TheVoid('RecentlyAdded', {'Id': view_id, 'ServerId': server_id}).get()
elif folder == 'genres': elif folder == 'genres':
@ -316,7 +316,6 @@ def browse(media, view_id=None, folder=None, server_id=None):
else: else:
listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': False}).get() listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': False}).get()
if listing: if listing:
actions = Actions(server_id) actions = Actions(server_id)
@ -396,6 +395,7 @@ def browse(media, view_id=None, folder=None, server_id=None):
xbmcplugin.setContent(int(sys.argv[1]), content_type) xbmcplugin.setContent(int(sys.argv[1]), content_type)
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def browse_subfolders(media, view_id, server_id=None): def browse_subfolders(media, view_id, server_id=None):
''' Display submenus for jellyfin views. ''' Display submenus for jellyfin views.
@ -421,6 +421,7 @@ def browse_subfolders(media, view_id, server_id=None):
xbmcplugin.setContent(int(sys.argv[1]), 'files') xbmcplugin.setContent(int(sys.argv[1]), 'files')
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def browse_letters(media, view_id, server_id=None): def browse_letters(media, view_id, server_id=None):
''' Display letters as options. ''' Display letters as options.
@ -445,6 +446,7 @@ def browse_letters(media, view_id, server_id=None):
xbmcplugin.setContent(int(sys.argv[1]), 'files') xbmcplugin.setContent(int(sys.argv[1]), 'files')
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def get_folder_type(item, content_type=None): def get_folder_type(item, content_type=None):
media = item['Type'] media = item['Type']
@ -480,6 +482,7 @@ def get_media_type(media):
elif media == 'music': elif media == 'music':
return "MusicArtist,MusicAlbum,Audio" return "MusicArtist,MusicAlbum,Audio"
def get_fanart(item_id, path, server_id=None): def get_fanart(item_id, path, server_id=None):
''' Get extra fanart for listitems. This is called by skinhelper. ''' Get extra fanart for listitems. This is called by skinhelper.
@ -524,6 +527,7 @@ def get_fanart(item_id, path, server_id=None):
xbmcplugin.addDirectoryItems(int(sys.argv[1]), list_li, len(list_li)) xbmcplugin.addDirectoryItems(int(sys.argv[1]), list_li, len(list_li))
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def get_video_extras(item_id, path, server_id=None): def get_video_extras(item_id, path, server_id=None):
''' Returns the video files for the item as plugin listing, can be used ''' Returns the video files for the item as plugin listing, can be used
@ -565,6 +569,7 @@ def get_video_extras(item_id, path, server_id=None):
#xbmcplugin.endOfDirectory(int(sys.argv[1])) #xbmcplugin.endOfDirectory(int(sys.argv[1]))
""" """
def get_next_episodes(item_id, limit): def get_next_episodes(item_id, limit):
''' Only for synced content. ''' Only for synced content.
@ -645,6 +650,7 @@ def get_next_episodes(item_id, limit):
xbmcplugin.setContent(int(sys.argv[1]), 'episodes') xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def create_listitem(item): def create_listitem(item):
''' Listitem based on jsonrpc items. ''' Listitem based on jsonrpc items.
@ -722,6 +728,7 @@ def create_listitem(item):
return li return li
def add_user(): def add_user():
''' Add or remove users from the default server session. ''' Add or remove users from the default server session.
@ -756,6 +763,7 @@ def add_user():
user = current[resp] user = current[resp]
event('AddUser', {'Id': user['UserId'], 'Add': False}) event('AddUser', {'Id': user['UserId'], 'Add': False})
def get_themes(): def get_themes():
''' Add theme media locally, via strm. This is only for tv tunes. ''' Add theme media locally, via strm. This is only for tv tunes.
@ -786,7 +794,6 @@ def get_themes():
all_views = jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_views() all_views = jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_views()
views = [x[0] for x in all_views if x[2] in ('movies', 'tvshows', 'mixed')] views = [x[0] for x in all_views if x[2] in ('movies', 'tvshows', 'mixed')]
items = {} items = {}
server = TheVoid('GetServerAddress', {'ServerId': None}).get() server = TheVoid('GetServerAddress', {'ServerId': None}).get()
token = TheVoid('GetToken', {'ServerId': None}).get() token = TheVoid('GetToken', {'ServerId': None}).get()
@ -829,6 +836,7 @@ def get_themes():
dialog("notification", heading="{jellyfin}", message=_(33153), icon="{jellyfin}", time=1000, sound=False) dialog("notification", heading="{jellyfin}", message=_(33153), icon="{jellyfin}", time=1000, sound=False)
def delete_item(): def delete_item():
''' Delete keymap action. ''' Delete keymap action.
@ -837,6 +845,7 @@ def delete_item():
context.Context(delete=True) context.Context(delete=True)
def backup(): def backup():
''' Jellyfin backup. ''' Jellyfin backup.

View file

@ -38,7 +38,6 @@ class Service(xbmc.Monitor):
warn = True warn = True
settings = {'last_progress': datetime.today(), 'last_progress_report': datetime.today()} settings = {'last_progress': datetime.today(), 'last_progress_report': datetime.today()}
def __init__(self): def __init__(self):
window('jellyfin_should_stop', clear=True) window('jellyfin_should_stop', clear=True)

View file

@ -36,7 +36,6 @@ class FullSync(object):
running = False running = False
screensaver = None screensaver = None
def __init__(self, library, server): def __init__(self, library, server):
''' You can call all big syncing methods here. ''' You can call all big syncing methods here.
@ -69,7 +68,6 @@ class FullSync(object):
return self return self
def libraries(self, library_id=None, update=False): def libraries(self, library_id=None, update=False):
''' Map the syncing process and start the sync. Ensure only one sync is running. ''' Map the syncing process and start the sync. Ensure only one sync is running.
@ -179,7 +177,6 @@ class FullSync(object):
return [libraries[x - 1] for x in selection] return [libraries[x - 1] for x in selection]
def start(self): def start(self):
''' Main sync process. ''' Main sync process.
@ -322,7 +319,7 @@ class FullSync(object):
message = show['Name'] message = show['Name']
dialog.update(percent, heading="%s: %s" % (_('addon_name'), library['Name']), message=message) dialog.update(percent, heading="%s: %s" % (_('addon_name'), library['Name']), message=message)
if obj.tvshow(show, library=library) != False: if obj.tvshow(show, library=library):
for episodes in server.get_episode_by_show(show['Id']): for episodes in server.get_episode_by_show(show['Id']):
for episode in episodes['Items']: for episode in episodes['Items']:
@ -431,7 +428,6 @@ class FullSync(object):
dialog.update(percent, message="%s/%s" % (message, song['Name'])) dialog.update(percent, message="%s/%s" % (message, song['Name']))
obj.song(song) obj.song(song)
if self.update_library: if self.update_library:
self.music_compare(library, obj, jellyfindb) self.music_compare(library, obj, jellyfindb)
@ -560,7 +556,6 @@ class FullSync(object):
save_sync(self.sync) save_sync(self.sync)
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
''' Exiting sync ''' Exiting sync

View file

@ -2,9 +2,8 @@
################################################################################################# #################################################################################################
class LibraryException(Exception): class LibraryException(Exception):
# Jellyfin library sync exception # Jellyfin library sync exception
def __init__(self, status): def __init__(self, status):
self.status = status self.status = status

View file

@ -52,8 +52,8 @@ def set_properties(item, method, server_id=None):
window('jellyfin_play.json', current) window('jellyfin_play.json', current)
class PlayUtils(object):
class PlayUtils(object):
def __init__(self, item, force_transcode=False, server_id=None, server=None, token=None): def __init__(self, item, force_transcode=False, server_id=None, server=None, token=None):
@ -236,7 +236,7 @@ class PlayUtils(object):
def transcode(self, source, audio=None, subtitle=None): def transcode(self, source, audio=None, subtitle=None):
if not 'TranscodingUrl' in source: if 'TranscodingUrl' not in source:
raise Exception("use get_sources to get transcoding url") raise Exception("use get_sources to get transcoding url")
self.info['Method'] = "Transcode" self.info['Method'] = "Transcode"
@ -275,13 +275,19 @@ class PlayUtils(object):
self.info['Method'] = "DirectStream" self.info['Method'] = "DirectStream"
if self.item['Type'] == "Audio": if self.item['Type'] == "Audio":
self.info['Path'] = ("%s/emby/Audio/%s/stream.%s?static=true&api_key=%s" % self.info['Path'] = "%s/emby/Audio/%s/stream.%s?static=true&api_key=%s" % (
(self.info['ServerAddress'], self.item['Id'], self.info['ServerAddress'],
self.item['Id'],
source.get('Container', "mp4").split(',')[0], source.get('Container', "mp4").split(',')[0],
self.info['Token'])) self.info['Token']
)
else: else:
self.info['Path'] = ("%s/emby/Videos/%s/stream?static=true&MediaSourceId=%s&api_key=%s" % self.info['Path'] = "%s/emby/Videos/%s/stream?static=true&MediaSourceId=%s&api_key=%s" % (
(self.info['ServerAddress'], self.item['Id'], source['Id'], self.info['Token'])) self.info['ServerAddress'],
self.item['Id'],
source['Id'],
self.info['Token']
)
return self.info['Path'] return self.info['Path']
@ -495,7 +501,6 @@ class PlayUtils(object):
listitem.setSubtitles(subs) listitem.setSubtitles(subs)
self.item['PlaybackInfo']['Subtitles'] = mapping self.item['PlaybackInfo']['Subtitles'] = mapping
@classmethod @classmethod
def download_external_subs(cls, src, filename): def download_external_subs(cls, src, filename):
@ -628,7 +633,13 @@ class PlayUtils(object):
if stream['IsTextSubtitleStream'] and 'DeliveryUrl' in stream and stream['DeliveryUrl'].lower().startswith('/videos'): if stream['IsTextSubtitleStream'] and 'DeliveryUrl' in stream and stream['DeliveryUrl'].lower().startswith('/videos'):
url = "%s/emby%s" % (self.info['ServerAddress'], stream['DeliveryUrl']) url = "%s/emby%s" % (self.info['ServerAddress'], stream['DeliveryUrl'])
else: else:
url = ("%s/emby/Videos/%s/%s/Subtitles/%s/Stream.%s?api_key=%s" % url = "%s/emby/Videos/%s/%s/Subtitles/%s/Stream.%s?api_key=%s" % (
(self.info['ServerAddress'], self.item['Id'], source['Id'], index, stream['Codec'], self.info['Token'])) self.info['ServerAddress'],
self.item['Id'],
source['Id'],
index,
stream['Codec'],
self.info['Token']
)
return url return url

View file

@ -15,6 +15,7 @@ LOG = logging.getLogger('JELLYFIN.'+__name__)
################################################################################################## ##################################################################################################
def _(string): def _(string):
''' Get add-on string. Returns in unicode. ''' Get add-on string. Returns in unicode.

View file

@ -26,12 +26,15 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
################################################################################################# #################################################################################################
def addon_id(): def addon_id():
return "plugin.video.jellyfin" return "plugin.video.jellyfin"
def kodi_version(): def kodi_version():
return xbmc.getInfoLabel('System.BuildVersion')[:2] return xbmc.getInfoLabel('System.BuildVersion')[:2]
def window(key, value=None, clear=False, window_id=10000): def window(key, value=None, clear=False, window_id=10000):
''' Get or set window properties. ''' Get or set window properties.
@ -65,6 +68,7 @@ def window(key, value=None, clear=False, window_id=10000):
return result return result
def settings(setting, value=None): def settings(setting, value=None):
''' Get or add add-on settings. ''' Get or add add-on settings.
@ -87,9 +91,11 @@ def settings(setting, value=None):
return result return result
def create_id(): def create_id():
return uuid4() return uuid4()
def compare_version(a, b): def compare_version(a, b):
''' -1 a is smaller ''' -1 a is smaller
@ -107,6 +113,7 @@ def compare_version(a, b):
return 0 return 0
def find(dict, item): def find(dict, item):
''' Find value in dictionary. ''' Find value in dictionary.
@ -119,6 +126,7 @@ def find(dict, item):
if re.match(key, item, re.I): if re.match(key, item, re.I):
return dict[key] return dict[key]
def event(method, data=None, sender=None, hexlify=False): def event(method, data=None, sender=None, hexlify=False):
''' Data is a dictionary. ''' Data is a dictionary.
@ -134,13 +142,16 @@ def event(method, data=None, sender=None, hexlify=False):
xbmc.executebuiltin('NotifyAll(%s, %s, %s)' % (sender, method, data)) xbmc.executebuiltin('NotifyAll(%s, %s, %s)' % (sender, method, data))
LOG.debug("---[ event: %s/%s ] %s", sender, method, data) LOG.debug("---[ event: %s/%s ] %s", sender, method, data)
def dialog(dialog_type, *args, **kwargs): def dialog(dialog_type, *args, **kwargs):
d = xbmcgui.Dialog() d = xbmcgui.Dialog()
if "icon" in kwargs: if "icon" in kwargs:
kwargs['icon'] = kwargs['icon'].replace("{jellyfin}", kwargs['icon'] = kwargs['icon'].replace(
"special://home/addons/plugin.video.jellyfin/resources/icon.png") "{jellyfin}",
"special://home/addons/plugin.video.jellyfin/resources/icon.png"
)
if "heading" in kwargs: if "heading" in kwargs:
kwargs['heading'] = kwargs['heading'].replace("{jellyfin}", _('addon_name')) kwargs['heading'] = kwargs['heading'].replace("{jellyfin}", _('addon_name'))
@ -155,6 +166,7 @@ def dialog(dialog_type, *args, **kwargs):
} }
return types[dialog_type](*args, **kwargs) return types[dialog_type](*args, **kwargs)
def should_stop(): def should_stop():
''' Checkpoint during the sync process. ''' Checkpoint during the sync process.
@ -171,6 +183,7 @@ def should_stop():
return False return False
def get_screensaver(): def get_screensaver():
''' Get the current screensaver value. ''' Get the current screensaver value.
@ -181,6 +194,7 @@ def get_screensaver():
except KeyError: except KeyError:
return "" return ""
def set_screensaver(value): def set_screensaver(value):
''' Toggle the screensaver ''' Toggle the screensaver
@ -192,6 +206,7 @@ def set_screensaver(value):
result = JSONRPC('Settings.setSettingValue').execute(params) result = JSONRPC('Settings.setSettingValue').execute(params)
LOG.info("---[ screensaver/%s ] %s", value, result) LOG.info("---[ screensaver/%s ] %s", value, result)
class JSONRPC(object): class JSONRPC(object):
version = 1 version = 1
@ -221,6 +236,7 @@ class JSONRPC(object):
self.params = params self.params = params
return json.loads(xbmc.executeJSONRPC(self._query())) return json.loads(xbmc.executeJSONRPC(self._query()))
def validate(path): def validate(path):
''' Verify if path is accessible. ''' Verify if path is accessible.
@ -241,6 +257,7 @@ def validate(path):
return True return True
def values(item, keys): def values(item, keys):
''' Grab the values in the item for a list of keys {key},{key1}.... ''' Grab the values in the item for a list of keys {key},{key1}....
@ -248,6 +265,7 @@ def values(item, keys):
''' '''
return (item[key.replace('{', "").replace('}', "")] if type(key) == str and key.startswith('{') else key for key in keys) return (item[key.replace('{', "").replace('}', "")] if type(key) == str and key.startswith('{') else key for key in keys)
def indent(elem, level=0): def indent(elem, level=0):
''' Prettify xml docs. ''' Prettify xml docs.
@ -270,6 +288,7 @@ def indent(elem, level=0):
LOG.exception(error) LOG.exception(error)
return return
def write_xml(content, file): def write_xml(content, file):
with open(file, 'w') as infile: with open(file, 'w') as infile:
@ -332,6 +351,7 @@ def unzip(path, dest, folder=None):
LOG.info("Unzipped %s", path) LOG.info("Unzipped %s", path)
def unzip_recursive(path, dirs, dest): def unzip_recursive(path, dirs, dest):
for directory in dirs: for directory in dirs:
@ -348,6 +368,7 @@ def unzip_recursive(path, dirs, dest):
for file in files: for file in files:
unzip_file(os.path.join(dirs_dir, file.decode('utf-8')), os.path.join(dest_dir, file.decode('utf-8'))) unzip_file(os.path.join(dirs_dir, file.decode('utf-8')), os.path.join(dest_dir, file.decode('utf-8')))
def unzip_file(path, dest): def unzip_file(path, dest):
''' Unzip specific file. Path should start with zip:// ''' Unzip specific file. Path should start with zip://
@ -355,6 +376,7 @@ def unzip_file(path, dest):
xbmcvfs.copy(path, dest) xbmcvfs.copy(path, dest)
LOG.debug("unzip: %s to %s", path, dest) LOG.debug("unzip: %s to %s", path, dest)
def get_zip_directory(path, folder): def get_zip_directory(path, folder):
dirs, files = xbmcvfs.listdir(path) dirs, files = xbmcvfs.listdir(path)
@ -367,6 +389,7 @@ def get_zip_directory(path, folder):
if result: if result:
return result return result
def copytree(path, dest): def copytree(path, dest):
''' Copy folder content from one to another. ''' Copy folder content from one to another.
@ -384,6 +407,7 @@ def copytree(path, dest):
LOG.info("Copied %s", path) LOG.info("Copied %s", path)
def copy_recursive(path, dirs, dest): def copy_recursive(path, dirs, dest):
for directory in dirs: for directory in dirs:
@ -400,6 +424,7 @@ def copy_recursive(path, dirs, dest):
for file in files: for file in files:
copy_file(os.path.join(dirs_dir, file.decode('utf-8')), os.path.join(dest_dir, file.decode('utf-8'))) copy_file(os.path.join(dirs_dir, file.decode('utf-8')), os.path.join(dest_dir, file.decode('utf-8')))
def copy_file(path, dest): def copy_file(path, dest):
''' Copy specific file. ''' Copy specific file.
@ -410,6 +435,7 @@ def copy_file(path, dest):
xbmcvfs.copy(path, dest) xbmcvfs.copy(path, dest)
LOG.debug("copy: %s to %s", path, dest) LOG.debug("copy: %s to %s", path, dest)
def normalize_string(text): def normalize_string(text):
''' For theme media, do not modify unless modified in TV Tunes. ''' For theme media, do not modify unless modified in TV Tunes.
@ -431,12 +457,14 @@ def normalize_string(text):
return text return text
def split_list(itemlist, size): def split_list(itemlist, size):
''' Split up list in pieces of size. Will generate a list of lists ''' Split up list in pieces of size. Will generate a list of lists
''' '''
return [itemlist[i:i + size] for i in range(0, len(itemlist), size)] return [itemlist[i:i + size] for i in range(0, len(itemlist), size)]
def convert_to_local(date): def convert_to_local(date):
''' Convert the local datetime to local. ''' Convert the local datetime to local.

View file

@ -15,6 +15,7 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
################################################################################################# #################################################################################################
def progress(message=None): def progress(message=None):
''' Will start and close the progress dialog. ''' Will start and close the progress dialog.
@ -61,6 +62,7 @@ def catch(errors=(Exception,)):
return wrapper return wrapper
return decorator return decorator
def silent_catch(errors=(Exception,)): def silent_catch(errors=(Exception,)):
''' Wrapper to catch exceptions and ignore them ''' Wrapper to catch exceptions and ignore them
@ -76,6 +78,7 @@ def silent_catch(errors=(Exception,)):
return wrapper return wrapper
return decorator return decorator
def stop(default=None): def stop(default=None):
''' Wrapper to catch exceptions and return using catch ''' Wrapper to catch exceptions and return using catch
@ -100,6 +103,7 @@ def stop(default=None):
return wrapper return wrapper
return decorator return decorator
def jellyfin_item(): def jellyfin_item():
''' Wrapper to retrieve the jellyfin_db item. ''' Wrapper to retrieve the jellyfin_db item.
@ -113,6 +117,7 @@ def jellyfin_item():
return wrapper return wrapper
return decorator return decorator
def library_check(): def library_check():
''' Wrapper to retrieve the library ''' Wrapper to retrieve the library

View file

@ -17,6 +17,7 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
################################################################################################# #################################################################################################
def sources(): def sources():
''' Create master lock compatible sources. ''' Create master lock compatible sources.
@ -77,6 +78,7 @@ def sources():
indent(xml) indent(xml)
write_xml(etree.tostring(xml, 'UTF-8'), file) write_xml(etree.tostring(xml, 'UTF-8'), file)
def tvtunes_nfo(path, urls): def tvtunes_nfo(path, urls):
''' Create tvtunes.nfo ''' Create tvtunes.nfo
@ -96,6 +98,7 @@ def tvtunes_nfo(path, urls):
indent(xml) indent(xml)
write_xml(etree.tostring(xml, 'UTF-8'), path) write_xml(etree.tostring(xml, 'UTF-8'), path)
def advanced_settings(): def advanced_settings():
''' Track the existence of <cleanonupdate>true</cleanonupdate> ''' Track the existence of <cleanonupdate>true</cleanonupdate>

View file

@ -9,21 +9,25 @@ from helpers import has_attribute
################################################################################################# #################################################################################################
class NullHandler(logging.Handler): class NullHandler(logging.Handler):
def emit(self, record): def emit(self, record):
print(self.format(record)) print(self.format(record))
loghandler = NullHandler loghandler = NullHandler
LOG = logging.getLogger('Jellyfin') LOG = logging.getLogger('Jellyfin')
################################################################################################# #################################################################################################
def config(level=logging.INFO): def config(level=logging.INFO):
logger = logging.getLogger('Jellyfin') logger = logging.getLogger('Jellyfin')
logger.addHandler(Jellyfin.loghandler()) logger.addHandler(Jellyfin.loghandler())
logger.setLevel(level) logger.setLevel(level)
def ensure_client(): def ensure_client():
def decorator(func): def decorator(func):

View file

@ -16,6 +16,7 @@ LOG = logging.getLogger('JELLYFIN.'+__name__)
################################################################################################# #################################################################################################
def callback(message, data): def callback(message, data):
''' Callback function should received message, data ''' Callback function should received message, data

View file

@ -1 +0,0 @@

View file

@ -31,6 +31,7 @@ CONNECTION_MODE = {
################################################################################################# #################################################################################################
def get_server_address(server, mode): def get_server_address(server, mode):
modes = { modes = {
@ -239,8 +240,10 @@ class ConnectionManager(object):
request.pop('dataType') request.pop('dataType')
headers['X-Application'] = self._add_app_info() headers['X-Application'] = self._add_app_info()
headers['Content-type'] = request.get('contentType', headers['Content-type'] = request.get(
'application/x-www-form-urlencoded; charset=UTF-8') 'contentType',
'application/x-www-form-urlencoded; charset=UTF-8'
)
def _connect_to_servers(self, servers, options): def _connect_to_servers(self, servers, options):
@ -496,7 +499,7 @@ class ConnectionManager(object):
def _after_connect_validated(self, server, credentials, system_info, connection_mode, verify_authentication, options): def _after_connect_validated(self, server, credentials, system_info, connection_mode, verify_authentication, options):
if options.get('enableAutoLogin') == False: if not options.get('enableAutoLogin'):
self.config.data['auth.user_id'] = server.pop('UserId', None) self.config.data['auth.user_id'] = server.pop('UserId', None)
self.config.data['auth.token'] = server.pop('AccessToken', None) self.config.data['auth.token'] = server.pop('AccessToken', None)
@ -581,7 +584,8 @@ class ConnectionManager(object):
if server['Id'] == result['ServerId']: if server['Id'] == result['ServerId']:
found_server = server found_server = server
break break
else: return # No server found else:
return # No server found
if options.get('updateDateLastAccessed') is not False: if options.get('updateDateLastAccessed') is not False:
found_server['DateLastAccessed'] = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ') found_server['DateLastAccessed'] = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')

View file

@ -14,6 +14,7 @@ LOG = logging.getLogger('JELLYFIN.'+__name__)
################################################################################################# #################################################################################################
class Credentials(object): class Credentials(object):
credentials = None credentials = None

View file

@ -2,10 +2,9 @@
################################################################################################# #################################################################################################
class HTTPException(Exception): class HTTPException(Exception):
# Jellyfin HTTP exception # Jellyfin HTTP exception
def __init__(self, status, message): def __init__(self, status, message):
self.status = status self.status = status
self.message = message self.message = message

View file

@ -11,5 +11,6 @@ LOG = logging.getLogger('JELLYFIN.'+__name__)
################################################################################################# #################################################################################################
def generate_client_id(): def generate_client_id():
return str("%012X" % uuid4()) return str("%012X" % uuid4())

View file

@ -43,8 +43,6 @@ import base64
import threading import threading
import time import time
import logging import logging
import traceback
import sys
""" """
websocket python client. websocket python client.
@ -89,12 +87,14 @@ class WebSocketConnectionClosedException(WebSocketException):
""" """
pass pass
class WebSocketTimeoutException(WebSocketException): class WebSocketTimeoutException(WebSocketException):
""" """
WebSocketTimeoutException will be raised at socket timeout during read/write data. WebSocketTimeoutException will be raised at socket timeout during read/write data.
""" """
pass pass
default_timeout = None default_timeout = None
traceEnabled = False traceEnabled = False
@ -135,8 +135,10 @@ def _wrap_sni_socket(sock, sslopt, hostname):
if sslopt.get('cert_reqs', ssl.CERT_NONE) != ssl.CERT_NONE: if sslopt.get('cert_reqs', ssl.CERT_NONE) != ssl.CERT_NONE:
capath = ssl.get_default_verify_paths().capath capath = ssl.get_default_verify_paths().capath
context.load_verify_locations(cafile=sslopt.get('ca_certs', None), context.load_verify_locations(
capath=sslopt.get('ca_cert_path', capath)) cafile=sslopt.get('ca_certs', None),
capath=sslopt.get('ca_cert_path', capath)
)
return context.wrap_socket( return context.wrap_socket(
sock, sock,
@ -217,6 +219,7 @@ def create_connection(url, timeout=None, **options):
websock.connect(url, **options) websock.connect(url, **options)
return websock return websock
_MAX_INTEGER = (1 << 32) - 1 _MAX_INTEGER = (1 << 32) - 1
_AVAILABLE_KEY_CHARS = range(0x21, 0x2f + 1) + range(0x3a, 0x7e + 1) _AVAILABLE_KEY_CHARS = range(0x21, 0x2f + 1) + range(0x3a, 0x7e + 1)
_MAX_CHAR_BYTE = (1 << 8) - 1 _MAX_CHAR_BYTE = (1 << 8) - 1
@ -318,9 +321,7 @@ class ABNF(object):
if length >= ABNF.LENGTH_63: if length >= ABNF.LENGTH_63:
raise ValueError("data is too long") raise ValueError("data is too long")
frame_header = chr(self.fin << 7 frame_header = chr(self.fin << 7 | self.rsv1 << 6 | self.rsv2 << 5 | self.rsv3 << 4 | self.opcode)
| self.rsv1 << 6 | self.rsv2 << 5 | self.rsv3 << 4
| self.opcode)
if length < ABNF.LENGTH_7: if length < ABNF.LENGTH_7:
frame_header += chr(self.mask << 7 | length) frame_header += chr(self.mask << 7 | length)
elif length < ABNF.LENGTH_16: elif length < ABNF.LENGTH_16:
@ -582,8 +583,7 @@ class WebSocket(object):
if traceEnabled: if traceEnabled:
logger.debug("send: " + repr(data)) logger.debug("send: " + repr(data))
while data: while data:
l = self._send(data) data = data[self._send(data):]
data = data[l:]
return length return length
def send_binary(self, payload): def send_binary(self, payload):
@ -685,7 +685,6 @@ class WebSocket(object):
self._frame_mask = None self._frame_mask = None
return ABNF(fin, rsv1, rsv2, rsv3, opcode, has_mask, payload) return ABNF(fin, rsv1, rsv2, rsv3, opcode, has_mask, payload)
def send_close(self, status=STATUS_NORMAL, reason=""): def send_close(self, status=STATUS_NORMAL, reason=""):
""" """
send close data to the server. send close data to the server.
@ -709,7 +708,7 @@ class WebSocket(object):
try: try:
self.sock.shutdown(socket.SHUT_RDWR) self.sock.shutdown(socket.SHUT_RDWR)
except: except: # noqa: E722
pass pass
''' '''
@ -766,7 +765,6 @@ class WebSocket(object):
raise WebSocketConnectionClosedException() raise WebSocketConnectionClosedException()
return bytes return bytes
def _recv_strict(self, bufsize): def _recv_strict(self, bufsize):
shortage = bufsize - sum(len(x) for x in self._recv_buffer) shortage = bufsize - sum(len(x) for x in self._recv_buffer)
while shortage > 0: while shortage > 0:
@ -781,7 +779,6 @@ class WebSocket(object):
self._recv_buffer = [unified[bufsize:]] self._recv_buffer = [unified[bufsize:]]
return unified[:bufsize] return unified[:bufsize]
def _recv_line(self): def _recv_line(self):
line = [] line = []
while True: while True:
@ -844,7 +841,7 @@ class WebSocketApp(object):
close websocket connection. close websocket connection.
""" """
self.keep_running = False self.keep_running = False
if(self.sock != None): if self.sock is None:
self.sock.close() self.sock.close()
def _send_ping(self, interval): def _send_ping(self, interval):
@ -890,7 +887,7 @@ class WebSocketApp(object):
try: try:
data = self.sock.recv() data = self.sock.recv()
if data is None or self.keep_running == False: if data is None or not self.keep_running:
break break
self._callback(self.on_message, data) self._callback(self.on_message, data)

View file

@ -41,7 +41,6 @@ MEDIA = {
################################################################################################## ##################################################################################################
class Library(threading.Thread): class Library(threading.Thread):
started = False started = False
@ -52,7 +51,6 @@ class Library(threading.Thread):
progress_updates = None progress_updates = None
total_updates = 0 total_updates = 0
def __init__(self, monitor): def __init__(self, monitor):
self.media = {'Movies': Movies, 'TVShows': TVShows, 'MusicVideos': MusicVideos, 'Music': Music} self.media = {'Movies': Movies, 'TVShows': TVShows, 'MusicVideos': MusicVideos, 'Music': Music}
@ -171,8 +169,7 @@ class Library(threading.Thread):
self.screensaver = get_screensaver() self.screensaver = get_screensaver()
set_screensaver(value="") set_screensaver(value="")
if (self.pending_refresh and not self.download_threads and not self.writer_threads['updated'] and if (self.pending_refresh and not self.download_threads and not self.writer_threads['updated'] and not self.writer_threads['userdata'] and not self.writer_threads['removed']):
not self.writer_threads['userdata'] and not self.writer_threads['removed']):
self.pending_refresh = False self.pending_refresh = False
self.save_last_sync() self.save_last_sync()
self.total_updates = 0 self.total_updates = 0
@ -313,7 +310,6 @@ class Library(threading.Thread):
LOG.info("-->[ q:notify/%s ]", id(new_thread)) LOG.info("-->[ q:notify/%s ]", id(new_thread))
self.notify_threads.append(new_thread) self.notify_threads.append(new_thread)
def startup(self): def startup(self):
''' Run at startup. ''' Run at startup.
@ -546,7 +542,6 @@ class Library(threading.Thread):
return True return True
def userdata(self, data): def userdata(self, data):
''' Add item_id to userdata queue. ''' Add item_id to userdata queue.
@ -654,6 +649,7 @@ class UpdatedWorker(threading.Thread):
LOG.info("--<[ q:updated/%s ]", id(self)) LOG.info("--<[ q:updated/%s ]", id(self))
self.is_done = True self.is_done = True
class UserDataWorker(threading.Thread): class UserDataWorker(threading.Thread):
is_done = False is_done = False
@ -697,6 +693,7 @@ class UserDataWorker(threading.Thread):
LOG.info("--<[ q:userdata/%s ]", id(self)) LOG.info("--<[ q:userdata/%s ]", id(self))
self.is_done = True self.is_done = True
class SortWorker(threading.Thread): class SortWorker(threading.Thread):
is_done = False is_done = False
@ -742,6 +739,7 @@ class SortWorker(threading.Thread):
LOG.info("--<[ q:sort/%s ]", id(self)) LOG.info("--<[ q:sort/%s ]", id(self))
self.is_done = True self.is_done = True
class RemovedWorker(threading.Thread): class RemovedWorker(threading.Thread):
is_done = False is_done = False
@ -789,6 +787,7 @@ class RemovedWorker(threading.Thread):
LOG.info("--<[ q:removed/%s ]", id(self)) LOG.info("--<[ q:removed/%s ]", id(self))
self.is_done = True self.is_done = True
class NotifyWorker(threading.Thread): class NotifyWorker(threading.Thread):
is_done = False is_done = False

View file

@ -79,7 +79,8 @@ class Actions(object):
index += 1 index += 1
if force_play: if force_play:
if len(sys.argv) > 1: xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, self.stack[0][1]) if len(sys.argv) > 1:
xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, self.stack[0][1])
xbmc.Player().play(kodi_playlist, windowed=False) xbmc.Player().play(kodi_playlist, windowed=False)
def set_playlist(self, item, listitem, db_id=None, transcode=False): def set_playlist(self, item, listitem, db_id=None, transcode=False):
@ -316,8 +317,8 @@ class Actions(object):
else: else:
obj['Artwork']['Primary'] = obj['Artwork']['Primary'] \ obj['Artwork']['Primary'] = obj['Artwork']['Primary'] \
or obj['Artwork']['Thumb'] \ or obj['Artwork']['Thumb'] \
or (obj['Artwork']['Backdrop'][0] \ or (obj['Artwork']['Backdrop'][0]
if len(obj['Artwork']['Backdrop']) \ if len(obj['Artwork']['Backdrop'])
else "special://home/addons/plugin.video.jellyfin/resources/fanart.png") else "special://home/addons/plugin.video.jellyfin/resources/fanart.png")
obj['Artwork']['Primary'] += "&KodiTrailer=true" \ obj['Artwork']['Primary'] += "&KodiTrailer=true" \
if obj['Type'] == 'Trailer' else "&KodiCinemaMode=true" if obj['Type'] == 'Trailer' else "&KodiCinemaMode=true"
@ -442,7 +443,7 @@ class Actions(object):
listitem.setProperty('IsPlayable', 'true') listitem.setProperty('IsPlayable', 'true')
listitem.setProperty('IsFolder', 'false') listitem.setProperty('IsFolder', 'false')
if obj['Resume'] and seektime != False: if obj['Resume'] and seektime:
listitem.setProperty('resumetime', str(obj['Resume'])) listitem.setProperty('resumetime', str(obj['Resume']))
listitem.setProperty('StartPercent', str(((obj['Resume'] / obj['Runtime']) * 100) - 0.40)) listitem.setProperty('StartPercent', str(((obj['Resume'] / obj['Runtime']) * 100) - 0.40))
else: else:
@ -688,9 +689,7 @@ class Actions(object):
return False return False
if (not xbmc.getCondVisibility('Window.IsMedia') and if (not xbmc.getCondVisibility('Window.IsMedia') and ((item['Type'] == 'Audio' and not xbmc.getCondVisibility('Integer.IsGreater(Playlist.Length(music),1)')) or not xbmc.getCondVisibility('Integer.IsGreater(Playlist.Length(video),1)'))):
((item['Type'] == 'Audio' and not xbmc.getCondVisibility('Integer.IsGreater(Playlist.Length(music),1)')) or
not xbmc.getCondVisibility('Integer.IsGreater(Playlist.Length(video),1)'))):
return True return True
@ -733,6 +732,7 @@ def on_update(data, server):
window('jellyfin.skip.%s' % item[0], clear=True) window('jellyfin.skip.%s' % item[0], clear=True)
def on_play(data, server): def on_play(data, server):
''' Setup progress for jellyfin playback. ''' Setup progress for jellyfin playback.
@ -781,6 +781,7 @@ def on_play(data, server):
item['PlaybackInfo'] = {'Path': file} item['PlaybackInfo'] = {'Path': file}
playutils.set_properties(item, 'DirectStream' if settings('useDirectPaths') == '0' else 'DirectPlay') playutils.set_properties(item, 'DirectStream' if settings('useDirectPaths') == '0' else 'DirectPlay')
def special_listener(): def special_listener():
''' Corner cases that needs to be listened to. ''' Corner cases that needs to be listened to.
@ -790,8 +791,7 @@ def special_listener():
isPlaying = player.isPlaying() isPlaying = player.isPlaying()
count = int(window('jellyfin.external_count') or 0) count = int(window('jellyfin.external_count') or 0)
if (not isPlaying and xbmc.getCondVisibility('Window.IsVisible(DialogContextMenu.xml)') and if (not isPlaying and xbmc.getCondVisibility('Window.IsVisible(DialogContextMenu.xml)') and xbmc.getInfoLabel('Control.GetLabel(1002)') == xbmc.getLocalizedString(12021)):
xbmc.getInfoLabel('Control.GetLabel(1002)') == xbmc.getLocalizedString(12021)):
control = int(xbmcgui.Window(10106).getFocusId()) control = int(xbmcgui.Window(10106).getFocusId())

View file

@ -37,7 +37,6 @@ class Artwork(object):
'port': settings('webServerPort') 'port': settings('webServerPort')
} }
def update(self, image_url, kodi_id, media, image): def update(self, image_url, kodi_id, media, image):
''' Update artwork in the video database. ''' Update artwork in the video database.
@ -220,8 +219,6 @@ class GetArtworkWorker(threading.Thread):
break break
""" """
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
@ -381,4 +378,3 @@ class Artwork(object):
count += 1 count += 1
""" """

View file

@ -19,7 +19,6 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
class Kodi(object): class Kodi(object):
def __init__(self): def __init__(self):
self.artwork = artwork.Artwork(self.cursor) self.artwork = artwork.Artwork(self.cursor)

View file

@ -16,7 +16,6 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
class Movies(Kodi): class Movies(Kodi):
def __init__(self, cursor): def __init__(self, cursor):
self.cursor = cursor self.cursor = cursor

View file

@ -16,7 +16,6 @@ log = logging.getLogger("JELLYFIN."+__name__)
class MusicVideos(Kodi): class MusicVideos(Kodi):
def __init__(self, cursor): def __init__(self, cursor):
self.cursor = cursor self.cursor = cursor

View file

@ -57,15 +57,13 @@ get_path = """ SELECT idPath
FROM path FROM path
WHERE strPath = ? WHERE strPath = ?
""" """
get_path_obj = [ "{Path}" get_path_obj = ["{Path}"]
]
get_file = """ SELECT idFile get_file = """ SELECT idFile
FROM files FROM files
WHERE idPath = ? WHERE idPath = ?
AND strFilename = ? AND strFilename = ?
""" """
get_file_obj = [ "{FileId}" get_file_obj = ["{FileId}"]
]
get_filename = """ SELECT strFilename get_filename = """ SELECT strFilename
FROM files FROM files
WHERE idFile = ? WHERE idFile = ?
@ -90,12 +88,9 @@ get_tag = """ SELECT tag_id
WHERE name = ? WHERE name = ?
COLLATE NOCASE COLLATE NOCASE
""" """
get_tag_movie_obj = [ "Favorite movies","{MovieId}","movie" get_tag_movie_obj = ["Favorite movies", "{MovieId}", "movie"]
] get_tag_mvideo_obj = ["Favorite musicvideos", "{MvideoId}", "musicvideo"]
get_tag_mvideo_obj = [ "Favorite musicvideos","{MvideoId}","musicvideo" get_tag_episode_obj = ["Favorite tvshows", "{KodiId}", "tvshow"]
]
get_tag_episode_obj = [ "Favorite tvshows","{KodiId}","tvshow"
]
get_art = """ SELECT url get_art = """ SELECT url
FROM art FROM art
WHERE media_id = ? WHERE media_id = ?
@ -106,28 +101,22 @@ get_movie = """ SELECT *
FROM movie FROM movie
WHERE idMovie = ? WHERE idMovie = ?
""" """
get_movie_obj = [ "{MovieId}" get_movie_obj = ["{MovieId}"]
]
get_rating = """ SELECT rating_id get_rating = """ SELECT rating_id
FROM rating FROM rating
WHERE media_type = ? WHERE media_type = ?
AND media_id = ? AND media_id = ?
""" """
get_rating_movie_obj = [ "movie","{MovieId}" get_rating_movie_obj = ["movie", "{MovieId}"]
] get_rating_episode_obj = ["episode", "{EpisodeId}"]
get_rating_episode_obj = [ "episode","{EpisodeId}"
]
get_unique_id = """ SELECT uniqueid_id get_unique_id = """ SELECT uniqueid_id
FROM uniqueid FROM uniqueid
WHERE media_type = ? WHERE media_type = ?
AND media_id = ? AND media_id = ?
""" """
get_unique_id_movie_obj = [ "movie","{MovieId}" get_unique_id_movie_obj = ["movie", "{MovieId}"]
] get_unique_id_tvshow_obj = ["tvshow", "{ShowId}"]
get_unique_id_tvshow_obj = [ "tvshow","{ShowId}" get_unique_id_episode_obj = ["episode", "{EpisodeId}"]
]
get_unique_id_episode_obj = [ "episode","{EpisodeId}"
]
get_country = """ SELECT country_id get_country = """ SELECT country_id
FROM country FROM country
WHERE name = ? WHERE name = ?
@ -142,31 +131,25 @@ get_musicvideo = """ SELECT *
FROM musicvideo FROM musicvideo
WHERE idMVideo = ? WHERE idMVideo = ?
""" """
get_musicvideo_obj = [ "{MvideoId}" get_musicvideo_obj = ["{MvideoId}"]
]
get_tvshow = """ SELECT * get_tvshow = """ SELECT *
FROM tvshow FROM tvshow
WHERE idShow = ? WHERE idShow = ?
""" """
get_tvshow_obj = [ "{ShowId}" get_tvshow_obj = ["{ShowId}"]
]
get_episode = """ SELECT * get_episode = """ SELECT *
FROM episode FROM episode
WHERE idEpisode = ? WHERE idEpisode = ?
""" """
get_episode_obj = [ "{EpisodeId}" get_episode_obj = ["{EpisodeId}"]
]
get_season = """ SELECT idSeason get_season = """ SELECT idSeason
FROM seasons FROM seasons
WHERE idShow = ? WHERE idShow = ?
AND season = ? AND season = ?
""" """
get_season_obj = [ "{Title}","{ShowId}","{Index}" get_season_obj = ["{Title}", "{ShowId}", "{Index}"]
] get_season_special_obj = [None, "{ShowId}", -1]
get_season_special_obj = [ None,"{ShowId}",-1 get_season_episode_obj = [None, "{ShowId}", "{Season}"]
]
get_season_episode_obj = [ None,"{ShowId}","{Season}"
]
get_backdrops = """ SELECT url get_backdrops = """ SELECT url
FROM art FROM art
WHERE media_id = ? WHERE media_id = ?
@ -193,32 +176,24 @@ get_total_episodes = """ SELECT totalCount
FROM tvshowcounts FROM tvshowcounts
WHERE idShow = ? WHERE idShow = ?
""" """
get_total_episodes_obj = [ "{ParentId}" get_total_episodes_obj = ["{ParentId}"]
]
add_path = """ INSERT INTO path(idPath, strPath) add_path = """ INSERT INTO path(idPath, strPath)
VALUES (?, ?) VALUES (?, ?)
""" """
add_path_obj = [ "{Path}" add_path_obj = ["{Path}"]
]
add_file = """ INSERT INTO files(idFile, idPath, strFilename) add_file = """ INSERT INTO files(idFile, idPath, strFilename)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
add_file_obj = [ "{PathId}","{Filename}" add_file_obj = ["{PathId}", "{Filename}"]
]
add_person = """ INSERT INTO actor(actor_id, name) add_person = """ INSERT INTO actor(actor_id, name)
VALUES (?, ?) VALUES (?, ?)
""" """
add_people_movie_obj = [ "{People}","{MovieId}","movie" add_people_movie_obj = ["{People}", "{MovieId}", "movie"]
] add_people_mvideo_obj = ["{People}", "{MvideoId}", "musicvideo"]
add_people_mvideo_obj = [ "{People}","{MvideoId}","musicvideo" add_people_tvshow_obj = ["{People}", "{ShowId}", "tvshow"]
] add_people_episode_obj = ["{People}", "{EpisodeId}", "episode"]
add_people_tvshow_obj = [ "{People}","{ShowId}","tvshow"
]
add_people_episode_obj = [ "{People}","{EpisodeId}","episode"
]
add_actor_link = """ INSERT INTO actor_link(actor_id, media_id, media_type, role, cast_order) add_actor_link = """ INSERT INTO actor_link(actor_id, media_id, media_type, role, cast_order)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""" """
@ -228,53 +203,39 @@ add_link = """ INSERT INTO {LinkType}(actor_id, media_id, media_type)
add_genre = """ INSERT INTO genre(genre_id, name) add_genre = """ INSERT INTO genre(genre_id, name)
VALUES (?, ?) VALUES (?, ?)
""" """
add_genres_movie_obj = [ "{Genres}","{MovieId}","movie" add_genres_movie_obj = ["{Genres}", "{MovieId}", "movie"]
] add_genres_mvideo_obj = ["{Genres}", "{MvideoId}", "musicvideo"]
add_genres_mvideo_obj = [ "{Genres}","{MvideoId}","musicvideo" add_genres_tvshow_obj = ["{Genres}", "{ShowId}", "tvshow"]
]
add_genres_tvshow_obj = [ "{Genres}","{ShowId}","tvshow"
]
add_studio = """ INSERT INTO studio(studio_id, name) add_studio = """ INSERT INTO studio(studio_id, name)
VALUES (?, ?) VALUES (?, ?)
""" """
add_studios_movie_obj = [ "{Studios}","{MovieId}","movie" add_studios_movie_obj = ["{Studios}", "{MovieId}", "movie"]
] add_studios_mvideo_obj = ["{Studios}", "{MvideoId}", "musicvideo"]
add_studios_mvideo_obj = [ "{Studios}","{MvideoId}","musicvideo" add_studios_tvshow_obj = ["{Studios}", "{ShowId}", "tvshow"]
]
add_studios_tvshow_obj = [ "{Studios}","{ShowId}","tvshow"
]
add_bookmark = """ INSERT INTO bookmark(idBookmark, idFile, timeInSeconds, totalTimeInSeconds, player, type) add_bookmark = """ INSERT INTO bookmark(idBookmark, idFile, timeInSeconds, totalTimeInSeconds, player, type)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
""" """
add_bookmark_obj = [ "{FileId}","{PlayCount}","{DatePlayed}","{Resume}","{Runtime}","DVDPlayer",1 add_bookmark_obj = ["{FileId}", "{PlayCount}", "{DatePlayed}", "{Resume}", "{Runtime}", "DVDPlayer", 1]
] add_streams_obj = ["{FileId}", "{Streams}", "{Runtime}"]
add_streams_obj = [ "{FileId}","{Streams}","{Runtime}"
]
add_stream_video = """ INSERT INTO streamdetails(idFile, iStreamType, strVideoCodec, fVideoAspect, iVideoWidth, add_stream_video = """ INSERT INTO streamdetails(idFile, iStreamType, strVideoCodec, fVideoAspect, iVideoWidth,
iVideoHeight, iVideoDuration, strStereoMode) iVideoHeight, iVideoDuration, strStereoMode)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""" """
add_stream_video_obj = [ "{FileId}",0,"{codec}","{aspect}","{width}","{height}","{Runtime}","{3d}" add_stream_video_obj = ["{FileId}", 0, "{codec}", "{aspect}", "{width}", "{height}", "{Runtime}", "{3d}"]
]
add_stream_audio = """ INSERT INTO streamdetails(idFile, iStreamType, strAudioCodec, iAudioChannels, strAudioLanguage) add_stream_audio = """ INSERT INTO streamdetails(idFile, iStreamType, strAudioCodec, iAudioChannels, strAudioLanguage)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""" """
add_stream_audio_obj = [ "{FileId}",1,"{codec}","{channels}","{language}" add_stream_audio_obj = ["{FileId}", 1, "{codec}", "{channels}", "{language}"]
]
add_stream_sub = """ INSERT INTO streamdetails(idFile, iStreamType, strSubtitleLanguage) add_stream_sub = """ INSERT INTO streamdetails(idFile, iStreamType, strSubtitleLanguage)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
add_stream_sub_obj = [ "{FileId}",2,"{language}" add_stream_sub_obj = ["{FileId}", 2, "{language}"]
]
add_tag = """ INSERT INTO tag(tag_id, name) add_tag = """ INSERT INTO tag(tag_id, name)
VALUES (?, ?) VALUES (?, ?)
""" """
add_tags_movie_obj = [ "{Tags}","{MovieId}","movie" add_tags_movie_obj = ["{Tags}", "{MovieId}", "movie"]
] add_tags_mvideo_obj = ["{Tags}", "{MvideoId}", "musicvideo"]
add_tags_mvideo_obj = [ "{Tags}","{MvideoId}","musicvideo" add_tags_tvshow_obj = ["{Tags}", "{ShowId}", "tvshow"]
]
add_tags_tvshow_obj = [ "{Tags}","{ShowId}","tvshow"
]
add_art = """ INSERT INTO art(media_id, media_type, type, url) add_art = """ INSERT INTO art(media_id, media_type, type, url)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""" """
@ -285,47 +246,37 @@ add_movie = """ INSERT INTO movie(idMovie, idFile, c00, c01, c02, c03, c04
add_movie_obj = ["{MovieId}", "{FileId}", "{Title}", "{Plot}", "{ShortPlot}", "{Tagline}", add_movie_obj = ["{MovieId}", "{FileId}", "{Title}", "{Plot}", "{ShortPlot}", "{Tagline}",
"{Votes}", "{RatingId}", "{Writers}", "{Year}", "{Unique}", "{SortTitle}", "{Votes}", "{RatingId}", "{Writers}", "{Year}", "{Unique}", "{SortTitle}",
"{Runtime}", "{Mpaa}", "{Genre}", "{Directors}", "{Title}", "{Studio}", "{Runtime}", "{Mpaa}", "{Genre}", "{Directors}", "{Title}", "{Studio}",
"{Trailer}","{Country}","{CriticRating}","{Year}" "{Trailer}", "{Country}", "{CriticRating}", "{Year}"]
]
add_rating = """ INSERT INTO rating(rating_id, media_id, media_type, rating_type, rating, votes) add_rating = """ INSERT INTO rating(rating_id, media_id, media_type, rating_type, rating, votes)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
""" """
add_rating_movie_obj = [ "{RatingId}","{MovieId}","movie","default","{Rating}","{Votes}" add_rating_movie_obj = ["{RatingId}", "{MovieId}", "movie", "default", "{Rating}", "{Votes}"]
] add_rating_tvshow_obj = ["{RatingId}", "{ShowId}", "tvshow", "default", "{Rating}", "{Votes}"]
add_rating_tvshow_obj = [ "{RatingId}","{ShowId}","tvshow","default","{Rating}","{Votes}" add_rating_episode_obj = ["{RatingId}", "{EpisodeId}", "episode", "default", "{Rating}", "{Votes}"]
]
add_rating_episode_obj = [ "{RatingId}","{EpisodeId}","episode","default","{Rating}","{Votes}"
]
add_unique_id = """ INSERT INTO uniqueid(uniqueid_id, media_id, media_type, value, type) add_unique_id = """ INSERT INTO uniqueid(uniqueid_id, media_id, media_type, value, type)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""" """
add_unique_id_movie_obj = [ "{Unique}","{MovieId}","movie","{UniqueId}","{ProviderName}" add_unique_id_movie_obj = ["{Unique}", "{MovieId}", "movie", "{UniqueId}", "{ProviderName}"]
] add_unique_id_tvshow_obj = ["{Unique}", "{ShowId}", "tvshow", "{UniqueId}", "{ProviderName}"]
add_unique_id_tvshow_obj = [ "{Unique}","{ShowId}","tvshow","{UniqueId}","{ProviderName}" add_unique_id_episode_obj = ["{Unique}", "{EpisodeId}", "episode", "{UniqueId}", "{ProviderName}"]
]
add_unique_id_episode_obj = [ "{Unique}","{EpisodeId}","episode","{UniqueId}","{ProviderName}"
]
add_country = """ INSERT INTO country(country_id, name) add_country = """ INSERT INTO country(country_id, name)
VALUES (?, ?) VALUES (?, ?)
""" """
add_set = """ INSERT INTO sets(idSet, strSet, strOverview) add_set = """ INSERT INTO sets(idSet, strSet, strOverview)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
add_set_obj = [ "{Title}","{Overview}" add_set_obj = ["{Title}", "{Overview}"]
]
add_musicvideo = """ INSERT INTO musicvideo(idMVideo, idFile, c00, c04, c05, c06, c07, c08, c09, c10, add_musicvideo = """ INSERT INTO musicvideo(idMVideo, idFile, c00, c04, c05, c06, c07, c08, c09, c10,
c11, c12, premiered) c11, c12, premiered)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""" """
add_musicvideo_obj = ["{MvideoId}", "{FileId}", "{Title}", "{Runtime}", "{Directors}", "{Studio}", "{Year}", add_musicvideo_obj = ["{MvideoId}", "{FileId}", "{Title}", "{Runtime}", "{Directors}", "{Studio}", "{Year}",
"{Plot}","{Album}","{Artists}","{Genre}","{Index}","{Premiere}" "{Plot}", "{Album}", "{Artists}", "{Genre}", "{Index}", "{Premiere}"]
]
add_tvshow = """ INSERT INTO tvshow(idShow, c00, c01, c02, c04, c05, c08, c09, c10, c12, c13, c14, c15) add_tvshow = """ INSERT INTO tvshow(idShow, c00, c01, c02, c04, c05, c08, c09, c10, c12, c13, c14, c15)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""" """
add_tvshow_obj = ["{ShowId}", "{Title}", "{Plot}", "{Status}", "{RatingId}", "{Premiere}", "{Genre}", "{Title}", add_tvshow_obj = ["{ShowId}", "{Title}", "{Plot}", "{Status}", "{RatingId}", "{Premiere}", "{Genre}", "{Title}",
"disintegrate browse bug", "{Unique}","{Mpaa}","{Studio}","{SortTitle}" "disintegrate browse bug", "{Unique}", "{Mpaa}", "{Studio}", "{SortTitle}"]
]
add_season = """ INSERT INTO seasons(idSeason, idShow, season) add_season = """ INSERT INTO seasons(idSeason, idShow, season)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
@ -335,34 +286,26 @@ add_episode = """ INSERT INTO episode(idEpisode, idFile, c00, c01, c03, c04,
""" """
add_episode_obj = ["{EpisodeId}", "{FileId}", "{Title}", "{Plot}", "{RatingId}", "{Writers}", "{Premiere}", "{Runtime}", add_episode_obj = ["{EpisodeId}", "{FileId}", "{Title}", "{Plot}", "{RatingId}", "{Writers}", "{Premiere}", "{Runtime}",
"{Directors}", "{Season}", "{Index}", "{Title}", "{ShowId}", "{AirsBeforeSeason}", "{Directors}", "{Season}", "{Index}", "{Title}", "{ShowId}", "{AirsBeforeSeason}",
"{AirsBeforeEpisode}","{SeasonId}" "{AirsBeforeEpisode}", "{SeasonId}"]
]
add_art = """ INSERT INTO art(media_id, media_type, type, url) add_art = """ INSERT INTO art(media_id, media_type, type, url)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""" """
update_path = """ UPDATE path update_path = """ UPDATE path
SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ? SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?
WHERE idPath = ? WHERE idPath = ?
""" """
update_path_movie_obj = [ "{Path}","movies","metadata.local",1,"{PathId}" update_path_movie_obj = ["{Path}", "movies", "metadata.local", 1, "{PathId}"]
] update_path_toptvshow_obj = ["{TopLevel}", "tvshows", "metadata.local", 1, "{TopPathId}"]
update_path_toptvshow_obj = [ "{TopLevel}","tvshows","metadata.local",1,"{TopPathId}" update_path_tvshow_obj = ["{Path}", None, None, 1, "{PathId}"]
] update_path_episode_obj = ["{Path}", None, None, 1, "{PathId}"]
update_path_tvshow_obj = [ "{Path}",None,None,1,"{PathId}" update_path_mvideo_obj = ["{Path}", "musicvideos", None, 1, "{PathId}"]
]
update_path_episode_obj = [ "{Path}",None,None,1,"{PathId}"
]
update_path_mvideo_obj = [ "{Path}","musicvideos",None,1,"{PathId}"
]
update_file = """ UPDATE files update_file = """ UPDATE files
SET idPath = ?, strFilename = ?, dateAdded = ? SET idPath = ?, strFilename = ?, dateAdded = ?
WHERE idFile = ? WHERE idFile = ?
""" """
update_file_obj = [ "{PathId}","{Filename}","{DateAdded}","{FileId}" update_file_obj = ["{PathId}", "{Filename}", "{DateAdded}", "{FileId}"]
]
update_genres = """ INSERT OR REPLACE INTO genre_link(genre_id, media_id, media_type) update_genres = """ INSERT OR REPLACE INTO genre_link(genre_id, media_id, media_type)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
@ -398,66 +341,53 @@ update_movie = """ UPDATE movie
update_movie_obj = ["{Title}", "{Plot}", "{ShortPlot}", "{Tagline}", "{Votes}", "{RatingId}", update_movie_obj = ["{Title}", "{Plot}", "{ShortPlot}", "{Tagline}", "{Votes}", "{RatingId}",
"{Writers}", "{Year}", "{Unique}", "{SortTitle}", "{Runtime}", "{Writers}", "{Year}", "{Unique}", "{SortTitle}", "{Runtime}",
"{Mpaa}", "{Genre}", "{Directors}", "{Title}", "{Studio}", "{Trailer}", "{Mpaa}", "{Genre}", "{Directors}", "{Title}", "{Studio}", "{Trailer}",
"{Country}","{CriticRating}","{Year}","{MovieId}" "{Country}", "{CriticRating}", "{Year}", "{MovieId}"]
]
update_rating = """ UPDATE rating update_rating = """ UPDATE rating
SET media_id = ?, media_type = ?, rating_type = ?, rating = ?, votes = ? SET media_id = ?, media_type = ?, rating_type = ?, rating = ?, votes = ?
WHERE rating_id = ? WHERE rating_id = ?
""" """
update_rating_movie_obj = [ "{MovieId}","movie","default","{Rating}","{Votes}","{RatingId}" update_rating_movie_obj = ["{MovieId}", "movie", "default", "{Rating}", "{Votes}", "{RatingId}"]
] update_rating_tvshow_obj = ["{ShowId}", "tvshow", "default", "{Rating}", "{Votes}", "{RatingId}"]
update_rating_tvshow_obj = [ "{ShowId}","tvshow","default","{Rating}","{Votes}","{RatingId}" update_rating_episode_obj = ["{EpisodeId}", "episode", "default", "{Rating}", "{Votes}", "{RatingId}"]
]
update_rating_episode_obj = [ "{EpisodeId}","episode","default","{Rating}","{Votes}","{RatingId}"
]
update_unique_id = """ UPDATE uniqueid update_unique_id = """ UPDATE uniqueid
SET media_id = ?, media_type = ?, value = ?, type = ? SET media_id = ?, media_type = ?, value = ?, type = ?
WHERE uniqueid_id = ? WHERE uniqueid_id = ?
""" """
update_unique_id_movie_obj = [ "{MovieId}","movie","{UniqueId}","{ProviderName}","{Unique}" update_unique_id_movie_obj = ["{MovieId}", "movie", "{UniqueId}", "{ProviderName}", "{Unique}"]
] update_unique_id_tvshow_obj = ["{ShowId}", "tvshow", "{UniqueId}", "{ProviderName}", "{Unique}"]
update_unique_id_tvshow_obj = [ "{ShowId}","tvshow","{UniqueId}","{ProviderName}","{Unique}" update_unique_id_episode_obj = ["{EpisodeId}", "episode", "{UniqueId}", "{ProviderName}", "{Unique}"]
]
update_unique_id_episode_obj = [ "{EpisodeId}","episode","{UniqueId}","{ProviderName}","{Unique}"
]
update_country = """ INSERT OR REPLACE INTO country_link(country_id, media_id, media_type) update_country = """ INSERT OR REPLACE INTO country_link(country_id, media_id, media_type)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
update_country_obj = [ "{Countries}","{MovieId}","movie" update_country_obj = ["{Countries}", "{MovieId}", "movie"]
]
update_set = """ UPDATE sets update_set = """ UPDATE sets
SET strSet = ?, strOverview = ? SET strSet = ?, strOverview = ?
WHERE idSet = ? WHERE idSet = ?
""" """
update_set_obj = [ "{Title}", "{Overview}", "{SetId}" update_set_obj = ["{Title}", "{Overview}", "{SetId}"]
]
update_movie_set = """ UPDATE movie update_movie_set = """ UPDATE movie
SET idSet = ? SET idSet = ?
WHERE idMovie = ? WHERE idMovie = ?
""" """
update_movie_set_obj = [ "{SetId}","{MovieId}" update_movie_set_obj = ["{SetId}", "{MovieId}"]
]
update_musicvideo = """ UPDATE musicvideo update_musicvideo = """ UPDATE musicvideo
SET c00 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c08 = ?, c09 = ?, c10 = ?, SET c00 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c08 = ?, c09 = ?, c10 = ?,
c11 = ?, c12 = ?, premiered = ? c11 = ?, c12 = ?, premiered = ?
WHERE idMVideo = ? WHERE idMVideo = ?
""" """
update_musicvideo_obj = ["{Title}", "{Runtime}", "{Directors}", "{Studio}", "{Year}", "{Plot}", "{Album}", update_musicvideo_obj = ["{Title}", "{Runtime}", "{Directors}", "{Studio}", "{Year}", "{Plot}", "{Album}",
"{Artists}","{Genre}","{Index}","{Premiere}","{MvideoId}" "{Artists}", "{Genre}", "{Index}", "{Premiere}", "{MvideoId}"]
]
update_tvshow = """ UPDATE tvshow update_tvshow = """ UPDATE tvshow
SET c00 = ?, c01 = ?, c02 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?, c10 = ?, SET c00 = ?, c01 = ?, c02 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?, c10 = ?,
c12 = ?, c13 = ?, c14 = ?, c15 = ? c12 = ?, c13 = ?, c14 = ?, c15 = ?
WHERE idShow = ? WHERE idShow = ?
""" """
update_tvshow_obj = ["{Title}", "{Plot}", "{Status}", "{RatingId}", "{Premiere}", "{Genre}", "{Title}", update_tvshow_obj = ["{Title}", "{Plot}", "{Status}", "{RatingId}", "{Premiere}", "{Genre}", "{Title}",
"disintegrate browse bug","{Unique}","{Mpaa}","{Studio}","{SortTitle}","{ShowId}" "disintegrate browse bug", "{Unique}", "{Mpaa}", "{Studio}", "{SortTitle}", "{ShowId}"]
]
update_tvshow_link = """ INSERT OR REPLACE INTO tvshowlinkpath(idShow, idPath) update_tvshow_link = """ INSERT OR REPLACE INTO tvshowlinkpath(idShow, idPath)
VALUES (?, ?) VALUES (?, ?)
""" """
update_tvshow_link_obj = [ "{ShowId}","{PathId}" update_tvshow_link_obj = ["{ShowId}", "{PathId}"]
]
update_season = """ UPDATE seasons update_season = """ UPDATE seasons
SET name = ? SET name = ?
WHERE idSeason = ? WHERE idSeason = ?
@ -469,21 +399,17 @@ update_episode = """ UPDATE episode
""" """
update_episode_obj = ["{Title}", "{Plot}", "{RatingId}", "{Writers}", "{Premiere}", "{Runtime}", "{Directors}", update_episode_obj = ["{Title}", "{Plot}", "{RatingId}", "{Writers}", "{Premiere}", "{Runtime}", "{Directors}",
"{Season}", "{Index}", "{Title}", "{AirsBeforeSeason}", "{AirsBeforeEpisode}", "{SeasonId}", "{Season}", "{Index}", "{Title}", "{AirsBeforeSeason}", "{AirsBeforeEpisode}", "{SeasonId}",
"{ShowId}","{EpisodeId}" "{ShowId}", "{EpisodeId}"]
]
delete_path = """ DELETE FROM path delete_path = """ DELETE FROM path
WHERE idPath = ? WHERE idPath = ?
""" """
delete_path_obj = [ "{PathId}" delete_path_obj = ["{PathId}"]
]
delete_file = """ DELETE FROM files delete_file = """ DELETE FROM files
WHERE idFile = ? WHERE idFile = ?
""" """
delete_file_obj = [ "{Path}","{Filename}" delete_file_obj = ["{Path}", "{Filename}"]
]
delete_file_by_path = """ DELETE FROM files delete_file_by_path = """ DELETE FROM files
WHERE idPath = ? WHERE idPath = ?
AND strFileName = ? AND strFileName = ?
@ -507,33 +433,26 @@ delete_tag = """ DELETE FROM tag_link
AND media_id = ? AND media_id = ?
AND media_type = ? AND media_type = ?
""" """
delete_tag_movie_obj = [ "Favorite movies","{MovieId}","movie" delete_tag_movie_obj = ["Favorite movies", "{MovieId}", "movie"]
] delete_tag_mvideo_obj = ["Favorite musicvideos", "{MvideoId}", "musicvideo"]
delete_tag_mvideo_obj = [ "Favorite musicvideos","{MvideoId}","musicvideo" delete_tag_episode_obj = ["Favorite tvshows", "{KodiId}", "tvshow"]
]
delete_tag_episode_obj = [ "Favorite tvshows","{KodiId}","tvshow"
]
delete_movie = """ DELETE FROM movie delete_movie = """ DELETE FROM movie
WHERE idMovie = ? WHERE idMovie = ?
""" """
delete_movie_obj = [ "{KodiId}","{FileId}" delete_movie_obj = ["{KodiId}", "{FileId}"]
]
delete_set = """ DELETE FROM sets delete_set = """ DELETE FROM sets
WHERE idSet = ? WHERE idSet = ?
""" """
delete_set_obj = [ "{KodiId}" delete_set_obj = ["{KodiId}"]
]
delete_movie_set = """ UPDATE movie delete_movie_set = """ UPDATE movie
SET idSet = null SET idSet = null
WHERE idMovie = ? WHERE idMovie = ?
""" """
delete_movie_set_obj = [ "{MovieId}" delete_movie_set_obj = ["{MovieId}"]
]
delete_musicvideo = """ DELETE FROM musicvideo delete_musicvideo = """ DELETE FROM musicvideo
WHERE idMVideo = ? WHERE idMVideo = ?
""" """
delete_musicvideo_obj = [ "{MvideoId}", "{FileId}" delete_musicvideo_obj = ["{MvideoId}", "{FileId}"]
]
delete_tvshow = """ DELETE FROM tvshow delete_tvshow = """ DELETE FROM tvshow
WHERE idShow = ? WHERE idShow = ?
""" """

View file

@ -13,13 +13,11 @@ create_genre = """ SELECT coalesce(max(idGenre), 0)
""" """
get_artist = """ SELECT idArtist, strArtist get_artist = """ SELECT idArtist, strArtist
FROM artist FROM artist
WHERE strMusicBrainzArtistID = ? WHERE strMusicBrainzArtistID = ?
""" """
get_artist_obj = [ "{ArtistId}","{Name}","{UniqueId}" get_artist_obj = ["{ArtistId}", "{Name}", "{UniqueId}"]
]
get_artist_by_name = """ SELECT idArtist get_artist_by_name = """ SELECT idArtist
FROM artist FROM artist
WHERE strArtist = ? WHERE strArtist = ?
@ -29,26 +27,22 @@ get_artist_by_id = """ SELECT *
FROM artist FROM artist
WHERE idArtist = ? WHERE idArtist = ?
""" """
get_artist_by_id_obj = [ "{ArtistId}" get_artist_by_id_obj = ["{ArtistId}"]
]
get_album_by_id = """ SELECT * get_album_by_id = """ SELECT *
FROM album FROM album
WHERE idAlbum = ? WHERE idAlbum = ?
""" """
get_album_by_id_obj = [ "{AlbumId}" get_album_by_id_obj = ["{AlbumId}"]
]
get_song_by_id = """ SELECT * get_song_by_id = """ SELECT *
FROM song FROM song
WHERE idSong = ? WHERE idSong = ?
""" """
get_song_by_id_obj = [ "{SongId}" get_song_by_id_obj = ["{SongId}"]
]
get_album = """ SELECT idAlbum get_album = """ SELECT idAlbum
FROM album FROM album
WHERE strMusicBrainzAlbumID = ? WHERE strMusicBrainzAlbumID = ?
""" """
get_album_obj = [ "{AlbumId}","{Title}","{UniqueId}","{Artists}","album" get_album_obj = ["{AlbumId}", "{Title}", "{UniqueId}", "{Artists}", "album"]
]
get_album_by_name = """ SELECT idAlbum, strArtists get_album_by_name = """ SELECT idAlbum, strArtists
FROM album FROM album
WHERE strAlbum = ? WHERE strAlbum = ?
@ -65,8 +59,7 @@ get_album_artist72 = """ SELECT strArtistDisp
FROM album FROM album
WHERE idAlbum = ? WHERE idAlbum = ?
""" """
get_album_artist_obj = [ "{AlbumId}","{strAlbumArtists}" get_album_artist_obj = ["{AlbumId}", "{strAlbumArtists}"]
]
get_genre = """ SELECT idGenre get_genre = """ SELECT idGenre
FROM genre FROM genre
WHERE strGenre = ? WHERE strGenre = ?
@ -78,7 +71,6 @@ get_total_episodes = """ SELECT totalCount
""" """
add_artist = """ INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID) add_artist = """ INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
@ -91,8 +83,7 @@ add_album72 = """ INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbum
add_single = """ INSERT INTO album(idAlbum, strGenres, iYear, strReleaseType) add_single = """ INSERT INTO album(idAlbum, strGenres, iYear, strReleaseType)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""" """
add_single_obj = [ "{AlbumId}","{Genre}","{Year}","single" add_single_obj = ["{AlbumId}", "{Genre}", "{Year}", "single"]
]
add_song = """ INSERT INTO song(idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack, add_song = """ INSERT INTO song(idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack,
iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed, iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed,
rating, comment, dateAdded) rating, comment, dateAdded)
@ -105,33 +96,27 @@ add_song72 = """ INSERT INTO song(idSong, idAlbum, idPath, strArtistDisp,
""" """
add_song_obj = ["{SongId}", "{AlbumId}", "{PathId}", "{Artists}", "{Genre}", "{Title}", "{Index}", add_song_obj = ["{SongId}", "{AlbumId}", "{PathId}", "{Artists}", "{Genre}", "{Title}", "{Index}",
"{Runtime}", "{Year}", "{Filename}", "{UniqueId}", "{PlayCount}", "{DatePlayed}", "{Rating}", "{Runtime}", "{Year}", "{Filename}", "{UniqueId}", "{PlayCount}", "{DatePlayed}", "{Rating}",
"{Comment}","{DateAdded}" "{Comment}", "{DateAdded}"]
]
add_genre = """ INSERT INTO genre(idGenre, strGenre) add_genre = """ INSERT INTO genre(idGenre, strGenre)
VALUES (?, ?) VALUES (?, ?)
""" """
add_genres_obj = [ "{AlbumId}","{Genres}","album" add_genres_obj = ["{AlbumId}", "{Genres}", "album"]
]
update_path = """ UPDATE path update_path = """ UPDATE path
SET strPath = ? SET strPath = ?
WHERE idPath = ? WHERE idPath = ?
""" """
update_path_obj = [ "{Path}","{PathId}" update_path_obj = ["{Path}", "{PathId}"]
]
update_role = """ INSERT OR REPLACE INTO role(idRole, strRole) update_role = """ INSERT OR REPLACE INTO role(idRole, strRole)
VALUES (?, ?) VALUES (?, ?)
""" """
update_role_obj = [ 1,"Composer" update_role_obj = [1, "Composer"]
]
update_artist_name = """ UPDATE artist update_artist_name = """ UPDATE artist
SET strArtist = ? SET strArtist = ?
WHERE idArtist = ? WHERE idArtist = ?
""" """
update_artist_name_obj = [ "{Name}","{ArtistId}" update_artist_name_obj = ["{Name}", "{ArtistId}"]
]
update_artist = """ UPDATE artist update_artist = """ UPDATE artist
SET strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?, lastScraped = ? SET strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?, lastScraped = ?
WHERE idArtist = ? WHERE idArtist = ?
@ -139,13 +124,11 @@ update_artist = """ UPDATE artist
update_link = """ INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist) update_link = """ INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
update_link_obj = [ "{ArtistId}","{AlbumId}","{Name}" update_link_obj = ["{ArtistId}", "{AlbumId}", "{Name}"]
]
update_discography = """ INSERT OR REPLACE INTO discography(idArtist, strAlbum, strYear) update_discography = """ INSERT OR REPLACE INTO discography(idArtist, strAlbum, strYear)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
update_discography_obj = [ "{ArtistId}","{Title}","{Year}" update_discography_obj = ["{ArtistId}", "{Title}", "{Year}"]
]
update_album = """ UPDATE album update_album = """ UPDATE album
SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?, SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,
iUserrating = ?, lastScraped = ?, strReleaseType = ? iUserrating = ?, lastScraped = ?, strReleaseType = ?
@ -156,10 +139,7 @@ update_album72 = """ UPDATE album
iUserrating = ?, lastScraped = ?, bScrapedMBID = 1, strReleaseType = ? iUserrating = ?, lastScraped = ?, bScrapedMBID = 1, strReleaseType = ?
WHERE idAlbum = ? WHERE idAlbum = ?
""" """
update_album_obj = [ "{Artists}","{Year}","{Genre}","{Bio}","{Thumb}","{Rating}","{LastScraped}", update_album_obj = ["{Artists}", "{Year}", "{Genre}", "{Bio}", "{Thumb}", "{Rating}", "{LastScraped}", "album", "{AlbumId}"]
"album","{AlbumId}"
]
update_album_artist = """ UPDATE album update_album_artist = """ UPDATE album
SET strArtists = ? SET strArtists = ?
WHERE idAlbum = ? WHERE idAlbum = ?
@ -182,34 +162,28 @@ update_song72 = """ UPDATE song
""" """
update_song_obj = ["{AlbumId}", "{Artists}", "{Genre}", "{Title}", "{Index}", "{Runtime}", "{Year}", update_song_obj = ["{AlbumId}", "{Artists}", "{Genre}", "{Title}", "{Index}", "{Runtime}", "{Year}",
"{Filename}", "{PlayCount}", "{DatePlayed}", "{Rating}", "{Comment}", "{Filename}", "{PlayCount}", "{DatePlayed}", "{Rating}", "{Comment}",
"{DateAdded}","{SongId}" "{DateAdded}", "{SongId}"]
]
update_song_artist = """ INSERT OR REPLACE INTO song_artist(idArtist, idSong, idRole, iOrder, strArtist) update_song_artist = """ INSERT OR REPLACE INTO song_artist(idArtist, idSong, idRole, iOrder, strArtist)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""" """
update_song_artist_obj = [ "{ArtistId}","{SongId}",1,"{Index}","{Name}" update_song_artist_obj = ["{ArtistId}", "{SongId}", 1, "{Index}", "{Name}"]
]
update_song_album = """ INSERT OR REPLACE INTO albuminfosong(idAlbumInfoSong, idAlbumInfo, iTrack, update_song_album = """ INSERT OR REPLACE INTO albuminfosong(idAlbumInfoSong, idAlbumInfo, iTrack,
strTitle, iDuration) strTitle, iDuration)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""" """
update_song_album_obj = [ "{SongId}","{AlbumId}","{Index}","{Title}","{Runtime}" update_song_album_obj = ["{SongId}", "{AlbumId}", "{Index}", "{Title}", "{Runtime}"]
]
update_song_rating = """ UPDATE song update_song_rating = """ UPDATE song
SET iTimesPlayed = ?, lastplayed = ?, rating = ? SET iTimesPlayed = ?, lastplayed = ?, rating = ?
WHERE idSong = ? WHERE idSong = ?
""" """
update_song_rating_obj = [ "{PlayCount}","{DatePlayed}","{Rating}","{KodiId}" update_song_rating_obj = ["{PlayCount}", "{DatePlayed}", "{Rating}", "{KodiId}"]
]
update_genre_album = """ INSERT OR REPLACE INTO album_genre(idGenre, idAlbum) update_genre_album = """ INSERT OR REPLACE INTO album_genre(idGenre, idAlbum)
VALUES (?, ?) VALUES (?, ?)
""" """
update_genre_song = """ INSERT OR REPLACE INTO song_genre(idGenre, idSong) update_genre_song = """ INSERT OR REPLACE INTO song_genre(idGenre, idSong)
VALUES (?, ?) VALUES (?, ?)
""" """
update_genre_song_obj = [ "{SongId}","{Genres}","song" update_genre_song_obj = ["{SongId}", "{Genres}", "song"]
]
delete_genres_album = """ DELETE FROM album_genre delete_genres_album = """ DELETE FROM album_genre

View file

@ -5,7 +5,6 @@ get_cache = """ SELECT cachedurl
""" """
delete_cache = """ DELETE FROM texture delete_cache = """ DELETE FROM texture
WHERE url = ? WHERE url = ?
""" """

View file

@ -16,7 +16,6 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
class TVShows(Kodi): class TVShows(Kodi):
def __init__(self, cursor): def __init__(self, cursor):
self.cursor = cursor self.cursor = cursor

View file

@ -103,13 +103,11 @@ class Movies(KodiDb):
obj['Tags'] = tags obj['Tags'] = tags
if update: if update:
self.movie_update(obj) self.movie_update(obj)
else: else:
self.movie_add(obj) self.movie_add(obj)
self.update_path(*values(obj, QU.update_path_movie_obj)) self.update_path(*values(obj, QU.update_path_movie_obj))
self.update_file(*values(obj, QU.update_file_obj)) self.update_file(*values(obj, QU.update_file_obj))
self.add_tags(*values(obj, QU.add_tags_movie_obj)) self.add_tags(*values(obj, QU.add_tags_movie_obj))
@ -192,7 +190,6 @@ class Movies(KodiDb):
} }
obj['Filename'] = "%s?%s" % (obj['Path'], urllib.urlencode(params)) obj['Filename'] = "%s?%s" % (obj['Path'], urllib.urlencode(params))
@stop() @stop()
@jellyfin_item() @jellyfin_item()
def boxset(self, item, e_item): def boxset(self, item, e_item):

View file

@ -77,13 +77,11 @@ class Music(KodiDb):
if obj['Backdrops']: if obj['Backdrops']:
obj['Backdrops'] = "<fanart>%s</fanart>" % obj['Backdrops'][0] obj['Backdrops'] = "<fanart>%s</fanart>" % obj['Backdrops'][0]
if update: if update:
self.artist_update(obj) self.artist_update(obj)
else: else:
self.artist_add(obj) self.artist_add(obj)
self.update(obj['Genre'], obj['Bio'], obj['Thumb'], obj['Backdrops'], obj['LastScraped'], obj['ArtistId']) self.update(obj['Genre'], obj['Bio'], obj['Thumb'], obj['Backdrops'], obj['LastScraped'], obj['ArtistId'])
self.artwork.add(obj['Artwork'], obj['ArtistId'], "artist") self.artwork.add(obj['Artwork'], obj['ArtistId'], "artist")
self.item_ids.append(obj['Id']) self.item_ids.append(obj['Id'])
@ -106,7 +104,6 @@ class Music(KodiDb):
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj)) self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
LOG.info("UPDATE artist [%s] %s: %s", obj['ArtistId'], obj['Name'], obj['Id']) LOG.info("UPDATE artist [%s] %s: %s", obj['ArtistId'], obj['Name'], obj['Id'])
@stop() @stop()
@jellyfin_item() @jellyfin_item()
def album(self, item, e_item): def album(self, item, e_item):
@ -144,13 +141,11 @@ class Music(KodiDb):
if obj['Thumb']: if obj['Thumb']:
obj['Thumb'] = "<thumb>%s</thumb>" % obj['Thumb'] obj['Thumb'] = "<thumb>%s</thumb>" % obj['Thumb']
if update: if update:
self.album_update(obj) self.album_update(obj)
else: else:
self.album_add(obj) self.album_add(obj)
self.artist_link(obj) self.artist_link(obj)
self.artist_discography(obj) self.artist_discography(obj)
self.update_album(*values(obj, QU.update_album_obj)) self.update_album(*values(obj, QU.update_album_obj))
@ -217,7 +212,6 @@ class Music(KodiDb):
self.link(*values(temp_obj, QU.update_link_obj)) self.link(*values(temp_obj, QU.update_link_obj))
self.item_ids.append(temp_obj['Id']) self.item_ids.append(temp_obj['Id'])
@stop() @stop()
@jellyfin_item() @jellyfin_item()
def song(self, item, e_item): def song(self, item, e_item):
@ -269,13 +263,11 @@ class Music(KodiDb):
if obj['Disc'] != 1: if obj['Disc'] != 1:
obj['Index'] = obj['Disc'] * 2 ** 16 + obj['Index'] obj['Index'] = obj['Disc'] * 2 ** 16 + obj['Index']
if update: if update:
self.song_update(obj) self.song_update(obj)
else: else:
self.song_add(obj) self.song_add(obj)
self.link_song_album(*values(obj, QU.update_song_album_obj)) self.link_song_album(*values(obj, QU.update_song_album_obj))
self.add_role(*values(obj, QU.update_role_obj)) # defaultt role self.add_role(*values(obj, QU.update_role_obj)) # defaultt role
self.song_artist_link(obj) self.song_artist_link(obj)
@ -415,7 +407,6 @@ class Music(KodiDb):
obj['AlbumId'] = self.create_entry_album() obj['AlbumId'] = self.create_entry_album()
self.add_single(*values(obj, QU.add_single_obj)) self.add_single(*values(obj, QU.add_single_obj))
@stop() @stop()
@jellyfin_item() @jellyfin_item()
def userdata(self, item, e_item): def userdata(self, item, e_item):

View file

@ -114,13 +114,11 @@ class MusicVideos(KodiDb):
obj['Tags'] = tags obj['Tags'] = tags
if update: if update:
self.musicvideo_update(obj) self.musicvideo_update(obj)
else: else:
self.musicvideo_add(obj) self.musicvideo_add(obj)
self.update_path(*values(obj, QU.update_path_mvideo_obj)) self.update_path(*values(obj, QU.update_path_mvideo_obj))
self.update_file(*values(obj, QU.update_file_obj)) self.update_file(*values(obj, QU.update_file_obj))
self.add_tags(*values(obj, QU.add_tags_mvideo_obj)) self.add_tags(*values(obj, QU.add_tags_mvideo_obj))
@ -176,7 +174,6 @@ class MusicVideos(KodiDb):
} }
obj['Filename'] = "%s?%s" % (obj['Path'], urllib.urlencode(params)) obj['Filename'] = "%s?%s" % (obj['Path'], urllib.urlencode(params))
@stop() @stop()
@jellyfin_item() @jellyfin_item()
def userdata(self, item, e_item): def userdata(self, item, e_item):

View file

@ -76,7 +76,6 @@ class TVShows(KodiDb):
update = False update = False
LOG.info("ShowId %s missing from kodi. repairing the entry.", obj['ShowId']) LOG.info("ShowId %s missing from kodi. repairing the entry.", obj['ShowId'])
obj['Path'] = API.get_file_path(obj['Path']) obj['Path'] = API.get_file_path(obj['Path'])
obj['LibraryId'] = library['Id'] obj['LibraryId'] = library['Id']
obj['LibraryName'] = library['Name'] obj['LibraryName'] = library['Name']
@ -107,13 +106,11 @@ class TVShows(KodiDb):
obj['Tags'] = tags obj['Tags'] = tags
if update: if update:
self.tvshow_update(obj) self.tvshow_update(obj)
else: else:
self.tvshow_add(obj) self.tvshow_add(obj)
self.link(*values(obj, QU.update_tvshow_link_obj)) self.link(*values(obj, QU.update_tvshow_link_obj))
self.update_path(*values(obj, QU.update_path_tvshow_obj)) self.update_path(*values(obj, QU.update_path_tvshow_obj))
self.add_tags(*values(obj, QU.add_tags_tvshow_obj)) self.add_tags(*values(obj, QU.add_tags_tvshow_obj))
@ -209,7 +206,6 @@ class TVShows(KodiDb):
obj['TopLevel'] = "plugin://plugin.video.jellyfin/" obj['TopLevel'] = "plugin://plugin.video.jellyfin/"
obj['Path'] = "%s%s/" % (obj['TopLevel'], obj['Id']) obj['Path'] = "%s%s/" % (obj['TopLevel'], obj['Id'])
@stop() @stop()
def season(self, item, show_id=None): def season(self, item, show_id=None):
@ -244,7 +240,6 @@ class TVShows(KodiDb):
self.artwork.add(obj['Artwork'], obj['SeasonId'], "season") self.artwork.add(obj['Artwork'], obj['SeasonId'], "season")
LOG.info("UPDATE season [%s/%s] %s: %s", obj['ShowId'], obj['SeasonId'], obj['Title'] or obj['Index'], obj['Id']) LOG.info("UPDATE season [%s/%s] %s: %s", obj['ShowId'], obj['SeasonId'], obj['Title'] or obj['Index'], obj['Id'])
@stop() @stop()
@jellyfin_item() @jellyfin_item()
def episode(self, item, e_item): def episode(self, item, e_item):
@ -286,7 +281,6 @@ class TVShows(KodiDb):
update = False update = False
LOG.info("EpisodeId %s missing from kodi. repairing the entry.", obj['EpisodeId']) LOG.info("EpisodeId %s missing from kodi. repairing the entry.", obj['EpisodeId'])
obj['Path'] = API.get_file_path(obj['Path']) obj['Path'] = API.get_file_path(obj['Path'])
obj['Index'] = obj['Index'] or -1 obj['Index'] = obj['Index'] or -1
obj['Writers'] = " / ".join(obj['Writers'] or []) obj['Writers'] = " / ".join(obj['Writers'] or [])
@ -329,13 +323,11 @@ class TVShows(KodiDb):
obj['SeasonId'] = self.get_season(*values(obj, QU.get_season_episode_obj)) obj['SeasonId'] = self.get_season(*values(obj, QU.get_season_episode_obj))
if update: if update:
self.episode_update(obj) self.episode_update(obj)
else: else:
self.episode_add(obj) self.episode_add(obj)
self.update_path(*values(obj, QU.update_path_episode_obj)) self.update_path(*values(obj, QU.update_path_episode_obj))
self.update_file(*values(obj, QU.update_file_obj)) self.update_file(*values(obj, QU.update_file_obj))
self.add_people(*values(obj, QU.add_people_episode_obj)) self.add_people(*values(obj, QU.add_people_episode_obj))
@ -440,7 +432,6 @@ class TVShows(KodiDb):
return True return True
@stop() @stop()
@jellyfin_item() @jellyfin_item()
def userdata(self, item, e_item): def userdata(self, item, e_item):

View file

@ -338,7 +338,6 @@ class Player(xbmc.Player):
return return
result = JSONRPC('Application.GetProperties').execute({'properties': ["volume", "muted"]}) result = JSONRPC('Application.GetProperties').execute({'properties': ["volume", "muted"]})
result = result.get('result', {}) result = result.get('result', {})
item['Volume'] = result.get('volume') item['Volume'] = result.get('volume')
@ -415,7 +414,6 @@ class Player(xbmc.Player):
LOG.info("<[ transcode/%s ]", item['Id']) LOG.info("<[ transcode/%s ]", item['Id'])
item['Server'].jellyfin.close_transcode(item['DeviceId']) item['Server'].jellyfin.close_transcode(item['DeviceId'])
path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/temp/").decode('utf-8') path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/temp/").decode('utf-8')
if xbmcvfs.exists(path): if xbmcvfs.exists(path):

View file

@ -136,6 +136,7 @@ def verify_kodi_defaults():
if not xbmcvfs.exists(playlist_path): if not xbmcvfs.exists(playlist_path):
xbmcvfs.mkdirs(playlist_path) xbmcvfs.mkdirs(playlist_path)
class Views(object): class Views(object):
sync = None sync = None
@ -421,7 +422,6 @@ class Views(object):
etree.SubElement(xml, 'match') etree.SubElement(xml, 'match')
etree.SubElement(xml, 'content') etree.SubElement(xml, 'content')
label = xml.find('label') label = xml.find('label')
label.text = str(name) if type(name) == int else name label.text = str(name) if type(name) == int else name
@ -661,7 +661,6 @@ class Views(object):
else: else:
etree.SubElement(root, 'content').text = "episodes" etree.SubElement(root, 'content').text = "episodes"
def order_media_folders(self, folders): def order_media_folders(self, folders):
''' Returns a list of sorted media folders based on the Jellyfin views. ''' Returns a list of sorted media folders based on the Jellyfin views.

View file

@ -17,6 +17,7 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
################################################################################################# #################################################################################################
class WebService(threading.Thread): class WebService(threading.Thread):
''' Run a webservice to trigger playback. ''' Run a webservice to trigger playback.
@ -142,4 +143,3 @@ class requestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self.send_error(500, "Exception occurred: %s" % error) self.send_error(500, "Exception occurred: %s" % error)
return return