jellyfin-kodi/resources/lib/CreateFiles.py

334 lines
16 KiB
Python

#################################################################################################
# CreateFiles
#################################################################################################
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
import os, sys
import json
import time
from calendar import timegm
from datetime import datetime
import string
import unicodedata
from xml.etree.ElementTree import Element, SubElement, Comment, tostring
from xml.etree import ElementTree
from xml.dom import minidom
import xml.etree.cElementTree as ET
from DownloadUtils import DownloadUtils
from API import API
from PlayUtils import PlayUtils
import Utils as utils
from ReadEmbyDB import ReadEmbyDB
addon = xbmcaddon.Addon(id='plugin.video.emby')
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
dataPath = os.path.join(addondir,"library")
movieLibrary = os.path.join(dataPath,'movies')
tvLibrary = os.path.join(dataPath,'tvshows')
musicvideoLibrary = os.path.join(dataPath,'musicvideos')
class CreateFiles():
def createSTRM(self,item):
item_type=str(item.get("Type")).encode('utf-8')
if item_type == "Movie":
itemPath = os.path.join(movieLibrary,item["Id"])
strmFile = os.path.join(itemPath,item["Id"] + ".strm")
if item_type == "MusicVideo":
itemPath = os.path.join(musicvideoLibrary,item["Id"])
strmFile = os.path.join(itemPath,item["Id"] + ".strm")
if item_type == "Episode":
itemPath = os.path.join(tvLibrary,item["SeriesId"])
if str(item.get("IndexNumber")) != None:
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S" + str(item.get("ParentIndexNumber")) + "E" + str(item.get("IndexNumber")) + " (" + item["Id"] + ").strm"
else:
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S0E0 " + self.CleanName(utils.convertEncoding(item.get("Name"))) + " (" + item["Id"] + ").strm"
strmFile = os.path.join(itemPath,filenamestr)
changes = False
if not xbmcvfs.exists(strmFile):
changes = True
xbmcvfs.mkdir(itemPath)
text_file = open(strmFile, "w")
playUrl = "plugin://plugin.video.emby/?id=" + item["Id"] + '&mode=play'
text_file.writelines(playUrl)
text_file.close()
#set timestamp on file - this will make sure that the dateadded field is properly set
if item.get("DateCreated") != None:
try:
timestamp = time.mktime(datetime.strptime(item.get("DateCreated").split(".")[0]+"GMT", "%Y-%m-%dT%H:%M:%S%Z").timetuple())
os.utime(strmFile,(timestamp,timestamp))
except:
pass
return changes
def createNFO(self,item):
downloadUtils = DownloadUtils()
timeInfo = API().getTimeInfo(item)
userData=API().getUserData(item)
people = API().getPeople(item)
mediaStreams=API().getMediaStreams(item)
studios = API().getStudios(item)
userid = downloadUtils.getUserId()
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
item_type=str(item.get("Type"))
if item_type == "Movie":
itemPath = os.path.join(movieLibrary,item["Id"])
nfoFile = os.path.join(itemPath,item["Id"] + ".nfo")
rootelement = "movie"
if item_type == "MusicVideo":
itemPath = os.path.join(musicvideoLibrary,item["Id"])
nfoFile = os.path.join(itemPath,item["Id"] + ".nfo")
rootelement = "musicvideo"
if item_type == "Series":
itemPath = os.path.join(tvLibrary,item["Id"])
nfoFile = os.path.join(itemPath,"tvshow.nfo")
rootelement = "tvshow"
if item_type == "Episode":
itemPath = os.path.join(tvLibrary,item["SeriesId"])
if str(item.get("ParentIndexNumber")) != None:
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S" + str(item.get("ParentIndexNumber")) + "E" + str(item.get("IndexNumber")) + " (" + item["Id"] + ").nfo"
else:
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S0E0 " + self.CleanName(utils.convertEncoding(item["Name"])) + " (" + item["Id"] + ").nfo"
nfoFile = os.path.join(itemPath,filenamestr)
rootelement = "episodedetails"
changes = False
if not xbmcvfs.exists(nfoFile):
changes = True
utils.logMsg("MB3 Syncer","creating NFO file " + nfoFile,2)
xbmcvfs.mkdir(itemPath)
root = Element(rootelement)
SubElement(root, "id").text = item["Id"]
SubElement(root, "uniqueid").text = item["Id"]
if item.get("Tag") != None:
for tag in item.get("Tag"):
SubElement(root, "tag").text = tag
SubElement(root, "thumb").text = API().getArtwork(item, "Primary")
if item_type == 'Series':
seasonData = ReadEmbyDB().getTVShowSeasons(item["Id"])
if seasonData != None:
for season in seasonData:
if season.has_key("IndexNumber"):
seasonart = API().getArtwork(season, "Primary")
if seasonart != None:
SubElement(root, "thumb",{"type":"season","aspect":"poster","season":str(season["IndexNumber"])}).text = seasonart
seasonart2 = API().getArtwork(season, "Banner")
if seasonart2 != None:
SubElement(root, "thumb",{"type":"season","aspect":"banner","season":str(season["IndexNumber"])}).text = seasonart2
SubElement(root, "fanart").text = API().getArtwork(item, "Backdrop")
SubElement(root, "title").text = utils.convertEncoding(item["Name"])
SubElement(root, "originaltitle").text = utils.convertEncoding(item["Name"])
SubElement(root, "sorttitle").text = utils.convertEncoding(item["SortName"])
if userData.get("LastPlayedDate") != None:
SubElement(root, "lastplayed").text = userData.get("LastPlayedDate")
else:
SubElement(root, "lastplayed").text = ""
if item.has_key("Album"):
SubElement(root, "album").text = item["Album"]
if item.has_key("Artist"):
SubElement(root, "artist").text = item["Artist"][0]
if item.has_key("OfficialRating"):
SubElement(root, "mpaa").text = item["OfficialRating"]
if item.get("CriticRating") != None:
rating = int(item.get("CriticRating"))/10
SubElement(root, "rating").text = str(rating)
if item.get("DateCreated") != None:
dateadded = item["DateCreated"].replace("T"," ")
dateadded = dateadded.replace(".0000000Z","")
SubElement(root, "dateadded").text = dateadded
if userData.get("PlayCount") != None:
SubElement(root, "playcount").text = userData.get("PlayCount")
if int(userData.get("PlayCount")) > 0:
SubElement(root, "watched").text = "true"
if timeInfo.get("ResumeTime") != None:
resume_sec = int(round(float(timeInfo.get("ResumeTime"))))*60
total_sec = int(round(float(timeInfo.get("TotalTime"))))*60
if resume_sec != 0:
resume = SubElement(root, "resume")
SubElement(resume, "position").text = str(resume_sec)
SubElement(resume, "total").text = str(total_sec)
if item_type == "Episode":
SubElement(root, "season").text = str(item.get("ParentIndexNumber"))
SubElement(root, "episode").text = str(item.get("IndexNumber"))
SubElement(root, "year").text = str(item.get("ProductionYear"))
if item.get("PremiereDate") != None:
premieredatelist = (item.get("PremiereDate")).split("T")
premieredate = premieredatelist[0]
SubElement(root, "firstaired").text = premieredate
SubElement(root, "premiered").text = premieredate
SubElement(root, "aired").text = premieredate
if(timeInfo.get('Duration') != "0"):
SubElement(root, "runtime").text = str(timeInfo.get('Duration'))
SubElement(root, "plot").text = utils.convertEncoding(API().getOverview(item))
if item.get("ShortOverview") != None:
SubElement(root, "outline").text = utils.convertEncoding(item.get("ShortOverview"))
if item.get("TmdbCollectionName") != None:
SubElement(root, "set").text = item.get("TmdbCollectionName")
if item.get("ProviderIds") != None:
if item.get("ProviderIds").get("Imdb") != None:
SubElement(root, "imdbnumber").text = item
if people.get("Writer") != None:
for writer in people.get("Writer"):
SubElement(root, "credits").text = utils.convertEncoding(writer)
if people.get("Director") != None:
for director in people.get("Director"):
SubElement(root, "director").text = utils.convertEncoding(director)
if item.get("Genres") != None:
for genre in item.get("Genres"):
SubElement(root, "genre").text = utils.convertEncoding(genre)
if studios != None:
for studio in studios:
SubElement(root, "studio").text = utils.convertEncoding(studio).replace("/", "&")
if item.get("ProductionLocations") != None:
for country in item.get("ProductionLocations"):
SubElement(root, "country").text = utils.convertEncoding(country)
#trailer link
trailerUrl = None
if item.get("LocalTrailerCount") != None and item.get("LocalTrailerCount") > 0:
itemTrailerUrl = "http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + item.get("Id") + "/LocalTrailers?format=json"
jsonData = downloadUtils.downloadUrl(itemTrailerUrl, suppress=False, popup=0 )
if(jsonData != ""):
trailerItem = json.loads(jsonData)
if trailerItem[0].get("LocationType") == "FileSystem":
trailerUrl = "plugin://plugin.video.emby/?id=" + trailerItem[0].get("Id") + '&mode=play'
SubElement(root, "trailer").text = trailerUrl
#add streamdetails
fileinfo = SubElement(root, "fileinfo")
streamdetails = SubElement(fileinfo, "streamdetails")
video = SubElement(streamdetails, "video")
SubElement(video, "duration").text = str(mediaStreams.get('totaltime'))
SubElement(video, "aspect").text = mediaStreams.get('aspectratio')
SubElement(video, "codec").text = mediaStreams.get('videocodec')
SubElement(video, "width").text = str(mediaStreams.get('width'))
SubElement(video, "height").text = str(mediaStreams.get('height'))
SubElement(video, "duration").text = str(timeInfo.get('Duration'))
audio = SubElement(streamdetails, "audio")
SubElement(audio, "codec").text = mediaStreams.get('audiocodec')
SubElement(audio, "channels").text = mediaStreams.get('channels')
#add people
if item.get("People") != None:
for actor in item.get("People"):
if(actor.get("Type") == "Actor"):
actor_elem = SubElement(root, "actor")
SubElement(actor_elem, "name").text = utils.convertEncoding(actor.get("Name"))
SubElement(actor_elem, "type").text = utils.convertEncoding(actor.get("Role"))
SubElement(actor_elem, "thumb").text = downloadUtils.imageUrl(actor.get("Id"), "Primary", 0, 400, 400)
# Some devices such as Mac are using an older version of python
try:
# 2.7 and greater
ET.ElementTree(root).write(nfoFile, xml_declaration=True)
except:
# <2.7
ET.ElementTree(root).write(nfoFile)
return changes
def copyThemeMusic(self,item):
downloadUtils = DownloadUtils()
userid = downloadUtils.getUserId()
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
item_type=str(item.get("Type"))
if item_type == "Movie":
itemPath = os.path.join(movieLibrary,item["Id"])
themeFile = os.path.join(itemPath,"theme.mp3")
if item_type == "Series":
itemPath = os.path.join(tvLibrary,item["Id"])
themeFile = os.path.join(itemPath,"theme.mp3")
if not xbmcvfs.exists(themeFile):
utils.logMsg("MB3 Syncer","creating Theme file " + themeFile,2)
#theme music link
themeMusicUrl = "http://" + server + "/mediabrowser/Items/" + item["Id"] + "/ThemeSongs?format=json"
jsonData = downloadUtils.downloadUrl(themeMusicUrl, suppress=False, popup=0 )
if(jsonData != ""):
themeMusic = json.loads(jsonData)
if(themeMusic != None and themeMusic["TotalRecordCount"] > 0):
themeItems = themeMusic["Items"]
if themeItems[0] != None:
mediasources = themeItems[0]["MediaSources"]
if mediasources[0]["Container"] == "mp3":
themeUrl = PlayUtils().getPlayUrl(server,themeItems[0]["Id"],themeItems[0])
xbmcvfs.copy(themeUrl,themeFile)
def copyExtraFanart(self,item):
downloadUtils = DownloadUtils()
userid = downloadUtils.getUserId()
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
item_type=str(item.get("Type"))
if item_type == "Movie":
itemPath = os.path.join(movieLibrary,item["Id"])
fanartDir = os.path.join(itemPath,"extrafanart" + os.sep)
if item_type == "Series":
itemPath = os.path.join(tvLibrary,item["Id"])
fanartDir = os.path.join(itemPath,"extrafanart" + os.sep)
if not xbmcvfs.exists(fanartDir):
utils.logMsg("MB3 Syncer","creating extrafanart directory ",2)
xbmcvfs.mkdir(fanartDir)
fullItem = ReadEmbyDB().getFullItem(item["Id"])
if(fullItem != None and fullItem["BackdropImageTags"] != None and len(fullItem["BackdropImageTags"]) > 1):
totalbackdrops = len(fullItem["BackdropImageTags"])
for index in range(1,totalbackdrops):
backgroundUrl = API().getArtwork(fullItem, "Backdrop",str(index))
fanartFile = os.path.join(fanartDir,"fanart" + str(index) + ".jpg")
xbmcvfs.copy(backgroundUrl,fanartFile)
def CleanName(self, filename):
validFilenameChars = "-_.() %s%s" % (string.ascii_letters, string.digits)
cleanedFilename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore')
return ''.join(c for c in cleanedFilename if c in validFilenameChars)