Example #1
0
 def update_items(self, itemsToUpdate):
     # doing adds and updates
     if (len(itemsToUpdate) > 0):
         self.logMsg(
             "Message : Doing LibraryChanged : Processing Added and Updated : "
             + str(itemsToUpdate), 0)
         connection = utils.KodiSQL()
         cursor = connection.cursor()
         LibrarySync().MoviesSync(connection,
                                  cursor,
                                  fullsync=False,
                                  installFirstRun=False,
                                  itemList=itemsToUpdate)
         LibrarySync().TvShowsSync(connection,
                                   cursor,
                                   fullsync=False,
                                   installFirstRun=False,
                                   itemList=itemsToUpdate)
         cursor.close()
Example #2
0
    def user_data_update(self, userDataList):

        for userData in userDataList:
            self.logMsg(
                "Message : Doing UserDataChanged : UserData : " +
                str(userData), 0)
            itemId = userData.get("ItemId")
            if (itemId != None):
                self.logMsg(
                    "Message : Doing UserDataChanged : calling updatePlayCount with ID : "
                    + str(itemId), 0)
                LibrarySync().updatePlayCount(itemId)
Example #3
0
    def ServiceEntryPoint(self):

        kodiProfile = xbmc.translatePath("special://profile")

        # Server auto-detect
        ConnectionManager().checkServer()

        # Initialize important threads
        user = UserClient()
        player = Player()
        ws = WebSocketThread()
        library = LibrarySync()
        # Sync and progress report
        lastProgressUpdate = datetime.today()

        while not self.KodiMonitor.abortRequested():

            # Before proceeding, need to make sure:
            # 1. Server is online
            # 2. User is set
            # 3. User has access to the server

            if utils.window("kodiProfile_emby") != kodiProfile:
                # Profile change happened, terminate this thread
                self.logMsg("Kodi profile was: %s and changed to: %s. Terminating old Emby thread." % (kodiProfile, utils.window("kodiProfile_emby")), 1)
                break
            
            if utils.window('Server_online') == "true":
                
                # Emby server is online
                # Verify if user is set and has access to the server
                if (user.currUser is not None) and user.HasAccess:

                    # If an item is playing
                    if xbmc.Player().isPlaying():
                        try:
                            # Update and report progress
                            playTime = xbmc.Player().getTime()
                            totalTime = xbmc.Player().getTotalTime()
                            currentFile = player.currentFile

                            # Update positionticks
                            if player.played_information.get(currentFile) is not None:
                                player.played_information[currentFile]['currentPosition'] = playTime
                            
                            td = datetime.today() - lastProgressUpdate
                            secDiff = td.seconds
                            
                            # Report progress to Emby server
                            if (secDiff > 3):
                                player.reportPlayback()
                                lastProgressUpdate = datetime.today()
                            
                            elif utils.window('commandUpdate') == "true":
                                # Received a remote control command that
                                # requires updating immediately
                                utils.window('commandUpdate', clear=True)
                                player.reportPlayback()
                                lastProgressUpdate = da4tetime.today()
                            
                        except Exception as e:
                            self.logMsg("Exception in Playback Monitor Service: %s" % e, 1)
                            pass
                    else:
                        # Start up events
                        self.warn_auth = True
                        if utils.settings('supressConnectMsg') == "false":
                            if self.welcome_msg:
                                # Reset authentication warnings
                                self.welcome_msg = False
                                # Get additional users
                                additionalUsers = user.AdditionalUser
                                if additionalUsers:
                                    add = ", %s" % ", ".join(additionalUsers)
                                else:
                                    add = ""
                                xbmcgui.Dialog().notification("Emby server", "Welcome %s%s!" % (user.currUser, add), icon="special://home/addons/plugin.video.emby/icon.png", time=2000, sound=False)

                        # Start the Websocket Client
                        if (self.newWebSocketThread is None):
                            self.newWebSocketThread = "Started"
                            ws.start()
                        # Start the Library Sync Thread
                        if (self.newLibraryThread is None):
                            self.newLibraryThread = "Started"
                            library.start()
                            
                else:
                    
                    if (user.currUser is None) and self.warn_auth:
                        # Alert user is not authenticated and suppress future warning
                        self.warn_auth = False
                        self.logMsg("Not authenticated yet.", 1)

                    # User access is restricted.
                    # Keep verifying until access is granted
                    # unless server goes offline or Kodi is shut down.
                    while user.HasAccess == False:
                        # Verify access with an API call
                        user.hasAccess()

                        if utils.window('Server_online') != "true":
                            # Server went offline
                            break

                        if self.KodiMonitor.waitForAbort(5):
                            # Abort was requested while waiting. We should exit
                            break

            else:
                # Wait until Emby server is online
                # or Kodi is shut down.
                while not self.KodiMonitor.abortRequested():
                    
                    if user.getServer() == "":
                        # No server info set in add-on settings
                        pass
                    
                    elif user.getPublicUsers() == False:
                        # Server is offline.
                        # Alert the user and suppress future warning
                        if self.server_online:
                            self.logMsg("Server is offline.", 1)
                            utils.window('Server_online', value="false")
                            xbmcgui.Dialog().notification("Error connecting", "%s Server is unreachable." % self.addonName, icon="special://home/addons/plugin.video.emby/icon.png", sound=False)
                        self.server_online = False
                    
                    else:
                        # Server is online
                        if not self.server_online:
                            # Server was offline when Kodi started.
                            # Wait for server to be fully established.
                            if self.KodiMonitor.waitForAbort(5):
                                # Abort was requested while waiting.
                                break
                            # Alert the user that server is online.
                            xbmcgui.Dialog().notification("Emby server", "Welcome %s!" % user.currUser, icon="special://home/addons/plugin.video.emby/icon.png", time=2000, sound=False)
                        
                        self.server_online = True
                        self.logMsg("Server is online and ready.", 1)
                        utils.window('Server_online', value="true")
                        
                        # Start the User client
                        if self.newUserClient is None:
                            self.newUserClient = "Started"
                            user.start()
                        break

                    if self.KodiMonitor.waitForAbort(1):
                        # Abort was requested while waiting.
                        break

            if self.KodiMonitor.waitForAbort(1):
                # Abort was requested while waiting. We should exit
                break

        ##### Emby thread is terminating. #####

        # If music is enabled and direct stream for music is enabled
        # We use Kodi pathsubstitution to allow for music to play outside network
        # The setting needs to be set before Kodi starts.
        if utils.settings('enableMusicSync') == "true" and utils.settings('directstreammusic') == "true":
            # We need to keep track of the settings
            alternate = utils.settings('altip') == "true"
            pathsub = utils.settings('pathsub') == "true"
            
            if pathsub and not alternate:
                # Path sub in place, but primary address in use, remove it
                utils.pathsubstitution(False)
            elif not pathsub and alternate:
                # Path sub not in place, but secondary address in use, add it
                utils.pathsubstitution()
        
        if (self.newWebSocketThread is not None):
            ws.stopClient()

        if (self.newUserClient is not None):
            user.stopClient()

        self.logMsg("======== STOP %s ========" % self.addonName, 0)
Example #4
0
    def stopAll(self):

        if not self.played_information:
            return

        self.logMsg("Played_information: %s" % self.played_information, 1)
        # Process each items
        for item in self.played_information:

            data = self.played_information.get(item)
            if data:

                self.logMsg("Item path: %s" % item, 2)
                self.logMsg("Item data: %s" % data, 2)

                runtime = data['runtime']
                currentPosition = data['currentPosition']
                itemId = data['item_id']
                refresh_id = data['refresh_id']
                currentFile = data['currentfile']
                type = data['Type']
                playMethod = data['playmethod']

                if currentPosition and runtime:
                    percentComplete = (currentPosition *
                                       10000000) / int(runtime)
                    markPlayedAt = float(utils.settings('markPlayed')) / 100

                    self.logMsg(
                        "Percent complete: %s Mark played at: %s" %
                        (percentComplete, markPlayedAt), 1)
                    # Prevent manually mark as watched in Kodi monitor > WriteKodiVideoDB().UpdatePlaycountFromKodi()
                    utils.window('SkipWatched%s' % itemId, "true")

                    self.stopPlayback(data)
                    offerDelete = utils.settings('offerDelete') == "true"
                    offerTypeDelete = False

                    if type == "Episode" and utils.settings(
                            'offerDeleteTV') == "true":
                        offerTypeDelete = True

                    elif type == "Movie" and utils.settings(
                            'offerDeleteMovies') == "true":
                        offerTypeDelete = True

                    if percentComplete >= markPlayedAt and offerDelete and offerTypeDelete:
                        # Make the bigger setting be able to disable option easily.
                        self.logMsg("Offering deletion for: %s." % itemId, 1)
                        return_value = xbmcgui.Dialog().yesno(
                            "Offer Delete",
                            "Delete %s" % currentFile.split("/")[-1],
                            "on Emby Server?")
                        if return_value:
                            # Delete Kodi entry before Emby
                            listItem = [itemId]
                            LibrarySync().removefromDB(listItem, True)

                # Stop transcoding
                if playMethod == "Transcode":
                    self.logMsg("Transcoding for %s terminated." % itemId, 1)
                    deviceId = self.clientInfo.getMachineId()
                    url = "{server}/mediabrowser/Videos/ActiveEncodings?DeviceId=%s" % deviceId
                    self.doUtils.downloadUrl(url, type="DELETE")

        self.played_information.clear()
Example #5
0
class Player(xbmc.Player):

    # Borg - multiple instances, shared state
    _shared_state = {}

    xbmcplayer = xbmc.Player()
    doUtils = DownloadUtils()
    clientInfo = ClientInformation()
    ws = WebSocketThread()
    librarySync = LibrarySync()

    addonName = clientInfo.getAddonName()

    played_information = {}
    playStats = {}
    currentFile = None

    def __init__(self, *args):

        self.__dict__ = self._shared_state
        self.logMsg("Starting playback monitor.", 2)

    def logMsg(self, msg, lvl=1):

        self.className = self.__class__.__name__
        utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl))

    def GetPlayStats(self):
        return self.playStats

    def onPlayBackStarted(self):
        # Will be called when xbmc starts playing a file
        xbmcplayer = self.xbmcplayer
        self.stopAll()

        # Get current file
        try:
            currentFile = xbmcplayer.getPlayingFile()
            xbmc.sleep(300)
        except:
            currentFile = ""
            count = 0
            while not currentFile:
                xbmc.sleep(100)
                try:
                    currentFile = xbmcplayer.getPlayingFile()
                except:
                    pass

                if count == 5:  # try 5 times
                    self.logMsg("Cancelling playback report...", 1)
                    break
                else:
                    count += 1

        if currentFile:

            self.currentFile = currentFile

            # We may need to wait for info to be set in kodi monitor
            itemId = utils.window("%sitem_id" % currentFile)
            tryCount = 0
            while not itemId:

                xbmc.sleep(200)
                itemId = utils.window("%sitem_id" % currentFile)
                if tryCount == 20:  # try 20 times or about 10 seconds
                    self.logMsg(
                        "Could not find itemId, cancelling playback report...",
                        1)
                    break
                else:
                    tryCount += 1

            else:
                self.logMsg(
                    "ONPLAYBACK_STARTED: %s ITEMID: %s" %
                    (currentFile, itemId), 0)

                # Only proceed if an itemId was found.
                runtime = utils.window("%sruntimeticks" % currentFile)
                refresh_id = utils.window("%srefresh_id" % currentFile)
                playMethod = utils.window("%splaymethod" % currentFile)
                itemType = utils.window("%stype" % currentFile)
                seekTime = xbmcplayer.getTime()

                # Get playback volume
                volume_query = '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume","muted"]}, "id": 1}'
                result = xbmc.executeJSONRPC(volume_query)
                result = json.loads(result)
                result = result.get('result')

                volume = result.get('volume')
                muted = result.get('muted')

                # Postdata structure to send to Emby server
                url = "{server}/mediabrowser/Sessions/Playing"
                postdata = {
                    'QueueableMediaTypes': "Video",
                    'CanSeek': True,
                    'ItemId': itemId,
                    'MediaSourceId': itemId,
                    'PlayMethod': playMethod,
                    'VolumeLevel': volume,
                    'PositionTicks': int(seekTime * 10000000),
                    'IsMuted': muted
                }

                # Get the current audio track and subtitles
                if playMethod == "Transcode":
                    # property set in PlayUtils.py
                    postdata['AudioStreamIndex'] = utils.window(
                        "%sAudioStreamIndex" % currentFile)
                    postdata['SubtitleStreamIndex'] = utils.window(
                        "%sSubtitleStreamIndex" % currentFile)

                else:
                    # Get the current kodi audio and subtitles and convert to Emby equivalent
                    track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties",  "params": {"playerid": 1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}'
                    result = xbmc.executeJSONRPC(track_query)
                    result = json.loads(result)
                    result = result.get('result')

                    try:  # Audio tracks
                        indexAudio = result['currentaudiostream']['index']
                    except (KeyError, TypeError):
                        indexAudio = 0

                    try:  # Subtitles tracks
                        indexSubs = result['currentsubtitle']['index']
                    except (KeyError, TypeError):
                        indexSubs = 0

                    try:  # If subtitles are enabled
                        subsEnabled = result['subtitleenabled']
                    except (KeyError, TypeError):
                        subsEnabled = ""

                    # Postdata for the audio
                    postdata['AudioStreamIndex'] = indexAudio + 1

                    # Postdata for the subtitles
                    if subsEnabled and len(
                            xbmc.Player().getAvailableSubtitleStreams()) > 0:

                        # Number of audiotracks to help get Emby Index
                        audioTracks = len(
                            xbmc.Player().getAvailableAudioStreams())
                        mapping = utils.window("%sIndexMapping" % currentFile)

                        if mapping:  # Set in PlaybackUtils.py

                            self.logMsg(
                                "Mapping for external subtitles index: %s" %
                                mapping, 2)
                            externalIndex = json.loads(mapping)

                            if externalIndex.get(str(indexSubs)):
                                # If the current subtitle is in the mapping
                                postdata[
                                    'SubtitleStreamIndex'] = externalIndex[str(
                                        indexSubs)]
                            else:
                                # Internal subtitle currently selected
                                postdata[
                                    'SubtitleStreamIndex'] = indexSubs - len(
                                        externalIndex) + audioTracks + 1

                        else:  # Direct paths enabled scenario or no external subtitles set
                            postdata[
                                'SubtitleStreamIndex'] = indexSubs + audioTracks + 1
                    else:
                        postdata['SubtitleStreamIndex'] = ""

                # Post playback to server
                self.logMsg("Sending POST play started: %s." % postdata, 2)
                self.doUtils.downloadUrl(url, postBody=postdata, type="POST")

                # Ensure we do have a runtime
                try:
                    runtime = int(runtime)
                except ValueError:
                    runtime = xbmcplayer.getTotalTime()
                    self.logMsg(
                        "Runtime is missing, grabbing runtime from Kodi player: %s"
                        % runtime, 1)

                # Save data map for updates and position calls
                data = {
                    'runtime': runtime,
                    'item_id': itemId,
                    'refresh_id': refresh_id,
                    'currentfile': currentFile,
                    'AudioStreamIndex': postdata['AudioStreamIndex'],
                    'SubtitleStreamIndex': postdata['SubtitleStreamIndex'],
                    'playmethod': playMethod,
                    'Type': itemType,
                    'currentPosition': int(seekTime)
                }

                self.played_information[currentFile] = data
                self.logMsg("ADDING_FILE: %s" % self.played_information, 1)

                # log some playback stats
                '''if(itemType != None):
                    if(self.playStats.get(itemType) != None):
                        count = self.playStats.get(itemType) + 1
                        self.playStats[itemType] = count
                    else:
                        self.playStats[itemType] = 1
                        
                if(playMethod != None):
                    if(self.playStats.get(playMethod) != None):
                        count = self.playStats.get(playMethod) + 1
                        self.playStats[playMethod] = count
                    else:
                        self.playStats[playMethod] = 1'''

    def reportPlayback(self):

        self.logMsg("reportPlayback Called", 2)
        xbmcplayer = self.xbmcplayer

        # Get current file
        currentFile = self.currentFile
        data = self.played_information.get(currentFile)

        # only report playback if emby has initiated the playback (item_id has value)
        if data:
            # Get playback information
            itemId = data['item_id']
            audioindex = data['AudioStreamIndex']
            subtitleindex = data['SubtitleStreamIndex']
            playTime = data['currentPosition']
            playMethod = data['playmethod']
            paused = data.get('paused', False)

            # Get playback volume
            volume_query = '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume","muted"]}, "id": 1}'
            result = xbmc.executeJSONRPC(volume_query)
            result = json.loads(result)
            result = result.get('result')

            volume = result.get('volume')
            muted = result.get('muted')

            # Postdata for the websocketclient report
            postdata = {
                'QueueableMediaTypes': "Video",
                'CanSeek': True,
                'ItemId': itemId,
                'MediaSourceId': itemId,
                'PlayMethod': playMethod,
                'PositionTicks': int(playTime * 10000000),
                'IsPaused': paused,
                'VolumeLevel': volume,
                'IsMuted': muted
            }

            if playMethod == "Transcode":
                # Track can't be changed, keep reporting the same index
                postdata['AudioStreamIndex'] = audioindex
                postdata['AudioStreamIndex'] = subtitleindex

            else:
                # Get current audio and subtitles track
                track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties",  "params": {"playerid":1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}'
                result = xbmc.executeJSONRPC(track_query)
                result = json.loads(result)
                result = result.get('result')

                try:  # Audio tracks
                    indexAudio = result['currentaudiostream']['index']
                except (KeyError, TypeError):
                    indexAudio = 0

                try:  # Subtitles tracks
                    indexSubs = result['currentsubtitle']['index']
                except (KeyError, TypeError):
                    indexSubs = 0

                try:  # If subtitles are enabled
                    subsEnabled = result['subtitleenabled']
                except (KeyError, TypeError):
                    subsEnabled = ""

                # Postdata for the audio
                data['AudioStreamIndex'], postdata['AudioStreamIndex'] = [
                    indexAudio + 1
                ] * 2

                # Postdata for the subtitles
                if subsEnabled and len(
                        xbmc.Player().getAvailableSubtitleStreams()) > 0:

                    # Number of audiotracks to help get Emby Index
                    audioTracks = len(xbmc.Player().getAvailableAudioStreams())
                    mapping = utils.window("%sIndexMapping" % currentFile)

                    if mapping:  # Set in PlaybackUtils.py

                        self.logMsg(
                            "Mapping for external subtitles index: %s" %
                            mapping, 2)
                        externalIndex = json.loads(mapping)

                        if externalIndex.get(str(indexSubs)):
                            # If the current subtitle is in the mapping
                            data['SubtitleStreamIndex'], postdata[
                                'SubtitleStreamIndex'] = [
                                    externalIndex[str(indexSubs)]
                                ] * 2
                        else:
                            # Internal subtitle currently selected
                            data['SubtitleStreamIndex'], postdata[
                                'SubtitleStreamIndex'] = [
                                    indexSubs - len(externalIndex) +
                                    audioTracks + 1
                                ] * 2

                    else:  # Direct paths enabled scenario or no external subtitles set
                        data['SubtitleStreamIndex'], postdata[
                            'SubtitleStreamIndex'] = [
                                indexSubs + audioTracks + 1
                            ] * 2
                else:
                    data['SubtitleStreamIndex'], postdata[
                        'SubtitleStreamIndex'] = [""] * 2

            # Report progress via websocketclient
            postdata = json.dumps(postdata)
            self.logMsg("Report: %s" % postdata, 2)
            self.ws.sendProgressUpdate(postdata)

    def onPlayBackPaused(self):

        currentFile = self.currentFile
        self.logMsg("PLAYBACK_PAUSED: %s" % currentFile, 2)

        if self.played_information.get(currentFile):
            self.played_information[currentFile]['paused'] = True

            self.reportPlayback()

    def onPlayBackResumed(self):

        currentFile = self.currentFile
        self.logMsg("PLAYBACK_RESUMED: %s" % currentFile, 2)

        if self.played_information.get(currentFile):
            self.played_information[currentFile]['paused'] = False

            self.reportPlayback()

    def onPlayBackSeek(self, time, seekOffset):
        # Make position when seeking a bit more accurate
        currentFile = self.currentFile
        self.logMsg("PLAYBACK_SEEK: %s" % currentFile, 2)

        if self.played_information.get(currentFile):
            position = self.xbmcplayer.getTime()
            self.played_information[currentFile]['currentPosition'] = position

            self.reportPlayback()

    def onPlayBackStopped(self):
        # Will be called when user stops xbmc playing a file
        self.logMsg("ONPLAYBACK_STOPPED", 2)
        self.stopAll()

    def onPlayBackEnded(self):
        # Will be called when xbmc stops playing a file
        self.logMsg("ONPLAYBACK_ENDED", 2)
        self.stopAll()

    def stopAll(self):

        if not self.played_information:
            return

        self.logMsg("Played_information: %s" % self.played_information, 1)
        # Process each items
        for item in self.played_information:

            data = self.played_information.get(item)
            if data:

                self.logMsg("Item path: %s" % item, 2)
                self.logMsg("Item data: %s" % data, 2)

                runtime = data['runtime']
                currentPosition = data['currentPosition']
                itemId = data['item_id']
                refresh_id = data['refresh_id']
                currentFile = data['currentfile']
                type = data['Type']
                playMethod = data['playmethod']

                if currentPosition and runtime:
                    percentComplete = (currentPosition *
                                       10000000) / int(runtime)
                    markPlayedAt = float(utils.settings('markPlayed')) / 100

                    self.logMsg(
                        "Percent complete: %s Mark played at: %s" %
                        (percentComplete, markPlayedAt), 1)
                    # Prevent manually mark as watched in Kodi monitor > WriteKodiVideoDB().UpdatePlaycountFromKodi()
                    utils.window('SkipWatched%s' % itemId, "true")

                    self.stopPlayback(data)
                    offerDelete = utils.settings('offerDelete') == "true"
                    offerTypeDelete = False

                    if type == "Episode" and utils.settings(
                            'offerDeleteTV') == "true":
                        offerTypeDelete = True

                    elif type == "Movie" and utils.settings(
                            'offerDeleteMovies') == "true":
                        offerTypeDelete = True

                    if percentComplete >= markPlayedAt and offerDelete and offerTypeDelete:
                        # Make the bigger setting be able to disable option easily.
                        self.logMsg("Offering deletion for: %s." % itemId, 1)
                        return_value = xbmcgui.Dialog().yesno(
                            "Offer Delete",
                            "Delete %s" % currentFile.split("/")[-1],
                            "on Emby Server?")
                        if return_value:
                            # Delete Kodi entry before Emby
                            listItem = [itemId]
                            LibrarySync().removefromDB(listItem, True)

                # Stop transcoding
                if playMethod == "Transcode":
                    self.logMsg("Transcoding for %s terminated." % itemId, 1)
                    deviceId = self.clientInfo.getMachineId()
                    url = "{server}/mediabrowser/Videos/ActiveEncodings?DeviceId=%s" % deviceId
                    self.doUtils.downloadUrl(url, type="DELETE")

        self.played_information.clear()

    def stopPlayback(self, data):

        self.logMsg("stopPlayback called", 2)

        itemId = data['item_id']
        currentPosition = data['currentPosition']
        positionTicks = int(currentPosition * 10000000)

        url = "{server}/mediabrowser/Sessions/Playing/Stopped"
        postdata = {
            'ItemId': itemId,
            'MediaSourceId': itemId,
            'PositionTicks': positionTicks
        }

        self.doUtils.downloadUrl(url, postBody=postdata, type="POST")
Example #6
0
    def __init__(self):

        # Parse parameters
        base_url = sys.argv[0]
        addon_handle = int(sys.argv[1])
        params = urlparse.parse_qs(sys.argv[2][1:])
        xbmc.log("Parameter string: %s" % sys.argv[2])

        try:
            mode = params['mode'][0]
            id = params.get('id', None)
            if id:
                id = id[0]
        except:
            params = {}
            mode = ""

        ##### PLAY ITEM VIA plugin://plugin.video.emby/ #####
        if "play" in mode or "playnow" in mode:
            entrypoint.doPlayback(id)

        #### DO RESET AUTH #####
        elif "resetauth" in mode:
            entrypoint.resetAuth()

        ##### DO DATABASE RESET #####
        elif "reset" in mode:
            import Utils as utils
            utils.reset()

        ##### ADD/REMOVE USER FROM SESSION #####
        elif "adduser" in mode:
            entrypoint.addUser()

        ##### SYNC THEME MEDIA #####
        elif "thememedia" in mode:
            entrypoint.getThemeMedia()

        ##### LAUNCH EMBY USER PREFS #####
        elif "userprefs" in mode:
            entrypoint.userPreferences()

        ##### OPEN ADDON SETTINGS #####
        elif "settings" in mode:
            xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')

        ##### MANUALLY SYNC LIBRARY #####
        elif "manualsync" in mode:
            from LibrarySync import LibrarySync
            LibrarySync().FullLibrarySync(True)

        ##### CACHE ARTWORK #####
        elif "texturecache" in mode:
            from TextureCache import TextureCache
            TextureCache().FullTextureCacheSync()

        ##### BROWSE EMBY CHANNELS FOLDER #####
        elif "channelsfolder" in mode:
            folderid = params['folderid'][0]
            entrypoint.BrowseChannels(id, folderid)

        ##### BROWSE EMBY CHANNELS ROOT #####
        elif "channels" in mode:
            entrypoint.BrowseChannels(id)

        ##### GET NEXTUP EPISODES FOR TAGNAME #####
        elif "nextup" in mode:
            limit = int(params['limit'][0])
            entrypoint.getNextUpEpisodes(id, limit)

        ##### GET INPROGRESS EPISODES FOR TAGNAME #####
        elif "inprogressepisodes" in mode:
            limit = int(params['limit'][0])
            entrypoint.getInProgressEpisodes(id, limit)

        ##### GET RECENT EPISODES FOR TAGNAME #####
        elif "recentepisodes" in mode:
            limit = int(params['limit'][0])
            entrypoint.getRecentEpisodes(id, limit)

        ##### GET EXTRAFANART FOR LISTITEM #####
        elif "extrafanart" in sys.argv[0]:
            entrypoint.getExtraFanArt()

        ##### SHOW ADDON NODES LISTING #####
        if not mode:
            entrypoint.doMainListing()
Example #7
0
import threading
import json
import inspect

import KodiMonitor
import Utils as utils

from DownloadUtils import DownloadUtils
from WebSocketClient import WebSocketThread
from PlayUtils import PlayUtils
from ClientInformation import ClientInformation
from LibrarySync import LibrarySync
from  PlaybackUtils import PlaybackUtils
from ReadEmbyDB import ReadEmbyDB
from API import API
librarySync = LibrarySync()

# service class for playback monitoring
class Player( xbmc.Player ):

    # Borg - multiple instances, shared state
    _shared_state = {}
    
    xbmcplayer = xbmc.Player()
    doUtils = DownloadUtils()
    clientInfo = ClientInformation()
    ws = WebSocketThread()

    addonName = clientInfo.getAddonName()
    addonId = clientInfo.getAddonId()
    addon = xbmcaddon.Addon(id=addonId)
Example #8
0
from datetime import datetime

cwd = xbmcaddon.Addon(id='plugin.video.emby').getAddonInfo('path')
BASE_RESOURCE_PATH = xbmc.translatePath( os.path.join( cwd, 'resources', 'lib' ) )
sys.path.append(BASE_RESOURCE_PATH)

import KodiMonitor
import Utils as utils
from LibrarySync import LibrarySync
from Player import Player
from DownloadUtils import DownloadUtils
from ConnectionManager import ConnectionManager
from ClientInformation import ClientInformation
from WebSocketClient import WebSocketThread
from UserClient import UserClient
librarySync = LibrarySync()


class Service():
    

    newWebSocketThread = None
    newUserClient = None

    clientInfo = ClientInformation()
    addonName = clientInfo.getAddonName()
    className = None
    
    def __init__(self, *args ):
        self.KodiMonitor = KodiMonitor.Kodi_Monitor()
        addonName = self.addonName
Example #9
0
    def on_message(self, ws, message):

        WINDOW = xbmcgui.Window(10000)
        self.logMsg("Message: %s" % message, 1)

        result = json.loads(message)
        messageType = result['MessageType']
        data = result.get("Data")

        if messageType == "Play":
            # A remote control play command has been sent from the server.
            itemIds = data['ItemIds']
            playCommand = data['PlayCommand']

            if "PlayNow" in playCommand:
                startPositionTicks = data.get('StartPositionTicks', 0)
                xbmc.executebuiltin("Dialog.Close(all,true)")
                xbmc.executebuiltin(
                    "XBMC.Notification(Playlist: Added %s items to Playlist,)"
                    % len(itemIds))
                PlaybackUtils().PLAYAllItems(itemIds, startPositionTicks)

            elif "PlayNext" in playCommand:
                xbmc.executebuiltin(
                    "XBMC.Notification(Playlist: Added %s items to Playlist,)"
                    % len(itemIds))
                playlist = PlaybackUtils().AddToPlaylist(itemIds)
                if not xbmc.Player().isPlaying():
                    xbmc.Player().play(playlist)

        elif messageType == "Playstate":
            # A remote control update playstate command has been sent from the server.
            command = data['Command']

            if "Stop" in command:
                self.logMsg("Playback Stopped.", 1)
                xbmc.Player().stop()
            elif "Unpause" in command:
                self.logMsg("Playback unpaused.", 1)
                xbmc.Player().pause()
            elif "Pause" in command:
                self.logMsg("Playback paused.", 1)
                xbmc.Player().pause()
            elif "NextTrack" in command:
                self.logMsg("Playback next track.", 1)
                xbmc.Player().playnext()
            elif "PreviousTrack" in command:
                self.logMsg("Playback previous track.", 1)
                xbmc.Player().playprevious()
            elif "Seek" in command:
                seekPositionTicks = data['SeekPositionTicks']
                seekTime = seekPositionTicks / 10000000.0
                self.logMsg("Seek to %s" % seekTime, 1)
                xbmc.Player().seekTime(seekTime)
            # Report playback
            WINDOW.setProperty('commandUpdate', "true")

        elif messageType == "UserDataChanged":
            # A user changed their personal rating for an item, or their playstate was updated
            userdataList = data['UserDataList']
            self.logMsg(
                "Message: Doing UserDataChanged: UserDataList: %s" %
                userdataList, 1)
            LibrarySync().user_data_update(userdataList)

        elif messageType == "LibraryChanged":
            # Library items
            itemsRemoved = data.get("ItemsRemoved")
            itemsAdded = data.get("ItemsAdded")
            itemsUpdated = data.get("ItemsUpdated")
            itemsToUpdate = itemsAdded + itemsUpdated

            self.logMsg(
                "Message: WebSocket LibraryChanged: Items Added: %s" %
                itemsAdded, 1)
            self.logMsg(
                "Message: WebSocket LibraryChanged: Items Updated: %s" %
                itemsUpdated, 1)
            self.logMsg(
                "Message: WebSocket LibraryChanged: Items Removed: %s" %
                itemsRemoved, 1)

            LibrarySync().remove_items(itemsRemoved)
            LibrarySync().update_items(itemsToUpdate)

        elif messageType == "GeneralCommand":

            command = data['Name']
            arguments = data.get("Arguments")

            if command in ('Mute', 'Unmute', 'SetVolume',
                           'SetSubtitleStreamIndex', 'SetAudioStreamIndex'):
                # These commands need to be reported back
                if command == "Mute":
                    xbmc.executebuiltin('Mute')
                elif command == "Unmute":
                    xbmc.executebuiltin('Mute')
                elif command == "SetVolume":
                    volume = arguments['Volume']
                    xbmc.executebuiltin('SetVolume(%s[,showvolumebar])' %
                                        volume)
                elif command == "SetSubtitleStreamIndex":
                    # Emby merges audio and subtitle index together
                    xbmcplayer = xbmc.Player()
                    currentFile = xbmcplayer.getPlayingFile()
                    embyIndex = int(arguments['Index'])

                    mapping = WINDOW.getProperty("%sIndexMapping" %
                                                 currentFile)
                    externalIndex = json.loads(mapping)

                    if externalIndex:
                        # If there's external subtitles added via PlaybackUtils
                        for index in externalIndex:
                            if externalIndex[index] == embyIndex:
                                xbmcplayer.setSubtitleStream(int(index))
                        else:
                            # User selected internal subtitles
                            external = len(externalIndex)
                            audioTracks = len(
                                xbmcplayer.getAvailableAudioStreams())
                            xbmcplayer.setSubtitleStream(external + embyIndex -
                                                         audioTracks - 1)
                    else:
                        # Emby merges audio and subtitle index together
                        audioTracks = len(
                            xbmcplayer.getAvailableAudioStreams())
                        xbmcplayer.setSubtitleStream(index - audioTracks - 1)

                elif command == "SetAudioStreamIndex":
                    index = int(arguments['Index'])
                    xbmc.Player().setAudioStream(index - 1)
                # Report playback
                WINDOW.setProperty('commandUpdate', "true")

            else:
                # GUI commands
                if command == "ToggleFullscreen":
                    xbmc.executebuiltin('Action(FullScreen)')
                elif command == "ToggleOsdMenu":
                    xbmc.executebuiltin('Action(OSD)')
                elif command == "MoveUp":
                    xbmc.executebuiltin('Action(Up)')
                elif command == "MoveDown":
                    xbmc.executebuiltin('Action(Down)')
                elif command == "MoveLeft":
                    xbmc.executebuiltin('Action(Left)')
                elif command == "MoveRight":
                    xbmc.executebuiltin('Action(Right)')
                elif command == "Select":
                    xbmc.executebuiltin('Action(Select)')
                elif command == "Back":
                    xbmc.executebuiltin('Action(back)')
                elif command == "ToggleContextMenu":
                    xbmc.executebuiltin('Action(ContextMenu)')
                elif command == "GoHome":
                    xbmc.executebuiltin('ActivateWindow(Home)')
                elif command == "PageUp":
                    xbmc.executebuiltin('Action(PageUp)')
                elif command == "NextLetter":
                    xbmc.executebuiltin('Action(NextLetter)')
                elif command == "GoToSearch":
                    xbmc.executebuiltin('VideoLibrary.Search')
                elif command == "GoToSettings":
                    xbmc.executebuiltin('ActivateWindow(Settings)')
                elif command == "PageDown":
                    xbmc.executebuiltin('Action(PageDown)')
                elif command == "PreviousLetter":
                    xbmc.executebuiltin('Action(PrevLetter)')
                elif command == "TakeScreenshot":
                    xbmc.executebuiltin('TakeScreenshot')
                elif command == "ToggleMute":
                    xbmc.executebuiltin('Mute')
                elif command == "VolumeUp":
                    xbmc.executebuiltin('Action(VolumeUp)')
                elif command == "VolumeDown":
                    xbmc.executebuiltin('Action(VolumeDown)')
                elif command == "DisplayMessage":
                    header = arguments['Header']
                    text = arguments['Text']
                    xbmcgui.Dialog().notification(
                        header,
                        text,
                        icon="special://home/addons/plugin.video.emby/icon.png",
                        time=4000)
                elif command == "SendString":
                    string = arguments['String']
                    text = '{"jsonrpc": "2.0", "method": "Input.SendText", "params": { "text": "%s", "done": false }, "id": 0}' % string
                    result = xbmc.executeJSONRPC(text)
                else:
                    self.logMsg("Unknown command.", 1)

        elif messageType == "ServerRestarting":
            if utils.settings('supressRestartMsg') == "true":
                xbmcgui.Dialog().notification(
                    "Emby server",
                    "Server is restarting.",
                    icon="special://home/addons/plugin.video.emby/icon.png")