Files
jellycon/resources/lib/utils.py

336 lines
14 KiB
Python

# Gnu General Public License - see LICENSE.TXT
import xbmcaddon
import xbmcgui
import xbmcplugin
import xbmc
import string
import random
import urllib
import json
import binascii
import time
from datetime import datetime
import _strptime
import calendar
import re
from .downloadutils import DownloadUtils
from .simple_logging import SimpleLogging
from .clientinfo import ClientInformation
# hack to get datetime strptime loaded
throwaway = time.strptime('20110101','%Y%m%d')
# define our global download utils
downloadUtils = DownloadUtils()
log = SimpleLogging(__name__)
def get_emby_url(base_url, params):
params["format"] = "json"
param_list = []
for key in params:
if params[key] is not None:
param_list.append(key + "=" + str(params[key]))
param_string = "&".join(param_list)
return base_url + "?" + param_string
###########################################################################
class PlayUtils():
def getPlayUrl(self, id, media_source, force_transcode, play_session_id):
log.debug("getPlayUrl")
addonSettings = xbmcaddon.Addon()
playback_type = addonSettings.getSetting("playback_type")
server = downloadUtils.getServer()
use_https = False
if addonSettings.getSetting('protocol') == "1":
use_https = True
log.debug("use_https: {0}", use_https)
verify_cert = addonSettings.getSetting('verify_cert') == 'true'
log.debug("verify_cert: {0}", verify_cert)
log.debug("playback_type: {0}", playback_type)
if force_transcode:
log.debug("playback_type: FORCED_TRANSCODE")
playurl = None
log.debug("play_session_id: {0}", play_session_id)
media_source_id = media_source.get("Id")
log.debug("media_source_id: {0}", media_source_id)
force_transcode_codecs = []
if addonSettings.getSetting("force_transcode_h265") == "true":
force_transcode_codecs.append("hevc")
force_transcode_codecs.append("h265")
if addonSettings.getSetting("force_transcode_mpeg2") == "true":
force_transcode_codecs.append("mpeg2video")
if addonSettings.getSetting("force_transcode_msmpeg4v3") == "true":
force_transcode_codecs.append("msmpeg4v3")
if addonSettings.getSetting("force_transcode_mpeg4") == "true":
force_transcode_codecs.append("mpeg4")
if len(force_transcode_codecs) > 0:
codec_force_transcode = False
codec_name = ""
streams = media_source.get("MediaStreams", [])
for stream in streams:
if stream.get("Type", "") == "Video":
codec_name = stream.get("Codec", "").lower()
if codec_name in force_transcode_codecs:
codec_force_transcode = True
break
if codec_force_transcode:
log.debug("codec_force_transcode: {0}", codec_name)
playback_type = "2"
if force_transcode:
playback_type = "2"
# transcode
if playback_type == "2":
playback_bitrate = addonSettings.getSetting("playback_bitrate")
log.debug("playback_bitrate: {0}", playback_bitrate)
playback_max_width = addonSettings.getSetting("playback_max_width")
playback_video_force_8 = addonSettings.getSetting("playback_video_force_8") == "true"
clientInfo = ClientInformation()
deviceId = clientInfo.getDeviceId()
bitrate = int(playback_bitrate) * 1000
user_token = downloadUtils.authenticate()
playurl = ("%s/emby/Videos/%s/master.m3u8" +
"?MediaSourceId=%s" +
"&PlaySessionId=%s" +
"&VideoCodec=h264" +
"&AudioCodec=ac3" +
"&MaxAudioChannels=6" +
"&deviceId=%s" +
"&VideoBitrate=%s" +
"&maxWidth=%s")
playurl = playurl % (server, id, media_source_id, play_session_id, deviceId, bitrate, playback_max_width)
if playback_video_force_8:
playurl += "&MaxVideoBitDepth=8"
playurl += "&api_key=" + user_token
if use_https and not verify_cert:
playurl += "|verifypeer=false"
# do direct path playback
elif playback_type == "0":
playurl = media_source.get("Path")
playurl = playurl.replace("\\", "/")
playurl = playurl.strip()
# handle DVD structure
if media_source.get("VideoType") == "Dvd":
playurl = playurl + "/VIDEO_TS/VIDEO_TS.IFO"
elif media_source.get("VideoType") == "BluRay":
playurl = playurl + "/BDMV/index.bdmv"
if playurl.startswith("//"):
smb_username = addonSettings.getSetting('smbusername')
smb_password = addonSettings.getSetting('smbpassword')
if not smb_username:
playurl = "smb://" + playurl[2:]
else:
playurl = "smb://" + smb_username + ':' + smb_password + '@' + playurl[2:]
# do direct http streaming playback
elif playback_type == "1":
playurl = ("%s/emby/Videos/%s/stream" +
"?static=true" +
"&PlaySessionId=%s" +
"&MediaSourceId=%s")
playurl = playurl % (server, id, play_session_id, media_source_id)
user_token = downloadUtils.authenticate()
playurl += "&api_key=" + user_token
if use_https and not verify_cert:
playurl += "|verifypeer=false"
log.debug("Playback URL: {0}", playurl)
return playurl, playback_type
def getStrmDetails(self, media_source):
playurl = None
listitem_props = []
contents = media_source.get('Path').encode('utf-8') # contains contents of strm file with linebreaks
line_break = '\r'
if '\r\n' in contents:
line_break = '\r\n'
elif '\n' in contents:
line_break = '\n'
lines = contents.split(line_break)
for line in lines:
line = line.strip()
log.debug("STRM Line: {0}", line)
if line.startswith('#KODIPROP:'):
match = re.search('#KODIPROP:(?P<item_property>[^=]+?)=(?P<property_value>.+)', line)
if match:
item_property = match.group('item_property')
property_value = match.group('property_value')
log.debug("STRM property found: {0} value: {1}", item_property, property_value)
listitem_props.append((item_property, property_value))
else:
log.debug("STRM #KODIPROP incorrect format")
elif line.startswith('#'):
# unrecognized, treat as comment
log.debug("STRM unrecognized line identifier, ignored")
elif line != '':
playurl = line
log.debug("STRM playback url found")
log.debug("Playback URL: {0} ListItem Properties: {1}", playurl, listitem_props)
return playurl, listitem_props
def getChecksum(item):
userdata = item['UserData']
checksum = "%s_%s_%s_%s_%s_%s_%s" % (
item['Etag'],
userdata['Played'],
userdata['IsFavorite'],
userdata.get('Likes', "-"),
userdata['PlaybackPositionTicks'],
userdata.get('UnplayedItemCount', "-"),
userdata.get("PlayedPercentage", "-")
)
return checksum
def getArt(item, server):
art = {
'thumb': '',
'fanart': '',
'poster': '',
'banner': '',
'clearlogo': '',
'clearart': '',
'discart': '',
'landscape': '',
'tvshow.fanart': '',
'tvshow.poster': '',
'tvshow.clearart': '',
'tvshow.clearlogo': '',
'tvshow.banner': '',
'tvshow.landscape': ''
}
item_id = item["Id"]
image_id = item_id
imageTags = item["ImageTags"]
if imageTags is not None and imageTags["Primary"] is not None:
image_tag = imageTags["Primary"]
art['thumb'] = downloadUtils.getArtwork(item, "Primary", server=server)
item_type = item["Type"]
if item_type == "Genre":
art['poster'] = downloadUtils.getArtwork(item, "Primary", server=server)
elif item_type == "Episode":
art['tvshow.poster'] = downloadUtils.getArtwork(item, "Primary", parent=True, server=server)
#art['poster'] = downloadUtils.getArtwork(item, "Primary", parent=True, server=server)
art['tvshow.clearart'] = downloadUtils.getArtwork(item, "Art", parent=True, server=server)
art['clearart'] = downloadUtils.getArtwork(item, "Art", parent=True, server=server)
art['tvshow.clearlogo'] = downloadUtils.getArtwork(item, "Logo", parent=True, server=server)
art['clearlogo'] = downloadUtils.getArtwork(item, "Logo", parent=True, server=server)
art['tvshow.banner'] = downloadUtils.getArtwork(item, "Banner", parent=True, server=server)
art['banner'] = downloadUtils.getArtwork(item, "Banner", parent=True, server=server)
art['tvshow.landscape'] = downloadUtils.getArtwork(item, "Thumb", parent=True, server=server)
art['landscape'] = downloadUtils.getArtwork(item, "Thumb", parent=True, server=server)
art['tvshow.fanart'] = downloadUtils.getArtwork(item, "Backdrop", parent=True, server=server)
art['fanart'] = downloadUtils.getArtwork(item, "Backdrop", parent=True, server=server)
elif item_type == "Season":
art['tvshow.poster'] = downloadUtils.getArtwork(item, "Primary", parent=True, server=server)
art['season.poster'] = downloadUtils.getArtwork(item, "Primary", parent=False, server=server)
art['poster'] = downloadUtils.getArtwork(item, "Primary", parent=False, server=server)
art['tvshow.clearart'] = downloadUtils.getArtwork(item, "Art", parent=True, server=server)
art['clearart'] = downloadUtils.getArtwork(item, "Art", parent=True, server=server)
art['tvshow.clearlogo'] = downloadUtils.getArtwork(item, "Logo", parent=True, server=server)
art['clearlogo'] = downloadUtils.getArtwork(item, "Logo", parent=True, server=server)
art['tvshow.banner'] = downloadUtils.getArtwork(item, "Banner", parent=True, server=server)
art['season.banner'] = downloadUtils.getArtwork(item, "Banner", parent=False, server=server)
art['banner'] = downloadUtils.getArtwork(item, "Banner", parent=False, server=server)
art['tvshow.landscape'] = downloadUtils.getArtwork(item, "Thumb", parent=True, server=server)
art['season.landscape'] = downloadUtils.getArtwork(item, "Thumb", parent=False, server=server)
art['landscape'] = downloadUtils.getArtwork(item, "Thumb", parent=False, server=server)
art['tvshow.fanart'] = downloadUtils.getArtwork(item, "Backdrop", parent=True, server=server)
art['fanart'] = downloadUtils.getArtwork(item, "Backdrop", parent=True, server=server)
elif item_type == "Series":
art['tvshow.poster'] = downloadUtils.getArtwork(item, "Primary", parent=False, server=server)
art['poster'] = downloadUtils.getArtwork(item, "Primary", parent=False, server=server)
art['tvshow.clearart'] = downloadUtils.getArtwork(item, "Art", parent=False, server=server)
art['clearart'] = downloadUtils.getArtwork(item, "Art", parent=False, server=server)
art['tvshow.clearlogo'] = downloadUtils.getArtwork(item, "Logo", parent=False, server=server)
art['clearlogo'] = downloadUtils.getArtwork(item, "Logo", parent=False, server=server)
art['tvshow.banner'] = downloadUtils.getArtwork(item, "Banner", parent=False, server=server)
art['banner'] = downloadUtils.getArtwork(item, "Banner", parent=False, server=server)
art['tvshow.landscape'] = downloadUtils.getArtwork(item, "Thumb", parent=False, server=server)
art['landscape'] = downloadUtils.getArtwork(item, "Thumb", parent=False, server=server)
art['tvshow.fanart'] = downloadUtils.getArtwork(item, "Backdrop", parent=False, server=server)
art['fanart'] = downloadUtils.getArtwork(item, "Backdrop", parent=False, server=server)
elif item_type == "Movie" or item_type == "BoxSet":
art['poster'] = downloadUtils.getArtwork(item, "Primary", server=server)
art['landscape'] = downloadUtils.getArtwork(item, "Thumb", server=server)
art['banner'] = downloadUtils.getArtwork(item, "Banner", server=server)
art['clearlogo'] = downloadUtils.getArtwork(item, "Logo", server=server)
art['clearart'] = downloadUtils.getArtwork(item, "Art", server=server)
art['discart'] = downloadUtils.getArtwork(item, "Disc", server=server)
art['fanart'] = downloadUtils.getArtwork(item, "Backdrop", server=server)
if not art['fanart']:
art['fanart'] = downloadUtils.getArtwork(item, "Backdrop", parent=True, server=server)
return art
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
def double_urlencode(text):
text = single_urlencode(text)
text = single_urlencode(text)
return text
def single_urlencode(text):
# urlencode needs a utf- string
text = urllib.urlencode({'blahblahblah': text.encode('utf-8')})
text = text[13:]
return text.decode('utf-8') #return the result again as unicode
def send_event_notification(method, data):
next_data = json.dumps(data)
source_id = "embycon"
data = '\\"[\\"{0}\\"]\\"'.format(binascii.hexlify(next_data))
command = 'XBMC.NotifyAll({0}.SIGNAL,{1},{2})'.format(source_id, method, data)
log.debug("Sending notification event data: {0}", command)
xbmc.executebuiltin(command)
def datetime_from_string(time_string):
if time_string[-1:] == "Z":
time_string = re.sub("[0-9]{1}Z", " UTC", time_string)
elif time_string[-6:] == "+00:00":
time_string = re.sub("[0-9]{1}\+00:00", " UTC", time_string)
log.debug("New Time String : {0}", time_string)
start_time = time.strptime(time_string, "%Y-%m-%dT%H:%M:%S.%f %Z")
dt = datetime(*(start_time[0:6]))
timestamp = calendar.timegm(dt.timetuple())
local_dt = datetime.fromtimestamp(timestamp)
local_dt.replace(microsecond=dt.microsecond)
return local_dt