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.
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:
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) #create folder path to allow os.makedirs() subpath = path.split("\\C\\") newFolder = os.path.join(dest, subpath) #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.
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!