Exemple #1
0
    def onPlayBackStarted(self):
        xbmc.sleep(1000)
        self.type = None
        self.id = None

        # take the user start scrobble offset into account
        scrobbleStartOffset = utilities.getSettingAsInt(
            'scrobble_start_offset') * 60
        if scrobbleStartOffset > 0:
            waitFor = 10
            waitedFor = 0
            # check each 10 seconds if we can abort or proceed
            while not xbmc.abortRequested and scrobbleStartOffset > waitedFor:
                waitedFor += waitFor
                time.sleep(waitFor)
                if not self.isPlayingVideo():
                    logger.debug(
                        '[traktPlayer] Playback stopped before reaching the scrobble offset'
                    )
                    return

        # only do anything if we're playing a video
        if self.isPlayingVideo():
            # get item data from json rpc
            result = utilities.kodiJsonRequest({
                'jsonrpc': '2.0',
                'method': 'Player.GetItem',
                'params': {
                    'playerid': 1
                },
                'id': 1
            })
            if result:
                logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)
                # check for exclusion
                _filename = None
                try:
                    _filename = self.getPlayingFile()
                except:
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Exception trying to get playing filename, player suddenly stopped."
                    )
                    return

                if utilities.checkExclusion(_filename):
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - '%s' is in exclusion settings, ignoring."
                        % _filename)
                    return

                self.type = result['item']['type']

                data = {'action': 'started'}

                # check type of item
                if 'id' not in result['item']:
                    # do a deeper check to see if we have enough data to perform scrobbles
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Started playing a non-library file, checking available data."
                    )

                    season = xbmc.getInfoLabel('VideoPlayer.Season')
                    episode = xbmc.getInfoLabel('VideoPlayer.Episode')
                    showtitle = xbmc.getInfoLabel('VideoPlayer.TVShowTitle')
                    year = xbmc.getInfoLabel('VideoPlayer.Year')
                    video_ids = xbmcgui.Window(10000).getProperty(
                        'script.trakt.ids')
                    if video_ids:
                        data['video_ids'] = json.loads(video_ids)

                    logger.debug(
                        "[traktPlayer] info - ids: %s, showtitle: %s, Year: %s, Season: %s, Episode: %s"
                        % (video_ids, showtitle, year, season, episode))

                    if season and episode and (showtitle or video_ids):
                        # we have season, episode and either a show title or video_ids, can scrobble this as an episode
                        self.type = 'episode'
                        data['type'] = 'episode'
                        data['season'] = int(season)
                        data['episode'] = int(episode)
                        data['showtitle'] = showtitle
                        data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                        if year.isdigit():
                            data['year'] = int(year)
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' - %s - S%02dE%02d - %s."
                            % (data['showtitle'], data['season'],
                               data['episode'], data['title']))
                    elif (year or video_ids) and not season and not showtitle:
                        # we have a year or video_id and no season/showtitle info, enough for a movie
                        self.type = 'movie'
                        data['type'] = 'movie'
                        if year.isdigit():
                            data['year'] = int(year)
                        data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Playing a non-library 'movie' - %s (%s)."
                            % (data['title'], data.get('year', 'NaN')))
                    elif showtitle:
                        title, season, episode = utilities.regex_tvshow(
                            False, showtitle)
                        data['type'] = 'episode'
                        data['season'] = int(season)
                        data['episode'] = int(episode)
                        data['showtitle'] = title
                        data['title'] = title
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Title: %s, showtitle: %s, season: %d, episode: %d"
                            % (title, showtitle, season, episode))
                    else:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Non-library file, not enough data for scrobbling, skipping."
                        )
                        return

                elif self.type == 'episode' or self.type == 'movie':
                    # get library id
                    self.id = result['item']['id']
                    data['id'] = self.id
                    data['type'] = self.type

                    if self.type == 'episode':
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Doing multi-part episode check."
                        )
                        result = utilities.kodiJsonRequest({
                            'jsonrpc': '2.0',
                            'method': 'VideoLibrary.GetEpisodeDetails',
                            'params': {
                                'episodeid':
                                self.id,
                                'properties':
                                ['tvshowid', 'season', 'episode', 'file']
                            },
                            'id': 1
                        })
                        if result:
                            logger.debug(
                                "[traktPlayer] onPlayBackStarted() - %s" %
                                result)
                            tvshowid = int(
                                result['episodedetails']['tvshowid'])
                            season = int(result['episodedetails']['season'])
                            currentfile = result['episodedetails']['file']

                            result = utilities.kodiJsonRequest({
                                'jsonrpc': '2.0',
                                'method': 'VideoLibrary.GetEpisodes',
                                'params': {
                                    'tvshowid': tvshowid,
                                    'season': season,
                                    'properties': ['episode', 'file'],
                                    'sort': {
                                        'method': 'episode'
                                    }
                                },
                                'id': 1
                            })
                            if result:
                                logger.debug(
                                    "[traktPlayer] onPlayBackStarted() - %s" %
                                    result)
                                # make sure episodes array exists in results
                                if 'episodes' in result:
                                    multi = []
                                    for i in range(result['limits']['start'],
                                                   result['limits']['total']):
                                        if currentfile == result['episodes'][
                                                i]['file']:
                                            multi.append(result['episodes'][i]
                                                         ['episodeid'])
                                    if len(multi) > 1:
                                        data['multi_episode_data'] = multi
                                        data['multi_episode_count'] = len(
                                            multi)
                                        logger.debug(
                                            "[traktPlayer] onPlayBackStarted() - This episode is part of a multi-part episode."
                                        )
                                    else:
                                        logger.debug(
                                            "[traktPlayer] onPlayBackStarted() - This is a single episode."
                                        )

                else:
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Video type '%s' unrecognized, skipping."
                        % self.type)
                    return

                pl = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
                plSize = len(pl)
                if plSize > 1:
                    pos = pl.getposition()
                    if not self.plIndex is None:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - User manually skipped to next (or previous) video, forcing playback ended event."
                        )
                        self.onPlayBackEnded()
                    self.plIndex = pos
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Playlist contains %d item(s), and is currently on item %d"
                        % (plSize, (pos + 1)))

                self._playing = True

                # send dispatch
                self.action(data)
def test_regex_tvshow_title_4():
    assert utilities.regex_tvshow('ShowTitle.Season 01 - Episode 02')[0] == 'ShowTitle'
Exemple #3
0
def test_regex_tvshow_title_6():
    assert utilities.regex_tvshow('ShowTitle - s01ep03')[0] == 'ShowTitle'
Exemple #4
0
    def onPlayBackStarted(self):
        xbmc.sleep(1000)
        self.type = None
        self.id = None

        # take the user start scrobble offset into account
        scrobbleStartOffset = kodiUtilities.getSettingAsInt(
            'scrobble_start_offset') * 60
        if scrobbleStartOffset > 0:
            waitFor = 10
            waitedFor = 0
            # check each 10 seconds if we can abort or proceed
            while not xbmc.abortRequested and scrobbleStartOffset > waitedFor:
                waitedFor += waitFor
                time.sleep(waitFor)
                if not self.isPlayingVideo():
                    logger.debug(
                        '[traktPlayer] Playback stopped before reaching the scrobble offset'
                    )
                    return

        # only do anything if we're playing a video
        if self.isPlayingVideo():
            # get item data from json rpc
            logger.debug(
                "[traktPlayer] onPlayBackStarted() - Doing Player.GetItem kodiJsonRequest"
            )
            result = kodiUtilities.kodiJsonRequest({
                'jsonrpc': '2.0',
                'method': 'Player.GetItem',
                'params': {
                    'playerid': 1
                },
                'id': 1
            })
            if result:
                logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)
                # check for exclusion
                _filename = None
                try:
                    _filename = self.getPlayingFile()
                except:
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Exception trying to get playing filename, player suddenly stopped."
                    )
                    return

                if kodiUtilities.checkExclusion(_filename):
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - '%s' is in exclusion settings, ignoring."
                        % _filename)
                    return

                self.type = result['item']['type']

                data = {'action': 'started'}

                if (kodiUtilities.getSettingAsBool('scrobble_mythtv_pvr')):
                    logger.debug(
                        '[traktPlayer] Setting is enabled to try scrobbling mythtv pvr recording, if necessary.'
                    )

                # check type of item
                if 'id' not in result['item']:
                    # do a deeper check to see if we have enough data to perform scrobbles
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Started playing a non-library file, checking available data."
                    )

                    season = xbmc.getInfoLabel('VideoPlayer.Season')
                    episode = xbmc.getInfoLabel('VideoPlayer.Episode')
                    showtitle = xbmc.getInfoLabel('VideoPlayer.TVShowTitle')
                    year = xbmc.getInfoLabel('VideoPlayer.Year')
                    video_ids = xbmcgui.Window(10000).getProperty(
                        'script.trakt.ids')
                    if video_ids:
                        data['video_ids'] = json.loads(video_ids)

                    logger.debug(
                        "[traktPlayer] info - ids: %s, showtitle: %s, Year: %s, Season: %s, Episode: %s"
                        % (video_ids, showtitle, year, season, episode))

                    if season and episode and (showtitle or video_ids):
                        # we have season, episode and either a show title or video_ids, can scrobble this as an episode
                        self.type = 'episode'
                        data['type'] = 'episode'
                        data['season'] = int(season)
                        data['episode'] = int(episode)
                        data['showtitle'] = showtitle
                        data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                        if year.isdigit():
                            data['year'] = int(year)
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' - %s - S%02dE%02d - %s."
                            % (data['showtitle'], data['season'],
                               data['episode'], data['title']))
                    elif (year or video_ids) and not season and not showtitle:
                        # we have a year or video_id and no season/showtitle info, enough for a movie
                        self.type = 'movie'
                        data['type'] = 'movie'
                        if year.isdigit():
                            data['year'] = int(year)
                        data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Playing a non-library 'movie' - %s (%s)."
                            % (data['title'], data.get('year', 'NaN')))
                    elif showtitle:
                        title, season, episode = utilities.regex_tvshow(
                            showtitle)
                        data['type'] = 'episode'
                        data['season'] = season
                        data['episode'] = episode
                        data['title'] = data['showtitle'] = title
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Title: %s, showtitle: %s, season: %d, episode: %d"
                            % (title, showtitle, season, episode))
                    else:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Non-library file, not enough data for scrobbling, skipping."
                        )
                        return

                elif self.type == 'episode' or self.type == 'movie':
                    # get library id
                    self.id = result['item']['id']
                    data['id'] = self.id
                    data['type'] = self.type

                    if self.type == 'episode':
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Doing multi-part episode check."
                        )
                        result = kodiUtilities.kodiJsonRequest({
                            'jsonrpc': '2.0',
                            'method': 'VideoLibrary.GetEpisodeDetails',
                            'params': {
                                'episodeid':
                                self.id,
                                'properties':
                                ['tvshowid', 'season', 'episode', 'file']
                            },
                            'id': 1
                        })
                        if result:
                            logger.debug(
                                "[traktPlayer] onPlayBackStarted() - %s" %
                                result)
                            tvshowid = int(
                                result['episodedetails']['tvshowid'])
                            season = int(result['episodedetails']['season'])
                            currentfile = result['episodedetails']['file']

                            result = kodiUtilities.kodiJsonRequest({
                                'jsonrpc': '2.0',
                                'method': 'VideoLibrary.GetEpisodes',
                                'params': {
                                    'tvshowid': tvshowid,
                                    'season': season,
                                    'properties': ['episode', 'file'],
                                    'sort': {
                                        'method': 'episode'
                                    }
                                },
                                'id': 1
                            })
                            if result:
                                logger.debug(
                                    "[traktPlayer] onPlayBackStarted() - %s" %
                                    result)
                                # make sure episodes array exists in results
                                if 'episodes' in result:
                                    multi = []
                                    for i in range(result['limits']['start'],
                                                   result['limits']['total']):
                                        if currentfile == result['episodes'][
                                                i]['file']:
                                            multi.append(result['episodes'][i]
                                                         ['episodeid'])
                                    if len(multi) > 1:
                                        data['multi_episode_data'] = multi
                                        data['multi_episode_count'] = len(
                                            multi)
                                        logger.debug(
                                            "[traktPlayer] onPlayBackStarted() - This episode is part of a multi-part episode."
                                        )
                                    else:
                                        logger.debug(
                                            "[traktPlayer] onPlayBackStarted() - This is a single episode."
                                        )
                elif (kodiUtilities.getSettingAsBool('scrobble_mythtv_pvr')
                      and self.type == 'unknown' and result['item']['label']):
                    # If we have label/id but no show type, then this might be a PVR recording.

                    # DEBUG INFO: This code is useful when trying to figure out what info is available. Many of the fields
                    # that you'd expect (TVShowTitle, episode, season, etc) are always blank. In Kodi v15, we got the show
                    # and episode name in the VideoPlayer label. In v16, that's gone, but the Player.Filename infolabel
                    # is populated with several interesting things. If these things change in future versions, uncommenting
                    # this code will hopefully provide some useful info in the debug log.
                    #logger.debug("[traktPlayer] onPlayBackStarted() - TEMP Checking all videoplayer infolabels.")
                    #for il in ['VideoPlayer.Time','VideoPlayer.TimeRemaining','VideoPlayer.TimeSpeed','VideoPlayer.Duration','VideoPlayer.Title','VideoPlayer.TVShowTitle','VideoPlayer.Season','VideoPlayer.Episode','VideoPlayer.Genre','VideoPlayer.Director','VideoPlayer.Country','VideoPlayer.Year','VideoPlayer.Rating','VideoPlayer.UserRating','VideoPlayer.Votes','VideoPlayer.RatingAndVotes','VideoPlayer.mpaa','VideoPlayer.IMDBNumber','VideoPlayer.EpisodeName','VideoPlayer.PlaylistPosition','VideoPlayer.PlaylistLength','VideoPlayer.Cast','VideoPlayer.CastAndRole','VideoPlayer.Album','VideoPlayer.Artist','VideoPlayer.Studio','VideoPlayer.Writer','VideoPlayer.Tagline','VideoPlayer.PlotOutline','VideoPlayer.Plot','VideoPlayer.LastPlayed','VideoPlayer.PlayCount','VideoPlayer.VideoCodec','VideoPlayer.VideoResolution','VideoPlayer.VideoAspect','VideoPlayer.AudioCodec','VideoPlayer.AudioChannels','VideoPlayer.AudioLanguage','VideoPlayer.SubtitlesLanguage','VideoPlayer.StereoscopicMode','VideoPlayer.EndTime','VideoPlayer.NextTitle','VideoPlayer.NextGenre','VideoPlayer.NextPlot','VideoPlayer.NextPlotOutline','VideoPlayer.NextStartTime','VideoPlayer.NextEndTime','VideoPlayer.NextDuration','VideoPlayer.ChannelName','VideoPlayer.ChannelNumber','VideoPlayer.SubChannelNumber','VideoPlayer.ChannelNumberLabel','VideoPlayer.ChannelGroup','VideoPlayer.ParentalRating','Player.FinishTime','Player.FinishTime(format)','Player.Chapter','Player.ChapterCount','Player.Time','Player.Time(format)','Player.TimeRemaining','Player.TimeRemaining(format)','Player.Duration','Player.Duration(format)','Player.SeekTime','Player.SeekOffset','Player.SeekOffset(format)','Player.SeekStepSize','Player.ProgressCache','Player.Folderpath','Player.Filenameandpath','Player.StartTime','Player.StartTime(format)','Player.Title','Player.Filename']:
                    #    logger.debug("[traktPlayer] TEMP %s : %s" % (il, xbmc.getInfoLabel(il)))
                    #for k,v in result.iteritems():
                    #    logger.debug("[traktPlayer] onPlayBackStarted() - result - %s : %s" % (k,v))
                    #for k,v in result['item'].iteritems():
                    #    logger.debug("[traktPlayer] onPlayBackStarted() - result.item - %s : %s" % (k,v))

                    # As of Kodi v16 with the MythTV PVR addon, the only way I could find to get the TV show and episode
                    # info is from the Player.Filename infolabel. It shows up like this:
                    # ShowName [sXXeYY ](year) EpisodeName, channel, PVRFileName
                    # The season and episode info may or may not be present. For example:
                    # Elementary s04e10 (2016) Alma Matters, TV (WWMT-HD), 20160129_030000.pvr
                    # DC's Legends of Tomorrow (2016) Pilot, Part 2, TV (CW W MI), 20160129_010000.pvr
                    foundLabel = xbmc.getInfoLabel('Player.Filename')
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Found unknown video type with label: %s. Might be a PVR episode, searching Trakt for it."
                        % foundLabel)
                    splitLabel = foundLabel.rsplit(", ", 2)
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Post-split of label: %s "
                        % splitLabel)
                    if len(splitLabel) != 3:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Label doesn't have the ShowName sXXeYY (year) EpisodeName, channel, PVRFileName format that was expected. Giving up."
                        )
                        return
                    foundShowAndEpInfo = splitLabel[0]
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - show plus episode info: %s"
                        % foundShowAndEpInfo)
                    splitShowAndEpInfo = re.split(
                        ' (s\d\de\d\d)? ?\((\d\d\d\d)\) ', foundShowAndEpInfo,
                        1)
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Post-split of show plus episode info: %s "
                        % splitShowAndEpInfo)
                    if len(splitShowAndEpInfo) != 4:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Show plus episode info doesn't have the ShowName sXXeYY (year) EpisodeName format that was expected. Giving up."
                        )
                        return
                    foundShowName = splitShowAndEpInfo[0]
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - using show name: %s"
                        % foundShowName)
                    foundEpisodeName = splitShowAndEpInfo[3]
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - using episode name: %s"
                        % foundEpisodeName)
                    foundEpisodeYear = splitShowAndEpInfo[2]
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - using episode year: %s"
                        % foundEpisodeYear)
                    epYear = None
                    try:
                        epYear = int(foundEpisodeYear)
                    except ValueError:
                        epYear = None
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - verified episode year: %d"
                        % epYear)
                    # All right, now we have the show name, episode name, and (maybe) episode year. All good, but useless for
                    # scrobbling since Trakt only understands IDs, not names.
                    data['video_ids'] = None
                    data['season'] = None
                    data['episode'] = None
                    data['episodeTitle'] = None
                    # First thing to try, a text query to the Trakt DB looking for this episode. Note
                    # that we can't search for show and episode together, because the Trakt function gets confused and returns nothing.
                    newResp = globals.traktapi.getTextQuery(
                        foundEpisodeName, "episode", epYear)
                    if not newResp:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Empty Response from getTextQuery, giving up"
                        )
                    else:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Got Response from getTextQuery: %s"
                            % str(newResp))
                        # We got something back. See if one of the returned values is for the show we're looking for. Often it's
                        # not, but since there's no way to tell the search which show we want, this is all we can do.
                        rightResp = None
                        for thisResp in newResp:
                            compareShowName = thisResp.show.title
                            logger.debug(
                                "[traktPlayer] onPlayBackStarted() - comparing show name: %s"
                                % compareShowName)
                            if thisResp.show.title == foundShowName:
                                logger.debug(
                                    "[traktPlayer] onPlayBackStarted() - found the right show, using this response"
                                )
                                rightResp = thisResp
                                break
                        if rightResp is None:
                            logger.debug(
                                "[traktPlayer] onPlayBackStarted() - Failed to find matching episode/show via text search."
                            )
                        else:
                            # OK, now we have a episode object to work with.
                            self.type = 'episode'
                            data['type'] = 'episode'
                            # You'd think we could just use the episode key that Trakt just returned to us, but the scrobbler
                            # function (see scrobber.py) only understands the show key plus season/episode values.
                            showKeys = {}
                            for eachKey in rightResp.show.keys:
                                showKeys[eachKey[0]] = eachKey[1]
                            data['video_ids'] = showKeys
                            # For some reason, the Trakt search call returns the season and episode as an array in the pk field.
                            # You'd think individual episode and season fields would be better, but whatever.
                            data['season'] = rightResp.pk[0]
                            data['episode'] = rightResp.pk[1]
                    # At this point if we haven't found the episode data yet, the episode-title-text-search method
                    # didn't work.
                    if (not data['season']):
                        # This text query API is basically the same as searching on the website. Works with alternative
                        # titles, unlike the scrobble function. Though we can't use the episode year since that would only
                        # match the show if we're dealing with season 1.
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Searching for show title via getTextQuery: %s"
                            % foundShowName)
                        newResp = globals.traktapi.getTextQuery(
                            foundShowName, "show", None)
                        if not newResp:
                            logger.debug(
                                "[traktPlayer] onPlayBackStarted() - Empty Show Response from getTextQuery, falling back on episode text query"
                            )
                        else:
                            logger.debug(
                                "[traktPlayer] onPlayBackStarted() - Got Show Response from getTextQuery: %s"
                                % str(newResp))
                            # We got something back. Have to assume the first show found is the right one; if there's more than
                            # one, there's no way to know which to use. Pull the ids from the show data, and store 'em for scrobbling.
                            showKeys = {}
                            for eachKey in newResp[0].keys:
                                showKeys[eachKey[0]] = eachKey[1]
                            data['video_ids'] = showKeys
                            # Now to find the episode. There's no search function to look for an episode within a show, but
                            # we can get all the episodes and look for the title.
                            while (not data['season']):
                                logger.debug(
                                    "[traktPlayer] onPlayBackStarted() - Querying for all seasons/episodes of this show"
                                )
                                epQueryResp = globals.traktapi.getShowWithAllEpisodesList(
                                    data['video_ids']['trakt'])
                                if not epQueryResp:
                                    # Nothing returned. Giving up.
                                    logger.debug(
                                        "[traktPlayer] onPlayBackStarted() - No response received"
                                    )
                                    break
                                else:
                                    # Got the list back. Go through each season.
                                    logger.debug(
                                        "[traktPlayer] onPlayBackStarted() - Got response with seasons: %s"
                                        % str(epQueryResp))
                                    for eachSeason in epQueryResp:
                                        # For each season, check each episode.
                                        logger.debug(
                                            "[traktPlayer] onPlayBackStarted() - Processing season: %s"
                                            % str(eachSeason))
                                        for eachEpisodeNumber in eachSeason.episodes:
                                            thisEpTitle = None
                                            # Get the title. The try block is here in case the title doesn't exist for some entries.
                                            try:
                                                thisEpTitle = eachSeason.episodes[
                                                    eachEpisodeNumber].title
                                            except:
                                                thisEpTitle = None
                                            logger.debug(
                                                "[traktPlayer] onPlayBackStarted() - Checking episode number %d with title %s"
                                                % (eachEpisodeNumber,
                                                   thisEpTitle))
                                            if (foundEpisodeName == thisEpTitle
                                                ):
                                                # Found it! Save the data. The scrobbler wants season and episode number. Which for some
                                                # reason is stored as a pair in the first item in the keys array.
                                                data[
                                                    'season'] = eachSeason.episodes[
                                                        eachEpisodeNumber].keys[
                                                            0][0]
                                                data[
                                                    'episode'] = eachSeason.episodes[
                                                        eachEpisodeNumber].keys[
                                                            0][1]
                                                # Title too, just for the heck of it. Though it's not actually used.
                                                data[
                                                    'episodeTitle'] = thisEpTitle
                                                break
                                        # If we already found our data, no need to go through the rest of the seasons.
                                        if (data['season']):
                                            break
                    # Now we've done all we can.
                    if (data['season']):
                        # OK, that's everything. Data should be all set for scrobbling.
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' : show trakt key %s, season: %d, episode: %d"
                            % (data['video_ids'], data['season'],
                               data['episode']))
                    else:
                        # Still no data? Too bad, have to give up.
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - Did our best, but couldn't get info for this show and episode. Skipping."
                        )
                        return
                else:
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Video type '%s' unrecognized, skipping."
                        % self.type)
                    return

                pl = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
                plSize = len(pl)
                if plSize > 1:
                    pos = pl.getposition()
                    if not self.plIndex is None:
                        logger.debug(
                            "[traktPlayer] onPlayBackStarted() - User manually skipped to next (or previous) video, forcing playback ended event."
                        )
                        self.onPlayBackEnded()
                    self.plIndex = pos
                    logger.debug(
                        "[traktPlayer] onPlayBackStarted() - Playlist contains %d item(s), and is currently on item %d"
                        % (plSize, (pos + 1)))

                self._playing = True

                # send dispatch
                self.action(data)
Exemple #5
0
def test_regex_tvshow_episode_6():
    assert utilities.regex_tvshow('ShowTitle - s01ep09')[2] == 9
Exemple #6
0
def test_regex_tvshow_title_4():
    assert utilities.regex_tvshow(
        'ShowTitle.Season 01 - Episode 02')[0] == 'ShowTitle'
def test_regex_tvshow_season_6():
    assert utilities.regex_tvshow('ShowTitle - s01ep03')[1] == 1
Exemple #8
0
def test_regex_tvshow_episode_4():
    assert utilities.regex_tvshow('ShowTitle.Season 01 - Episode 09')[2] == 9
def test_regex_tvshow_season_4():
    assert utilities.regex_tvshow('ShowTitle.Season 01 - Episode 02')[1] == 1
def test_regex_tvshow_season_5():
    assert utilities.regex_tvshow('ShowTitle_[s01]_[e01]')[1] == 1
def test_regex_tvshow_season_3():
    assert utilities.regex_tvshow('ShowTitle.109')[1] == 1
def test_regex_tvshow_title_6():
    assert utilities.regex_tvshow('ShowTitle - s01ep03')[0] == 'ShowTitle'
def test_regex_tvshow_title_5():
    assert utilities.regex_tvshow('ShowTitle_[s01]_[e01]')[0] == 'ShowTitle'
Exemple #14
0
def test_regex_tvshow_season_6():
    assert utilities.regex_tvshow('ShowTitle - s01ep03')[1] == 1
def test_regex_tvshow_episode_3():
    assert utilities.regex_tvshow('ShowTitle.109')[2] == 9
Exemple #16
0
def test_regex_tvshow_episode_3():
    assert utilities.regex_tvshow('ShowTitle.109')[2] == 9
def test_regex_tvshow_episode_4():
    assert utilities.regex_tvshow('ShowTitle.Season 01 - Episode 09')[2] == 9
Exemple #18
0
def test_regex_tvshow_episode_5():
    assert utilities.regex_tvshow('ShowTitle_[s01]_[e09]')[2] == 9
def test_regex_tvshow_episode_5():
    assert utilities.regex_tvshow('ShowTitle_[s01]_[e09]')[2] == 9
Exemple #20
0
def test_regex_tvshow_title_3():
    assert utilities.regex_tvshow('ShowTitle.109')[0] == 'ShowTitle'
def test_regex_tvshow_episode_6():
    assert utilities.regex_tvshow('ShowTitle - s01ep09')[2] == 9
Exemple #22
0
def test_regex_tvshow_title_5():
    assert utilities.regex_tvshow('ShowTitle_[s01]_[e01]')[0] == 'ShowTitle'
Exemple #23
0
def test_regex_tvshow_season_3():
    assert utilities.regex_tvshow('ShowTitle.109')[1] == 1
Exemple #24
0
    def onPlayBackStarted(self):
        xbmc.sleep(1000)
        self.type = None
        self.id = None

        # only do anything if we're playing a video
        if self.isPlayingVideo():
            # get item data from json rpc
            result = utilities.xbmcJsonRequest({
                'jsonrpc': '2.0',
                'method': 'Player.GetItem',
                'params': {
                    'playerid': 1
                },
                'id': 1
            })
            utilities.Debug("[traktPlayer] onPlayBackStarted() - %s" % result)

            # check for exclusion
            _filename = None
            try:
                _filename = self.getPlayingFile()
            except:
                utilities.Debug(
                    "[traktPlayer] onPlayBackStarted() - Exception trying to get playing filename, player suddenly stopped."
                )
                return

            if utilities.checkScrobblingExclusion(_filename):
                utilities.Debug(
                    "[traktPlayer] onPlayBackStarted() - '%s' is in exclusion settings, ignoring."
                    % _filename)
                return

            self.type = result['item']['type']

            data = {'action': 'started'}

            # check type of item
            if self.type == 'unknown':
                # do a deeper check to see if we have enough data to perform scrobbles
                utilities.Debug(
                    "[traktPlayer] onPlayBackStarted() - Started playing a non-library file, checking available data."
                )

                season = xbmc.getInfoLabel('VideoPlayer.Season')
                episode = xbmc.getInfoLabel('VideoPlayer.Episode')
                showtitle = xbmc.getInfoLabel('VideoPlayer.TVShowTitle')
                year = xbmc.getInfoLabel('VideoPlayer.Year')

                utilities.Debug("[traktPlayer] info - showtitle:" + showtitle +
                                ", Year:" + year + ", Season:" + season +
                                ", Episode:" + episode)

                if season and episode and showtitle:
                    # we have season, episode and show title, can scrobble this as an episode
                    self.type = 'episode'
                    data['type'] = 'episode'
                    data['season'] = int(season)
                    data['episode'] = int(episode)
                    data['showtitle'] = showtitle
                    data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                    if year.isdigit():
                        data['year'] = year
                    utilities.Debug(
                        "[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' - %s - S%02dE%02d - %s."
                        % (data['showtitle'], data['season'], data['episode'],
                           data['title']))
                elif year and not season and not showtitle:
                    # we have a year and no season/showtitle info, enough for a movie
                    self.type = 'movie'
                    data['type'] = 'movie'
                    data['year'] = int(year)
                    data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                    utilities.Debug(
                        "[traktPlayer] onPlayBackStarted() - Playing a non-library 'movie' - %s (%d)."
                        % (data['title'], data['year']))
                elif showtitle:
                    title, season, episode = utilities.regex_tvshow(
                        False, showtitle)
                    data['type'] = 'episode'
                    data['season'] = int(season)
                    data['episode'] = int(episode)
                    data['showtitle'] = title
                    data['title'] = title
                    utilities.Debug(
                        "[traktPlayer] onPlayBackStarted() - Title:" + title +
                        ", showtitle:" + showtitle + ", season:" + season +
                        ", episode:" + episode)
                else:
                    utilities.Debug(
                        "[traktPlayer] onPlayBackStarted() - Non-library file, not enough data for scrobbling, skipping."
                    )
                    return

            elif self.type == 'episode' or self.type == 'movie':
                # get library id
                self.id = result['item']['id']
                data['id'] = self.id
                data['type'] = self.type

                if self.type == 'episode':
                    utilities.Debug(
                        "[traktPlayer] onPlayBackStarted() - Doing multi-part episode check."
                    )
                    result = utilities.xbmcJsonRequest({
                        'jsonrpc': '2.0',
                        'method': 'VideoLibrary.GetEpisodeDetails',
                        'params': {
                            'episodeid': self.id,
                            'properties': ['tvshowid', 'season', 'episode']
                        },
                        'id': 1
                    })
                    if result:
                        utilities.Debug(
                            "[traktPlayer] onPlayBackStarted() - %s" % result)
                        tvshowid = int(result['episodedetails']['tvshowid'])
                        season = int(result['episodedetails']['season'])
                        episode = int(result['episodedetails']['episode'])
                        episode_index = episode - 1

                        result = utilities.xbmcJsonRequest({
                            'jsonrpc': '2.0',
                            'method': 'VideoLibrary.GetEpisodes',
                            'params': {
                                'tvshowid': tvshowid,
                                'season': season,
                                'properties': ['episode', 'file'],
                                'sort': {
                                    'method': 'episode'
                                }
                            },
                            'id': 1
                        })
                        if result:
                            utilities.Debug(
                                "[traktPlayer] onPlayBackStarted() - %s" %
                                result)
                            # make sure episodes array exists in results
                            if 'episodes' in result:
                                multi = []
                                for i in range(episode_index,
                                               result['limits']['total']):
                                    if result['episodes'][i]['file'] == result[
                                            'episodes'][episode_index]['file']:
                                        multi.append(
                                            result['episodes'][i]['episodeid'])
                                    else:
                                        break
                                if len(multi) > 1:
                                    data['multi_episode_data'] = multi
                                    data['multi_episode_count'] = len(multi)
                                    utilities.Debug(
                                        "[traktPlayer] onPlayBackStarted() - This episode is part of a multi-part episode."
                                    )
                                else:
                                    utilities.Debug(
                                        "[traktPlayer] onPlayBackStarted() - This is a single episode."
                                    )

            else:
                utilities.Debug(
                    "[traktPlayer] onPlayBackStarted() - Video type '%s' unrecognized, skipping."
                    % self.type)
                return

            pl = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
            plSize = len(pl)
            if plSize > 1:
                pos = pl.getposition()
                if not self.plIndex is None:
                    utilities.Debug(
                        "[traktPlayer] onPlayBackStarted() - User manually skipped to next (or previous) video, forcing playback ended event."
                    )
                    self.onPlayBackEnded()
                self.plIndex = pos
                utilities.Debug(
                    "[traktPlayer] onPlayBackStarted() - Playlist contains %d item(s), and is currently on item %d"
                    % (plSize, (pos + 1)))

            self._playing = True

            # send dispatch
            self.action(data)
Exemple #25
0
def test_regex_tvshow_season_4():
    assert utilities.regex_tvshow('ShowTitle.Season 01 - Episode 02')[1] == 1
Exemple #26
0
    def onPlayBackStarted(self):
        xbmc.sleep(1000)
        self.type = None
        self.id = None

        # only do anything if we're playing a video
        if self.isPlayingVideo():
            # get item data from json rpc
            result = utilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'Player.GetItem', 'params': {'playerid': 1}, 'id': 1})
            logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)

            # check for exclusion
            _filename = None
            try:
                _filename = self.getPlayingFile()
            except:
                logger.debug("[traktPlayer] onPlayBackStarted() - Exception trying to get playing filename, player suddenly stopped.")
                return

            if utilities.checkExclusion(_filename):
                logger.debug("[traktPlayer] onPlayBackStarted() - '%s' is in exclusion settings, ignoring." % _filename)
                return

            self.type = result['item']['type']

            data = {'action': 'started'}

            # check type of item
            if 'id' not in result['item']:
                # do a deeper check to see if we have enough data to perform scrobbles
                logger.debug("[traktPlayer] onPlayBackStarted() - Started playing a non-library file, checking available data.")

                season = xbmc.getInfoLabel('VideoPlayer.Season')
                episode = xbmc.getInfoLabel('VideoPlayer.Episode')
                showtitle = xbmc.getInfoLabel('VideoPlayer.TVShowTitle')
                year = xbmc.getInfoLabel('VideoPlayer.Year')
                video_ids = xbmcgui.Window(10000).getProperty('script.trakt.ids')
                if video_ids:
                    data['video_ids'] = json.loads(video_ids)

                logger.debug("[traktPlayer] info - ids: %s, showtitle: %s, Year: %s, Season: %s, Episode: %s" % (video_ids, showtitle, year, season, episode))

                if season and episode and (showtitle or video_ids):
                    # we have season, episode and either a show title or video_ids, can scrobble this as an episode
                    self.type = 'episode'
                    data['type'] = 'episode'
                    data['season'] = int(season)
                    data['episode'] = int(episode)
                    data['showtitle'] = showtitle
                    data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                    if year.isdigit():
                        data['year'] = int(year)
                    logger.debug("[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' - %s - S%02dE%02d - %s." % (data['showtitle'], data['season'], data['episode'], data['title']))
                elif (year or video_ids) and not season and not showtitle:
                    # we have a year or video_id and no season/showtitle info, enough for a movie
                    self.type = 'movie'
                    data['type'] = 'movie'
                    if year.isdigit():
                        data['year'] = int(year)
                    data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                    logger.debug("[traktPlayer] onPlayBackStarted() - Playing a non-library 'movie' - %s (%s)." % (data['title'], data.get('year', 'NaN')))
                elif showtitle:
                    title, season, episode = utilities.regex_tvshow(False, showtitle)
                    data['type'] = 'episode'
                    data['season'] = int(season)
                    data['episode'] = int(episode)
                    data['showtitle'] = title
                    data['title'] = title
                    logger.debug("[traktPlayer] onPlayBackStarted() - Title: %s, showtitle: %s, season: %d, episode: %d" % (title, showtitle, season, episode))
                else:
                    logger.debug("[traktPlayer] onPlayBackStarted() - Non-library file, not enough data for scrobbling, skipping.")
                    return

            elif self.type == 'episode' or self.type == 'movie':
                # get library id
                self.id = result['item']['id']
                data['id'] = self.id
                data['type'] = self.type

                if self.type == 'episode':
                    logger.debug("[traktPlayer] onPlayBackStarted() - Doing multi-part episode check.")
                    result = utilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodeDetails', 'params': {'episodeid': self.id, 'properties': ['tvshowid', 'season', 'episode', 'file']}, 'id': 1})
                    if result:
                        logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)
                        tvshowid = int(result['episodedetails']['tvshowid'])
                        season = int(result['episodedetails']['season'])
                        currentfile = result['episodedetails']['file']

                        result = utilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': tvshowid, 'season': season, 'properties': ['episode', 'file'], 'sort': {'method': 'episode'}}, 'id': 1})
                        if result:
                            logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)
                            # make sure episodes array exists in results
                            if 'episodes' in result:
                                multi = []
                                for i in range(result['limits']['start'], result['limits']['total']):
                                    if currentfile == result['episodes'][i]['file']:
                                        multi.append(result['episodes'][i]['episodeid'])
                                if len(multi) > 1:
                                    data['multi_episode_data'] = multi
                                    data['multi_episode_count'] = len(multi)
                                    logger.debug("[traktPlayer] onPlayBackStarted() - This episode is part of a multi-part episode.")
                                else:
                                    logger.debug("[traktPlayer] onPlayBackStarted() - This is a single episode.")

            else:
                logger.debug("[traktPlayer] onPlayBackStarted() - Video type '%s' unrecognized, skipping." % self.type)
                return

            pl = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
            plSize = len(pl)
            if plSize > 1:
                pos = pl.getposition()
                if not self.plIndex is None:
                    logger.debug("[traktPlayer] onPlayBackStarted() - User manually skipped to next (or previous) video, forcing playback ended event.")
                    self.onPlayBackEnded()
                self.plIndex = pos
                logger.debug("[traktPlayer] onPlayBackStarted() - Playlist contains %d item(s), and is currently on item %d" % (plSize, (pos + 1)))

            self._playing = True

            # send dispatch
            self.action(data)
Exemple #27
0
def test_regex_tvshow_season_5():
    assert utilities.regex_tvshow('ShowTitle_[s01]_[e01]')[1] == 1
Exemple #28
0
    def onPlayBackStarted(self):
        xbmc.sleep(1000)
        self.type = None
        self.id = None

        # take the user start scrobble offset into account
        scrobbleStartOffset = kodiUtilities.getSettingAsInt('scrobble_start_offset')*60
        if scrobbleStartOffset > 0:
            waitFor = 10
            waitedFor = 0
            # check each 10 seconds if we can abort or proceed
            while not xbmc.abortRequested and scrobbleStartOffset > waitedFor:
                waitedFor += waitFor
                time.sleep(waitFor)
                if not self.isPlayingVideo():
                    logger.debug('[traktPlayer] Playback stopped before reaching the scrobble offset')
                    return

        # only do anything if we're playing a video
        if self.isPlayingVideo():
            # get item data from json rpc
            logger.debug("[traktPlayer] onPlayBackStarted() - Doing Player.GetItem kodiJsonRequest")
            result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'Player.GetItem', 'params': {'playerid': 1}, 'id': 1})
            if result:
                logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)
                # check for exclusion
                _filename = None
                try:
                    _filename = self.getPlayingFile()
                except:
                    logger.debug("[traktPlayer] onPlayBackStarted() - Exception trying to get playing filename, player suddenly stopped.")
                    return

                if kodiUtilities.checkExclusion(_filename):
                    logger.debug("[traktPlayer] onPlayBackStarted() - '%s' is in exclusion settings, ignoring." % _filename)
                    return

                self.type = result['item']['type']

                data = {'action': 'started'}

                if (kodiUtilities.getSettingAsBool('scrobble_mythtv_pvr')):
                    logger.debug('[traktPlayer] Setting is enabled to try scrobbling mythtv pvr recording, if necessary.')

                # check type of item
                if 'id' not in result['item']:
                    # do a deeper check to see if we have enough data to perform scrobbles
                    logger.debug("[traktPlayer] onPlayBackStarted() - Started playing a non-library file, checking available data.")

                    season = xbmc.getInfoLabel('VideoPlayer.Season')
                    episode = xbmc.getInfoLabel('VideoPlayer.Episode')
                    showtitle = xbmc.getInfoLabel('VideoPlayer.TVShowTitle')
                    year = xbmc.getInfoLabel('VideoPlayer.Year')
                    video_ids = xbmcgui.Window(10000).getProperty('script.trakt.ids')
                    if video_ids:
                        data['video_ids'] = json.loads(video_ids)

                    logger.debug("[traktPlayer] info - ids: %s, showtitle: %s, Year: %s, Season: %s, Episode: %s" % (video_ids, showtitle, year, season, episode))

                    if season and episode and (showtitle or video_ids):
                        # we have season, episode and either a show title or video_ids, can scrobble this as an episode
                        self.type = 'episode'
                        data['type'] = 'episode'
                        data['season'] = int(season)
                        data['episode'] = int(episode)
                        data['showtitle'] = showtitle
                        data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                        if year.isdigit():
                            data['year'] = int(year)
                        logger.debug("[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' - %s - S%02dE%02d - %s." % (data['showtitle'], data['season'], data['episode'], data['title']))
                    elif (year or video_ids) and not season and not showtitle:
                        # we have a year or video_id and no season/showtitle info, enough for a movie
                        self.type = 'movie'
                        data['type'] = 'movie'
                        if year.isdigit():
                            data['year'] = int(year)
                        data['title'] = xbmc.getInfoLabel('VideoPlayer.Title')
                        logger.debug("[traktPlayer] onPlayBackStarted() - Playing a non-library 'movie' - %s (%s)." % (data['title'], data.get('year', 'NaN')))
                    elif showtitle:
                        title, season, episode = utilities.regex_tvshow(showtitle)
                        data['type'] = 'episode'
                        data['season'] = season
                        data['episode'] = episode
                        data['title'] = data['showtitle'] = title
                        logger.debug("[traktPlayer] onPlayBackStarted() - Title: %s, showtitle: %s, season: %d, episode: %d" % (title, showtitle, season, episode))
                    else:
                        logger.debug("[traktPlayer] onPlayBackStarted() - Non-library file, not enough data for scrobbling, skipping.")
                        return

                elif self.type == 'episode' or self.type == 'movie':
                    # get library id
                    self.id = result['item']['id']
                    data['id'] = self.id
                    data['type'] = self.type

                    if self.type == 'episode':
                        logger.debug("[traktPlayer] onPlayBackStarted() - Doing multi-part episode check.")
                        result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodeDetails', 'params': {'episodeid': self.id, 'properties': ['tvshowid', 'season', 'episode', 'file']}, 'id': 1})
                        if result:
                            logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)
                            tvshowid = int(result['episodedetails']['tvshowid'])
                            season = int(result['episodedetails']['season'])
                            currentfile = result['episodedetails']['file']

                            result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': tvshowid, 'season': season, 'properties': ['episode', 'file'], 'sort': {'method': 'episode'}}, 'id': 1})
                            if result:
                                logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result)
                                # make sure episodes array exists in results
                                if 'episodes' in result:
                                    multi = []
                                    for i in range(result['limits']['start'], result['limits']['total']):
                                        if currentfile == result['episodes'][i]['file']:
                                            multi.append(result['episodes'][i]['episodeid'])
                                    if len(multi) > 1:
                                        data['multi_episode_data'] = multi
                                        data['multi_episode_count'] = len(multi)
                                        logger.debug("[traktPlayer] onPlayBackStarted() - This episode is part of a multi-part episode.")
                                    else:
                                        logger.debug("[traktPlayer] onPlayBackStarted() - This is a single episode.")
                elif (kodiUtilities.getSettingAsBool('scrobble_mythtv_pvr') and self.type == 'unknown' and result['item']['label']):
                    # If we have label/id but no show type, then this might be a PVR recording.

                    # DEBUG INFO: This code is useful when trying to figure out what info is available. Many of the fields
                    # that you'd expect (TVShowTitle, episode, season, etc) are always blank. In Kodi v15, we got the show
                    # and episode name in the VideoPlayer label. In v16, that's gone, but the Player.Filename infolabel
                    # is populated with several interesting things. If these things change in future versions, uncommenting
                    # this code will hopefully provide some useful info in the debug log.
                    #logger.debug("[traktPlayer] onPlayBackStarted() - TEMP Checking all videoplayer infolabels.")
                    #for il in ['VideoPlayer.Time','VideoPlayer.TimeRemaining','VideoPlayer.TimeSpeed','VideoPlayer.Duration','VideoPlayer.Title','VideoPlayer.TVShowTitle','VideoPlayer.Season','VideoPlayer.Episode','VideoPlayer.Genre','VideoPlayer.Director','VideoPlayer.Country','VideoPlayer.Year','VideoPlayer.Rating','VideoPlayer.UserRating','VideoPlayer.Votes','VideoPlayer.RatingAndVotes','VideoPlayer.mpaa','VideoPlayer.IMDBNumber','VideoPlayer.EpisodeName','VideoPlayer.PlaylistPosition','VideoPlayer.PlaylistLength','VideoPlayer.Cast','VideoPlayer.CastAndRole','VideoPlayer.Album','VideoPlayer.Artist','VideoPlayer.Studio','VideoPlayer.Writer','VideoPlayer.Tagline','VideoPlayer.PlotOutline','VideoPlayer.Plot','VideoPlayer.LastPlayed','VideoPlayer.PlayCount','VideoPlayer.VideoCodec','VideoPlayer.VideoResolution','VideoPlayer.VideoAspect','VideoPlayer.AudioCodec','VideoPlayer.AudioChannels','VideoPlayer.AudioLanguage','VideoPlayer.SubtitlesLanguage','VideoPlayer.StereoscopicMode','VideoPlayer.EndTime','VideoPlayer.NextTitle','VideoPlayer.NextGenre','VideoPlayer.NextPlot','VideoPlayer.NextPlotOutline','VideoPlayer.NextStartTime','VideoPlayer.NextEndTime','VideoPlayer.NextDuration','VideoPlayer.ChannelName','VideoPlayer.ChannelNumber','VideoPlayer.SubChannelNumber','VideoPlayer.ChannelNumberLabel','VideoPlayer.ChannelGroup','VideoPlayer.ParentalRating','Player.FinishTime','Player.FinishTime(format)','Player.Chapter','Player.ChapterCount','Player.Time','Player.Time(format)','Player.TimeRemaining','Player.TimeRemaining(format)','Player.Duration','Player.Duration(format)','Player.SeekTime','Player.SeekOffset','Player.SeekOffset(format)','Player.SeekStepSize','Player.ProgressCache','Player.Folderpath','Player.Filenameandpath','Player.StartTime','Player.StartTime(format)','Player.Title','Player.Filename']:
                    #    logger.debug("[traktPlayer] TEMP %s : %s" % (il, xbmc.getInfoLabel(il)))
                    #for k,v in result.iteritems():
                    #    logger.debug("[traktPlayer] onPlayBackStarted() - result - %s : %s" % (k,v))
                    #for k,v in result['item'].iteritems():
                    #    logger.debug("[traktPlayer] onPlayBackStarted() - result.item - %s : %s" % (k,v))

                    # As of Kodi v16 with the MythTV PVR addon, the only way I could find to get the TV show and episode
                    # info is from the Player.Filename infolabel. It shows up like this:
                    # ShowName [sXXeYY ](year) EpisodeName, channel, PVRFileName
                    # The season and episode info may or may not be present. For example:
                    # Elementary s04e10 (2016) Alma Matters, TV (WWMT-HD), 20160129_030000.pvr
                    # DC's Legends of Tomorrow (2016) Pilot, Part 2, TV (CW W MI), 20160129_010000.pvr
                    foundLabel = xbmc.getInfoLabel('Player.Filename')
                    logger.debug("[traktPlayer] onPlayBackStarted() - Found unknown video type with label: %s. Might be a PVR episode, searching Trakt for it." % foundLabel)
                    splitLabel = foundLabel.rsplit(", ", 2)
                    logger.debug("[traktPlayer] onPlayBackStarted() - Post-split of label: %s " % splitLabel)
                    if len(splitLabel) != 3:
                        logger.debug("[traktPlayer] onPlayBackStarted() - Label doesn't have the ShowName sXXeYY (year) EpisodeName, channel, PVRFileName format that was expected. Giving up.")
                        return
                    foundShowAndEpInfo = splitLabel[0]
                    logger.debug("[traktPlayer] onPlayBackStarted() - show plus episode info: %s" % foundShowAndEpInfo)
                    splitShowAndEpInfo = re.split(' (s\d\de\d\d)? ?\((\d\d\d\d)\) ',foundShowAndEpInfo, 1)
                    logger.debug("[traktPlayer] onPlayBackStarted() - Post-split of show plus episode info: %s " % splitShowAndEpInfo)
                    if len(splitShowAndEpInfo) != 4:
                        logger.debug("[traktPlayer] onPlayBackStarted() - Show plus episode info doesn't have the ShowName sXXeYY (year) EpisodeName format that was expected. Giving up.")
                        return
                    foundShowName = splitShowAndEpInfo[0]
                    logger.debug("[traktPlayer] onPlayBackStarted() - using show name: %s" % foundShowName)
                    foundEpisodeName = splitShowAndEpInfo[3]
                    logger.debug("[traktPlayer] onPlayBackStarted() - using episode name: %s" % foundEpisodeName)
                    foundEpisodeYear = splitShowAndEpInfo[2]
                    logger.debug("[traktPlayer] onPlayBackStarted() - using episode year: %s" % foundEpisodeYear)
                    epYear = None
                    try:
                        epYear = int(foundEpisodeYear)
                    except ValueError:
                        epYear = None
                    logger.debug("[traktPlayer] onPlayBackStarted() - verified episode year: %d" % epYear)
                    # All right, now we have the show name, episode name, and (maybe) episode year. All good, but useless for
                    # scrobbling since Trakt only understands IDs, not names.
                    data['video_ids'] = None
                    data['season'] = None
                    data['episode'] = None
                    data['episodeTitle'] = None
                    # First thing to try, a text query to the Trakt DB looking for this episode. Note
                    # that we can't search for show and episode together, because the Trakt function gets confused and returns nothing.
                    newResp = globals.traktapi.getTextQuery(foundEpisodeName, "episode", epYear)
                    if not newResp:
                        logger.debug("[traktPlayer] onPlayBackStarted() - Empty Response from getTextQuery, giving up")
                    else:
                        logger.debug("[traktPlayer] onPlayBackStarted() - Got Response from getTextQuery: %s" % str(newResp))
                        # We got something back. See if one of the returned values is for the show we're looking for. Often it's
                        # not, but since there's no way to tell the search which show we want, this is all we can do.
                        rightResp = None
                        for thisResp in newResp:
                            compareShowName = thisResp.show.title
                            logger.debug("[traktPlayer] onPlayBackStarted() - comparing show name: %s" % compareShowName)
                            if thisResp.show.title == foundShowName:
                                logger.debug("[traktPlayer] onPlayBackStarted() - found the right show, using this response")
                                rightResp = thisResp
                                break
                        if rightResp is None:
                            logger.debug("[traktPlayer] onPlayBackStarted() - Failed to find matching episode/show via text search.")
                        else:
                            # OK, now we have a episode object to work with.
                            self.type = 'episode'
                            data['type'] = 'episode'
                            # You'd think we could just use the episode key that Trakt just returned to us, but the scrobbler
                            # function (see scrobber.py) only understands the show key plus season/episode values.
                            showKeys = { }
                            for eachKey in rightResp.show.keys:
                                showKeys[eachKey[0]] = eachKey[1]
                            data['video_ids'] = showKeys
                            # For some reason, the Trakt search call returns the season and episode as an array in the pk field.
                            # You'd think individual episode and season fields would be better, but whatever.
                            data['season'] = rightResp.pk[0];
                            data['episode'] = rightResp.pk[1];
                    # At this point if we haven't found the episode data yet, the episode-title-text-search method
                    # didn't work.
                    if (not data['season']):
                        # This text query API is basically the same as searching on the website. Works with alternative
                        # titles, unlike the scrobble function. Though we can't use the episode year since that would only
                        # match the show if we're dealing with season 1.
                        logger.debug("[traktPlayer] onPlayBackStarted() - Searching for show title via getTextQuery: %s" % foundShowName)
                        newResp = globals.traktapi.getTextQuery(foundShowName, "show", None)
                        if not newResp:
                            logger.debug("[traktPlayer] onPlayBackStarted() - Empty Show Response from getTextQuery, falling back on episode text query")
                        else:
                            logger.debug("[traktPlayer] onPlayBackStarted() - Got Show Response from getTextQuery: %s" % str(newResp))
                            # We got something back. Have to assume the first show found is the right one; if there's more than
                            # one, there's no way to know which to use. Pull the ids from the show data, and store 'em for scrobbling.
                            showKeys = { }
                            for eachKey in newResp[0].keys:
                                showKeys[eachKey[0]] = eachKey[1]
                            data['video_ids'] = showKeys
                            # Now to find the episode. There's no search function to look for an episode within a show, but
                            # we can get all the episodes and look for the title.
                            while (not data['season']):
                                logger.debug("[traktPlayer] onPlayBackStarted() - Querying for all seasons/episodes of this show")
                                epQueryResp = globals.traktapi.getShowWithAllEpisodesList(data['video_ids']['trakt'])
                                if not epQueryResp:
                                    # Nothing returned. Giving up.
                                    logger.debug("[traktPlayer] onPlayBackStarted() - No response received")
                                    break;
                                else:
                                    # Got the list back. Go through each season.
                                    logger.debug("[traktPlayer] onPlayBackStarted() - Got response with seasons: %s" % str(epQueryResp))
                                    for eachSeason in epQueryResp:
                                        # For each season, check each episode.
                                        logger.debug("[traktPlayer] onPlayBackStarted() - Processing season: %s" % str(eachSeason))
                                        for eachEpisodeNumber in eachSeason.episodes:
                                            thisEpTitle = None
                                            # Get the title. The try block is here in case the title doesn't exist for some entries.
                                            try:
                                                thisEpTitle = eachSeason.episodes[eachEpisodeNumber].title
                                            except:
                                                thisEpTitle = None
                                            logger.debug("[traktPlayer] onPlayBackStarted() - Checking episode number %d with title %s" % (eachEpisodeNumber, thisEpTitle))
                                            if (foundEpisodeName == thisEpTitle):
                                                # Found it! Save the data. The scrobbler wants season and episode number. Which for some
                                                # reason is stored as a pair in the first item in the keys array.
                                                data['season'] = eachSeason.episodes[eachEpisodeNumber].keys[0][0]
                                                data['episode'] = eachSeason.episodes[eachEpisodeNumber].keys[0][1]
                                                # Title too, just for the heck of it. Though it's not actually used.
                                                data['episodeTitle'] = thisEpTitle
                                                break
                                        # If we already found our data, no need to go through the rest of the seasons.
                                        if (data['season']):
                                            break;
                    # Now we've done all we can.
                    if (data['season']):
                        # OK, that's everything. Data should be all set for scrobbling.
                        logger.debug("[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' : show trakt key %s, season: %d, episode: %d" % (data['video_ids'], data['season'], data['episode']))
                    else:
                        # Still no data? Too bad, have to give up.
                        logger.debug("[traktPlayer] onPlayBackStarted() - Did our best, but couldn't get info for this show and episode. Skipping.")
                        return;
                else:
                    logger.debug("[traktPlayer] onPlayBackStarted() - Video type '%s' unrecognized, skipping." % self.type)
                    return

                pl = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
                plSize = len(pl)
                if plSize > 1:
                    pos = pl.getposition()
                    if not self.plIndex is None:
                        logger.debug("[traktPlayer] onPlayBackStarted() - User manually skipped to next (or previous) video, forcing playback ended event.")
                        self.onPlayBackEnded()
                    self.plIndex = pos
                    logger.debug("[traktPlayer] onPlayBackStarted() - Playlist contains %d item(s), and is currently on item %d" % (plSize, (pos + 1)))

                self._playing = True

                # send dispatch
                self.action(data)
def test_regex_tvshow_title_3():
    assert utilities.regex_tvshow('ShowTitle.109')[0] == 'ShowTitle'