def get_server(server=None): global EMBY try: EMBY = Emby(server).get_client() except KeyError: # Server never loaded. event('ServerConnect', {'Id': server}) monitor = xbmc.Monitor() for i in range(300): if server is None and window('emby_online.bool'): Emby().set_state(window('emby.server.state.json')) break if server is not None and server in window('emby.server.states.json') or []: Emby(server).set_state(window('emby.server.%s.state.json' % server)) break if monitor.waitForAbort(0.1): raise Exception('ShutDownRequested') else: LOG.error("Server %s is not online", server) raise Exception('ServerOffline') EMBY = Emby(server).get_client()
def _get_server(self, method, data): ''' Retrieve the Emby server. ''' try: if not data.get('ServerId'): raise Exception("ServerId undefined.") if method != 'LoadServer' and data['ServerId'] not in self.servers: try: connect.Connect().register(data['ServerId']) self.server_instance(data['ServerId']) except Exception as error: LOG.error(error) dialog("ok", heading="{emby}", line1=_(33142)) return server = Emby(data['ServerId']).get_client() except Exception: server = Emby().get_client() return server
def shutdown(self): LOG.warn("---<[ EXITING ]") window('emby_should_stop.bool', True) properties = [ # TODO: review "emby_state", "emby_serverStatus", "emby_currUser", "emby_play", "emby_online", "emby.connected", "emby.resume", "emby_startup", "emby.updatewidgets", "emby.external", "emby.external_check", "emby_deviceId", "emby_db_check", "emby_pathverified", "emby_sync" ] for prop in properties: window(prop, clear=True) Emby.close_all() if self.library_thread is not None: self.library_thread.stop_client() if self.webservice is not None: self.webservice.stop() if self.monitor is not None: self.monitor.listener.stop() LOG.warn("---<<<[ %s ]", client.get_addon_name())
def shutdown(self): LOG.warn("---<[ EXITING ]") window('emby_should_stop.bool', True) properties = [ "emby.play", "emby.play.widget", "emby.autoplay", "emby_online", "emby.connected", "emby.resume", "emby.updatewidgets", "emby.external", "emby.external_check", "emby_deviceId", "emby_pathverified", "emby_sync", "emby.restart", "emby.sync.pause", "emby.playlist.clear", "emby.server.state", "emby.server.states" ] for server in window('emby.server.states.json') or []: properties.append("emby.server.%s.state" % server) for prop in properties: window(prop, clear=True) WEBSERVICE.stop() Emby.close_all() if self['library'] is not None: self['library'].stop_client() if self['monitor'] is not None: self['monitor'].listener.stop() LOG.warn("---<<<[ %s ]", client.get_addon_name())
def __init__(self, library, library_id=None, update=False): self.library = library self.direct_path = settings('useDirectPaths') == "1" self.update_library = update self.server = Emby() self.sync = get_sync() if library_id: libraries = library_id.split(',') for selected in libraries: if selected not in [x.replace('Mixed:', "") for x in self.sync['Libraries']]: library = self.get_libraries(selected) if library: self.sync['Libraries'].append("Mixed:%s" % selected if library[1] == 'mixed' else selected) if library[1] in ('mixed', 'movies'): self.sync['Libraries'].append('Boxsets:%s' % selected) else: self.sync['Libraries'].append(selected) else: self.mapping() xmls.sources() if not xmls.advanced_settings() and self.sync['Libraries']: self.start()
def __init__(self, params, server_id=None): ''' Workflow: Strm that calls our webservice in database. When played, the webserivce returns a dummy file to play. Meanwhile, PlayStrm adds the real listitems for items to play to the playlist. ''' self.info = { 'Intros': None, 'Item': None, 'Id': params.get('Id'), 'DbId': params.get('KodiId'), 'Transcode': params.get('transcode'), 'AdditionalParts': None, 'ServerId': server_id, 'KodiPlaylist': xbmc.PlayList(xbmc.PLAYLIST_VIDEO), 'Server': Emby(server_id).get_client() } if self.info['Transcode'] is None: self.info['Transcode'] = settings( 'playFromTranscode.bool') if settings( 'playFromStream.bool') else None self.actions = Actions(server_id, self.info['Server']['auth/server-address']) self.set_listitem = self.actions.set_listitem self.params = params self._detect_play() LOG.info("[ play strm ]")
def onPlayBackError(self): LOG.warn("Playback error occured") window('emby.play.widget', clear=True) self.stop_playback() try: items = self._get_items() except Exception as error: LOG.error(error) return item = items.pop(0) self._set_items(items) item['Server'] = Emby(item['ServerId']).get_client() if item.get('LiveStreamId'): LOG.info("<[ livestream/%s ]", item['LiveStreamId']) item['Server']['api'].close_live_stream(item['LiveStreamId']) elif item['PlayMethod'] == 'Transcode': LOG.info("<[ transcode/%s ]", item['Id']) item['Server']['api'].close_transcode(item['DeviceId'])
def run(self): ''' This is a thread to not block the main service thread. ''' try: if 'default' in Emby.client: window('emby_online', clear=True) Emby().close() if self.service['library'] is not None: self.service['library'].stop_client() self.service['library'] = None if self.close: raise Exception("terminate default server thread") if self.retry and self.service['monitor'].waitForAbort( self.retry) or not self.service.running: raise Exception("abort default server thread") self.service['connect'].register() setup.Setup() self.service['mode'] = settings('useDirectPaths') if self.service['library'] is None: self.service['library'] = library.Library(self.service) except Exception as error: LOG.error( error ) # we don't really case, event will retrigger if need be. self.service.server_thread.remove(self)
def __init__(self, monitor): self.media = { 'Movies': Movies, 'TVShows': TVShows, 'MusicVideos': MusicVideos, 'Music': Music } self.MEDIA = MEDIA self.direct_path = settings('useDirectPaths') == "1" self.progress_display = int(settings('syncProgress') or 50) self.monitor = monitor self.player = monitor.monitor.player self.server = Emby().get_client() self.updated_queue = Queue.Queue() self.userdata_queue = Queue.Queue() self.removed_queue = Queue.Queue() self.updated_output = self.__new_queues__() self.userdata_output = self.__new_queues__() self.removed_output = self.__new_queues__() self.notify_output = Queue.Queue() self.emby_threads = [] self.download_threads = [] self.notify_threads = [] self.writer_threads = {'updated': [], 'userdata': [], 'removed': []} self.database_lock = threading.Lock() self.music_database_lock = threading.Lock() threading.Thread.__init__(self)
def stop_default(self): window('emby_online', clear=True) Emby().close() if self.library_thread is not None: self.library_thread.stop_client() self.library_thread = None
def get_client(self, server, server_id=None): ''' Get Emby client. ''' client = Emby(server_id) client['config/app']("Kodi", self.info['Version'], self.info['DeviceName'], self.info['DeviceId']) client['config'][ 'http.user_agent'] = "Emby-Kodi/%s" % self.info['Version'] client['config']['auth.ssl'] = server.get('verify', self.get_ssl()) return client
def __init__(self, library, library_id=None, update=False): ''' Map the syncing process and start the sync. Ensure only one sync is running. ''' self.__dict__ = self._shared_state window('emby_sync.bool', True) if not settings('dbSyncScreensaver.bool'): xbmc.executebuiltin('InhibitIdleShutdown(true)') self.screensaver = get_screensaver() set_screensaver(value="") if not self.running: self.running = True self.library = library self.direct_path = settings('useDirectPaths') == "1" self.update_library = update self.server = Emby() self.sync = get_sync() if library_id: libraries = library_id.split(',') for selected in libraries: if selected not in [x.replace('Mixed:', "") for x in self.sync['Libraries']]: library = self.get_libraries(selected) if library: self.sync['Libraries'].append("Mixed:%s" % selected if library[1] == 'mixed' else selected) if library[1] in ('mixed', 'movies'): self.sync['Libraries'].append('Boxsets:%s' % selected) else: self.sync['Libraries'].append(selected) else: self.mapping() xmls.sources() if not xmls.advanced_settings() and self.sync['Libraries']: self.start() else: self.running = False else: dialog("ok", heading="{emby}", line1=_(33197)) raise Exception("Sync is already running.")
def remove_server(self, server_id): ''' Stop client and remove server. ''' Emby(server_id).close() credentials = get_credentials() for server in credentials['Servers']: if server['Id'] == server_id: credentials['Servers'].remove(server) break save_credentials(credentials) LOG.info("[ remove server ] %s", server_id)
def register(self, server_id=None, options={}): ''' Login into server. If server is None, then it will show the proper prompts to login, etc. If a server id is specified then only a login dialog will be shown for that server. ''' LOG.info("--[ server/%s ]", server_id or 'default') if (server_id) in self.pending: LOG.info("[ server/%s ] is already being registered", server_id or 'default') return self.pending.append(server_id) credentials = get_credentials() if server_id is None and credentials['Servers']: credentials['Servers'] = [credentials['Servers'][0]] elif credentials['Servers']: for server in credentials['Servers']: if server['Id'] == server_id: credentials['Servers'] = [server] server_select = True if server_id is None and not settings( 'SyncInstallRunDone.bool') else False try: new_credentials = self.register_client(credentials, options, server_id, server_select) credentials = self._save_servers(new_credentials['Servers'], server_id is None) new_credentials.update(credentials) save_credentials(new_credentials) Emby(server_id).start(not bool(server_id), True) except HTTPException as error: if error.status == 'ServerUnreachable': self.pending.remove(server_id) raise except ValueError as error: LOG.error(error) self.pending.remove(server_id)
def set_item(self, file, item): ''' Set playback information. ''' try: item['Runtime'] = int(item['Runtime']) except (TypeError, ValueError): try: item['Runtime'] = int(self.getTotalTime()) LOG.info("Runtime is missing, Kodi runtime: %s" % item['Runtime']) except Exception: item['Runtime'] = 0 LOG.info("Runtime is missing, Using Zero") try: seektime = self.getTime() except Exception: # at this point we should be playing and if not then bail out return result = JSONRPC('Application.GetProperties').execute( {'properties': ["volume", "muted"]}) result = result.get('result', {}) volume = result.get('volume') muted = result.get('muted') item.update({ 'File': file, 'CurrentPosition': item.get('CurrentPosition') or int(seektime), 'Muted': muted, 'Volume': volume, 'Server': Emby(item['ServerId']).get_client(), 'Paused': False, 'Track': False }) self.played[file] = item LOG.info("-->[ play/%s ] %s", item['Id'], item)
def server_instance(self, server_id=None): server = Emby(server_id) self.post_capabilities(server) if server_id is not None: self.servers.append(server_id) elif settings('additionalUsers'): users = settings('additionalUsers').split(',') all_users = server['api'].get_users() for additional in users: for user in all_users: if user['Name'].lower() in additional.decode('utf-8').lower(): server['api'].session_add_user(server['config/app.session'], user['Id'], True) self.additional_users(server)
def __init__(self, monitor): self.media = { 'Movies': Movies, 'TVShows': TVShows, 'MusicVideos': MusicVideos, 'Music': Music } self.kodi_media = { 'Movies': kMovies, 'TVShows': kTVShows, 'MusicVideos': kMusicVideos, 'Music': kMusic, 'Kodi': Kodi } self.MEDIA = MEDIA self.direct_path = settings('useDirectPaths') == "1" self.monitor = monitor self.player = monitor.monitor.player self.server = Emby().get_client() self.updated_queue = Queue.Queue() self.userdata_queue = Queue.Queue() self.removed_queue = Queue.Queue() self.updated_output = self.__new_queues__() self.userdata_output = self.__new_queues__() self.removed_output = self.__new_queues__() self.notify_output = Queue.Queue() self.add_lib_queue = Queue.Queue() self.remove_lib_queue = Queue.Queue() self.verify_queue = Queue.Queue() self.emby_threads = [] self.download_threads = [] self.notify_threads = [] self.writer_threads = {'updated': [], 'userdata': [], 'removed': []} self.database_lock = threading.Lock() self.music_database_lock = threading.Lock() self.sync = Sync threading.Thread.__init__(self) self.start()
def server_instance(self, server_id=None): server = Emby(server_id) self.post_capabilities(server) if server_id is not None: self.servers.append(server_id) elif settings('addUsers'): users = settings('addUsers').split(',') all_users = server['api'].get_users(hidden=True) for additional in users: for user in all_users: if user['Id'] == additional: server['api'].session_add_user( server['config/app.session'], user['Id'], True) self.additional_users(server)
def __init__(self, play=False, transcode=False, delete=False): self.server_id = None self.kodi_id = None self.media = None try: self.kodi_id = max( sys.listitem.getVideoInfoTag().getDbId(), 0) or max( sys.listitem.getMusicInfoTag().getDbId(), 0) or None self.media = self.get_media_type() self.server_id = sys.listitem.getProperty('embyserver') or None item_id = sys.listitem.getProperty('embyid') except AttributeError: if xbmc.getInfoLabel('ListItem.Property(embyid)'): item_id = xbmc.getInfoLabel('ListItem.Property(embyid)') else: self.kodi_id = xbmc.getInfoLabel('ListItem.DBID') self.media = xbmc.getInfoLabel('ListItem.DBTYPE') item_id = None self.server = Emby(self.server_id).get_client() if item_id: self.item = self.server['api'].get_item(item_id) else: self.item = self.get_item_id() if self.item: if play or transcode: self.play(transcode) elif delete: self.delete_item() elif self.select_menu(): self.action_menu()
def register(self, server_id=None, options={}): ''' Login into server. If server is None, then it will show the proper prompts to login, etc. If a server id is specified then only a login dialog will be shown for that server. ''' LOG.info("--[ server/%s ]", server_id or 'default') credentials = dict(get_credentials()) servers = credentials['Servers'] if server_id is None and credentials['Servers']: credentials['Servers'] = [credentials['Servers'][0]] elif credentials['Servers']: for server in credentials['Servers']: if server['Id'] == server_id: credentials['Servers'] = [server] server_select = True if server_id is None and not settings( 'SyncInstallRunDone.bool') else False new_credentials = self.register_client(credentials, options, server_id, server_select) for server in servers: if server['Id'] == new_credentials['Servers'][0]['Id']: server = new_credentials['Servers'][0] break else: servers = new_credentials['Servers'] credentials['Servers'] = servers save_credentials(credentials) try: Emby(server_id).start(True) except ValueError as error: LOG.error(error)
def server_instance(self, server_id=None): server = Emby(server_id).get_client() self.post_capabilities(server) if server_id is not None: self.servers.append(server_id) elif settings('addUsers'): users = settings('addUsers').split(',') hidden = None if settings('addUsersHidden.bool') else False all_users = server['api'].get_users(hidden=hidden) for additional in users: for user in all_users: if user['Id'] == additional: server['api'].session_add_user( server['config/app.session'], user['Id']) self.additional_users(server) event('ServerOnline', {'ServerId': server_id})
# -*- coding: utf-8 -*- ################################################################################################# import logging import xbmc import xbmcvfs from helper import loghandler from emby import Emby ################################################################################################# Emby.set_loghandler(loghandler.LogHandler, logging.DEBUG) loghandler.reset() loghandler.config() LOG = logging.getLogger('EMBY.entrypoint') ################################################################################################# from default import Events from service import Service from context import Context
def __init__(self, redirect, server_id=None): self.redirect = redirect self.server = Emby(server_id).get_client() threading.Thread.__init__(self)
def onNotification(self, sender, method, data): ''' All notifications are sent via NotifyAll built-in or Kodi. Central hub. ''' if sender.lower() not in ('plugin.video.emby', 'xbmc'): return if sender == 'plugin.video.emby': method = method.split('.')[1] if method not in ('ServerUnreachable', 'ServerShuttingDown', 'UserDataChanged', 'ServerConnect', 'LibraryChanged', 'ServerOnline', 'SyncLibrary', 'RepairLibrary', 'RemoveLibrary', 'EmbyConnect', 'SyncLibrarySelection', 'RepairLibrarySelection', 'AddServer', 'Unauthorized', 'UpdateServer', 'UserConfigurationUpdated', 'ServerRestarting', 'RemoveServer', 'AddLibrarySelection', 'CheckUpdate', 'RemoveLibrarySelection', 'PatchMusic'): return data = json.loads(data)[0] else: if method not in ('System.OnQuit', 'System.OnSleep', 'System.OnWake'): return data = json.loads(data) LOG.debug("[ onNotification/%s/%s ]", sender, method) LOG.debug("[ %s: %s ] %s", sender, method, json.dumps(data, indent=4)) if method == 'ServerOnline': if data.get('ServerId') is None: window('emby_online.bool', True) self.settings['auth_check'] = True self.warn = True if settings('connectMsg.bool'): users = [ user for user in (settings('additionalUsers') or "" ).decode('utf-8').split(',') if user ] users.insert(0, settings('username').decode('utf-8')) dialog("notification", heading="{emby}", message="%s %s" % (_(33000), ", ".join(users)), icon="{emby}", time=1500, sound=False) if self.webservice is None: self.webservice = webservice.WebService() self.webservice.start() if self.library_thread is None: self.library_thread = library.Library(self) self.library_thread.start() elif method in ('ServerUnreachable', 'ServerShuttingDown'): if self.warn or data.get('ServerId'): self.warn = data.get('ServerId') is not None dialog("notification", heading="{emby}", message=_(33146) if data.get('ServerId') is None else _(33149), icon=xbmcgui.NOTIFICATION_ERROR) if data.get('ServerId') is None: self.stop_default() if self.waitForAbort(20): return self.start_default() elif method == 'Unauthorized': dialog("notification", heading="{emby}", message=_(33147) if data['ServerId'] is None else _(33148), icon=xbmcgui.NOTIFICATION_ERROR) if data.get('ServerId') is None and self.settings['auth_check']: self.settings['auth_check'] = False self.stop_default() if self.waitForAbort(5): return self.start_default() elif method == 'ServerRestarting': if data.get('ServerId'): return if settings('restartMsg.bool'): dialog("notification", heading="{emby}", message=_(33006), icon="{emby}") self.stop_default() if self.waitForAbort(15): return self.start_default() elif method == 'ServerConnect': self.connect.register(data['Id']) xbmc.executebuiltin("Container.Refresh") elif method == 'EmbyConnect': self.connect.setup_login_connect() elif method == 'AddServer': self.connect.setup_manual_server() xbmc.executebuiltin("Container.Refresh") elif method == 'RemoveServer': self.connect.remove_server(data['Id']) xbmc.executebuiltin("Container.Refresh") elif method == 'UpdateServer': dialog("ok", heading="{emby}", line1=_(33151)) self.connect.setup_manual_server() elif method == 'UserDataChanged' and self.library_thread: if data.get('ServerId') or not window('emby_startup.bool'): return LOG.info("[ UserDataChanged ] %s", data) self.library_thread.userdata(data['UserDataList']) elif method == 'LibraryChanged' and self.library_thread: if data.get('ServerId') or not window('emby_startup.bool'): return LOG.info("[ LibraryChanged ] %s", data) self.library_thread.updated(data['ItemsUpdated'] + data['ItemsAdded']) self.library_thread.removed(data['ItemsRemoved']) elif method == 'System.OnQuit': window('emby_should_stop.bool', True) self.running = False elif method in ('SyncLibrarySelection', 'RepairLibrarySelection', 'AddLibrarySelection', 'RemoveLibrarySelection'): self.library_thread.select_libraries(method) elif method == 'SyncLibrary': if not data.get('Id'): return self.library_thread.add_library(data['Id'], data.get('Update', False)) xbmc.executebuiltin("Container.Refresh") elif method == 'RepairLibrary': if not data.get('Id'): return libraries = data['Id'].split(',') for lib in libraries: if not self.library_thread.remove_library(lib): return self.library_thread.add_library(data['Id']) xbmc.executebuiltin("Container.Refresh") elif method == 'RemoveLibrary': libraries = data['Id'].split(',') for lib in libraries: if not self.library_thread.remove_library(lib): return xbmc.executebuiltin("Container.Refresh") elif method == 'System.OnSleep': LOG.info("-->[ sleep ]") window('emby_should_stop.bool', True) if self.library_thread is not None: self.library_thread.stop_client() self.library_thread = None Emby.close_all() self.monitor.server = [] self.monitor.sleep = True elif method == 'System.OnWake': if not self.monitor.sleep: LOG.warn("System.OnSleep was never called, skip System.OnWake") return LOG.info("--<[ sleep ]") xbmc.sleep(10000) # Allow network to wake up self.monitor.sleep = False window('emby_should_stop', clear=True) try: self.connect.register() except Exception as error: LOG.error(error) elif method == 'GUI.OnScreensaverDeactivated': LOG.info("--<[ screensaver ]") xbmc.sleep(5000) if self.library_thread is not None: self.library_thread.fast_sync() elif method == 'UserConfigurationUpdated': if data.get('ServerId') is None: Views().get_views() elif method == 'CheckUpdate': if not self.patch.check_update(True): dialog("notification", heading="{emby}", message=_(21341), icon="{emby}", sound=False) else: dialog("notification", heading="{emby}", message=_(33181), icon="{emby}", sound=False) window('emby.restart.bool', True) elif method == 'PatchMusic': self.library_thread.run_library_task( method, data.get('Notification', True))
def __init__(self): global CONTENT_TYPE ''' Parse the parameters. Reroute to our service.py where user is fully identified already. ''' base_url = sys.argv[0] path = sys.argv[2] try: params = dict(urlparse.parse_qsl(path[1:])) except Exception: params = {} if 'content_type' in params: window('emby.plugin.content.type', params['content_type']) CONTENT_TYPE = params['content_type'] else: CONTENT_TYPE = window('emby.plugin.content.type') or None mode = params.get('mode') server = params.get('server') if server == 'None' or not server: server = None LOG.warn("path: %s params: %s", path, json.dumps(params, indent=4)) if '/extrafanart' in base_url: emby_path = path[1:] emby_id = params.get('id') get_fanart(emby_id, emby_path, server) elif '/Extras' in base_url or '/VideoFiles' in base_url: emby_path = path[1:] emby_id = params.get('id') get_video_extras(emby_id, emby_path, server) elif mode == 'play': window('emby.sync.pause.bool', True) window('emby.playlist.plugin.bool', True) try: objects.PlayPlugin(params, server).play('trailer' in base_url) except Exception as error: LOG.exception(error) if not xbmc.Player().isPlaying(): xbmc.Player().stop() xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem()) window('emby.sync.pause.bool', clear=True) window('emby.playlist.plugin', clear=True) elif mode =='playstrm': window('emby.sync.pause.bool', True) window('emby.playlist.plugin.bool', True) while not window('emby.playlist.play.bool'): xbmc.sleep(50) if window('emby.playlist.aborted.bool'): LOG.warn("[ playback aborted ]") break else: LOG.info("[ playback started ]") xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem()) window('emby.playlist.aborted', clear=True) window('emby.sync.pause', clear=True) window('emby.playlist.plugin', clear=True) elif mode == 'playsingle': window('emby.sync.pause.bool', True) window('emby.playlist.plugin.bool', True) try: objects.PlaySingle(params, server).play() except Exception as error: LOG.exception(error) if not xbmc.Player().isPlaying(): xbmc.Player().stop() xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem()) window('emby.sync.pause', clear=True) window('emby.playlist.plugin', clear=True) elif mode == 'playlist': event('PlayPlaylist', {'Id': params['id'], 'ServerId': server}) elif mode == 'photoviewer': xbmc.executebuiltin('ShowPicture(%s/emby/Items/%s/Images/Primary)' % (Emby(server)['auth/server-address'], params['id'])) elif mode == 'deviceid': client.reset_device_id() elif mode == 'reset': reset() elif mode == 'delete': delete_item() elif mode == 'refreshboxsets': event('SyncLibrary', {'Id': "Boxsets:Refresh"}) elif mode == 'nextepisodes': get_next_episodes(params['id'], params['limit']) elif mode == 'browse': browse(params.get('type'), params.get('id'), params.get('folder'), server) elif mode == 'synclib': event('SyncLibrary', {'Id': params.get('id')}) elif mode == 'updatelib': event('SyncLibrary', {'Id': params.get('id'), 'Update': True}) elif mode == 'repairlib': event('RepairLibrary', {'Id': params.get('id')}) elif mode == 'removelib': event('RemoveLibrary', {'Id': params.get('id')}) elif mode == 'repairlibs': event('RepairLibrarySelection') elif mode == 'updatelibs': event('SyncLibrarySelection') elif mode == 'removelibs': event('RemoveLibrarySelection') elif mode == 'addlibs': event('AddLibrarySelection') elif mode == 'connect': event('EmbyConnect') elif mode == 'addserver': event('AddServer') elif mode == 'login': event('ServerConnect', {'Id': server}) elif mode == 'removeserver': event('RemoveServer', {'Id': server}) elif mode == 'settings': xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)') elif mode == 'adduser': add_user(params.get('permanent') == 'true') elif mode == 'checkupdate': event('CheckUpdate') elif mode == 'resetupdate': event('ResetUpdate') elif mode == 'updateserver': event('UpdateServer') elif mode == 'thememedia': get_themes() elif mode == 'managelibs': manage_libraries() elif mode == 'texturecache': cache_artwork() elif mode == 'backup': backup() elif mode == 'restartservice': window('emby.restart.bool', True) elif mode == 'patchmusic': event('PatchMusic', {'Notification': True}) elif mode == 'changelog': changelog() elif mode == 'setssl': event('SetServerSSL', {'Id': server}) else: listing()
def _http(action, url, request={}, server_id=None): request.update({'url': url, 'type': action}) return Emby(server_id)['http/request'](request)
def set_item(self, file, track=True): ''' Call when playback start to setup play entry in player tracker. ''' self.playlist = xbmc.PlayList(self.monitor.playlistid) if not file: LOG.warn("Filename is invalid") return try: items = self._get_items() except Exception as error: if file in self.played: LOG.warn("[ reusing played item ]") item = self.played[file] else: LOG.error(error) return else: item = None for item in items: if item['Path'] == file.decode('utf-8'): items.pop(items.index(item)) break else: if items[0]['PlayOption'] != 'Addon' and not xbmc.getInfoLabel( 'VideoPlayer.DBID' ): # prevent unknown files from picking up emby files return item = items.pop(0) self._set_items(items) try: item['Runtime'] = int(item['Runtime']) except (TypeError, ValueError): try: item['Runtime'] = self.get_total_time() LOG.info("Runtime is missing, Kodi runtime: %s" % item['Runtime']) except Exception: item['Runtime'] = 0 LOG.info("Runtime is missing, Using Zero") try: seektime = self.get_time() except Exception: # at this point we should be playing and if not then bail out return volume, muted = self.get_volume() item.update({ 'File': file, 'CurrentPosition': item.get('CurrentPosition') or int(seektime), 'Muted': muted, 'Volume': volume, 'Server': Emby(item['ServerId']).get_client(), 'Paused': False, 'Track': False }) self.played[file] = item LOG.info("-->[ play/%s ] %s", item['Id'], item) data = { 'QueueableMediaTypes': "Video,Audio", 'CanSeek': True, 'ItemId': item['Id'], 'MediaSourceId': item['MediaSourceId'], 'PlayMethod': item['PlayMethod'], 'VolumeLevel': item['Volume'], 'PositionTicks': int(item['CurrentPosition'] * 10000000), 'IsPaused': item['Paused'], 'IsMuted': item['Muted'], 'PlaySessionId': item['PlaySessionId'], 'AudioStreamIndex': item['AudioStreamIndex'], 'SubtitleStreamIndex': item['SubtitleStreamIndex'] } item['Server']['api'].session_playing(data) if track: item['Track'] = True if self.monitor.waitForAbort(2): return return item
def __init__(self): self.sync = get_sync() self.server = Emby()
################################################################################################# import logging import sys import xbmc import xbmcvfs from emby import Emby from helper import loghandler, window ################################################################################################# loghandler.reset() loghandler.config() LOG = logging.getLogger('EMBY.entrypoint') Emby.set_loghandler(loghandler.LogHandler, logging.DEBUG) ################################################################################################# if 'service' in sys.argv: from service import Service else: Emby().set_state(window('emby.server.state.json')) for server in window('emby.server.states.json') or []: Emby(server).set_state(window('emby.server.%s.state.json' % server)) from context import Context from default import Events
def onNotification(self, sender, method, data): if sender.lower() not in ('plugin.video.emby', 'xbmc', 'upnextprovider.signal'): return if sender == 'plugin.video.emby': method = method.split('.')[1] if method not in ('GetItem', 'ReportProgressRequested', 'LoadServer', 'RandomItems', 'Recommended', 'GetServerAddress', 'GetPlaybackInfo', 'Browse', 'GetImages', 'GetToken', 'PlayPlaylist', 'Play', 'GetIntros', 'GetAdditionalParts', 'RefreshItem', 'Genres', 'FavoriteItem', 'DeleteItem', 'AddUser', 'GetSession', 'GetUsers', 'GetThemes', 'GetTheme', 'Playstate', 'GeneralCommand', 'GetTranscodeOptions', 'RecentlyAdded', 'BrowseSeason', 'LiveTV', 'GetLiveStream'): return data = json.loads(data)[0] elif sender.startswith('upnextprovider'): method = method.split('.')[1] if method not in ('plugin.video.emby_play_action'): return data = json.loads(data) method = "Play" if data: data = json.loads(binascii.unhexlify(data[0])) else: if method not in ('Player.OnPlay', 'VideoLibrary.OnUpdate', 'Player.OnAVChange'): ''' We have to clear the playlist if it was stopped before it has been played completely. Otherwise the next played item will be added the previous queue. ''' if method == "Player.OnStop": xbmc.sleep( 3000 ) # let's wait for the player so we don't clear the canceled playlist by mistake. if xbmc.getCondVisibility( "!Player.HasMedia + !Window.IsVisible(busydialog)" ): xbmc.executebuiltin("Playlist.Clear") LOG.info("[ playlist ] cleared") return data = json.loads(data) LOG.debug("[ %s: %s ] %s", sender, method, json.dumps(data, indent=4)) if self.sleep: LOG.info("System.OnSleep detected, ignore monitor request.") return try: if not data.get('ServerId'): raise Exception("ServerId undefined.") if method != 'LoadServer' and data['ServerId'] not in self.servers: try: connect.Connect().register(data['ServerId']) self.server_instance(data['ServerId']) except Exception as error: LOG.error(error) dialog("ok", heading="{emby}", line1=_(33142)) return server = Emby(data['ServerId']) except Exception: server = Emby() if method == 'GetItem': item = server['api'].get_item(data['Id']) self.void_responder(data, item) elif method == 'GetAdditionalParts': item = server['api'].get_additional_parts(data['Id']) self.void_responder(data, item) elif method == 'GetIntros': item = server['api'].get_intros(data['Id']) self.void_responder(data, item) elif method == 'GetImages': item = server['api'].get_images(data['Id']) self.void_responder(data, item) elif method == 'GetServerAddress': server_address = server['auth/server-address'] self.void_responder(data, server_address) elif method == 'GetPlaybackInfo': sources = server['api'].get_play_info(data['Id'], data['Profile']) self.void_responder(data, sources) elif method == 'GetLiveStream': sources = server['api'].get_live_stream(data['Id'], data['PlaySessionId'], data['Token'], data['Profile']) self.void_responder(data, sources) elif method == 'GetToken': token = server['auth/token'] self.void_responder(data, token) elif method == 'GetSession': session = server['api'].get_device(self.device_id) self.void_responder(data, session) elif method == 'GetUsers': users = server['api'].get_users(data.get('IsDisabled', True), data.get('IsHidden', True)) self.void_responder(data, users) elif method == 'GetTranscodeOptions': result = server['api'].get_transcode_settings() self.void_responder(data, result) elif method == 'GetThemes': if data['Type'] == 'Video': theme = server['api'].get_items_theme_video(data['Id']) else: theme = server['api'].get_items_theme_song(data['Id']) self.void_responder(data, theme) elif method == 'GetTheme': theme = server['api'].get_themes(data['Id']) self.void_responder(data, theme) elif method == 'Browse': result = downloader.get_filtered_section(data.get('Id'), data.get('Media'), data.get('Limit'), data.get('Recursive'), data.get('Sort'), data.get('SortOrder'), data.get('Filters'), data.get('Params'), data.get('ServerId')) self.void_responder(data, result) elif method == 'BrowseSeason': result = server['api'].get_seasons(data['Id']) self.void_responder(data, result) elif method == 'LiveTV': result = server['api'].get_channels() self.void_responder(data, result) elif method == 'RecentlyAdded': result = server['api'].get_recently_added(data.get('Media'), data.get('Id'), data.get('Limit')) self.void_responder(data, result) elif method == 'Genres': result = server['api'].get_genres(data.get('Id')) self.void_responder(data, result) elif method == 'Recommended': result = server['api'].get_recommendation(data.get('Id'), data.get('Limit')) self.void_responder(data, result) elif method == 'RefreshItem': server['api'].refresh_item(data['Id']) elif method == 'FavoriteItem': server['api'].favorite(data['Id'], data['Favorite']) elif method == 'DeleteItem': server['api'].delete_item(data['Id']) elif method == 'PlayPlaylist': server['api'].post_session( server['config/app.session'], "Playing", { 'PlayCommand': "PlayNow", 'ItemIds': data['Id'], 'StartPositionTicks': 0 }) elif method == 'Play': items = server['api'].get_items(data['ItemIds']) PlaylistWorker(data.get('ServerId'), items, data['PlayCommand'] == 'PlayNow', data.get('StartPositionTicks', 0), data.get('AudioStreamIndex'), data.get('SubtitleStreamIndex')).start() elif method in ('ReportProgressRequested', 'Player.OnAVChange'): self.player.report_playback(data.get('Report', True)) elif method == 'Playstate': self.playstate(data) elif method == 'GeneralCommand': self.general_commands(data) elif method == 'LoadServer': self.server_instance(data['ServerId']) elif method == 'AddUser': server['api'].session_add_user(server['config/app.session'], data['Id'], data['Add']) self.additional_users(server) elif method == 'Player.OnPlay': on_play(data, server) elif method == 'VideoLibrary.OnUpdate': on_update(data, server)