# -- coding: utf-8 -- # API.py # This class helps translate more complex cases from the MediaBrowser API to the XBMC API from datetime import datetime from random import randrange import xbmc import xbmcgui import Utils as utils class API(): def getPeople(self, item): # Process People director = [] writer = [] cast = [] try: people = item['People'] except: pass else: for person in people: type = person['Type'] Name = person['Name'] if "Director" in type: director.append(Name) elif "Writing" in type: writer.append(Name) elif "Writer" in type: writer.append(Name) elif "Actor" in type: cast.append(Name) return { 'Director': director, 'Writer': writer, 'Cast': cast } def getTimeInfo(self, item): # Runtime and Resume point tempRuntime = 0 runtime = 0 resume = 0 try: # Get resume point userdata = item['UserData'] playbackPosition = userdata['PlaybackPositionTicks'] resume = playbackPosition / 10000000.0 except: pass try: # Get total runtime tempRuntime = item['RunTimeTicks'] except: try: tempRuntime = item['CumulativeRunTimeTicks'] except: pass finally: runtime = tempRuntime / 10000000.0 return { 'ResumeTime': resume, 'TotalTime': runtime } def getStudios(self, item): # Process Studio studios = [] try: studio = item['SeriesStudio'] studios.append(self.getStudio(studio)) except: try: studioArray = item['Studios'] for studio in studioArray: studios.append(self.getStudio(studio['Name'])) except: pass return studios def getStudio(self, studioName): # Convert studio for Kodi to properly detect them studios = { 'abc (us)': "ABC", 'fox (us)': "FOX", 'mtv (us)': "MTV", 'showcase (ca)': "Showcase", 'wgn america': "WGN" } return studios.get(studioName.lower(), studioName) def getGenre(self,item): genre = "" genres = item.get("Genres") if genres != None and genres != []: for genre_string in genres: if genre == "": #Just take the first genre genre = genre_string else: genre = genre + " / " + genre_string elif item.get("SeriesGenres") != None and item.get("SeriesGenres") != '': genres = item.get("SeriesGenres") if genres != None and genres != []: for genre_string in genres: if genre == "": #Just take the first genre genre = genre_string else: genre = genre + " / " + genre_string return genre def getMediaStreams(self, item, mediaSources = False): videotracks = [] # Height, Width, Codec, AspectRatio, AspectFloat, 3D audiotracks = [] # Codec, Channels, language subtitlelanguages = [] # Language if mediaSources: try: MediaStreams = item['MediaSources'][0]['MediaStreams'] except: MediaStreams = None else: MediaStreams = item.get('MediaStreams') if MediaStreams: # Sort through the Video, Audio, Subtitle tracks for mediaStream in MediaStreams: type = mediaStream.get('Type', "") profile = mediaStream.get('Profile', "").lower() codec = mediaStream.get('Codec', "").lower() if "Video" in type: videotrack = {} videotrack['videocodec'] = codec container = item['MediaSources'][0].get('Container', "").lower() if "msmpeg4" in videotrack['videocodec']: videotrack['videocodec'] = "divx" elif "mpeg4" in videotrack['videocodec']: if "simple profile" in profile or profile == "": videotrack['videocodec'] = "xvid" elif "h264" in videotrack['videocodec']: if container in ("mp4", "mov", "m4v"): videotrack['videocodec'] = "avc1" videotrack['height'] = mediaStream.get('Height') videotrack['width'] = mediaStream.get('Width') videotrack['Video3DFormat'] = item.get('Video3DFormat') if item.get('AspectRatio'): # Metadata aspect ratio videotrack['aspectratio'] = item['AspectRatio'] else: # File aspect ratio videotrack['aspectratio'] = mediaStream.get('AspectRatio', "0") if len(videotrack['aspectratio']) >= 3: try: aspectwidth, aspectheight = videotrack['aspectratio'].split(':') videotrack['aspectratio'] = round(float(aspectwidth) / float(aspectheight), 6) except: videotrack['aspectratio'] = 1.85 else: try: videotrack['aspectratio'] = round(float(videotrack['width'] / videotrack['height']), 6) except: # In the event the aspect ratio is missing and the width and height are missing as well. videotrack['aspectratio'] = 1.85 videotracks.append(videotrack) elif "Audio" in type: audiotrack = {} audiotrack['audiocodec'] = codec if "dca" in audiotrack['audiocodec'] and "dts-hd ma" in profile: audiotrack['audiocodec'] = "dtshd_ma" audiotrack['channels'] = mediaStream.get('Channels') audiotrack['audiolanguage'] = mediaStream.get('Language') audiotracks.append(audiotrack) elif "Subtitle" in type: try: subtitlelanguages.append(mediaStream['Language']) except: subtitlelanguages.append("Unknown") return { 'videocodec' : videotracks, 'audiocodec' : audiotracks, 'subtitlelanguage' : subtitlelanguages } def getChecksum(self, item): # use the etags checksum for this if available # AND the userdata checksum = "" if item.get("Etag") != None: checksum = item.get("Etag") userData = item.get("UserData") if(userData != None): checksum += str(userData.get("Played")) checksum += str(userData.get("IsFavorite")) if userData.get('UnplayedItemCount') != None: checksum += str(userData.get("UnplayedItemCount")) if userData.get('LastPlayedDate') != None: checksum += str(userData.get("LastPlayedDate")) if userData.get('PlaybackPositionTicks') != None: checksum += str(userData.get("PlaybackPositionTicks")) return checksum def getUserData(self, item): # Default favorite = False playcount = None lastPlayedDate = None userKey = "" try: userdata = item['UserData'] except: # No userdata found. pass else: favorite = userdata['IsFavorite'] userKey = userdata.get('Key', "") watched = userdata['Played'] if watched: # Playcount is tied to the watch status playcount = userdata['PlayCount'] if playcount == 0: playcount = 1 else: playcount = None lastPlayedDate = userdata.get('LastPlayedDate', None) if lastPlayedDate: lastPlayedDate = lastPlayedDate.split('.')[0].replace('T', " ") return { 'Favorite': favorite, 'PlayCount': playcount, 'LastPlayedDate': lastPlayedDate, 'Key': userKey } def getRecursiveItemCount(self, item): if item.get("RecursiveItemCount") != None: return str(item.get("RecursiveItemCount")) else: return "0" def getOverview(self, item): overview = "" try: overview = item['Overview'] overview = overview.replace("\"", "\'") overview = overview.replace("\n", " ") overview = overview.replace("\r", " ") except: pass return overview def getTVInfo(self, item, userData): TotalSeasons = 0 if item.get("ChildCount")==None else item.get("ChildCount") TotalEpisodes = 0 if item.get("RecursiveItemCount")==None else item.get("RecursiveItemCount") WatchedEpisodes = 0 if userData.get("UnplayedItemCount")==None else TotalEpisodes-int(userData.get("UnplayedItemCount")) UnWatchedEpisodes = 0 if userData.get("UnplayedItemCount")==None else int(userData.get("UnplayedItemCount")) NumEpisodes = TotalEpisodes tempEpisode = "" if (item.get("IndexNumber") != None): episodeNum = item.get("IndexNumber") if episodeNum < 10: tempEpisode = "0" + str(episodeNum) else: tempEpisode = str(episodeNum) tempSeason = "" if (str(item.get("ParentIndexNumber")) != None): tempSeason = str(item.get("ParentIndexNumber")) if item.get("ParentIndexNumber") < 10: tempSeason = "0" + tempSeason if item.get("SeriesName") != None: temp=item.get("SeriesName") SeriesName=temp.encode('utf-8') else: SeriesName='' return {'TotalSeasons' : str(TotalSeasons), 'TotalEpisodes' : str(TotalEpisodes), 'WatchedEpisodes' : str(WatchedEpisodes), 'UnWatchedEpisodes': str(UnWatchedEpisodes), 'NumEpisodes' : str(NumEpisodes), 'Season' : tempSeason, 'Episode' : tempEpisode, 'SeriesName' : SeriesName } def getDateCreated(self, item): try: dateadded = item['DateCreated'] dateadded = dateadded.split('.')[0].replace('T', " ") except: dateadded = None return dateadded def getPremiereDate(self, item): try: premiere = item['PremiereDate'] premiere = premiere.split('.')[0].replace('T', " ") except: premiere = None return premiere def getTagline(self, item): try: tagline = item['Taglines'][0] except: tagline = None return tagline def getProvider(self, item, providername): # Provider Name: imdb or tvdb try: if "imdb" in providername: provider = item['ProviderIds']['Imdb'] elif "tvdb" in providername: provider = item['ProviderIds']['Tvdb'] elif "musicBrainzArtist" in providername: provider = item['ProviderIds']['MusicBrainzArtist'] elif "musicBrainzAlbum" in providername: provider = item['ProviderIds']['MusicBrainzAlbum'] elif "musicBrainzTrackId" in providername: provider = item['ProviderIds']['MusicBrainzTrackId'] except: provider = None return provider def getCountry(self, item): try: country = item['ProductionLocations'][0] except: country = None return country def getMpaa(self, item): # Convert more complex cases mpaa = item.get('OfficialRating', "") if mpaa in ("NR", "UR"): # Kodi seems to not like NR, but will accept Rated Not Rated mpaa = "Rated Not Rated" return mpaa def getAllArtwork(self, item, parentInfo = False): """ Get all artwork, it will return an empty string for the artwork type not found. Artwork type: Primary, Art, Banner, Logo, Thumb, Disc, Backdrop """ username = utils.window('currUser') server = utils.window('server%s' % username) id = item['Id'] artworks = item['ImageTags'] backdrops = item['BackdropImageTags'] maxHeight = 10000 maxWidth = 10000 customquery = "" if utils.settings('compressArt') == "true": customquery = "&Quality=90" if utils.settings('disableCoverArt') == "true": customquery += "&EnableImageEnhancers=false" allartworks = { 'Primary': "", 'Art': "", 'Banner': "", 'Logo': "", 'Thumb': "", 'Disc': "", 'Backdrop': [] } # Process backdrops backdropIndex = 0 for backdroptag in backdrops: artwork = "%s/mediabrowser/Items/%s/Images/Backdrop/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, backdropIndex, maxWidth, maxHeight, backdroptag, customquery) allartworks['Backdrop'].append(artwork) backdropIndex += 1 # Process the rest of the artwork for art in artworks: tag = artworks[art] artwork = "%s/mediabrowser/Items/%s/Images/%s/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, art, maxWidth, maxHeight, tag, customquery) allartworks[art] = artwork # Process parent items if the main item is missing artwork if parentInfo: # Process backdrops if not allartworks['Backdrop']: parentId = item.get('ParentBackdropItemId') if parentId: # If there is a parentId, go through the parent backdrop list parentbackdrops = item['ParentBackdropImageTags'] backdropIndex = 0 for parentbackdroptag in parentbackdrops: artwork = "%s/mediabrowser/Items/%s/Images/Backdrop/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, backdropIndex, maxWidth, maxHeight, parentbackdroptag, customquery) allartworks['Backdrop'].append(artwork) backdropIndex += 1 # Process the rest of the artwork parentartwork = ['Logo', 'Art', 'Thumb'] for parentart in parentartwork: if not allartworks[parentart]: parentId = item.get('Parent%sItemId' % parentart) if parentId: parentTag = item['Parent%sImageTag' % parentart] artwork = "%s/mediabrowser/Items/%s/Images/%s/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, parentart, maxWidth, maxHeight, parentTag, customquery) allartworks[parentart] = artwork # Parent album works a bit differently if not allartworks['Primary']: parentId = item.get('AlbumId') if parentId and item.get('AlbumPrimaryImageTag'): parentTag = item['AlbumPrimaryImageTag'] artwork = "%s/mediabrowser/Items/%s/Images/Primary/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, maxWidth, maxHeight, parentTag, customquery) allartworks['Primary'] = artwork return allartworks def getArtwork(self, data, type, mediaType = "", index = "0", userParentInfo = False): id = data.get("Id") getSeriesData = False userData = data.get("UserData") if type == "tvshow.poster": # Change the Id to the series to get the overall series poster if data.get("Type") == "Season" or data.get("Type")== "Episode": id = data.get("SeriesId") getSeriesData = True elif type == "poster" and data.get("Type") == "Episode" and utils.settings('useSeasonPoster')=='true': # Change the Id to the Season to get the season poster id = data.get("SeasonId") if type == "poster" or type == "tvshow.poster": # Now that the Ids are right, change type to MB3 name type="Primary" if data.get("Type") == "Season": # For seasons: primary (poster), thumb and banner get season art, rest series art if type != "Primary" and type != "Primary2" and type != "Primary3" and type != "Primary4" and type != "Thumb" and type != "Banner" and type!="Thumb3" and type!="Backdrop": id = data.get("SeriesId") getSeriesData = True if data.get("Type") == "Episode": # For episodes: primary (episode thumb) gets episode art, rest series art. if type != "Primary" and type != "Primary2" and type != "Primary3" and type != "Primary4": id = data.get("SeriesId") getSeriesData = True if type =="Primary2" or type=="Primary3" or type=="Primary4": id = data.get("SeasonId") getSeriesData = True if data.get("SeasonUserData") != None: userData = data.get("SeasonUserData") if id == None: id=data.get("Id") imageTag = "e3ab56fe27d389446754d0fb04910a34" # a place holder tag, needs to be in this format originalType = type if type == "Primary2" or type == "Primary3" or type == "Primary4" or type=="SeriesPrimary": type = "Primary" if type == "Backdrop2" or type=="Backdrop3" or type=="BackdropNoIndicators": type = "Backdrop" if type == "Thumb2" or type=="Thumb3": type = "Thumb" if(data.get("ImageTags") != None and data.get("ImageTags").get(type) != None): imageTag = data.get("ImageTags").get(type) if (data.get("Type") == "Episode" or data.get("Type") == "Season") and type=="Logo": imageTag = data.get("ParentLogoImageTag") if (data.get("Type") == "Episode" or data.get("Type") == "Season") and type=="Art": imageTag = data.get("ParentArtImageTag") if (data.get("Type") == "Episode" or data.get("Type") == "Season") and type=="Backdrop": if data.get("BackdropImageTags"): imageTag = data['BackdropImageTags'][0] if (data.get("Type") == "Episode" and originalType=="Thumb3"): imageTag = data.get("SeriesThumbImageTag") if (data.get("Type") == "Season" and originalType=="Thumb3" and imageTag=="e3ab56fe27d389446754d0fb04910a34"): imageTag = data.get("ParentThumbImageTag") id = data.get("SeriesId") # for music we return the parent art if no image exists if (data.get("Type") == "MusicAlbum" or data.get("Type") == "Audio") and type=="Backdrop" and not data.get("BackdropImageTags"): data["BackdropImageTags"] = data.get("ParentBackdropImageTags") id = data.get("ParentBackdropItemId") if (data.get("Type") == "MusicAlbum" or data.get("Type") == "Audio") and type=="Logo" and (not imageTag or imageTag == "e3ab56fe27d389446754d0fb04910a34"): imageTag = data.get("ParentLogoImageTag") id = data.get("ParentLogoItemId") if (data.get("Type") == "MusicAlbum" or data.get("Type") == "Audio") and type=="Art" and (not imageTag or imageTag == "e3ab56fe27d389446754d0fb04910a34"): imageTag = data.get("ParentArtImageTag") id = data.get("ParentArtItemId") query = "" maxHeight = "10000" maxWidth = "10000" height = "" width = "" played = "0" totalbackdrops = 0 if utils.settings('coverArtratio') == "true": if mediaType in ("movie","boxset","tvshow"): if "Primary" in type: # Only force ratio for cover art for main covers aspectratio = data.get("PrimaryImageAspectRatio") width = "&Width=1000" height = "&Height=1480" if originalType =="BackdropNoIndicators" and index == "0" and data.get("BackdropImageTags") != None: totalbackdrops = len(data.get("BackdropImageTags")) if totalbackdrops != 0: index = str(randrange(0,totalbackdrops)) # use the local image proxy server that is made available by this addons service # Load user information set by UserClient WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') server = WINDOW.getProperty('server%s' % username) if utils.settings('compressArt')=='true': query = query + "&Quality=90" if imageTag == None: imageTag = "e3ab56fe27d389446754d0fb04910a34" artwork = "%s/mediabrowser/Items/%s/Images/%s/%s?MaxWidth=%s&MaxHeight=%s%s%s&Format=original&Tag=%s%s" % (server, id, type, index, maxWidth, maxHeight, height, width, imageTag, query) #artwork = "%s/mediabrowser/Items/%s/Images/%s/%s/%s/original/%s/%s/%s?%s" % (server, id, type, index, imageTag, width, height, played, query) <- broken if utils.settings('disableCoverArt')=='true': artwork = artwork + "&EnableImageEnhancers=false" # do not return non-existing images if ( (type!="Backdrop" and imageTag=="e3ab56fe27d389446754d0fb04910a34") | #Remember, this is the placeholder tag, meaning we didn't find a valid tag (type=="Backdrop" and data.get("BackdropImageTags") != None and len(data.get("BackdropImageTags")) == 0) | (type=="Backdrop" and data.get("BackdropImageTag") != None and len(data.get("BackdropImageTag")) == 0) ): if type != "Backdrop" or (type=="Backdrop" and getSeriesData==True and data.get("ParentBackdropImageTags") == None) or (type=="Backdrop" and getSeriesData!=True): artwork='' return artwork def imageUrl(self, id, type, index, width, height): WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') server = WINDOW.getProperty('server%s' % username) # For people image - actors, directors, writers return "%s/mediabrowser/Items/%s/Images/%s?MaxWidth=%s&MaxHeight=%s&Index=%s" % (server, id, type, width, height, index) def getUserArtwork(self, data, type, index = "0"): # Load user information set by UserClient WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') server = WINDOW.getProperty('server%s' % username) id = data.get("Id") artwork = "%s/mediabrowser/Users/%s/Images/%s?Format=original" % (server, id, type) return artwork