def _get_item_id(cls, kodi_id, item_type):
     item_id = xbmc.getInfoLabel('ListItem.Property(plexid)')
     if not item_id and kodi_id and item_type:
         with embydb.GetEmbyDB() as emby_db:
             item = emby_db.getItem_byKodiId(kodi_id, item_type)
         try:
             item_id = item[0]
         except TypeError:
             log.error('Could not get the Plex id for context menu')
     return item_id
Example #2
0
 def skipTo(self, plexId, typus):
     # playlistId = self.getPlaylistId(tryDecode(xbmc_type(typus)))
     # playerId = self.
     with embydb.GetEmbyDB() as emby_db:
         embydb_item = emby_db.getItem_byId(plexId)
         try:
             dbid = embydb_item[0]
             mediatype = embydb_item[4]
         except TypeError:
             log.info('Couldnt find item %s in Kodi db' % plexId)
             return
     log.debug('plexid: %s, kodi id: %s, type: %s' %
               (plexId, dbid, mediatype))
Example #3
0
    def playAll(self, itemids, startat):
        log = self.logMsg
        window = utils.window

        embyconn = utils.kodiSQL('emby')
        embycursor = embyconn.cursor()
        emby_db = embydb.Embydb_Functions(embycursor)

        player = xbmc.Player()
        playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
        playlist.clear()

        log("---*** PLAY ALL ***---", 1)
        log("Items: %s and start at: %s" % (itemids, startat), 1)

        started = False
        window('emby_customplaylist', value="true")

        if startat != 0:
            # Seek to the starting position
            window('emby_customplaylist.seektime', str(startat))

        with embydb.GetEmbyDB() as emby_db:
            for itemid in itemids:
                embydb_item = emby_db.getItem_byId(itemid)
                try:
                    dbid = embydb_item[0]
                    mediatype = embydb_item[4]
                except TypeError:
                    # Item is not found in our database, add item manually
                    log(
                        "Item was not found in the database, manually adding item.",
                        1)
                    item = PlexFunctions.GetPlexMetadata(itemid)
                    if item is None or item == 401:
                        log('Could not download itemid %s' % itemid, -1)
                    else:
                        self.addtoPlaylist_xbmc(playlist, item)
                else:
                    # Add to playlist
                    self.addtoPlaylist(dbid, mediatype)

                log("Adding %s to playlist." % itemid, 1)

                if not started:
                    started = True
                    player.play(playlist)

        self.verifyPlaylist()
Example #4
0
 def _initiatePlaylist(self):
     log.info('Initiating playlist')
     playlist = None
     with embydb.GetEmbyDB() as emby_db:
         for item in self.items:
             itemid = item['plexId']
             embydb_item = emby_db.getItem_byId(itemid)
             try:
                 mediatype = embydb_item[4]
             except TypeError:
                 log.info('Couldnt find item %s in Kodi db' % itemid)
                 item = PlexFunctions.GetPlexMetadata(itemid)
                 if item in (None, 401):
                     log.info('Couldnt find item %s on PMS, trying next' %
                              itemid)
                     continue
                 if PlexAPI.API(item[0]).getType() == 'track':
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
                     log.info('Music playlist initiated')
                     self.typus = 'music'
                 else:
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
                     log.info('Video playlist initiated')
                     self.typus = 'video'
             else:
                 if mediatype == 'song':
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
                     log.info('Music playlist initiated')
                     self.typus = 'music'
                 else:
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
                     log.info('Video playlist initiated')
                     self.typus = 'video'
             break
     self.playlist = playlist
     if self.playlist is not None:
         self.playlistId = self.playlist.getPlayListId()
Example #5
0
    def _processItems(self, startitem, startPlayer=False):
        startpos = None
        with embydb.GetEmbyDB() as emby_db:
            for pos, item in enumerate(self.items):
                kodiId = None
                plexId = item['plexId']
                embydb_item = emby_db.getItem_byId(plexId)
                try:
                    kodiId = embydb_item[0]
                    mediatype = embydb_item[4]
                except TypeError:
                    log.info('Couldnt find item %s in Kodi db' % plexId)
                    xml = PlexFunctions.GetPlexMetadata(plexId)
                    if xml in (None, 401):
                        log.error('Could not download plexId %s' % plexId)
                    else:
                        log.debug('Downloaded xml metadata, adding now')
                        self._addtoPlaylist_xbmc(xml[0])
                else:
                    # Add to playlist
                    log.debug("Adding %s PlexId %s, KodiId %s to playlist." %
                              (mediatype, plexId, kodiId))
                    self._addtoPlaylist(kodiId, mediatype)
                # Add the kodiId
                if kodiId is not None:
                    item['kodiId'] = str(kodiId)
                if (startpos is None and startitem[1] == item[startitem[0]]):
                    startpos = pos

        if startPlayer is True and len(self.playlist) > 0:
            if startpos is not None:
                self.player.play(self.playlist, startpos=startpos)
            else:
                log.info('Never received a starting item for playlist, '
                         'starting with the first entry')
                self.player.play(self.playlist)
Example #6
0
    plexid = ""
    if not itemtype and xbmc.getCondVisibility("Container.Content(albums)"):
        itemtype = "album"
    if not itemtype and xbmc.getCondVisibility("Container.Content(artists)"):
        itemtype = "artist"
    if not itemtype and xbmc.getCondVisibility("Container.Content(songs)"):
        itemtype = "song"
    if not itemtype and xbmc.getCondVisibility("Container.Content(pictures)"):
        itemtype = "picture"

    if (not itemid or itemid
            == "-1") and xbmc.getInfoLabel("ListItem.Property(plexid)"):
        plexid = xbmc.getInfoLabel("ListItem.Property(plexid)")
    else:
        with embydb.GetEmbyDB() as emby_db:
            item = emby_db.getItem_byKodiId(itemid, itemtype)
        if item:
            plexid = item[0]

    logMsg("Contextmenu opened for plexid: %s  - itemtype: %s" %
           (plexid, itemtype))

    if plexid:
        item = PF.GetPlexMetadata(plexid)
        if item is None or item == 401:
            logMsg('Could not get item metadata for item %s' % plexid, -1)
            return
        API = PlexAPI.API(item[0])
        userdata = API.getUserData()
        likes = userdata['Likes']
Example #7
0
    def onPlayBackStarted(self):
        """
        Will be called when xbmc starts playing a file.
        Window values need to have been set in Kodimonitor.py
        """
        self.stopAll()

        # Get current file (in utf-8!)
        try:
            currentFile = self.getPlayingFile()
            xbmc.sleep(300)
        except:
            currentFile = ""
            count = 0
            while not currentFile:
                xbmc.sleep(100)
                try:
                    currentFile = self.getPlayingFile()
                except:
                    pass
                if count == 20:
                    break
                else:
                    count += 1
        if not currentFile:
            log.warn('Error getting currently playing file; abort reporting')
            return

        # Save currentFile for cleanup later and for references
        self.currentFile = currentFile
        window('plex_lastPlayedFiled', value=currentFile)
        # We may need to wait for info to be set in kodi monitor
        itemId = window("emby_%s.itemid" % currentFile)
        count = 0
        while not itemId:
            xbmc.sleep(200)
            itemId = window("emby_%s.itemid" % currentFile)
            if count == 5:
                log.warn("Could not find itemId, cancelling playback report!")
                return
            count += 1

        log.info("ONPLAYBACK_STARTED: %s itemid: %s" % (currentFile, itemId))

        embyitem = "emby_%s" % currentFile
        runtime = window("%s.runtime" % embyitem)
        refresh_id = window("%s.refreshid" % embyitem)
        playMethod = window("%s.playmethod" % embyitem)
        itemType = window("%s.type" % embyitem)
        try:
            playcount = int(window("%s.playcount" % embyitem))
        except ValueError:
            playcount = 0
        window('emby_skipWatched%s' % itemId, value="true")

        log.debug("Playing itemtype is: %s" % itemType)

        customseek = window('plex_customplaylist.seektime')
        if customseek:
            # Start at, when using custom playlist (play to Kodi from
            # webclient)
            log.info("Seeking to: %s" % customseek)
            try:
                self.seekTime(int(customseek))
            except:
                log.error('Could not seek!')
            window('plex_customplaylist.seektime', clear=True)

        try:
            seekTime = self.getTime()
        except RuntimeError:
            log.error('Could not get current seektime from xbmc player')
            seekTime = 0

        # Get playback volume
        volume_query = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "Application.GetProperties",
            "params": {
                "properties": ["volume", "muted"]
            }
        }
        result = xbmc.executeJSONRPC(json.dumps(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}/:/timeline?"
        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'] = window("%sAudioStreamIndex" %
                                                  currentFile)
            postdata['SubtitleStreamIndex'] = window("%sSubtitleStreamIndex" %
                                                     currentFile)
        else:
            # Get the current kodi audio and subtitles and convert to Emby equivalent
            tracks_query = {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "Player.GetProperties",
                "params": {
                    "playerid":
                    1,
                    "properties": [
                        "currentsubtitle", "currentaudiostream",
                        "subtitleenabled"
                    ]
                }
            }
            result = xbmc.executeJSONRPC(json.dumps(tracks_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 = window("%s.indexMapping" % embyitem)

                if mapping:  # Set in playbackutils.py

                    log.debug("Mapping for external subtitles index: %s" %
                              mapping)
                    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
                        subindex = indexSubs - len(
                            externalIndex) + audioTracks + 1
                        postdata['SubtitleStreamIndex'] = subindex

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

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

        # Ensure we do have a runtime
        try:
            runtime = int(runtime)
        except ValueError:
            try:
                runtime = self.getTotalTime()
                log.error("Runtime is missing, Kodi runtime: %s" % runtime)
            except:
                log.error('Could not get kodi runtime, setting to zero')
                runtime = 0

        with embydb.GetEmbyDB() as emby_db:
            emby_dbitem = emby_db.getItem_byId(itemId)
        try:
            fileid = emby_dbitem[1]
        except TypeError:
            log.info("Could not find fileid in plex db.")
            fileid = None
        # 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),
            'fileid': fileid,
            'itemType': itemType,
            'playcount': playcount
        }

        self.played_info[currentFile] = data
        log.info("ADDING_FILE: %s" % data)

        # log some playback stats
        '''if(itemType != None):
Example #8
0
    def onNotification(self, sender, method, data):
        if method not in ("Playlist.OnAdd"):
            self.logMsg("Method: %s Data: %s" % (method, data), 1)

        if data:
            data = json.loads(data, 'utf-8')

        if method == "Player.OnPlay":
            self.PlayBackStart(data)

        elif method == "Player.OnStop":
            # Should refresh our video nodes, e.g. on deck
            # xbmc.executebuiltin('ReloadSkin()')
            pass

        elif method == "VideoLibrary.OnUpdate":
            # Manually marking as watched/unwatched
            playcount = data.get('playcount')
            item = data.get('item')
            try:
                kodiid = item['id']
                item_type = item['type']
            except (KeyError, TypeError):
                self.logMsg("Item is invalid for playstate update.", 1)
            else:
                # Send notification to the server.
                with embydb.GetEmbyDB() as emby_db:
                    emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type)
                try:
                    itemid = emby_dbitem[0]
                except TypeError:
                    self.logMsg("Could not find itemid in emby database.", 1)
                else:
                    # Stop from manually marking as watched unwatched, with actual playback.
                    if utils.window('emby_skipWatched%s' % itemid) == "true":
                        # property is set in player.py
                        utils.window('emby_skipWatched%s' % itemid, clear=True)
                    else:
                        # notify the server
                        if playcount != 0:
                            scrobble(itemid, 'watched')
                        else:
                            scrobble(itemid, 'unwatched')

        elif method == "VideoLibrary.OnRemove":
            # Removed function, because with plugin paths + clean library, it will wipe
            # entire library if user has permissions. Instead, use the emby context menu available
            # in Isengard and higher version
            pass
            '''try:
                kodiid = data['id']
                type = data['type']
            except (KeyError, TypeError):
                self.logMsg("Item is invalid for emby deletion.", 1)
            else:
                # Send the delete action to the server.
                embyconn = utils.kodiSQL('emby')
                embycursor = embyconn.cursor()
                emby_db = embydb.Embydb_Functions(embycursor)
                emby_dbitem = emby_db.getItem_byKodiId(kodiid, type)
                try:
                    itemid = emby_dbitem[0]
                except TypeError:
                    self.logMsg("Could not find itemid in emby database.", 1)
                else:
                    if utils.settings('skipContextMenu') != "true":
                        resp = xbmcgui.Dialog().yesno(
                                                heading="Confirm delete",
                                                line1="Delete file on Emby Server?")
                        if not resp:
                            self.logMsg("User skipped deletion.", 1)
                            embycursor.close()
                            return

                    url = "{server}/emby/Items/%s?format=json" % itemid
                    self.logMsg("Deleting request: %s" % itemid)
                    doUtils.downloadUrl(url, action_type="DELETE")
                finally:
                    embycursor.close()'''

        elif method == "System.OnWake":
            # Allow network to wake up
            xbmc.sleep(10000)
            utils.window('plex_onWake', value="true")

        elif method == "GUI.OnScreensaverDeactivated":
            if utils.settings('dbSyncScreensaver') == "true":
                xbmc.sleep(5000)
                utils.window('plex_runLibScan', value="full")

        elif method == "Playlist.OnClear":
            pass
Example #9
0
    def PlayBackStart(self, data):
        """
        Called whenever a playback is started
        """
        log = self.logMsg
        window = utils.window

        # Get currently playing file - can take a while. Will be utf-8!
        try:
            currentFile = self.xbmcplayer.getPlayingFile()
        except:
            currentFile = None
            count = 0
            while currentFile is None:
                xbmc.sleep(100)
                try:
                    currentFile = self.xbmcplayer.getPlayingFile()
                except:
                    pass
                if count == 50:
                    log("No current File - Cancelling OnPlayBackStart...", -1)
                    return
                else:
                    count += 1
        log("Currently playing file is: %s" % utils.tryDecode(currentFile), 1)

        # Try to get a Kodi ID
        item = data.get('item')
        try:
            type = item['type']
        except:
            log("Item is invalid for PMS playstate update.", 0)
            return
        try:
            kodiid = item['id']
        except (KeyError, TypeError):
            itemType = window("emby_%s.type" % currentFile)
            log("No kodi id passed. Playing itemtype is: %s" % itemType, 1)
            if itemType in ('movie', 'episode'):
                # Window was setup by PKC and is NOT a trailer ('clip')
                with kodidb.GetKodiDB('video') as kodi_db:
                    kodiid = kodi_db.getIdFromTitle(data.get('item'))
                    if kodiid is None:
                        log(
                            "Skip playstate update. No unique Kodi title found"
                            " for %s" % data.get('item'), 0)
                        return
            else:
                log("Item is invalid for PMS playstate update.", 0)
                return

        # Get Plex' item id
        with embydb.GetEmbyDB() as emby_db:
            emby_dbitem = emby_db.getItem_byKodiId(kodiid, type)
        try:
            plexid = emby_dbitem[0]
        except TypeError:
            log("No Plex id returned for kodiid %s" % kodiid, 0)
            return
        log("Found Plex id %s for Kodi id %s" % (plexid, kodiid), 1)

        # Set some stuff if Kodi initiated playback
        if ((utils.settings('useDirectPaths') == "1" and not type == "song") or
            (type == "song" and utils.settings('enableMusic') == "true")):
            if self.StartDirectPath(plexid, type, currentFile) is False:
                log('Could not initiate monitoring; aborting', -1)
                return

        # Save currentFile for cleanup later and to be able to access refs
        window('plex_lastPlayedFiled', value=utils.tryDecode(currentFile))
        window('Plex_currently_playing_itemid', value=plexid)
        window("emby_%s.itemid" % currentFile, value=plexid)
        log('Finish playback startup', 1)
Example #10
0
    def PlayBackStart(self, data):
        """
        Called whenever a playback is started
        """
        # Get currently playing file - can take a while. Will be utf-8!
        try:
            currentFile = self.xbmcplayer.getPlayingFile()
        except:
            currentFile = None
            count = 0
            while currentFile is None:
                xbmc.sleep(100)
                try:
                    currentFile = self.xbmcplayer.getPlayingFile()
                except:
                    pass
                if count == 50:
                    log.info("No current File, cancel OnPlayBackStart...")
                    return
                else:
                    count += 1
        # Just to be on the safe side
        currentFile = tryDecode(currentFile)
        log.debug("Currently playing file is: %s" % currentFile)

        # Get the type of media we're playing
        try:
            typus = data['item']['type']
        except (TypeError, KeyError):
            log.info("Item is invalid for PMS playstate update.")
            return
        log.debug("Playing itemtype is (or appears to be): %s" % typus)

        # Try to get a Kodi ID
        # If PKC was used - native paths, not direct paths
        plexid = window('emby_%s.itemid' % tryEncode(currentFile))
        # Get rid of the '' if the window property was not set
        plexid = None if not plexid else plexid
        kodiid = None
        if plexid is None:
            log.debug('Did not get Plex id from window properties')
            try:
                kodiid = data['item']['id']
            except (TypeError, KeyError):
                log.debug('Did not get a Kodi id from Kodi, darn')
        # For direct paths, if we're not streaming something
        # When using Widgets, Kodi doesn't tell us shit so we need this hack
        if (kodiid is None and plexid is None and typus != 'song'
                and not currentFile.startswith('http')):
            try:
                filename = currentFile.rsplit('/', 1)[1]
                path = currentFile.rsplit('/', 1)[0] + '/'
            except IndexError:
                filename = currentFile.rsplit('\\', 1)[1]
                path = currentFile.rsplit('\\', 1)[0] + '\\'
            log.debug('Trying to figure out playing item from filename: %s '
                      'and path: %s' % (filename, path))
            with kodidb.GetKodiDB('video') as kodi_db:
                try:
                    kodiid, typus = kodi_db.getIdFromFilename(filename, path)
                except TypeError:
                    log.info('Abort playback report, could not id kodi item')
                    return

        if plexid is None:
            # Get Plex' item id
            with embydb.GetEmbyDB() as emby_db:
                emby_dbitem = emby_db.getItem_byKodiId(kodiid, typus)
            try:
                plexid = emby_dbitem[0]
            except TypeError:
                log.info("No Plex id returned for kodiid %s. Aborting playback"
                         " report" % kodiid)
                return
        log.debug("Found Plex id %s for Kodi id %s for type %s" %
                  (plexid, kodiid, typus))

        # Set some stuff if Kodi initiated playback
        if ((settings('useDirectPaths') == "1" and not typus == "song")
                or (typus == "song" and settings('enableMusic') == "true")):
            if self.StartDirectPath(plexid, typus,
                                    tryEncode(currentFile)) is False:
                log.error('Could not initiate monitoring; aborting')
                return

        # Save currentFile for cleanup later and to be able to access refs
        window('plex_lastPlayedFiled', value=currentFile)
        window('plex_currently_playing_itemid', value=plexid)
        window("emby_%s.itemid" % tryEncode(currentFile), value=plexid)
        log.info('Finish playback startup')