jellyfin-kodi/resources/lib/CreateFiles.py

341 lines
16 KiB
Python
Raw Normal View History

2015-03-17 18:18:17 +00:00
#################################################################################################
# CreateFiles
#################################################################################################
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
import os, sys
2015-03-17 18:18:17 +00:00
import json
import time
from calendar import timegm
from datetime import datetime
2015-03-25 11:55:14 +00:00
import string
import unicodedata
2015-03-17 18:18:17 +00:00
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
2015-03-24 22:54:33 +00:00
from PlayUtils import PlayUtils
2015-03-17 18:18:17 +00:00
import Utils as utils
from ReadEmbyDB import ReadEmbyDB
2015-03-17 18:18:17 +00:00
2015-03-25 17:37:21 +00:00
addon = xbmcaddon.Addon(id='plugin.video.emby')
2015-03-17 18:18:17 +00:00
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
dataPath = os.path.join(addondir,"library")
movieLibrary = os.path.join(dataPath,'movies')
tvLibrary = os.path.join(dataPath,'tvshows')
2015-03-21 13:31:30 +00:00
musicvideoLibrary = os.path.join(dataPath,'musicvideos')
2015-03-17 18:18:17 +00:00
class CreateFiles():
2015-03-19 08:44:25 +00:00
def createSTRM(self,item):
2015-03-17 18:18:17 +00:00
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":
2015-03-21 13:31:30 +00:00
itemPath = os.path.join(musicvideoLibrary,item["Id"])
2015-03-17 18:18:17 +00:00
strmFile = os.path.join(itemPath,item["Id"] + ".strm")
if item_type == "Episode":
2015-03-19 08:44:25 +00:00
itemPath = os.path.join(tvLibrary,item["SeriesId"])
2015-03-17 18:18:17 +00:00
if str(item.get("IndexNumber")) != None:
2015-03-21 19:26:59 +00:00
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S" + str(item.get("ParentIndexNumber")) + "E" + str(item.get("IndexNumber")) + " (" + item["Id"] + ").strm"
2015-03-17 18:18:17 +00:00
else:
2015-03-21 19:26:59 +00:00
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S0E0 " + self.CleanName(utils.convertEncoding(item.get("Name"))) + " (" + item["Id"] + ").strm"
2015-03-17 18:18:17 +00:00
strmFile = os.path.join(itemPath,filenamestr)
2015-03-17 18:18:17 +00:00
changes = False
if not xbmcvfs.exists(strmFile):
changes = True
xbmcvfs.mkdir(itemPath)
text_file = open(strmFile, "w")
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
playurl = PlayUtils().getPlayUrl(server, item["Id"], item)
#do not use direct path for transcoding
if playurl.startswith("http"):
playurl = "plugin://plugin.video.emby/?id=" + item["Id"] + '&mode=play'
2015-03-17 18:18:17 +00:00
text_file.writelines(playurl)
2015-03-17 18:18:17 +00:00
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
2015-03-17 18:18:17 +00:00
return changes
2015-03-19 08:44:25 +00:00
def createNFO(self,item):
2015-03-17 18:18:17 +00:00
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"
2015-03-21 13:31:30 +00:00
if item_type == "MusicVideo":
itemPath = os.path.join(musicvideoLibrary,item["Id"])
nfoFile = os.path.join(itemPath,item["Id"] + ".nfo")
rootelement = "musicvideo"
2015-03-17 18:18:17 +00:00
if item_type == "Series":
itemPath = os.path.join(tvLibrary,item["Id"])
nfoFile = os.path.join(itemPath,"tvshow.nfo")
rootelement = "tvshow"
if item_type == "Episode":
2015-03-19 08:44:25 +00:00
itemPath = os.path.join(tvLibrary,item["SeriesId"])
2015-03-17 18:18:17 +00:00
if str(item.get("ParentIndexNumber")) != None:
2015-03-21 15:05:47 +00:00
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S" + str(item.get("ParentIndexNumber")) + "E" + str(item.get("IndexNumber")) + " (" + item["Id"] + ").nfo"
2015-03-17 18:18:17 +00:00
else:
2015-03-25 11:46:08 +00:00
filenamestr = self.CleanName(utils.convertEncoding(item.get("SeriesName"))) + " S0E0 " + self.CleanName(utils.convertEncoding(item["Name"])) + " (" + item["Id"] + ").nfo"
2015-03-17 18:18:17 +00:00
nfoFile = os.path.join(itemPath,filenamestr)
rootelement = "episodedetails"
2015-03-17 18:18:17 +00:00
changes = False
if not xbmcvfs.exists(nfoFile):
changes = True
utils.logMsg("MB3 Syncer","creating NFO file " + nfoFile,2)
2015-03-17 18:18:17 +00:00
xbmcvfs.mkdir(itemPath)
root = Element(rootelement)
SubElement(root, "id").text = item["Id"]
2015-03-20 19:26:37 +00:00
SubElement(root, "uniqueid").text = item["Id"]
2015-03-17 18:18:17 +00:00
if item.get("Tag") != None:
for tag in item.get("Tag"):
SubElement(root, "tag").text = tag
SubElement(root, "thumb").text = API().getArtwork(item, "Primary")
2015-03-19 21:31:06 +00:00
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")
2015-03-20 15:16:39 +00:00
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
2015-03-20 15:58:46 +00:00
SubElement(root, "fanart").text = API().getArtwork(item, "Backdrop")
2015-03-17 18:18:17 +00:00
SubElement(root, "title").text = utils.convertEncoding(item["Name"])
SubElement(root, "originaltitle").text = utils.convertEncoding(item["Name"])
SubElement(root, "sorttitle").text = utils.convertEncoding(item["SortName"])
2015-03-24 20:03:07 +00:00
if userData.get("LastPlayedDate") != None:
SubElement(root, "lastplayed").text = userData.get("LastPlayedDate")
else:
SubElement(root, "lastplayed").text = ""
2015-03-21 13:31:30 +00:00
if item.has_key("Album"):
SubElement(root, "album").text = item["Album"]
if item.has_key("Artist"):
SubElement(root, "artist").text = utils.convertEncoding(item["Artist"][0])
2015-03-21 13:31:30 +00:00
2015-03-17 18:18:17 +00:00
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
2015-03-17 18:18:17 +00:00
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)
2015-03-17 18:18:17 +00:00
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
2015-03-18 17:49:20 +00:00
SubElement(root, "premiered").text = premieredate
SubElement(root, "aired").text = premieredate
2015-03-17 18:18:17 +00:00
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"))
2015-03-17 18:18:17 +00:00
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)
2015-03-17 18:18:17 +00:00
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("/", "&")
2015-03-17 18:18:17 +00:00
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 )
2015-03-17 18:18:17 +00:00
if(jsonData != ""):
trailerItem = json.loads(jsonData)
if trailerItem[0].get("LocationType") == "FileSystem":
2015-03-25 17:37:21 +00:00
trailerUrl = "plugin://plugin.video.emby/?id=" + trailerItem[0].get("Id") + '&mode=play'
SubElement(root, "trailer").text = trailerUrl
2015-03-17 18:18:17 +00:00
#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)
2015-03-17 18:18:17 +00:00
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)
2015-03-25 14:00:08 +00:00
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)
2015-03-17 18:18:17 +00:00
2015-03-25 11:46:08 +00:00
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)