Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

VideoBeagle

macrumors 6502a
Original poster
Aug 17, 2010
823
18
App Q&A testing by request.
I have a huge number of data CD's (and DVDS) that I want to copy to HDD for other storage options.

I'm thinking an applescript or automater might be able to make this work better, so I can just insert the disc, it automatically copies it's contents, and it ejects the disc. I put the next CD in, rinse and repeat.

I've googled this, and found some real old posts about doing this.. one script that in theory gives the disc name for the script, but i find it doesn't work.

So my first question, is automating this a fools errand or can it be done?
2) Has someone already done this, so I don't start from scratch.

Thanks :)
 
How are you planning on copying the data? File-by-file? Disk images (ISO?)?

I did something like this a while back for magnetic tapes uber Linux and it worked OK.

B
 
How are you planning on copying the data? File-by-file? Disk images (ISO?)?
B

As files.. Like manually, I'd just drag the CD into the folder and get a folder with the CD name. (ISO just pushes the ultimate goal down the road).

I want to have all the files, organize them (tons of pdf's) and then put it on a hardrive, flash drive..blu ray..something, but getting rid of this binder of cd's :)

(I'm actually also doing a Cassette tape project, recording tapes into MP3's so I can pack the plastic up and go out of the way).
 
This Python script should do most of what you want:
Code:
import subprocess
import shutil
import errno
import time
import sys
import os
import re

DESTINATION = '/Users/me/Desktop/'

def get_volume_name(properties):
    # Searching for the device identifier (/dev/disk...)
    m = re.search('Name:\s+(/dev/disk\S*)', properties, re.MULTILINE)
    if m is None:  # If there was no Name: /dev/disk... in the properties
        print "Could not recognise a device name from drutil status"
        sys.exit(1)

    device = m.group(1)

    # Use diskutil info to get the volume name from the device identifier
    cmd = ["diskutil", "info", device]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    device_info = proc.communicate()[0]
    m = re.search('Volume Name:\s+(.*)', device_info)
    if m is None:
        print "Could not get a volume name for {} using diskutil info".format(device)
        sys.exit(1)
  
    name = m.group(1)
    return name

def copy_dir(source, dest):
    shutil.copytree(source, dest)

def media_inserted(properties):
    print "Detected inserted media..."
    name = get_volume_name(properties)
    print "Name: " + name
    path = os.path.join("/Volumes", name)
    dest = os.path.join(DESTINATION, name)
    print "Copying to {}...".format(dest)
    try:
        copy_dir(path, dest)
    except OSError as e:
        if e.errno == errno.EEXIST:
            print "A disc with name '{}' has already been imported to {}. Please resolve the conflict and restart the script.".format(name, DESTINATION)
            sys.exit(1)
    print "Copied {} to {}.".format(name, dest)
    eject_media()

def eject_media():
    cmd = ["drutil", "eject"]
    proc = subprocess.Popen(cmd)
    _ = proc.communicate()

def mainloop():
    cmd = ["drutil", "status"] # bash command returns info about inserted media
    media_was_inserted = False
    try:

        while True:   # The main loop
            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            drutil_status = proc.communicate()[0]

            media_inserted_now = ("No Media Inserted" not in drutil_status) and ("Type" in drutil_status)

            if media_inserted_now and not media_was_inserted:
                media_inserted(drutil_status)
            else:
                time.sleep(0.3)

            media_was_inserted = media_inserted_now


    except KeyboardInterrupt:  # Allow ^C to stop script
        sys.exit(0)

if __name__ == "__main__":
    mainloop()

This uses the drutil command line utility to spot when a disc has been inserted then uses diskutil to get the volume name and copies it to the destination defined at the top of the file. Automatically ejects and waits for the next disc. You may need to tweak bits of it as I've only checked that it gets as far as starting copying correctly.

Usage: python cd.py
 
This Python script […] uses the drutil command line utility to spot when a disc has been inserted then uses diskutil to get the volume name

diskutil will not give you the volume name consistently (“Volume Name: Not applicable (no file system)”), but df will. See this answer at Stack Overflow using drutil + df to get the path to each of the mount points of volumes in inserted optical media. And there’s that: “volumes”, in plural, because multisession CDs might contain more than one.

It would be nice if someone integrated the answer at Stack Overflow with this python script.
 
Another key issue to consider is that 0d085d’s python script above uses shutil.copytree for copying. shutil docs state:

On POSIX platforms […] file owner and group are lost as well as ACLs. On Mac OS, the resource fork and other metadata are not used. This means that resources will be lost and file type and creator codes will not be correct.​

which makes it an inappropriate choice for the task. It would probably be better if it used the command ditto, which (by default) does preserve all of those and more. If using an external command, the script should then also take into account its exit code in order to handle cases in which parts of the disc were not readable or whatever.

Again, I do not have the skills to incorporate that change into the script myself, though, so it would be nice if somebody else did that.
 
Now there's a data medium I haven't heard mentioned since... um.. Star Trek reruns.
you do realise most of industry still uses tape for daily backups since it is superior to other methods...it is a shame consumer level tape options disappeared.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.