Tag Archives: python

Practical Programming

I used to do IT work, I printed some flyers and would fix computers. Fixing computers for the average home user isn’t so hard when you have the know how.

Knowing this it annoys me when I see people’s lives made difficult by what should be a service that supports and informs. When  asked to restore a backup from an external drive to a new laptop for an older friend I thought “sure this will take ten minutes”…. you see where this is going.

The IT technician had used the default backup software that comes with the hard drive. I have a dislike of these packaged software as I often think of them as “bloatware”, if I want something on a hard drive i’ll put it there. Putting that aside though I installed the software and went to the recovery options, uh oh… no backups detected.

I tried all the standard things, updating software and praying to various deities. No luck, it looked like the backup wasn’t being read due a windows permission error, or something. The software has a single task and failed I wasn’t wasting more time working out why it didn’t do the thing it was meant to.

Time to get our hands dirty and do some practical programming.

The backup files where stored in a simple .zip thats a plus. They where also in hundreds of individual .zips, that’s a minus.

With the files sitting there in zips I decided a two pronged approach could rebuild the backup.

Batch unzip

Firstly the zips needed to be taken care of, with so many zipped files a batch file was in order. I found a suitable one through the google machine:

http://serverfault.com/questions/8092/how-do-i-extract-all-archives-in-the-subdirectories-of-this-folder

FOR /D /r %%F in ("*") DO (
    pushd %CD%
    cd %%F
        FOR %%X in (*.rar *.zip) DO (
            "C:\Program Files (x86)\7-Zip\7z.exe" x "%%X"
        )
    popd
)

This gem unzips everything below the directory it runs in.

Python folder structure rebuild

With the folder unzipped the last thing was to rebuild the original folder structure.

I try not to do anything destructive in any workflow, so the goal was to rebuild the structure and copy the files into it.

For this I used python, this is a single use high end script making other options overkill.

I ran into some issues with os.listdir() throwing errors, since this is a once shot use I just threw it all into a try/catch and left it alone. It was only the odd uneeded system file that this happened for.

Throw in some recursive goodness and we have a functioning script!

import os
import shutil

dest = "D:/restore";

pathToMerge = "D:/folder/moreFolder/Backup Set yyy-mm-dd timetime";

"""
fileFinder recursively digs down to each file within a directory, building and
copying to the new one as it goes
"""
def fileFinder(path):
    if(os.path.exists(path)):
        try:
            dirList = os.listdir(path) #due to system files this can fail

            for x in range(0, len(dirList)):
                oldPath = os.path.join(path, dirList[x])
                if(os.path.isdir(oldPath)):
                    fileFinder(oldPath) #if we find a folder drill down recursively
                else:
                    #split the drive path at the correct junction
                    splObj = oldPath.split("\\C\\")

                    #create restored file path
                    newObj = os.path.join(dest, splObj[1])

                    #create folder path to allow os.makedirs()
                    subpath = path.split("\\C\\")
                    newFolder = os.path.join(dest, subpath[1])

                    #create folder if needed
                    if not os.path.exists(newFolder):
                        os.makedirs(newFolder)

                    #notify the user and copy the folder
                    #note that so many print statements can slow things down, but I link the feedback
                    print("copying file: " + newObj)
                    shutil.copy2(oldPath, newObj)

        except:
            pass
            #print("found an error, ignoring that sucka: " + path)

    else:
        print("path does not exist")

"""
drill down to the top level backup within each folder and call the file finder
"""
for basePath in os.listdir(pathToMerge):
    newPath = os.path.join(pathToMerge, basePath )
    for copyPath in os.listdir(newPath):
        if(copyPath == "C"):
            src = os.path.join(newPath, copyPath)
            #print(src)
            fileFinder(src)

And boom, rebuilt structure.

Practical programming

Being able to create these little scripts is a fantastic ability that any computer user would benefit from.

For a lot of people though this just isn’t a practical option. The importance of  decent IT technicians cannot be overstated!

Custom timeline control – Pyside – Maya 2014+

Recently a work colleague approached me with a request for a custom feature in Maya.

The request was for a custom tool that replicated the Maya timeline and it’s tools in a torn off window.

The colleague has a thing for large windows when animating, they enjoy a very custom setup.

So useful

If it’s useful to one person others may find it helpful as well

Tools that are going to be used are the best kind to make.

This is written entirely for Pyside, using a method for controlling Maya elements using pointers shown to me by Malcom.

As it’s written for pyside/Maya 2014+ you need not install anything to use it.

The timeline

As I looked a little deeper into this I came across this with the timeline:

From the Maya docs here

Note: only one timeControl may be created. The one Maya creates on startup can be accessed from the global string variable $gPlayBackSlider. Also, it is not a good idea to delete it.

So there can be only one, and yes I deleted it a few times. You do not want that, it does not come back.

So this tool rips the timeline from Maya and re parents it into the QT window, Holding a reference to the location it came from.

It then puts the timeline back on the close event of the QT window.

Range control

Creating the range control is straight forward as there can be more than one of these see here.

Other features

The tool will store the position and size of the window when the window is closed. It will then restore to this location/dimensions on next use.

There other elements are all QT.

Download

The script can be downloaded here

Installation and use

  1. Unzip and copy the to “timelineCtrl” folder to maya script folder for example:
  2. C:\Users\YourName\Documents\maya\scripts
  3. run Maya, open script editor (Python window) and type in:
  4. import timelineCtrl
  5. timelineCtrl.run()

The import and timeline control lines can also be saved off to the shelf for easy use.

And boom, tool is good to go.

Alternate use method

If you have a thing for not installing scripts you can do the following:

  1. Copy the contents of “BigTimelineWindow.py”
  2. Paste this into a python script editor window
  3. Run the code

Note: The refreshing of the states in the torn of window currently do not update as well as they could.

Tested on windows only, will note work with pre-Maya 2014 as Pyside is not part of the standard install.

Nuke scripting – let’s get ordely random

#update – here is an example of the script in effect

http://www.youtube.com/watch?v=7XP9rzx1ZTo

 

I needed a function for my upcoming Escort cinematic in Nuke, it didn’t exist out of the box (not that I found anyway).

I needed to be able to create a dynamic random character output from the text node (yay for broken robot HUD’s):

  • Random numbers/integers
  • Random characters
  • The ability to disable these at a given time/frame
  • the ability to choose how many values to display (avoid repeating the statement repeatedly)
I’ve got a background in programming (semester at UTAS) but haven’t delved into python to often, my love affair with nuke might change this.
I got my code working and now for the next step… getting nuke to load this automatically so I need not worry about pasting it in through the script editor. Easy? well yes and no, I have trouble with all the tutorial material being for Macs, but I digress.

So I’ve modified/created my init.py file (relax not the main one… the user one)

After breaking down a little I caved and watched the intro to external .py scripts here And pow, new functionality added!

 

I’m loving the ability to code straight into nuke, the amount of functionality is staggering and I am excited by the things I want to do, yeah this code is pretty simple but I get exactly the control I wanted out of it.

If I get round to doing tutorials (max/maya/nuke) I’ll definitely include a scripting component.

#sorry for the formatting being butchered.

 

import nuke
#####
#startFrame = frame to lock number
#staticInt = number to show after start frame
#digitsAmountStartdigitsAmountEnd = define the range of digits to show, allows
#big number to be shown easily
def randIntLimit(startFrame, staticInt, digitsAmountStart, digitsAmountEnd):
import random
randint = “0”
if startFrame > nuke.frame():
for i in range(digitsAmountStart, digitsAmountEnd):
randint += str(random.randrange(0,10))
else:
randint = staticInt
return randint

def randCharLimit(startFrame, staticChar, digitsAmountStart, digitsAmountEnd):
import random
ch = “”
if startFrame > nuke.frame():
for i in range(digitsAmountStart, digitsAmountEnd):
rand = random.randint(0,35)
if rand < 10:
ch += str(rand)
ch += chr(rand + 55)
else:
ch = staticChar

return ch