Esempio n. 1
0
def _record_playstate(status, ended):
    with kodidb.GetKodiDB('video') as kodi_db:
        # Hack - remove any obsolete file entries Kodi made
        kodi_db.clean_file_table()
    if not status['plex_id']:
        LOG.debug('No Plex id found to record playstate for status %s', status)
        return
    with plexdb.Get_Plex_DB() as plex_db:
        kodi_db_item = plex_db.getItem_byId(status['plex_id'])
    if kodi_db_item is None:
        # Item not (yet) in Kodi library
        LOG.debug('No playstate update due to Plex id not found: %s', status)
        return
    totaltime = float(kodi_time_to_millis(status['totaltime'])) / 1000
    if ended:
        progress = 0.99
        time = v.IGNORE_SECONDS_AT_START + 1
    else:
        time = float(kodi_time_to_millis(status['time'])) / 1000
        try:
            progress = time / totaltime
        except ZeroDivisionError:
            progress = 0.0
        LOG.debug('Playback progress %s (%s of %s seconds)', progress, time,
                  totaltime)
    playcount = status['playcount']
    last_played = unix_date_to_kodi(unix_timestamp())
    if playcount is None:
        LOG.info('playcount not found, looking it up in the Kodi DB')
        with kodidb.GetKodiDB('video') as kodi_db:
            playcount = kodi_db.get_playcount(kodi_db_item[1])
        playcount = 0 if playcount is None else playcount
    if time < v.IGNORE_SECONDS_AT_START:
        LOG.debug('Ignoring playback less than %s seconds',
                  v.IGNORE_SECONDS_AT_START)
        # Annoying Plex bug - it'll reset an already watched video to unwatched
        playcount = 0
        last_played = None
        time = 0
    elif progress >= v.MARK_PLAYED_AT:
        LOG.debug('Recording entirely played video since progress > %s',
                  v.MARK_PLAYED_AT)
        playcount += 1
        time = 0
    with kodidb.GetKodiDB('video') as kodi_db:
        kodi_db.addPlaystate(kodi_db_item[1], time, totaltime, playcount,
                             last_played)
    # Hack to force "in progress" widget to appear if it wasn't visible before
    if (state.FORCE_RELOAD_SKIN
            and xbmc.getCondVisibility('Window.IsVisible(Home.xml)')):
        LOG.debug('Refreshing skin to update widgets')
        xbmc.executebuiltin('ReloadSkin()')
Esempio n. 2
0
def conclude_playback(playqueue, pos):
    """
    ONLY if actually being played (e.g. at 5th position of a playqueue).

        Decide on direct play, direct stream, transcoding
        path to
            direct paths: file itself
            PMS URL
            Web URL
        audiostream (e.g. let user choose)
        subtitle stream (e.g. let user choose)
        Init Kodi Playback (depending on situation):
            start playback
            return PKC listitem attached to result
    """
    LOG.info('Concluding playback for playqueue position %s', pos)
    result = Playback_Successful()
    listitem = PKC_ListItem()
    item = playqueue.items[pos]
    if item.xml is not None:
        # Got a Plex element
        api = API(item.xml)
        api.setPartNumber(item.part)
        api.CreateListItemFromPlexItem(listitem)
        playutils = PlayUtils(api, item)
        playurl = playutils.getPlayUrl()
    else:
        playurl = item.file
    listitem.setPath(tryEncode(playurl))
    if item.playmethod in ('DirectStream', 'DirectPlay'):
        listitem.setSubtitles(api.externalSubs())
    else:
        playutils.audio_subtitle_prefs(listitem)
    if state.RESUME_PLAYBACK is True:
        state.RESUME_PLAYBACK = False
        if (item.offset is None and item.plex_type
                not in (v.PLEX_TYPE_SONG, v.PLEX_TYPE_CLIP)):
            with plexdb.Get_Plex_DB() as plex_db:
                plex_dbitem = plex_db.getItem_byId(item.plex_id)
                file_id = plex_dbitem[1] if plex_dbitem else None
            with kodidb.GetKodiDB('video') as kodi_db:
                item.offset = kodi_db.get_resume(file_id)
        LOG.info('Resuming playback at %s', item.offset)
        listitem.setProperty('StartOffset', str(item.offset))
        listitem.setProperty('resumetime', str(item.offset))
    # Reset the resumable flag
    state.RESUMABLE = False
    result.listitem = listitem
    pickle_me(result)
    LOG.info('Done concluding playback')
Esempio n. 3
0
    def stopAll(self):
        if not self.played_info:
            return
        log.info("Played_information: %s" % self.played_info)
        # Process each items
        for item in self.played_info:
            data = self.played_info.get(item)
            if data:
                log.debug("Item path: %s" % item)
                log.debug("Item data: %s" % data)

                runtime = data['runtime']
                currentPosition = data['currentPosition']
                itemid = data['item_id']
                refresh_id = data['refresh_id']
                currentFile = data['currentfile']
                media_type = data['Type']
                playMethod = data['playmethod']

                # Prevent manually mark as watched in Kodi monitor
                window('plex_skipWatched%s' % itemid, value="true")

                if currentPosition and runtime:
                    try:
                        percentComplete = float(currentPosition) / float(
                            runtime)
                    except ZeroDivisionError:
                        # Runtime is 0.
                        percentComplete = 0

                    markPlayed = 0.90
                    log.info("Percent complete: %s Mark played at: %s" %
                             (percentComplete, markPlayed))
                    if percentComplete >= markPlayed:
                        # Tell Kodi that we've finished watching (Plex knows)
                        if (data['fileid'] is not None and data['itemType']
                                in (v.KODI_TYPE_MOVIE, v.KODI_TYPE_EPISODE)):
                            with kodidb.GetKodiDB('video') as kodi_db:
                                kodi_db.addPlaystate(
                                    data['fileid'], None, None,
                                    data['playcount'] + 1,
                                    DateToKodi(getUnixTimestamp()))
                    # Send the delete action to the server.
                    offerDelete = False

                    if media_type == "Episode" and settings(
                            'deleteTV') == "true":
                        offerDelete = True
                    elif media_type == "Movie" and settings(
                            'deleteMovies') == "true":
                        offerDelete = True

                    if settings('offerDelete') != "true":
                        # Delete could be disabled, even if the subsetting is enabled.
                        offerDelete = False

                    # Plex: never delete
                    offerDelete = False
                    if percentComplete >= markPlayed and offerDelete:
                        resp = xbmcgui.Dialog().yesno(lang(30091),
                                                      lang(33015),
                                                      autoclose=120000)
                        if not resp:
                            log.info("User skipped deletion.")
                            continue

                        url = "{server}/emby/Items/%s?format=json" % itemid
                        log.info("Deleting request: %s" % itemid)
                        self.doUtils(url, action_type="DELETE")

        # Clean the WINDOW properties
        for filename in self.played_info:
            plex_item = 'plex_%s' % tryEncode(filename)
            cleanup = (
                '%s.itemid' % plex_item,
                '%s.runtime' % plex_item,
                '%s.refreshid' % plex_item,
                '%s.playmethod' % plex_item,
                '%s.type' % plex_item,
                '%s.runtime' % plex_item,
                '%s.playcount' % plex_item,
                '%s.playlistPosition' % plex_item,
                '%s.subtitle' % plex_item,
            )
            for item in cleanup:
                window(item, clear=True)

        # Stop transcoding
        if playMethod == "Transcode":
            log.info("Transcoding for %s terminating" % itemid)
            self.doUtils("{server}/video/:/transcode/universal/stop",
                         parameters={'session': window('plex_client_Id')})

        self.played_info.clear()
Esempio n. 4
0
    def stopAll(self):
        if not self.played_info:
            return
        log.info("Played_information: %s" % self.played_info)
        # Process each items
        for item in self.played_info:
            data = self.played_info.get(item)
            if not data:
                continue
            log.debug("Item path: %s" % item)
            log.debug("Item data: %s" % data)

            runtime = data['runtime']
            currentPosition = data['currentPosition']
            itemid = data['item_id']
            refresh_id = data['refresh_id']
            currentFile = data['currentfile']
            media_type = data['Type']
            playMethod = data['playmethod']

            # Prevent manually mark as watched in Kodi monitor
            window('plex_skipWatched%s' % itemid, value="true")

            if not currentPosition or not runtime:
                continue
            try:
                percentComplete = float(currentPosition) / float(runtime)
            except ZeroDivisionError:
                # Runtime is 0.
                percentComplete = 0

            markPlayed = 0.90
            log.info("Percent complete: %s Mark played at: %s" %
                     (percentComplete, markPlayed))
            if percentComplete >= markPlayed:
                # Tell Kodi that we've finished watching (Plex knows)
                if (data['fileid'] is not None and data['itemType']
                        in (v.KODI_TYPE_MOVIE, v.KODI_TYPE_EPISODE)):
                    with kodidb.GetKodiDB('video') as kodi_db:
                        kodi_db.addPlaystate(data['fileid'], None, None,
                                             data['playcount'] + 1,
                                             DateToKodi(getUnixTimestamp()))

        # Clean the WINDOW properties
        for filename in self.played_info:
            plex_item = 'plex_%s' % tryEncode(filename)
            cleanup = (
                '%s.itemid' % plex_item,
                '%s.runtime' % plex_item,
                '%s.refreshid' % plex_item,
                '%s.playmethod' % plex_item,
                '%s.type' % plex_item,
                '%s.runtime' % plex_item,
                '%s.playcount' % plex_item,
                '%s.playlistPosition' % plex_item,
                '%s.subtitle' % plex_item,
            )
            for item in cleanup:
                window(item, clear=True)

        # Stop transcoding
        if playMethod == "Transcode":
            log.info("Transcoding for %s terminating" % itemid)
            self.doUtils("{server}/video/:/transcode/universal/stop",
                         parameters={'session': window('plex_client_Id')})

        self.played_info.clear()
Esempio n. 5
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)
Esempio n. 6
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')