diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 513e9e75..0f72d4da 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -52,10 +52,31 @@ LOG = getLogger("PLEX." + __name__) REGEX_IMDB = re_compile(r'''/(tt\d+)''') REGEX_TVDB = re_compile(r'''thetvdb:\/\/(.+?)\?''') + +# Key of library: Plex-identifier. Value represents the Kodi/emby side +PEOPLE_OF_INTEREST = { + 'Director': 'Director', + 'Writer': 'Writer', + 'Role': 'Actor', + 'Producer': 'Producer' +} +# we need to use a little mapping between fanart.tv arttypes and kodi +# artttypes +FANART_TV_TYPES = [ + ("logo", "Logo"), + ("musiclogo", "clearlogo"), + ("disc", "Disc"), + ("clearart", "Art"), + ("banner", "Banner"), + ("clearlogo", "Logo"), + ("background", "fanart"), + ("showbackground", "fanart"), + ("characterart", "characterart") +] ############################################################################### -class API(): +class API(object): """ API(item) @@ -70,47 +91,40 @@ class API(): self.mediastream = None self.server = window('pms_server') - def setPartNumber(self, number=None): + def set_part_number(self, number=None): """ Sets the part number to work with (used to deal with Movie with several parts). """ self.part = number or 0 - def getPartNumber(self): - """ - Returns the current media part number we're dealing with. - """ - return self.part - - def getType(self): + def plex_type(self): """ Returns the type of media, e.g. 'movie' or 'clip' for trailers """ return self.item.attrib.get('type') - def getChecksum(self): + def checksum(self): """ - Returns a string, not int. - + Returns a string, not int. WATCH OUT - time in Plex, not Kodi ;-) """ # Include a letter to prohibit saving as an int! - checksum = "K%s%s" % (self.getRatingKey(), + checksum = "K%s%s" % (self.plex_id(), self.item.attrib.get('updatedAt', '')) return checksum - def getRatingKey(self): + def plex_id(self): """ - Returns the Plex key such as '246922' as a string + Returns the Plex ratingKey such as '246922' as a string or None """ return self.item.attrib.get('ratingKey') - def getKey(self): + def path_and_plex_id(self): """ - Returns the Plex key such as '/library/metadata/246922' or empty string + Returns the Plex key such as '/library/metadata/246922' or None """ - return self.item.attrib.get('key', '') + return self.item.attrib.get('key') def plex_media_streams(self): """ @@ -119,23 +133,23 @@ class API(): """ return self.item[self.mediastream][self.part] - def getFilePath(self, forceFirstMediaStream=False): + def file_path(self, force_first_media=False): """ Returns the direct path to this item, e.g. '\\NAS\movies\movie.mkv' or None - forceFirstMediaStream=True: + force_first_media=True: will always use 1st media stream, e.g. when several different files are present for the same PMS item """ - if self.mediastream is None and forceFirstMediaStream is False: - self.getMediastreamNumber() + if self.mediastream is None and force_first_media is False: + self.mediastream_number() try: - if forceFirstMediaStream is False: + if force_first_media is False: ans = self.item[self.mediastream][self.part].attrib['file'] else: ans = self.item[0][self.part].attrib['file'] - except: + except (TypeError, AttributeError, IndexError, KeyError): ans = None if ans is not None: try: @@ -162,14 +176,14 @@ class API(): 1920, 1080) else: - path = self.addPlexCredentialsToUrl( + path = self.attach_plex_token_to_url( '%s%s' % (window('pms_server'), self.item[0][0].attrib['key'])) # Attach Plex id to url to let it be picked up by our playqueue agent # later - return try_encode('%s&plex_id=%s' % (path, self.getRatingKey())) + return try_encode('%s&plex_id=%s' % (path, self.plex_id())) - def getTVShowPath(self): + def tv_show_path(self): """ Returns the direct path to the TV show, e.g. '\\NAS\tv\series' or None @@ -180,13 +194,13 @@ class API(): res = child.attrib.get('path') return res - def getIndex(self): + def season_number(self): """ Returns the 'index' of an PMS XML reply. Depicts e.g. season number. """ return self.item.attrib.get('index') - def getDateCreated(self): + def date_created(self): """ Returns the date when this library item was created. @@ -199,7 +213,7 @@ class API(): res = '2000-01-01 10:00:00' return res - def getViewCount(self): + def viewcount(self): """ Returns the play count for the item as an int or the int 0 if not found """ @@ -208,7 +222,7 @@ class API(): except (KeyError, ValueError): return 0 - def getUserData(self): + def userdata(self): """ Returns a dict with None if a value is missing { @@ -231,13 +245,13 @@ class API(): played = True if playcount else False try: - lastPlayedDate = unix_date_to_kodi(int(item['lastViewedAt'])) + last_played = unix_date_to_kodi(int(item['lastViewedAt'])) except (KeyError, ValueError): - lastPlayedDate = None + last_played = None if state.INDICATE_MEDIA_VERSIONS is True: userrating = 0 - for entry in self.item.findall('./Media'): + for _ in self.item.findall('./Media'): userrating += 1 # Don't show a value of '1' userrating = 0 if userrating == 1 else userrating @@ -255,19 +269,19 @@ class API(): except (KeyError, ValueError): rating = 0.0 - resume, runtime = self.getRuntime() + resume, runtime = self.resume_runtime() return { 'Favorite': favorite, 'PlayCount': playcount, 'Played': played, - 'LastPlayedDate': lastPlayedDate, + 'LastPlayedDate': last_played, 'Resume': resume, 'Runtime': runtime, 'Rating': rating, 'UserRating': userrating } - def getCollections(self): + def collection_list(self): """ Returns a list of PMS collection tags or an empty list """ @@ -278,7 +292,7 @@ class API(): collections.append(child.attrib['tag']) return collections - def getPeople(self): + def people(self): """ Returns a dict of lists of people found. { @@ -312,7 +326,7 @@ class API(): 'Producer': producer } - def getPeopleList(self): + def people_list(self): """ Returns a list of people from item, with a list item of the form { @@ -324,36 +338,26 @@ class API(): } """ people = [] - # Key of library: Plex-identifier. Value represents the Kodi/emby side - people_of_interest = { - 'Director': 'Director', - 'Writer': 'Writer', - 'Role': 'Actor', - 'Producer': 'Producer' - } for child in self.item: - if child.tag in people_of_interest.keys(): + if child.tag in PEOPLE_OF_INTEREST.keys(): name = child.attrib['tag'] name_id = child.attrib['id'] - Type = child.tag - Type = people_of_interest[Type] - + typus = PEOPLE_OF_INTEREST[child.tag] url = child.attrib.get('thumb') - Role = child.attrib.get('role') - + role = child.attrib.get('role') people.append({ 'Name': name, - 'Type': Type, + 'Type': typus, 'Id': name_id, 'imageurl': url }) if url: people[-1].update({'imageurl': url}) - if Role: - people[-1].update({'Role': Role}) + if role: + people[-1].update({'Role': role}) return people - def getGenres(self): + def genre_list(self): """ Returns a list of genres found. (Not a string) """ @@ -363,10 +367,7 @@ class API(): genre.append(child.attrib['tag']) return genre - def getGuid(self): - return self.item.attrib.get('guid') - - def getProvider(self, providername=None): + def provider(self, providername=None): """ providername: e.g. 'imdb', 'tvdb' @@ -393,10 +394,10 @@ class API(): provider = None return provider - def getTitle(self): + def titles(self): """ Returns an item's name/title or "Missing Title Name". - Output: + Output is the tuple title, sorttitle sorttitle = title, if no sorttitle is found @@ -405,19 +406,19 @@ class API(): sorttitle = self.item.attrib.get('titleSort', title) return title, sorttitle - def getPlot(self): + def plot(self): """ Returns the plot or None. """ return self.item.attrib.get('summary', None) - def getTagline(self): + def tagline(self): """ Returns a shorter tagline or None """ return self.item.attrib.get('tagline', None) - def getAudienceRating(self): + def audience_rating(self): """ Returns the audience rating, 'rating' itself or 0.0 """ @@ -430,13 +431,13 @@ class API(): res = 0.0 return res - def getYear(self): + def year(self): """ Returns the production(?) year ("year") or None """ return self.item.attrib.get('year', None) - def getResume(self): + def resume_point(self): """ Returns the resume point of time in seconds as int. 0 if not found """ @@ -446,13 +447,13 @@ class API(): resume = 0.0 return int(resume * v.PLEX_TO_KODI_TIMEFACTOR) - def getRuntime(self): + def resume_runtime(self): """ Resume point of time and runtime/totaltime in rounded to seconds. Time from Plex server is measured in milliseconds. Kodi: seconds - Output: + Output is the tuple: resume, runtime as ints. 0 if not found """ item = self.item.attrib @@ -470,7 +471,7 @@ class API(): resume = int(resume * v.PLEX_TO_KODI_TIMEFACTOR) return resume, runtime - def getMpaa(self): + def content_rating(self): """ Get the content rating or None """ @@ -481,7 +482,7 @@ class API(): mpaa = "Rated Not Rated" return mpaa - def getCountry(self): + def country_list(self): """ Returns a list of all countries found in item. """ @@ -491,27 +492,31 @@ class API(): country.append(child.attrib['tag']) return country - def getPremiereDate(self): + def premiere_date(self): """ Returns the "originallyAvailableAt" or None """ return self.item.attrib.get('originallyAvailableAt') - def getMusicStudio(self): - return self.item.attrib.get('studio', '') + def music_studio(self): + """ + Returns the 'studio' or None + """ + return self.item.attrib.get('studio') - def getStudios(self): + def music_studio_list(self): """ Returns a list with a single entry for the studio, or an empty list """ studio = [] try: - studio.append(self.getStudio(self.item.attrib['studio'])) + studio.append(self.replace_studio(self.item.attrib['studio'])) except KeyError: pass return studio - def getStudio(self, studioName): + @staticmethod + def replace_studio(studio_name): """ Convert studio for Kodi to properly detect them """ @@ -522,21 +527,24 @@ class API(): 'showcase (ca)': "Showcase", 'wgn america': "WGN" } - return studios.get(studioName.lower(), studioName) + return studios.get(studio_name.lower(), studio_name) - def joinList(self, listobject): + @staticmethod + def list_to_string(listobject): """ - Smart-joins the listobject into a single string using a " / " - separator. + Smart-joins the listobject into a single string using a " / " separator. If the list is empty, smart_join returns an empty string. """ string = " / ".join(listobject) return string - def getParentRatingKey(self): - return self.item.attrib.get('parentRatingKey', '') + def parent_plex_id(self): + """ + Returns the 'parentRatingKey' as a string or None + """ + return self.item.attrib.get('parentRatingKey') - def getEpisodeDetails(self): + def episode_data(self): """ Call on a single episode. @@ -548,29 +556,13 @@ class API(): Episode number, Plex: 'index' ] """ - item = self.item.attrib - key = item.get('grandparentRatingKey') - title = item.get('grandparentTitle') - season = item.get('parentIndex') - episode = item.get('index') - return key, title, season, episode + return (self.item.get('grandparentRatingKey'), + self.item.get('grandparentTitle'), + self.item.get('parentIndex'), + self.item.get('index')) - def addPlexHeadersToUrl(self, url, arguments={}): - """ - Takes an URL and optional arguments (also to be URL-encoded); returns - an extended URL with e.g. the Plex token included. - - arguments overrule everything - """ - xargs = client.getXArgsDeviceInfo() - xargs.update(arguments) - if '?' not in url: - url = "%s?%s" % (url, urlencode(xargs)) - else: - url = "%s&%s" % (url, urlencode(xargs)) - return url - - def addPlexCredentialsToUrl(self, url): + @staticmethod + def attach_plex_token_to_url(url): """ Returns an extended URL with the Plex token included as 'X-Plex-Token=' @@ -584,7 +576,7 @@ class API(): url = "%s&X-Plex-Token=%s" % (url, window('pms_token')) return url - def getItemId(self): + def item_id(self): """ Returns current playQueueItemID or if unsuccessful the playListItemID If not found, None is returned @@ -598,7 +590,7 @@ class API(): answ = None return answ - def getDataFromPartOrMedia(self, key): + def _data_from_part_or_media(self, key): """ Retrieves XML data 'key' first from the active part. If unsuccessful, tries to retrieve the data from the Media response part. @@ -617,7 +609,7 @@ class API(): value = None return value - def getVideoCodec(self): + def video_codec(self): """ Returns the video codec and resolution for the child and part selected. If any data is not found on a part-level, the Media-level data is @@ -637,21 +629,21 @@ class API(): } """ answ = { - 'videocodec': self.getDataFromPartOrMedia('videoCodec'), - 'resolution': self.getDataFromPartOrMedia('videoResolution'), - 'height': self.getDataFromPartOrMedia('height'), - 'width': self.getDataFromPartOrMedia('width'), - 'aspectratio': self.getDataFromPartOrMedia('aspectratio'), - 'bitrate': self.getDataFromPartOrMedia('bitrate'), - 'container': self.getDataFromPartOrMedia('container'), + 'videocodec': self._data_from_part_or_media('videoCodec'), + 'resolution': self._data_from_part_or_media('videoResolution'), + 'height': self._data_from_part_or_media('height'), + 'width': self._data_from_part_or_media('width'), + 'aspectratio': self._data_from_part_or_media('aspectratio'), + 'bitrate': self._data_from_part_or_media('bitrate'), + 'container': self._data_from_part_or_media('container'), } try: - answ['bitDepth'] = self.item[0][self.part][self.mediastream].attrib.get('bitDepth') - except: + answ['bitDepth'] = self.item[0][self.part][self.mediastream].get('bitDepth') + except (TypeError, AttributeError, KeyError, IndexError): answ['bitDepth'] = None return answ - def getExtras(self): + def extras_list(self): """ Currently ONLY returns the very first trailer found! @@ -676,10 +668,10 @@ class API(): return elements for extra in extras: try: - extraType = int(extra.attrib['extraType']) + typus = int(extra.attrib['extraType']) except (KeyError, TypeError): - extraType = None - if extraType != 1: + typus = None + if typus != 1: continue duration = float(extra.attrib.get('duration', 0.0)) elements.append({ @@ -687,14 +679,14 @@ class API(): 'title': extra.attrib.get('title'), 'thumb': extra.attrib.get('thumb'), 'duration': int(duration * v.PLEX_TO_KODI_TIMEFACTOR), - 'extraType': extraType, + 'extraType': typus, 'originallyAvailableAt': extra.attrib.get('originallyAvailableAt'), 'year': extra.attrib.get('year') }) break return elements - def getMediaStreams(self): + def mediastreams(self): """ Returns the media streams for metadata purposes @@ -744,7 +736,7 @@ class API(): track['width'] = stream.get('width') # track['Video3DFormat'] = item.get('Video3DFormat') track['aspect'] = stream.get('aspectRatio', aspect) - track['duration'] = self.getRuntime()[1] + track['duration'] = self.resume_runtime()[1] track['video3DFormat'] = None videotracks.append(track) elif media_type == 2: # Audio streams @@ -768,21 +760,22 @@ class API(): 'subtitle': subtitlelanguages } - def __getOneArtwork(self, entry): + def _one_artwork(self, entry): if entry not in self.item.attrib: return '' artwork = self.item.attrib[entry] if artwork.startswith('http'): pass else: - artwork = self.addPlexCredentialsToUrl( - "%s/photo/:/transcode?width=4000&height=4000&minSize=1&upscale=0&url=%s" % (self.server, artwork)) + artwork = self.attach_plex_token_to_url( + '%s/photo/:/transcode?width=4000&height=4000&' + 'minSize=1&upscale=0&url=%s' % (self.server, artwork)) return artwork - def getAllArtwork(self, parentInfo=False): + def artwork(self, parent_info=False): """ Gets the URLs to the Plex artwork, or empty string if not found. - parentInfo=True will check for parent's artwork if None is found + parent_info=True will check for parent's artwork if None is found Output: { @@ -806,25 +799,25 @@ class API(): } # Process backdrops # Get background artwork URL - allartworks['Backdrop'].append(self.__getOneArtwork('art')) + allartworks['Backdrop'].append(self._one_artwork('art')) # Get primary "thumb" pictures: - allartworks['Primary'] = self.__getOneArtwork('thumb') + allartworks['Primary'] = self._one_artwork('thumb') # Banner (usually only on tv series level) - allartworks['Banner'] = self.__getOneArtwork('banner') + allartworks['Banner'] = self._one_artwork('banner') # For e.g. TV shows, get series thumb - allartworks['Thumb'] = self.__getOneArtwork('grandparentThumb') + allartworks['Thumb'] = self._one_artwork('grandparentThumb') # Process parent items if the main item is missing artwork - if parentInfo: + if parent_info: # Process parent backdrops if not allartworks['Backdrop']: allartworks['Backdrop'].append( - self.__getOneArtwork('parentArt')) + self._one_artwork('parentArt')) if not allartworks['Primary']: - allartworks['Primary'] = self.__getOneArtwork('parentThumb') + allartworks['Primary'] = self._one_artwork('parentThumb') return allartworks - def getFanartArtwork(self, allartworks, parentInfo=False): + def fanart_artwork(self, allartworks): """ Downloads additional fanart from third party sources (well, link to fanart only). @@ -839,12 +832,12 @@ class API(): 'Backdrop': [] } """ - externalId = self.getExternalItemId() - if externalId is not None: - allartworks = self.getFanartTVArt(externalId, allartworks) + external_id = self.retrieve_external_item_id() + if external_id is not None: + allartworks = self.lookup_fanart_tv(external_id, allartworks) return allartworks - def getExternalItemId(self, collection=False): + def retrieve_external_item_id(self, collection=False): """ Returns the item's IMDB id for movies or tvdb id for TV shows @@ -857,23 +850,23 @@ class API(): """ item = self.item.attrib media_type = item.get('type') - mediaId = None + media_id = None # Return the saved Plex id's, if applicable # Always seek collection's ids since not provided by PMS if collection is False: if media_type == v.PLEX_TYPE_MOVIE: - mediaId = self.getProvider('imdb') + media_id = self.provider('imdb') elif media_type == v.PLEX_TYPE_SHOW: - mediaId = self.getProvider('tvdb') - if mediaId is not None: - return mediaId + media_id = self.provider('tvdb') + if media_id is not None: + return media_id LOG.info('Plex did not provide ID for IMDB or TVDB. Start ' 'lookup process') else: LOG.info('Start movie set/collection lookup on themoviedb using %s', item.get('title', '')) - apiKey = settings('themoviedbAPIKey') + api_key = settings('themoviedbAPIKey') if media_type == v.PLEX_TYPE_SHOW: media_type = 'tv' title = item.get('title', '') @@ -882,7 +875,7 @@ class API(): title = sub(r'\s*\(\d{4}\)$', '', title, count=1) url = 'https://api.themoviedb.org/3/search/%s' % media_type parameters = { - 'api_key': apiKey, + 'api_key': api_key, 'language': v.KODILANGUAGE, 'query': try_encode(title) } @@ -892,7 +885,7 @@ class API(): timeout=7) try: data.get('test') - except: + except AttributeError: LOG.error('Could not download data from FanartTV') return if data.get('results') is None: @@ -901,18 +894,18 @@ class API(): return year = item.get('year') - matchFound = None + match_found = None # find year match if year is not None: for entry in data["results"]: if year in entry.get("first_air_date", ""): - matchFound = entry + match_found = entry break elif year in entry.get("release_date", ""): - matchFound = entry + match_found = entry break # find exact match based on title, if we haven't found a year match - if matchFound is None: + if match_found is None: LOG.info('No themoviedb match found using year %s', year) replacements = ( ' ', @@ -928,53 +921,53 @@ class API(): title_alt = title.lower() name_alt = name.lower() org_name_alt = original_name.lower() - for replaceString in replacements: - title_alt = title_alt.replace(replaceString, '') - name_alt = name_alt.replace(replaceString, '') - org_name_alt = org_name_alt.replace(replaceString, '') + for replace_string in replacements: + title_alt = title_alt.replace(replace_string, '') + name_alt = name_alt.replace(replace_string, '') + org_name_alt = org_name_alt.replace(replace_string, '') if name == title or original_name == title: # match found for exact title name - matchFound = entry + match_found = entry break elif (name.split(" (")[0] == title or title_alt == name_alt or title_alt == org_name_alt): # match found with substituting some stuff - matchFound = entry + match_found = entry break # if a match was not found, we accept the closest match from TMDB - if matchFound is None and len(data.get("results")) > 0: + if match_found is None and len(data.get("results")): LOG.info('Using very first match from themoviedb') - matchFound = entry = data.get("results")[0] + match_found = entry = data.get("results")[0] - if matchFound is None: + if match_found is None: LOG.info('Still no themoviedb match for type: %s, title: %s, ' 'year: %s', media_type, title, year) LOG.debug('themoviedb answer was %s', data['results']) return LOG.info('Found themoviedb match for %s: %s', - item.get('title'), matchFound) + item.get('title'), match_found) - tmdbId = str(entry.get("id", "")) - if tmdbId == '': + tmdb_id = str(entry.get("id", "")) + if tmdb_id == '': LOG.error('No themoviedb ID found, aborting') return if media_type == "multi" and entry.get("media_type"): media_type = entry.get("media_type") name = entry.get("name", entry.get("title")) - # lookup external tmdbId and perform artwork lookup on fanart.tv + # lookup external tmdb_id and perform artwork lookup on fanart.tv parameters = { - 'api_key': apiKey + 'api_key': api_key } for language in [v.KODILANGUAGE, "en"]: parameters['language'] = language if media_type == "movie": - url = 'https://api.themoviedb.org/3/movie/%s' % tmdbId + url = 'https://api.themoviedb.org/3/movie/%s' % tmdb_id parameters['append_to_response'] = 'videos' elif media_type == "tv": - url = 'https://api.themoviedb.org/3/tv/%s' % tmdbId + url = 'https://api.themoviedb.org/3/tv/%s' % tmdb_id parameters['append_to_response'] = 'external_ids,videos' data = DU().downloadUrl(url, authenticate=False, @@ -982,24 +975,24 @@ class API(): timeout=7) try: data.get('test') - except: + except AttributeError: LOG.error('Could not download %s with parameters %s', url, parameters) continue if collection is False: if data.get("imdb_id") is not None: - mediaId = str(data.get("imdb_id")) + media_id = str(data.get("imdb_id")) break if data.get("external_ids") is not None: - mediaId = str(data["external_ids"].get("tvdb_id")) + media_id = str(data["external_ids"].get("tvdb_id")) break else: if data.get("belongs_to_collection") is None: continue - mediaId = str(data.get("belongs_to_collection").get("id")) + media_id = str(data.get("belongs_to_collection").get("id")) LOG.debug('Retrieved collections tmdb id %s for %s', - mediaId, title) - url = 'https://api.themoviedb.org/3/collection/%s' % mediaId + media_id, title) + url = 'https://api.themoviedb.org/3/collection/%s' % media_id data = DU().downloadUrl(url, authenticate=False, parameters=parameters, @@ -1011,17 +1004,19 @@ class API(): 'the language %s', title, language) continue else: - poster = 'https://image.tmdb.org/t/p/original%s' % data.get('poster_path') - background = 'https://image.tmdb.org/t/p/original%s' % data.get('backdrop_path') - mediaId = mediaId, poster, background + poster = ('https://image.tmdb.org/t/p/original%s' % + data.get('poster_path')) + background = ('https://image.tmdb.org/t/p/original%s' % + data.get('backdrop_path')) + media_id = media_id, poster, background break - return mediaId + return media_id - def getFanartTVArt(self, mediaId, allartworks, setInfo=False): + def lookup_fanart_tv(self, media_id, allartworks, set_info=False): """ perform artwork lookup on fanart.tv - mediaId: IMDB id for movies, tvdb id for TV shows + media_id: IMDB id for movies, tvdb id for TV shows """ item = self.item.attrib api_key = settings('FanArtTVAPIKey') @@ -1031,10 +1026,10 @@ class API(): if typus == "movie": url = 'http://webservice.fanart.tv/v3/movies/%s?api_key=%s' \ - % (mediaId, api_key) + % (media_id, api_key) elif typus == 'tv': url = 'http://webservice.fanart.tv/v3/tv/%s?api_key=%s' \ - % (mediaId, api_key) + % (media_id, api_key) else: # Not supported artwork return allartworks @@ -1043,30 +1038,18 @@ class API(): timeout=15) try: data.get('test') - except: + except AttributeError: LOG.error('Could not download data from FanartTV') return allartworks - # we need to use a little mapping between fanart.tv arttypes and kodi - # artttypes - fanartTVTypes = [ - ("logo", "Logo"), - ("musiclogo", "clearlogo"), - ("disc", "Disc"), - ("clearart", "Art"), - ("banner", "Banner"), - ("clearlogo", "Logo"), - ("background", "fanart"), - ("showbackground", "fanart"), - ("characterart", "characterart") - ] - if typus == "artist": - fanartTVTypes.append(("thumb", "folder")) - else: - fanartTVTypes.append(("thumb", "Thumb")) + fanart_tv_types = list(FANART_TV_TYPES) - if setInfo: - fanartTVTypes.append(("poster", "Primary")) + if typus == "artist": + fanart_tv_types.append(("thumb", "folder")) + else: + fanart_tv_types.append(("thumb", "Thumb")) + if set_info: + fanart_tv_types.append(("poster", "Primary")) prefixes = ( "hd" + typus, @@ -1074,7 +1057,7 @@ class API(): typus, "", ) - for fanarttype in fanartTVTypes: + for fanarttype in fanart_tv_types: # Skip the ones we already have if allartworks.get(fanarttype[1]): continue @@ -1112,7 +1095,7 @@ class API(): fanartcount += 1 return allartworks - def getSetArtwork(self, parentInfo=False): + def set_artwork(self): """ Gets the URLs to the Plex artwork, or empty string if not found. parentInfo=True will check for parent's artwork if None is found @@ -1142,30 +1125,32 @@ class API(): # Plex does not get much artwork - go ahead and get the rest from # fanart tv only for movie or tv show - externalId = self.getExternalItemId(collection=True) - if externalId is not None: + external_id = self.retrieve_external_item_id(collection=True) + if external_id is not None: try: - externalId, poster, background = externalId + external_id, poster, background = external_id except TypeError: poster, background = None, None if poster is not None: allartworks['Primary'] = poster if background is not None: allartworks['Backdrop'].append(background) - allartworks = self.getFanartTVArt(externalId, allartworks, True) + allartworks = self.lookup_fanart_tv(external_id, + allartworks, + set_info=True) else: LOG.info('Did not find a set/collection ID on TheMovieDB using %s.' - ' Artwork will be missing.', self.getTitle()[0]) + ' Artwork will be missing.', self.titles()[0]) return allartworks - def shouldStream(self): + def should_stream(self): """ Returns True if the item's 'optimizedForStreaming' is set, False other- wise """ return self.item[0].attrib.get('optimizedForStreaming') == '1' - def getMediastreamNumber(self): + def mediastream_number(self): """ Returns the Media stream as an int (mostly 0). Will let the user choose if several media streams are present for a PMS item (if settings are @@ -1176,10 +1161,10 @@ class API(): for entry in self.item.findall('./Media'): count += 1 if (count > 1 and ( - (self.getType() != 'clip' and + (self.plex_type() != 'clip' and settings('bestQuality') == 'false') or - (self.getType() == 'clip' and + (self.plex_type() == 'clip' and settings('bestTrailer') == 'false'))): # Several streams/files available. dialoglist = [] @@ -1222,7 +1207,7 @@ class API(): self.mediastream = media return media - def getTranscodeVideoPath(self, action, quality=None): + def transcode_video_path(self, action, quality=None): """ To be called on a VIDEO level of PMS xml response! @@ -1244,7 +1229,7 @@ class API(): TODO: mediaIndex """ if self.mediastream is None: - self.getMediastreamNumber() + self.mediastream_number() if quality is None: quality = {} xargs = client.getXArgsDeviceInfo() @@ -1269,7 +1254,7 @@ class API(): } # Path/key to VIDEO item of xml PMS response is needed, not part path = self.item.attrib['key'] - transcodePath = self.server + \ + transcode_path = self.server + \ '/video/:/transcode/universal/start.m3u8?' args = { 'audioBoost': settings('audioBoost'), @@ -1285,17 +1270,19 @@ class API(): 'hasMDE': 1, 'location': 'lan', 'subtitleSize': settings('subtitleSize') - # 'copyts': 1, - # 'offset': 0, # Resume point } # Look like Android to let the PMS use the transcoding profile xargs.update(headers) LOG.debug("Setting transcode quality to: %s", quality) args.update(quality) - url = transcodePath + urlencode(xargs) + '&' + urlencode(args) + url = transcode_path + urlencode(xargs) + '&' + urlencode(args) return url - def externalSubs(self): + def cache_external_subs(self): + """ + Downloads external subtitles temporarily to Kodi and returns a list + of their paths + """ externalsubs = [] try: mediastreams = self.item[0][self.part] @@ -1324,7 +1311,7 @@ class API(): fileindex += 1 # We don't know the language - no need to download else: - path = self.addPlexCredentialsToUrl( + path = self.attach_plex_token_to_url( "%s%s" % (self.server, key)) externalsubs.append(path) kodiindex += 1 @@ -1342,30 +1329,30 @@ class API(): if not exists_dir(v.EXTERNAL_SUBTITLE_TEMP_PATH): makedirs(v.EXTERNAL_SUBTITLE_TEMP_PATH) path = join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename) - r = DU().downloadUrl(url, return_response=True) + response = DU().downloadUrl(url, return_response=True) try: - r.status_code + response.status_code except AttributeError: LOG.error('Could not temporarily download subtitle %s', url) return else: LOG.debug('Writing temp subtitle to %s', path) try: - with open(path, 'wb') as f: - f.write(r.content) + with open(path, 'wb') as filer: + filer.write(response.content) except UnicodeEncodeError: LOG.debug('Need to slugify the filename %s', path) path = slugify(path) - with open(path, 'wb') as f: - f.write(r.content) + with open(path, 'wb') as filer: + filer.write(response.content) return path - def GetKodiPremierDate(self): + def kodi_premiere_date(self): """ Takes Plex' originallyAvailableAt of the form "yyyy-mm-dd" and returns - Kodi's "dd.mm.yyyy" + Kodi's "dd.mm.yyyy" or None """ - date = self.getPremiereDate() + date = self.premiere_date() if date is None: return try: @@ -1374,156 +1361,157 @@ class API(): date = None return date - def CreateListItemFromPlexItem(self, - listItem=None, - appendShowTitle=False, - appendSxxExx=False): - if self.getType() == v.PLEX_TYPE_PHOTO: - listItem = self.__createPhotoListItem(listItem) + def create_listitem(self, listitem=None, append_show_title=False, + append_sxxexx=False): + """ + Return a xbmcgui.ListItem() for this Plex item + """ + if self.plex_type() == v.PLEX_TYPE_PHOTO: + listitem = self._create_photo_listitem(listitem) # Only set the bare minimum of artwork - listItem.setArt({'icon': 'DefaultPicture.png', - 'fanart': self.__getOneArtwork('thumb')}) + listitem.setArt({'icon': 'DefaultPicture.png', + 'fanart': self._one_artwork('thumb')}) else: - listItem = self.__createVideoListItem(listItem, - appendShowTitle, - appendSxxExx) - self.add_video_streams(listItem) - self.set_listitem_artwork(listItem) - return listItem + listitem = self._create_video_listitem(listitem, + append_show_title, + append_sxxexx) + self.add_video_streams(listitem) + self.set_listitem_artwork(listitem) + return listitem - def __createPhotoListItem(self, listItem=None): + def _create_photo_listitem(self, listitem=None): """ Use for photo items only """ - title, _ = self.getTitle() - if listItem is None: - listItem = ListItem(title) + title, _ = self.titles() + if listitem is None: + listitem = ListItem(title) else: - listItem.setLabel(title) + listitem.setLabel(title) metadata = { - 'date': self.GetKodiPremierDate(), + 'date': self.kodi_premiere_date(), 'size': long(self.item[0][0].attrib.get('size', 0)), 'exif:width': self.item[0].attrib.get('width', ''), 'exif:height': self.item[0].attrib.get('height', ''), } - listItem.setInfo(type='image', infoLabels=metadata) - listItem.setProperty('plot', self.getPlot()) - listItem.setProperty('plexid', self.getRatingKey()) - return listItem + listitem.setInfo(type='image', infoLabels=metadata) + listitem.setProperty('plot', self.plot()) + listitem.setProperty('plexid', self.plex_id()) + return listitem - def __createVideoListItem(self, - listItem=None, - appendShowTitle=False, - appendSxxExx=False): + def _create_video_listitem(self, + listitem=None, + append_show_title=False, + append_sxxexx=False): """ Use for video items only Call on a child level of PMS xml response (e.g. in a for loop) - listItem : existing xbmcgui.ListItem to work with + listitem : existing xbmcgui.ListItem to work with otherwise, a new one is created - appendShowTitle : True to append TV show title to episode title - appendSxxExx : True to append SxxExx to episode title + append_show_title : True to append TV show title to episode title + append_sxxexx : True to append SxxExx to episode title Returns XBMC listitem for this PMS library item """ - title, sorttitle = self.getTitle() - typus = self.getType() + title, sorttitle = self.titles() + typus = self.plex_type() - if listItem is None: - listItem = ListItem(title) + if listitem is None: + listitem = ListItem(title) else: - listItem.setLabel(title) + listitem.setLabel(title) # Necessary; Kodi won't start video otherwise! - listItem.setProperty('IsPlayable', 'true') + listitem.setProperty('IsPlayable', 'true') # Video items, e.g. movies and episodes or clips - people = self.getPeople() - userdata = self.getUserData() + people = self.people() + userdata = self.userdata() metadata = { - 'genre': self.joinList(self.getGenres()), - 'year': self.getYear(), - 'rating': self.getAudienceRating(), + 'genre': self.list_to_string(self.genre_list()), + 'year': self.year(), + 'rating': self.audience_rating(), 'playcount': userdata['PlayCount'], 'cast': people['Cast'], - 'director': self.joinList(people.get('Director')), - 'plot': self.getPlot(), + 'director': self.list_to_string(people.get('Director')), + 'plot': self.plot(), 'sorttitle': sorttitle, 'duration': userdata['Runtime'], - 'studio': self.joinList(self.getStudios()), - 'tagline': self.getTagline(), - 'writer': self.joinList(people.get('Writer')), - 'premiered': self.getPremiereDate(), - 'dateadded': self.getDateCreated(), + 'studio': self.list_to_string(self.music_studio_list()), + 'tagline': self.tagline(), + 'writer': self.list_to_string(people.get('Writer')), + 'premiered': self.premiere_date(), + 'dateadded': self.date_created(), 'lastplayed': userdata['LastPlayedDate'], - 'mpaa': self.getMpaa(), - 'aired': self.getPremiereDate() + 'mpaa': self.content_rating(), + 'aired': self.premiere_date() } # Do NOT set resumetime - otherwise Kodi always resumes at that time # even if the user chose to start element from the beginning - # listItem.setProperty('resumetime', str(userdata['Resume'])) - listItem.setProperty('totaltime', str(userdata['Runtime'])) + # listitem.setProperty('resumetime', str(userdata['Resume'])) + listitem.setProperty('totaltime', str(userdata['Runtime'])) if typus == v.PLEX_TYPE_EPISODE: - key, show, season, episode = self.getEpisodeDetails() + _, show, season, episode = self.episode_data() season = -1 if season is None else int(season) episode = -1 if episode is None else int(episode) metadata['episode'] = episode metadata['season'] = season metadata['tvshowtitle'] = show if season and episode: - listItem.setProperty('episodeno', + listitem.setProperty('episodeno', "s%.2de%.2d" % (season, episode)) - if appendSxxExx is True: + if append_sxxexx is True: title = "S%.2dE%.2d - %s" % (season, episode, title) - listItem.setArt({'icon': 'DefaultTVShows.png'}) - if appendShowTitle is True: + listitem.setArt({'icon': 'DefaultTVShows.png'}) + if append_show_title is True: title = "%s - %s " % (show, title) - if appendShowTitle or appendSxxExx: - listItem.setLabel(title) + if append_show_title or append_sxxexx: + listitem.setLabel(title) elif typus == v.PLEX_TYPE_MOVIE: - listItem.setArt({'icon': 'DefaultMovies.png'}) + listitem.setArt({'icon': 'DefaultMovies.png'}) else: # E.g. clips, trailers, ... - listItem.setArt({'icon': 'DefaultVideo.png'}) + listitem.setArt({'icon': 'DefaultVideo.png'}) - plexId = self.getRatingKey() - listItem.setProperty('plexid', plexId) + plex_id = self.plex_id() + listitem.setProperty('plexid', plex_id) with plexdb.Get_Plex_DB() as plex_db: try: - listItem.setProperty('dbid', - str(plex_db.getItem_byId(plexId)[0])) + listitem.setProperty('dbid', + str(plex_db.getItem_byId(plex_id)[0])) except TypeError: pass # Expensive operation metadata['title'] = title - listItem.setInfo('video', infoLabels=metadata) + listitem.setInfo('video', infoLabels=metadata) try: # Add context menu entry for information screen - listItem.addContextMenuItems([(lang(30032), 'XBMC.Action(Info)',)]) + listitem.addContextMenuItems([(lang(30032), 'XBMC.Action(Info)',)]) except TypeError: # Kodi fuck-up pass - return listItem + return listitem - def add_video_streams(self, listItem): + def add_video_streams(self, listitem): """ Add media stream information to xbmcgui.ListItem """ - for key, value in self.getMediaStreams().iteritems(): + for key, value in self.mediastreams().iteritems(): if value: - listItem.addStreamInfo(key, value) + listitem.addStreamInfo(key, value) - def validatePlayurl(self, path, typus, forceCheck=False, folder=False, - omitCheck=False): + def validate_playurl(self, path, typus, force_check=False, folder=False, + omit_check=False): """ Returns a valid path for Kodi, e.g. with '\' substituted to '\\' in Unicode. Returns None if this is not possible path : Unicode typus : Plex type from PMS xml - forceCheck : Will always try to check validity of path + force_check : Will always try to check validity of path Will also skip confirmation dialog if path not found folder : Set to True if path is a folder - omitCheck : Will entirely omit validity check if True + omit_check : Will entirely omit validity check if True """ if path is None: return None @@ -1537,8 +1525,8 @@ class API(): elif state.REPLACE_SMB_PATH is True: if path.startswith('\\\\'): path = 'smb:' + path.replace('\\', '/') - if ((state.PATH_VERIFIED and forceCheck is False) or - omitCheck is True): + if ((state.PATH_VERIFIED and force_check is False) or + omit_check is True): return path # exist() needs a / or \ at the end to work for directories @@ -1560,20 +1548,21 @@ class API(): check = exists_dir(path) if not check: - if forceCheck is False: + if force_check is False: # Validate the path is correct with user intervention - if self.askToValidate(path): + if self.ask_to_validate(path): state.STOP_SYNC = True path = None state.PATH_VERIFIED = True else: path = None - elif forceCheck is False: + elif force_check is False: # Only set the flag if we were not force-checking the path state.PATH_VERIFIED = True return path - def askToValidate(self, url): + @staticmethod + def ask_to_validate(url): """ Displays a YESNO dialog box: Kodi can't locate file: . Please verify the path. @@ -1593,12 +1582,10 @@ class API(): """ Set all artwork to the listitem """ - allartwork = self.getAllArtwork(parentInfo=True) + allartwork = self.artwork(parent_info=True) arttypes = { 'poster': "Primary", 'tvshow.poster': "Thumb", - 'clearart': "Art", - 'tvshow.clearart': "Art", 'clearart': "Primary", 'tvshow.clearart': "Primary", 'clearlogo': "Logo", @@ -1611,17 +1598,15 @@ class API(): for arttype in arttypes: art = arttypes[arttype] if art == "Backdrop": - try: - # Backdrop is a list, grab the first backdrop - self._set_listitem_artprop(listitem, - arttype, - allartwork[art][0]) - except: - pass + # Backdrop is a list, grab the first backdrop + self._set_listitem_artprop(listitem, + arttype, + allartwork[art][0]) else: self._set_listitem_artprop(listitem, arttype, allartwork[art]) - def _set_listitem_artprop(self, listitem, arttype, path): + @staticmethod + def _set_listitem_artprop(listitem, arttype, path): if arttype in ( 'thumb', 'fanart_image', 'small_poster', 'tiny_poster', 'medium_landscape', 'medium_poster', 'small_fanartimage', @@ -1629,29 +1614,3 @@ class API(): listitem.setProperty(arttype, path) else: listitem.setArt({arttype: path}) - - def set_playback_win_props(self, playurl, listitem): - """ - Set all properties necessary for plugin path playback for listitem - """ - itemtype = self.getType() - userdata = self.getUserData() - - plexitem = "plex_%s" % playurl - window('%s.runtime' % plexitem, value=str(userdata['Runtime'])) - window('%s.type' % plexitem, value=itemtype) - state.PLEX_IDS[try_decode(playurl)] = self.getRatingKey() - # window('%s.itemid' % plexitem, value=self.getRatingKey()) - window('%s.playcount' % plexitem, value=str(userdata['PlayCount'])) - - if itemtype == v.PLEX_TYPE_EPISODE: - window('%s.refreshid' % plexitem, value=self.getParentRatingKey()) - else: - window('%s.refreshid' % plexitem, value=self.getRatingKey()) - - # Append external subtitles to stream - playmethod = window('%s.playmethod' % plexitem) - # Direct play automatically appends external - # BUT: Plex may add additional subtitles NOT lying right next to video - if playmethod in ("DirectStream", "DirectPlay"): - listitem.setSubtitles(self.externalSubs(playurl)) diff --git a/resources/lib/PlexCompanion.py b/resources/lib/PlexCompanion.py index ffd31e07..9b2a5048 100644 --- a/resources/lib/PlexCompanion.py +++ b/resources/lib/PlexCompanion.py @@ -57,10 +57,10 @@ class PlexCompanion(Thread): LOG.error('Could not download Plex metadata for: %s', data) return api = API(xml[0]) - if api.getType() == v.PLEX_TYPE_ALBUM: + if api.plex_type() == v.PLEX_TYPE_ALBUM: LOG.debug('Plex music album detected') PQ.init_playqueue_from_plex_children( - api.getRatingKey(), + api.plex_id(), transient_token=data.get('token')) elif data['containerKey'].startswith('/playQueues/'): _, container_key, _ = ParseContainerKey(data['containerKey']) @@ -70,7 +70,7 @@ class PlexCompanion(Thread): dialog('notification', lang(29999), lang(30128), icon='{error}') return playqueue = PQ.get_playqueue_from_type( - v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()]) + v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.plex_type()]) playqueue.clear() get_playlist_details_from_xml(playqueue, xml) playqueue.plex_transient_token = data.get('token') @@ -84,7 +84,7 @@ class PlexCompanion(Thread): if data.get('offset') != '0': state.RESUMABLE = True state.RESUME_PLAYBACK = True - playback_triage(api.getRatingKey(), api.getType(), resolve=False) + playback_triage(api.plex_id(), api.plex_type(), resolve=False) @staticmethod def _process_node(data): @@ -119,7 +119,7 @@ class PlexCompanion(Thread): return api = API(xml[0]) playqueue = PQ.get_playqueue_from_type( - v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()]) + v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.plex_type()]) PQ.update_playqueue_from_PMS( playqueue, playqueue_id=container_key, diff --git a/resources/lib/context_entry.py b/resources/lib/context_entry.py index b86fffe1..0b1a7e25 100644 --- a/resources/lib/context_entry.py +++ b/resources/lib/context_entry.py @@ -100,7 +100,7 @@ class ContextMenu(object): options.append(OPTIONS['PMS_Play']) if self.kodi_type in v.KODI_VIDEOTYPES: options.append(OPTIONS['Transcode']) - # userdata = self.api.getUserData() + # userdata = self.api.userdata() # if userdata['Favorite']: # # Remove from emby favourites # options.append(OPTIONS['RemoveFav']) diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index b8f5bb26..dd228719 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -194,7 +194,7 @@ def GetSubFolders(nodeindex): ##### LISTITEM SETUP FOR VIDEONODES ##### -def createListItem(item, appendShowTitle=False, appendSxxExx=False): +def createListItem(item, append_show_title=False, append_sxxexx=False): title = item['title'] li = ListItem(title) li.setProperty('IsPlayable', "true") @@ -215,7 +215,7 @@ def createListItem(item, appendShowTitle=False, appendSxxExx=False): if season and episode: li.setProperty('episodeno', "s%.2de%.2d" % (season, episode)) - if appendSxxExx is True: + if append_sxxexx is True: title = "S%.2dE%.2d - %s" % (season, episode, title) if "firstaired" in item: @@ -223,7 +223,7 @@ def createListItem(item, appendShowTitle=False, appendSxxExx=False): if "showtitle" in item: metadata['TVshowTitle'] = item['showtitle'] - if appendShowTitle is True: + if append_show_title is True: title = item['showtitle'] + ' - ' + title if "rating" in item: @@ -375,8 +375,8 @@ def getRecentEpisodes(viewid, mediatype, tagname, limit): # if the addon is called with recentepisodes parameter, # we return the recentepisodes list of the given tagname xbmcplugin.setContent(HANDLE, 'episodes') - appendShowTitle = settings('RecentTvAppendShow') == 'true' - appendSxxExx = settings('RecentTvAppendSeason') == 'true' + append_show_title = settings('RecentTvAppendShow') == 'true' + append_sxxexx = settings('RecentTvAppendSeason') == 'true' # First we get a list of all the TV shows - filtered by tag allshowsIds = set() params = { @@ -402,8 +402,8 @@ def getRecentEpisodes(viewid, mediatype, tagname, limit): for episode in js.get_episodes(params): if episode['tvshowid'] in allshowsIds: listitem = createListItem(episode, - appendShowTitle=appendShowTitle, - appendSxxExx=appendSxxExx) + append_show_title=append_show_title, + append_sxxexx=append_sxxexx) xbmcplugin.addDirectoryItem( handle=HANDLE, url=episode['file'], @@ -501,7 +501,7 @@ def getExtraFanArt(plexid, plexPath): return xbmcplugin.endOfDirectory(HANDLE) api = API(xml[0]) - backdrops = api.getAllArtwork()['Backdrop'] + backdrops = api.artwork()['Backdrop'] for count, backdrop in enumerate(backdrops): # Same ordering as in artwork fanartFile = try_encode(join(fanartDir, "fanart%.3d.jpg" % count)) @@ -536,8 +536,8 @@ def getOnDeck(viewid, mediatype, tagname, limit): limit: Max. number of items to retrieve, e.g. 50 """ xbmcplugin.setContent(HANDLE, 'episodes') - appendShowTitle = settings('OnDeckTvAppendShow') == 'true' - appendSxxExx = settings('OnDeckTvAppendSeason') == 'true' + append_show_title = settings('OnDeckTvAppendShow') == 'true' + append_sxxexx = settings('OnDeckTvAppendSeason') == 'true' directpaths = settings('useDirectPaths') == 'true' if settings('OnDeckTVextended') == 'false': # Chances are that this view is used on Kodi startup @@ -558,16 +558,16 @@ def getOnDeck(viewid, mediatype, tagname, limit): limitcounter = 0 for item in xml: api = API(item) - listitem = api.CreateListItemFromPlexItem( - appendShowTitle=appendShowTitle, - appendSxxExx=appendSxxExx) + listitem = api.create_listitem( + append_show_title=append_show_title, + append_sxxexx=append_sxxexx) if directpaths: - url = api.getFilePath() + url = api.file_path() else: params = { 'mode': "play", - 'plex_id': api.getRatingKey(), - 'plex_type': api.getType() + 'plex_id': api.plex_id(), + 'plex_type': api.plex_type() } url = "plugin://plugin.video.plexkodiconnect/tvshows/?%s" \ % urlencode(params) @@ -646,8 +646,8 @@ def getOnDeck(viewid, mediatype, tagname, limit): for episode in episodes: # There will always be only 1 episode ('limit=1') listitem = createListItem(episode, - appendShowTitle=appendShowTitle, - appendSxxExx=appendSxxExx) + append_show_title=append_show_title, + append_sxxexx=append_sxxexx) xbmcplugin.addDirectoryItem(handle=HANDLE, url=episode['file'], listitem=listitem, @@ -823,25 +823,25 @@ def __build_folder(xml_element, plex_section_id=None): def __build_item(xml_element): api = API(xml_element) - listitem = api.CreateListItemFromPlexItem() - resume = api.getResume() + listitem = api.create_listitem() + resume = api.resume_point() if resume: listitem.setProperty('resumetime', str(resume)) - if (api.getKey().startswith('/system/services') or - api.getKey().startswith('http')): + if (api.path_and_plex_id().startswith('/system/services') or + api.path_and_plex_id().startswith('http')): params = { 'mode': 'plex_node', 'key': xml_element.attrib.get('key'), 'offset': xml_element.attrib.get('viewOffset', '0'), } url = "plugin://%s?%s" % (v.ADDON_ID, urlencode(params)) - elif api.getType() == v.PLEX_TYPE_PHOTO: + elif api.plex_type() == v.PLEX_TYPE_PHOTO: url = api.get_picture_path() else: params = { 'mode': 'play', - 'plex_id': api.getRatingKey(), - 'plex_type': api.getType(), + 'plex_id': api.plex_id(), + 'plex_type': api.plex_type(), } url = "plugin://%s?%s" % (v.ADDON_ID, urlencode(params)) xbmcplugin.addDirectoryItem(handle=HANDLE, diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index a8e63238..9c59489a 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -106,17 +106,17 @@ class Items(object): return False api = API(xml[0]) if allartworks is None: - allartworks = api.getAllArtwork() - self.artwork.addArtwork(api.getFanartArtwork(allartworks), + allartworks = api.artwork() + self.artwork.addArtwork(api.fanart_artwork(allartworks), kodi_id, kodi_type, self.kodicursor) # Also get artwork for collections/movie sets if kodi_type == v.KODI_TYPE_MOVIE: - for setname in api.getCollections(): + for setname in api.collection_list(): LOG.debug('Getting artwork for movie set %s', setname) setid = self.kodi_db.createBoxset(setname) - self.artwork.addArtwork(api.getSetArtwork(), + self.artwork.addArtwork(api.set_artwork(), setid, v.KODI_TYPE_SET, self.kodicursor) @@ -133,13 +133,13 @@ class Items(object): for mediaitem in xml: api = API(mediaitem) # Get key and db entry on the Kodi db side - db_item = self.plex_db.getItem_byId(api.getRatingKey()) + db_item = self.plex_db.getItem_byId(api.plex_id()) try: fileid = db_item[1] except TypeError: continue # Grab the user's viewcount, resume points etc. from PMS' answer - userdata = api.getUserData() + userdata = api.userdata() # Write to Kodi DB self.kodi_db.addPlaystate(fileid, userdata['Resume'], @@ -191,7 +191,7 @@ class Movies(Items): # item update # If the item doesn't exist, we'll add it to the database update_item = True - itemid = api.getRatingKey() + itemid = api.plex_id() # Cannot parse XML, abort if not itemid: LOG.error("Cannot parse XML data for movie") @@ -221,35 +221,35 @@ class Movies(Items): movieid) # fileId information - checksum = api.getChecksum() - dateadded = api.getDateCreated() - userdata = api.getUserData() + checksum = api.checksum() + dateadded = api.date_created() + userdata = api.userdata() playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] resume = userdata['Resume'] runtime = userdata['Runtime'] # item details - people = api.getPeople() - writer = api.joinList(people['Writer']) - director = api.joinList(people['Director']) - genres = api.getGenres() - genre = api.joinList(genres) - title, sorttitle = api.getTitle() - plot = api.getPlot() + people = api.people() + writer = api.list_to_string(people['Writer']) + director = api.list_to_string(people['Director']) + genres = api.genre_list() + genre = api.list_to_string(genres) + title, sorttitle = api.titles() + plot = api.plot() shortplot = None - tagline = api.getTagline() + tagline = api.tagline() votecount = None - collections = api.getCollections() + collections = api.collection_list() rating = userdata['Rating'] - year = api.getYear() - premieredate = api.getPremiereDate() - imdb = api.getProvider('imdb') - mpaa = api.getMpaa() - countries = api.getCountry() - country = api.joinList(countries) - studios = api.getStudios() + year = api.year() + premieredate = api.premiere_date() + imdb = api.provider('imdb') + mpaa = api.content_rating() + countries = api.country_list() + country = api.list_to_string(countries) + studios = api.music_studio_list() try: studio = studios[0] except IndexError: @@ -257,7 +257,7 @@ class Movies(Items): # Find one trailer trailer = None - extras = api.getExtras() + extras = api.extras_list() for extra in extras: # Only get 1st trailer element if extra['extraType'] == 1: @@ -269,12 +269,12 @@ class Movies(Items): do_indirect = not state.DIRECT_PATHS if state.DIRECT_PATHS: # Direct paths is set the Kodi way - playurl = api.getFilePath(forceFirstMediaStream=True) + playurl = api.file_path(force_first_media=True) if playurl is None: # Something went wrong, trying to use non-direct paths do_indirect = True else: - playurl = api.validatePlayurl(playurl, api.getType()) + playurl = api.validate_playurl(playurl, api.plex_type()) if playurl is None: return False if "\\" in playurl: @@ -439,13 +439,13 @@ class Movies(Items): # Process countries self.kodi_db.addCountries(movieid, countries, "movie") # Process cast - self.kodi_db.addPeople(movieid, api.getPeopleList(), "movie") + self.kodi_db.addPeople(movieid, api.people_list(), "movie") # Process genres self.kodi_db.addGenres(movieid, genres, "movie") # Process artwork - artwork.addArtwork(api.getAllArtwork(), movieid, "movie", kodicursor) + artwork.addArtwork(api.artwork(), movieid, "movie", kodicursor) # Process stream details - self.kodi_db.addStreams(fileid, api.getMediaStreams(), runtime) + self.kodi_db.addStreams(fileid, api.mediastreams(), runtime) # Process studios self.kodi_db.addStudios(movieid, studios, "movie") # Process tags: view, Plex collection tags @@ -520,7 +520,7 @@ class TVShows(Items): api = API(item) update_item = True - itemid = api.getRatingKey() + itemid = api.plex_id() if not itemid: LOG.error("Cannot parse XML data for TV show") @@ -548,20 +548,20 @@ class TVShows(Items): showid) # fileId information - checksum = api.getChecksum() + checksum = api.checksum() # item details - genres = api.getGenres() - title, sorttitle = api.getTitle() - plot = api.getPlot() - rating = api.getAudienceRating() + genres = api.genre_list() + title, sorttitle = api.titles() + plot = api.plot() + rating = api.audience_rating() votecount = None - premieredate = api.getPremiereDate() - tvdb = api.getProvider('tvdb') - mpaa = api.getMpaa() - genre = api.joinList(genres) - studios = api.getStudios() - collections = api.getCollections() + premieredate = api.premiere_date() + tvdb = api.provider('tvdb') + mpaa = api.content_rating() + genre = api.list_to_string(genres) + studios = api.music_studio_list() + collections = api.collection_list() try: studio = studios[0] except IndexError: @@ -571,14 +571,14 @@ class TVShows(Items): do_indirect = not state.DIRECT_PATHS if state.DIRECT_PATHS: # Direct paths is set the Kodi way - playurl = api.getTVShowPath() + playurl = api.tv_show_path() if playurl is None: # Something went wrong, trying to use non-direct paths do_indirect = True else: - playurl = api.validatePlayurl(playurl, - api.getType(), - folder=True) + playurl = api.validate_playurl(playurl, + api.plex_type(), + folder=True) if playurl is None: return False if "\\" in playurl: @@ -728,12 +728,12 @@ class TVShows(Items): kodicursor.execute(query, (path, None, None, 1, toppathid, pathid)) # Process cast - people = api.getPeopleList() + people = api.people_list() self.kodi_db.addPeople(showid, people, "tvshow") # Process genres self.kodi_db.addGenres(showid, genres, "tvshow") # Process artwork - allartworks = api.getAllArtwork() + allartworks = api.artwork() artwork.addArtwork(allartworks, showid, "tvshow", kodicursor) # Process studios self.kodi_db.addStudios(showid, studios, "tvshow") @@ -748,14 +748,14 @@ class TVShows(Items): Process a single season of a certain tv show """ api = API(item) - plex_id = api.getRatingKey() + plex_id = api.plex_id() if not plex_id: LOG.error('Error getting plex_id for season, skipping') return kodicursor = self.kodicursor plex_db = self.plex_db artwork = self.artwork - seasonnum = api.getIndex() + seasonnum = api.season_number() # Get parent tv show Plex id plexshowid = item.attrib.get('parentRatingKey') # Get Kodi showid @@ -768,13 +768,13 @@ class TVShows(Items): return seasonid = self.kodi_db.addSeason(showid, seasonnum) - checksum = api.getChecksum() + checksum = api.checksum() # Check whether Season already exists plex_dbitem = plex_db.getItem_byId(plex_id) update_item = False if plex_dbitem is None else True # Process artwork - allartworks = api.getAllArtwork() + allartworks = api.artwork() artwork.addArtwork(allartworks, seasonid, "season", kodicursor) if update_item: @@ -804,7 +804,7 @@ class TVShows(Items): # item update # If the item doesn't exist, we'll add it to the database update_item = True - itemid = api.getRatingKey() + itemid = api.plex_id() if not itemid: LOG.error('Error getting itemid for episode, skipping') return @@ -832,26 +832,26 @@ class TVShows(Items): episodeid) # fileId information - checksum = api.getChecksum() - dateadded = api.getDateCreated() - userdata = api.getUserData() + checksum = api.checksum() + dateadded = api.date_created() + userdata = api.userdata() playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] - tvdb = api.getProvider('tvdb') + tvdb = api.provider('tvdb') votecount = None # item details - peoples = api.getPeople() - director = api.joinList(peoples['Director']) - writer = api.joinList(peoples['Writer']) - title, _ = api.getTitle() - plot = api.getPlot() + peoples = api.people() + director = api.list_to_string(peoples['Director']) + writer = api.list_to_string(peoples['Writer']) + title, _ = api.titles() + plot = api.plot() rating = userdata['Rating'] - resume, runtime = api.getRuntime() - premieredate = api.getPremiereDate() + resume, runtime = api.resume_runtime() + premieredate = api.premiere_date() # episode details - series_id, _, season, episode = api.getEpisodeDetails() + series_id, _, season, episode = api.episode_data() if season is None: season = -1 @@ -886,14 +886,14 @@ class TVShows(Items): # GET THE FILE AND PATH ##### do_indirect = not state.DIRECT_PATHS - playurl = api.getFilePath(forceFirstMediaStream=True) + playurl = api.file_path(force_first_media=True) if state.DIRECT_PATHS: # Direct paths is set the Kodi way if playurl is None: # Something went wrong, trying to use non-direct paths do_indirect = True else: - playurl = api.validatePlayurl(playurl, api.getType()) + playurl = api.validate_playurl(playurl, api.plex_type()) if playurl is None: return False if "\\" in playurl: @@ -1081,19 +1081,19 @@ class TVShows(Items): )) kodicursor.execute(query, (pathid, filename, dateadded, fileid)) # Process cast - people = api.getPeopleList() + people = api.people_list() self.kodi_db.addPeople(episodeid, people, "episode") # Process artwork # Wide "screenshot" of particular episode poster = item.attrib.get('thumb') if poster: - poster = api.addPlexCredentialsToUrl( + poster = api.attach_plex_token_to_url( "%s%s" % (self.server, poster)) artwork.addOrUpdateArt( poster, episodeid, "episode", "thumb", kodicursor) # Process stream details - streams = api.getMediaStreams() + streams = api.mediastreams() self.kodi_db.addStreams(fileid, streams, runtime) # Process playstates self.kodi_db.addPlaystate(fileid, @@ -1293,7 +1293,7 @@ class Music(Items): api = API(item) update_item = True - itemid = api.getRatingKey() + itemid = api.plex_id() plex_dbitem = plex_db.getItem_byId(itemid) try: artistid = plex_dbitem[0] @@ -1302,17 +1302,17 @@ class Music(Items): # The artist details ##### lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - dateadded = api.getDateCreated() - checksum = api.getChecksum() + dateadded = api.date_created() + checksum = api.checksum() - name, _ = api.getTitle() - # musicBrainzId = api.getProvider('MusicBrainzArtist') + name, _ = api.titles() + # musicBrainzId = api.provider('MusicBrainzArtist') musicBrainzId = None - genres = ' / '.join(api.getGenres()) - bio = api.getPlot() + genres = ' / '.join(api.genre_list()) + bio = api.plot() # Associate artwork - artworks = api.getAllArtwork(parentInfo=True) + artworks = api.artwork(parent_info=True) thumb = artworks['Primary'] backdrops = artworks['Backdrop'] # List @@ -1381,7 +1381,7 @@ class Music(Items): api = API(item) update_item = True - itemid = api.getRatingKey() + itemid = api.plex_id() if not itemid: LOG.error('Error processing Album, skipping') return @@ -1394,19 +1394,19 @@ class Music(Items): # The album details ##### lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - dateadded = api.getDateCreated() - userdata = api.getUserData() - checksum = api.getChecksum() + dateadded = api.date_created() + userdata = api.userdata() + checksum = api.checksum() - name, _ = api.getTitle() - # musicBrainzId = api.getProvider('MusicBrainzAlbum') + name, _ = api.titles() + # musicBrainzId = api.provider('MusicBrainzAlbum') musicBrainzId = None - year = api.getYear() - self.genres = api.getGenres() + year = api.year() + self.genres = api.genre_list() self.genre = ' / '.join(self.genres) - bio = api.getPlot() + bio = api.plot() rating = userdata['UserRating'] - studio = api.getMusicStudio() + studio = api.music_studio() artistname = item.attrib.get('parentTitle') if not artistname: artistname = item.attrib.get('originalTitle') @@ -1418,7 +1418,7 @@ class Music(Items): self.compilation = 1 break # Associate artwork - artworks = api.getAllArtwork(parentInfo=True) + artworks = api.artwork(parent_info=True) thumb = artworks['Primary'] if thumb: thumb = "%s" % thumb @@ -1576,7 +1576,7 @@ class Music(Items): api = API(item) update_item = True - itemid = api.getRatingKey() + itemid = api.plex_id() if not itemid: LOG.error('Error processing Song; skipping') return @@ -1592,9 +1592,9 @@ class Music(Items): songid = kodicursor.fetchone()[0] + 1 # The song details ##### - checksum = api.getChecksum() - dateadded = api.getDateCreated() - userdata = api.getUserData() + checksum = api.checksum() + dateadded = api.date_created() + userdata = api.userdata() playcount = userdata['PlayCount'] if playcount is None: # This is different to Video DB! @@ -1602,8 +1602,8 @@ class Music(Items): dateplayed = userdata['LastPlayedDate'] # item details - title, _ = api.getTitle() - # musicBrainzId = api.getProvider('MusicBrainzTrackId') + title, _ = api.titles() + # musicBrainzId = api.provider('MusicBrainzTrackId') musicBrainzId = None try: genres = self.genres @@ -1627,8 +1627,8 @@ class Music(Items): track = tracknumber else: track = disc*2**16 + tracknumber - year = api.getYear() - _, duration = api.getRuntime() + year = api.year() + _, duration = api.resume_runtime() rating = userdata['UserRating'] comment = None # Moods @@ -1642,12 +1642,12 @@ class Music(Items): do_indirect = not state.DIRECT_PATHS if state.DIRECT_PATHS: # Direct paths is set the Kodi way - playurl = api.getFilePath(forceFirstMediaStream=True) + playurl = api.file_path(force_first_media=True) if playurl is None: # Something went wrong, trying to use non-direct paths do_indirect = True else: - playurl = api.validatePlayurl(playurl, api.getType()) + playurl = api.validate_playurl(playurl, api.plex_type()) if playurl is None: return False if "\\" in playurl: @@ -1660,7 +1660,7 @@ class Music(Items): if do_indirect: # Plex works a bit differently path = "%s%s" % (self.server, item[0][0].attrib.get('key')) - path = api.addPlexCredentialsToUrl(path) + path = api.attach_plex_token_to_url(path) filename = path.rsplit('/', 1)[1] path = path.replace(filename, '') @@ -1710,7 +1710,7 @@ class Music(Items): itemid) albumid = self.kodi_db.addAlbum( album_name, - api.getProvider('MusicBrainzAlbum')) + api.provider('MusicBrainzAlbum')) plex_db.addReference("%salbum%s" % (itemid, albumid), v.PLEX_TYPE_ALBUM, albumid, @@ -1854,7 +1854,7 @@ class Music(Items): if genres: self.kodi_db.addMusicGenres(songid, genres, v.KODI_TYPE_SONG) # Update artwork - allart = api.getAllArtwork(parentInfo=True) + allart = api.artwork(parent_info=True) artwork.addArtwork(allart, songid, v.KODI_TYPE_SONG, kodicursor) if item.get('parentKey') is None: # Update album artwork diff --git a/resources/lib/kodidb_functions.py b/resources/lib/kodidb_functions.py index 5390c8e6..5c263a30 100644 --- a/resources/lib/kodidb_functions.py +++ b/resources/lib/kodidb_functions.py @@ -766,7 +766,7 @@ class Kodidb_Functions(): ) self.cursor.execute(query, (fileid, 2, subtitletrack)) - def getResumes(self): + def resume_points(self): """ VIDEOS diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index 4f6886f1..06e08f80 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -568,7 +568,7 @@ class LibrarySync(Thread): Output: self.updatelist, self.allPlexElementsId self.updatelist APPENDED(!!) list itemids (Plex Keys as - as received from API.getRatingKey()) + as received from API.plex_id()) One item in this list is of the form: 'itemId': xxx, 'itemType': 'Movies','TVShows', ... @@ -744,7 +744,7 @@ class LibrarySync(Thread): # Pull the list of movies and boxsets in Kodi try: self.allKodiElementsId = dict( - plex_db.getChecksum(v.PLEX_TYPE_MOVIE)) + plex_db.checksum(v.PLEX_TYPE_MOVIE)) except ValueError: self.allKodiElementsId = {} @@ -836,7 +836,7 @@ class LibrarySync(Thread): v.PLEX_TYPE_SEASON, v.PLEX_TYPE_EPISODE): try: - elements = dict(plex.getChecksum(kind)) + elements = dict(plex.checksum(kind)) self.allKodiElementsId.update(elements) # Yet empty/not yet synched except ValueError: @@ -1009,7 +1009,7 @@ class LibrarySync(Thread): with plexdb.Get_Plex_DB() as plex_db: # Pull the list of items already in Kodi try: - elements = dict(plex_db.getChecksum(kind)) + elements = dict(plex_db.checksum(kind)) self.allKodiElementsId.update(elements) # Yet empty/nothing yet synched except ValueError: @@ -1349,7 +1349,7 @@ class LibrarySync(Thread): plex_id) continue api = PlexAPI.API(xml[0]) - userdata = api.getUserData() + userdata = api.userdata() session['duration'] = userdata['Runtime'] session['viewCount'] = userdata['PlayCount'] # Sometimes, Plex tells us resume points in milliseconds and diff --git a/resources/lib/music.py b/resources/lib/music.py index 136c0a7a..726ff0b1 100644 --- a/resources/lib/music.py +++ b/resources/lib/music.py @@ -38,9 +38,9 @@ def excludefromscan_music_folders(): continue for location in library: if location.tag == 'Location': - path = api.validatePlayurl(location.attrib['path'], - typus=v.PLEX_TYPE_ARTIST, - omitCheck=True) + path = api.validate_playurl(location.attrib['path'], + typus=v.PLEX_TYPE_ARTIST, + omit_check=True) paths.append(__turn_to_regex(path)) try: with XmlKodiSetting('advancedsettings.xml', diff --git a/resources/lib/playback.py b/resources/lib/playback.py index 35010d17..4619bcf5 100644 --- a/resources/lib/playback.py +++ b/resources/lib/playback.py @@ -94,7 +94,7 @@ def playback_init(plex_id, plex_type, playqueue): return trailers = False api = API(xml[0]) - if (plex_type == v.PLEX_TYPE_MOVIE and not api.getResume() and + if (plex_type == v.PLEX_TYPE_MOVIE and not api.resume_point() and settings('enableCinema') == "true"): if settings('askCinema') == "true": # "Play trailers?" @@ -144,11 +144,11 @@ def _prep_playlist_stack(xml): for item in xml: api = API(item) if (state.CONTEXT_MENU_PLAY is False and - api.getType() != v.PLEX_TYPE_CLIP): + api.plex_type() != v.PLEX_TYPE_CLIP): # If user chose to play via PMS or force transcode, do not # use the item path stored in the Kodi DB with plexdb.Get_Plex_DB() as plex_db: - plex_dbitem = plex_db.getItem_byId(api.getRatingKey()) + plex_dbitem = plex_db.getItem_byId(api.plex_id()) kodi_id = plex_dbitem[0] if plex_dbitem else None kodi_type = plex_dbitem[4] if plex_dbitem else None else: @@ -156,17 +156,17 @@ def _prep_playlist_stack(xml): kodi_id = None kodi_type = None for part, _ in enumerate(item[0]): - api.setPartNumber(part) + api.set_part_number(part) if kodi_id is None: # Need to redirect again to PKC to conclude playback params = { 'mode': 'play', - 'plex_id': api.getRatingKey(), - 'plex_type': api.getType() + 'plex_id': api.plex_id(), + 'plex_type': api.plex_type() } path = ('plugin://plugin.video.plexkodiconnect?%s' % urlencode(params)) - listitem = api.CreateListItemFromPlexItem() + listitem = api.create_listitem() listitem.setPath(try_encode(path)) else: # Will add directly via the Kodi DB @@ -179,9 +179,9 @@ def _prep_playlist_stack(xml): 'xml_video_element': item, 'listitem': listitem, 'part': part, - 'playcount': api.getViewCount(), - 'offset': api.getResume(), - 'id': api.getItemId() + 'playcount': api.viewcount(), + 'offset': api.resume_point(), + 'id': api.item_id() }) return stack @@ -238,15 +238,15 @@ def conclude_playback(playqueue, pos): if item.xml is not None: # Got a Plex element api = API(item.xml) - api.setPartNumber(item.part) - api.CreateListItemFromPlexItem(listitem) + api.set_part_number(item.part) + api.create_listitem(listitem) playutils = PlayUtils(api, item) playurl = playutils.getPlayUrl() else: playurl = item.file listitem.setPath(try_encode(playurl)) if item.playmethod in ('DirectStream', 'DirectPlay'): - listitem.setSubtitles(api.externalSubs()) + listitem.setSubtitles(api.cache_external_subs()) else: playutils.audio_subtitle_prefs(listitem) if state.RESUME_PLAYBACK is True: @@ -300,9 +300,9 @@ def process_indirect(key, offset, resolve=True): # Todo: implement offset api = API(xml[0]) listitem = PKC_ListItem() - api.CreateListItemFromPlexItem(listitem) + api.create_listitem(listitem) playqueue = PQ.get_playqueue_from_type( - v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()]) + v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.plex_type()]) playqueue.clear() item = PL.Playlist_Item() item.xml = xml[0] diff --git a/resources/lib/playlist_func.py b/resources/lib/playlist_func.py index 041414ea..de480620 100644 --- a/resources/lib/playlist_func.py +++ b/resources/lib/playlist_func.py @@ -280,8 +280,8 @@ def playlist_item_from_xml(playlist, xml_video_element, kodi_id=None, """ item = Playlist_Item() api = API(xml_video_element) - item.plex_id = api.getRatingKey() - item.plex_type = api.getType() + item.plex_id = api.plex_id() + item.plex_type = api.plex_type() try: item.id = xml_video_element.attrib['%sItemID' % playlist.kind] except KeyError: diff --git a/resources/lib/playqueue.py b/resources/lib/playqueue.py index fffd311a..5cf61332 100644 --- a/resources/lib/playqueue.py +++ b/resources/lib/playqueue.py @@ -91,7 +91,7 @@ def init_playqueue_from_plex_children(plex_id, transient_token=None): playqueue.clear() for i, child in enumerate(xml): api = API(child) - PL.add_item_to_playlist(playqueue, i, plex_id=api.getRatingKey()) + PL.add_item_to_playlist(playqueue, i, plex_id=api.plex_id()) playqueue.plex_transient_token = transient_token LOG.debug('Firing up Kodi player') Player().play(playqueue.kodi_pl, None, False, 0) diff --git a/resources/lib/playutils.py b/resources/lib/playutils.py index b4753532..cad9b47e 100644 --- a/resources/lib/playutils.py +++ b/resources/lib/playutils.py @@ -29,18 +29,18 @@ class PlayUtils(): playurl is in unicode! """ - self.api.getMediastreamNumber() + self.api.mediastream_number() playurl = self.isDirectPlay() if playurl is not None: LOG.info("File is direct playing.") self.item.playmethod = 'DirectPlay' elif self.isDirectStream(): LOG.info("File is direct streaming.") - playurl = self.api.getTranscodeVideoPath('DirectStream') + playurl = self.api.transcode_video_path('DirectStream') self.item.playmethod = 'DirectStream' else: LOG.info("File is transcoding.") - playurl = self.api.getTranscodeVideoPath( + playurl = self.api.transcode_video_path( 'Transcode', quality={ 'maxVideoBitrate': self.get_bitrate(), @@ -58,16 +58,16 @@ class PlayUtils(): Returns the path/playurl if we can direct play, None otherwise """ # True for e.g. plex.tv watch later - if self.api.shouldStream() is True: + if self.api.should_stream() is True: LOG.info("Plex item optimized for direct streaming") return # Check whether we have a strm file that we need to throw at Kodi 1:1 - path = self.api.getFilePath() + path = self.api.file_path() if path is not None and path.endswith('.strm'): LOG.info('.strm file detected') - playurl = self.api.validatePlayurl(path, - self.api.getType(), - forceCheck=True) + playurl = self.api.validate_playurl(path, + self.api.plex_type(), + force_check=True) return playurl # set to either 'Direct Stream=1' or 'Transcode=2' # and NOT to 'Direct Play=0' @@ -77,9 +77,9 @@ class PlayUtils(): return if self.mustTranscode(): return - return self.api.validatePlayurl(path, - self.api.getType(), - forceCheck=True) + return self.api.validate_playurl(path, + self.api.plex_type(), + force_check=True) def mustTranscode(self): """ @@ -93,10 +93,10 @@ class PlayUtils(): - video bitrate above specified settings bitrate if the corresponding file settings are set to 'true' """ - if self.api.getType() in (v.PLEX_TYPE_CLIP, v.PLEX_TYPE_SONG): + if self.api.plex_type() in (v.PLEX_TYPE_CLIP, v.PLEX_TYPE_SONG): LOG.info('Plex clip or music track, not transcoding') return False - videoCodec = self.api.getVideoCodec() + videoCodec = self.api.video_codec() LOG.info("videoCodec: %s" % videoCodec) if self.item.force_transcode is True: LOG.info('User chose to force-transcode') @@ -136,7 +136,7 @@ class PlayUtils(): def isDirectStream(self): # Never transcode Music - if self.api.getType() == 'track': + if self.api.plex_type() == 'track': return True # set to 'Transcode=2' if settings('playType') == "2": @@ -232,7 +232,7 @@ class PlayUtils(): """ # Set media and part where we're at if self.api.mediastream is None: - self.api.getMediastreamNumber() + self.api.mediastream_number() try: mediastreams = self.api.plex_media_streams() except (TypeError, IndexError): @@ -302,7 +302,7 @@ class PlayUtils(): stream.attrib['codec'])) # We don't know the language - no need to download else: - path = self.api.addPlexCredentialsToUrl( + path = self.api.attach_plex_token_to_url( "%s%s" % (window('pms_server'), stream.attrib['key'])) downloadable_streams.append(index) diff --git a/resources/lib/plexdb_functions.py b/resources/lib/plexdb_functions.py index 742a461d..ca7949cf 100644 --- a/resources/lib/plexdb_functions.py +++ b/resources/lib/plexdb_functions.py @@ -296,7 +296,7 @@ class Plex_DB_Functions(): self.plexcursor.execute(query, (parent_id, kodi_type,)) return self.plexcursor.fetchall() - def getChecksum(self, plex_type): + def checksum(self, plex_type): """ Returns a list of tuples (plex_id, checksum) for plex_type """