diff --git a/jellyfin_kodi/database/__init__.py b/jellyfin_kodi/database/__init__.py index 54a2fa51..605712de 100644 --- a/jellyfin_kodi/database/__init__.py +++ b/jellyfin_kodi/database/__init__.py @@ -20,6 +20,8 @@ from helper import LazyLogger LOG = LazyLogger(__name__) +ADDON_DATA = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/") + ################################################################################################# @@ -67,8 +69,8 @@ class Database(object): contents = query.fetchall() if contents: for item in contents: - newPath = item[1].replace('/emby/', '/') - self.conn.execute('UPDATE path SET strPath = "{}" WHERE idPath = "{}"'.format(newPath, item[0])) + new_path = item[1].replace('/emby/', '/') + self.conn.execute('UPDATE path SET strPath = "{}" WHERE idPath = "{}"'.format(new_path, item[0])) return self @@ -249,16 +251,14 @@ def reset(): if dialog("yesno", heading="{jellyfin}", line1=translate(33086)): reset_artwork() - addon_data = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/") - if dialog("yesno", heading="{jellyfin}", line1=translate(33087)): - xbmcvfs.delete(os.path.join(addon_data, "settings.xml")) - xbmcvfs.delete(os.path.join(addon_data, "data.json")) + xbmcvfs.delete(os.path.join(ADDON_DATA, "settings.xml")) + xbmcvfs.delete(os.path.join(ADDON_DATA, "data.json")) LOG.info("[ reset settings ]") - if xbmcvfs.exists(os.path.join(addon_data, "sync.json")): - xbmcvfs.delete(os.path.join(addon_data, "sync.json")) + if xbmcvfs.exists(os.path.join(ADDON_DATA, "sync.json")): + xbmcvfs.delete(os.path.join(ADDON_DATA, "sync.json")) settings('enableMusic.bool', False) settings('MinimumSetup', "") @@ -341,13 +341,11 @@ def reset_artwork(): def get_sync(): - path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/") - - if not xbmcvfs.exists(path): - xbmcvfs.mkdirs(path) + if not xbmcvfs.exists(ADDON_DATA): + xbmcvfs.mkdirs(ADDON_DATA) try: - with open(os.path.join(path, 'sync.json'), 'rb') as infile: + with open(os.path.join(ADDON_DATA, 'sync.json'), 'rb') as infile: sync = json.load(infile, encoding='utf-8') except Exception: sync = {} @@ -362,14 +360,12 @@ def get_sync(): def save_sync(sync): - path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/") - - if not xbmcvfs.exists(path): - xbmcvfs.mkdirs(path) + if not xbmcvfs.exists(ADDON_DATA): + xbmcvfs.mkdirs(ADDON_DATA) sync['Date'] = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') - with open(os.path.join(path, 'sync.json'), 'wb') as outfile: + with open(os.path.join(ADDON_DATA, 'sync.json'), 'wb') as outfile: data = json.dumps(sync, sort_keys=True, indent=4, ensure_ascii=False) if isinstance(data, text_type): data = data.encode('utf-8') @@ -378,22 +374,20 @@ def save_sync(sync): def get_credentials(): - path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/") - - if not xbmcvfs.exists(path): - xbmcvfs.mkdirs(path) + if not xbmcvfs.exists(ADDON_DATA): + xbmcvfs.mkdirs(ADDON_DATA) try: - with open(os.path.join(path, 'data.json'), 'rb') as infile: + with open(os.path.join(ADDON_DATA, 'data.json'), 'rb') as infile: credentials = json.load(infile, encoding='utf8') except Exception: try: - with open(os.path.join(path, 'data.txt'), 'rb') as infile: + with open(os.path.join(ADDON_DATA, 'data.txt'), 'rb') as infile: credentials = json.load(infile, encoding='utf-8') save_credentials(credentials) - xbmcvfs.delete(os.path.join(path, 'data.txt')) + xbmcvfs.delete(os.path.join(ADDON_DATA, 'data.txt')) except Exception: credentials = {} @@ -422,12 +416,11 @@ def get_credentials(): def save_credentials(credentials): credentials = credentials or {} - path = xbmc.translatePath("special://profile/addon_data/plugin.video.jellyfin/") - if not xbmcvfs.exists(path): - xbmcvfs.mkdirs(path) + if not xbmcvfs.exists(ADDON_DATA): + xbmcvfs.mkdirs(ADDON_DATA) try: - with open(os.path.join(path, 'data.json'), 'wb') as outfile: + with open(os.path.join(ADDON_DATA, 'data.json'), 'wb') as outfile: data = json.dumps(credentials, sort_keys=True, indent=4, ensure_ascii=False) if isinstance(data, text_type): data = data.encode('utf-8') diff --git a/jellyfin_kodi/dialogs/context.py b/jellyfin_kodi/dialogs/context.py index 7f90872d..e4ce520f 100644 --- a/jellyfin_kodi/dialogs/context.py +++ b/jellyfin_kodi/dialogs/context.py @@ -34,8 +34,11 @@ class ContextMenu(xbmcgui.WindowXMLDialog): xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs) - def set_options(self, options=[]): - self._options = options + def set_options(self, options=None): + if options is None: + self._options = [] + else: + self._options = options def is_selected(self): return True if self.selected_option else False diff --git a/jellyfin_kodi/dialogs/loginmanual.py b/jellyfin_kodi/dialogs/loginmanual.py index c8749b9c..b2ef2157 100644 --- a/jellyfin_kodi/dialogs/loginmanual.py +++ b/jellyfin_kodi/dialogs/loginmanual.py @@ -3,12 +3,10 @@ from __future__ import division, absolute_import, print_function, unicode_litera ################################################################################################## -import os - from six import iteritems -from kodi_six import xbmcgui, xbmcaddon +from kodi_six import xbmcgui -from helper import translate, addon_id +from helper import translate from helper import LazyLogger ################################################################################################## @@ -97,9 +95,8 @@ class LoginManual(xbmcgui.WindowXMLDialog): if action in (ACTION_BACK, ACTION_PARENT_DIR, ACTION_PREVIOUS_MENU): self.close() - def _add_editcontrol(self, x, y, height, width, password=0): + def _add_editcontrol(self, x, y, height, width, password=False): - media = os.path.join(xbmcaddon.Addon(addon_id()).getAddonInfo('path'), 'resources', 'skins', 'default', 'media') control = xbmcgui.ControlEdit(0, 0, 0, 0, label="User", font="font13", diff --git a/jellyfin_kodi/dialogs/resume.py b/jellyfin_kodi/dialogs/resume.py index 9639227a..4cfca7ea 100644 --- a/jellyfin_kodi/dialogs/resume.py +++ b/jellyfin_kodi/dialogs/resume.py @@ -46,12 +46,12 @@ class ResumeDialog(xbmcgui.WindowXMLDialog): if action in (ACTION_BACK, ACTION_PARENT_DIR, ACTION_PREVIOUS_MENU): self.close() - def onClick(self, controlID): + def onClick(self, control_id): - if controlID == RESUME: + if control_id == RESUME: self.selected_option = 1 self.close() - if controlID == START_BEGINNING: + if control_id == START_BEGINNING: self.selected_option = 0 self.close() diff --git a/jellyfin_kodi/dialogs/servermanual.py b/jellyfin_kodi/dialogs/servermanual.py index 469d3099..78bd537c 100644 --- a/jellyfin_kodi/dialogs/servermanual.py +++ b/jellyfin_kodi/dialogs/servermanual.py @@ -3,13 +3,12 @@ from __future__ import division, absolute_import, print_function, unicode_litera ################################################################################################## -import os import re from six import iteritems -from kodi_six import xbmcgui, xbmcaddon +from kodi_six import xbmcgui -from helper import translate, addon_id +from helper import translate from jellyfin.connection_manager import CONNECTION_STATE from helper import LazyLogger @@ -98,7 +97,6 @@ class ServerManual(xbmcgui.WindowXMLDialog): def _add_editcontrol(self, x, y, height, width): - media = os.path.join(xbmcaddon.Addon(addon_id()).getAddonInfo('path'), 'resources', 'skins', 'default', 'media') control = xbmcgui.ControlEdit(0, 0, 0, 0, label="User", font="font13", diff --git a/jellyfin_kodi/downloader.py b/jellyfin_kodi/downloader.py index a1e42297..3b0e0ab9 100644 --- a/jellyfin_kodi/downloader.py +++ b/jellyfin_kodi/downloader.py @@ -43,7 +43,11 @@ def browse_info(): ) -def _http(action, url, request={}, server_id=None): +def _http(action, url, request=None, server_id=None): + + if request is None: + request = {} + request.update({'url': url, 'type': action}) return Jellyfin(server_id).http.request(request) @@ -268,8 +272,11 @@ def _get_items(query, server_id=None): params_copy['Limit'] = count return params_copy - query_params = [get_query_params(params, offset, LIMIT) \ - for offset in range(params['StartIndex'], items['TotalRecordCount'], LIMIT)] + query_params = [ + get_query_params(params, offset, LIMIT) + for offset + in range(params['StartIndex'], items['TotalRecordCount'], LIMIT) + ] # multiprocessing.dummy.Pool completes all requests in multiple threads but has to # complete all tasks before allowing any results to be processed. ThreadPoolExecutor diff --git a/jellyfin_kodi/entrypoint/default.py b/jellyfin_kodi/entrypoint/default.py index 288fdc4f..9fa936f2 100644 --- a/jellyfin_kodi/entrypoint/default.py +++ b/jellyfin_kodi/entrypoint/default.py @@ -22,6 +22,10 @@ from helper import LazyLogger LOG = LazyLogger(__name__) +ADDON_BASE_URL = sys.argv[0] +PROCESS_HANDLE = int(sys.argv[1]) +QUERY_STRING = sys.argv[2] + ################################################################################################# @@ -32,8 +36,8 @@ class Events(object): ''' Parse the parameters. Reroute to our service.py where user is fully identified already. ''' - base_url = sys.argv[0] - path = sys.argv[2] + base_url = ADDON_BASE_URL + path = QUERY_STRING try: params = dict(parse_qsl(path[1:])) @@ -183,8 +187,8 @@ def listing(): if settings('backupPath'): directory(translate(33092), "plugin://plugin.video.jellyfin/?mode=backup", False) - xbmcplugin.setContent(int(sys.argv[1]), 'files') - xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.setContent(PROCESS_HANDLE, 'files') + xbmcplugin.endOfDirectory(PROCESS_HANDLE) def directory(label, path, folder=True, artwork=None, fanart=None, context=None): @@ -196,7 +200,7 @@ def directory(label, path, folder=True, artwork=None, fanart=None, context=None) if context: li.addContextMenuItems(context) - xbmcplugin.addDirectoryItem(int(sys.argv[1]), path, li, folder) + xbmcplugin.addDirectoryItem(PROCESS_HANDLE, path, li, folder) return li @@ -224,8 +228,8 @@ def manage_libraries(): directory(translate(33184), "plugin://plugin.video.jellyfin/?mode=removelibs", False) directory(translate(33060), "plugin://plugin.video.jellyfin/?mode=thememedia", False) - xbmcplugin.setContent(int(sys.argv[1]), 'files') - xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.setContent(PROCESS_HANDLE, 'files') + xbmcplugin.endOfDirectory(PROCESS_HANDLE) def browse(media, view_id=None, folder=None, server_id=None): @@ -259,7 +263,7 @@ def browse(media, view_id=None, folder=None, server_id=None): if view_id: view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get() - xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name']) + xbmcplugin.setPluginCategory(PROCESS_HANDLE, view['Name']) content_type = "files" @@ -381,16 +385,16 @@ def browse(media, view_id=None, folder=None, server_id=None): list_li.append((li.getProperty('path'), li, False)) - xbmcplugin.addDirectoryItems(int(sys.argv[1]), list_li, len(list_li)) + xbmcplugin.addDirectoryItems(PROCESS_HANDLE, list_li, len(list_li)) if content_type == 'images': - xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_TITLE) - xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE) - xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RATING) - xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RUNTIME) + xbmcplugin.addSortMethod(PROCESS_HANDLE, xbmcplugin.SORT_METHOD_VIDEO_TITLE) + xbmcplugin.addSortMethod(PROCESS_HANDLE, xbmcplugin.SORT_METHOD_DATE) + xbmcplugin.addSortMethod(PROCESS_HANDLE, xbmcplugin.SORT_METHOD_VIDEO_RATING) + xbmcplugin.addSortMethod(PROCESS_HANDLE, xbmcplugin.SORT_METHOD_VIDEO_RUNTIME) - xbmcplugin.setContent(int(sys.argv[1]), content_type) - xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.setContent(PROCESS_HANDLE, content_type) + xbmcplugin.endOfDirectory(PROCESS_HANDLE) def browse_subfolders(media, view_id, server_id=None): @@ -400,7 +404,7 @@ def browse_subfolders(media, view_id, server_id=None): from views import DYNNODES view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get() - xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name']) + xbmcplugin.setPluginCategory(PROCESS_HANDLE, view['Name']) nodes = DYNNODES[media] for node in nodes: @@ -415,8 +419,8 @@ def browse_subfolders(media, view_id, server_id=None): path = "%s?%s" % ("plugin://plugin.video.jellyfin/", urlencode(params)) directory(node[1] or view['Name'], path) - xbmcplugin.setContent(int(sys.argv[1]), 'files') - xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.setContent(PROCESS_HANDLE, 'files') + xbmcplugin.endOfDirectory(PROCESS_HANDLE) def browse_letters(media, view_id, server_id=None): @@ -426,7 +430,7 @@ def browse_letters(media, view_id, server_id=None): letters = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ" view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get() - xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name']) + xbmcplugin.setPluginCategory(PROCESS_HANDLE, view['Name']) for node in letters: @@ -440,8 +444,8 @@ def browse_letters(media, view_id, server_id=None): path = "%s?%s" % ("plugin://plugin.video.jellyfin/", urlencode(params)) directory(node, path) - xbmcplugin.setContent(int(sys.argv[1]), 'files') - xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.setContent(PROCESS_HANDLE, 'files') + xbmcplugin.endOfDirectory(PROCESS_HANDLE) def get_folder_type(item, content_type=None): @@ -521,8 +525,8 @@ def get_fanart(item_id, path, server_id=None): li = xbmcgui.ListItem(file, path=fanart) list_li.append((fanart, li, False)) - xbmcplugin.addDirectoryItems(int(sys.argv[1]), list_li, len(list_li)) - xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.addDirectoryItems(PROCESS_HANDLE, list_li, len(list_li)) + xbmcplugin.endOfDirectory(PROCESS_HANDLE) def get_video_extras(item_id, path, server_id=None): @@ -536,8 +540,8 @@ def get_video_extras(item_id, path, server_id=None): if not item_id: return - item = TheVoid('GetItem', {'ServerId': server_id, 'Id': item_id}).get() - # TODO + TheVoid('GetItem', {'ServerId': server_id, 'Id': item_id}).get() + # TODO: Investigate the void (issue #228) """ def getVideoFiles(jellyfinId,jellyfinPath): @@ -558,12 +562,12 @@ def get_video_extras(item_id, path, server_id=None): for file in files: file = filelocation + file li = xbmcgui.ListItem(file, path=file) - xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=file, listitem=li) + xbmcplugin.addDirectoryItem(handle=PROCESS_HANDLE, url=file, listitem=li) for dir in dirs: dir = filelocation + dir li = xbmcgui.ListItem(dir, path=dir) - xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=dir, listitem=li, isFolder=True) - #xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.addDirectoryItem(handle=PROCESS_HANDLE, url=dir, listitem=li, isFolder=True) + #xbmcplugin.endOfDirectory(PROCESS_HANDLE) """ @@ -643,9 +647,9 @@ def get_next_episodes(item_id, limit): if len(list_li) == limit: break - xbmcplugin.addDirectoryItems(int(sys.argv[1]), list_li, len(list_li)) - xbmcplugin.setContent(int(sys.argv[1]), 'episodes') - xbmcplugin.endOfDirectory(int(sys.argv[1])) + xbmcplugin.addDirectoryItems(PROCESS_HANDLE, list_li, len(list_li)) + xbmcplugin.setContent(PROCESS_HANDLE, 'episodes') + xbmcplugin.endOfDirectory(PROCESS_HANDLE) def create_listitem(item): diff --git a/jellyfin_kodi/helper/playutils.py b/jellyfin_kodi/helper/playutils.py index 7ee21cb1..d6b5259d 100644 --- a/jellyfin_kodi/helper/playutils.py +++ b/jellyfin_kodi/helper/playutils.py @@ -12,9 +12,9 @@ from kodi_six import xbmc, xbmcvfs import client import requests from downloader import TheVoid +from helper import LazyLogger from . import translate, settings, window, dialog, api -from helper import LazyLogger ################################################################################################# @@ -152,7 +152,7 @@ class PlayUtils(object): def is_file_exists(self, source): - path = self.direct_play(source) + self.direct_play(source) if xbmcvfs.exists(self.info['Path']): LOG.info("Path exists.") diff --git a/jellyfin_kodi/helper/utils.py b/jellyfin_kodi/helper/utils.py index 84da6b6c..c7e92a1b 100644 --- a/jellyfin_kodi/helper/utils.py +++ b/jellyfin_kodi/helper/utils.py @@ -244,8 +244,6 @@ def validate(path): if window('jellyfin_pathverified.bool'): return True - path = path if os.path.supports_unicode_filenames else path - if not xbmcvfs.exists(path): LOG.info("Could not find %s", path) diff --git a/jellyfin_kodi/jellyfin/__init__.py b/jellyfin_kodi/jellyfin/__init__.py index 38d33472..688a3c36 100644 --- a/jellyfin_kodi/jellyfin/__init__.py +++ b/jellyfin_kodi/jellyfin/__init__.py @@ -5,9 +5,10 @@ from __future__ import division, absolute_import, print_function, unicode_litera import logging -from .client import JellyfinClient from helper import has_attribute, LazyLogger +from .client import JellyfinClient + ################################################################################################# LOG = LazyLogger() diff --git a/jellyfin_kodi/jellyfin/api.py b/jellyfin_kodi/jellyfin/api.py index cbf2e552..48c8f023 100644 --- a/jellyfin_kodi/jellyfin/api.py +++ b/jellyfin_kodi/jellyfin/api.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- from __future__ import division, absolute_import, print_function, unicode_literals -import requests + import json +import requests + from helper.utils import settings from helper import LazyLogger @@ -46,7 +48,10 @@ class API(object): self.config = client.config self.default_timeout = 5 - def _http(self, action, url, request={}): + def _http(self, action, url, request=None): + if request is None: + request = {} + request.update({'type': action, 'handler': url}) return self.client.request(request) @@ -392,7 +397,7 @@ class API(object): def login(self, server_url, username, password=""): path = "Users/AuthenticateByName" - authData = { + auth_data = { "username": username, "Pw": password } @@ -402,7 +407,7 @@ class API(object): try: LOG.info("Trying to login to %s/%s as %s" % (server_url, path, username)) - response = self.send_request(server_url, path, method="post", headers=headers, data=json.dumps(authData)) + response = self.send_request(server_url, path, method="post", headers=headers, data=json.dumps(auth_data)) if response.status_code == 200: return response.json() @@ -418,13 +423,11 @@ class API(object): return {} def validate_authentication_token(self, server): - - url = "%s/%s" % (server['address'], "system/info") - authTokenHeader = { + auth_token_header = { 'X-MediaBrowser-Token': server['AccessToken'] } headers = self.get_default_headers() - headers.update(authTokenHeader) + headers.update(auth_token_header) response = self.send_request(server['address'], "system/info", headers=headers) return response.json() if response.status_code == 200 else {} diff --git a/jellyfin_kodi/jellyfin/connection_manager.py b/jellyfin_kodi/jellyfin/connection_manager.py index 353ce022..d6e87115 100644 --- a/jellyfin_kodi/jellyfin/connection_manager.py +++ b/jellyfin_kodi/jellyfin/connection_manager.py @@ -5,18 +5,17 @@ from __future__ import division, absolute_import, print_function, unicode_litera import json import socket -import time from datetime import datetime from operator import itemgetter +import traceback import urllib3 -from .credentials import Credentials -from .http import HTTP # noqa: I201,I100 -from .api import API -import traceback from helper import LazyLogger +from .credentials import Credentials +from .api import API + ################################################################################################# LOG = LazyLogger(__name__) @@ -29,6 +28,7 @@ CONNECTION_STATE = { ################################################################################################# + class ConnectionManager(object): user = {} @@ -88,7 +88,7 @@ class ConnectionManager(object): if not server_url: raise AttributeError("server url cannot be empty") - data = self.API.login(server_url, username, password) # returns empty dict on failure + data = self.API.login(server_url, username, password) # returns empty dict on failure if not data: LOG.info("Failed to login as `"+username+"`") @@ -106,7 +106,7 @@ class ConnectionManager(object): found_server = server break else: - return {} # No server found + return {} # No server found found_server['DateLastAccessed'] = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ') found_server['UserId'] = data['User']['Id'] @@ -124,7 +124,6 @@ class ConnectionManager(object): return data - def connect_to_address(self, address, options={}): if not address: @@ -143,14 +142,13 @@ class ConnectionManager(object): server = self.connect_to_server(server, options) if server is False: LOG.error("connectToAddress %s failed", address) - return { 'State': CONNECTION_STATE['Unavailable'] } + return {'State': CONNECTION_STATE['Unavailable']} return server except Exception as error: LOG.exception(error) LOG.error("connectToAddress %s failed", address) - return { 'State': CONNECTION_STATE['Unavailable'] } - + return {'State': CONNECTION_STATE['Unavailable']} def connect_to_server(self, server, options={}): @@ -161,7 +159,7 @@ class ConnectionManager(object): if not result: LOG.error("Failed to connect to server: %s" % server.get('address')) - return { 'State': CONNECTION_STATE['Unavailable'] } + return {'State': CONNECTION_STATE['Unavailable']} LOG.info("calling onSuccessfulConnection with server %s", server.get('Name')) @@ -172,7 +170,7 @@ class ConnectionManager(object): except Exception as e: LOG.error(traceback.format_exc()) LOG.error("Failing server connection. ERROR msg: {}".format(e)) - return { 'State': CONNECTION_STATE['Unavailable'] } + return {'State': CONNECTION_STATE['Unavailable']} def connect(self, options={}): @@ -181,7 +179,7 @@ class ConnectionManager(object): servers = self.get_available_servers() LOG.info("connect has %s servers", len(servers)) - if not (len(servers)): # No servers provided + if not (len(servers)): # No servers provided return { 'State': ['ServerSelection'] } @@ -191,7 +189,7 @@ class ConnectionManager(object): return result - def jellyfin_token(self): # Called once monitor.py#163 + def jellyfin_token(self): # Called once monitor.py#163 return self.get_server_info(self.server_id)['AccessToken'] def get_server_info(self, server_id): @@ -321,7 +319,7 @@ class ConnectionManager(object): server['UserId'] = None server['AccessToken'] = None - return { 'State': CONNECTION_STATE['Unavailable'] } + return {'State': CONNECTION_STATE['Unavailable']} self._update_server_info(server, system_info) diff --git a/jellyfin_kodi/jellyfin/http.py b/jellyfin_kodi/jellyfin/http.py index f5f7178b..067d0e41 100644 --- a/jellyfin_kodi/jellyfin/http.py +++ b/jellyfin_kodi/jellyfin/http.py @@ -3,16 +3,16 @@ from __future__ import division, absolute_import, print_function, unicode_litera ################################################################################################# -import json import time import requests from six import string_types -from .exceptions import HTTPException from helper.utils import JsonDebugPrinter from helper import LazyLogger +from .exceptions import HTTPException + ################################################################################################# LOG = LazyLogger(__name__) @@ -154,9 +154,6 @@ class HTTP(object): LOG.error("Request missing Schema. " + str(error)) raise HTTPException("MissingSchema", {'Id': self.config.data.get('auth.server', "None")}) - except Exception as error: - raise - else: try: self.config.data['server-time'] = r.headers['Date'] diff --git a/jellyfin_kodi/jellyfin/websocket.py b/jellyfin_kodi/jellyfin/websocket.py index 8958dcd7..a363a2b6 100644 --- a/jellyfin_kodi/jellyfin/websocket.py +++ b/jellyfin_kodi/jellyfin/websocket.py @@ -727,7 +727,7 @@ class WebSocket(object): try: self.sock.shutdown(socket.SHUT_RDWR) - except: # noqa: E722 + except Exception: pass ''' @@ -813,7 +813,7 @@ class WebSocketApp(object): Higher level of APIs are provided. The interface is like JavaScript WebSocket object. """ - def __init__(self, url, header=[], + def __init__(self, url, header=None, on_open=None, on_message=None, on_error=None, on_close=None, keep_running=True, get_mask_key=None): """ @@ -837,7 +837,10 @@ class WebSocketApp(object): docstring for more information """ self.url = url - self.header = header + if header is None: + self.header = [] + else: + self.header = header self.on_open = on_open self.on_message = on_message self.on_error = on_error diff --git a/jellyfin_kodi/library.py b/jellyfin_kodi/library.py index 90cc01cf..15bf6f57 100644 --- a/jellyfin_kodi/library.py +++ b/jellyfin_kodi/library.py @@ -90,7 +90,7 @@ class Library(threading.Thread): try: self.service() - except LibraryException as error: + except LibraryException: break except Exception as error: LOG.exception(error) @@ -662,20 +662,19 @@ class UserDataWorker(threading.Thread): except Queue.Empty: break - try: if item['Type'] == 'Movie': - obj = Movies(self.args[0], jellyfindb, kodidb, self.args[1]).userdata(item) + Movies(self.args[0], jellyfindb, kodidb, self.args[1]).userdata(item) elif item['Type'] in ['Series', 'Season', 'Episode']: - obj = TVShows(self.args[0], jellyfindb, kodidb, self.args[1]).userdata(item) + TVShows(self.args[0], jellyfindb, kodidb, self.args[1]).userdata(item) elif item['Type'] == 'MusicAlbum': - obj = Music(self.args[0], jellyfindb, kodidb, self.args[1]).album(item) + Music(self.args[0], jellyfindb, kodidb, self.args[1]).album(item) elif item['Type'] == 'MusicArtist': - obj = Music(self.args[0], jellyfindb, kodidb, self.args[1]).artist(item) + Music(self.args[0], jellyfindb, kodidb, self.args[1]).artist(item) elif item['Type'] == 'AlbumArtist': - obj = Music(self.args[0], jellyfindb, kodidb, self.args[1]).albumartist(item) + Music(self.args[0], jellyfindb, kodidb, self.args[1]).albumartist(item) elif item['Type'] == 'Audio': - obj = Music(self.args[0], jellyfindb, kodidb, self.args[1]).song(item) + Music(self.args[0], jellyfindb, kodidb, self.args[1]).song(item) except LibraryException as error: if error.status == 'StopCalled': break diff --git a/jellyfin_kodi/objects/actions.py b/jellyfin_kodi/objects/actions.py index 45b9ede5..8ce6f1b4 100644 --- a/jellyfin_kodi/objects/actions.py +++ b/jellyfin_kodi/objects/actions.py @@ -11,11 +11,12 @@ from kodi_six import xbmc, xbmcgui, xbmcplugin, xbmcaddon import database from downloader import TheVoid -from .obj import Objects from helper import translate, playutils, api, window, settings, dialog from dialogs import resume from helper import LazyLogger +from .obj import Objects + ################################################################################################# LOG = LazyLogger(__name__) @@ -133,7 +134,7 @@ class Actions(object): LOG.info("[ intro/%s ] %s", intro['Id'], intro['Name']) play = playutils.PlayUtils(intro, False, self.server_id, self.server) - source = play.select_source(play.get_sources()) + play.select_source(play.get_sources()) self.set_listitem(intro, listitem, intro=True) listitem.setPath(intro['PlaybackInfo']['Path']) playutils.set_properties(intro, intro['PlaybackInfo']['Method'], self.server_id) @@ -797,10 +798,10 @@ def special_listener(): This is run in a loop within monitor.py ''' player = xbmc.Player() - isPlaying = player.isPlaying() + is_playing = player.isPlaying() count = int(window('jellyfin.external_count') or 0) - if (not isPlaying and xbmc.getCondVisibility('Window.IsVisible(DialogContextMenu.xml)') and xbmc.getInfoLabel('Control.GetLabel(1002)') == xbmc.getLocalizedString(12021)): + if (not is_playing and xbmc.getCondVisibility('Window.IsVisible(DialogContextMenu.xml)') and xbmc.getInfoLabel('Control.GetLabel(1002)') == xbmc.getLocalizedString(12021)): control = int(xbmcgui.Window(10106).getFocusId()) @@ -812,7 +813,7 @@ def special_listener(): LOG.info("Resume dialog: Resume selected.") window('jellyfin.resume.bool', True) - elif isPlaying and not window('jellyfin.external_check'): + elif is_playing and not window('jellyfin.external_check'): time = player.getTime() if time > 1: # Not external player. diff --git a/jellyfin_kodi/objects/kodi/artwork.py b/jellyfin_kodi/objects/kodi/artwork.py index e4847a12..a986f96a 100644 --- a/jellyfin_kodi/objects/kodi/artwork.py +++ b/jellyfin_kodi/objects/kodi/artwork.py @@ -3,18 +3,9 @@ from __future__ import division, absolute_import, print_function, unicode_litera ################################################################################################# -import threading - -from six.moves import queue as Queue -from six.moves.urllib.parse import urlencode - -from kodi_six import xbmc, xbmcvfs +from helper import LazyLogger from . import queries as QU -from . import queries_texture as QUTEX -from helper import settings -import requests -from helper import LazyLogger ################################################################################################## diff --git a/jellyfin_kodi/objects/kodi/kodi.py b/jellyfin_kodi/objects/kodi/kodi.py index ff567bf1..33dc864a 100644 --- a/jellyfin_kodi/objects/kodi/kodi.py +++ b/jellyfin_kodi/objects/kodi/kodi.py @@ -3,11 +3,13 @@ from __future__ import division, absolute_import, print_function, unicode_litera ################################################################################################## +from sqlite3 import IntegrityError + +from helper import values +from helper import LazyLogger + from . import artwork from . import queries as QU -from helper import values -from sqlite3 import IntegrityError -from helper import LazyLogger ################################################################################################## @@ -23,7 +25,7 @@ class Kodi(object): try: self.cursor.execute(QU.get_all_people) - except: + except Exception: # Failed to load the table. Has the table been created? self._people_cache = {} else: @@ -276,7 +278,7 @@ class Kodi(object): self.cursor.execute(QU.delete_tags, args) for tag in tags: - tag_id = self.get_tag(tag, *args) + self.get_tag(tag, *args) def add_tag(self, *args): diff --git a/jellyfin_kodi/objects/kodi/music.py b/jellyfin_kodi/objects/kodi/music.py index 473f3523..831cbe43 100644 --- a/jellyfin_kodi/objects/kodi/music.py +++ b/jellyfin_kodi/objects/kodi/music.py @@ -61,15 +61,15 @@ class Music(Kodi): try: self.cursor.execute(QU.get_artist, (musicbrainz,)) result = self.cursor.fetchone() - artist_id = result[0] + artist_id_res = result[0] artist_name = result[1] except TypeError: - artist_id = self.add_artist(artist_id, name, musicbrainz) + artist_id_res = self.add_artist(artist_id, name, musicbrainz) else: if artist_name != name: self.update_artist_name(artist_id, name) - return artist_id + return artist_id_res def add_artist(self, artist_id, name, *args): @@ -77,12 +77,12 @@ class Music(Kodi): ''' try: self.cursor.execute(QU.get_artist_by_name, (name,)) - artist_id = self.cursor.fetchone()[0] + artist_id_res = self.cursor.fetchone()[0] except TypeError: - artist_id = artist_id or self.create_entry() + artist_id_res = artist_id or self.create_entry() self.cursor.execute(QU.add_artist, (artist_id, name,) + args) - return artist_id + return artist_id_res def update_artist_name(self, *args): self.cursor.execute(QU.update_artist_name, args) diff --git a/jellyfin_kodi/objects/movies.py b/jellyfin_kodi/objects/movies.py index e74c7f70..b3a7dc5b 100644 --- a/jellyfin_kodi/objects/movies.py +++ b/jellyfin_kodi/objects/movies.py @@ -7,11 +7,12 @@ from six.moves.urllib.parse import urlencode from kodi_six.utils import py2_encode import downloader as server +from database import jellyfin_db, queries as QUEM +from helper import api, stop, validate, jellyfin_item, library_check, values, Local +from helper import LazyLogger + from .obj import Objects from .kodi import Movies as KodiDb, queries as QU -from database import jellyfin_db, queries as QUEM -from helper import api, stop, validate, jellyfin_item, library_check, values, settings, Local -from helper import LazyLogger ################################################################################################## diff --git a/jellyfin_kodi/objects/music.py b/jellyfin_kodi/objects/music.py index fa4080e3..e5f9a29d 100644 --- a/jellyfin_kodi/objects/music.py +++ b/jellyfin_kodi/objects/music.py @@ -5,12 +5,12 @@ from __future__ import division, absolute_import, print_function, unicode_litera import datetime -from .obj import Objects -from .kodi import Music as KodiDb, queries_music as QU from database import jellyfin_db, queries as QUEM from helper import api, stop, validate, jellyfin_item, values, library_check, Local from helper import LazyLogger +from .obj import Objects +from .kodi import Music as KodiDb, queries_music as QU ################################################################################################## LOG = LazyLogger(__name__) diff --git a/jellyfin_kodi/objects/musicvideos.py b/jellyfin_kodi/objects/musicvideos.py index 4f4ceb41..d94ba3e7 100644 --- a/jellyfin_kodi/objects/musicvideos.py +++ b/jellyfin_kodi/objects/musicvideos.py @@ -5,15 +5,17 @@ from __future__ import division, absolute_import, print_function, unicode_litera import datetime import re + from six.moves.urllib.parse import urlencode from kodi_six.utils import py2_encode -from .obj import Objects -from .kodi import MusicVideos as KodiDb, queries as QU from database import jellyfin_db, queries as QUEM from helper import api, stop, validate, library_check, jellyfin_item, values, Local from helper import LazyLogger +from .obj import Objects +from .kodi import MusicVideos as KodiDb, queries as QU + ################################################################################################## LOG = LazyLogger(__name__) diff --git a/jellyfin_kodi/objects/obj.py b/jellyfin_kodi/objects/obj.py index 0d6da07c..81b2b666 100644 --- a/jellyfin_kodi/objects/obj.py +++ b/jellyfin_kodi/objects/obj.py @@ -86,9 +86,7 @@ class Objects(object): for d in self.__recursiveloop__(obj, obj_param): - if obj_filters and self.__filters__(d, obj_filters): - result.append(d) - elif not obj_filters: + if not obj_filters or self.__filters__(d, obj_filters): result.append(d) obj = result diff --git a/jellyfin_kodi/objects/obj_map.json b/jellyfin_kodi/objects/obj_map.json index f2ff9d15..557d4331 100644 --- a/jellyfin_kodi/objects/obj_map.json +++ b/jellyfin_kodi/objects/obj_map.json @@ -286,7 +286,6 @@ "DatePlayed": "UserData/LastPlayedDate", "Artists": "Artists", "Album": "Album", - "Votes": "VoteCount", "Path": "Path", "LocalTrailer": "LocalTrailerCount", "Trailer": "RemoteTrailers/0/Url", diff --git a/jellyfin_kodi/objects/tvshows.py b/jellyfin_kodi/objects/tvshows.py index 7980e351..01cd9abc 100644 --- a/jellyfin_kodi/objects/tvshows.py +++ b/jellyfin_kodi/objects/tvshows.py @@ -9,13 +9,14 @@ from ntpath import dirname from six.moves.urllib.parse import urlencode from kodi_six.utils import py2_encode -from .obj import Objects -from .kodi import TVShows as KodiDb, queries as QU import downloader as server from database import jellyfin_db, queries as QUEM -from helper import api, stop, validate, jellyfin_item, library_check, settings, values, Local +from helper import api, stop, validate, jellyfin_item, library_check, values, Local from helper import LazyLogger +from .obj import Objects +from .kodi import TVShows as KodiDb, queries as QU + ################################################################################################## LOG = LazyLogger(__name__) diff --git a/jellyfin_kodi/player.py b/jellyfin_kodi/player.py index 3a5754e4..6a059c27 100644 --- a/jellyfin_kodi/player.py +++ b/jellyfin_kodi/player.py @@ -290,7 +290,7 @@ class Player(xbmc.Player): self.report_playback() LOG.debug("--<[ paused ]") - def onPlayBackSeek(self, time, seekOffset): + def onPlayBackSeek(self, time, seek_offset): ''' Does not seem to work in Leia?? ''' diff --git a/jellyfin_kodi/webservice.py b/jellyfin_kodi/webservice.py index 4cb199eb..c2523e35 100644 --- a/jellyfin_kodi/webservice.py +++ b/jellyfin_kodi/webservice.py @@ -3,9 +3,10 @@ from __future__ import division, absolute_import, print_function, unicode_litera ################################################################################################# +import threading + from six.moves import BaseHTTPServer from six.moves import http_client as httplib -import threading from six.moves.urllib.parse import parse_qsl from kodi_six import xbmc @@ -112,8 +113,6 @@ class requestHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.send_response(200) self.end_headers() - return - def do_GET(self): ''' Return plugin path @@ -143,5 +142,3 @@ class requestHandler(BaseHTTPServer.BaseHTTPRequestHandler): LOG.exception(error) self.send_error(500, "Exception occurred: %s" % error) - - return