def _ProcessMessage(self, messageObj): if not messageObj: return if not WS_MESSAGE_TYPE in messageObj: ProviderObserver.log( 'message without "{}" received from {}'.format( WS_MESSAGE_TYPE, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING) return if not WS_DATA in messageObj: ProviderObserver.log( 'message without "{}" received from {}'.format( WS_DATA, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING) return messageType = messageObj[WS_MESSAGE_TYPE] data = messageObj[WS_DATA] if messageType == WS_MESSAGE_TYPE_LIBRARY_CHANGED: self._ProcessMessageLibraryChanged(data) elif messageType == WS_MESSAGE_TYPE_USER_DATA_CHANGED: self._ProcessMessageUserDataChanged(data) elif messageType in (WS_MESSAGE_TYPE_SERVER_SHUTTING_DOWN, WS_MESSAGE_TYPE_SERVER_RESTARTING): self._ProcessMessageServer(messageType, data) else: ProviderObserver.log( 'ignoring "{}" message from {}'.format( messageType, mediaProvider2str(self._mediaProvider)), xbmc.LOGDEBUG)
def _ProcessMessages(self): # nothing to do if we are not connected to an Emby server if not self._connected: return while True: try: message = self._websocket.recv() if message is None: break messageObj = json.loads(message) if not messageObj: ProviderObserver.log( 'invalid JSON message ({}) from {} received: {}'. format(len(message), mediaProvider2str(self._mediaProvider), message), xbmc.LOGWARNING) continue self._ProcessMessage(messageObj) except websocket.WebSocketTimeoutException: break except Exception as error: ProviderObserver.log( 'unknown exception when receiving data from {}: {}'.format( mediaProvider2str(self._mediaProvider), error.args[0]), xbmc.LOGWARNING) break
def _ProcessMessage(self, message): if not message: return if not WS_MESSAGE_NOTIFICATION_CONTAINER in message: log( 'message without "{}" received from {}: {}'.format( WS_MESSAGE_NOTIFICATION_CONTAINER, mediaProvider2str(self._mediaProvider), json.dumps(message)), xbmc.LOGWARNING) return messageData = message[WS_MESSAGE_NOTIFICATION_CONTAINER] if not WS_MESSAGE_NOTIFICATION_TYPE in messageData: log( 'message without "{}" received from {}: {}'.format( WS_MESSAGE_NOTIFICATION_TYPE, mediaProvider2str(self._mediaProvider), json.dumps(message)), xbmc.LOGWARNING) return messageType = messageData[WS_MESSAGE_NOTIFICATION_TYPE] if messageType == WS_MESSAGE_NOTIFICATION_TYPE_TIMELINE: self._ProcessMessageTimelineEntry(messageData) elif messageType == WS_MESSAGE_NOTIFICATION_TYPE_PLAYING: self._ProcessMessagePlaySessionState(messageData) elif messageType == WS_MESSAGE_NOTIFICATION_TYPE_ACTIVITY: self._ProcessMessageActivity(messageData) else: log( 'ignoring "{}" message from {}: {}'.format( messageType, mediaProvider2str(self._mediaProvider), json.dumps(message)), xbmc.LOGDEBUG)
def _ProcessMessageUserDataChanged(self, data): ProviderObserver.log( 'processing userdata changed message from {}...'.format( mediaProvider2str(self._mediaProvider))) userDataList = data[WS_USER_DATA_CHANGED_USER_DATA_LIST] changedItems = [] for userDataItem in userDataList: if not WS_USER_DATA_CHANGED_USER_DATA_ITEM_ID in userDataItem: continue itemId = userDataItem[WS_USER_DATA_CHANGED_USER_DATA_ITEM_ID] if not itemId or not isinstance(itemId, string_types): continue item = self._GetItemDetails(itemId) if not item: ProviderObserver.log( 'failed to get details for changed item with id "{}" from {}' .format(itemId, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING) continue changedItems.append( (xbmcmediaimport.MediaImportChangesetTypeChanged, item, itemId)) self._ChangeItems(changedItems)
def _ChangeItems(self, changedItems): # map the changed items to their media import changedItemsMap = {} for (changesetType, item, itemId) in changedItems: if not item: continue # find a matching import for the changed item mediaImport = self._FindImportForItem(item) if not mediaImport: ProviderObserver.log( 'failed to determine media import for changed item with id "{}" from {}' .format(itemId, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING) continue if mediaImport not in changedItemsMap: changedItemsMap[mediaImport] = [] changedItemsMap[mediaImport].append((changesetType, item)) # finally pass the changed items grouped by their media import to Kodi for (mediaImport, changedItems) in changedItemsMap.items(): if xbmcmediaimport.changeImportedItems(mediaImport, changedItems): ProviderObserver.log( 'changed {} imported items for media import {} from {}'. format(len(changedItems), mediaImport2str(mediaImport), mediaProvider2str(self._mediaProvider))) else: ProviderObserver.log( 'failed to change {} imported items for media import {} from {}' .format(len(changedItems), mediaImport2str(mediaImport), mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING)
def _addExternalSubtitles(self): if not self._item: return # get the item's details to look for external subtitles itemObj = Library.GetItem(self._server, self._itemId) if not itemObj: Player.log('cannot retrieve details of "{}" ({}) from media provider {}' \ .format(self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING) return # extract the media source ID if not PROPERTY_ITEM_MEDIA_SOURCES in itemObj or not itemObj[ PROPERTY_ITEM_MEDIA_SOURCES]: Player.log('cannot add external subtitles for "{}" ({}) from media provider {} ' \ 'because it doesn\'t have a media source' \ .format(self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)), xbmc.LOGDEBUG) return mediaSourceId = itemObj.get(PROPERTY_ITEM_MEDIA_SOURCES)[0].get( PROPERTY_ITEM_MEDIA_SOURCES_ID) # look for external subtitles for stream in itemObj.get(PROPERTY_ITEM_MEDIA_STREAMS): if stream.get(PROPERTY_ITEM_MEDIA_STREAM_TYPE ) != 'Subtitle' or not stream.get( PROPERTY_ITEM_MEDIA_STREAM_IS_EXTERNAL): continue # get the index of the subtitle index = stream.get(PROPERTY_ITEM_MEDIA_STREAM_INDEX) # determine the language and name name = stream.get( PROPERTY_ITEM_MEDIA_STREAM_DISPLAY_TITLE ) if PROPERTY_ITEM_MEDIA_STREAM_DISPLAY_TITLE in stream else '' language = stream.get( PROPERTY_ITEM_MEDIA_STREAM_LANGUAGE ) if PROPERTY_ITEM_MEDIA_STREAM_LANGUAGE in stream else '' # determine the stream URL if PROPERTY_ITEM_MEDIA_STREAM_DELIVERY_URL in stream and \ stream.get(PROPERTY_ITEM_MEDIA_STREAM_DELIVERY_URL).upper().startswith('/{}'.format(URL_VIDEOS)): url = self._server.BuildStreamDeliveryUrl( stream.get(PROPERTY_ITEM_MEDIA_STREAM_DELIVERY_URL)) else: url = self._server.BuildSubtitleStreamUrl( self._itemId, mediaSourceId, index, stream.get(PROPERTY_ITEM_MEDIA_STREAM_CODEC)) if not url: Player.log('cannot add external subtitle at index {} for "{}" ({}) from media provider {}' \ .format(index, self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING) continue self.addSubtitle(url, name, language, False) # TODO(Montellese): activate? Player.log('external subtitle "{}" [{}] at index {} added for "{}" ({}) from media provider {}' \ .format(name, language, index, self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)))
def _StartAction(self, mediaProvider): if not mediaProvider: raise RuntimeError('invalid mediaProvider') # if we are already connected check if something important changed in the media provider if self._connected: if Api.compareMediaProviders(self._mediaProvider, mediaProvider): return True self._StopAction(restart=True) self._mediaProvider = mediaProvider settings = self._mediaProvider.prepareSettings() if not settings: raise RuntimeError('cannot prepare media provider settings') # create Plex server instance self._server = Server(self._mediaProvider) # first authenticate with the Plex Media Server try: authenticated = self._server.Authenticate() except: authenticated = False if not authenticated: log( 'failed to authenticate with {}'.format( mediaProvider2str(self._mediaProvider)), xbmc.LOGERROR) self._Reset() return False # prepare the URL url = self._server.PlexServer().url(self.ENDPOINT, includeToken=True).replace( 'http', 'ws') # connect the websocket try: self._websocket.connect(url) except: log('failed to connect to {} using a websocket'.format(url), xbmc.LOGERROR) self._Reset() return False log('successfully connected to {} to observe media imports'.format( mediaProvider2str(self._mediaProvider))) self._connected = True return True
def discoverProviderLocally(handle, options): baseUrl = xbmcgui.Dialog().input(localise(32050), 'http://') if not baseUrl: return None log('trying to discover an Emby server at {}...'.format(baseUrl)) try: serverInfo = emby.api.server.Server.GetInfo(baseUrl) if not serverInfo: return None except: return None providerId = Server.BuildProviderId(serverInfo.id) providerIconUrl = Server.BuildIconUrl(baseUrl) provider = xbmcmediaimport.MediaProvider( providerId, baseUrl, serverInfo.name, providerIconUrl, emby.constants.SUPPORTED_MEDIA_TYPES) provider.setIconUrl(kodi.Api.downloadIcon(provider)) # store local authentication in settings providerSettings = provider.prepareSettings() if not providerSettings: return None providerSettings.setString( emby.constants.SETTING_PROVIDER_AUTHENTICATION, emby.constants.SETTING_PROVIDER_AUTHENTICATION_OPTION_LOCAL) providerSettings.save() log('Local Emby server {} successfully discovered at {}'.format( mediaProvider2str(provider), baseUrl)) return provider
def settingOptionsFillerViews(handle, options): # retrieve the media provider mediaProvider = xbmcmediaimport.getProvider(handle) if not mediaProvider: log('cannot retrieve media provider', xbmc.LOGERROR) return # retrieve the media import mediaImport = xbmcmediaimport.getImport(handle) if not mediaImport: log('cannot retrieve media import', xbmc.LOGERROR) return # prepare the media provider settings if not mediaProvider.prepareSettings(): log('cannot prepare media provider settings', xbmc.LOGERROR) return embyServer = Server(mediaProvider) if not embyServer.Authenticate(): log('failed to authenticate on media provider {}'.format(mediaProvider2str(mediaProvider)), xbmc.LOGERROR) return libraryViews = Library.GetViews(embyServer, mediaImport.getMediaTypes()) views = [] for libraryView in libraryViews: views.append((libraryView.name, libraryView.id)) # get the import's settings settings = mediaImport.getSettings() # pass the list of views back to Kodi settings.setStringOptions(emby.constants.SETTING_IMPORT_VIEWS_SPECIFIC, views)
def settingOptionsFillerLibrarySections(handle, options): # retrieve the media provider mediaProvider = xbmcmediaimport.getProvider(handle) if not mediaProvider: log('cannot retrieve media provider', xbmc.LOGERROR) return # retrieve the media import mediaImport = xbmcmediaimport.getImport(handle) if not mediaImport: log('cannot retrieve media import', xbmc.LOGERROR) return # prepare the media provider settings if not mediaProvider.prepareSettings(): log('cannot prepare media provider settings', xbmc.LOGERROR) return server = Server(mediaProvider) if not server.Authenticate(): log('failed to connect to Plex Media Server for {}'.format(mediaProvider2str(mediaProvider)), xbmc.LOGWARNING) return plexServer = server.PlexServer() # get all library sections mediaTypes = mediaImport.getMediaTypes() librarySections = getLibrarySections(plexServer, mediaTypes) sections = [ (section['title'], section['key']) for section in librarySections ] # get the import's settings settings = mediaImport.getSettings() # pass the list of views back to Kodi settings.setStringOptions(plex.constants.SETTINGS_IMPORT_LIBRARY_SECTIONS, sections)
def downloadIcon(mediaProvider): if not mediaProvider: raise ValueError('invalid mediaProvider') try: basePath = xbmc.translatePath(__addon__.getAddonInfo('profile')).decode('utf-8') except AttributeError: basePath = xbmc.translatePath(__addon__.getAddonInfo('profile')) # determine the icon's URL on the media provider iconUrl = Server.BuildIconUrl(mediaProvider.getBasePath()) # make sure the addon data directory exists if not xbmcvfs.exists(basePath): if not Api._makeDir(basePath): log('failed to create addon data directory at {}'.format(basePath), xbmc.LOGWARNING) return iconUrl # generate the icon's local path serverId = Server.GetServerId(mediaProvider.getIdentifier()) iconPath = os.path.join(basePath, '{}.png'.format(serverId)) # try to download the icon (since Emby's webserver doesn't support HEAD requests) try: urlretrieve(iconUrl, iconPath) except IOError as err: log('failed to download icon for {} from {}: {}'.format(mediaProvider2str(mediaProvider), iconUrl, err), xbmc.LOGWARNING) return iconUrl return iconPath
def onPlayBackSeekChapter(self, chapter): with self._lock: if self._reportPlaybackProgress(): Player.log( 'playback seek chapter for "{}" ({}) on {} reported'. format(self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)))
def _addServer(self, server): registerServer = False # check if the server is already known if not server.id in self._servers: self._servers[server.id] = server registerServer = True else: # check if the server has already been registered or if some of its properties have changed if not self._servers[server.id].registered or self._servers[ server.id].name != server.name or self._servers[ server.id].address != server.address: self._servers[server.id] = server registerServer = True else: # simply update the server's last seen property self._servers[server.id].lastseen = server.lastseen # if the server doesn't need to be registered there's nothing else to do if not registerServer: return providerId = Server.BuildProviderId(server.id) providerIconUrl = Server.BuildIconUrl(server.address) provider = xbmcmediaimport.MediaProvider( providerId, server.address, server.name, providerIconUrl, plex.constants.SUPPORTED_MEDIA_TYPES) # store local authentication in settings providerSettings = provider.prepareSettings() if not providerSettings: return None providerSettings.setInt( plex.constants.SETTINGS_PROVIDER_AUTHENTICATION, plex.constants.SETTINGS_PROVIDER_AUTHENTICATION_OPTION_LOCAL) providerSettings.save() if xbmcmediaimport.addAndActivateProvider(provider): self._servers[server.id].registered = True log('Plex Media Server {} successfully added and activated'.format( mediaProvider2str(provider))) else: self._servers[server.id].registered = False log('failed to add and/or activate Plex Media Server {}'.format( mediaProvider2str(provider)))
def onPlayBackResumed(self): with self._lock: self._paused = False if self._reportPlaybackProgress(): Player.log( 'playback resumed for "{}" ({}) on {} reported'.format( self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)))
def refreshMetadata(item, itemId, mediaProvider): # create an Emby server instance embyServer = Server(mediaProvider) # trigger a metadata refresh on the Emby server Library.RefreshItemMetadata(embyServer, itemId) log('[context/refresh] triggered metadata refresh for {} on {}'.format( listItem2str(item, itemId), mediaProvider2str(mediaProvider)))
def RemoveProvider(self, mediaProvider): if not mediaProvider: raise ValueError('invalid mediaProvider') with self._lock: del self._providers[mediaProvider.getIdentifier()] Player.log('{} removed'.format(mediaProvider2str(mediaProvider)))
def AddProvider(self, mediaProvider): if not mediaProvider: raise ValueError('invalid mediaProvider') with self._lock: self._providers[mediaProvider.getIdentifier()] = mediaProvider Player.log('{} added'.format(mediaProvider2str(mediaProvider)))
def AddImport(self, mediaImport): if not mediaImport: raise ValueError('invalid mediaImport') # look for a matching import matchingImportIndices = self._FindImportIndices(mediaImport) # if a matching import has been found update it if matchingImportIndices: self._imports[matchingImportIndices[0]] = mediaImport ProviderObserver.log('media import {} from {} updated'.format( mediaImport2str(mediaImport), mediaProvider2str(self._mediaProvider))) else: # otherwise add the import to the list self._imports.append(mediaImport) ProviderObserver.log('media import {} from {} added'.format( mediaImport2str(mediaImport), mediaProvider2str(self._mediaProvider)))
def _StopAction(self, restart=False): if not self._connected: return if not restart: log('stopped observing media imports from {}'.format( mediaProvider2str(self._mediaProvider))) self._websocket.close() self._Reset()
def _stopPlayback(self, failed=False): if not self._item: return data = self._preparePlayingData(stopped=True, failed=failed) PlaybackCheckin.StopPlayback(self._server, data) Player.log('playback stopped for "{}" ({}) on {} reported'.format( self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider))) self._reset()
def RemoveImport(self, mediaImport): if not mediaImport: raise ValueError('invalid mediaImport') # look for a matching import matchingImportIndices = self._FindImportIndices(mediaImport) if not matchingImportIndices: return # remove the media import from the list del self._imports[matchingImportIndices[0]] ProviderObserver.log('media import {} from {} removed'.format( mediaImport2str(mediaImport), mediaProvider2str(self._mediaProvider)))
def _ProcessMessageActivity(self, data): if not WS_MESSAGE_NOTIFICATION_ACTIVITY in data: log( 'invalid activity message received from {}: {}'.format( mediaProvider2str(self._mediaProvider), json.dumps(data)), xbmc.LOGWARNING) return activities = data[WS_MESSAGE_NOTIFICATION_ACTIVITY] if not activities: return changedPlexItems = [] for activity in activities: if not all(key in activity for key in (WS_MESSAGE_NOTIFICATION_ACTIVITY_EVENT, WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY)): continue # we are only interested in the final result if activity[ WS_MESSAGE_NOTIFICATION_ACTIVITY_EVENT] != WS_MESSAGE_NOTIFICATION_ACTIVITY_EVENT_ENDED: continue activityDetails = activity[ WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY] if not all(key in activityDetails for key in ( WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY_TYPE, WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY_CONTEXT)): continue # we are only interested in changes to library items if activityDetails[ WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY_TYPE] != WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY_TYPE_REFRESH_ITEMS: continue context = activityDetails[ WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY_CONTEXT] if not WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY_CONTEXT_KEY in context: continue plexItemKey = context[ WS_MESSAGE_NOTIFICATION_ACTIVITY_ACTIVITY_CONTEXT_KEY] plexItemId = Api.getItemIdFromPlexKey(plexItemKey) if not plexItemId: continue changedPlexItems.append( (xbmcmediaimport.MediaImportChangesetTypeChanged, plexItemId, None)) self._ProcessChangedPlexItems(changedPlexItems)
def synchronize(item, itemId, mediaProvider): # find the matching media import mediaImport = getMediaImport(mediaProvider, item) if not mediaImport: log( '[context/sync] cannot find the media import of {} from {}'.format( listItem2str(item, itemId), mediaProvider2str(mediaProvider)), xbmc.LOGERROR) return # determine whether Direct Play is allowed mediaProviderSettings = mediaProvider.getSettings() allowDirectPlay = mediaProviderSettings.getBool( emby.constants.SETTING_PROVIDER_PLAYBACK_ALLOW_DIRECT_PLAY) # create an Emby server instance embyServer = Server(mediaProvider) # synchronize the active item syncedItem = synchronizeItem(item, itemId, mediaProvider, embyServer, allowDirectPlay=allowDirectPlay) if not syncedItem: return syncedItems = [(xbmcmediaimport.MediaImportChangesetTypeChanged, syncedItem)] if xbmcmediaimport.changeImportedItems(mediaImport, syncedItems): log('[context/sync] synchronized {} from {}'.format( listItem2str(item, itemId), mediaProvider2str(mediaProvider))) else: log( '[context/sync] failed to synchronize {} from {}'.format( listItem2str(item, itemId), mediaProvider2str(mediaProvider)), xbmc.LOGWARNING)
def _GetItemDetails(self, itemId): # retrieve all details of the item itemObj = Library.GetItem(self._server, itemId) if not itemObj: ProviderObserver.log( 'cannot retrieve details of updated item with id "{}" from {}'. format(itemId, mediaProvider2str(self._mediaProvider)), xbmc.LOGERROR) return None return kodi.Api.toFileItem( self._server, itemObj, allowDirectPlay=self._settings.getBool( SETTING_PROVIDER_PLAYBACK_ALLOW_DIRECT_PLAY))
def _ProcessMessagePlaySessionState(self, data): if not WS_MESSAGE_NOTIFICATION_PLAY_SESSION_STATE in data: log( 'invalid playing message received from {}: {}'.format( mediaProvider2str(self._mediaProvider), json.dumps(data)), xbmc.LOGWARNING) return playSessionStates = data[WS_MESSAGE_NOTIFICATION_PLAY_SESSION_STATE] if not playSessionStates: return for playSessionState in playSessionStates: # TODO(Montellese) pass
def synchronizeItem(item, itemId, mediaProvider, embyServer, allowDirectPlay=True): # retrieve all details of the item itemObj = Library.GetItem(embyServer, itemId) if not itemObj: log( '[context/sync] cannot retrieve details of {} from {}'.format( listItem2str(item, itemId), mediaProvider2str(mediaProvider)), xbmc.LOGERROR) return None return kodi.Api.toFileItem(embyServer, itemObj, allowDirectPlay=allowDirectPlay)
def testAuthentication(handle, _): # retrieve the media provider mediaProvider = xbmcmediaimport.getProvider(handle) if not mediaProvider: log('cannot retrieve media provider', xbmc.LOGERROR) return log('testing authentication with {}...'.format(mediaProvider2str(mediaProvider))) success = False try: success = Server(mediaProvider).Authenticate(force=True) except: pass line = 32018 if success: line = 32017 xbmcgui.Dialog().ok(mediaProvider.getFriendlyName(), localise(line))
def resetDeviceId(handle, _): # retrieve the media provider mediaProvider = xbmcmediaimport.getProvider(handle) if not mediaProvider: log('cannot retrieve media provider', xbmc.LOGERROR) return # get the media provider settings providerSettings = mediaProvider.prepareSettings() if not providerSettings: return deviceId = Request.GenerateDeviceId() log('created a new device identifier for {}: {}'.format(mediaProvider2str(mediaProvider), deviceId)) providerSettings.setString(emby.constants.SETTING_PROVIDER_DEVICEID, deviceId) xbmcgui.Dialog().ok(mediaProvider.getFriendlyName(), localise(32063))
def run(action): item = sys.listitem # pylint: disable=no-member if not item: log('[context] missing ListItem', xbmc.LOGERROR) return itemId = kodi.Api.getEmbyItemIdFromItem(item) if not itemId: log( '[context] cannot determine the Emby identifier of "{}"'.format( item.getLabel()), xbmc.LOGERROR) return mediaProviderId = item.getMediaProviderId() if not mediaProviderId: log( '[context] cannot determine the media provider identifier of {}'. format(listItem2str(item, itemId)), xbmc.LOGERROR) return # get the media provider mediaProvider = xbmcmediaimport.getProviderById(mediaProviderId) if not mediaProvider: log( '[context] cannot determine the media provider ({}) of {}'.format( mediaProviderId, listItem2str(item, itemId)), xbmc.LOGERROR) return # prepare the media provider settings if not mediaProvider.prepareSettings(): log( '[context] cannot prepare media provider ({}) settings of {}'. format(mediaProvider2str(mediaProvider), listItem2str(item, itemId)), xbmc.LOGERROR) return if action == ContextAction.Play: play(item, itemId, mediaProvider) elif action == ContextAction.Synchronize: synchronize(item, itemId, mediaProvider) elif action == ContextAction.RefreshMetadata: refreshMetadata(item, itemId, mediaProvider) else: raise ValueError('unknown action {}'.format(action))
def discoverProvider(handle, options): baseUrl = xbmcgui.Dialog().input(localise(32050), 'http://') if not baseUrl: return log('trying to discover an Emby server at {}...'.format(baseUrl)) try: serverInfo = emby.api.server.Server.GetInfo(baseUrl) if not serverInfo: return except: return providerId = Server.BuildProviderId(serverInfo.id) providerIconUrl = Server.BuildIconUrl(baseUrl) mediaProvider = xbmcmediaimport.MediaProvider(providerId, baseUrl, serverInfo.name, providerIconUrl, emby.constants.SUPPORTED_MEDIA_TYPES) mediaProvider.setIconUrl(kodi.Api.downloadIcon(mediaProvider)) log('Emby server {} successfully discovered at {}'.format(mediaProvider2str(mediaProvider), baseUrl)) xbmcmediaimport.setDiscoveredProvider(handle, True, mediaProvider)