コード例 #1
0
ファイル: XMLConverter.py プロジェクト: heather81/PlexConnect
 def TREE_ADDXML(self, elem, child, src, srcXML, param):
     tag, leftover = self.getParam(src, param)
     key, leftover, dfltd = self.getKey(src, srcXML, leftover)
     
     if 'PlexConnectUDID' in self.options:
         UDID = self.options['PlexConnectUDID']
         PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
         auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
     else:
         auth_token = ''
     
     PMS_baseURL = self.PMS_baseURL
     
     if key.startswith('//'):  # local servers signature
         pathstart = key.find('/',3)
         PMS_baseURL= key[:pathstart]
         path = key[pathstart:]
     elif key.startswith('/'):  # internal full path.
         path = key
     #elif key.startswith('http://'):  # external address
     #    path = key
     elif key == '':  # internal path
         path = self.path[srcXML]
     else:  # internal path, add-on
         path = self.path[srcXML] + '/' + key
     
     if PMS_baseURL.startswith('//'):
         PMS = PlexAPI.getXMLFromMultiplePMS(UDID, path, PMS_baseURL[2:], self.options)
     else:
         PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options, auth_token)
     
     self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
     self.path[tag] = path  # store base path
     
     return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #2
0
 def ATTRIB_MUSICURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     
     UDID = self.options['PlexConnectUDID']
     PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMSaddress)
     AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
     scheme = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'scheme')
     
     # direct play
     res = PlexAPI.getDirectAudioPath(key, AuthToken)
     
     if res.startswith('/'):  # internal full path.
         res = scheme + '://' + self.PMSaddress + res
     elif res.startswith('http://') or res.startswith('https://'):  # external address
         hijack = g_param['HostToIntercept']
         if hijack in res:
             dprint(__name__, 1, "twisting...")
             hijack_twisted = hijack[::-1]
             res = res.replace(hijack, hijack_twisted)
             dprint(__name__, 1, res)
     else:  # internal path, add-on
         res = scheme + '://' + self.PMSaddress + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'MusicURL: {0}', res)
     return res
コード例 #3
0
ファイル: Subtitle.py プロジェクト: Andyspickle/PlexConnect
def getSubtitleJSON(PMS_address, path, options):
    """
    # double check aTV UDID, redo from client IP if needed/possible
    if not 'PlexConnectUDID' in options:
        UDID = getATVFromIP(options['aTVAddress'])
        if UDID:
            options['PlexConnectUDID'] = UDID
    """
    path = path + '?' if not '?' in path else '&'
    path = path + 'encoding=utf-8'
    
    if not 'PlexConnectUDID' in options:
        # aTV unidentified, UDID not known
        return False
    
    UDID = options['PlexConnectUDID']
    
    # determine PMS_uuid, PMSBaseURL from IP (PMS_mark)
    xargs = {}
    PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_address)
    PMS_baseURL = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'baseURL')
    xargs['X-Plex-Token'] = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
    
    dprint(__name__, 1, "subtitle URL: {0}{1}", PMS_baseURL, path)
    dprint(__name__, 1, "xargs: {0}", xargs)
    
    request = urllib2.Request(PMS_baseURL+path , None, xargs)
    try:
        response = urllib2.urlopen(request, timeout=20)
    except urllib2.URLError as e:
        dprint(__name__, 0, 'No Response from Plex Media Server')
        if hasattr(e, 'reason'):
            dprint(__name__, 0, "We failed to reach a server. Reason: {0}", e.reason)
        elif hasattr(e, 'code'):
            dprint(__name__, 0, "The server couldn't fulfill the request. Error code: {0}", e.code)
        return False
    except IOError:
        dprint(__name__, 0, 'Error loading response XML from Plex Media Server')
        return False
    
    # Todo: Deal with ANSI files. How to select used "codepage"?
    subtitleFile = response.read()
    
    print response.headers
    
    dprint(__name__, 1, "====== received Subtitle ======")
    dprint(__name__, 1, "{0} [...]", subtitleFile[:255])
    dprint(__name__, 1, "====== Subtitle finished ======")
    
    if options['PlexConnectSubtitleFormat']=='srt':
        subtitle = parseSRT(subtitleFile)
    else:
        return False
    
    JSON = json.dumps(subtitle)
    
    dprint(__name__, 1, "====== generated subtitle aTV subtitle JSON ======")
    dprint(__name__, 1, "{0} [...]", JSON[:255])
    dprint(__name__, 1, "====== aTV subtitle JSON finished ======")
    return(JSON)
コード例 #4
0
ファイル: XMLConverter.py プロジェクト: heather81/PlexConnect
 def ATTRIB_IMAGEURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     width, leftover = self.getParam(src, leftover)
     height, leftover = self.getParam(src, leftover)
     if height=='':
         height = width
     
     PMS_baseURL = self.PMS_baseURL
     cmd_start = key.find('PMS(')
     cmd_end = key.find(')', cmd_start)
     if cmd_start>-1 and cmd_end>-1 and cmd_end>cmd_start:
         PMS_baseURL = key[cmd_start+4:cmd_end]
         key = key[cmd_end+1:]
     
     UDID = self.options['PlexConnectUDID']
     PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_baseURL)
     AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
     
     if width=='':
         # direct play
         res = PlexAPI.getDirectImagePath(key, AuthToken)
     else:
         # request transcoding
         res = PlexAPI.getTranscodeImagePath(key, AuthToken, self.path[srcXML], width, height)
     
     if res.startswith('/'):  # internal full path.
         res = PMS_baseURL + res
     elif res.startswith('http://') or key.startswith('https://'):  # external address
         pass
     else:  # internal path, add-on
         res = PMS_baseURL + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'ImageURL: {0}', res)
     return res
コード例 #5
0
ファイル: XMLConverter.py プロジェクト: liuxuan30/PlexConnect
    def TREE_ADDXML(self, elem, child, src, srcXML, param):
        tag, leftover = self.getParam(src, param)
        key, leftover, dfltd = self.getKey(src, srcXML, leftover)

        PMS_address = self.PMS_address

        if key.startswith('//'):  # local servers signature
            pathstart = key.find('/', 3)
            PMS_address = key[:pathstart]
            path = key[pathstart:]
        elif key.startswith('/'):  # internal full path.
            path = key
        #elif key.startswith('http://'):  # external address
        #    path = key
        elif key == '':  # internal path
            path = self.path[srcXML]
        else:  # internal path, add-on
            path = self.path[srcXML] + '/' + key

        if PMS_address[0].isalpha():  # owned, shared
            type = self.PMS_address
            PMS = PlexAPI.getXMLFromMultiplePMS(self.ATV_udid, path, type,
                                                self.options)
        else:  # IP
            auth_token = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid,
                                                'accesstoken')
            PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options,
                                        auth_token)

        self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
        self.path[tag] = path  # store base path

        return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #6
0
    def ATTRIB_MUSICURL(self, src, srcXML, param):
        key, leftover, dfltd = self.getKey(src, srcXML, param)

        UDID = self.options['PlexConnectUDID']
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
        AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')

        # direct play
        res = PlexAPI.getDirectAudioPath(key, AuthToken)

        if res.startswith('/'):  # internal full path.
            res = self.PMS_baseURL + res
        elif res.startswith('http://') or key.startswith(
                'https://'):  # external address
            hijack = g_param['HostToIntercept']
            if hijack in res:
                dprint(__name__, 1, "twisting...")
                hijack_twisted = hijack[::-1]
                res = res.replace(hijack, hijack_twisted)
                dprint(__name__, 1, res)
        else:  # internal path, add-on
            res = self.PMS_baseURL + self.path[srcXML] + '/' + res

        dprint(__name__, 1, 'MusicURL: {0}', res)
        return res
コード例 #7
0
ファイル: XMLConverter.py プロジェクト: joeocampo/PlexConnect
 def ATTRIB_IMAGEURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     width, leftover = self.getParam(src, leftover)
     height, leftover = self.getParam(src, leftover)
     if height=='':
         height = width
     
     UDID = self.options['PlexConnectUDID']
     AuthToken = g_ATVSettings.getSetting(UDID, 'myplex_auth')
     
     if width=='':
         # direct play
         res = PlexAPI.getDirectImagePath(key, AuthToken)
     else:
         # request transcoding
         res = PlexAPI.getTranscodeImagePath(key, AuthToken, self.path[srcXML], width, height)
     
     if res.startswith('/'):  # internal full path.
         res = 'http://' + self.PMSaddress + res
     elif res.startswith('http://'):  # external address
         hijack = g_param['HostToIntercept']
         if hijack in res:
             dprint(__name__, 1, "twisting...")
             hijack_twisted = hijack[::-1]
             res = res.replace(hijack, hijack_twisted)
             dprint(__name__, 1, res)
     else:  # internal path, add-on
         res = 'http://' + self.PMSaddress + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'ImageURL: {0}', res)
     return res
コード例 #8
0
 def TREE_ADDXML(self, elem, child, src, srcXML, param):
     tag, leftover = self.getParam(src, param)
     key, leftover, dfltd = self.getKey(src, srcXML, leftover)
     
     PMS_address = self.PMS_address
     
     if key.startswith('//'):  # local servers signature
         pathstart = key.find('/',3)
         PMS_address= key[:pathstart]
         path = key[pathstart:]
     elif key.startswith('/'):  # internal full path.
         path = key
     #elif key.startswith('http://'):  # external address
     #    path = key
     elif key == '':  # internal path
         path = self.path[srcXML]
     else:  # internal path, add-on
         path = self.path[srcXML] + '/' + key
     
     if PMS_address[0].isalpha():  # owned, shared
         type = self.PMS_address
         PMS = PlexAPI.getXMLFromMultiplePMS(self.ATV_udid, path, type, self.options)
     else:  # IP
         auth_token = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid, 'accesstoken')
         PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options, auth_token)
     
     self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
     self.path[tag] = path  # store base path
     
     return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #9
0
 def ATTRIB_IMAGEURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     width, leftover = self.getParam(src, leftover)
     height, leftover = self.getParam(src, leftover)
     if height=='':
         height = width
     
     PMS_baseURL = self.PMS_baseURL
     cmd_start = key.find('PMS(')
     cmd_end = key.find(')', cmd_start)
     if cmd_start>-1 and cmd_end>-1 and cmd_end>cmd_start:
         PMS_baseURL = key[cmd_start+4:cmd_end]
         key = key[cmd_end+1:]
     
     UDID = self.options['PlexConnectUDID']
     PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_baseURL)
     AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
     
     if width=='':
         # direct play
         res = PlexAPI.getDirectImagePath(key, AuthToken)
     else:
         # request transcoding
         res = PlexAPI.getTranscodeImagePath(key, AuthToken, self.path[srcXML], width, height)
     
     if res.startswith('/'):  # internal full path.
         res = PMS_baseURL + res
     elif res.startswith('http://') or key.startswith('https://'):  # external address
         pass
     else:  # internal path, add-on
         res = PMS_baseURL + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'ImageURL: {0}', res)
     return res
コード例 #10
0
ファイル: XMLConverter.py プロジェクト: fredfri/PlexConnect
 def ATTRIB_IMAGEURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     width, leftover = self.getParam(src, leftover)
     height, leftover = self.getParam(src, leftover)
     if height=='':
         height = width
     
     PMSaddress = self.PMSaddress
     cmd_start = key.find('PMS(')
     cmd_end = key.find(')', cmd_start)
     if cmd_start>-1 and cmd_end>-1 and cmd_end>cmd_start:
         PMSaddress = key[cmd_start+4:cmd_end]
         key = key[cmd_end+1:]
     
     UDID = self.options['PlexConnectUDID']
     AuthToken = g_ATVSettings.getSetting(UDID, 'myplex_auth')
     
     if width=='':
         # direct play
         res = PlexAPI.getDirectImagePath(key, AuthToken)
     else:
         # request transcoding
         res = PlexAPI.getTranscodeImagePath(key, AuthToken, self.path[srcXML], width, height)
     
     if res.startswith('/'):  # internal full path.
         res = 'http://' + PMSaddress + res
     elif res.startswith('http://'):  # external address
         pass
     else:  # internal path, add-on
         res = 'http://' + PMSaddress + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'ImageURL: {0}', res)
     return res
コード例 #11
0
ファイル: XMLConverter.py プロジェクト: fredfri/PlexConnect
 def TREE_ADDXML(self, elem, child, src, srcXML, param):
     tag, leftover = self.getParam(src, param)
     key, leftover, dfltd = self.getKey(src, srcXML, leftover)
     
     if 'PlexConnectUDID' in self.options:
         UDID = self.options['PlexConnectUDID']
         auth_token = g_ATVSettings.getSetting(UDID, 'myplex_auth')
     else:
         auth_token = ''
     
     if key.startswith('//local'):  # local servers signature
         path = key[len('//local'):]
         PMS = PlexAPI.getXMLFromMultiplePMS(UDID, path, self.options, auth_token)
     elif key.startswith('/'):  # internal full path.
         path = key
         PMS = PlexAPI.getXMLFromPMS('http://'+self.PMSaddress, path, self.options, auth_token)
     #elif key.startswith('http://'):  # external address
     #    path = key
     #    hijack = g_param['HostToIntercept']
     #    if hijack in path:
     #        dprint(__name__, 1, "twisting...")
     #        hijack_twisted = hijack[::-1]
     #        path = path.replace(hijack, hijack_twisted)
     #        dprint(__name__, 1, path)
     elif key == '':  # internal path
         path = self.path[srcXML]
         PMS = PlexAPI.getXMLFromPMS('http://'+self.PMSaddress, path, self.options, auth_token)
     else:  # internal path, add-on
         path = self.path[srcXML] + '/' + key
         PMS = PlexAPI.getXMLFromPMS('http://'+self.PMSaddress, path, self.options, auth_token)
     
     self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
     self.path[tag] = path  # store base path
     
     return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #12
0
ファイル: Subtitle.py プロジェクト: waldenr27/PlexConnect
def getSubtitleJSON(PMS_baseURL, path, options):
    """
    # double check aTV UDID, redo from client IP if needed/possible
    if not 'PlexConnectUDID' in options:
        UDID = getATVFromIP(options['aTVAddress'])
        if UDID:
            options['PlexConnectUDID'] = UDID
    """
    path = path + '?' if not '?' in path else '&'
    path = path + 'encoding=utf-8'

    xargs = {}
    if 'PlexConnectUDID' in options:
        UDID = options['PlexConnectUDID']
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_baseURL)
        xargs['X-Plex-Token'] = PlexAPI.getPMSProperty(UDID, PMS_uuid,
                                                       'accesstoken')

    dprint(__name__, 1, "subtitle URL: {0}{1}", PMS_baseURL, path)
    dprint(__name__, 1, "xargs: {0}", xargs)

    request = urllib2.Request(PMS_baseURL + path, None, xargs)
    try:
        response = urllib2.urlopen(request, timeout=20)
    except urllib2.URLError as e:
        dprint(__name__, 0, 'No Response from Plex Media Server')
        if hasattr(e, 'reason'):
            dprint(__name__, 0, "We failed to reach a server. Reason: {0}",
                   e.reason)
        elif hasattr(e, 'code'):
            dprint(__name__, 0,
                   "The server couldn't fulfill the request. Error code: {0}",
                   e.code)
        return False
    except IOError:
        dprint(__name__, 0,
               'Error loading response XML from Plex Media Server')
        return False

    # Todo: Deal with ANSI files. How to select used "codepage"?
    subtitleFile = response.read()

    print response.headers

    dprint(__name__, 1, "====== received Subtitle ======")
    dprint(__name__, 1, "{0} [...]", subtitleFile[:255])
    dprint(__name__, 1, "====== Subtitle finished ======")

    if options['PlexConnectSubtitleFormat'] == 'srt':
        subtitle = parseSRT(subtitleFile)
    else:
        return False

    JSON = json.dumps(subtitle)

    dprint(__name__, 1, "====== generated subtitle aTV subtitle JSON ======")
    dprint(__name__, 1, "{0} [...]", JSON[:255])
    dprint(__name__, 1, "====== aTV subtitle JSON finished ======")
    return (JSON)
コード例 #13
0
 def ATTRIB_PMSNAME(self, src, srcXML, param):
     UDID = self.options['PlexConnectUDID']
     PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMSaddress)
     PMS_name = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'name')
     if PMS_name == '':
         return "No Server in Proximity"
     else:
         return PMS_name
コード例 #14
0
 def ATTRIB_PMSNAME(self, src, srcXML, param):
     UDID = self.options["PlexNMTUDID"]
     PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
     PMS_name = PlexAPI.getPMSProperty(UDID, PMS_uuid, "name")
     if PMS_name == "":
         return "No Server in Proximity"
     else:
         return PMS_name
コード例 #15
0
ファイル: XMLConverter.py プロジェクト: heather81/PlexConnect
 def ATTRIB_PMSNAME(self, src, srcXML, param):
     UDID = self.options['PlexConnectUDID']
     PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
     PMS_name = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'name')
     if PMS_name=='':
         return "No Server in Proximity"
     else:
         return PMS_name
コード例 #16
0
 def __init__(self, options, PMSroot, PMS_address, path):
     self.options = options
     self.PMSroot = {'main': PMSroot}
     self.PMS_address = PMS_address  # default PMS if nothing else specified
     self.path = {'main': path}
     
     self.ATV_udid = options['PlexConnectUDID']
     self.PMS_uuid = PlexAPI.getPMSFromAddress(self.ATV_udid, PMS_address)
     self.PMS_baseURL = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid, 'baseURL')
     self.variables = {}
コード例 #17
0
ファイル: XMLConverter.py プロジェクト: joeocampo/PlexConnect
 def ATTRIB_MEDIAURL(self, src, srcXML, param):
     Video, leftover = self.getElement(src, srcXML, param)
     
     if Video!=None:
         Media = Video.find('Media')
     
     # check "Media" element and get key
     if Media!=None:
         UDID = self.options['PlexConnectUDID']
         AuthToken = g_ATVSettings.getSetting(UDID, 'myplex_auth')
         
         if g_ATVSettings.getSetting(UDID, 'transcoderaction')=='DirectPlay' \
            or \
            g_ATVSettings.getSetting(UDID, 'transcoderaction')=='Auto' and \
            Media.get('protocol','-') in ("hls") \
            or \
            g_ATVSettings.getSetting(UDID, 'transcoderaction')=='Auto' and \
            Media.get('container','-') in ("mov", "mp4") and \
            Media.get('videoCodec','-') in ("mpeg4", "h264", "drmi") and \
            Media.get('audioCodec','-') in ("aac", "ac3", "drms"):
             # direct play for...
             #    force direct play
             # or HTTP live stream
             # or native aTV media
             res, leftover, dfltd = self.getKey(Media, srcXML, 'Part/key')
             
             if Media.get('indirect', False):  # indirect... todo: select suitable resolution, today we just take first Media
                 PMS = PlexAPI.getXMLFromPMS(self.PMSaddress, res, self.options, AuthToken)  # todo... check key for trailing '/' or even 'http'
                 res, leftover, dfltd = self.getKey(PMS.getroot(), srcXML, 'Video/Media/Part/key')
             
             res = PlexAPI.getDirectVideoPath(res, AuthToken)
         
         else:
             # request transcoding
             res = Video.get('key','')
             res = PlexAPI.getTranscodeVideoPath(res, AuthToken, self.options, g_ATVSettings)
     
     else:
         dprint(__name__, 0, "MEDIAPATH - element not found: {0}", param)
         res = 'FILE_NOT_FOUND'  # not found?
     
     if res.startswith('/'):  # internal full path.
         res = 'http://' + self.PMSaddress + res
     elif res.startswith('http://'):  # external address
         hijack = g_param['HostToIntercept']
         if hijack in res:
             dprint(__name__, 1, "twisting...")
             hijack_twisted = hijack[::-1]
             res = res.replace(hijack, hijack_twisted)
             dprint(__name__, 1, res)
     else:  # internal path, add-on
         res = 'http://' + self.PMSaddress + self.path[srcXML] + res
     
     dprint(__name__, 1, 'MediaURL: {0}', res)
     return res
コード例 #18
0
ファイル: XMLConverter.py プロジェクト: liuxuan30/PlexConnect
    def __init__(self, options, PMSroot, PMS_address, path):
        self.options = options
        self.PMSroot = {'main': PMSroot}
        self.PMS_address = PMS_address  # default PMS if nothing else specified
        self.path = {'main': path}

        self.ATV_udid = options['PlexConnectUDID']
        self.PMS_uuid = PlexAPI.getPMSFromAddress(self.ATV_udid, PMS_address)
        self.PMS_baseURL = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid,
                                                  'baseURL')
        self.variables = {}
コード例 #19
0
    def getKey(self, src, srcXML, param):
        attrib, leftover = self.getParam(src, param)
        default, leftover = self.getParam(src, leftover)

        el, srcXML, attrib = self.getBase(src, srcXML, attrib)

        # walk the path if neccessary
        while '/' in attrib and el != None:
            parts = attrib.split('/', 1)
            if parts[0].startswith('#'):  # internal variable in path
                el = el.find(self.variables[parts[0][1:]])
            elif parts[0].startswith('$'):  # setting
                UDID = self.options['PlexConnectUDID']
                el = el.find(g_ATVSettings.getSetting(UDID, parts[0][1:]))
            elif parts[0].startswith('%'):  # PMS property
                UDID = self.options['PlexConnectUDID']
                PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
                el = el.find(
                    PlexAPI.getPMSProperty(UDID, PMS_uuid, parts[0][1:]))
            else:
                el = el.find(parts[0])
            attrib = parts[1]

        # check element and get attribute
        if attrib.startswith('#'):  # internal variable
            res = self.variables[attrib[1:]]
            dfltd = False
        elif attrib.startswith('$'):  # setting
            UDID = self.options['PlexConnectUDID']
            res = g_ATVSettings.getSetting(UDID, attrib[1:])
            dfltd = False
        elif attrib.startswith('%'):  # PMS property
            UDID = self.options['PlexConnectUDID']
            PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
            res = PlexAPI.getPMSProperty(UDID, PMS_uuid, attrib[1:])
            dfltd = False
        elif attrib.startswith('^'):  # aTV property, http request options
            res = self.options[attrib[1:]]
            dfltd = False
        elif el != None and attrib in el.attrib:
            res = el.get(attrib)
            dfltd = False

        else:  # path/attribute not found
            res = default
            dfltd = True

        dprint(__name__, 2, "CCmds_getKey: {0},{1},{2}", res, leftover, dfltd)
        return [res, leftover, dfltd]
コード例 #20
0
 def ATTRIB_IMAGEURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     width, leftover = self.getParam(src, leftover)
     height, leftover = self.getParam(src, leftover)
     if height=='':
         height = width
     
     PMS_uuid = self.PMS_uuid
     PMS_baseURL = self.PMS_baseURL
     cmd_start = key.find('PMS(')
     cmd_end = key.find(')', cmd_start)
     if cmd_start>-1 and cmd_end>-1 and cmd_end>cmd_start:
         PMS_address = key[cmd_start+4:cmd_end]
         PMS_uuid = PlexAPI.getPMSFromAddress(self.ATV_udid, PMS_address)
         PMS_baseURL = PlexAPI.getPMSProperty(self.ATV_udid, PMS_uuid, 'baseURL')
         key = key[cmd_end+1:]
     
     AuthToken = PlexAPI.getPMSProperty(self.ATV_udid, PMS_uuid, 'accesstoken')
     
     # transcoder action
     transcoderAction = g_ATVSettings.getSetting(self.ATV_udid, 'phototranscoderaction')
     
     # aTV native filetypes
     parts = key.rsplit('.',1)
     photoATVNative = parts[-1].lower() in ['jpg','jpeg','tif','tiff','gif','png']
     dprint(__name__, 2, "photo: ATVNative - {0}", photoATVNative)
     
     if width=='' and \
        transcoderAction=='Auto' and \
        photoATVNative:
         # direct play
         res = PlexAPI.getDirectImagePath(key, AuthToken)
     else:
         if width=='':
             width = 1920  # max for HDTV. Relate to aTV version? Increase for KenBurns effect?
         if height=='':
             height = 1080  # as above
         # request transcoding
         res = PlexAPI.getTranscodeImagePath(key, AuthToken, self.path[srcXML], width, height)
     
     if res.startswith('/'):  # internal full path.
         res = PMS_baseURL + res
     elif res.startswith('http://') or key.startswith('https://'):  # external address
         pass
     else:  # internal path, add-on
         res = PMS_baseURL + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'ImageURL: {0}', res)
     return res
コード例 #21
0
ファイル: XMLConverter.py プロジェクト: heather81/PlexConnect
 def getKey(self, src, srcXML, param):
     attrib, leftover = self.getParam(src, param)
     default, leftover = self.getParam(src, leftover)
     
     el, srcXML, attrib = self.getBase(src, srcXML, attrib)         
     
     # walk the path if neccessary
     while '/' in attrib and el!=None:
         parts = attrib.split('/',1)
         if parts[0].startswith('#'):  # internal variable in path
             el = el.find(self.variables[parts[0][1:]])
         elif parts[0].startswith('$'):  # setting
             UDID = self.options['PlexConnectUDID']
             el = el.find(g_ATVSettings.getSetting(UDID, parts[0][1:]))
         elif parts[0].startswith('%'):  # PMS property
             UDID = self.options['PlexConnectUDID']
             PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
             el = el.find(PlexAPI.getPMSProperty(UDID, PMS_uuid, parts[0][1:]))
         else:
             el = el.find(parts[0])
         attrib = parts[1]
     
     # check element and get attribute
     if attrib.startswith('#'):  # internal variable
         res = self.variables[attrib[1:]]
         dfltd = False
     elif attrib.startswith('$'):  # setting
         UDID = self.options['PlexConnectUDID']
         res = g_ATVSettings.getSetting(UDID, attrib[1:])
         dfltd = False
     elif attrib.startswith('%'):  # PMS property
         UDID = self.options['PlexConnectUDID']
         PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
         res = PlexAPI.getPMSProperty(UDID, PMS_uuid, attrib[1:])
         dfltd = False
     elif attrib.startswith('^'):  # aTV property, http request options
         res = self.options[attrib[1:]]
         dfltd = False
     elif el!=None and attrib in el.attrib:
         res = el.get(attrib)
         dfltd = False
     
     else:  # path/attribute not found
         res = default
         dfltd = True
     
     dprint(__name__, 2, "CCmds_getKey: {0},{1},{2}", res, leftover,dfltd)
     return [res,leftover,dfltd]
コード例 #22
0
ファイル: XMLConverter.py プロジェクト: nico300/PlexConnect
 def ATTRIB_URL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     
     # compare PMS_mark in PlexAPI/getXMLFromMultiplePMS()
     PMS_mark = '/PMS(' + PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid, 'ip') + ')'
     
     # overwrite with URL embedded PMS address
     cmd_start = key.find('PMS(')
     cmd_end = key.find(')', cmd_start)
     if cmd_start>-1 and cmd_end>-1 and cmd_end>cmd_start:
         PMS_mark = '/'+key[cmd_start:cmd_end+1]
         key = key[cmd_end+1:]
     
     res = g_param['baseURL']  # base address to PlexConnect
     
     if key.endswith('.js'):  # link to PlexConnect owned .js stuff
         res = res + key
     elif key.startswith('http://') or key.startswith('https://'):  # external server
         res = key
         """
         parts = urlparse.urlsplit(key)  # (scheme, networklocation, path, ...)
         key = urlparse.urlunsplit(('', '', parts[2], parts[3], parts[4]))  # keep path only
         PMS_uuid = PlexAPI.getPMSFromIP(g_param['PMS_list'], parts.hostname)
         PMSaddress = PlexAPI.getAddress(g_param['PMS_list'], PMS_uuid)  # get PMS address (might be local as well!?!)
         res = res + '/PMS(' + quote_plus(PMSaddress) + ')' + key
         """
     elif key.startswith('/'):  # internal full path.
         res = res + PMS_mark + key
     elif key == '':  # internal path
         res = res + PMS_mark + self.path[srcXML]
     else:  # internal path, add-on
         res = res + PMS_mark + self.path[srcXML] + '/' + key
     
     return res
コード例 #23
0
 def setUserPref(self):
     log.info('Setting user preferences')
     # Only try to get user avatar if there is a token
     if self.currToken:
         url = PlexAPI.PlexAPI().GetUserArtworkURL(self.currUser)
         if url:
             window('PlexUserImage', value=url)
コード例 #24
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)
        self.doUtils = DownloadUtils().downloadUrl

        self.machineIdentifier = window('plex_machineIdentifier')
コード例 #25
0
ファイル: XMLConverter.py プロジェクト: nico300/PlexConnect
 def ATTRIB_MUSICURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     
     AuthToken = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid, 'accesstoken')
     
     # direct play
     res = PlexAPI.getDirectAudioPath(key, AuthToken)
     
     if res.startswith('/'):  # internal full path.
         res = self.PMS_baseURL + res
     elif res.startswith('http://') or res.startswith('https://'):  # external address
         pass
     else:  # internal path, add-on
         res = self.PMS_baseURL + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'MusicURL: {0}', res)
     return res
コード例 #26
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.userid = window('currUserId')
        self.server = window('pms_server')
        self.machineIdentifier = window('plex_machineIdentifier')
コード例 #27
0
    def loadCurrUser(self, username, userId, usertoken, authenticated=False):
        log.debug('Loading current user')
        doUtils = self.doUtils

        self.currUserId = userId
        self.currToken = usertoken
        self.currServer = self.getServer()
        self.ssl = self.getSSLverify()
        self.sslcert = self.getSSL()

        if authenticated is False:
            log.debug('Testing validity of current token')
            res = PlexAPI.PlexAPI().CheckConnection(self.currServer,
                                                    token=self.currToken,
                                                    verifySSL=self.ssl)
            if res is False:
                # PMS probably offline
                return False
            elif res == 401:
                log.error('Token is no longer valid')
                return 401
            elif res >= 400:
                log.error('Answer from PMS is not as expected. Retrying')
                return False

        # Set to windows property
        window('currUserId', value=userId)
        window('plex_username', value=username)
        # This is the token for the current PMS (might also be '')
        window('pms_token', value=self.currToken)
        # This is the token for plex.tv for the current user
        # Is only '' if user is not signed in to plex.tv
        window('plex_token', value=settings('plexToken'))
        window('plex_restricteduser', value=settings('plex_restricteduser'))
        window('pms_server', value=self.currServer)
        window('plex_machineIdentifier', value=self.machineIdentifier)
        window('plex_servername', value=self.servername)
        window('plex_authenticated', value='true')

        window('useDirectPaths', value='true'
               if settings('useDirectPaths') == "1" else 'false')
        window('plex_force_transcode_pix', value='true'
               if settings('force_transcode_pix') == "1" else 'false')

        # Start DownloadUtils session
        doUtils.startSession(reset=True)
        # self.getAdditionalUsers()
        # Set user preferences in settings
        self.currUser = username
        self.setUserPref()

        # Writing values to settings file
        settings('username', value=username)
        settings('userid', value=userId)
        settings('accessToken', value=usertoken)
        return True
コード例 #28
0
ファイル: XMLConverter.py プロジェクト: liuxuan30/PlexConnect
    def ATTRIB_MUSICURL(self, src, srcXML, param):
        key, leftover, dfltd = self.getKey(src, srcXML, param)

        AuthToken = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid,
                                           'accesstoken')

        # direct play
        res = PlexAPI.getDirectAudioPath(key, AuthToken)

        if res.startswith('/'):  # internal full path.
            res = self.PMS_baseURL + res
        elif res.startswith('http://') or res.startswith(
                'https://'):  # external address
            pass
        else:  # internal path, add-on
            res = self.PMS_baseURL + self.path[srcXML] + '/' + res

        dprint(__name__, 1, 'MusicURL: {0}', res)
        return res
コード例 #29
0
    def ATTRIB_MUSICURL(self, src, srcXML, param):
        key, leftover, dfltd = self.getKey(src, srcXML, param)

        UDID = self.options["PlexNMTUDID"]
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
        AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, "accesstoken")

        # direct play
        res = PlexAPI.getDirectAudioPath(key, AuthToken)

        if res.startswith("/"):  # internal full path.
            res = self.PMS_baseURL + res
        elif res.startswith("http://") or res.startswith("https://"):  # external address
            pass
        else:  # internal path, add-on
            res = self.PMS_baseURL + self.path[srcXML] + "/" + res

        dprint(__name__, 1, "MusicURL: {0}", res)
        return res
コード例 #30
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.clientInfo = clientinfo.ClientInfo()

        self.userid = utils.window('currUserId')
        self.server = utils.window('pms_server')
        self.machineIdentifier = utils.window('plex_machineIdentifier')
コード例 #31
0
    def addtoPlaylist_xbmc(self, playlist, item):
        path = "plugin://plugin.video.plexkodiconnect.movies/"
        params = {'mode': "play", 'dbid': 999999999}
        API = PlexAPI.API(item[0])
        params['id'] = API.getRatingKey()
        params['filename'] = API.getKey()
        playurl = path + '?' + urlencode(params)

        listitem = xbmcgui.ListItem()

        playlist.add(playurl, listitem)
コード例 #32
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.userid = window('currUserId')
        self.server = window('pms_server')

        if self.API.getType() == 'track':
            self.pl = playlist.Playlist(typus='music')
        else:
            self.pl = playlist.Playlist(typus='video')
コード例 #33
0
    def TREE_ADDXML(self, elem, child, src, srcXML, param):
        tag, leftover = self.getParam(src, param)
        key, leftover, dfltd = self.getKey(src, srcXML, leftover)

        if "PlexNMTUDID" in self.options:
            UDID = self.options["PlexNMTUDID"]
            PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
            auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, "accesstoken")
        else:
            auth_token = ""

        if key.startswith("//"):  # local servers signature
            pathstart = key.find("/", 3)
            type = key[2:pathstart]
            path = key[pathstart:]
            PMS = PlexAPI.getXMLFromMultiplePMS(UDID, path, type, self.options)
        elif key.startswith("/"):  # internal full path.
            path = key
            PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options, auth_token)
        # elif key.startswith('http://'):  # external address
        #    path = key
        elif key == "":  # internal path
            path = self.path[srcXML]
            PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options, auth_token)
        else:  # internal path, add-on
            path = self.path[srcXML] + "/" + key
            PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options, auth_token)

        self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
        self.path[tag] = path  # store base path

        return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #34
0
    def TREE_ADDXML(self, elem, child, src, srcXML, param):
        tag, leftover = self.getParam(src, param)
        key, leftover, dfltd = self.getKey(src, srcXML, leftover)

        if 'PlexNMTUDID' in self.options:
            UDID = self.options['PlexNMTUDID']
            PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
            auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
        else:
            auth_token = ''

        if key.startswith('//'):  # local servers signature
            pathstart = key.find('/', 3)
            type = key[2:pathstart]
            path = key[pathstart:]
            PMS = PlexAPI.getXMLFromMultiplePMS(UDID, path, type, self.options)
        elif key.startswith('/'):  # internal full path.
            path = key
            PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options,
                                        auth_token)
        #elif key.startswith('http://'):  # external address
        #    path = key
        elif key == '':  # internal path
            path = self.path[srcXML]
            PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options,
                                        auth_token)
        else:  # internal path, add-on
            path = self.path[srcXML] + '/' + key
            PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, path, self.options,
                                        auth_token)

        self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
        self.path[tag] = path  # store base path

        return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #35
0
ファイル: XMLConverter.py プロジェクト: joeocampo/PlexConnect
 def ATTRIB_URL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     
     res = 'http://' + g_param['HostOfPlexConnect']  # base address to PlexConnect
     
     if key.endswith('.js'):  # link to PlexConnect owned .js stuff
         pass
     elif key.startswith('http://'):  # external server
         parts = urlparse.urlsplit(key)  # (scheme, networklocation, path, ...)
         key = urlparse.urlunsplit(('', '', parts[2], parts[3], parts[4]))  # keep path only
         PMS_uuid = PlexAPI.getPMSFromIP(g_param['PMS_list'], parts.hostname)
         PMSaddress = PlexAPI.getAddress(g_param['PMS_list'], PMS_uuid)  # get PMS address (might be local as well!?!)
         res = res + '/PMS(' + quote_plus(PMSaddress) + ')'
     else:  # include current PMS address
         res = res + '/PMS(' + quote_plus(self.PMSaddress) + ')'
     
     if key.startswith('/'):  # internal full path.
         res = res + key
     elif key == '':  # internal path
         res = res + self.path[srcXML]
     else:  # internal path, add-on
         res = res + self.path[srcXML] + '/' + key
     return res
コード例 #36
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()

        self.userid = utils.window('currUserId')
        self.server = utils.window('pms_server')

        self.artwork = artwork.Artwork()
        self.emby = embyserver.Read_EmbyServer()
        self.pl = playlist.Playlist()
コード例 #37
0
ファイル: playlist.py プロジェクト: im85288/PlexKodiConnect
    def addtoPlaylist_xbmc(self, playlist, item):
        API = PlexAPI.API(item[0])
        params = {
            'mode': "play",
            'dbid': 999999999,
            'id': API.getRatingKey(),
            'filename': API.getKey()
        }
        playurl = "plugin://plugin.video.plexkodiconnect.movies/?%s" \
            % urlencode(params)

        listitem = API.CreateListItemFromPlexItem()
        playbackutils.PlaybackUtils(item[0]).setArtwork(listitem)

        playlist.add(playurl, listitem)
コード例 #38
0
ファイル: XMLConverter.py プロジェクト: pbaeten/PlexConnect
    def ATTRIB_MUSICURL(self, src, srcXML, param):
        key, leftover, dfltd = self.getKey(src, srcXML, param)

        UDID = self.options["PlexConnectUDID"]
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
        AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, "accesstoken")

        # direct play
        res = PlexAPI.getDirectAudioPath(key, AuthToken)

        if res.startswith("/"):  # internal full path.
            res = self.PMS_baseURL + res
        elif res.startswith("http://") or key.startswith("https://"):  # external address
            hijack = g_param["HostToIntercept"]
            if hijack in res:
                dprint(__name__, 1, "twisting...")
                hijack_twisted = hijack[::-1]
                res = res.replace(hijack, hijack_twisted)
                dprint(__name__, 1, res)
        else:  # internal path, add-on
            res = self.PMS_baseURL + self.path[srcXML] + "/" + res

        dprint(__name__, 1, "MusicURL: {0}", res)
        return res
コード例 #39
0
 def ATTRIB_BACKGROUNDURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     
     if key.startswith('/'):  # internal full path.
         key = self.PMS_baseURL + key
     elif key.startswith('http://') or key.startswith('https://'):  # external address
         pass
     else:  # internal path, add-on
         key = self.PMS_baseURL + self.path[srcXML] + key
     
     auth_token = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid, 'accesstoken')
     
     dprint(__name__, 0, "Background (Source): {0}", key)
     res = g_param['baseURL']  # base address to PlexConnect
     res = res + PILBackgrounds.generate(self.PMS_uuid, key, auth_token, self.options['aTVScreenResolution'], g_ATVSettings.getSetting(self.ATV_udid, 'fanart_blur'))
     dprint(__name__, 0, "Background: {0}", res)
     return res
コード例 #40
0
    def __init__(self):
        log.debug('Entering initialsetup class')
        self.clientInfo = clientinfo.ClientInfo()
        self.addonId = self.clientInfo.getAddonId()
        self.doUtils = downloadutils.DownloadUtils().downloadUrl
        self.userClient = userclient.UserClient()
        self.plx = PlexAPI.PlexAPI()
        self.dialog = xbmcgui.Dialog()

        self.server = self.userClient.getServer()
        self.serverid = settings('plex_machineIdentifier')
        # Get Plex credentials from settings file, if they exist
        plexdict = self.plx.GetPlexLoginFromSettings()
        self.myplexlogin = plexdict['myplexlogin'] == 'true'
        self.plexLogin = plexdict['plexLogin']
        self.plexToken = plexdict['plexToken']
        self.plexid = plexdict['plexid']
        if self.plexToken:
            log.debug('Found a plex.tv token in the settings')
コード例 #41
0
    def AddTrailers(self, xml):
        """
        Adds trailers to a movie, if applicable. Returns True if trailers were
        added
        """
        # Failure when downloading trailer playQueue
        if xml in (None, 401):
            return False
        # Failure when getting trailers, e.g. when no plex pass
        if xml.attrib.get('size') == '1':
            return False

        if settings('askCinema') == "true":
            resp = xbmcgui.Dialog().yesno(addonName, "Play trailers?")
            if not resp:
                # User selected to not play trailers
                log.info("Skip trailers.")
                return False

        # Playurl needs to point back so we can get metadata!
        path = "plugin://plugin.video.plexkodiconnect.movies/"
        params = {
            'mode': "play",
            'dbid': 999999999
        }
        for counter, intro in enumerate(xml):
            # Don't process the last item - it's the original movie
            if counter == len(xml)-1:
                break
            # The server randomly returns intros, process them.
            # introListItem = xbmcgui.ListItem()
            # introPlayurl = putils.PlayUtils(intro).getPlayUrl()
            introAPI = PlexAPI.API(intro)
            params['id'] = introAPI.getRatingKey()
            params['filename'] = introAPI.getKey()
            introPlayurl = path + '?' + urlencode(params)
            log.info("Adding Intro: %s" % introPlayurl)

            self.pl.insertintoPlaylist(self.currentPosition, url=introPlayurl)
            self.currentPosition += 1

        return True
コード例 #42
0
    def __init__(self):
        self.kodi_id = xbmc.getInfoLabel('ListItem.DBID').decode('utf-8')
        self.item_type = self._get_item_type()
        self.item_id = self._get_item_id(self.kodi_id, self.item_type)

        log.info("Found item_id: %s item_type: %s"
                 % (self.item_id, self.item_type))

        if not self.item_id:
            return

        self.item = GetPlexMetadata(self.item_id)
        self.api = PlexAPI.API(self.item)

        if self._select_menu():
            self._action_menu()

            if self._selected_option in (OPTIONS['Delete'],
                                         OPTIONS['Refresh']):
                log.info("refreshing container")
                xbmc.sleep(500)
                xbmc.executebuiltin('Container.Refresh')
コード例 #43
0
ファイル: XMLConverter.py プロジェクト: joeocampo/PlexConnect
 def ATTRIB_MUSICURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     
     UDID = self.options['PlexConnectUDID']
     AuthToken = g_ATVSettings.getSetting(UDID, 'myplex_auth')
     
     # direct play
     res = PlexAPI.getDirectAudioPath(key, AuthToken)
     
     if res.startswith('/'):  # internal full path.
         res = 'http://' + self.PMSaddress + res
     elif res.startswith('http://'):  # external address
         hijack = g_param['HostToIntercept']
         if hijack in res:
             dprint(__name__, 1, "twisting...")
             hijack_twisted = hijack[::-1]
             res = res.replace(hijack, hijack_twisted)
             dprint(__name__, 1, res)
     else:  # internal path, add-on
         res = 'http://' + self.PMSaddress + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'MusicURL: {0}', res)
     return res
コード例 #44
0
ファイル: XMLConverter.py プロジェクト: fredfri/PlexConnect
 def ATTRIB_MUSICURL(self, src, srcXML, param):
     key, leftover, dfltd = self.getKey(src, srcXML, param)
     
     UDID = self.options['PlexConnectUDID']
     AuthToken = g_ATVSettings.getSetting(UDID, 'myplex_auth')
     
     # direct play
     res = PlexAPI.getDirectAudioPath(key, AuthToken)
     
     if res.startswith('/'):  # internal full path.
         res = 'http://' + self.PMSaddress + res
     elif res.startswith('http://'):  # external address
         hijack = g_param['HostToIntercept']
         if hijack in res:
             dprint(__name__, 1, "twisting...")
             hijack_twisted = hijack[::-1]
             res = res.replace(hijack, hijack_twisted)
             dprint(__name__, 1, res)
     else:  # internal path, add-on
         res = 'http://' + self.PMSaddress + self.path[srcXML] + '/' + res
     
     dprint(__name__, 1, 'MusicURL: {0}', res)
     return res
コード例 #45
0
 def ATTRIB_MUSICURL(self, src, srcXML, param):
     Track, leftover = self.getElement(src, srcXML, param)
     
     AuthToken = PlexAPI.getPMSProperty(self.ATV_udid, self.PMS_uuid, 'accesstoken')
     
     if not Track:
         # not a complete audio/track structure - take key directly and build direct-play path
         key, leftover, dfltd = self.getKey(src, srcXML, param)
         res = PlexAPI.getDirectAudioPath(key, AuthToken)
         res = PlexAPI.getURL(self.PMS_baseURL, self.path[srcXML], res)
         dprint(__name__, 1, 'MusicURL - direct: {0}', res)
         return res
     
     # complete track structure - request transcoding if needed
     Media = Track.find('Media')
     
     # check "Media" element and get key
     if Media!=None:
         # transcoder action setting?
         # transcoder bitrate setting [kbps] -  eg. 128, 256, 384, 512?
         maxAudioBitrate = '384'
         
         audioATVNative = \
             Media.get('audioCodec','-') in ("mp3", "aac", "ac3", "drms", "alac", "aiff", "wav")
         # check Media.get('container') as well - mp3, m4a, ...?
         
         dprint(__name__, 2, "audio: ATVNative - {0}", audioATVNative)
         
         if audioATVNative and\
            int(Media.get('bitrate','0')) < int(maxAudioBitrate):
             # direct play
             res, leftover, dfltd = self.getKey(Media, srcXML, 'Part/key')
             res = PlexAPI.getDirectAudioPath(res, AuthToken)
         else:
             # request transcoding
             res, leftover, dfltd = self.getKey(Track, srcXML, 'key')
             res = PlexAPI.getTranscodeAudioPath(res, AuthToken, self.options, maxAudioBitrate)
     
     else:
         dprint(__name__, 0, "MEDIAPATH - element not found: {0}", param)
         res = 'FILE_NOT_FOUND'  # not found?
     
     res = PlexAPI.getURL(self.PMS_baseURL, self.path[srcXML], res)
     dprint(__name__, 1, 'MusicURL: {0}', res)
     return res
コード例 #46
0
ファイル: playlist.py プロジェクト: kageurufu/PlexKodiConnect
 def _initiatePlaylist(self):
     log.info('Initiating playlist')
     playlist = None
     with embydb.GetEmbyDB() as emby_db:
         for item in self.items:
             itemid = item['plexId']
             embydb_item = emby_db.getItem_byId(itemid)
             try:
                 mediatype = embydb_item[4]
             except TypeError:
                 log.info('Couldnt find item %s in Kodi db' % itemid)
                 item = PlexFunctions.GetPlexMetadata(itemid)
                 if item in (None, 401):
                     log.info('Couldnt find item %s on PMS, trying next' %
                              itemid)
                     continue
                 if PlexAPI.API(item[0]).getType() == 'track':
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
                     log.info('Music playlist initiated')
                     self.typus = 'music'
                 else:
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
                     log.info('Video playlist initiated')
                     self.typus = 'video'
             else:
                 if mediatype == 'song':
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
                     log.info('Music playlist initiated')
                     self.typus = 'music'
                 else:
                     playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
                     log.info('Video playlist initiated')
                     self.typus = 'video'
             break
     self.playlist = playlist
     if self.playlist is not None:
         self.playlistId = self.playlist.getPlayListId()
コード例 #47
0
 def TREE_ADDXML(self, elem, child, src, srcXML, param):
     tag, leftover = self.getParam(src, param)
     key, leftover, dfltd = self.getKey(src, srcXML, leftover)
     
     if 'PlexConnectUDID' in self.options:
         UDID = self.options['PlexConnectUDID']
         PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMSaddress)
         auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
         scheme = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'scheme')
     else:
         auth_token = ''
         scheme = 'http'
     if key.startswith('//'):  # local servers signature
         pathstart = key.find('/',3)
         type = key[2:pathstart]
         path = key[pathstart:]
         PMS = PlexAPI.getXMLFromMultiplePMS(UDID, path, type, self.options)
     elif key.startswith('/'):  # internal full path.
         path = key
         PMS = PlexAPI.getXMLFromPMS(scheme+'://'+self.PMSaddress, path, self.options, auth_token)
     #elif key.startswith('http://'):  # external address
     #    path = key
     #    hijack = g_param['HostToIntercept']
     #    if hijack in path:
     #        dprint(__name__, 1, "twisting...")
     #        hijack_twisted = hijack[::-1]
     #        path = path.replace(hijack, hijack_twisted)
     #        dprint(__name__, 1, path)
     elif key == '':  # internal path
         path = self.path[srcXML]
         PMS = PlexAPI.getXMLFromPMS(scheme+'://'+self.PMSaddress, path, self.options, auth_token)
     else:  # internal path, add-on
         path = self.path[srcXML] + '/' + key
         PMS = PlexAPI.getXMLFromPMS(scheme+'://'+self.PMSaddress, path, self.options, auth_token)
     
     self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
     self.path[tag] = path  # store base path
     
     return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #48
0
ファイル: XMLConverter.py プロジェクト: liuxuan30/PlexConnect
    def ATTRIB_URL(self, src, srcXML, param):
        key, leftover, dfltd = self.getKey(src, srcXML, param)

        # compare PMS_mark in PlexAPI/getXMLFromMultiplePMS()
        PMS_mark = '/PMS(' + PlexAPI.getPMSProperty(self.ATV_udid,
                                                    self.PMS_uuid, 'ip') + ')'

        # overwrite with URL embedded PMS address
        cmd_start = key.find('PMS(')
        cmd_end = key.find(')', cmd_start)
        if cmd_start > -1 and cmd_end > -1 and cmd_end > cmd_start:
            PMS_mark = '/' + key[cmd_start:cmd_end + 1]
            key = key[cmd_end + 1:]

        res = g_param['baseURL']  # base address to PlexConnect

        if key.endswith('.js'):  # link to PlexConnect owned .js stuff
            res = res + key
        elif key.startswith('http://') or key.startswith(
                'https://'):  # external server
            res = key
            """
            parts = urlparse.urlsplit(key)  # (scheme, networklocation, path, ...)
            key = urlparse.urlunsplit(('', '', parts[2], parts[3], parts[4]))  # keep path only
            PMS_uuid = PlexAPI.getPMSFromIP(g_param['PMS_list'], parts.hostname)
            PMSaddress = PlexAPI.getAddress(g_param['PMS_list'], PMS_uuid)  # get PMS address (might be local as well!?!)
            res = res + '/PMS(' + quote_plus(PMSaddress) + ')' + key
            """
        elif key.startswith('/'):  # internal full path.
            res = res + PMS_mark + key
        elif key == '':  # internal path
            res = res + PMS_mark + self.path[srcXML]
        else:  # internal path, add-on
            res = res + PMS_mark + self.path[srcXML] + '/' + key

        return res
コード例 #49
0
ファイル: XMLConverter.py プロジェクト: akso/PlexConnect
 def TREE_ADDXML(self, elem, child, src, srcXML, param):
     tag, leftover = self.getParam(src, param)
     key, leftover, dfltd = self.getKey(src, srcXML, leftover)
     
     if key.startswith('/'):  # internal full path.
         path = key
     #elif key.startswith('http://'):  # external address
     #    path = key
     #    hijack = g_param['HostToIntercept']
     #    if hijack in path:
     #        dprint(__name__, 1, "twisting...")
     #        hijack_twisted = hijack[::-1]
     #        path = path.replace(hijack, hijack_twisted)
     #        dprint(__name__, 1, path)
     elif key == '':  # internal path
         path = self.path[srcXML]
     else:  # internal path, add-on
         path = self.path[srcXML] + '/' + key
     
     PMS = PlexAPI.getXMLFromPMS(g_param['Addr_PMS'], path)
     self.PMSroot[tag] = PMS.getroot()  # store additional PMS XML
     self.path[tag] = path  # store base path
     
     return False  # tree unchanged (well, source tree yes. but that doesn't count...)
コード例 #50
0
    def ATTRIB_MEDIAURL(self, src, srcXML, param):
        Video, leftover = self.getElement(src, srcXML, param)

        UDID = self.options['PlexConnectUDID']
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMSaddress)
        AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')

        if not Video:
            # not a complete video structure - take key directly and build direct-play path
            key, leftover, dfltd = self.getKey(src, srcXML, param)
            res = PlexAPI.getDirectVideoPath(key, AuthToken)
            res = PlexAPI.getURL('http://' + self.PMSaddress,
                                 self.path[srcXML], res)
            return res

        # complete video structure - request transcoding if needed
        Media = Video.find('Media')

        # check "Media" element and get key
        if Media != None:
            if g_ATVSettings.getSetting(UDID, 'transcoderaction')=='DirectPlay' \
               or \
               g_ATVSettings.getSetting(UDID, 'transcoderaction')=='Auto' and \
               Media.get('protocol','-') in ("hls") \
               or \
               g_ATVSettings.getSetting(UDID, 'transcoderaction')=='Auto' and \
               Media.get('container','-') in ("mov", "mp4") and \
               Media.get('videoCodec','-') in ("mpeg4", "h264", "drmi") and \
               Media.get('audioCodec','-') in ("aac", "ac3", "drms"):
                # direct play for...
                #    force direct play
                # or HTTP live stream
                # or native aTV media
                res, leftover, dfltd = self.getKey(Media, srcXML, 'Part/key')

                if Media.get(
                        'indirect', False
                ):  # indirect... todo: select suitable resolution, today we just take first Media
                    PMS = PlexAPI.getXMLFromPMS(
                        'http://' + self.PMSaddress, res, self.options,
                        AuthToken
                    )  # todo... check key for trailing '/' or even 'http'
                    res, leftover, dfltd = self.getKey(PMS.getroot(), srcXML,
                                                       'Video/Media/Part/key')

                res = PlexAPI.getDirectVideoPath(res, AuthToken)

            else:
                # request transcoding
                res = Video.get('key', '')
                res = PlexAPI.getTranscodeVideoPath(res, AuthToken,
                                                    self.options,
                                                    g_ATVSettings)

        else:
            dprint(__name__, 0, "MEDIAPATH - element not found: {0}", param)
            res = 'FILE_NOT_FOUND'  # not found?

        if res.startswith('/'):  # internal full path.
            res = 'http://' + self.PMSaddress + res
        elif res.startswith('http://'):  # external address
            hijack = g_param['HostToIntercept']
            if hijack in res:
                dprint(__name__, 1, "twisting...")
                hijack_twisted = hijack[::-1]
                res = res.replace(hijack, hijack_twisted)
                dprint(__name__, 1, res)
        else:  # internal path, add-on
            res = 'http://' + self.PMSaddress + self.path[srcXML] + res

        dprint(__name__, 1, 'MediaURL: {0}', res)
        return res
コード例 #51
0
ファイル: XMLConverter.py プロジェクト: heather81/PlexConnect
def XML_PMS2aTV(PMS_baseURL, path, options):
    # double check aTV UDID, redo from client IP if needed/possible
    if not 'PlexConnectUDID' in options:
        UDID = getATVFromIP(options['aTVAddress'])
        if UDID:
            options['PlexConnectUDID'] = UDID
    else:
        declareATV(options['PlexConnectUDID'], options['aTVAddress'])  # update with latest info
    
    # check cmd to work on
    cmd = ''
    if 'PlexConnect' in options:
        cmd = options['PlexConnect']
    dprint(__name__, 1, "PlexConnect Cmd: "+cmd)
    
    # check aTV language setting
    if not 'aTVLanguage' in options:
        dprint(__name__, 1, "no aTVLanguage - pick en")
        options['aTVLanguage'] = 'en'
    
    # XML Template selector
    # - PlexConnect command
    # - path
    # - PMS ViewGroup
    XMLtemplate = ''
    PMS = None
    PMSroot = None
    
    # XML direct request or
    # XMLtemplate defined by solely PlexConnect Cmd
    if path.endswith(".xml"):
        XMLtemplate = path.lstrip('/')
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd=='Play':
        XMLtemplate = 'PlayVideo.xml'
    
    elif cmd=='PlayVideo_ChannelsV1':
        dprint(__name__, 1, "playing Channels XML Version 1: {0}".format(path))
        UDID = options['PlexConnectUDID']
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_baseURL)
        auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
        path = PlexAPI.getDirectVideoPath(path, auth_token)
        return XML_PlayVideo_ChannelsV1(PMS_baseURL, path)  # direct link, no PMS XML available
    
    elif cmd=='PlayTrailer':
        trailerID = options['PlexConnectTrailerID']
        info = urllib2.urlopen("http://youtube.com/get_video_info?video_id=" + trailerID).read()
        parsed = urlparse.parse_qs(info)
        
        key = 'url_encoded_fmt_stream_map'
        if not key in parsed:
            return XML_Error('PlexConnect', 'Youtube: No Trailer Info available')
        streams = parsed[key][0].split(',')
        
        url = ''
        for i in range(len(streams)):
            stream = urlparse.parse_qs(streams[i])
            if stream['itag'][0] == '18':
                url = stream['url'][0] + '&signature=' + stream['sig'][0]
        if url == '':
            return XML_Error('PlexConnect','Youtube: ATV compatible Trailer not available')
        
        return XML_PlayVideo_ChannelsV1('', url.replace('&','&amp;'))

    elif cmd=='ScrobbleMenu':
        XMLtemplate = 'ScrobbleMenu.xml'

    elif cmd=='ScrobbleMenuVideo':
        XMLtemplate = 'ScrobbleMenuVideo.xml'

    elif cmd=='ScrobbleMenuTVOnDeck':
        XMLtemplate = 'ScrobbleMenuTVOnDeck.xml'
        
    elif cmd=='ChangeShowArtwork':
        XMLtemplate = 'ChangeShowArtwork.xml'

    elif cmd=='ChangeSingleArtwork':
        XMLtemplate = 'ChangeSingleArtwork.xml'

    elif cmd=='ChangeSingleArtworkVideo':
        XMLtemplate = 'ChangeSingleArtworkVideo.xml'
        
    elif cmd=='PhotoBrowser':
        XMLtemplate = 'Photo_Browser.xml'
        
    elif cmd=='MoviePreview':
        XMLtemplate = 'MoviePreview.xml'
    
    elif cmd=='HomeVideoPrePlay':
        XMLtemplate = 'HomeVideoPrePlay.xml'
        
    elif cmd=='MoviePrePlay':
        XMLtemplate = 'MoviePrePlay.xml'

    elif cmd=='EpisodePrePlay':
        XMLtemplate = 'EpisodePrePlay.xml'
        
    elif cmd=='ChannelPrePlay':
        XMLtemplate = 'ChannelPrePlay.xml'
    
    elif cmd=='ChannelsVideo':
        XMLtemplate = 'ChannelsVideo.xml'

    elif cmd=='ByFolder':
        XMLtemplate = 'ByFolder.xml'

    elif cmd=='HomeVideoByFolder':
        XMLtemplate = 'HomeVideoByFolder.xml'

    elif cmd == 'HomeVideoDirectory':
        XMLtemplate = 'HomeVideoDirectory.xml'

    elif cmd=='MovieByFolder':
        XMLtemplate = 'MovieByFolder.xml'

    elif cmd == 'MovieDirectory':
        XMLtemplate = 'MovieDirectory.xml'

    elif cmd == 'MovieSection':
        XMLtemplate = 'MovieSection.xml'
    
    elif cmd == 'HomeVideoSection':
        XMLtemplate = 'HomeVideoSection.xml'
        
    elif cmd == 'TVSection':
        XMLtemplate = 'TVSection.xml'
    
    elif cmd.find('SectionPreview') != -1:
        XMLtemplate = cmd + '.xml'
    
    elif cmd == 'AllMovies':
        XMLtemplate = 'Movie_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'movieview').replace(' ','')+'.xml'  
    
    elif cmd == 'AllHomeVideos':
        XMLtemplate = 'HomeVideo_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'homevideoview').replace(' ','')+'.xml'  
        
    elif cmd == 'MovieSecondary':
        XMLtemplate = 'MovieSecondary.xml'
    
    elif cmd == 'AllShows':
        XMLtemplate = 'Show_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'showview')+'.xml'  
          
    elif cmd == 'TVSecondary':
        XMLtemplate = 'TVSecondary.xml'
        
    elif cmd == 'PhotoSecondary':
        XMLtemplate = 'PhotoSecondary.xml'
        
    elif cmd == 'Directory':
        XMLtemplate = 'Directory.xml'
    
    elif cmd == 'DirectoryWithPreview':
        XMLtemplate = 'DirectoryWithPreview.xml'

    elif cmd == 'DirectoryWithPreviewActors':
        XMLtemplate = 'DirectoryWithPreviewActors.xml'
            
    elif cmd=='Settings':
        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd=='SettingsVideoOSD':
        XMLtemplate = 'Settings_VideoOSD.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd=='SettingsMovies':
        XMLtemplate = 'Settings_Movies.xml'
        path = ''  # clear path - we don't need PMS-XML
        
    elif cmd=='SettingsTVShows':
        XMLtemplate = 'Settings_TVShows.xml'
        path = ''  # clear path - we don't need PMS-XML
 
    elif cmd=='SettingsHomeVideos':
        XMLtemplate = 'Settings_HomeVideos.xml'
        path = ''  # clear path - we don't need PMS-XML
        
    elif cmd.startswith('SettingsToggle:'):
        opt = cmd[len('SettingsToggle:'):]  # cut command:
        parts = opt.split('+')
        g_ATVSettings.toggleSetting(options['PlexConnectUDID'], parts[0].lower())
        XMLtemplate = parts[1] + ".xml"
        dprint(__name__, 2, "ATVSettings->Toggle: {0} in template: {1}", parts[0], parts[1])
        
        path = ''  # clear path - we don't need PMS-XML
        
    elif cmd==('MyPlexLogin'):
        dprint(__name__, 2, "MyPlex->Logging In...")
        if not 'PlexConnectCredentials' in options:
            return XML_Error('PlexConnect', 'MyPlex Sign In called without Credentials.')
        
        parts = options['PlexConnectCredentials'].split(':',1)        
        (username, auth_token) = PlexAPI.MyPlexSignIn(parts[0], parts[1], options)
        
        UDID = options['PlexConnectUDID']
        g_ATVSettings.setSetting(UDID, 'myplex_user', username)
        g_ATVSettings.setSetting(UDID, 'myplex_auth', auth_token)
        
        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd=='MyPlexLogout':
        dprint(__name__, 2, "MyPlex->Logging Out...")
        
        UDID = options['PlexConnectUDID']
        auth_token = g_ATVSettings.getSetting(UDID, 'myplex_auth')
        PlexAPI.MyPlexSignOut(auth_token)
        
        g_ATVSettings.setSetting(UDID, 'myplex_user', '')
        g_ATVSettings.setSetting(UDID, 'myplex_auth', '')
        
        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd.startswith('Discover'):
        UDID = options['PlexConnectUDID']
        auth_token = g_ATVSettings.getSetting(UDID, 'myplex_auth')
        PlexAPI.discoverPMS(UDID, g_param['CSettings'], auth_token)
        
        return XML_Error('PlexConnect', 'Discover!')  # not an error - but aTV won't care anyways.
    
    elif path.startswith('/search?'):
        XMLtemplate = 'Search_Results.xml'
    
    elif path=='/library/sections':  # from PlexConnect.xml -> for //local, //myplex
        XMLtemplate = 'Library.xml'
    
    elif path=='/channels/all':
        XMLtemplate = 'Channel_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'channelview')+'.xml'
        path = ''
    
    # request PMS XML
    if not path=='':
        if 'PlexConnectUDID' in options:
            UDID = options['PlexConnectUDID']
            PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_baseURL)
            auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
        else:
            auth_token = ''
        
        if PMS_baseURL.startswith('//'):  # //local, //myplex
            UDID = options['PlexConnectUDID']
            type = PMS_baseURL[2:]
            PMS = PlexAPI.getXMLFromMultiplePMS(UDID, path, type, options)
        else:
            PMS = PlexAPI.getXMLFromPMS(PMS_baseURL, path, options, authtoken=auth_token)
        
        if PMS==False:
            return XML_Error('PlexConnect', 'No Response from Plex Media Server')
        
        PMSroot = PMS.getroot()
        
        dprint(__name__, 1, "viewGroup: "+PMSroot.get('ViewGroup','None'))
    
    # XMLtemplate defined by PMS XML content
    if path=='':
        pass  # nothing to load
    
    elif not XMLtemplate=='':
        pass  # template already selected

    elif PMSroot.get('viewGroup','')=="secondary" and (PMSroot.get('art','').find('video') != -1 or PMSroot.get('thumb','').find('video') != -1):
        XMLtemplate = 'HomeVideoSectionTopLevel.xml'

    elif PMSroot.get('viewGroup','')=="secondary" and (PMSroot.get('art','').find('movie') != -1 or PMSroot.get('thumb','').find('movie') != -1):
        XMLtemplate = 'MovieSectionTopLevel.xml'
    
    elif PMSroot.get('viewGroup','')=="secondary" and (PMSroot.get('art','').find('show') != -1 or PMSroot.get('thumb','').find('show') != -1):
        XMLtemplate = 'TVSectionTopLevel.xml'
        
    elif PMSroot.get('viewGroup','')=="secondary" and (PMSroot.get('art','').find('photo') != -1 or PMSroot.get('thumb','').find('photo') != -1):
        XMLtemplate = 'PhotoSectionTopLevel.xml'
        
    elif PMSroot.get('viewGroup','')=="secondary":
        XMLtemplate = 'Directory.xml'
    
    elif PMSroot.get('viewGroup','')=='show':
        if PMSroot.get('title2')=='By Folder':
          # By Folder View
          XMLtemplate = 'ByFolder.xml'
        else:
          # TV Show grid view
          XMLtemplate = 'Show_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'showview')+'.xml'
        
    elif PMSroot.get('viewGroup','')=='season':
        # TV Season view
        XMLtemplate = 'Season_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'seasonview')+'.xml'

    elif PMSroot.get('viewGroup','')=='movie' and PMSroot.get('thumb','').find('video') != -1:
        if PMSroot.get('title2')=='By Folder':
          # By Folder View
          XMLtemplate = 'HomeVideoByFolder.xml'
        else:
          # Home Video listing
          XMLtemplate = 'HomeVideo_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'homevideoview').replace(' ','')+'.xml'
    
    elif PMSroot.get('viewGroup','')=='movie' and PMSroot.get('thumb','').find('movie') != -1:
        if PMSroot.get('title2')=='By Folder':
          # By Folder View
          XMLtemplate = 'MovieByFolder.xml'
        else:
          # Movie listing
          XMLtemplate = 'Movie_'+g_ATVSettings.getSetting(options['PlexConnectUDID'], 'homevideoview').replace(' ','')+'.xml'
          
    elif PMSroot.get('viewGroup','')=='track':
        XMLtemplate = 'Music_Track.xml'
   
    elif PMSroot.get('viewGroup','')=='episode':
        if PMSroot.get('title2')=='On Deck' or \
           PMSroot.get('title2')=='Recently Viewed Episodes' or \
           PMSroot.get('title2')=='Recently Aired' or \
           PMSroot.get('title2')=='Recently Added':
            # TV On Deck View
            XMLtemplate = 'TV_OnDeck.xml'
        else:
            # TV Episode view
            XMLtemplate = 'Episode.xml'
    
    elif PMSroot.get('viewGroup','')=='photo':
        # Photo listing
        XMLtemplate = 'Photo.xml'
    
    else:
        XMLtemplate = 'Directory.xml'
    
    dprint(__name__, 1, "XMLTemplate: "+XMLtemplate)
    
    # get XMLtemplate
    aTVTree = etree.parse(sys.path[0]+'/assets/templates/'+XMLtemplate)
    aTVroot = aTVTree.getroot()
    
    # convert PMS XML to aTV XML using provided XMLtemplate
    global g_CommandCollection
    g_CommandCollection = CCommandCollection(options, PMSroot, PMS_baseURL, path)
    XML_ExpandTree(aTVroot, PMSroot, 'main')
    XML_ExpandAllAttrib(aTVroot, PMSroot, 'main')
    del g_CommandCollection
    
    dprint(__name__, 1, "====== generated aTV-XML ======")
    dprint(__name__, 1, prettyXML(aTVTree))
    dprint(__name__, 1, "====== aTV-XML finished ======")
    
    return etree.tostring(aTVroot)
コード例 #52
0
ファイル: XMLConverter.py プロジェクト: heather81/PlexConnect
 def ATTRIB_PMSCOUNT(self, src, srcXML, param):
     UDID = self.options['PlexConnectUDID']
     return str(PlexAPI.getPMSCount(UDID))
コード例 #53
0
ファイル: XMLConverter.py プロジェクト: heather81/PlexConnect
 def ATTRIB_MEDIAURL(self, src, srcXML, param):
     Video, leftover = self.getElement(src, srcXML, param)
     
     UDID = self.options['PlexConnectUDID']
     PMS_uuid = PlexAPI.getPMSFromAddress(UDID, self.PMS_baseURL)
     AuthToken = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
     
     if not Video:
         # not a complete video structure - take key directly and build direct-play path
         key, leftover, dfltd = self.getKey(src, srcXML, param)
         res = PlexAPI.getDirectVideoPath(key, AuthToken)
         res = PlexAPI.getURL(self.PMS_baseURL, self.path[srcXML], res)
         return res
     
     # complete video structure - request transcoding if needed
     Media = Video.find('Media')
     
     # check "Media" element and get key
     if Media!=None:
         # transcoder action
         transcoderAction = g_ATVSettings.getSetting(UDID, 'transcoderaction')
         
         # video format
         #    HTTP live stream
         # or native aTV media
         videoATVNative = \
             Media.get('protocol','-') in ("hls") \
             or \
             Media.get('container','-') in ("mov", "mp4") and \
             Media.get('videoCodec','-') in ("mpeg4", "h264", "drmi") and \
             Media.get('audioCodec','-') in ("aac", "ac3", "drms")
         dprint(__name__, 2, "video: ATVNative - {0}", videoATVNative)
         
         # quality limits: quality=(resolution, quality, bitrate)
         qLookup = { '480p 2.0Mbps' :('720x480', '60', '2000'), \
                     '720p 3.0Mbps' :('1280x720', '75', '3000'), \
                     '720p 4.0Mbps' :('1280x720', '100', '4000'), \
                     '1080p 8.0Mbps' :('1920x1080', '60', '8000'), \
                     '1080p 10.0Mbps' :('1920x1080', '75', '10000'), \
                     '1080p 12.0Mbps' :('1920x1080', '90', '12000'), \
                     '1080p 20.0Mbps' :('1920x1080', '100', '20000'), \
                     '1080p 40.0Mbps' :('1920x1080', '100', '40000') }
         if PlexAPI.getPMSProperty(UDID, PMS_uuid, 'local')=='1':
             qLimits = qLookup[g_ATVSettings.getSetting(UDID, 'transcodequality')]
         else:
             qLimits = qLookup[g_ATVSettings.getSetting(UDID, 'remotebitrate')]
         
         # subtitle renderer, subtitle selection
         subtitleRenderer = g_ATVSettings.getSetting(UDID, 'subtitlerenderer')
         
         subtitleId = ''
         subtitleKey = ''
         subtitleFormat = ''
         for Stream in Media.find('Part').findall('Stream'):  # Todo: check 'Part' existance, deal with multi part video
             if Stream.get('streamType','') == '3' and\
                Stream.get('selected','0') == '1':
                 subtitleId = Stream.get('id','')
                 subtitleKey = Stream.get('key','')
                 subtitleFormat = Stream.get('format','')
                 break
         
         subtitleIOSNative = \
             subtitleKey=='' and subtitleFormat=="tx3g"  # embedded
         subtitlePlexConnect = \
             subtitleKey!='' and subtitleFormat=="srt"  # external
         
         # subtitle suitable for direct play?
         #    no subtitle
         # or 'Auto'    with subtitle by iOS or PlexConnect
         # or 'iOS,PMS' with subtitle by iOS
         subtitleDirectPlay = \
             subtitleId=='' \
             or \
             subtitleRenderer=='Auto' and \
             ( (videoATVNative and subtitleIOSNative) or subtitlePlexConnect ) \
             or \
             subtitleRenderer=='iOS, PMS' and \
             (videoATVNative and subtitleIOSNative)
         dprint(__name__, 2, "subtitle: IOSNative - {0}, PlexConnect - {1}, DirectPlay - {2}", subtitleIOSNative, subtitlePlexConnect, subtitleDirectPlay)
         
         # determine video URL
         if transcoderAction=='DirectPlay' \
            or \
            transcoderAction=='Auto' and \
            videoATVNative and \
            int(Media.get('bitrate','0')) < int(qLimits[2]) and \
            subtitleDirectPlay:
             # direct play for...
             #    force direct play
             # or videoATVNative (HTTP live stream m4v/h264/aac...)
             #    limited by quality setting
             #    with aTV supported subtitle (iOS embedded tx3g, PlexConnext external srt)
             res, leftover, dfltd = self.getKey(Media, srcXML, 'Part/key')
             
             if Media.get('indirect', False):  # indirect... todo: select suitable resolution, today we just take first Media
                 PMS = PlexAPI.getXMLFromPMS(self.PMS_baseURL, res, self.options, AuthToken)  # todo... check key for trailing '/' or even 'http'
                 res, leftover, dfltd = self.getKey(PMS.getroot(), srcXML, 'Video/Media/Part/key')
             
             res = PlexAPI.getDirectVideoPath(res, AuthToken)
         else:
             # request transcoding
             res = Video.get('key','')
             
             # misc settings: subtitlesize, audioboost
             subtitle = { 'selected': '1' if subtitleId else '0', \
                          'dontBurnIn': '1' if subtitleDirectPlay else '0', \
                          'size': g_ATVSettings.getSetting(UDID, 'subtitlesize') }
             audio = { 'boost': g_ATVSettings.getSetting(UDID, 'audioboost') }
             res = PlexAPI.getTranscodeVideoPath(res, AuthToken, self.options, transcoderAction, qLimits, subtitle, audio)
     
     else:
         dprint(__name__, 0, "MEDIAPATH - element not found: {0}", param)
         res = 'FILE_NOT_FOUND'  # not found?
     
     if res.startswith('/'):  # internal full path.
         res = self.PMS_baseURL + res
     elif res.startswith('http://') or res.startswith('https://'):  # external address
         pass
     else:  # internal path, add-on
         res = self.PMS_baseURL + self.path[srcXML] + res
     
     dprint(__name__, 1, 'MediaURL: {0}', res)
     return res
コード例 #54
0
def XML_PMS2NMT(PMS_baseURL, path, options):
    # double check NMT UDID, redo from client IP if needed/possible
    if not "PlexNMTUDID" in options:
        UDID = getNMTFromIP(options["NMTAddress"])
        if UDID:
            options["PlexNMTUDID"] = UDID
    else:
        declareNMT(options["PlexNMTUDID"], options["NMTAddress"])  # update with latest info

    # check cmd to work on
    cmd = ""
    if "PlexNMT" in options:
        cmd = options["PlexNMT"]
    dprint(__name__, 1, "PlexNMT Cmd: " + cmd)

    # check NMT language setting
    if not "NMTLanguage" in options:
        dprint(__name__, 1, "no NMTLanguage - pick en")
        options["NMTLanguage"] = "en"

    # XML Template selector
    # - PlexNMT command
    # - path
    # - PMS ViewGroup
    XMLtemplate = ""
    PMS = None
    PMSroot = None

    # XML direct request or
    # XMLtemplate defined by solely PlexNMT Cmd
    if path.endswith(".xml"):
        XMLtemplate = path.lstrip("/")
        path = ""  # clear path - we don't need PMS-XML

        """
    elif cmd=='Play':
        XMLtemplate = 'PlayVideo.xml'
    
    elif cmd=='PlayVideo_ChannelsV1':
        dprint(__name__, 1, "playing Channels XML Version 1: {0}".format(path))
        UDID = options['PlexNMTUDID']
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_baseURL)
        auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
        path = PlexAPI.getDirectVideoPath(path, auth_token)
        return XML_PlayVideo_ChannelsV1(PMS_baseURL, path)  # direct link, no PMS XML available
    
    elif cmd=='PlayTrailer':
        trailerID = options['PlexConnectTrailerID']
        info = urllib2.urlopen("http://youtube.com/get_video_info?video_id=" + trailerID).read()
        parsed = urlparse.parse_qs(info)
        
        key = 'url_encoded_fmt_stream_map'
        if not key in parsed:
            return XML_Error('PlexConnect', 'Youtube: No Trailer Info available')
        streams = parsed[key][0].split(',')
        
        url = ''
        for i in range(len(streams)):
            stream = urlparse.parse_qs(streams[i])
            if stream['itag'][0] == '18':
                url = stream['url'][0] + '&signature=' + stream['sig'][0]
        if url == '':
            return XML_Error('PlexConnect','Youtube: ATV compatible Trailer not available')
        
        return XML_PlayVideo_ChannelsV1('', url.replace('&','&amp;'))
    
    elif cmd=='PhotoBrowser':
        XMLtemplate = 'Photo_Browser.xml'
        
    elif cmd=='MoviePreview':
        XMLtemplate = 'MoviePreview.xml'
    
    elif cmd=='MoviePrePlay':
        XMLtemplate = 'MoviePrePlay.xml'
    
    elif cmd=='EpisodePrePlay':
        XMLtemplate = 'EpisodePrePlay.xml'
        
    elif cmd=='ChannelPrePlay':
        XMLtemplate = 'ChannelPrePlay.xml'
    
    elif cmd=='ChannelsVideo':
        XMLtemplate = 'ChannelsVideo.xml'

    elif cmd=='ByFolder':
        XMLtemplate = 'ByFolder.xml'
    
    elif cmd == 'MovieSection':
        XMLtemplate = 'MovieSection.xml'
    
    elif cmd == 'TVSection':
        XMLtemplate = 'TVSection.xml'
    
    elif cmd.find('SectionPreview') != -1:
        XMLtemplate = cmd + '.xml'
    
    elif cmd == 'AllMovies':
        XMLtemplate = 'Movie_'+g_NMTSettings.getSetting(options['PlexNMTUDID'], 'movieview').replace(' ','')+'.xml'  
    
    elif cmd == 'MovieSecondary':
        XMLtemplate = 'MovieSecondary.xml'
    
    elif cmd == 'AllShows':
        XMLtemplate = 'Show_'+g_NMTSettings.getSetting(options['PlexNMTUDID'], 'showview')+'.xml'  
          
    elif cmd == 'TVSecondary':
        XMLtemplate = 'TVSecondary.xml'
        
    elif cmd == 'PhotoSecondary':
        XMLtemplate = 'PhotoSecondary.xml'
        
    elif cmd == 'Directory':
        XMLtemplate = 'Directory.xml'
    
    elif cmd == 'DirectoryWithPreview':
        XMLtemplate = 'DirectoryWithPreview.xml'

    elif cmd == 'DirectoryWithPreviewActors':
        XMLtemplate = 'DirectoryWithPreviewActors.xml'
            
    elif cmd=='Settings':
        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd=='SettingsVideoOSD':
        XMLtemplate = 'Settings_VideoOSD.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd=='SettingsMovies':
        XMLtemplate = 'Settings_Movies.xml'
        path = ''  # clear path - we don't need PMS-XML
        
    elif cmd=='SettingsTVShows':
        XMLtemplate = 'Settings_TVShows.xml'
        path = ''  # clear path - we don't need PMS-XML
        
    elif cmd.startswith('SettingsToggle:'):
        opt = cmd[len('SettingsToggle:'):]  # cut command:
        parts = opt.split('+')
        g_NMTSettings.toggleSetting(options['PlexNMTUDID'], parts[0].lower())
        XMLtemplate = parts[1] + ".xml"
        dprint(__name__, 2, "ATVSettings->Toggle: {0} in template: {1}", parts[0], parts[1])
        
        path = ''  # clear path - we don't need PMS-XML
        
    elif cmd==('MyPlexLogin'):
        dprint(__name__, 2, "MyPlex->Logging In...")
        if not 'PlexConnectCredentials' in options:
            return XML_Error('PlexConnect', 'MyPlex Sign In called without Credentials.')
        
        parts = options['PlexConnectCredentials'].split(':',1)        
        (username, auth_token) = PlexAPI.MyPlexSignIn(parts[0], parts[1], options)
        
        UDID = options['PlexNMTUDID']
        g_NMTSettings.setSetting(UDID, 'myplex_user', username)
        g_NMTSettings.setSetting(UDID, 'myplex_auth', auth_token)
        
        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd=='MyPlexLogout':
        dprint(__name__, 2, "MyPlex->Logging Out...")
        
        UDID = options['PlexNMTUDID']
        auth_token = g_NMTSettings.getSetting(UDID, 'myplex_auth')
        PlexAPI.MyPlexSignOut(auth_token)
        
        g_NMTSettings.setSetting(UDID, 'myplex_user', '')
        g_NMTSettings.setSetting(UDID, 'myplex_auth', '')
        
        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML
    
    elif cmd.startswith('Discover'):
        UDID = options['PlexNMTUDID']
        auth_token = g_NMTSettings.getSetting(UDID, 'myplex_auth')
        PlexAPI.discoverPMS(UDID, g_param['CSettings'], auth_token)
        
        return XML_Error('PlexConnect', 'Discover!')  # not an error - but aTV won't care anyways.
	
    elif path.startswith('/search?'):
        XMLtemplate = 'Search_Results.xml'
    
    elif path=='/library/sections':  # from PlexConnect.xml -> for //local, //myplex
        XMLtemplate = 'Library.xml'
    
    elif path=='/channels/all':
        XMLtemplate = 'Channel_'+g_NMTSettings.getSetting(options['PlexNMTUDID'], 'channelview')+'.xml'
        path = ''
    """

    # check options for XSL and start-page PSR
    if "PlexNMTXSL" in options:
        XSL = options["PlexNMTXSL"]
    else:
        XSL = "library.xsl"
    if "PlexNMTstart" in options:
        nmtstart = etree.XSLT.strparam(options["PlexNMTstart"])
    else:
        nmtstart = etree.XSLT.strparam("1")
    if "PlexNMTview" in options:
        nmtview = etree.XSLT.strparam(options["PlexNMTview"])
    else:
        nmtview = etree.XSLT.strparam("library")

    # request PMS XML
    if not path == "" or path == "":  # PSR
        if "PlexNMTUDID" in options:
            UDID = options["PlexNMTUDID"]
            PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMS_baseURL)
            auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, "accesstoken")
        else:
            auth_token = ""

        if PMS_baseURL.startswith("//"):  # //local, //myplex
            UDID = options["PlexNMTUDID"]
            type = PMS_baseURL[2:]
            PMS = PlexAPI.getXMLFromMultiplePMS(UDID, path, type, options)
        else:
            PMS = PlexAPI.getXMLFromPMS(PMS_baseURL, path, options, authtoken=auth_token)

        if PMS == False:
            return XML_Error("PlexNMT", "No Response from Plex Media Server")

        PMSroot = PMS.getroot()

        dprint(__name__, 1, "viewGroup: " + PMSroot.get("ViewGroup", "None"))

    # PSR - have PMS as XML content - move on.
    """
    # XMLtemplate defined by PMS XML content
    if path=='':
        pass  # nothing to load
    
    elif not XMLtemplate=='':
        pass  # template already selected
    
    elif PMSroot.get('viewGroup','')=="secondary" and (PMSroot.get('art','').find('movie') != -1 or PMSroot.get('thumb','').find('movie') != -1):
        XMLtemplate = 'MovieSectionTopLevel.xml'
    
    elif PMSroot.get('viewGroup','')=="secondary" and (PMSroot.get('art','').find('show') != -1 or PMSroot.get('thumb','').find('show') != -1):
        XMLtemplate = 'TVSectionTopLevel.xml'
        
    elif PMSroot.get('viewGroup','')=="secondary" and (PMSroot.get('art','').find('photo') != -1 or PMSroot.get('thumb','').find('photo') != -1):
        XMLtemplate = 'PhotoSectionTopLevel.xml'
        
    elif PMSroot.get('viewGroup','')=="secondary":
        XMLtemplate = 'Directory.xml'
    
    elif PMSroot.get('viewGroup','')=='show':
        if PMSroot.get('title2')=='By Folder':
          # By Folder View
          XMLtemplate = 'ByFolder.xml'
        else:
          # TV Show grid view
          XMLtemplate = 'Show_'+g_NMTSettings.getSetting(options['PlexNMTUDID'], 'showview')+'.xml'
        
    elif PMSroot.get('viewGroup','')=='season':
        # TV Season view
        XMLtemplate = 'Season_'+g_NMTSettings.getSetting(options['PlexNMTUDID'], 'seasonview')+'.xml'
        
    elif PMSroot.get('viewGroup','')=='movie':
        if PMSroot.get('title2')=='By Folder':
          # By Folder View
          XMLtemplate = 'ByFolder.xml'
        else:
          # Movie listing
          XMLtemplate = 'Movie_'+g_NMTSettings.getSetting(options['PlexNMTUDID'], 'movieview').replace(' ','')+'.xml'
          
    elif PMSroot.get('viewGroup','')=='track':
        XMLtemplate = 'Music_Track.xml'
   
    elif PMSroot.get('viewGroup','')=='episode':
        if PMSroot.get('title2')=='On Deck' or \
           PMSroot.get('title2')=='Recently Viewed Episodes' or \
           PMSroot.get('title2')=='Recently Aired' or \
           PMSroot.get('title2')=='Recently Added':
            # TV On Deck View
            XMLtemplate = 'TV_OnDeck.xml'
        else:
            # TV Episode view
            XMLtemplate = 'Episode.xml'
    
    elif PMSroot.get('viewGroup','')=='photo':
        # Photo listing
        XMLtemplate = 'Photo.xml'
    
    else:
        XMLtemplate = 'Directory.xml'
    
    dprint(__name__, 1, "XMLTemplate: "+XMLtemplate)
    """

    # PSR
    # get XSL Transform
    dprint(__name__, 1, "XSL=" + XSL)
    try:
        XSLtree = etree.parse(sys.path[0] + "/assets/" + XSL)
    except Exception, e:
        dprint(__name__, 0, "Error parsing XSLT tree ", XSL, e)
        return
コード例 #55
0
 def ATTRIB_PMSCOUNT(self, src, srcXML, param):
     UDID = self.options["PlexNMTUDID"]
     return str(PlexAPI.getPMSCount(UDID))
コード例 #56
0
 def ATTRIB_PMSCOUNT(self, src, srcXML, param):
     UDID = self.options['PlexConnectUDID']
     return str(PlexAPI.getPMSCount(UDID))
コード例 #57
0
def XML_PMS2aTV(PMSaddress, path, options):
    # double check aTV UDID, redo from client IP if needed/possible
    if not 'PlexConnectUDID' in options:
        UDID = getATVFromIP(options['aTVAddress'])
        if UDID:
            options['PlexConnectUDID'] = UDID
    else:
        declareATV(options['PlexConnectUDID'],
                   options['aTVAddress'])  # update with latest info

    # double check PMS IP address
    # the hope is: aTV sends either PMS address coded into URL or UDID in options
    if PMSaddress == '':
        if 'PlexConnectUDID' in options:
            UDID = options['PlexConnectUDID']
            PMS_uuid = g_ATVSettings.getSetting(options['PlexConnectUDID'],
                                                'pms_uuid')
            PMSaddress = PlexAPI.getPMSAddress(UDID, PMS_uuid)
            # this doesn't work any more, does it? is it really still used/needed?

    # check cmd to work on
    cmd = ''
    if 'PlexConnect' in options:
        cmd = options['PlexConnect']
    dprint(__name__, 1, "PlexConnect Cmd: " + cmd)

    # check aTV language setting
    if not 'aTVLanguage' in options:
        dprint(__name__, 1, "no aTVLanguage - pick en")
        options['aTVLanguage'] = 'en'

    # discover! PlexGDM and MyPlex lookup - application just started on aTV UDID
    if path == '/PlexConnect.xml':
        UDID = options['PlexConnectUDID']
        auth_token = g_ATVSettings.getSetting(UDID, 'myplex_auth')
        PlexAPI.discoverPMS(UDID, g_param['CSettings'], auth_token)

    # XML Template selector
    # - PlexConnect command
    # - path
    # - PMS ViewGroup
    XMLtemplate = ''
    PMS = None
    PMSroot = None

    # XML direct request or
    # XMLtemplate defined by solely PlexConnect Cmd
    if path.endswith(".xml"):
        XMLtemplate = path.lstrip('/')
        path = ''  # clear path - we don't need PMS-XML

    elif cmd == 'Play':
        XMLtemplate = 'PlayVideo.xml'

    elif cmd == 'PlayVideo_ChannelsV1':
        dprint(__name__, 1, "playing Channels XML Version 1: {0}".format(path))
        UDID = options['PlexConnectUDID']
        PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMSaddress)
        auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
        path = PlexAPI.getDirectVideoPath(path, auth_token)
        return XML_PlayVideo_ChannelsV1(
            PMSaddress, path)  # direct link, no PMS XML available

    elif cmd == 'PhotoBrowser':
        XMLtemplate = 'Photo_Browser.xml'

    elif cmd == 'MoviePreview':
        XMLtemplate = 'MoviePreview.xml'

    elif cmd == 'MoviePrePlay':
        XMLtemplate = 'MoviePrePlay.xml'

    elif cmd == 'EpisodePrePlay':
        XMLtemplate = 'EpisodePrePlay.xml'

    elif cmd == 'ChannelPrePlay':
        XMLtemplate = 'ChannelPrePlay.xml'

    elif cmd == 'ChannelsVideo':
        XMLtemplate = 'ChannelsVideo.xml'

    elif cmd == 'ByFolder':
        XMLtemplate = 'ByFolder.xml'

    elif cmd == 'MovieSection':
        XMLtemplate = 'MovieSection.xml'

    elif cmd == 'TVSection':
        XMLtemplate = 'TVSection.xml'

    elif cmd.find('SectionPreview') != -1:
        XMLtemplate = cmd + '.xml'

    elif cmd == 'AllMovies':
        XMLtemplate = 'Movie_' + g_ATVSettings.getSetting(
            options['PlexConnectUDID'], 'movieview') + '.xml'

    elif cmd == 'MovieSecondary':
        XMLtemplate = 'MovieSecondary.xml'

    elif cmd == 'AllShows':
        XMLtemplate = 'Show_' + g_ATVSettings.getSetting(
            options['PlexConnectUDID'], 'showview') + '.xml'

    elif cmd == 'TVSecondary':
        XMLtemplate = 'TVSecondary.xml'

    elif cmd == 'PhotoSecondary':
        XMLtemplate = 'PhotoSecondary.xml'

    elif cmd == 'Directory':
        XMLtemplate = 'Directory.xml'

    elif cmd == 'DirectoryWithPreview':
        XMLtemplate = 'DirectoryWithPreview.xml'

    elif cmd == 'DirectoryWithPreviewActors':
        XMLtemplate = 'DirectoryWithPreviewActors.xml'

    elif cmd == 'Settings':
        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML

    elif cmd == 'SettingsVideoOSD':
        XMLtemplate = 'Settings_VideoOSD.xml'
        path = ''  # clear path - we don't need PMS-XML

    elif cmd == 'SettingsMovies':
        XMLtemplate = 'Settings_Movies.xml'
        path = ''  # clear path - we don't need PMS-XML

    elif cmd == 'SettingsTVShows':
        XMLtemplate = 'Settings_TVShows.xml'
        path = ''  # clear path - we don't need PMS-XML

    elif cmd.startswith('SettingsToggle:'):
        opt = cmd[len('SettingsToggle:'):]  # cut command:
        parts = opt.split('+')
        g_ATVSettings.toggleSetting(options['PlexConnectUDID'],
                                    parts[0].lower())
        XMLtemplate = parts[1] + ".xml"
        dprint(__name__, 2, "ATVSettings->Toggle: {0} in template: {1}",
               parts[0], parts[1])

        path = ''  # clear path - we don't need PMS-XML

    elif cmd == ('MyPlexLogin'):
        dprint(__name__, 2, "MyPlex->Logging In...")
        if not 'PlexConnectCredentials' in options:
            return XML_Error('PlexConnect',
                             'MyPlex Sign In called without Credentials.')

        parts = options['PlexConnectCredentials'].split(':', 1)
        (username, auth_token) = PlexAPI.MyPlexSignIn(parts[0], parts[1],
                                                      options)

        UDID = options['PlexConnectUDID']
        g_ATVSettings.setSetting(UDID, 'myplex_user', username)
        g_ATVSettings.setSetting(UDID, 'myplex_auth', auth_token)

        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML

    elif cmd == 'MyPlexLogout':
        dprint(__name__, 2, "MyPlex->Logging Out...")

        UDID = options['PlexConnectUDID']
        auth_token = g_ATVSettings.getSetting(UDID, 'myplex_auth')
        PlexAPI.MyPlexSignOut(auth_token)

        g_ATVSettings.setSetting(UDID, 'myplex_user', '')
        g_ATVSettings.setSetting(UDID, 'myplex_auth', '')

        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML

    elif cmd.startswith('Discover'):
        UDID = options['PlexConnectUDID']
        auth_token = g_ATVSettings.getSetting(UDID, 'myplex_auth')
        PlexAPI.discoverPMS(UDID, g_param['CSettings'], auth_token)

        XMLtemplate = 'Settings.xml'
        path = ''  # clear path - we don't need PMS-XML

    elif path.startswith('/search?'):
        XMLtemplate = 'Search_Results.xml'

    elif path == '/library/sections':
        XMLtemplate = 'Library.xml'
        path = ''

    elif path == '/channels/all':
        XMLtemplate = 'Channels.xml'
        path = ''

    # request PMS XML
    if not path == '':
        if 'PlexConnectUDID' in options:
            UDID = options['PlexConnectUDID']
            PMS_uuid = PlexAPI.getPMSFromAddress(UDID, PMSaddress)
            auth_token = PlexAPI.getPMSProperty(UDID, PMS_uuid, 'accesstoken')
        else:
            auth_token = ''

        PMS = PlexAPI.getXMLFromPMS('http://' + PMSaddress,
                                    path,
                                    options,
                                    authtoken=auth_token)
        if PMS == False:
            return XML_Error('PlexConnect',
                             'No Response from Plex Media Server')

        PMSroot = PMS.getroot()

        dprint(__name__, 1, "viewGroup: " + PMSroot.get('ViewGroup', 'None'))

    # XMLtemplate defined by PMS XML content
    if path == '':
        pass  # nothing to load

    elif not XMLtemplate == '':
        pass  # template already selected

    elif PMSroot.get('viewGroup', '') == "secondary" and (
            PMSroot.get('art', '').find('movie') != -1
            or PMSroot.get('thumb', '').find('movie') != -1):
        XMLtemplate = 'MovieSectionTopLevel.xml'

    elif PMSroot.get('viewGroup', '') == "secondary" and (
            PMSroot.get('art', '').find('show') != -1
            or PMSroot.get('thumb', '').find('show') != -1):
        XMLtemplate = 'TVSectionTopLevel.xml'

    elif PMSroot.get('viewGroup', '') == "secondary" and (
            PMSroot.get('art', '').find('photo') != -1
            or PMSroot.get('thumb', '').find('photo') != -1):
        XMLtemplate = 'PhotoSectionTopLevel.xml'

    elif PMSroot.get('viewGroup', '') == "secondary":
        XMLtemplate = 'Directory.xml'

    elif PMSroot.get('viewGroup', '') == 'show':
        if PMSroot.get('title2') == 'By Folder':
            # By Folder View
            XMLtemplate = 'ByFolder.xml'
        else:
            # TV Show grid view
            XMLtemplate = 'Show_' + g_ATVSettings.getSetting(
                options['PlexConnectUDID'], 'showview') + '.xml'

    elif PMSroot.get('viewGroup', '') == 'season':
        # TV Season view
        XMLtemplate = 'Season_' + g_ATVSettings.getSetting(
            options['PlexConnectUDID'], 'seasonview') + '.xml'

    elif PMSroot.get('viewGroup', '') == 'movie':
        if PMSroot.get('title2') == 'By Folder':
            # By Folder View
            XMLtemplate = 'ByFolder.xml'
        else:
            # Movie listing
            XMLtemplate = 'Movie_' + g_ATVSettings.getSetting(
                options['PlexConnectUDID'], 'movieview') + '.xml'

    elif PMSroot.get('viewGroup', '') == 'track':
        XMLtemplate = 'Music_Track.xml'

    elif PMSroot.get('viewGroup', '') == 'episode':
        if PMSroot.get('title2')=='On Deck' or \
           PMSroot.get('title2')=='Recently Viewed Episodes' or \
           PMSroot.get('title2')=='Recently Aired' or \
           PMSroot.get('title2')=='Recently Added':
            # TV On Deck View
            XMLtemplate = 'TV_OnDeck.xml'
        else:
            # TV Episode view
            XMLtemplate = 'Episode.xml'

    elif PMSroot.get('viewGroup', '') == 'photo':
        # Photo listing
        XMLtemplate = 'Photo.xml'

    else:
        XMLtemplate = 'Directory.xml'

    dprint(__name__, 1, "XMLTemplate: " + XMLtemplate)

    # get XMLtemplate
    aTVTree = etree.parse(sys.path[0] + '/assets/templates/' + XMLtemplate)
    aTVroot = aTVTree.getroot()

    # convert PMS XML to aTV XML using provided XMLtemplate
    global g_CommandCollection
    g_CommandCollection = CCommandCollection(options, PMSroot, PMSaddress,
                                             path)
    XML_ExpandTree(aTVroot, PMSroot, 'main')
    XML_ExpandAllAttrib(aTVroot, PMSroot, 'main')
    del g_CommandCollection

    dprint(__name__, 1, "====== generated aTV-XML ======")
    dprint(__name__, 1, prettyXML(aTVTree))
    dprint(__name__, 1, "====== aTV-XML finished ======")

    return etree.tostring(aTVroot)