########################################################################
###   PROXY TOOLS 1.0
###   by Brian Willard
###   mybikeislost@gmail.com
###
###   Generates reformat and write nodes for rendering proxies on a farm
###   option to process all read nodes, selected read nodes, or all quicktime files in a script 
###   reads metadata to determine filetype to handle quicktime files with and without and extension.
###   process sequences proxy subfolders
###   option to create a read node that reflects the new proxy/fullres path
###   TODO: add support for r3d files
###          
###
########################################################################

import re
import os
import sys
import nuke
import nukescripts
def proxyTools():

    def _buildPROXIES(selection, processPlates, createRead, formatFullVal, formatProxyVal, formatProxySizeVal):
        print '\n######## PROXYTOOLS Variables ########\n'
        print 'selection: ' +selection
        print 'processPlates: ' +processPlates
        print 'createRead: ' +str(createRead)
        print 'formatFullVal: ' +formatFullVal
        print 'formatProxyVal: ' +formatProxyVal
        print 'formatProxySizeVal: ' +formatProxySizeVal
        print '\n###############################\n'
        
        ### Figure out what we're rendering and build a list (all, selected, quicktime)
        readlist = []                  
        if selection ==('selected'):
            readlist= [i for i in nuke.selectedNodes() if i.Class() =='Read'] 
            if readlist ==[]:
                nuke.message('no Read nodes selected!')
                return
        if selection == ('all'):
            readlist= [i for i in nuke.allNodes() if i.Class() =='Read']
        if selection == ('quicktime'):
            readlist = [i for i in nuke.allNodes() if i.metadata('input/filereader') == 'QuickTime']

        ### Figure out if we're rendering fullres, proxies, or both    
        if processPlates == 'both':
            processProxy = True
            processFull = True
            print 'rendering Proxy and FullRes'
        if processPlates == 'proxy':
            processFull = False
            processProxy = True
            print 'rendering Proxy only'
        if processPlates == 'full':
            processFull = True
            processProxy = False
            print 'rendering FullRes only'
   
      
        if sys.platform.startswith('win'): 
            pathslash = ('\\')
        else:
            pathslash = ('/') 

        for i in readlist:

            curNode = i
            truncpath = i.knob('file').value().rfind(pathslash)
            truncfile = i.knob('file').value().rfind('.mov')
            dirpath = i.knob('file').value()[:truncpath]
            print '\n######## Begin ' +i.name() + ' ########\n'            

    
            ### Get filename and padding info from source knob
            if i.metadata('input/filereader') == 'QuickTime':
               filetype='quicktime'
               filepath = i.knob('file').getValue('fileName')

               filename = os.path.splitext(i.knob('file').getValue('fileName').split(pathslash)[-1])[-2]
               padding = 4
               print 'source file is a quicktime ' 
               fullFmt = str(int((i.format().width()))) +'x' +str(int((i.format().height())))
               print 'filepath: ' +filepath
               print 'filename: ' +filename
               print 'fullFmt: ' +fullFmt
               resFolder = False
    
            else:
                filetype='imgSequence' 
                filepath = i.knob('file').getValue('fileName')
                filename =(i.knob('file').getValue('fileName')).split('.')[-3].split(pathslash)[-1]
                parentfolder = (i.knob('file').getValue('fileName')).split('.')[-3].split(pathslash)[-2]
                fullFmt = str(int((i.format().width()))) +'x' +str(int((i.format().height())))
                print 'source file is an image sequence'
                print 'filepath: ' +filepath
                print 'filename: ' +filename
                print 'parentfolder: ' +parentfolder
                print 'fullFmt: ' +fullFmt
                if parentfolder == fullFmt:
                    resFolder = True
                    print 'we are in a resolution folder, rendering 1 level up'
                    dirpath = os.sep.join(dirpath.split(pathslash)[:-1])
                    print 'adjusted output path is: ' +dirpath
                else:
                    resFolder = False
                    print 'fullres not in a format folder, creating sub folders'
                    #print 'adjusted output path is: ' +dirpath
                
                number = re.search('(%+\d+d)|(#+)|(%d)' , filepath) 
                if number:
                    padding = len(number.group(1)) 
                path = i.knob('file').value()
                if path.find('rnd'):
                    os.path.basename(path)
    
            foldername = filename + '_IMG'   
#            try:
#                os.mkdir(dirpath +pathslash +foldername)
#            except OSError:            pass
    
            ######################################################
            ###   BUILD PROXY
            ###   FILTER TYPES BY PROXY RASTER: Full (Impulse), half (Cubic), quarter (Cubic)
            ###
            ######################################################
            if processProxy == True:
    
                ### CREATE FORMAT
                m = nuke.createNode('Reformat', inpanel = False)
                m.setInput(0,i)
                m.setXYpos((int(i.knob('xpos').value())), (int(i.knob('ypos').value())+125))

                m.knob('type').setValue('scale')
                if formatProxySizeVal ==('full'):
                    sizeVal = 1.0
                    m.knob('filter').setValue('Impulse')
                elif formatProxySizeVal ==('half'):
                    sizeVal = 0.5
                    m.knob('filter').setValue('Cubic')
                elif formatProxySizeVal ==('quarter'):
                    sizeVal = 0.25
                    m.knob('filter').setValue('Cubic')   
                m.knob('scale').setValue(sizeVal)             
                m.knob('label').setValue('Filter: '+ m.knob('filter').value()+ '\nProxy Size: ' +formatProxySizeVal)
            
                ### CREATE WRITE
                
                n = nuke.createNode('Write', inpanel=False)
                n.setXYpos((int(m.knob('xpos').value())), (int(m.knob('ypos').value())+50))

                proxyFmt = str(int((i.format().width())*sizeVal)) +'x' +str(int((i.format().height())*sizeVal)) 
                print 'proxyFmt: ' +proxyFmt
                if formatProxyVal ==('exr'):
                    if resFolder == True:
                        n.knob('file').setValue(dirpath +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')
                    else:
                        n.knob('file').setValue(dirpath +pathslash + foldername +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')
                    n.knob('file_type').setValue('exr')
                    n.knob('channels').setValue('all')
                    n.knob('colorspace').setValue(int(i.knob('colorspace').getValue()))
                    n.knob('premultiplied').setValue(i.knob('premultiplied').value())
                    n.knob('raw').setValue(i.knob('raw').value())
                    n.knob('stereo').setValue(False)
                elif formatProxyVal ==('jpeg'):
                    n.knob('file_type').setValue('jpeg')
                    n.knob('channels').setValue('all')
                    n.knob('_jpeg_quality').setValue(0.97)
                    if resFolder == True:
                        n.knob('file').setValue(dirpath +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.jpg')
                    else:
                        n.knob('file').setValue(dirpath +pathslash + foldername +pathslash +proxyFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.jpg')
                n.knob('disable').setExpression('!inrange(frame, '+ str(i.knob('first').value()) + ', ' + str(i.knob('last').value()) + ')',0)
                n.knob('label').setValue('PROXY \n Format: ' + proxyFmt)
                print 'Proxy output: ' +n.knob('file').getValue()
   
             
            ######################################################
            ###   BUILD FULL RES
            ###
            ###
            ######################################################
    
            #move 'dot' up in DAG

            if processFull == True:
                d = nuke.createNode('Dot', inpanel=False)
                d.setInput(0,i)
                d.setXYpos((int(i.knob('xpos').value())+160), (int(i.knob('ypos').value())+45))
                o = nuke.createNode('Write', inpanel=False)
                o.setInput(0,d)
                o.setXYpos((int(d.knob('xpos').value()-33)), (int(d.knob('ypos').value())+120))
                fullFmt = str(o.format().width()) +'x' +str(o.format().height()) 
                if formatFullVal ==('exr'):
                    o.knob('file_type').setValue('exr')
                    o.knob('channels').setValue('all')
                    o.knob('colorspace').setValue(int(i.knob('colorspace').getValue()))
                    o.knob('premultiplied').setValue(i.knob('premultiplied').value())
                    if resFolder == True:
                        o.knob('file').setValue(dirpath+pathslash +fullFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')

                    else:
                        o.knob('file').setValue(dirpath+pathslash + foldername +pathslash +fullFmt +pathslash + filename +'.' + '%0'+str(padding)+'d.exr')
                    o.knob('raw').setValue(i.knob('raw').value())
                    o.knob('stereo').setValue(False)
                elif formatFullVal ==('jpeg'):
                    o.knob('file_type').setValue('jpeg')
                    o.knob('channels').setValue('all')
                    o.knob('_jpeg_quality').setValue(0.97)
                    o.knob('file').setValue(dirpath+pathslash + foldername +pathslash +fullFmt  +pathslash + filename +'.' + '%0'+str(padding)+'d.jpg')
                o.knob('label').setValue('FULL \n Format: [value format.w]x[value format.h]')
                o.knob('disable').setExpression('!inrange(frame, '+ str(i.knob('first').value()) + ', ' + str(i.knob('last').value()) + ')',0)
                print 'FullRes output: ' +o.knob('file').getValue()
    
    
            ######################################################
            ### CREATE READ FROM OUR PROXY/FULL RASTER RENDERS
            ###
            ###
            ######################################################
            if createRead == True:
                p = nuke.createNode('Read', inpanel = False)
                print '\n#### generating ' +p.name() +'####\n'

                if processFull== True:
                    p.knob('file').setValue((o.knob('file').getValue('fileName')))
                else:
                    p.knob('file').setValue((i.knob('file').getValue('fileName')))
                print 'file path: ' +p.knob('file').getValue('fileName')

                if processProxy == True:
                    p.knob('proxy').setValue((n.knob('file').getValue('fileName')))
                    print 'proxy path: '  +p.knob('proxy').getValue('fileName')
                p.knob('first').setValue(int(i.knob('first').value()))
                p.knob('last').setValue(int(i.knob('last').value()))
                p.knob('first').setValue(int(i.knob('origfirst').value()))
                p.knob('origlast').setValue(int(i.knob('origlast').value()))
                p.setXYpos((int(i.knob('xpos').value())), (int(i.knob('ypos').value())+300))

            print '\n######## Finished ' +i.name() + ' ########\n'            

    class ProxyToolsPanel(nukescripts.PythonPanel):
        def __init__(self):
            nukescripts.PythonPanel.__init__(self, 'Proxy Tools v1.0', 'com.mybikeislost.ProxyTools')
    
            ### Create KNOBS
            self.processSelectionKnob = nuke.Enumeration_Knob('processSelection', 'Process Reads:', ['all', 'selected', 'quicktime'])
            self.processPlatesKnob = nuke.Enumeration_Knob('processPlates', 'Process Plates:', ['both', 'full', 'proxy'])
            self.createReadKnob = nuke.Boolean_Knob('create write node with our full/proxy paths from above', 'Create Read')
            self.dividerKnob = nuke.Text_Knob('div name','','')
            self.formatFullKnob = nuke.Enumeration_Knob('format', 'Full Res Format', ['exr', 'jpeg'])
            self.dividerKnob2 = nuke.Text_Knob('div name','','')
            self.formatProxyKnob = nuke.Enumeration_Knob('proxy_Format', 'Proxy Format:', ['jpeg', 'exr'])
            self.proxySizeKnob = nuke.Enumeration_Knob('proxy_Size', 'Proxy Size:', ['half', 'full', 'quarter'])
            self.dividerKnob3 = nuke.Text_Knob('div name','','')
    
            ### ADD KNOBS
            for k in ( self.processSelectionKnob, self.processPlatesKnob, self.createReadKnob, self.dividerKnob, self.formatFullKnob, self.dividerKnob2, self.formatProxyKnob, self.proxySizeKnob, self.dividerKnob3 ):
                self.addKnob( k )
    
        def showModalDialog(self):
            result = nukescripts.PythonPanel.showModalDialog(self)
            if result:
                selection = str(self.processSelectionKnob.value())

                processPlates = str(self.processPlatesKnob.value())
                createRead = self.createReadKnob.value()
                formatFullVal =str(self.formatFullKnob.value())
                formatProxyVal = self.formatProxyKnob.value()
                formatProxySizeVal = str(self.proxySizeKnob.value())


                _buildPROXIES(selection, processPlates, createRead, formatFullVal, formatProxyVal, formatProxySizeVal)
 
    def showProxyTools():
        ProxyToolsPanel().showModalDialog()
    showProxyTools()


