On Sun, Jun 6, 2010 at 10:08 PM, Robert G. (Doc) Savage <dsavage@xxxxxxxxxxx> wrote: > I wrote to the maintainer (James) and received the following reply: Great minds think alike. I did the same and got pretty much the same response. I've forwarded him my updates but I'll attach it here one more time. Some things I've added/fixed: - Fixed DVD +R capacity (had an extra *2 in it) - Got subprocess.Popen working - Added a very basic usage (--help) output. - Switched from a more procedural approach to capturing the main portion of the program in a def Main() call and if __name__ == '__main__': which should make it easier to wrap a gui around it. - Starting from disc other than #1. I hit enter too early on a backup and it exited and I didn't want to burn the first two discs over. - Got basic command parsing implemented. Some things I was going to work on: - assignable disc volume name by command line argument. Richard
#! /usr/bin/python import os, sys, os.path, math, tempfile, dbus, readline, getopt from subprocess import * def main(): # Parse arguments try: opts, args = getopt.getopt(sys.argv[1:], 'hts:', ['help', 'test', 'disc-skip=']) except getopt.GetoptError, err: # print help information and exit: print str(err) # will print something like "option -a not recognized" usage() sys.exit(2) disc_skip = 0 for opt, value in opts: if opt in ('-s', '--disc-skip'): disc_skip = value elif opt in ('-t', '--test'): test = True elif opt in ('-h', '--help'): usage() sys.exit(0) else: print "\nBad option: %s" % opt usage() sys.exit(0) try: while True: try: dir = raw_input('Which directory would you like to backup?\n') if os.path.isdir(dir): dir = os.path.abspath(dir) + '/' # Add trailing slash here instead of later. break else: print "You must enter a valid directory." continue except: raise input = raw_input("\nPlease put a blank DVD in your drive so I can attempt to autodetect the device name and press Enter\n") drives = discover() if len(drives) == 1: statement = '\nUsing %s (%s) as your dvd burner, if this is wrong enter a valid one or press Enter to continue\n' % (drives.keys()[0], drives[drives.keys()[0]][1]) elif len(drives) > 1: statement ='\nFound these capable dvd burners %s, enter one\n' % " ".join(drives).keys() else: statement ='\nNo dvd burner(s) found. You may attempt to manually enter a device name\n' drive_input=raw_input(statement) if drive_input == "" and len(drives) ==1: drive = drives.keys()[0] else: drive = drive_input total_size = 0 disc_capacity = int(drives[drive][0]) print "The disc capacity of the disc in %s (%s) is %s GB" % (drive, drives[drive][1], str(disc_capacity / 1073741824.0) ) speed = raw_input("\nEnter the speed which your drive and media support and press Enter\n") file_list = [] for path, dirs, files in os.walk(dir): for filename in files: file_list.append(os.path.join(path, filename)) print os.path.join(path, filename) file_list.sort() for file in file_list: if not os.path.islink(file): size = os.path.getsize(file) total_size = total_size + size if size >= disc_capacity: print "%s is larger than the capacity of the disc. I can not span large files across discs." sys.exit(1) num_discs = int( math.ceil (total_size / disc_capacity) ) (discs) = build_list(file_list, disc_capacity) print "\nNumber of %s's required to burn: %s" % ("dvd", len(discs)) file_count = 0 for disc in discs: file_count = file_count + len(disc) print "\nSanity Check\n" print "Total files in directory", len(file_list) print "Total files in all discs: ", file_count disc_num = 1 # Really ugly way of skipping to a disc. if disc_skip > 0: print "Skipping to disc", disc_skip for disc in range(disc_skip-1): del discs[0] for disc in discs: burn(disc,dir, drive, speed, disc_num, len(discs)) disc_num = disc_num + 1 except KeyboardInterrupt: print "\nUser Interrupted.\n" sys.exit(1) except: raise def usage(): print """ Usage: discspan.py [OPTIONS] Options: -h, --help This help. -s, --disc-skip=<num> Skip to a particular disk to burn. -t, --test Run but don't actually burn to disc.""" def discover(): # get a connection to the system bus drives = [] discs = { 'dvd_r' : 4.38 * 1024 * 1024 * 1024, 'dvd_rw' : 4.38 * 1024 * 1024 * 1024, 'dvd_plus_r' : 4.37 * 1024 * 1024 * 1024, 'dvd_plus_rw' : 4.37 * 1024 * 1024 * 1024, 'dvd_plus_r_dl': 4.37 * 2 * 1024 * 1024 * 1024, 'dvd_plus_rw_dl': 4.37 * 2 * 1024 * 1024 * 1024, # bd_re If someone can test this with these new formats, # hddvd_rw let me know! I need values for their capacity # bd_r # hddvd_r } bus = dbus.SystemBus () hal_obj = bus.get_object ('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager') hal = dbus.Interface (hal_obj, 'org.freedesktop.Hal.Manager') udis = hal.FindDeviceByCapability ('volume') drives = {} for udi in udis: dev_obj = bus.get_object ('org.freedesktop.Hal', udi) dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device') parent_obj = bus.get_object ('org.freedesktop.Hal', dev.GetProperty("info.parent")) parent = dbus.Interface (parent_obj, 'org.freedesktop.Hal.Device') if parent.GetProperty ('storage.hotpluggable') or 'storage.cdrom' in parent.GetProperty('info.capabilities'): try: if dev.GetProperty('volume.disc.type') in discs.keys(): device_name = dev.GetProperty ('block.device') capacity = discs[dev.GetProperty('volume.disc.type')] print capacity drive_name = parent.GetProperty('info.product') drives[device_name] = [capacity, drive_name] print "Found a %s in %s (%s)" % (dev.GetProperty('volume.disc.type'), device_name, drive_name ) except: continue else: continue return drives def RunCmd(command): print "Running command : %s" % command app = Popen(command, bufsize=0, shell=True, close_fds=True, stdout=PIPE, stderr=STDOUT) output= [] while app.poll() == None: # Had to change from -1 or it never branched. while 1: try: line = app.stdout.readline().rstrip("\n") sys.stdout.flush() # Not sure if this is necessary but doesn't seem to hurt. except: pass if not line: break output.append(line) print line if app.poll() > 0 : print "There was an error running %s." % command sys.exit(1) return output def build_list(files, dvd_capacity): file_count = 1 disc_size = 0 disc_list = [] disc_files = [] outfiles = [] for file in files: if not os.path.islink(file): size = os.path.getsize(file) disc_size = disc_size + size else: size = 0 if disc_size >= dvd_capacity: disc_list.append(disc_files) disc_size = 0 disc_size = disc_size + size disc_files = [] disc_files.append(file) else: disc_files.append(file) disc_list.append(disc_files) return (disc_list) def burn(disc, dir, drive, speed, disc_num, total_disc): if disc_num ==1: msg = "\nReady to burn disc %s/%s. Press Enter" % (disc_num, total_disc ) else: msg = "\nInsert Empty Disc %s/%s and Press Enter\n" % (disc_num, total_disc ) input=raw_input(msg) list = "" for file in disc: file_on_disc = file.replace(dir, "") list = list + "%s=%s\n" % (file_on_disc, file) fd, temp_list = tempfile.mkstemp(suffix=".discspanlist") output = open(temp_list, 'w') output.write(list) output.close() burn_cmd = "growisofs -Z %s -speed=%s -use-the-force-luke=notray" \ " -use-the-force-luke=tty -gui" \ " -V DiscSpanData -A DiscSpan -p Unknown -iso-level 3" \ " -l -r -hide-rr-moved -J -joliet-long" \ " -graft-points --path-list %s" %(drive, speed, temp_list) if test == True: burn_cmd.append(' -use-the-force-luke=dummy') RunCmd(burn_cmd) os.unlink(temp_list) RunCmd("eject") if __name__ == "__main__": sys.exit(main())
-- users mailing list users@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe or change subscription options: https://admin.fedoraproject.org/mailman/listinfo/users Guidelines: http://fedoraproject.org/wiki/Mailing_list_guidelines