def selectPList():
	Log.Debug("User selected to export a playlist")
	# Abort if set to auto path
	if Prefs['Auto_Path']:
		message = 'Playlists can not be exported when path is set to auto. You need to specify a manual path in the prefs'
		oc = ObjectContainer(title1='Error!. Playlists can not be exported when path is set to auto. You need to specify a manual path in the prefs', no_cache=True, message=message)
		oc.add(DirectoryObject(key=Callback(MainMenu), title="Go to the Main Menu"))
		Log.Debug('Can not continue, since on AutoPath')
		return oc
	# Else build up a menu of the playlists
	oc = ObjectContainer(title1='Select Playlist to export', no_cache=True)
	playlists = XML.ElementFromURL(misc.GetLoopBack() + '/playlists/all', timeout=float(PMSTIMEOUT)).xpath('//Playlist')
	for playlist in playlists:
		title = playlist.get('title')
		try:
			thumb = misc.GetLoopBack() + playlist.get('composite')
		except:
			pass
		playListType= playlist.get('playlistType')
		if playListType in ['video','audio', 'photo']:
			key = playlist.get('key')
			Log.Debug("Added playlist: " + title + " to the listing with a key of: " + key)
			oc.add(DirectoryObject(key=Callback(backgroundScan, title=playListType, sectiontype='playlists', key=key, random=time.clock()), thumb=thumb, title='Export from "' + title + '"', summary='Export list from "' + title + '"'))
	oc.add(DirectoryObject(key=Callback(MainMenu), title="Go to the Main Menu"))
	return oc
def MainMenu(random=0):
	Log.Debug("**********  Starting MainMenu  **********")
	global sectiontype
	title = NAME  + VERSION
	oc = ObjectContainer(title1=title, no_cache=True, no_history=True, art=R(ART))
	oc.view_group = 'List'
	try:
		if ValidateExportPath():
			title = 'playlists'
			key = '-1'
			thumb = R(PLAYLIST)
			sectiontype = title
			oc.add(DirectoryObject(key=Callback(selectPList), thumb=thumb, title='Export from "' + title + '"', summary='Export list from "' + title + '"'))
			Log.Debug('Getting section List from: ' + misc.GetLoopBack() + '/library/sections')
			sections = XML.ElementFromURL(misc.GetLoopBack() + '/library/sections', timeout=float(PMSTIMEOUT)).xpath('//Directory')
			for section in sections:
				sectiontype = section.get('type')
				if sectiontype != "photook": # ToDo: Remove artist when code is in place for it.
					title = section.get('title')
					key = section.get('key')
					thumb = misc.GetLoopBack() + section.get('thumb')		
					Log.Debug('Title of section is %s with a key of %s' %(title, key))
					oc.add(DirectoryObject(key=Callback(backgroundScan, title=title, sectiontype=sectiontype, key=key, random=time.clock()), thumb=thumb, title='Export from "' + title + '"', summary='Export list from "' + title + '"'))
		else:
			oc.add(DirectoryObject(key=Callback(MainMenu, random=time.clock()), title="Select Preferences to set the export path"))
	except:
		Log.Critical("Exception happened in MainMenu")
		raise
	oc.add(PrefsObject(title='Preferences', thumb=R(ICON)))
	Log.Debug("**********  Ending MainMenu  **********")
	return oc
Beispiel #3
0
def sectionList():
    # Path to DefaultPrefs.json
    prefsFile = Core.storage.join_path(Core.app_support_path,
                                       Core.config.bundles_dir_name,
                                       APPNAME + '.bundle', 'Contents',
                                       'DefaultPrefs.json')
    with io.open(prefsFile) as json_file:
        data = json.load(json_file)
    #print(json.dumps(data, indent=4, sort_keys=True))

    # Get list of libraries
    SectionsURL = misc.GetLoopBack() + '/library/sections'
    SectionList = XML.ElementFromURL(SectionsURL).xpath('//Directory')
    LibraryValues = []
    LibraryValues.append('*** Idle ***'.decode('utf-8'))
    LibraryValues.append('*** Reload Library List ***'.decode('utf-8'))
    for Section in SectionList:
        LibraryValues.append(Section.get('title').decode('utf-8'))
    for item in data:
        if item['id'] == 'Libraries':
            item['values'] = LibraryValues
            break
    with io.open(prefsFile, 'wb') as outfile:
        json.dump(data, outfile, indent=4)
    restart()
    return
Beispiel #4
0
def scanArtistDB(myMediaURL, myCSVFile):
    Log.Debug("******* Starting scanArtistDB with an URL of %s ***********" %
              (myMediaURL))
    global bScanStatusCount
    global bScanStatusCountOf
    global bScanStatus
    bScanStatusCount = 0
    try:
        mySepChar = Prefs['Seperator']
        Log.Debug('Writing headers for Audio Export')
        csvfile = io.open(myCSVFile, 'wb')
        csvwriter = csv.DictWriter(csvfile,
                                   fieldnames=audio.getMusicHeader(
                                       Prefs['Artist_Level']),
                                   delimiter=Prefs['Delimiter'],
                                   quoting=csv.QUOTE_NONNUMERIC)
        csvwriter.writeheader()
        if Prefs['Artist_Level'] in audiofields.singleCall:
            bExtraInfo = False
        else:
            bExtraInfo = True
        Log.Debug('Starting to fetch the list of items in this section')
        fetchURL = myMediaURL + '?type=10&X-Plex-Container-Start=' + str(
            bScanStatusCount) + '&X-Plex-Container-Size=0'
        medias = XML.ElementFromURL(fetchURL)
        if bScanStatusCount == 0:
            bScanStatusCountOf = medias.get('totalSize')
            Log.Debug('Amount of items in this section is %s' %
                      bScanStatusCountOf)
        Log.Debug("Walking medias")
        while True:
            fetchURL = myMediaURL + '?type=10&sort=artist.titleSort,album.titleSort:asc&X-Plex-Container-Start=' + str(
                bScanStatusCount) + '&X-Plex-Container-Size=' + str(
                    consts.CONTAINERSIZEAUDIO)
            medias = XML.ElementFromURL(fetchURL)
            if medias.get('size') == '0':
                break
            # HERE WE DO STUFF
            tracks = medias.xpath('.//Track')
            for track in tracks:
                bScanStatusCount += 1
                # Get the Audio Info
                myRow = {}
                # Was extra info needed here?
                if bExtraInfo:
                    myExtendedInfoURL = misc.GetLoopBack(
                    ) + '/library/metadata/' + misc.GetRegInfo(
                        track, 'ratingKey') + '?includeExtras=1'
                    if Prefs['Check_Files']:
                        myExtendedInfoURL = myExtendedInfoURL + '&checkFiles=1'
                    track = XML.ElementFromURL(myExtendedInfoURL).xpath(
                        '//Track')[0]
                audio.getAudioInfo(track, myRow)
                csvwriter.writerow(myRow)
        csvfile.close
    except:
        Log.Critical("Detected an exception in scanArtistDB")
        bScanStatus = 99
        raise  # Dumps the error so you can see what the problem is
    Log.Debug("******* Ending scanArtistDB ***********")
def getOutFileName(title, skipts, level, playlist):
    ''' returns the name of the output file to create '''
    extension = '.' + Prefs['Output_Format']
    # Get current date and time
    if skipts:
        timestr = ''
    else:
        timestr = '-' + time.strftime("%Y%m%d-%H%M%S")
    # Generate Output FileName

    # Remove invalid caracters, if on Windows......
    newtitle = re.sub('[\/[:#*?"<>|]', '_', title).strip()
    if playlist:
        outFile = os.path.join(
            Prefs['Export_Path'], APPNAME,
            'Playlist-' + newtitle + '-' + level + timestr + extension)
    else:
        if Prefs['Auto_Path']:
            # Need to grap the first location for the section
            locations = XML.ElementFromURL(
                misc.GetLoopBack() + '/library/sections/',
                timeout=float(PMSTIMEOUT)).xpath('.//Directory[@title="' +
                                                 title + '"]')[0]
            location = locations[0].get('path')
            outFile = os.path.join(
                location, APPNAME,
                newtitle + '-' + level + timestr + extension)
        else:
            outFile = os.path.join(
                Prefs['Export_Path'], APPNAME,
                newtitle + '-' + level + timestr + extension)
    return outFile
def scanMovieDB(myMediaURL, outFile):
    Log.Debug("******* Starting scanMovieDB with an URL of %s ***********" %
              (myMediaURL))
    Log.Debug('Movie Export level is %s' % (Prefs['Movie_Level']))
    global bScanStatusCount
    global bScanStatusCountOf
    global bScanStatus
    bScanStatusCount = 0
    bScanStatusCountOf = 0
    iCurrent = 0
    try:
        Log.Debug("About to open file %s" % (outFile))
        output.createHeader(outFile, 'movies')
        if Prefs['Movie_Level'] in moviefields.singleCall:
            bExtraInfo = False
        else:
            bExtraInfo = True
        while True:
            Log.Debug("Walking medias")
            fetchURL = myMediaURL + '?X-Plex-Container-Start=' + str(
                iCurrent) + '&X-Plex-Container-Size=' + str(
                    CONTAINERSIZEMOVIES)
            iCount = bScanStatusCount
            partMedias = XML.ElementFromURL(fetchURL,
                                            timeout=float(PMSTIMEOUT))
            if bScanStatusCount == 0:
                bScanStatusCountOf = partMedias.get('totalSize')
                Log.Debug('Amount of items in this section is %s' %
                          bScanStatusCountOf)
            # HERE WE DO STUFF
            Log.Debug("Retrieved part of medias okay [%s of %s]" %
                      (str(bScanStatusCount), str(bScanStatusCountOf)))
            medias = partMedias.xpath('.//Video')
            for media in medias:
                myRow = {}
                # Was extra info needed here?
                if bExtraInfo:
                    myExtendedInfoURL = genParam(
                        misc.GetLoopBack() + '/library/metadata/' +
                        misc.GetRegInfo(media, 'ratingKey'))
                    media = XML.ElementFromURL(
                        myExtendedInfoURL,
                        timeout=float(PMSTIMEOUT)).xpath('//Video')[0]
                # Export the info
                myRow = movies.getMovieInfo(media, myRow)
                output.writerow(myRow)
                iCurrent += 1
                bScanStatusCount += 1
                Log.Debug("Media #%s from database: '%s'" %
                          (str(iCurrent), misc.GetRegInfo(media, 'title')))
            # Got to the end of the line?
            if int(partMedias.get('size')) == 0:
                break
            if bScanStatus == 3:
                break
        output.closefile()
    except ValueError, Argument:
        Log.Critical('Unknown error in scanMovieDb %s' % (Argument))
        bScanStatus = 99
        raise
Beispiel #7
0
def getShowOnly(myMedia, myRow, level):
	prefsLevel = Prefs['TV_Level']
	if prefsLevel in ['Show Only 1', 'Show Only 2', 'Show Only 3']:
		for key, value in tvfields.Show_1:
			element = myMedia.get(value[1:])
			if element == None:
				element = 'N/A'
			element = misc.WrapStr(misc.fixCRLF(element).encode('utf8'))
			if key == 'MetaDB Link':
				myRow[key] = misc.metaDBLink(element)
			elif key in myRow:
				myRow[key] = myRow[key] + Prefs['Seperator'] + element
			else:
				myRow[key] = element
	if prefsLevel in ['Show Only 2', 'Show Only 3']:
		for key, value in tvfields.Show_2:			
			myRow[key] =  misc.GetArrayAsString(myMedia, value, default = consts.DEFAULT)
	# Additional call needed for level 3
	if prefsLevel in ['Show Only 3']:
		directURL = misc.GetLoopBack() + '/library/metadata/' + myRow['Media ID']
		directMedia = XML.ElementFromURL(directURL, timeout=float(consts.PMSTIMEOUT))
		for key, value in tvfields.Show_3:			
			if key == 'MetaDB Link':
				myRow[key] = misc.metaDBLink(str(directMedia.xpath('//Directory/@guid')))			
			else:	
				myRow[key] = misc.GetArrayAsString(directMedia, value, default = consts.DEFAULT)
	return myRow
Beispiel #8
0
def getShowOnly(myMedia, myRow, level):
    ''' Export TV Show info only '''
    if level:
        prefsLevel = level
    else:
        prefsLevel = Prefs['TV_Level']
    if prefsLevel in ['Show Only 1', 'Show Only 2', 'Show Only 3']:
        for key, value in tvfields.Show_1:
            element = myMedia.get(value[1:])
            if element is None:
                element = consts.DEFAULT
            element = misc.WrapStr(misc.fixCRLF(element).encode('utf8'))
            if key == 'MetaDB Link':
                myRow[key] = misc.metaDBLink(element)
            # Is it a dateStamp?
            elif value[1:] in tvfields.dateTimeFields:
                myRow[key] = misc.ConvertDateStamp(element)
            elif key in myRow:
                myRow[key] = myRow[key] + Prefs['Seperator'] + element
            else:
                myRow[key] = element
    if prefsLevel in ['Show Only 2', 'Show Only 3']:
        for key, value in tvfields.Show_2:
            myRow[key] = misc.GetArrayAsString(myMedia,
                                               value,
                                               default=consts.DEFAULT)
    # Additional call needed for level 3
    if prefsLevel in ['Show Only 3']:
        directURL = misc.GetLoopBack() + '/library/metadata/' + \
            myRow['Media ID']
        directMedia = XML.ElementFromURL(directURL,
                                         timeout=float(consts.PMSTIMEOUT))
        for key, value in tvfields.Show_3:
            if key == 'MetaDB Link':
                try:
                    myRow[key] = misc.metaDBLink(
                        str(directMedia.xpath('//Directory/@guid')))
                except Exception, e:
                    myRow[key] = consts.DEFAULT
                    pass
            elif key == 'Delete Item Watched after days':
                try:
                    deleteDays = directMedia.xpath(
                        '//Directory/@autoDeletionItemPolicyWatchedLibrary')
                    if deleteDays == ['100']:
                        deleteDays = 'Next Refresh'
                    elif deleteDays == []:
                        deleteDays = 'Never'
                    elif deleteDays == ['0']:
                        deleteDays = 'Never'
                    elif deleteDays == ['1']:
                        deleteDays = '1 Day'
                    elif deleteDays == ['7']:
                        deleteDays = '7 Days'
                    myRow[key] = deleteDays
                except Exception, e:
                    myRow[key] = consts.DEFAULT
                    pass
Beispiel #9
0
def scanArtistDB(myMediaURL, outFile, level=None):
    ''' This function will scan a Music section.'''
    Log.Debug("*** Starting scanArtistDB with an URL of %s ***" % myMediaURL)
    global bScanStatusCount
    global bScanStatusCountOf
    global bScanStatus
    bScanStatusCount = 0
    try:
        Log.Debug('Writing headers for Audio Export')
        output.createHeader(outFile=outFile, sectionType='audio', level=level)
        if level in audiofields.singleCall:
            bExtraInfo = False
        else:
            bExtraInfo = True
        Log.Debug('Starting to fetch the list of items in this section')
        fetchURL = ''.join((myMediaURL, '?type=10&X-Plex-Container-Start=',
                            str(bScanStatusCount), '&X-Plex-Container-Size=0'))
        medias = XML.ElementFromURL(fetchURL, timeout=float(PMSTIMEOUT))
        if bScanStatusCount == 0:
            bScanStatusCountOf = medias.get('totalSize')
            output.setMax(int(bScanStatusCountOf))
            Log.Debug('Amount of items in this section is %s' %
                      bScanStatusCountOf)
        Log.Debug("Walking medias")
        while True:
            fetchURL = ''.join(
                (myMediaURL, '?type=10&sort=artist.titleSort,album.titleSort:',
                 'asc&X-Plex-Container-Start=', str(bScanStatusCount),
                 '&X-Plex-Container-Size=', str(CONTAINERSIZEAUDIO)))
            medias = XML.ElementFromURL(fetchURL, timeout=float(PMSTIMEOUT))
            if medias.get('size') == '0':
                break
            # HERE WE DO STUFF
            tracks = medias.xpath('.//Track')
            for track in tracks:
                bScanStatusCount += 1
                # Get the Audio Info
                myRow = {}
                # Was extra info needed here?
                if bExtraInfo:
                    myExtendedInfoURL = genParam(''.join(
                        (misc.GetLoopBack(), '/library/metadata/',
                         misc.GetRegInfo(track, 'ratingKey'))))
                    track = XML.ElementFromURL(
                        myExtendedInfoURL,
                        timeout=float(PMSTIMEOUT)).xpath('//Track')[0]
                audio.getAudioInfo(track, myRow, level=level)
                output.writerow(myRow)
        output.closefile()
    except Exception, e:
        Log.Exception("Detected an exception in scanArtistDB as: %s" % str(e))
        bScanStatus = 99
        # Dumps the error so you can see what the problem is
        raise
Beispiel #10
0
def scanMovieDB(myMediaURL, myCSVFile):
	Log.Debug("******* Starting scanMovieDB with an URL of %s ***********" %(myMediaURL))
	Log.Debug('Movie Export level is %s' %(Prefs['Movie_Level']))
	global bScanStatusCount
	global bScanStatusCountOf
	global bScanStatus
	bScanStatusCount = 0
	bScanStatusCountOf = 0	
	iCurrent = 0
	try:
		Log.Debug("About to open file %s" %(myCSVFile))
		csvfile = io.open(myCSVFile,'wb')
		# Create output file, and print the header
		csvwriter = csv.DictWriter(csvfile, fieldnames=movies.getMovieHeader(Prefs['Movie_Level']), delimiter=Prefs['Delimiter'], quoting=csv.QUOTE_NONNUMERIC)
		Log.Debug("Writing header")
		csvwriter.writeheader()
		if Prefs['Movie_Level'] in moviefields.singleCall:
			bExtraInfo = False
		else:
			bExtraInfo = True	
		while True:
			Log.Debug("Walking medias")
			fetchURL = myMediaURL + '?X-Plex-Container-Start=' + str(iCurrent) + '&X-Plex-Container-Size=' + str(consts.CONTAINERSIZEMOVIES)	
			iCount = bScanStatusCount
			partMedias = XML.ElementFromURL(fetchURL)
			if bScanStatusCount == 0:
				bScanStatusCountOf = partMedias.get('totalSize')
				Log.Debug('Amount of items in this section is %s' %bScanStatusCountOf)
			# HERE WE DO STUFF
			Log.Debug("Retrieved part of medias okay [%s of %s]" %(str(bScanStatusCount), str(bScanStatusCountOf)))
			medias = partMedias.xpath('.//Video')
			for media in medias:
				myRow = {}
				# Was extra info needed here?
				if bExtraInfo:
					myExtendedInfoURL = misc.GetLoopBack() + '/library/metadata/' + misc.GetRegInfo(media, 'ratingKey') + '?includeExtras=1'
					if Prefs['Check_Files']:				
						myExtendedInfoURL = myExtendedInfoURL + '&checkFiles=1'				
					media = XML.ElementFromURL(myExtendedInfoURL).xpath('//Video')[0]
				# Export the info			
				myRow = movies.getMovieInfo(media, myRow, csvwriter)
				csvwriter.writerow(myRow)
				iCurrent += 1
				bScanStatusCount += 1
				Log.Debug("Media #%s from database: '%s'" %(str(iCurrent), misc.GetRegInfo(media, 'title')))
			# Got to the end of the line?		
			if int(partMedias.get('size')) == 0:
				break
		csvfile.close
	except ValueError, Argument:
		Log.Critical('Unknown error in scanMovieDb %s' %(Argument))
		bScanStatus = 99
		raise 
Beispiel #11
0
def restart():
    try:
        Log.Debug('Restarting plugin')
        pFile = Core.storage.join_path(Core.app_support_path,
                                       Core.config.bundles_dir_name,
                                       APPNAME + '.bundle', 'Contents',
                                       'Info.plist')
        pl = plistlib.readPlist(pFile)
        url = ''.join((misc.GetLoopBack(),
                       '/:/plugins/%s/restart')) % pl['CFBundleIdentifier']
        HTTP.Request(misc.GetLoopBack() +
                     '/:/plugins/%s/restart' % pl['CFBundleIdentifier'],
                     cacheTime=0,
                     immediate=True)
    except Exception, e:
        try:
            HTTP.Request(misc.GetLoopBack() +
                         '/:/plugins/com.plexapp.system/restart',
                         immediate=True)
        except:
            pass
def scanArtistDB(myMediaURL, outFile):
    Log.Debug("******* Starting scanArtistDB with an URL of %s ***********" %
              (myMediaURL))
    global bScanStatusCount
    global bScanStatusCountOf
    global bScanStatus
    bScanStatusCount = 0
    try:
        Log.Debug('Writing headers for Audio Export')
        output.createHeader(outFile, 'audio')
        if Prefs['Artist_Level'] in audiofields.singleCall:
            bExtraInfo = False
        else:
            bExtraInfo = True
        Log.Debug('Starting to fetch the list of items in this section')
        fetchURL = myMediaURL + '?type=10&X-Plex-Container-Start=' + str(
            bScanStatusCount) + '&X-Plex-Container-Size=0'
        medias = XML.ElementFromURL(fetchURL, timeout=float(PMSTIMEOUT))
        if bScanStatusCount == 0:
            bScanStatusCountOf = medias.get('totalSize')
            Log.Debug('Amount of items in this section is %s' %
                      bScanStatusCountOf)
        Log.Debug("Walking medias")
        while True:
            fetchURL = myMediaURL + '?type=10&sort=artist.titleSort,album.titleSort:asc&X-Plex-Container-Start=' + str(
                bScanStatusCount) + '&X-Plex-Container-Size=' + str(
                    CONTAINERSIZEAUDIO)
            medias = XML.ElementFromURL(fetchURL, timeout=float(PMSTIMEOUT))
            if medias.get('size') == '0':
                break
            # HERE WE DO STUFF
            tracks = medias.xpath('.//Track')
            for track in tracks:
                bScanStatusCount += 1
                # Get the Audio Info
                myRow = {}
                # Was extra info needed here?
                if bExtraInfo:
                    myExtendedInfoURL = genParam(
                        misc.GetLoopBack() + '/library/metadata/' +
                        misc.GetRegInfo(track, 'ratingKey'))
                    track = XML.ElementFromURL(
                        myExtendedInfoURL,
                        timeout=float(PMSTIMEOUT)).xpath('//Track')[0]
                audio.getAudioInfo(track, myRow)
                output.writerow(myRow)
        output.closefile()
    except:
        Log.Critical("Detected an exception in scanArtistDB")
        bScanStatus = 99
        raise  # Dumps the error so you can see what the problem is
    Log.Debug("******* Ending scanArtistDB ***********")
Beispiel #13
0
def ResetToIdle():
    '''
    Reset Library Prefs to idle
    '''
    pFile = Core.storage.join_path(Core.app_support_path,
                                   Core.config.bundles_dir_name,
                                   APPNAME + '.bundle', 'Contents',
                                   'Info.plist')
    pl = plistlib.readPlist(pFile)
    CFBundleIdentifier = pl['CFBundleIdentifier']
    url = ''.join((misc.GetLoopBack(), '/:/plugins/', CFBundleIdentifier,
                   '/prefs/set?Libraries=***%20Idle%20***'))
    HTTP.Request(url, cacheTime=0, immediate=True)
    return
Beispiel #14
0
def ScanLib(title='', skipts=False, level=None):
    Log.Debug('Starting to scan section from prefs: %s' % title)
    # Get list of libraries
    SectionsURL = misc.GetLoopBack() + '/library/sections'
    Library = XML.ElementFromURL(SectionsURL).xpath('//Directory[@title="' +
                                                    title + '"]')
    key = Library[0].get('key').decode('utf-8')
    sectiontype = Library[0].get('type').decode('utf-8')
    Log.Debug('Key detected as %s and type as %s' % (key, sectiontype))
    Thread.Create(backgroundScanThread,
                  globalize=True,
                  title=title,
                  key=key,
                  sectiontype=sectiontype,
                  skipts=skipts,
                  level=level)
    return
Beispiel #15
0
def getPhotoItems(medias, bExtraInfo):
	global bScanStatusCount
	try:
		# Start by grapping pictures here
		et = medias.xpath('.//Photo')
		for element in et:
			myRow = {}
			myRow = photo.getInfo(element, myRow)		
			bScanStatusCount += 1		
			output.writerow(myRow)	
		# Elements that are directories
		et = medias.xpath('.//Directory')
		for element in et:
			myExtendedInfoURL = genParam(misc.GetLoopBack() + element.get('key'))
			# TODO: Make small steps here when req. photos
			elements = XML.ElementFromURL(myExtendedInfoURL, timeout=float(PMSTIMEOUT))
			getPhotoItems(elements, bExtraInfo)
	except Exception, e:
		Log.Debug('Exception in getPhotoItems was %s' %(str(e)))
		pass
Beispiel #16
0
def getShowOnly(myMedia, myRow, level):
    prefsLevel = Prefs['TV_Level']
    for key, value in tvfields.Show_1:
        element = myMedia.get(value[1:])
        if element == None:
            element = 'N/A'
        element = misc.WrapStr(misc.fixCRLF(element).encode('utf8'))
        if key in myRow:
            myRow[key] = myRow[key] + Prefs['Seperator'] + element
        else:
            myRow[key] = element
    # Now we sadly needs to make a call for each show :-(
    if '2' in prefsLevel:
        myExtendedInfoURL = misc.GetLoopBack(
        ) + '/library/metadata/' + myMedia.get('ratingKey')
        for key, value in tvfields.Show_2:
            if key == 'MetaDB Link':
                myRow[key] = misc.metaDBLink(
                    XML.ElementFromURL(
                        myExtendedInfoURL,
                        timeout=float(consts.PMSTIMEOUT))[0].xpath('@guid')[0])

    return myRow
Beispiel #17
0
def getPhotoItems(medias, csvwriter, bExtraInfo):
    global bScanStatusCount
    # Start by grapping pictures here
    et = medias.xpath('.//Photo')
    for element in et:
        myRow = {}
        myRow = photo.getInfo(element, myRow)
        bScanStatusCount += 1
        csvwriter.writerow(myRow)
    # Elements that are directories
    et = medias.xpath('.//Directory')
    for element in et:
        myExtendedInfoURL = misc.GetLoopBack() + element.get(
            'key') + '?includeExtras=1'
        #		if bExtraInfo:
        #			if Prefs['Check_Files']:
        #				myExtendedInfoURL = myExtendedInfoURL + '&checkFiles=1'
        # TODO: Make small steps here when req. photos
        elements = XML.ElementFromURL(myExtendedInfoURL,
                                      timeout=float(consts.PMSTIMEOUT))
        #		if bExtraInfo:

        getPhotoItems(elements, csvwriter, bExtraInfo)
Beispiel #18
0
def createFile(sectionKey, sectionType, title):
	global newtitle
	# Type of export
	global extension
	# Name of muFile
	global muFile
	# fileObject for 3mu file
	global writer3muFile
	global playListType
	extension = '.' + Prefs['Output_Format']
	# Placeholder for return array
	retVal =[]
	if sectionType == 'playlists':
		myMediaURL = misc.GetLoopBack() + sectionKey
		playListType = title
		title = XML.ElementFromURL(myMediaURL, timeout=float(PMSTIMEOUT)).get('title')
	else:
		myMediaURL = misc.GetLoopBack() + '/library/sections/' + sectionKey + "/all"
	Log.Debug("Path to medias in selection is %s" %(myMediaURL))
	# Get current date and time
	timestr = time.strftime("%Y%m%d-%H%M%S")
	# Generate Output FileName
	if sectionType == 'show':
		myLevel = Prefs['TV_Level']
	elif sectionType == 'movie':
		myLevel = Prefs['Movie_Level']
	elif sectionType == 'artist':
		myLevel = Prefs['Artist_Level']
	elif sectionType == 'photo':
		myLevel = Prefs['Photo_Level']
	elif sectionType == 'playlists':
		myLevel = Prefs['PlayList_Level']
	else:
		myLevel = ''
	# Remove invalid caracters, if on Windows......
	newtitle = re.sub('[\/[:#*?"<>|]', '_', title).strip()
	if sectionType == 'playlists':
		outFile = os.path.join(Prefs['Export_Path'], NAME, 'Playlist-' + newtitle + '-' + myLevel + '-' + timestr + extension)
		if Prefs['mu_Level'] != 'Disabled':
			muFile = os.path.join(Prefs['Export_Path'], NAME, 'Playlist-' + newtitle + '-' + Prefs['mu_Level'] + '-' + timestr + '.m3u8')
			writer3muFile = codecs.open(muFile,'w', encoding='utf8')
			if Prefs['mu_Level'] == 'Enhanced':
				writer3muFile.write(unicode('#EXTM3U') + '\n')
				writer3muFile.write(unicode('#Written by ExportTools for Plex') + '\n')
				writer3muFile.write(unicode('#Playlist name: ' + newtitle) + '\n')
	else:
		if Prefs['Auto_Path']:
			# Need to grap the first location for the section
			locations = XML.ElementFromURL('http://127.0.0.1:32400/library/sections/', timeout=float(PMSTIMEOUT)).xpath('.//Directory[@key="' + sectionKey + '"]')[0]
			location = locations[0].get('path')
			outFile = os.path.join(location, NAME, newtitle + '-' + myLevel + '-' + timestr + extension)
			if not os.path.exists(os.path.join(location, NAME)):
				os.makedirs(os.path.join(location, NAME))
				Log.Debug('Auto Created directory named: %s' %(os.path.join(location, NAME)))
			else:
				Log.Debug('Auto directory named: %s already exists' %(os.path.join(location, NAME)))
		else:
			outFile = os.path.join(Prefs['Export_Path'], NAME, newtitle + '-' + myLevel + '-' + timestr + extension)
	# Add what we got to the return array
	retVal.append(outFile)
	retVal.append(myMediaURL)
	# Posters ?
	global doPosters
	doPosters = False		
	if Prefs['Export_Posters']:	
		global posterDir
		if sectionType == 'show':
			if Prefs['TV_Level'] not in ["Level 1"]:
				doPosters = True
		if sectionType == 'movie':
			if Prefs['Movie_Level'] not in ["Level 1","Level 2","Special Level 1"]:
				doPosters = True
		if doPosters:
			posterDir = os.path.join(os.path.dirname(outFile), 'posters')
			if not os.path.exists(posterDir):
				os.makedirs(posterDir)
	return retVal
Beispiel #19
0
                # Write Enhanced Info
                writer3muFile.write(unicode(line) + '\n')
            # Write FileName
            writer3muFile.write(unicode(rowentry['File Name']) + '\n')
            # Write special comment, that maybe can be used for import later
            info = {}
            info['type'] = rowentry['Type']
            info['id'] = rowentry['Media ID']
            strInfo = '#' + str(info)
            writer3muFile.write(unicode(strInfo) + '\n')
    except Exception, e:
        Log.Exception('Exception writing 3mu entry was %s' % str(e))
        pass

    if doPosters:
        posterUrl = ''.join((misc.GetLoopBack(), '/photo/:/transcode?width=',
                             str(Prefs['Poster_Width']), '&height=',
                             str(Prefs['Poster_Hight']), '&minSize=1&url=',
                             String.Quote(rowentry['Poster url'])))
        try:
            thumbFile = os.path.join(posterDir, rowentry['Media ID'] + '.jpg')
            thumb = HTTP.Request(posterUrl).content
            with io.open(thumbFile, 'wb') as handler:
                handler.write(thumb)
        except Exception, e:
            Log.Exception('Exception was %s' % str(e))


def closefile():
    ''' Close file again '''
    global targetfile
Beispiel #20
0
                writer3muFile.write(unicode(line) + '\n')
            # Write FileName
            writer3muFile.write(unicode(rowentry['File Name']) + '\n')
            # Write special comment, that maybe can be used for import later
            info = {}
            info['type'] = rowentry['Type']
            info['id'] = rowentry['Media ID']
            strInfo = '#' + str(info)
            writer3muFile.write(unicode(strInfo) + '\n')
    except Exception, e:
        Log.Exception('Exception writing 3mu entry was %s' % str(e))
        pass

    if doPosters:
        posterUrl = ''.join((
            misc.GetLoopBack(),
            '/photo/:/transcode?width=',
            str(Prefs['Poster_Width']),
            '&height=',
            str(Prefs['Poster_Hight']),
            '&minSize=1&url=',
            String.Quote(rowentry['Poster url'])))
        try:
            thumbFile = os.path.join(posterDir, rowentry['Media ID'] + '.jpg')
            thumb = HTTP.Request(posterUrl).content
            with io.open(thumbFile, 'wb') as handler:
                handler.write(thumb)
        except Exception, e:
            Log.Exception('Exception was %s' % str(e))

Beispiel #21
0
def scanShowDB(myMediaURL, outFile):
    Log.Debug("******* Starting scanShowDB with an URL of %s ***********" %(myMediaURL))
    global bScanStatusCount
    global bScanStatusCountOf
    global bScanStatus
    bScanStatusCount = 0
    bScanStatusCountOf = 0	
    try:
        Log.Debug("About to open file %s" %(outFile))
        output.createHeader(outFile, 'tvseries')
        if Prefs['TV_Level'] in tvfields.singleCall:
            bExtraInfo = False
        else:
            bExtraInfo = True	
        Log.Debug('Starting to fetch the list of items in this section')
        while True:
            Log.Debug("Walking medias")
            iCount = bScanStatusCount
            if 'Show Only' in Prefs['TV_Level']:
                fetchURL = myMediaURL + '?X-Plex-Container-Start=' + str(iCount) + '&X-Plex-Container-Size=1'
            else:			
                fetchURL = myMediaURL + '?X-Plex-Container-Start=' + str(iCount) + '&X-Plex-Container-Size=' + str(CONTAINERSIZETV)			
            partMedias = XML.ElementFromURL(fetchURL, timeout=float(PMSTIMEOUT))
            if bScanStatusCount == 0:
                bScanStatusCountOf = partMedias.get('totalSize')
                Log.Debug('Amount of items in this section is %s' %bScanStatusCountOf)
            # HERE WE DO STUFF
            Log.Debug("Retrieved part of medias okay [%s of %s]" %(str(iCount), str(bScanStatusCountOf)))
            for TVShow in partMedias:
                bScanStatusCount += 1
                iCount += 1
                ratingKey = TVShow.get("ratingKey")
                title = TVShow.get("title")
                if 'Show Only' in Prefs['TV_Level']:                    
                    myRow = {}
                    # Export the info                    
                    myRow = tvseries.getShowOnly(TVShow, myRow, Prefs['TV_Level'])
                    try:
                        output.writerow(myRow)
                    except Exception, e:
                        Log.Exception('Exception happend in ScanShowDB: %s' %str(e))
                    continue					
                else:
                    if Prefs['TV_Level'] in ['Level 2','Level 3', 'Level 4', 'Level 5', 'Level 6', 'Level 7', 'Level 8', 'Level 666']:
                        myURL = misc.GetLoopBack() + '/library/metadata/' + ratingKey
                        tvSeriesInfo = XML.ElementFromURL(myURL, timeout=float(PMSTIMEOUT))
                        # Getting stuff from the main TV-Show page
                        # Grab collections
                        serieInfo = tvSeriesInfo.xpath('//Directory/Collection')
                        myCol = ''
                        for collection in serieInfo:
                            if myCol == '':
                                myCol = collection.get('tag')
                            else:
                                myCol = myCol + Prefs['Seperator'] + collection.get('tag')
                        if myCol == '':
                            myCol = 'N/A'
                        # Grab locked fields
                        serieInfo = tvSeriesInfo.xpath('//Directory/Field')
                        myField = ''
                        for Field in serieInfo:
                            if myField == '':
                                myField = Field.get('name')
                            else:
                                myField = myField + Prefs['Seperator'] + Field.get('name')
                        if myField == '':
                            myField = 'N/A'
                    # Get size of TV-Show
                    episodeTotalSize = XML.ElementFromURL(misc.GetLoopBack() + '/library/metadata/' + ratingKey + '/allLeaves?X-Plex-Container-Start=0&X-Plex-Container-Size=0', timeout=float(PMSTIMEOUT)).xpath('@totalSize')[0]
                    Log.Debug('Show: %s has %s episodes' %(title, episodeTotalSize))
                    episodeCounter = 0
                    baseURL = misc.GetLoopBack() + '/library/metadata/' + ratingKey + '/allLeaves'
                    while True:
                        myURL = baseURL + '?X-Plex-Container-Start=' + str(episodeCounter) + '&X-Plex-Container-Size=' + str(CONTAINERSIZEEPISODES)
                        Log.Debug('Show %s of %s with a RatingKey of %s at myURL: %s with a title of "%s" episode %s of %s' %(iCount, bScanStatusCountOf, ratingKey, myURL, title, episodeCounter, episodeTotalSize))
                        MainEpisodes = XML.ElementFromURL(myURL, timeout=float(PMSTIMEOUT))
                        Episodes = MainEpisodes.xpath('//Video')
                        for Episode in Episodes:
                            myRow = {}	
                            # Was extra info needed here?
                            if bExtraInfo:
                                myExtendedInfoURL = genParam(misc.GetLoopBack() + '/library/metadata/' + misc.GetRegInfo(Episode, 'ratingKey'))
                                Episode = XML.ElementFromURL(myExtendedInfoURL, timeout=float(PMSTIMEOUT)).xpath('//Video')[0]
                            # Export the info			
                            myRow = tvseries.getTvInfo(Episode, myRow)
                            if Prefs['TV_Level'] in ['Level 2','Level 3', 'Level 4', 'Level 5', 'Level 6', 'Level 7', 'Level 8', 'Level 666']:
                                myRow['Collection'] = myCol
                                myRow['Locked Fields'] = myField									
                            output.writerow(myRow)								
                        episodeCounter += CONTAINERSIZEEPISODES
                        if episodeCounter > int(episodeTotalSize):
                            break
            # Got to the end of the line?		
            if int(partMedias.get('size')) == 0:
                break
        output.closefile()
Beispiel #22
0
def scanShowDB(myMediaURL, myCSVFile):
	Log.Debug("******* Starting scanShowDB with an URL of %s ***********" %(myMediaURL))
	global bScanStatusCount
	global bScanStatusCountOf
	global bScanStatus
	bScanStatusCount = 0
	bScanStatusCountOf = 0	
	try:
		Log.Debug("About to open file %s" %(myCSVFile))
		csvfile = io.open(myCSVFile,'wb')
		# Create output file, and print the header
		csvwriter = csv.DictWriter(csvfile, fieldnames=tvseries.getTVHeader(Prefs['TV_Level']), delimiter=Prefs['Delimiter'], quoting=csv.QUOTE_NONNUMERIC)
		Log.Debug("Writing header")
		csvwriter.writeheader()
		if Prefs['TV_Level'] in tvfields.singleCall:
			bExtraInfo = False
		else:
			bExtraInfo = True	
		Log.Debug('Starting to fetch the list of items in this section')
		while True:
			Log.Debug("Walking medias")
			iCount = bScanStatusCount
			fetchURL = myMediaURL + '?X-Plex-Container-Start=' + str(iCount) + '&X-Plex-Container-Size=' + str(consts.CONTAINERSIZETV)			
			partMedias = XML.ElementFromURL(fetchURL, headers=MYHEADER)
			if bScanStatusCount == 0:
				bScanStatusCountOf = partMedias.get('totalSize')
				Log.Debug('Amount of items in this section is %s' %bScanStatusCountOf)
			# HERE WE DO STUFF
			Log.Debug("Retrieved part of medias okay [%s of %s]" %(str(iCount), str(bScanStatusCountOf)))
			AllTVShows = partMedias.xpath('.//Directory')
			for TVShows in AllTVShows:
				bScanStatusCount += 1
				iCount += 1
				ratingKey = TVShows.get("ratingKey")
				title = TVShows.get("title")
				if Prefs['TV_Level'] in ['Level 2','Level 3', 'Level 4', 'Level 5', 'Level 6', 'Level 7', 'Level 8', 'Level 666']:
					# Getting stuff from the main TV-Show page
					myURL = misc.GetLoopBack() + '/library/metadata/' + ratingKey
					# Grab collections
					serieInfo = XML.ElementFromURL(myURL).xpath('//Directory/Collection')
					myCol = ''
					for collection in serieInfo:
						if myCol == '':
							myCol = collection.get('tag')
						else:
							myCol = myCol + Prefs['Seperator'] + collection.get('tag')
					if myCol == '':
						myCol = 'N/A'
					# Grab locked fields
					serieInfo = XML.ElementFromURL(myURL).xpath('//Directory/Field')
					myField = ''
					for Field in serieInfo:
						if myField == '':
							myField = Field.get('name')
						else:
							myField = myField + Prefs['Seperator'] + Field.get('name')
					if myField == '':
						myField = 'N/A'
				myURL = misc.GetLoopBack() + '/library/metadata/' + ratingKey + '/allLeaves'
				Log.Debug('Show %s of %s with a RatingKey of %s at myURL: %s with a title of "%s"' %(iCount, bScanStatusCountOf, ratingKey, myURL, title))			
				MainEpisodes = XML.ElementFromURL(myURL)
				Episodes = MainEpisodes.xpath('//Video')
				Log.Debug('Show %s with an index of %s contains %s episodes' %(MainEpisodes.get('parentTitle'), iCount, MainEpisodes.get('size')))
				for Episode in Episodes:
					myRow = {}	
					# Was extra info needed here?
					if bExtraInfo:
						myExtendedInfoURL = misc.GetLoopBack() + '/library/metadata/' + misc.GetRegInfo(Episode, 'ratingKey') + '?includeExtras=1'
						if Prefs['Check_Files']:				
							myExtendedInfoURL = myExtendedInfoURL + '&checkFiles=1'							
						Episode = XML.ElementFromURL(myExtendedInfoURL).xpath('//Video')[0]
					# Export the info			
					myRow = tvseries.getTvInfo(Episode, myRow)
					if Prefs['TV_Level'] in ['Level 2','Level 3', 'Level 4', 'Level 5', 'Level 6', 'Level 7', 'Level 8', 'Level 666']:
						myRow['Collection'] = myCol
						myRow['Locked Fields'] = myField




#					Log.Debug("Show %s from database: %s Season %s Episode %s title: %s" %(bScanStatusCount, misc.GetRegInfo(Episode, 'grandparentTitle'), misc.GetRegInfo(Episode, 'parentIndex'), misc.GetRegInfo(Episode, 'index'), misc.GetRegInfo(Episode, 'title')))							
					csvwriter.writerow(myRow)								
			# Got to the end of the line?		
			if int(partMedias.get('size')) == 0:
				break
		csvfile.close
	except ValueError as err:
		Log.Debug('Exception happend as %s' %err.args)		
	Log.Debug("******* Ending scanShowDB ***********")
Beispiel #23
0
def backgroundScanThread(title, key, sectiontype):
	Log.Debug("*******  Starting backgroundScanThread  ***********")
	global bScanStatus
	global bScanStatusCount
	global bScanStatusCountOf	
	global EXPORTPATH
	try:
		bScanStatus = 1
		Log.Debug("Section type is %s" %(sectiontype))
		if sectiontype == 'playlists':
			myMediaURL = misc.GetLoopBack() + key
			playListType = title
			title = XML.ElementFromURL(myMediaURL).get('title')
		else:
			myMediaURL = misc.GetLoopBack() + '/library/sections/' + key + "/all"
		Log.Debug("Path to medias in selection is %s" %(myMediaURL))
		# Get current date and time
		timestr = time.strftime("%Y%m%d-%H%M%S")
		# Generate Output FileName
		if sectiontype == 'show':
			myLevel = Prefs['TV_Level']
		elif sectiontype == 'movie':
			myLevel = Prefs['Movie_Level']
		elif sectiontype == 'artist':
			myLevel = Prefs['Artist_Level']
		elif sectiontype == 'photo':
			myLevel = Prefs['Photo_Level']
		elif sectiontype == 'playlists':
			myLevel = Prefs['PlayList_Level']
		else:
			myLevel = ''
		# Remove invalid caracters, if on Windows......
		newtitle = re.sub('[\/[:#*?"<>|]', '_', title)
		if sectiontype == 'playlists':
			myCSVFile = os.path.join(Prefs['Export_Path'], consts.NAME, 'Playlist-' + newtitle + '-' + myLevel + '-' + timestr + '.csv')
		else:
			if Prefs['Auto_Path']:
				# Need to grap the first location for the section
				locations = XML.ElementFromURL('http://127.0.0.1:32400/library/sections/').xpath('.//Directory[@key="' + key + '"]')[0]
				location = locations[0].get('path')
				myCSVFile = os.path.join(location, consts.NAME, newtitle + '-' + myLevel + '-' + timestr + '.csv')
				if not os.path.exists(os.path.join(location, consts.NAME)):
					os.makedirs(os.path.join(location, consts.NAME))
					Log.Debug('Auto Created directory named: %s' %(os.path.join(location, consts.NAME)))
				else:
					Log.Debug('Auto directory named: %s already exists' %(os.path.join(location, consts.NAME)))
			else:
				myCSVFile = os.path.join(Prefs['Export_Path'], consts.NAME, newtitle + '-' + myLevel + '-' + timestr + '.csv')
		EXPORTPATH = myCSVFile
		Log.Debug('Output file is named %s' %(myCSVFile))
		# Scan the database based on the type of section
		if sectiontype == "movie":
			scanMovieDB(myMediaURL, myCSVFile)
		elif sectiontype == "artist":
			scanArtistDB(myMediaURL, myCSVFile)
		elif sectiontype == "show":
			scanShowDB(myMediaURL, myCSVFile)
		elif sectiontype == "playlists":
			scanPList(myMediaURL, playListType, myCSVFile)
		elif sectiontype == "photo":
			scanPhotoDB(myMediaURL, myCSVFile)
		else:
			Log.Debug("Error: unknown section type: %s" %(sectiontype))
			bScanStatus = 91
		# Stop scanner on error
		if bScanStatus >= 90: return
		Log.Debug("*******  Ending backgroundScanThread  ***********")
		bScanStatus = 2
		return
	except:
		Log.Critical("Exception happened in backgroundScanThread")
		bScanStatus = 99
		raise
	Log.Debug("*******  Ending backgroundScanThread  ***********")