jellyfin-kodi/resources/lib/api.py

381 lines
10 KiB
Python
Raw Normal View History

2015-12-24 20:07:00 +00:00
# -*- coding: utf-8 -*-
2016-02-02 01:29:43 +00:00
# Read an api response and convert more complex cases
2015-12-24 20:07:00 +00:00
##################################################################################################
import logging
from utils import settings
##################################################################################################
log = logging.getLogger("EMBY."+__name__)
2015-12-24 20:07:00 +00:00
##################################################################################################
class API():
def __init__(self, item):
2016-06-16 05:43:36 +00:00
2016-02-02 01:29:43 +00:00
# item is the api response
2015-12-24 20:07:00 +00:00
self.item = item
2016-02-02 01:29:43 +00:00
2015-12-24 20:07:00 +00:00
def getUserData(self):
# Default
favorite = False
2016-01-11 18:26:38 +00:00
likes = None
2015-12-24 20:07:00 +00:00
playcount = None
played = False
lastPlayedDate = None
resume = 0
userrating = 0
2015-12-24 20:07:00 +00:00
try:
userdata = self.item['UserData']
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
except KeyError: # No userdata found.
pass
else:
favorite = userdata['IsFavorite']
likes = userdata.get('Likes')
# Userrating is based on likes and favourite
2015-12-24 20:07:00 +00:00
if favorite:
userrating = 5
2015-12-24 20:07:00 +00:00
elif likes:
userrating = 3
2015-12-24 20:07:00 +00:00
elif likes == False:
userrating = 0
2015-12-24 20:07:00 +00:00
else:
userrating = 1
2015-12-24 20:07:00 +00:00
lastPlayedDate = userdata.get('LastPlayedDate')
if lastPlayedDate:
lastPlayedDate = lastPlayedDate.split('.')[0].replace('T', " ")
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
if userdata['Played']:
# Playcount is tied to the watch status
played = True
playcount = userdata['PlayCount']
if playcount == 0:
playcount = 1
if lastPlayedDate is None:
lastPlayedDate = self.getDateCreated()
playbackPosition = userdata.get('PlaybackPositionTicks')
if playbackPosition:
resume = playbackPosition / 10000000.0
return {
'Favorite': favorite,
'Likes': likes,
2015-12-24 20:07:00 +00:00
'PlayCount': playcount,
'Played': played,
'LastPlayedDate': lastPlayedDate,
'Resume': resume,
'UserRating': userrating
2015-12-24 20:07:00 +00:00
}
def getPeople(self):
# Process People
director = []
writer = []
cast = []
try:
people = self.item['People']
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
except KeyError:
pass
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
else:
for person in people:
type = person['Type']
name = person['Name']
if "Director" in type:
director.append(name)
elif "Actor" in type:
cast.append(name)
elif type in ("Writing", "Writer"):
writer.append(name)
return {
'Director': director,
'Writer': writer,
'Cast': cast
}
def getMediaStreams(self):
videotracks = []
audiotracks = []
subtitlelanguages = []
try:
2016-03-31 03:01:37 +00:00
media_streams = self.item['MediaSources'][0]['MediaStreams']
2015-12-24 20:07:00 +00:00
except KeyError:
2016-03-31 03:01:37 +00:00
if not self.item.get("MediaStreams"): return None
media_streams = self.item['MediaStreams']
2015-12-24 20:07:00 +00:00
for media_stream in media_streams:
# Sort through Video, Audio, Subtitle
stream_type = media_stream['Type']
codec = media_stream.get('Codec', "").lower()
profile = media_stream.get('Profile', "").lower()
if stream_type == "Video":
# Height, Width, Codec, AspectRatio, AspectFloat, 3D
track = {
'codec': codec,
2015-12-24 20:07:00 +00:00
'height': media_stream.get('Height'),
'width': media_stream.get('Width'),
2016-03-31 03:01:37 +00:00
'video3DFormat': self.item.get('Video3DFormat'),
'aspect': 1.85
2015-12-24 20:07:00 +00:00
}
try:
2016-03-31 03:01:37 +00:00
container = self.item['MediaSources'][0]['Container'].lower()
2015-12-24 20:07:00 +00:00
except:
container = ""
# Sort codec vs container/profile
if "msmpeg4" in codec:
track['codec'] = "divx"
2015-12-24 20:07:00 +00:00
elif "mpeg4" in codec:
if "simple profile" in profile or not profile:
track['codec'] = "xvid"
2015-12-24 20:07:00 +00:00
elif "h264" in codec:
if container in ("mp4", "mov", "m4v"):
track['codec'] = "avc1"
2015-12-24 20:07:00 +00:00
# Aspect ratio
2016-03-31 03:01:37 +00:00
if self.item.get('AspectRatio'):
2015-12-24 20:07:00 +00:00
# Metadata AR
2016-03-31 03:01:37 +00:00
aspect = self.item['AspectRatio']
2015-12-24 20:07:00 +00:00
else: # File AR
aspect = media_stream.get('AspectRatio', "0")
2015-12-24 20:07:00 +00:00
try:
aspectwidth, aspectheight = aspect.split(':')
track['aspect'] = round(float(aspectwidth) / float(aspectheight), 6)
2016-03-31 03:01:37 +00:00
2015-12-25 00:02:31 +00:00
except (ValueError, ZeroDivisionError):
width = track.get('width')
height = track.get('height')
2015-12-24 20:07:00 +00:00
if width and height:
track['aspect'] = round(float(width / height), 6)
2015-12-25 00:02:31 +00:00
else:
track['aspect'] = 1.85
2016-03-31 03:01:37 +00:00
if self.item.get("RunTimeTicks"):
track['duration'] = self.item.get("RunTimeTicks") / 10000000.0
2015-12-24 20:07:00 +00:00
videotracks.append(track)
elif stream_type == "Audio":
# Codec, Channels, language
track = {
2016-03-31 03:01:37 +00:00
'codec': codec,
2015-12-24 20:07:00 +00:00
'channels': media_stream.get('Channels'),
'language': media_stream.get('Language')
2015-12-24 20:07:00 +00:00
}
if "dca" in codec and "dts-hd ma" in profile:
track['codec'] = "dtshd_ma"
2015-12-24 20:07:00 +00:00
audiotracks.append(track)
elif stream_type == "Subtitle":
# Language
subtitlelanguages.append(media_stream.get('Language', "Unknown"))
return {
2016-03-31 03:01:37 +00:00
'video': videotracks,
2015-12-24 20:07:00 +00:00
'audio': audiotracks,
'subtitle': subtitlelanguages
}
def getRuntime(self):
try:
2016-03-31 03:01:37 +00:00
runtime = self.item['RunTimeTicks'] / 10000000.0
2015-12-24 20:07:00 +00:00
except KeyError:
2016-03-31 03:01:37 +00:00
runtime = self.item.get('CumulativeRunTimeTicks', 0) / 10000000.0
2015-12-24 20:07:00 +00:00
return runtime
def adjustResume(self, resume_seconds):
resume = 0
if resume_seconds:
resume = round(float(resume_seconds), 6)
2016-06-16 05:43:36 +00:00
jumpback = int(settings('resumeJumpBack'))
2015-12-24 20:07:00 +00:00
if resume > jumpback:
# To avoid negative bookmark
resume = resume - jumpback
return resume
def getStudios(self):
# Process Studios
studios = []
try:
2016-03-31 03:01:37 +00:00
studio = self.item['SeriesStudio']
2015-12-24 20:07:00 +00:00
studios.append(self.verifyStudio(studio))
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
except KeyError:
2016-03-31 03:01:37 +00:00
studioList = self.item['Studios']
2015-12-24 20:07:00 +00:00
for studio in studioList:
name = studio['Name']
studios.append(self.verifyStudio(name))
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
return studios
def verifyStudio(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 getChecksum(self):
# Use the etags checksum and userdata
2016-03-31 03:01:37 +00:00
userdata = self.item['UserData']
2015-12-24 20:07:00 +00:00
checksum = "%s%s%s%s%s%s%s" % (
2016-03-31 03:01:37 +00:00
self.item['Etag'],
2015-12-24 20:07:00 +00:00
userdata['Played'],
userdata['IsFavorite'],
userdata.get('Likes',''),
2015-12-24 20:07:00 +00:00
userdata['PlaybackPositionTicks'],
userdata.get('UnplayedItemCount', ""),
userdata.get('LastPlayedDate', "")
)
return checksum
def getGenres(self):
all_genres = ""
2016-03-31 03:01:37 +00:00
genres = self.item.get('Genres', self.item.get('SeriesGenres'))
2015-12-24 20:07:00 +00:00
if genres:
all_genres = " / ".join(genres)
return all_genres
def getDateCreated(self):
try:
dateadded = self.item['DateCreated']
dateadded = dateadded.split('.')[0].replace('T', " ")
except KeyError:
dateadded = None
return dateadded
def getPremiereDate(self):
try:
premiere = self.item['PremiereDate']
premiere = premiere.split('.')[0].replace('T', " ")
except KeyError:
premiere = None
return premiere
def getOverview(self):
try:
overview = self.item['Overview']
overview = overview.replace("\"", "\'")
overview = overview.replace("\n", " ")
overview = overview.replace("\r", " ")
except KeyError:
overview = ""
return overview
def getTagline(self):
try:
tagline = self.item['Taglines'][0]
except IndexError:
tagline = None
return tagline
def getProvider(self, providername):
try:
provider = self.item['ProviderIds'][providername]
except KeyError:
provider = None
return provider
def getMpaa(self):
# Convert more complex cases
mpaa = self.item.get('OfficialRating', "")
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
if mpaa in ("NR", "UR"):
# Kodi seems to not like NR, but will accept Not Rated
mpaa = "Not Rated"
return mpaa
def getCountry(self):
try:
country = self.item['ProductionLocations'][0]
except IndexError:
country = None
return country
def getFilePath(self):
try:
2016-03-31 03:01:37 +00:00
filepath = self.item['Path']
2015-12-24 20:07:00 +00:00
except KeyError:
filepath = ""
else:
if "\\\\" in filepath:
# append smb protocol
filepath = filepath.replace("\\\\", "smb://")
filepath = filepath.replace("\\", "/")
2016-03-31 03:01:37 +00:00
if self.item.get('VideoType'):
videotype = self.item['VideoType']
2015-12-24 20:07:00 +00:00
# Specific format modification
if 'Dvd'in videotype:
filepath = "%s/VIDEO_TS/VIDEO_TS.IFO" % filepath
2016-02-02 01:29:43 +00:00
elif 'BluRay' in videotype:
2015-12-24 20:07:00 +00:00
filepath = "%s/BDMV/index.bdmv" % filepath
2016-03-31 03:01:37 +00:00
2015-12-24 20:07:00 +00:00
if "\\" in filepath:
# Local path scenario, with special videotype
filepath = filepath.replace("/", "\\")
return filepath