################################################################################################# # 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.mb3sync') 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.mb3sync/?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.mb3sync/?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)