예제 #1
0
def getFilesFromLib(libs, sType):
    itemList = {}
    # Add from one library at a time
    for lib in libs:
        start = 0  # Start point of items
        baseUrl = misc.GetLoopBack(
        ) + '/library/sections/' + lib + '/all?type=' + str(MEDIATYPES[
            ROOTNODES[sType]]) + '&' + EXCLUDE + '&X-Plex-Container-Start='
        url = baseUrl + '0' + '&X-Plex-Container-Size=0'
        libInfo = XML.ElementFromURL(url)
        # Now get the amount of items we need to add
        totalSize = libInfo.get('totalSize')
        # Now get the UUID of the library
        librarySectionUUID = libInfo.get('librarySectionUUID')
        try:
            while int(start) < int(totalSize):
                url = baseUrl + str(start) + '&X-Plex-Container-Size=' + str(
                    MEDIASTEPS)
                medias = XML.ElementFromURL(url)
                for media in medias:
                    parts = media.xpath('//Media/Part')
                    for part in parts:
                        mediaInfo = {}
                        item = {}
                        mediaInfo = {
                            'fullFileName': part.get('file'),
                            'librarySectionUUID': librarySectionUUID
                        }
                        key = media.get('ratingKey')
                        item[key] = [mediaInfo]
                        itemList[os.path.basename(part.get('file'))] = item
                start += MEDIASTEPS
        except Exception, e:
            Log.Exception('exception in getFilesFromLib was: %s' % str(e))
예제 #2
0
 def RESET(self, req, *args):
     """Reset WT to factory settings"""
     try:
         Log.Info('Factory Reset called')
         cachePath = Core.storage.join_path(Core.app_support_path,
                                            'Plug-in Support', 'Caches',
                                            'com.plexapp.plugins.' + NAME)
         dataPath = Core.storage.join_path(Core.app_support_path,
                                           'Plug-in Support', 'Data',
                                           'com.plexapp.plugins.' + NAME)
         shutil.rmtree(cachePath)
         shutil.rmtree(dataPath)
         try:
             Dict.Reset()
         except:
             Log.Critical('Fatal error in clearing dict during reset')
         # Restart system bundle
         HTTP.Request(misc.GetLoopBack() +
                      '/:/plugins/com.plexapp.plugins.' + NAME + '/restart',
                      cacheTime=0,
                      immediate=True)
         req.clear()
         req.set_status(200)
         req.finish('WebTools has been reset')
     except Exception, e:
         Log.Exception('Fatal error happened in wt.reset: ' + str(e))
         req.clear()
         req.set_status(e.code)
         req.finish('Fatal error happened in wt.reset: %s' % (str(e)))
예제 #3
0
 def SearchMedia(self, req, watched, section, sectionType):
     Log.Info('Starting to search')
     returnJson = {}
     try:
         if sectionType == 'movie':
             MediaType = str(PLEX_MEDIATYPE['METADATA_MOVIE'])
         elif sectionType == 'Ged':
             pass
         url = misc.GetLoopBack() + '/library/sections/' + section
         url += '/all?type=' + MediaType
         url += '&X-Plex-Container-Start=0&X-Plex-Container-Size=1&'
         url += EXCLUDEELEMENTS + '&' + EXCLUDEFIELDS + '&title='
         for title, key in watched.items():
             SearchUrl = url + String.Quote(title)
             key = XML.ElementFromURL(SearchUrl).xpath(
                 '//Video/@ratingKey')[0]
             returnJson[title] = key
         return returnJson
     except Exception, e:
         Log.Exception(
             'Fatal exception happened in ViewState Search was %s' % str(e))
         req.clear()
         req.set_status(500)
         req.finish(
             'Exception happened in ViewState Search was: %s' % (str(e)))
예제 #4
0
def checkItemIsValid(key, title, sType):
    url = misc.GetLoopBack() + '/library/metadata/' + str(key) + '?' + EXCLUDE
    mediaTitle = None
    try:
        mediaTitle = XML.ElementFromURL(url).xpath(
            '//' + ROOTNODES[sType])[0].get('title')
    except:
        pass
    return (title == mediaTitle)
예제 #5
0
 def getPrimaryAgent(self, section):
     # Get the primary agent for the library
     url = ''.join((
         misc.GetLoopBack(),
         '/library/sections'))
     try:
         Scanner = XML.ElementFromURL(url).xpath(
             '//Directory[@key="' + section + '"]/@agent')[0]
         return Scanner
     except Exception, e:
         Log.Exception('Exception in PlayList orderList was %s' % (str(e)))
예제 #6
0
        def doImport(jsonItems, playlistType, playlistTitle):
            # jsonItems = {}
            playlistSmart = (jsonItems.get('smart') == 1)
            # Make url for creation of playlist
            targetFirstUrl = misc.GetLoopBack() + '/playlists?type=' + playlistType + \
                '&title=' + String.Quote(playlistTitle) + \
                '&smart=0&uri=library://'
            counter = 0
            for lib in jsonItems:
                if counter < 1:
                    targetFirstUrl += lib + '/directory//library/metadata/'
                    medias = ','.join(
                        map(str, (item['id'] for item in jsonItems[lib])))
                    targetFirstUrl += String.Quote(medias)
                    # First url for the post created, so send it, and grab the response
                    try:
                        response = HTTP.Request(targetFirstUrl,
                                                cacheTime=0,
                                                immediate=True,
                                                method="POST")

                        ratingKey = XML.ElementFromString(response).xpath(
                            'Playlist/@ratingKey')[0]
                    except Exception, e:
                        Log.Exception(
                            'Exception creating first part of playlist was: %s'
                            % (str(e)))
                    counter += 1
                else:
                    # Remaining as put
                    medias = ','.join(
                        map(str, (item['id'] for item in jsonItems[lib])))
                    targetSecondUrl = misc.GetLoopBack() + '/playlists/' + ratingKey + '/items?uri=library://' + \
                        lib + '/directory//library/metadata/' + \
                        String.Quote(medias)
                    HTTP.Request(targetSecondUrl,
                                 cacheTime=0,
                                 immediate=True,
                                 method="PUT")
예제 #7
0
 def setWatched(self, req, watched, user, users):
     url = misc.GetLoopBack(
     ) + '/:/scrobble?identifier=com.plexapp.plugins.library&key='
     for key, value in watched.items():
         target = url + str(value)
         if not user:
             httpResponse = HTTP.Request(target, immediate=True, timeout=5)
         else:
             print 'Ged do alternative http get'
             # TODO Change to native framework call, when Plex allows token in header
             opener = urllib2.build_opener(urllib2.HTTPHandler)
             request = urllib2.Request(target)
             request.add_header('X-Plex-Token', users[user]['accessToken'])
             response = opener.open(request).read()
예제 #8
0
 def orderPlaylist(playlistId, orgPlaylist, sType):
     try:
         rootNode = ROOTNODES[sType]
         # Now get the import list as it is now
         url = misc.GetLoopBack(
         ) + '/playlists/' + playlistId + '/items' + '?' + EXCLUDE
         playListXML = XML.ElementFromURL(url)
         newList = {}
         # Grap the original one, and sort by ListId
         for lib in orgPlaylist:
             for item in orgPlaylist[lib]:
                 newList[item['ListId']] = item['title']
         # Need a counter here, since HTTP url differs from first to last ones
         counter = 0
         for item in sorted(newList):
             # get playListItemId of item
             xPathStr = "//" + rootNode + \
                 "[@title='" + newList[item] + "']/@playlistItemID"
             itemToMove = str(playListXML.xpath(unicode(xPathStr))[0])
             if counter == 0:
                 url = misc.GetLoopBack() + '/playlists/' + playlistId + \
                     '/items/' + itemToMove + '/move'
                 counter += 1
                 after = itemToMove
             else:
                 url = misc.GetLoopBack() + '/playlists/' + playlistId + \
                     '/items/' + itemToMove + \
                     '/move?after=' + after
                 after = itemToMove
             # Now move the darn thing
             HTTP.Request(url,
                          cacheTime=0,
                          immediate=True,
                          method="PUT")
     except Exception, e:
         Log.Exception('Exception in PlayList orderList was %s' %
                       (str(e)))
예제 #9
0
def getLibsOfType(sType):
    libsToSearch = []
    if sType == 'audio':
        sType = 'artist'
    # Getting a list of all libraries
    try:
        url = misc.GetLoopBack() + '/library/sections/all'
        xPathStr = 'Directory[@type="' + sType + '"]'
        libs = XML.ElementFromURL(url).xpath(xPathStr)
        for lib in libs:
            libsToSearch.append(lib.get('key'))
        Log.Info('Need to serch the following libraries: %s' %
                 str(libsToSearch))
        return libsToSearch
    except Exception, e:
        Log.Exception('Exception in playList getLibsOfType was %s' % str(e))
예제 #10
0
def deletePlayLIstforUsr(req, key, token):
    url = misc.GetLoopBack() + '/playlists/' + key
    try:
        # TODO Change to native framework call, when Plex allows token in header
        opener = urllib2.build_opener(urllib2.HTTPHandler)
        request = urllib2.Request(url)
        request.add_header('X-Plex-Token', token)
        request.get_method = lambda: 'DELETE'
        url = opener.open(request)
    except Ex.HTTPError, e:
        Log.Exception(
            'HTTP exception  when deleting a playlist for the owner was: %s' %
            (e))
        req.clear()
        req.set_status(e.code)
        req.finish(str(e))
예제 #11
0
 def DELETE(self, req, *args):
     try:
         user = None
         if args != None:
             # We got additional arguments
             if len(args) > 0:
                 # Get them in lower case
                 arguments = [item.lower() for item in list(args)[0]]
                 if 'user' in arguments:
                     # Get key of the user
                     user = arguments[arguments.index('user') + 1]
             # So now user is either none (Owner) or a keyId of a user
             # Now lets get the key of the playlist
             if 'key' in arguments:
                 # Get key of the user
                 key = arguments[arguments.index('key') + 1]
                 url = misc.GetLoopBack() + '/playlists/' + key
             else:
                 Log.Error('Missing key of playlist')
                 req.clear()
                 req.set_status(412)
                 req.finish('Missing key of playlist')
         if user == None:
             try:
                 # Delete playlist from the owner
                 Log.Info('Deleting playlist with ID: %s' % key)
                 HTTP.Request(url,
                              cacheTime=0,
                              immediate=True,
                              method="DELETE")
             except Ex.HTTPError, e:
                 Log.Exception(
                     'HTTP exception  when deleting a playlist for the owner was: %s'
                     % (e))
                 req.clear()
                 req.set_status(e.code)
                 req.finish(str(e))
             except Exception, e:
                 Log.Exception(
                     'Exception happened when deleting a playlist for the owner was: %s'
                     % (str(e)))
                 req.clear()
                 req.set_status(500)
                 req.finish(
                     'Exception happened when deleting a playlist for the owner was: %s'
                     % (str(e)))
예제 #12
0
 def __init__(self):
     global retMsg
     global MediaChuncks
     global CoreUrl
     try:
         # Only init once during the lifetime of this
         if not findMedia.init_already:
             findMedia.init_already = True
             retMsg = ['WebTools']
             self.populatePrefs()
             Log.Debug('******* Starting findMedia *******')
             Log.Debug('********* Prefs are ***********')
             Log.Debug(Dict['findMedia'])
         self.MediaChuncks = 40
         self.CoreUrl = misc.GetLoopBack() + '/library/sections/'
     except exception, e:
         Log.Critical('Exception in FM Init was %s' % (e))
예제 #13
0
 def phraseOurs(lines):
     # Placeholder for items to import
     items = {}
     Log.Debug('Import file was ours')
     ourLine = lines[2][1:].replace('None', '"None"')
     jsonLine = JSON.ObjectFromString(ourLine)
     sName = jsonLine['title']
     Log.Debug('Playlist name internally is %s' % sName)
     sType = jsonLine['playlistType']
     Log.Debug('Playlist type is %s' % sType)
     sSrvId = jsonLine['ServerID']
     smart = jsonLine['smart']
     Log.Debug('Playlist smart is %s' % smart)
     Log.Debug('ServerId this playlist belongs to is %s' % sSrvId)
     thisServerID = XML.ElementFromURL(
         misc.GetLoopBack() + '/identity').get('machineIdentifier')
     Log.Debug('Current Server id is %s' % thisServerID)
     bSameSrv = (thisServerID == sSrvId)
     lineNo = 5
     try:
         for line in lines[5:len(lines):3]:
             if not line:
                 break
             myLine = str(line[1:])
             myLine = myLine.replace("None", str(-1))
             media = JSON.ObjectFromString(myLine)
             id = media['Id']
             item = {}
             item['ListId'] = media['ListId']
             item['LibraryUUID'] = media['LibraryUUID']
             lineNo += 1
             media = lines[lineNo][8:].split(',', 1)
             item['title'] = media[1].split(' - ', 1)[1]
             lineNo += 1
             item['fileName'] = lines[lineNo]
             items[id] = item
             lineNo += 1
         return items
     except IndexError:
         pass
     except Exception, e:
         Log.Exception('Exception happened in phraseOurs was %s' %
                       (str(e)))
         pass
예제 #14
0
def searchForItemKey(title, sType):
    try:
        result = []
        # TODO: Fix for other types
        # Are we talking about a video here?



        url = misc.GetLoopBack() + '/search?type=10&query=' + \
            String.Quote(title) + '&' + EXCLUDE
        found = XML.ElementFromURL(url)
        ratingKey = found.xpath('//' + ROOTNODES[sType] + '/@ratingKey')[0]
        result.append(ratingKey)
        librarySectionUUID = found.xpath('//' + ROOTNODES[sType] +
                                         '/@librarySectionUUID')[0]
        result.append(librarySectionUUID)
        Log.Info('Item named %s was located as item with key %s' %
                 (title, ratingKey))
        return result
    except Exception, e:
        pass
예제 #15
0
 def GETSECTIONSLIST(self, req, *args):
     Log.Debug('getSectionsList requested')
     try:
         rawSections = XML.ElementFromURL(
             misc.GetLoopBack() + '/library/sections')
         Sections = []
         for directory in rawSections:
             if directory.get('type') in SUPPORTEDSECTIONS:
                 Section = {
                     'key': directory.get('key'),
                     'title': directory.get('title'),
                     'type': directory.get('type')}
                 Sections.append(Section)
         req.clear()
         req.set_status(200)
         req.set_header('Content-Type', 'application/json; charset=utf-8')
         req.finish(json.dumps(Sections))
     except Exception, e:
         Log.Exception(
             'Fatal error happened in getSectionsList: %s' % (str(e)))
         req.clear()
         req.set_status(500)
         req.finish('Fatal error happened in getSectionsList')
예제 #16
0
 def scanItems(self, req, sectionNumber, Agent, Force=False):
     print 'Ged Force', Force
     """Scan db. Must run as a thread"""
     try:
         # Let's find out the info of section here
         url = misc.GetLoopBack() + '/library/sections/'
         response = XML.ElementFromURL(url).xpath(
             '//Directory[@key=' + sectionNumber + ']')
         sectionTitle = response[0].get('title')
         sectionType = response[0].get('type')
         strMsg = ''.join((
             'Going to scan section',
             sectionNumber,
             ' with a title of ',
             sectionTitle,
             ' and a type of ',
             sectionType))
         Log.Debug(strMsg)
         if runningState in [0, 99]:
             Thread.Create(
                 scanMedias, globalize=True,
                 sectionNumber=sectionNumber,
                 sectionType=sectionType,
                 agent=Agent,
                 Force=Force,
                 req=req)
         else:
             req.clear()
             req.set_status(409)
             req.finish('Scanning already in progress')
     except Exception, ex:
         Log.Exception('Fatal error happened in scanItems: ' + str(ex))
         req.clear()
         req.set_status(500)
         req.finish('Fatal error happened in scanItems: ' + str(ex))
         return req
예제 #17
0
 def DOWNLOAD(self, req, *args):
     try:
         user = None
         if args != None:
             # We got additional arguments
             if len(args) > 0:
                 # Get them in lower case
                 arguments = [item.lower() for item in list(args)[0]]
                 if 'user' in arguments:
                     # Get key of the user
                     user = arguments[arguments.index('user') + 1]
             # So now user is either none (Owner) or a keyId of a user
             # Now lets get the key of the playlist
             if 'key' in arguments:
                 # Get key of the user
                 key = arguments[arguments.index('key') + 1]
                 url = misc.GetLoopBack(
                 ) + '/playlists/' + key + '/items' + '?' + EXCLUDE
             else:
                 Log.Error('Missing key of playlist')
                 req.clear()
                 req.set_status(412)
                 req.finish('Missing key of playlist')
             try:
                 Log.Info('downloading playlist with ID: %s' % key)
                 try:
                     title, playList = getPlayListItems(user, key)
                     # Replace invalid caracters for a filename with underscore
                     fileName = re.sub('[\/[:#*?"<>|]', '_',
                                       title).strip() + '.m3u8'
                     req.set_header(
                         'Content-Disposition',
                         'attachment; filename="' + fileName + '"')
                     req.set_header('Cache-Control', 'no-cache')
                     req.set_header('Pragma', 'no-cache')
                     req.set_header('Content-Type',
                                    'application/text/plain')
                     # start writing
                     for line in playList:
                         #print line
                         req.write(unicode(line))
                     req.set_status(200)
                     req.finish()
                 except Exception, e:
                     Log.Exception(
                         'Exception when downloading a playlist as the owner was %s'
                         % str(e))
                     Log.Debug('Trying to get more info here')
                     req.clear()
                     req.set_status(500)
                     req.finish(str(e))
             except Ex.HTTPError, e:
                 Log.Exception(
                     'HTTP exception  when downloading a playlist for the owner was: %s'
                     % (e))
                 req.clear()
                 req.set_status(500)
                 req.finish(str(e))
             except Exception, e:
                 Log.Exception(
                     'Exception happened when downloading a playlist for the owner was: %s'
                     % (str(e)))
                 req.clear()
                 req.set_status(500)
                 req.finish(
                     'Exception happened when downloading a playlist for the owner was: %s'
                     % (str(e)))
예제 #18
0
def scanMovieDb(sectionNumber=0, agent=None):
    """Get a list of all files in a Movie Library from the database"""
    global AmountOfMediasInDatabase
    global statusMsg
    global runningState
    try:
        Log.Debug(
            'Starting scanMovieDb for section %s' % (sectionNumber))
        runningState = -1
        strStatus = (
            'Starting to scan database for section %s'
            % sectionNumber)
        statusMsg = (
            wtV3().GETTRANSLATE(
                None, Internal=True,
                String=strStatus))
        # Start by getting the totals of this section
        totalSize = XML.ElementFromURL(
            misc.GetLoopBack() + '/library/sections/' + sectionNumber +
            '/all?X-Plex-Container-Start=1&X-Plex-Container-Size=0')\
            .get('totalSize')
        AmountOfMediasInDatabase = totalSize
        print 'Ged51 episodes', str(totalSize)
        Log.Debug('Total size of medias are %s' % (totalSize))
        iStart = 0
        iCount = 0
        strMsg = 'Scanning database: item %s of %s : \
        Working' % (iCount, totalSize)
        statusMsg = wtV3().GETTRANSLATE(
            None, Internal=True, String=strMsg)
        # So let's walk the library
        while True:
            # Grap a chunk of videos from the server
            medias = XML.ElementFromURL(
                misc.GetLoopBack() + '/library/sections/' + sectionNumber +
                '/all?X-Plex-Container-Start=' + str(iStart) +
                '&X-Plex-Container-Size=' + str(MediaChuncks) +
                '&excludeElements=' + EXCLUDEELEMENTS +
                '&excludeFields=' + EXCLUDEFIELDS).xpath('//Video')
            for video in medias:
                iCount += 1
                videoUrl = ''.join((
                    misc.GetLoopBack(),
                    video.get('key'),
                    '?excludeElements=' + EXCLUDEELEMENTS,
                    '&excludeFields=' + EXCLUDEFIELDS
                ))                
                guid = XML.ElementFromURL(
                    videoUrl).xpath('//Video')[0].get('guid')
                if agent not in guid:
                    Log.Info('Need to update media: %s' % video.get('title'))
                    updateMediaAgent(
                        video.get('ratingKey'),
                        agent,
                        video.get('year'),
                        video.get('title'))
                # Did user abort?
                if bAbort:
                    runningState = 0
                    raise ValueError('Aborted')
                    break
                strMsg = 'Scanning database: item %s of %s : \
                Working' % (iCount, totalSize)
                statusMsg = wtV3().GETTRANSLATE(
                    None, Internal=True,
                    String=strMsg)
            iStart += MediaChuncks
            if len(medias) == 0:
                statusMsg = 'Scanning database: %s : Done' % (
                    totalSize)
                Log.Info('***** Done scanning the database *****')
                runningState = 1
                break
        return
    except Exception, e:
        Log.Exception(
                'Exception Fatal error in scanMovieDb: ' + str(e))
        runningState = 99
예제 #19
0
 def init(self):
     self.getListsURL = misc.GetLoopBack() + '/playlists/all'
예제 #20
0
 def COPY(self, req, *args):
     users = None
     # Start by getting the key of the PlayList
     if args != None:
         # We got additional arguments
         if len(args) > 0:
             # Get them in lower case
             arguments = [item.lower() for item in list(args)[0]]
         else:
             Log.Critical('Missing Arguments')
             req.clear()
             req.set_status(412)
             req.finish('Missing Arguments')
         # Get playlist Key
         if 'key' in arguments:
             # Get key of the user
             key = arguments[arguments.index('key') + 1]
         else:
             Log.Error('Missing key of playlist')
             req.clear()
             req.set_status(412)
             req.finish('Missing key of playlist')
         # Get UserFrom
         if 'userfrom' in arguments:
             # Get the userfrom
             userfrom = arguments[arguments.index('userfrom') + 1]
         else:
             # Copy from the Owner
             userfrom = None
         # Get UserTo
         if 'userto' in arguments:
             # Get the userto
             userto = arguments[arguments.index('userto') + 1]
         else:
             Log.Error('Missing target user of playlist')
             req.clear()
             req.set_status(412)
             req.finish('Missing targetuser of playlist')
         # Get user list, among with access token
         users = plexTV().getUserList()
         # Get the playlist that needs to be copied
         url = misc.GetLoopBack() + '/playlists/' + key + '/items'
         if userfrom == None:
             # Get it from the owner
             playlist = XML.ElementFromURL(url)
         else:
             # We need to logon as specified user
             try:
                 # Get user playlist
                 # TODO Change to native framework call, when Plex allows token in header
                 opener = urllib2.build_opener(urllib2.HTTPHandler)
                 request = urllib2.Request(url)
                 request.add_header('X-Plex-Token',
                                    users[userfrom]['accessToken'])
                 response = opener.open(request).read()
                 playlist = XML.ElementFromString(response)
             except Ex.HTTPError, e:
                 Log.Exception(
                     'HTTP exception  when downloading a playlist for the owner was: %s'
                     % (e))
                 req.clear()
                 req.set_status(e.code)
                 req.finish(str(e))
             except Exception, e:
                 Log.Exception(
                     'Exception happened when downloading a playlist for the user was: %s'
                     % (str(e)))
                 req.clear()
                 req.set_status(500)
                 req.finish(
                     'Exception happened when downloading a playlist for the user was: %s'
                     % (str(e)))
예제 #21
0
     return
 # So now user is either none or a keyId
 if not user:
     result['user'] = None
     result['username'] = '******'
 else:
     # Darn....Hard work ahead..We have to
     # logon as another user here :-(
     result['user'] = user
     # Get user list, among with their access tokens
     users = plexTV().getUserList()
     result['username'] = users[user]['username']
 count = 0
 # Add some export core info here
 result['section'] = section
 sectionTypeUrl = misc.GetLoopBack() + '/library/sections/' + str(section) + \
     '/all?X-Plex-Container-Start=0&X-Plex-Container-Size=0'
 result['sectionType'] = XML.ElementFromURL(
     sectionTypeUrl).get('viewGroup')
 result['sectionTitle'] = XML.ElementFromURL(
     sectionTypeUrl).get('librarySectionTitle')
 result['serverId'] = XML.ElementFromURL(
     misc.GetLoopBack() + '/identity').get('machineIdentifier')
 # Get the type of items to get, based on section type
 if result['sectionType'] == 'show':
     Type = PLEX_MEDIATYPE['METADATA_EPISODE']
 elif result['sectionType'] == 'movie':
     Type = PLEX_MEDIATYPE['METADATA_MOVIE']
 elif result['sectionType'] == 'artist':
     Type = PLEX_MEDIATYPE['METADATA_TRACK']
 # Url to grap
예제 #22
0
         Log.Exception(
             'Exception happened when downloading a playlist for the user was: %s'
             % (str(e)))
         req.clear()
         req.set_status(500)
         req.finish(
             'Exception happened when downloading a playlist for the user was: %s'
             % (str(e)))
 # Now walk the playlist, and do a lookup for the items, in order to grab the librarySectionUUID
 jsonItems = {}
 playlistType = playlist.get('playlistType')
 playlistTitle = playlist.get('title')
 playlistSmart = (playlist.get('smart') == 1)
 for item in playlist:
     itemKey = item.get('ratingKey')
     xmlUrl = misc.GetLoopBack(
     ) + '/library/metadata/' + itemKey + '?' + EXCLUDE
     UUID = XML.ElementFromURL(misc.GetLoopBack() +
                               '/library/metadata/' +
                               itemKey).get('librarySectionUUID')
     if UUID in jsonItems:
         jsonItems[UUID].append(itemKey)
     else:
         jsonItems[UUID] = []
         jsonItems[UUID].append(itemKey)
 Log.Debug('Got a playlist that looks like:')
 Log.Debug(json.dumps(jsonItems))
 # So we got all the info needed now from the source user, now time for the target user
 try:
     # TODO Change to native framework call, when Plex allows token in header
     urltoPlayLists = misc.GetLoopBack() + '/playlists'
     opener = urllib2.build_opener(urllib2.HTTPHandler)
예제 #23
0
 def scanShowDB(sectionNumber=0):
     global AmountOfMediasInDatabase
     global mediasFromDB
     global statusMsg
     global runningState
     try:
         Log.Debug('Starting scanShowDB for section %s' %
                   (sectionNumber))
         runningState = -1
         statusMsg = 'Starting to scan database for section %s' % (
             sectionNumber)
         # Start by getting the totals of this section
         totalSize = XML.ElementFromURL(
             self.CoreUrl + sectionNumber +
             '/all?X-Plex-Container-Start=1&X-Plex-Container-Size=0'
         ).get('totalSize')
         AmountOfMediasInDatabase = totalSize
         Log.Debug('Total size of medias are %s' % (totalSize))
         iShow = 0
         iCShow = 0
         statusShows = 'Scanning database show %s of %s : ' % (
             iShow, totalSize)
         statusMsg = statusShows
         # So let's walk the library
         while True:
             # Grap shows
             shows = XML.ElementFromURL(
                 self.CoreUrl + sectionNumber +
                 '/all?X-Plex-Container-Start=' + str(iCShow) +
                 '&X-Plex-Container-Size=' + str(self.MediaChuncks) +
                 '&excludeElements=' + excludeElements +
                 '&excludeFields=' + excludeFields).xpath('//Directory')
             # Grap individual show
             for show in shows:
                 statusShow = show.get('title')
                 statusMsg = statusShows + statusShow
                 iSeason = 0
                 iCSeason = 0
                 # Grap seasons
                 while True:
                     seasons = XML.ElementFromURL(
                         misc.GetLoopBack() + show.get('key') +
                         '?X-Plex-Container-Start=' + str(iCSeason) +
                         '&X-Plex-Container-Size=' +
                         str(self.MediaChuncks) + '&excludeElements=' +
                         excludeElements + '&excludeFields=' +
                         excludeFields).xpath('//Directory')
                     # Grap individual season
                     for season in seasons:
                         if season.get('title') == 'All episodes':
                             iSeason += 1
                             continue
                         statusSeason = ' ' + season.get('title')
                         statusMsg = statusShows + statusShow + statusSeason
                         iSeason += 1
                         # Grap Episodes
                         iEpisode = 0
                         iCEpisode = 0
                         while True:
                             episodes = XML.ElementFromURL(
                                 misc.GetLoopBack() +
                                 season.get('key') +
                                 '?X-Plex-Container-Start=' +
                                 str(iCEpisode) +
                                 '&X-Plex-Container-Size=' +
                                 str(self.MediaChuncks) +
                                 '&excludeElements=' + excludeElements +
                                 '&excludeFields=' +
                                 excludeFields).xpath('//Part')
                             for episode in episodes:
                                 if bAbort:
                                     raise ValueError('Aborted')
                                 filename = episode.get('file')
                                 filename = String.Unquote(
                                     filename).encode('utf8', 'ignore')
                                 mediasFromDB.append(filename)
                                 iEpisode += 1
                             # Inc Episodes counter
                             iCEpisode += self.MediaChuncks
                             if len(episodes) == 0:
                                 break
                     # Inc Season counter
                     iCSeason += self.MediaChuncks
                     if len(seasons) == 0:
                         break
                 iShow += 1
                 statusShows = 'Scanning database show %s of %s : ' % (
                     iShow, totalSize)
             # Inc. Shows counter
             iCShow += self.MediaChuncks
             if len(shows) == 0:
                 statusMsg = 'Scanning database: %s : Done' % (
                     totalSize)
                 Log.Debug('***** Done scanning the database *****')
                 if DEBUGMODE:
                     Log.Debug(mediasFromDB)
                 runningState = 1
                 break
         return
     except ValueError:
         statusMsg = 'Idle'
         runningState = 99
         Log.Info('Aborted in ScanShowDB')
     except Exception, e:
         Log.Exception('Fatal error in scanShowDB: ' + str(e))
         runningState = 99
예제 #24
0
class viewstate(object):
    @classmethod
    def init(self):
        return

    '''
    This metode will import a viewlist file
    * Param: localFile (In the payload)
    * Param: User (In param, optional, and if missing, is the uwner)
    * Param: Section (In param, and mandentory)
    '''
    @classmethod
    def IMPORT(self, req, *args):
        print '*********** GED ***********'
        print 'Ged logon as not owner', 'Check access denied', 'Make it a thread', 'Make a method to grap status', 'Make it possible to abort'

        Log.Info('ViewState Import called')
        # Payload Upload file present?
        if not 'localFile' in req.request.files:
            req.clear()
            req.set_status(412)
            req.finish(
                'Missing upload file parameter named \
                localFile from the payload')
        else:
            localFile = req.request.files['localFile'][0]['body']
        # Get parameters from url
        try:
            user = None
            if args is not None:
                # We got additional arguments
                if len(args) > 0:
                    # Get them in lower case
                    arguments = [item.lower() for item in list(args)[0]]
                    if 'user' in arguments:
                        # Get key of the user
                        user = arguments[arguments.index('user') + 1]
                    if 'section' in arguments:
                        # Get Section Number
                        section = arguments[arguments.index('section') + 1]
                    else:
                        section = None
            if not section:
                req.clear()
                req.set_status(412)
                req.finish('Missing import file parameter named Section')
        except Exception, e:
            Log.Exception(
                'Exception happened in ViewState Import was: %s' % (str(e)))
            req.clear()
            req.set_status(500)
            req.finish(
                'Exception happened in ViewState Import was: %s' % (str(e)))

        # So now user is either none or a keyId
        if user:
            # Darn....Hard work ahead..We have
            # to logon as another user here :-(
            result['user'] = user
            # Get user list, among with their access tokens
            users = plexTV().getUserList()

            print 'Ged Users', users
        else:
            print 'User is the owner'

        try:
            ViewState = json.loads(localFile)
            Log.Info('Import returned %s' %
                     (json.dumps(ViewState, ensure_ascii=False)))
            watched = ViewState['watched']
            print 'Ged Watched', watched
            ServerId = ViewState['serverId']
            sectionType = ViewState['sectionType']

            CurrentServerId = XML.ElementFromURL(
                misc.GetLoopBack() + '/identity').get('machineIdentifier')
            print 'Ged ServedID', CurrentServerId, ServerId
            self.ImportFile(ServerId == CurrentServerId)
            '''
            if ServerId == CurrentServerId:
                # Same Server, so no need to search here :)
                print 'Ged Same server detected'
                Log.Debug('Same Server detected, so no need to search here')
                self.setWatched(req, watched, user, None)

            else:
                # We need to search sadly
                Log.Debug(
                    'New server, so we need to search here, limited to selected section key')
                print 'Ged do stuff but search first'
                watched = self.SearchMedia(req, watched, section, sectionType)
                self.setWatched(req, watched, user, None)
            '''
        except Exception, e:
            Log.Exception(
                'Exception happened in ViewState Import was: %s' % (str(e)))
            req.clear()
            req.set_status(500)
            req.finish(
                'Exception happened in ViewState Import was: %s' % (str(e)))
예제 #25
0
def updateMediaAgent(key, agent, year, title):
    global ChangedErr
    global ChangedOK
    url = ''.join((
        misc.GetLoopBack(),
        '/library/metadata/',
        key,
        '/matches?agent=',
        agent,
        '&manual=0'
    ))
    try:
        result = False
        print 'ged 101', url
        SearchResults = XML.ElementFromURL(url).xpath('//SearchResult')
        print 'ged 102'
        Log.Info(
            'Found %s possibillities for %s' % (len(SearchResults), title))
        # for SearchResult in SearchResults:
        SearchResult = SearchResults[0]
        print 'ged 103'
        # Check if there's an year in the title, and if so, remove it
        match = re.match(r'.*([1-2][0-9]{3})', title)
        if match is not None:
            # Then it found a match!
            title = title.replace(match.group(1), '')
            title = re.sub("\(|\)|\[|\]", "", title).strip()
        print 'Ged 104'
        if year == SearchResult.get('year'):
            if title == SearchResult.get('name'):
                if int(SearchResult.get('score')) >= MinScore:
                    print 'ged 55', String.Quote(SearchResult.get('guid'))
                    updateurl = ''.join((
                        misc.GetLoopBack(),
                        '/library/metadata/',
                        key,
                        '/match?guid=',
                        String.Quote(SearchResult.get('guid')),
                        '&name=',
                        String.Quote(SearchResult.get('name'))
                    ))
                    try:
                        result = HTTP.Request(
                            url=updateurl,
                            method='PUT',
                            immediate=True,
                            timeout=5)
                        ChangedOK.append(unicode(title, "utf-8"))
                        result = True
                        print 'Ged 105'
                        break
                    except Exception, e:
                        Log.Exception(
                            'Exception happened in \
                            updateMediaAgent was %s' % str(e))
                        ChangedErr.append(unicode(title, "utf-8"))
                        result = False
                else:
                    Log.Info(
                        'Updating failed, since a score of %s %' % SearchResult.get('score'))
                    Log.Info('is below the minimum of %s %' % MinScore)
        if not result:
            Log.Info('Could not find any match for: %s', title)
            ChangedErr.append(title)
예제 #26
0
def scanShowDB(sectionNumber=0, agent=None, Force=False):
    """Scan Episodes from the database"""
    global statusMsg
    global runningState
    try:
        Log.Debug(
            'Starting scanShowDB for section %s' % (
                sectionNumber))
        runningState = -1
        statusMsg = wtV3().GETTRANSLATE(
            None, Internal=True,
            String='Starting to scan database for section %s')\
            % (sectionNumber)
        # Start by getting the totals of episodes for this section
        urlSize = ''.join((
            misc.GetLoopBack(),
            '/library/sections/',
            sectionNumber,
            '/all?X-Plex-Container-Start=1',
            '&X-Plex-Container-Size=0',
            '&type=',
            str(MEDIATYPE['Episode'])
        ))
        totalSize = XML.ElementFromURL(urlSize).get('totalSize')
        AmountOfMediasInDatabase = totalSize
        Log.Debug('Total size of medias are %s' % (totalSize))
        iEpisode = 0
        iCEpisode = 0
        statusEpisodes = wtV3().GETTRANSLATE(
            None, Internal=True,
            String='Scanning database episodes %s of %s :')\
            % (iEpisode, totalSize)
        statusMsg = statusEpisodes
        # So let's walk the library
        while True:
            # Grap Episodes
            urlEpisodes = ''.join((
                misc.GetLoopBack(),
                '/library/sections/',
                sectionNumber,
                '/all?excludeElements=',
                EXCLUDEELEMENTS,
                '&excludeFields=',
                EXCLUDEFIELDS,
                '&X-Plex-Container-Start=',
                str(iCEpisode),
                '&X-Plex-Container-Size=',
                str(MediaChuncks),
                '&type=',
                str(MEDIATYPE['Episode'])
            ))
            print 'Ged 61 urlEpisodes', urlEpisodes

            episodes = XML.ElementFromURL(urlEpisodes).xpath('//Video')
            # Grap individual shows
            for episode in episodes:
                urlEpisode = ''.join((
                    misc.GetLoopBack(),
                    '/library/metadata/',
                    episode.get('ratingKey'),
                    '?excludeElements=',
                    EXCLUDEELEMENTS,
                    '&excludeFields=',
                    EXCLUDEFIELDS
                ))
                print 'Ged 81', urlEpisode
                currentEpisode = XML.ElementFromURL(
                    urlEpisode).xpath('//Video')[0]
                title = currentEpisode.get('title')
                guid = currentEpisode.get('guid')
                # year = currentShow.get('year')
                # key = currentShow.get('ratingKey')
                statusMsg = 'investigating episode: %s' % (
                    title)
                Log.Info(statusMsg)
                key = episode.get('ratingKey')
                year = episode.get('year')

                print 'GED KIG HER'
                # Store show id in a list. and afterwards, fix each show one by one
                statusMsg = 'Updating show: %s' % (
                    title)
                if agent not in guid:
                    Log.Info(statusMsg)
                    print 'Ged updating', title
                    # key = show.get('ratingKey')
                    # year = show.get('year')
                    updateMediaAgent(key, agent, year, title)
                elif Force:
                    Log.Info(statusMsg)
                    print 'Ged Key', key
                    print 'Ged Agent', agent
                    print 'Ged Year', year
                    print 'Ged Title', title
                    updateMediaAgent(key, agent, year, title)
                else:
                    Log.Info('Episode: %s is okay' % title)
            iCEpisode += MediaChuncks
            if len(episodes) == 0:
                strMsg = (
                    'Scanning database: %s : Done'
                    % (str(totalSize)))
                statusMsg = wtV3().GETTRANSLATE(
                    None, Internal=True,
                    String=strMsg)
                Log.Debug('***** Done scanning the database *****')
                runningState = 1
                break
        return
    except ValueError:
        statusMsg = wtV3().GETTRANSLATE(
            None, Internal=True,
            String='Idle')
        runningState = 99
        Log.Info('Aborted in ScanShowDB')
    except Exception, e:
        Log.Exception('Fatal error in scanShowDB: ' + str(e))
        runningState = 99
예제 #27
0
 def get_thisPMSIdentity(self):
     return XML.ElementFromURL(misc.GetLoopBack() +
                               '/identity').get('machineIdentifier')
예제 #28
0
 def auth2myPlex(self):
     return 'ok' == XML.ElementFromURL(
         misc.GetLoopBack()).get('myPlexSigninState')
예제 #29
0
 def GETINFO(self, req, *args):
     Log.Debug('Starting getInfo')
     try:
         techInfo = {}
         try:
             id = XML.ElementFromURL(misc.GetLoopBack() + '/identity')
         except:
             pass
         # Get File system encoding
         Log.Info('File System Encoding: %s' %
                  str(sys.getfilesystemencoding()))
         techInfo['File System Encoding'] = str(sys.getfilesystemencoding())
         Log.Info(
             '********************** INFO from API **********************')
         try:
             Log.Info('OS is: %s' % Platform.OS)
             techInfo['Platform'] = Platform.OS
         except:
             pass
         try:
             Log.Info('CPU is: %s' % Platform.CPU)
             techInfo['CPU'] = Platform.CPU
         except:
             pass
         try:
             Log.Info('Python version is: %s' % sys.version)
             techInfo['Python'] = sys.version
         except:
             pass
         try:
             Log.Info('Support Silverlight: %s' % Platform.HasSilverlight)
             techInfo['Silverlight'] = Platform.HasSilverlight
         except:
             pass
         try:
             Log.Info('Locale is: %s' % locale.getdefaultlocale())
             techInfo['Locale'] = str(locale.getdefaultlocale())
         except:
             pass
         try:
             Log.Info('Machine Identifier: %s' %
                      id.get('machineIdentifier'))
             techInfo['MachineID'] = id.get('machineIdentifier')
         except:
             pass
         try:
             Log.Info('PMS Version: %s' % id.get('version'))
             techInfo['PMSVersion'] = id.get('version')
         except:
             pass
         try:
             Log.Info('PMS App Support path: %s' % Core.app_support_path)
             techInfo['AppSupportPath_FrameWork'] = Core.app_support_path
         except:
             pass
         Log.Info(
             '********************** INFO from ENV *********************')
         try:
             Log.Info(
                 'PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR: %s' %
                 os.environ['PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR'])
             techInfo['AppSupportPath_OS'] = os.environ[
                 'PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR']
         except:
             pass
         try:
             Log.Info('PYTHONDONTWRITEBYTECODE: %s' %
                      os.environ['PYTHONDONTWRITEBYTECODE'])
             techInfo['PythonDontWriteByteCode'] = os.environ[
                 'PYTHONDONTWRITEBYTECODE']
         except:
             pass
         try:
             Log.Info('USER: %s' % os.environ['USER'])
             techInfo['User'] = os.environ['USER']
         except:
             pass
         try:
             dirUsr = getpwuid(os.stat(Core.bundle_path).st_uid).pw_name
             Log.Info('User BundleDir: %s' % dirUsr)
             techInfo['WebTools directory owner'] = dirUsr
         except:
             pass
         try:
             dirGroup = getgrgid(os.stat(Core.bundle_path).st_gid).gr_name
             Log.Info('Group BundleDir: %s' % dirGroup)
             techInfo['WebTools directory group'] = dirGroup
         except:
             pass
         try:
             Log.Info('HOME: %s' % os.environ['HOME'])
             techInfo['Home'] = os.environ['HOME']
         except:
             pass
         try:
             Log.Info('LD_LIBRARY_PATH: %s' % os.environ['LD_LIBRARY_PATH'])
             techInfo['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
         except:
             pass
         try:
             Log.Info('LANG: %s' % os.environ['LANG'])
             techInfo['LANG'] = os.environ['LANG']
         except:
             pass
         try:
             Log.Info('LANGUAGE: %s' % os.environ['LANGUAGE'])
             techInfo['LANGUAGE'] = os.environ['LANGUAGE']
         except:
             pass
         try:
             Log.Info('TMPDIR: %s' % os.environ['TMPDIR'])
             techInfo['TMPDIR'] = os.environ['TMPDIR']
         except:
             pass
         try:
             Log.Info('PLEXLOCALAPPDATA: %s' %
                      os.environ['PLEXLOCALAPPDATA'])
             techInfo['PLEXLOCALAPPDATA'] = os.environ['PLEXLOCALAPPDATA']
         except:
             pass
         try:
             Log.Info('LC_ALL: %s' % os.environ['LC_ALL'])
             techInfo['LC_ALL'] = os.environ['LC_ALL']
         except:
             pass
         try:
             Log.Info('Executable: %s' % os.environ['_'])
             techInfo['Executable'] = os.environ['_']
         except:
             pass
         try:
             Log.Info('PLEXBUNDLEDEXTS: %s' % os.environ['PLEXBUNDLEDEXTS'])
             techInfo['PLEXBUNDLEDEXTS'] = os.environ['PLEXBUNDLEDEXTS']
         except:
             pass
         try:
             Log.Info('PYTHONHOME: %s' % os.environ['PYTHONHOME'])
             techInfo['PYTHONHOME'] = os.environ['PYTHONHOME']
         except:
             pass
         try:
             Log.Info('PWD: %s' % os.environ['PWD'])
             techInfo['PWD'] = os.environ['PWD']
         except:
             pass
         try:
             Log.Info('PLEXBUNDLEDPLUGINSPATH: ' %
                      os.environ['PLEXBUNDLEDPLUGINSPATH'])
             techInfo['PLEXBUNDLEDPLUGINSPATH'] = os.environ[
                 'PLEXBUNDLEDPLUGINSPATH']
         except:
             pass
         try:
             Log.Info('PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS: ' %
                      os.environ['PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS'])
             techInfo['PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS'] = os.environ[
                 'PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS']
         except:
             pass
         try:
             Log.Info('PLEXTOKEN: **** SCRAMBLED ****')
             StringKey = 'PLEXTOKEN *********'
             StringValue = wtV3().GETTRANSLATE(
                 None,
                 None,
                 Internal=True,
                 String='DO NOT SHARE THIS IN ANY PUBLIC WEBSITE!!!')
             techInfo[StringKey] = StringValue
             techInfo['PLEXTOKEN'] = os.environ['PLEXTOKEN']
         except:
             pass
         try:
             Log.Info('PLEX_MEDIA_SERVER_INFO_VENDOR: ' %
                      os.environ['PLEX_MEDIA_SERVER_INFO_VENDOR'])
             techInfo['PLEX_MEDIA_SERVER_INFO_VENDOR'] = os.environ[
                 'PLEX_MEDIA_SERVER_INFO_VENDOR']
         except:
             pass
         try:
             Log.Info('PLEX_MEDIA_SERVER_INFO_DEVICE: ' %
                      os.environ['PLEX_MEDIA_SERVER_INFO_DEVICE'])
             techInfo['PLEX_MEDIA_SERVER_INFO_DEVICE'] = os.environ[
                 'PLEX_MEDIA_SERVER_INFO_DEVICE']
         except:
             pass
         try:
             Log.Info('PLEX_MEDIA_SERVER_INFO_MODEL: ' %
                      os.environ['PLEX_MEDIA_SERVER_INFO_MODEL'])
             techInfo['PLEX_MEDIA_SERVER_INFO_MODEL'] = os.environ[
                 'PLEX_MEDIA_SERVER_INFO_MODEL']
         except:
             pass
         try:
             Log.Info('PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION: ' %
                      os.environ['PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION'])
             techInfo[
                 'PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION'] = os.environ[
                     'PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION']
         except:
             pass
         Log.Info('********************** INFO End ******************')
         techInfo['Log Directory'] = LOG_DIR
         req.clear()
         req.set_status(200)
         req.set_header('Content-Type', 'application/json; charset=utf-8')
         req.finish(json.dumps(techInfo, sort_keys=True))
     except Exception, e:
         Log.Exception('Exception in getInfo: ' + str(e))
         req.clear()
         req.set_status(500)
         req.finish('Fatal error happened in getInfo: ' + str(e))
         return req
예제 #30
0
 def GETINFO(self, req, *args):
     Log.Debug('Starting getInfo')
     try:
         techInfo = {}
         try:
             id = XML.ElementFromURL(misc.GetLoopBack() + '/identity')
         except:
             pass
         Log.Info(
             '************************** INFO from API **************************'
         )
         try:
             Log.Info('OS is: ' + Platform.OS)
             techInfo['Platform'] = Platform.OS
         except:
             pass
         try:
             Log.Info('CPU is: ' + Platform.CPU)
             techInfo['CPU'] = Platform.CPU
         except:
             pass
         try:
             Log.Info('Python version is: ' + sys.version)
             techInfo['Python'] = sys.version
         except:
             pass
         try:
             Log.Info('Support Silverlight: ' + Platform.HasSilverlight)
             techInfo['Silverlight'] = Platform.HasSilverlight
         except:
             pass
         try:
             Log.Info('Locale is: ' + str(locale.getdefaultlocale()))
             techInfo['Locale'] = str(locale.getdefaultlocale())
         except:
             pass
         try:
             Log.Info('Machine Identifier: ' + id.get('machineIdentifier'))
             techInfo['MachineID'] = id.get('machineIdentifier')
         except:
             pass
         try:
             Log.Info('PMS Version: ' + id.get('version'))
             techInfo['PMSVersion'] = id.get('version')
         except:
             pass
         try:
             Log.Info('PMS App Support path: ' + Core.app_support_path)
             techInfo['AppSupportPath_FrameWork'] = Core.app_support_path
         except:
             pass
         Log.Info(
             '************************** INFO from ENV **************************'
         )
         try:
             Log.Info(
                 'PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR: ' +
                 os.environ['PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR'])
             techInfo['AppSupportPath_OS'] = os.environ[
                 'PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR']
         except:
             pass
         try:
             Log.Info('PYTHONDONTWRITEBYTECODE: ' +
                      os.environ['PYTHONDONTWRITEBYTECODE'])
             techInfo['PythonDontWriteByteCode'] = os.environ[
                 'PYTHONDONTWRITEBYTECODE']
         except:
             pass
         try:
             Log.Info('USER: '******'USER'])
             techInfo['User'] = os.environ['USER']
         except:
             pass
         try:
             Log.Info('HOME: ' + os.environ['HOME'])
             techInfo['Home'] = os.environ['HOME']
         except:
             pass
         try:
             Log.Info('LD_LIBRARY_PATH: ' + os.environ['LD_LIBRARY_PATH'])
             techInfo['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
         except:
             pass
         try:
             Log.Info('LANG: ' + os.environ['LANG'])
             techInfo['LANG'] = os.environ['LANG']
         except:
             pass
         try:
             Log.Info('LANGUAGE: ' + os.environ['LANGUAGE'])
             techInfo['LANGUAGE'] = os.environ['LANGUAGE']
         except:
             pass
         try:
             Log.Info('TMPDIR: ' + os.environ['TMPDIR'])
             techInfo['TMPDIR'] = os.environ['TMPDIR']
         except:
             pass
         try:
             Log.Info('PLEXLOCALAPPDATA: ' + os.environ['PLEXLOCALAPPDATA'])
             techInfo['PLEXLOCALAPPDATA'] = os.environ['PLEXLOCALAPPDATA']
         except:
             pass
         try:
             Log.Info('LC_ALL: ' + os.environ['LC_ALL'])
             techInfo['LC_ALL'] = os.environ['LC_ALL']
         except:
             pass
         try:
             Log.Info('Executable: ' + os.environ['_'])
             techInfo['Executable'] = os.environ['_']
         except:
             pass
         try:
             Log.Info('PLEXBUNDLEDEXTS: ' + os.environ['PLEXBUNDLEDEXTS'])
             techInfo['PLEXBUNDLEDEXTS'] = os.environ['PLEXBUNDLEDEXTS']
         except:
             pass
         try:
             Log.Info('PYTHONHOME: ' + os.environ['PYTHONHOME'])
             techInfo['PYTHONHOME'] = os.environ['PYTHONHOME']
         except:
             pass
         try:
             Log.Info('PWD: ' + os.environ['PWD'])
             techInfo['PWD'] = os.environ['PWD']
         except:
             pass
         try:
             Log.Info('PLEXBUNDLEDPLUGINSPATH: ' +
                      os.environ['PLEXBUNDLEDPLUGINSPATH'])
             techInfo['PLEXBUNDLEDPLUGINSPATH'] = os.environ[
                 'PLEXBUNDLEDPLUGINSPATH']
         except:
             pass
         try:
             Log.Info('PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS: ' +
                      os.environ['PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS'])
             techInfo['PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS'] = os.environ[
                 'PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS']
         except:
             pass
         try:
             Log.Info('PLEXTOKEN: **** SCRAMBLED ****')
             StringKey = 'PLEXTOKEN *********'
             StringValue = wtV3().GETTRANSLATE(
                 None,
                 None,
                 Internal=True,
                 String='DO NOT SHARE THIS IN ANY PUBLIC WEBSITE!!!')
             techInfo[StringKey] = StringValue
             techInfo['PLEXTOKEN'] = os.environ['PLEXTOKEN']
         except:
             pass
         Log.Info(
             '************************** INFO End **********************')
         try:
             if 'PLEX_MEDIA_SERVER_LOG_DIR' in os.environ:
                 LOGDIR = os.environ['PLEX_MEDIA_SERVER_LOG_DIR']
             elif sys.platform.find(
                     'linux') == 0 and 'PLEXLOCALAPPDATA' in os.environ:
                 LOGDIR = os.path.join(os.environ['PLEXLOCALAPPDATA'],
                                       'Plex Media Server', 'Logs')
             elif sys.platform == 'win32':
                 if 'PLEXLOCALAPPDATA' in os.environ:
                     key = 'PLEXLOCALAPPDATA'
                 else:
                     key = 'LOCALAPPDATA'
                 LOGDIR = os.path.join(os.environ[key], 'Plex Media Server',
                                       'Logs')
             else:
                 LOGDIR = os.path.join(os.environ['HOME'], 'Library',
                                       'Logs', 'Plex Media Server')
                 if not os.path.isdir(self.LOGDIR):
                     LOGDIR = os.path.join(Core.app_support_path, 'Logs')
         except Exception, e:
             Log.Exception(
                 'Fatal error happened in getting the Log Directory: ' +
                 str(e))
             req.clear()
             req.set_status(500)
             req.finish(
                 'Fatal error happened in TechInfo getting the Log Dir list: '
                 + str(e))
         techInfo['Log Directory'] = LOGDIR
         req.clear()
         req.set_status(200)
         req.set_header('Content-Type', 'application/json; charset=utf-8')
         req.finish(json.dumps(techInfo, sort_keys=True))