Example #1
0
def get_listitem(name="", icon="", fanart="", channel={}, no_puls4=True):
    if channel:
        listitem = ListItem(channel["name"])
        listitem.setProperty('IsPlayable', 'true')
        if no_puls4:
            listitem.setLabel(listitem.getLabel().replace("Puls4 ", ""))
        images = json.loads(channel["images_json"])
        if images:
            if "image_base" in images and images["image_base"]:
                listitem.setArt({'icon':images["image_base"], 'thumb':images["image_base"], 'poster':images["image_base"]})
            else:
                listitem.setArt({'icon':images["icon_1"], 'thumb':images["icon_1"], 'poster':images["icon_1"]})
        if "next_program" in channel:
            #'Title': channel["name"]
            listitem.setInfo(type='Video', infoLabels={'Title': listitem.getLabel(), 'Plot': channel["next_program"]["name"]+'[CR]'+channel["next_program"]["description"], 'mediatype': 'video'})
            program_images = json.loads(channel["next_program"]["images_json"])
            if program_images:
                listitem.setArt({'fanart' : program_images["image_base"]})
    else:
        listitem = ListItem(name)
        listitem.setProperty('IsPlayable', 'true')
        listitem.setInfo(type='Video', infoLabels={'mediatype': 'video'})
        if icon != "":
            listitem.setArt({'icon':icon, 'thumb':icon, 'poster':icon})
        if fanart != "":
            listitem.setArt({'fanart':fanart})
    return listitem
Example #2
0
    def _add_listitem(self, parsed_item):
        # type: (ParsedItem) -> None

        is_folder = parsed_item.url.get("mode") == "collection"

        _LOGGER.debug("Add ListItem %s", parsed_item)
        listitem = ListItem(label=self._localize(parsed_item.label),
                            offscreen=True)
        if not parsed_item.info.get("plot"):
            parsed_item.info["plot"] = listitem.getLabel()

        listitem.setInfo("video", parsed_item.info)

        # Set fallback fanart
        parsed_item.art.setdefault("fanart", self._ADDON_FANART)
        listitem.setArt(parsed_item.art)

        # Add context menu for alternate stream versions
        if parsed_item.url.get("mode") == "watch":
            self._add_video_context_menu(listitem, str(parsed_item.url["id"]))

        for key, value in list(parsed_item.properties.items()):
            listitem.setProperty(key, value)

        xbmcplugin.addDirectoryItem(
            self._handle,
            update_url_params(self._base_url, **parsed_item.url),
            listitem,
            isFolder=is_folder,
        )
Example #3
0
    def toFileItem(plexServer, plexItem, mediaType=None, plexLibType=None):
        # determine the matching Plex library type if possible
        checkMediaType = mediaType is not None
        if checkMediaType and not plexLibType:
            mappedMediaType = Api.getPlexMediaType(mediaType)
            if not mappedMediaType:
                log(
                    'cannot import unsupported media type "{}"'.format(
                        mediaType), xbmc.LOGERROR)
                return None

            plexLibType = mappedMediaType['libtype']

        # make sure the item matches the media type
        if plexLibType is not None and not Api.validatePlexLibraryItemType(
                plexItem, plexLibType):
            log(
                'cannot import {} item from invalid Plex library item: {}'.
                format(mediaType, plexItem), xbmc.LOGERROR)
            return None

        # determine the Kodi media type based on the Plex library type
        if not checkMediaType:
            plexLibType = plexItem.type
            mappedMediaTypes = Api.getKodiMediaTypesFromPlexLibraryTpe(
                plexLibType)
            if not mappedMediaTypes:
                log(
                    'cannot import unsupported Plex library type "{}"'.format(
                        plexLibType), xbmc.LOGERROR)
                return None

            if len(mappedMediaTypes) > 1:
                log(
                    '{} supported media type for Plex library type "{}"'.
                    format(len(mappedMediaTypes), plexLibType), xbmc.LOGDEBUG)

            mediaType = mappedMediaTypes[0]['kodi']

        itemId = plexItem.ratingKey
        if not itemId:
            log('cannot import {} item without identifier'.format(mediaType),
                xbmc.LOGERROR)
            return None

        item = ListItem(label=plexItem.title)

        # fill video details
        Api.fillVideoInfos(plexServer, itemId, plexItem, mediaType, item)

        if not item.getPath():
            log(
                'failed to retrieve a path for {} item "{}"'.format(
                    mediaType, item.getLabel()), xbmc.LOGWARNING)
            return None

        return item
Example #4
0
def show_category(category_id):
    #setContent(plugin.handle, 'albums')
    if category_id == "livestream":
        channels = get_url(ids.overview_url)
        json_data = {}
        if channels != "":
            json_data = json.loads(channels)
        else:
            kodiutils.notification("ERROR GETTING LIVESTREAM INFO", "using saved values")
        # current = ListItem("ORF 1")
        # current.setInfo(type="Video")
        # current.setProperty('IsPlayable', 'true')
        # orf1
        channel = get_channel(json_data, "orf1")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "orf1"), listitem=get_listitem(name="ORF 1", channel=channel))
        channel = get_channel(json_data, "orf2")
        addDirectoryItem(plugin.handle, plugin.url_for(
            play_livestream, "orf2"), get_listitem(name="ORF 2", channel=channel))
        channel = get_channel(json_data, "Puls4")
        addDirectoryItem(plugin.handle, plugin.url_for(
            play_livestream, "puls4_at"), get_listitem(name="PULS 4", channel=channel, no_puls4=False))
        channel = get_channel(json_data, "Popup")
        addDirectoryItem(plugin.handle, plugin.url_for(
            play_livestream, "popuptv"), get_listitem(name="Popup TV", channel=channel, no_puls4=False))
        channel = get_channel(json_data, "ATV")
        addDirectoryItem(plugin.handle, plugin.url_for(
            play_livestream, "atv"), get_listitem(name="ATV", channel=channel))
        channel = get_channel(json_data, "ATV2")
        addDirectoryItem(plugin.handle, plugin.url_for(
            play_livestream, "atv2"), get_listitem(name="ATV 2", channel=channel))
        addDirectoryItem(plugin.handle, plugin.url_for(
            show_category, "austria"), ListItem(kodiutils.get_string(32026)), True)
        addDirectoryItem(plugin.handle, plugin.url_for(
            show_category, "germany"), ListItem(kodiutils.get_string(32027)), True)
        addDirectoryItem(plugin.handle, plugin.url_for(
            show_category, "switzerland"), ListItem(kodiutils.get_string(32028)), True)
    elif category_id == "austria":
        channels = get_url(ids.overview_url)
        json_data = {}
        if channels != "":
            json_data = json.loads(channels)
        else:
            kodiutils.notification("ERROR GETTING LIVESTREAM INFO", "using saved values")
        channel = get_channel(json_data, "kabel eins")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "kabeleins_at"), listitem=get_listitem(name="Kabel eins AT", channel=channel))
        channel = get_channel(json_data, "Kabel1Doku")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "kabeleinsdoku_at"), listitem=get_listitem(name="Kabel1Doku AT", channel=channel))
        channel = get_channel(json_data, "ProSieben")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "prosieben_at"), listitem=get_listitem(name="ProSieben AT", channel=channel))
        channel = get_channel(json_data, "ProSiebenMaxx")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "prosiebenmaxx_at"), listitem=get_listitem(name="ProSiebenMaxx AT", channel=channel))
        channel = get_channel(json_data, "SAT.1")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "sat1_at"), listitem=get_listitem(name="SAT.1 AT", channel=channel))
        channel = get_channel(json_data, "SAT.1 Gold")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "sat1gold_at"), listitem=get_listitem(name="SAT.1 Gold AT", channel=channel))
        channel = get_channel(json_data, "Sixx")
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "sixx_at"), listitem=get_listitem(name="Sixx AT", channel=channel))
    elif category_id == "germany" or category_id == "switzerland":
        if category_id == "germany":
            id = "_de"
            name = " DE"
        else:
            id = "_ch"
            name = " CH"
        listitem = get_listitem(name="Kabel eins"+name)
        listitem.setArt({'icon': icon_path.format("kabeleins"), 'thumb': icon_path.format("kabeleins"), 'poster': icon_path.format("kabeleins")})
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "kabeleins"+id), listitem=listitem)
        listitem = get_listitem(name="Kabel1Doku"+name)
        listitem.setArt({'icon': icon_path.format("kabeleinsdoku"), 'thumb': icon_path.format("kabeleinsdoku"), 'poster': icon_path.format("kabeleinsdoku")})
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "kabeleinsdoku"+id), listitem=listitem)
        listitem = get_listitem(name="ProSieben"+name)
        listitem.setArt({'icon': icon_path.format("prosieben"), 'thumb': icon_path.format("prosieben"), 'poster': icon_path.format("prosieben")})
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "prosieben"+id), listitem=listitem)
        listitem = get_listitem(name="ProSiebenMaxx"+name)
        listitem.setArt({'icon': icon_path.format("prosiebenmaxx"), 'thumb': icon_path.format("prosiebenmaxx"), 'poster': icon_path.format("prosiebenmaxx")})
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "prosiebenmaxx"+id), listitem=listitem)
        listitem = get_listitem(name="SAT.1"+name)
        listitem.setArt({'icon': icon_path.format("sat1"), 'thumb': icon_path.format("sat1"), 'poster': icon_path.format("sat1")})
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "sat1"+id), listitem=listitem)
        listitem = get_listitem(name="SAT.1 Gold"+name)
        listitem.setArt({'icon': icon_path.format("sat1gold"), 'thumb': icon_path.format("sat1gold"), 'poster': icon_path.format("sat1gold")})
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "sat1gold"+id), listitem=listitem)
        listitem = get_listitem(name="Sixx"+name)
        listitem.setArt({'icon': icon_path.format("sixx"), 'thumb': icon_path.format("sixx"), 'poster': icon_path.format("sixx")})
        addDirectoryItem(plugin.handle, url=plugin.url_for(
            play_livestream, "sixx"+id), listitem=listitem)

    elif category_id == "favorites":
        xbmcplugin.addSortMethod(plugin.handle, xbmcplugin.SORT_METHOD_LABEL)
        global favorites
        if not favorites and xbmcvfs.exists(favorites_file_path):
            favorites_file = xbmcvfs.File(favorites_file_path)
            favorites = json.load(favorites_file)
            favorites_file.close()

        for item in favorites:
            listitem = ListItem(favorites[item]["name"])
            listitem.setArt({'icon': favorites[item]["icon"], 'thumb':favorites[item]["icon"], 'poster':favorites[item]["icon"], 'fanart' : favorites[item]["fanart"]})
            addDirectoryItem(plugin.handle, url=item,
                listitem=listitem, isFolder=True)
    elif category_id == "tvprogramm":
        channels = get_url(ids.collections_request_url.format(id=ids.epg_id, page = "1"), critical=True)
        channels_json = json.loads(channels)
        xbmcplugin.addSortMethod(plugin.handle, xbmcplugin.SORT_METHOD_LABEL)
        for channel in channels_json["results"]:
            listitem = ListItem(channel["name"])
            if listitem.getLabel() != "Puls4 TV":
                listitem.setLabel(listitem.getLabel().replace("Puls4 ", ""))
            images = json.loads(channel["images_json"])
            icon = ""
            if "image_base" in images and images["image_base"]:
                icon = images["image_base"]
            else:
                icon = images["icon_1"]
            listitem.setArt({'icon': icon, 'thumb': icon, 'poster': icon})
            addDirectoryItem(plugin.handle, url=plugin.url_for(
                show_epg, channel_id=channel["id"], icon=quote(icon)), listitem=listitem, isFolder=True)

    else:
        addDirectoryItem(plugin.handle, "", ListItem(kodiutils.get_string(32004)), False)
    endOfDirectory(plugin.handle)
Example #5
0
    def fillVideoInfos(
            plexServer: plexapi.server.PlexServer,
            itemId: int,
            plexItem: video.Video,
            mediaType: str,
            item: ListItem
    ):
        """
        Populate the provided ListItem object with existing data from plexItem
        and additional detail pulled from the provided plexServer

        :param plexServer: Plex server to gather additional details from
        :type plexServer: plexapi.server.PlexServer
        :param itemId: Unique ID of the plex Video object item
        :type itemId: int
        :param plexItem: Plex object populated with information about the item
        :type plexItem: video.Video
        :param mediaType: Kodi Media type object
        :type mediaType: str
        :param item: Instantiated Kodi ListItem to populate with additional details
        :type item: :class:`ListItem`
        """
        info = {
            'mediatype': mediaType,
            'path': '',
            'filenameandpath': '',
            'title': item.getLabel() or '',
            'sorttitle': '',
            'originaltitle': '',
            'plot': plexItem.summary or '',
            'dateadded': Api.convertDateTimeToDbDateTime(plexItem.addedAt),
            'year': 0,
            'set': '',
            'rating': 0.0,
            'userrating': 0.0,
            'mpaa': '',
            'duration': 0,
            'playcount': 0,
            'lastplayed': '',
            'director': [],
            'writer': [],
            'genre': [],
            'country': [],
            'tag': []
        }

        date = None
        isFolder = False

        resumePoint = {
            'totaltime': 0,
            'resumetime': 0
        }

        artwork = {}
        collections = []
        media = []
        locations = []
        roles = []

        if isinstance(plexItem, video.Video):
            info.update({
                'sorttitle': plexItem.titleSort,
                'playcount': plexItem.viewCount,
                'lastplayed': Api.convertDateTimeToDbDateTime(plexItem.lastViewedAt),
            })
            info['tag'].append(plexItem.librarySectionTitle)

        if isinstance(plexItem, video.Movie):
            info.update({
                'mpaa': plexItem.contentRating or '',
                'duration': Api.MillisecondsToSeconds(plexItem.duration),
                'originaltitle': plexItem.originalTitle or '',
                'premiered': Api.convertDateTimeToDbDate(plexItem.originallyAvailableAt),
                'rating': plexItem.rating or 0.0,
                'studio': Api.ListFromString(plexItem.studio),
                'tagline': plexItem.tagline or '',
                'userrating': plexItem.userRating or 0.0,
                'year': plexItem.year or 0,
                'country': Api.ListFromMediaTags(plexItem.countries),
                'director': Api.ListFromMediaTags(plexItem.directors),
                'genre': Api.ListFromMediaTags(plexItem.genres),
                'writer': Api.ListFromMediaTags(plexItem.writers),
            })

            date = info['premiered']
            resumePoint['resumetime'] = Api.MillisecondsToSeconds(plexItem.viewOffset)
            collections = plexItem.collections
            media = plexItem.media
            roles = plexItem.roles
        elif isinstance(plexItem, library.Collections):
            isFolder = True
        elif isinstance(plexItem, video.Show):
            info.update({
                'mpaa': plexItem.contentRating or '',
                'duration': Api.MillisecondsToSeconds(plexItem.duration),
                'premiered': Api.convertDateTimeToDbDate(plexItem.originallyAvailableAt),
                'rating': plexItem.rating or 0.0,
                'studio': Api.ListFromString(plexItem.studio),
                'year': plexItem.year or 0,
                'genre': Api.ListFromMediaTags(plexItem.genres),
            })

            date = info['premiered']
            isFolder = True
            locations = plexItem.locations
            collections = plexItem.collections
            roles = plexItem.roles

            banner = plexItem.banner
            if banner:
                artwork['banner'] = plexServer.url(banner, includeToken=True)
        elif isinstance(plexItem, video.Season):
            info.update({
                'tvshowtitle': plexItem.parentTitle or '',
                'season': plexItem.index,
            })
            isFolder = True
        elif isinstance(plexItem, video.Episode):
            info.update({
                'tvshowtitle': plexItem.grandparentTitle or '',
                'season': plexItem.parentIndex,
                'episode': plexItem.index,
                'mpaa': plexItem.contentRating or '',
                'duration': Api.MillisecondsToSeconds(plexItem.duration),
                'aired': Api.convertDateTimeToDbDate(plexItem.originallyAvailableAt),
                'rating': plexItem.rating or 0.0,
                'year': plexItem.year or 0,
                'director': Api.ListFromMediaTags(plexItem.directors),
                'writer': Api.ListFromMediaTags(plexItem.writers),
            })

            date = info['aired']
            resumePoint['resumetime'] = Api.MillisecondsToSeconds(plexItem.viewOffset)
            media = plexItem.media

        # handle collections / sets
        collections = Api.ListFromMediaTags(collections)
        if collections:
            # Kodi can only store one set per media item
            info['set'] = collections[0]

        # set the item's datetime if available
        if date:
            item.setDateTime(date)

        # specify whether the item is a folder or not
        item.setIsFolder(isFolder)

        # add the item's ID as a unique ID belonging to Plex
        item.getVideoInfoTag().setUniqueIDs({
            PLEX_PROTOCOL: itemId
        }, PLEX_PROTOCOL)

        # handle actors / cast
        cast = []
        for index, role in enumerate(roles):
            cast.append({
                'name': role.tag.strip(),
                'role': role.role.strip(),
                'order': index
            })
        if cast:
            item.setCast(cast)

        # handle resume point
        if resumePoint['resumetime'] > 0 and info['duration'] > 0:
            resumePoint['totaltime'] = info['duration']
            item.setProperties(resumePoint)

        # handle stream details
        mediaPart = None
        for mediaStream in media:
            for part in mediaStream.parts:
                # pick the first MediaPart with a valid file and stream URL
                if mediaPart is None and part.file is not None and part.key is not None:
                    mediaPart = part

                for videoStream in part.videoStreams():
                    item.addStreamInfo('video', {
                        'codec': videoStream.codec,
                        'language': videoStream.language,
                        'width': videoStream.width,
                        'height': videoStream.height,
                        'duration': info['duration']
                    })

                for audioStream in part.audioStreams():
                    item.addStreamInfo(
                        'audio', {
                            'codec': audioStream.codec,
                            'language': audioStream.language,
                            'channels': audioStream.channels
                        }
                    )

                for subtitleStream in part.subtitleStreams():
                    item.addStreamInfo(
                        'subtitle', {
                            'language': subtitleStream.language
                        }
                    )

        if mediaPart:
            # extract the absolute / actual path and the stream URL from the selected MediaPart
            info['path'] = mediaPart.file
            item.setPath(plexServer.url(mediaPart.key, includeToken=True))
        elif isFolder:
            # for folders use locations for the path
            if locations:
                info['path'] = locations[0]
            item.setPath(plexServer.url(plexItem.key, includeToken=True))
        info['filenameandpath'] = item.getPath()

        # set all the video infos
        item.setInfo('video', info)

        # handle artwork
        poster = None
        fanart = None
        if isinstance(plexItem, video.Video):
            poster = plexItem.thumbUrl
            fanart = plexItem.artUrl
        elif isinstance(plexItem, library.Collections) and plexItem.thumb:
            poster = plexServer.url(plexItem.thumb, includeToken=True)

        if poster:
            artwork['poster'] = poster
        if fanart:
            artwork['fanart'] = fanart
        if artwork:
            item.setArt(artwork)
Example #6
0
    def createVideoInfoItemWithVideoSetters(embyServer,
                                            itemId,
                                            itemPath,
                                            itemObj,
                                            mediaType,
                                            libraryView='',
                                            allowDirectPlay=True):

        item = ListItem(path=itemPath,
                        label=itemObj.get(constants.PROPERTY_ITEM_NAME, ''),
                        offscreen=True)
        item.setIsFolder(itemObj.get(constants.PROPERTY_ITEM_IS_FOLDER, False))

        # handle date
        premiereDate = itemObj.get(constants.PROPERTY_ITEM_PREMIERE_DATE)
        if premiereDate:
            item.setDateTime(premiereDate)

        videoInfoTag = item.getVideoInfoTag()

        userdata = {}
        if constants.PROPERTY_ITEM_USER_DATA in itemObj:
            userdata = itemObj[constants.PROPERTY_ITEM_USER_DATA]

        duration = int(
            Api.ticksToSeconds(
                itemObj.get(constants.PROPERTY_ITEM_RUN_TIME_TICKS, 0)))

        videoInfoTag.setMediaType(mediaType)
        videoInfoTag.setPath(itemObj.get(constants.PROPERTY_ITEM_PATH, ''))
        videoInfoTag.setFilenameAndPath(item.getPath())
        videoInfoTag.setTitle(item.getLabel() or '')
        videoInfoTag.setSortTitle(
            itemObj.get(constants.PROPERTY_ITEM_SORT_NAME, ''))
        videoInfoTag.setOriginalTitle(
            itemObj.get(constants.PROPERTY_ITEM_ORIGINAL_TITLE, ''))
        videoInfoTag.setPlot(
            Api._mapOverview(itemObj.get(constants.PROPERTY_ITEM_OVERVIEW,
                                         '')))
        videoInfoTag.setPlotOutline(
            itemObj.get(constants.PROPERTY_ITEM_SHORT_OVERVIEW, ''))
        videoInfoTag.setDateAdded(
            Api.convertDateTimeToDbDateTime(
                itemObj.get(constants.PROPERTY_ITEM_DATE_CREATED, '')))
        videoInfoTag.setYear(
            itemObj.get(constants.PROPERTY_ITEM_PRODUCTION_YEAR, 0))
        videoInfoTag.setMpaa(
            Api._mapMpaa(
                itemObj.get(constants.PROPERTY_ITEM_OFFICIAL_RATING, '')))
        videoInfoTag.setDuration(duration)
        videoInfoTag.setPlaycount(
            userdata.get(constants.PROPERTY_ITEM_USER_DATA_PLAY_COUNT, 0
                         ) if userdata.
            get(constants.PROPERTY_ITEM_USER_DATA_PLAYED, False) else 0)
        videoInfoTag.setLastPlayed(
            Api.convertDateTimeToDbDateTime(
                userdata.get(
                    constants.PROPERTY_ITEM_USER_DATA_LAST_PLAYED_DATE, '')))
        videoInfoTag.setArtists(
            itemObj.get(constants.PROPERTY_ITEM_ARTISTS, []))
        videoInfoTag.setAlbum(itemObj.get(constants.PROPERTY_ITEM_ALBUM, ''))
        videoInfoTag.setGenres(itemObj.get(constants.PROPERTY_ITEM_GENRES, []))
        videoInfoTag.setCountries(
            itemObj.get(constants.PROPERTY_ITEM_PRODUCTION_LOCATIONS, []))

        # process ratings
        if constants.PROPERTY_ITEM_COMMUNITY_RATING in itemObj:
            defaultRating = itemObj.get(
                constants.PROPERTY_ITEM_COMMUNITY_RATING)
            videoInfoTag.setRating(defaultRating, isDefault=True)
        # handle critic rating as rotten tomato rating
        if constants.PROPERTY_ITEM_CRITIC_RATING in itemObj:
            criticRating = float(
                itemObj.get(constants.PROPERTY_ITEM_CRITIC_RATING)) / 10.0
            videoInfoTag.setRating(criticRating, type='tomatometerallcritics')

        # handle unique / provider IDs
        uniqueIds = \
            {key.lower(): value for key, value in iteritems(itemObj.get(constants.PROPERTY_ITEM_PROVIDER_IDS, {}))}
        defaultUniqueId = Api._mapDefaultUniqueId(uniqueIds, mediaType)
        # add the item's ID as a unique ID belonging to Emby
        uniqueIds[constants.EMBY_PROTOCOL] = itemId
        videoInfoTag.setUniqueIDs(uniqueIds, defaultUniqueId)

        # process tags
        tags = []
        if constants.PROPERTY_ITEM_TAG_ITEMS in itemObj:
            tags = [
                tag.get(constants.PROPERTY_ITEM_TAG_ITEMS_NAME)
                for tag in itemObj.get(constants.PROPERTY_ITEM_TAG_ITEMS)
                if constants.PROPERTY_ITEM_TAG_ITEMS_NAME in tag
            ]
        # add the library view as a tag
        if libraryView:
            tags.append(libraryView)
        videoInfoTag.setTags(tags)

        # handle aired / premiered
        if premiereDate:
            pos = premiereDate.find('T')
            if pos >= 0:
                premiereDate = premiereDate[:pos]

            if mediaType == xbmcmediaimport.MediaTypeEpisode:
                videoInfoTag.setFirstAired(premiereDate)
            else:
                videoInfoTag.setPremiered(premiereDate)

        # handle trailers
        trailerUrl = Api.getTrailer(embyServer,
                                    itemId,
                                    itemObj,
                                    allowDirectPlay=allowDirectPlay)
        if trailerUrl:
            videoInfoTag.setTrailer(trailerUrl)

        # handle taglines
        embyTaglines = itemObj.get(constants.PROPERTY_ITEM_TAGLINES, [])
        if embyTaglines:
            videoInfoTag.setTagLine(embyTaglines[0])

        # handle studios
        studios = []
        for studio in itemObj.get(constants.PROPERTY_ITEM_STUDIOS, []):
            studios.append(Api._mapStudio(studio['Name']))
        videoInfoTag.setStudios(studios)

        # handle tvshow, season and episode specific properties
        if mediaType == xbmcmediaimport.MediaTypeTvShow:
            videoInfoTag.setTvShowTitle(videoInfoTag.getTitle())
            videoInfoTag.setTvShowStatus(
                itemObj.get(constants.PROPERTY_ITEM_STATUS, ''))
        elif mediaType in (xbmcmediaimport.MediaTypeSeason,
                           xbmcmediaimport.MediaTypeEpisode):
            videoInfoTag.setTvShowTitle(
                itemObj.get(constants.PROPERTY_ITEM_SERIES_NAME, ''))
            index = itemObj.get(constants.PROPERTY_ITEM_INDEX_NUMBER, 0)
            if mediaType == xbmcmediaimport.MediaTypeSeason:
                videoInfoTag.setSeason(index)

                # ATTENTION
                # something is wrong with the SortName property for seasons which interfers with Kodi
                # abusing sorttitle for custom season titles
                videoInfoTag.setSortTitle('')
            else:
                videoInfoTag.setSeason(
                    itemObj.get(constants.PROPERTY_ITEM_PARENT_INDEX_NUMBER,
                                0))
                videoInfoTag.setEpisode(index)

        # handle resume point
        videoInfoTag.setResumePoint(
            Api.ticksToSeconds(
                userdata.get(
                    constants.PROPERTY_ITEM_USER_DATA_PLAYBACK_POSITION_TICKS,
                    0)), duration)

        # handle actors / cast
        cast = []
        writers = []
        directors = []
        for index, person in enumerate(
                itemObj.get(constants.PROPERTY_ITEM_PEOPLE, [])):
            name = person.get(constants.PROPERTY_ITEM_PEOPLE_NAME, '')
            castType = person.get(constants.PROPERTY_ITEM_PEOPLE_TYPE, '')
            if castType == constants.PROPERTY_ITEM_PEOPLE_TYPE_ACTOR:
                role = person.get(constants.PROPERTY_ITEM_PEOPLE_ROLE, '')
                # determine the thumbnail (if available)
                thumbnail = ''
                personId = person.get(constants.PROPERTY_ITEM_PEOPLE_ID, None)
                primaryImageTag = person.get(
                    constants.PROPERTY_ITEM_PEOPLE_PRIMARY_IMAGE_TAG, '')
                if personId and primaryImageTag:
                    thumbnail = \
                        embyServer.BuildImageUrl(personId, constants.PROPERTY_ITEM_IMAGE_TAGS_PRIMARY, primaryImageTag)

                cast.append(xbmc.Actor(name, role, index, thumbnail))
            elif castType == constants.PROPERTY_ITEM_PEOPLE_TYPE_WRITER:
                writers.append(name)
            elif castType == constants.PROPERTY_ITEM_PEOPLE_TYPE_DIRECTOR:
                directors.append(name)

        videoInfoTag.setCast(cast)
        videoInfoTag.setWriters(writers)
        videoInfoTag.setDirectors(directors)

        # stream details
        for stream in itemObj.get(constants.PROPERTY_ITEM_MEDIA_STREAMS, []):
            streamType = stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_TYPE,
                                    '')
            if streamType == 'video':
                details = Api._mapVideoStream({
                    'codec':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_CODEC, ''),
                    'profile':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_PROFILE,
                               ''),
                    'language':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_LANGUAGE,
                               ''),
                    'width':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_WIDTH, 0),
                    'height':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_HEIGHT, 0),
                    'aspect':
                    stream.get(
                        constants.PROPERTY_ITEM_MEDIA_STREAM_ASPECT_RATIO,
                        '0'),
                    'stereomode':
                    stream.get(
                        constants.PROPERTY_ITEM_MEDIA_STREAM_VIDEO_3D_FORMAT,
                        'mono'),
                    'duration':
                    duration
                })
                videoInfoTag.addVideoStream(
                    xbmc.VideoStreamDetail(
                        width=details['width'],
                        height=details['height'],
                        aspect=details['aspect'],
                        duration=details['duration'],
                        codec=details['codec'],
                        stereoMode=details['stereomode'],
                        language=details['language'],
                    ))
            elif streamType == 'audio':
                details = Api._mapAudioStream({
                    'codec':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_CODEC, ''),
                    'profile':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_PROFILE,
                               ''),
                    'language':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_LANGUAGE,
                               ''),
                    'channels':
                    stream.get(constants.PROPERTY_ITEM_MEDIA_STREAM_CHANNELS,
                               2)
                })
                videoInfoTag.addAudioStream(
                    xbmc.AudioStreamDetail(
                        channels=details['channels'],
                        codec=details['codec'],
                        language=details['language'],
                    ))
            elif streamType == 'subtitle':
                videoInfoTag.addSubtitleStream(
                    xbmc.SubtitleStreamDetail(language=stream.get(
                        constants.PROPERTY_ITEM_MEDIA_STREAM_LANGUAGE, ''), ))

        return item
Example #7
0
    def fillVideoInfos(plexServer: server.PlexServer,
                       itemId: int,
                       plexItem: video.Video,
                       mediaType: str,
                       item: ListItem,
                       allowDirectPlay: bool = False):
        """
        Populate the provided ListItem object with existing data from plexItem
        and additional detail pulled from the provided plexServer

        :param plexServer: Plex server to gather additional details from
        :type plexServer: server.PlexServer
        :param itemId: Unique ID of the plex Video object item
        :type itemId: int
        :param plexItem: Plex object populated with information about the item
        :type plexItem: video.Video
        :param mediaType: Kodi Media type object
        :type mediaType: str
        :param item: Instantiated Kodi ListItem to populate with additional details
        :type item: :class:`ListItem`
        :param allowDirectPlay: Settings definition on provider if directPlay is allowed
        :type allowDirectPlay: bool, optional
        """
        videoInfoTag = item.getVideoInfoTag()

        videoInfoTag.setMediaType(mediaType)
        videoInfoTag.setTitle(item.getLabel() or '')

        date = None
        isFolder = False

        resumeTime = 0.0
        duration = 0.0

        artwork = {}
        collections = []
        media = []
        locations = []
        roles = []

        if isinstance(plexItem, video.Video):
            videoInfoTag.setSortTitle(plexItem.titleSort or '')
            videoInfoTag.setPlot(plexItem.summary or '')
            videoInfoTag.setDateAdded(
                Api.convertDateTimeToDbDateTime(plexItem.addedAt))
            videoInfoTag.setPlaycount(plexItem.viewCount or 0)
            videoInfoTag.setLastPlayed(
                Api.convertDateTimeToDbDateTime(plexItem.lastViewedAt))
            videoInfoTag.setTags([plexItem.librarySectionTitle])

        if isinstance(plexItem, video.Movie):
            date = Api.convertDateTimeToDbDate(plexItem.originallyAvailableAt)
            duration = Api.MillisecondsToSeconds(plexItem.duration)
            resumeTime = Api.MillisecondsToSeconds(plexItem.viewOffset)
            collections = plexItem.collections or []
            media = plexItem.media or []
            roles = plexItem.roles or []

            videoInfoTag.setMpaa(plexItem.contentRating or '')
            videoInfoTag.setDuration(int(duration))
            videoInfoTag.setOriginalTitle(plexItem.originalTitle or '')
            videoInfoTag.setPremiered(date)
            videoInfoTag.setRating(plexItem.rating or 0.0)
            videoInfoTag.setTagLine(plexItem.tagline or '')
            videoInfoTag.setUserRating(int(plexItem.userRating or 0))
            videoInfoTag.setYear(plexItem.year or 0)
            videoInfoTag.setStudios(Api.ListFromString(plexItem.studio))
            videoInfoTag.setCountries(Api.ListFromMediaTags(
                plexItem.countries))
            videoInfoTag.setGenres(Api.ListFromMediaTags(plexItem.genres))
            videoInfoTag.setDirectors(Api.ListFromMediaTags(
                plexItem.directors))
            videoInfoTag.setWriters(Api.ListFromMediaTags(plexItem.writers))
        elif isinstance(plexItem, collection.Collection):
            # ignore empty collections
            if plexItem.childCount <= 0:
                return

            isFolder = True

            videoInfoTag.setPlot(plexItem.summary or '')
            videoInfoTag.setDateAdded(
                Api.convertDateTimeToDbDateTime(plexItem.addedAt))
        elif isinstance(plexItem, video.Show):
            isFolder = True
            date = Api.convertDateTimeToDbDate(plexItem.originallyAvailableAt)
            duration = Api.MillisecondsToSeconds(plexItem.duration)
            locations = plexItem.locations or []
            collections = plexItem.collections or []
            roles = plexItem.roles or []

            banner = plexItem.banner
            if banner:
                artwork['banner'] = plexServer.url(banner, includeToken=True)

            videoInfoTag.setMpaa(plexItem.contentRating or '')
            videoInfoTag.setDuration(int(duration))
            videoInfoTag.setOriginalTitle(plexItem.originalTitle or '')
            videoInfoTag.setPremiered(date)
            videoInfoTag.setRating(plexItem.rating or 0.0)
            videoInfoTag.setTagLine(plexItem.tagline or '')
            videoInfoTag.setYear(plexItem.year or 0)
            videoInfoTag.setStudios(Api.ListFromString(plexItem.studio))
            videoInfoTag.setGenres(Api.ListFromMediaTags(plexItem.genres))
        elif isinstance(plexItem, video.Season):
            isFolder = True

            videoInfoTag.setTvShowTitle(plexItem.parentTitle or '')
            videoInfoTag.setSeason(plexItem.index)
        elif isinstance(plexItem, video.Episode):
            date = Api.convertDateTimeToDbDate(plexItem.originallyAvailableAt)
            resumeTime = Api.MillisecondsToSeconds(plexItem.viewOffset)
            duration = Api.MillisecondsToSeconds(plexItem.duration)
            media = plexItem.media or []

            videoInfoTag.setTvShowTitle(plexItem.grandparentTitle or '')
            videoInfoTag.setSeason(int(plexItem.parentIndex))
            videoInfoTag.setEpisode(plexItem.index)
            videoInfoTag.setMpaa(plexItem.contentRating or '')
            videoInfoTag.setDuration(int(duration))
            videoInfoTag.setFirstAired(date)
            videoInfoTag.setRating(plexItem.rating or 0.0)
            videoInfoTag.setYear(plexItem.year or 0)
            videoInfoTag.setDirectors(Api.ListFromMediaTags(
                plexItem.directors))
            videoInfoTag.setWriters(Api.ListFromMediaTags(plexItem.writers))

        # handle collections / sets
        collections = Api.ListFromMediaTags(collections)
        if collections:
            # Kodi can only store one set per media item
            videoInfoTag.setSet(collections[0])

        # set the item's datetime if available
        if date:
            item.setDateTime(date)

        # specify whether the item is a folder or not
        item.setIsFolder(isFolder)

        # add the item's ID as a unique ID belonging to Plex
        uniqueIDs = {PLEX_PROTOCOL: str(itemId)}
        # retrieve and map GUIDS from Plex
        if isinstance(plexItem,
                      (video.Movie, video.Show, video.Season, video.Episode)):
            guids = Api._mapGuids(plexItem.guids)
            if guids:
                uniqueIDs = {**guids, **uniqueIDs}

        videoInfoTag.setUniqueIDs(uniqueIDs, PLEX_PROTOCOL)

        # handle actors / cast
        cast = []
        for index, role in enumerate(roles):
            actor = xbmc.Actor(role.tag.strip(), (role.role or '').strip(),
                               index, role.thumb)
            cast.append(actor)
        if cast:
            videoInfoTag.setCast(cast)

        # handle resume point
        if resumeTime > 0 and duration > 0.0:
            videoInfoTag.setResumePoint(resumeTime, duration)

        # handle stream details
        path = None
        for mediaStream in media:
            for part in mediaStream.parts:
                # pick the first MediaPart with a valid file and stream URL
                if not path and part.file and part.key:
                    path = part.file

                for videoStream in part.videoStreams():
                    videoInfoTag.addVideoStream(
                        xbmc.VideoStreamDetail(width=videoStream.width or 0,
                                               height=videoStream.height or 0,
                                               codec=videoStream.codec or '',
                                               duration=int(duration),
                                               language=videoStream.language
                                               or ''))

                for audioStream in part.audioStreams():
                    videoInfoTag.addAudioStream(
                        xbmc.AudioStreamDetail(channels=audioStream.channels
                                               or 2,
                                               codec=audioStream.codec or '',
                                               language=audioStream.language
                                               or ''))

                for index, subtitleStream in enumerate(part.subtitleStreams()):
                    videoInfoTag.addSubtitleStream(
                        xbmc.SubtitleStreamDetail(
                            language=subtitleStream.language or f"[{index}]"))

        if isFolder:
            # for folders use locations for the path
            if locations:
                path = locations[0]
            item.setPath(plexServer.url(plexItem.key, includeToken=True))
        else:
            # determine if directPlay is enabled and possible
            if allowDirectPlay:
                directPlayUrl = Api.getDirectPlayUrlFromPlexItem(plexItem)
                if directPlayUrl:
                    item.setPath(directPlayUrl)

            # otherwise determine the stream URL
            if not item.getPath():
                item.setPath(Api.getStreamUrlFromPlexItem(
                    plexItem, plexServer))

        if path:
            videoInfoTag.setPath(path)
        videoInfoTag.setFilenameAndPath(item.getPath())

        # handle artwork
        poster = None
        fanart = None
        if isinstance(plexItem, video.Video):
            poster = plexItem.thumbUrl
            fanart = plexItem.artUrl
        elif isinstance(plexItem, collection.Collection) and plexItem.thumb:
            poster = plexServer.url(plexItem.thumb, includeToken=True)

        if poster:
            artwork['poster'] = poster
        if fanart:
            artwork['fanart'] = fanart
        if artwork:
            item.setArt(artwork)