Example #1
0
def get_disks_list():
    '''
    This method is used by the BurnerGUI when the user clicks the ComboBox.

    It grabs all disk ids and then for every disk we get the name and size.
    Sizes will be converted to GB (not GiB).

    NOTE: We do no return all disks that are found!

    Example:
        disk id: /dev/rdisk2
        disk name: APPLE SD Card Reader USB
        disk size: 16.03
    '''

    disks = list()

    for disk_id in get_disk_ids():

        # change disk to raw to increase performance
        disk_id = disk_id[:5] + 'r' + disk_id[5:]

        # get the disk manufacturer and size in GB
        disk_name, disk_size = get_disk_name_size(disk_id)

        disk = {'id': disk_id, 'name': disk_name, 'size': disk_size}

        # make sure we do not list any potential hard drive or too small SD card
        if disk['size'] < 3.5 or disk['size'] > 16.5:  # GB
            debugger('Ignoring {}'.format(disk))
        else:
            debugger('Listing {}'.format(disk))
            disks.append(disk)

    return disks
Example #2
0
def get_disk_mount(disk_id):
    TEMP_DIR = 'C:\\temp\\kano-burner\\'
    disk_mount = ''   # mount point e.g. C:\ or D:\

    # extract the id of the physical disk, required by diskpart
    # e.g. \\?\Device\Harddisk[id]\Partition0
    id = int(disk_id.split("Harddisk")[1][0])  # access by string index alone is dangerous!

    # create a diskpart script to find the mount point for the given disk
    diskpart_detail_script = 'select disk {} \ndetail disk'.format(id)
    write_file_contents(TEMP_DIR + "detail_disk.txt", diskpart_detail_script)

    # run the created diskpart script
    cmd = 'diskpart /s {}'.format(TEMP_DIR + "detail_disk.txt")
    output, error, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('Ran diskpart detail script')
    else:
        debugger('[ERROR] ' + error.strip('\n'))
        return

    # now the mount point is the third word on the last line of the output
    disk_mount = output.splitlines()[-1].split()[2]

    return disk_mount
Example #3
0
def get_disks_list():
    '''
    This method is used by the BurnerGUI when the user clicks the ComboBox.

    It grabs all disk ids, disk names, and disk sizes separately and then
    matches them by index. Sizes will be converted to GB (not GiB).

    NOTE: We do no return all disks that are found!

    Example:
        disk id: /dev/sda
        disk name: Sandisk Ultra USB
        disk size: 16.03
    '''

    disks = list()

    for disk_id in get_disk_ids():

        # get the disk manufacturer and size in GB
        disk_name, disk_size = get_disk_name_size(disk_id)

        disk = {'id': disk_id, 'name': disk_name, 'size': disk_size}

        # make sure we do not list any potential hard drive or too small SD card
        if disk['size'] < 3.5 or disk['size'] > 16.5:  # GB
            debugger('Ignoring {}'.format(disk))
        else:
            debugger('Listing {}'.format(disk))
            disks.append(disk)

    return disks
Example #4
0
def close_all_explorer_windows():
    cmd = '{}\\nircmd.exe win close class "CabinetWClass"'.format(_nircmd_path)
    _, error, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('Closed all Explorer windows')
    else:
        debugger('[ERROR]: ' + error.strip('\n'))
Example #5
0
def unmount_disk(disk_mount):
    cmd = "mountvol {}:\\ /D".format(disk_mount)
    error, _, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('{}:\\ successfully unmounted'.format(disk_mount))
    else:
        debugger('[ERROR]: ' + error.strip('\n'))
Example #6
0
def test_write(disk_mount):
    cmd = '{}\\dd.exe if=/dev/random of=\\\\.\\{}: bs=4M count=10'.format(_dd_path, disk_mount)
    _, output, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('Written 40M random data to {}:\\'.format(disk_mount))
    else:
        debugger('[ERROR]: ' + output.strip('\n'))
Example #7
0
def format_disk(disk_id):
    cmd = 'diskutil eraseDisk fat32 UNTITLED {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully erased and formatted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #8
0
def unmount_disk(disk_id):
    cmd = 'diskutil unmountDisk {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully unmounted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #9
0
def unzip_kano_os(os_path, dest_path):
    cmd = '"{}\\7za.exe" e "{}" -o"{}"'.format(_7zip_path, os_path, dest_path)
    _, output, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('Unzipped Kano OS successfully')
    else:
        debugger('[ERROR]: ' + output.strip('\n'))
Example #10
0
def close_all_explorer_windows():
    cmd = '{}\\nircmd.exe win close class "CabinetWClass"'.format(_nircmd_path)
    _, error, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('Closed all Explorer windows')
    else:
        debugger('[ERROR]: ' + error.strip('\n'))
Example #11
0
def format_disk(disk_id):
    cmd = 'mkdosfs -I -F 32 -v {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully erased and formatted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #12
0
def format_disk(disk_id):
    cmd = 'mkdosfs -I -F 32 -v {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully erased and formatted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #13
0
def get_disk_ids():
    cmd = "diskutil list | grep '/dev/'"
    output, error, return_code = run_cmd(cmd)

    if not return_code:
        return output.split()
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #14
0
def unmount_disk(disk_id):
    cmd = 'diskutil unmountDisk {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully unmounted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #15
0
def format_disk(disk_id):
    cmd = 'diskutil eraseDisk fat32 UNTITLED {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully erased and formatted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #16
0
def get_disk_ids():
    cmd = "diskutil list | grep '/dev/'"
    output, error, return_code = run_cmd(cmd)

    if not return_code:
        return output.split()
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #17
0
def is_installed(programs_list):
    cmd = 'which {}'.format(' '.join(programs_list))
    output, error, return_code = run_cmd(cmd)

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))
        return True  # if something goes wrong here, it shouldn't be catastrophic

    return len(output.split()) == len(programs_list)
Example #18
0
def unmount_disk(disk_id):
    cmd = 'diskutil unmountDisk {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully unmounted'.format(disk_id))
    else:
        debugger('[ERROR: {}] {}'.format(cmd,  error.strip('\n')))
        raise disk_error(UNMOUNT_ERROR)
Example #19
0
def is_installed(programs_list):
    cmd = 'which {}'.format(' '.join(programs_list))
    output, error, return_code = run_cmd(cmd)

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))
        return True  # if something goes wrong here, it shouldn't be catastrophic

    return len(output.split()) == len(programs_list)
Example #20
0
def unmount_disk(disk_id):
    cmd = 'diskutil unmountDisk {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully unmounted'.format(disk_id))
    else:
        debugger('[ERROR: {}] {}'.format(cmd, error.strip('\n')))
        raise disk_error(UNMOUNT_ERROR)
Example #21
0
 def getAriaStatus(self):
     self.process.poll()
     if not self.process.returncode:
         try:
             self.ariaStatus = self.server.aria2.tellStatus('token:'+self.secret, self.gid)
             if not isinstance(self.ariaStatus, dict):
                 self.ariaStatus = {}
         except Exception as e:
             self.failed = True
             self.failure = e
             debugger('status call error {}'.format(e))
Example #22
0
def unmount_disk(disk_id):
    # to unmount an entire disk, we first need to unmount all it's volumes
    unmount_volumes(disk_id)

    # now we can safely unmount the disk
    cmd = 'umount {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)
    if not return_code:
        debugger('disk {} successfully unmounted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #23
0
def unmount_disk(disk_id):
    # to unmount an entire disk, we first need to unmount all it's volumes
    unmount_volumes(disk_id)

    # now we can safely unmount the disk
    cmd = 'umount {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)
    if not return_code:
        debugger('disk {} successfully unmounted'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #24
0
 def getAriaStatus(self):
     self.process.poll()
     if not self.process.returncode:
         try:
             self.ariaStatus = self.server.aria2.tellStatus(
                 'token:' + self.secret, self.gid)
             if not isinstance(self.ariaStatus, dict):
                 self.ariaStatus = {}
         except Exception as e:
             self.failed = True
             self.failure = e
             debugger('status call error {}'.format(e))
Example #25
0
def is_sufficient_space(required_mb):
    cmd = "df %s | grep -v 'Available' | awk '{print $4}'" % temp_path
    output, _, _ = run_cmd(cmd)

    try:
        free_space_mb = float(output.strip()) * 512 / BYTES_IN_MEGABYTE
    except:
        debugger('[ERROR] Failed parsing the line ' + output)
        return True

    debugger('Free space {0:.2f} MB in {1}'.format(free_space_mb, temp_path))
    return free_space_mb > required_mb
Example #26
0
def mount_disk(disk_id):
    # the following may not work if the disk has been unmounted, consider caching
    disk_mount = get_disk_mount(disk_id)
    disk_volume = get_disk_volume(disk_id, disk_mount)

    cmd = "mountvol {}:\\ {}".format(disk_mount, disk_volume)
    _, error, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('{} successfully mounted'.format(disk_mount))
    else:
        debugger('[ERROR]: ' + error.strip('\n'))
Example #27
0
def is_sufficient_space(path, required_mb):
    cmd = "df %s | grep -v 'Available' | awk '{print $4}'" % path
    output, _, _ = run_cmd(cmd)

    try:
        free_space_mb = float(output.strip()) * 512 / BYTES_IN_MEGABYTE
    except:
        debugger('[ERROR] Failed parsing the line ' + output)
        return True

    debugger('Free space {0:.2f} MB in {1}'.format(free_space_mb, path))
    return free_space_mb > required_mb
Example #28
0
def get_disk_ids():
    cmd = "parted --list | grep 'Disk /dev/.*:' | awk '{print $2}'"
    output, error, return_code = run_cmd(cmd)

    disk_ids = []
    for id in output.splitlines():
        disk_ids.append(id[:-1])

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    return disk_ids
Example #29
0
def get_disk_ids():
    cmd = "parted --list | grep 'Disk /dev/.*:' | awk '{print $2}'"
    output, error, return_code = run_cmd(cmd)

    disk_ids = []
    for id in output.splitlines():
        disk_ids.append(id[:-1])

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    return disk_ids
Example #30
0
def get_disk_names():
    cmd = "parted --list | grep 'Model:'"
    output, error, return_code = run_cmd(cmd)

    disk_names = []
    for name in output.splitlines():
        disk_names.append(' '.join(name.split()[1:-1]))

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    # grab the first line of the output and the name is from the 4th word onwards
    return disk_names
Example #31
0
def eject_disk(disk_id):
    '''
    This method is used by the backendThread to ensure safe removal
    after burning finished successfully.
    '''

    cmd = 'diskutil eject {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully ejected'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #32
0
def eject_disk(disk_id):
    '''
    This method is used by the backendThread to ensure safe removal
    after burning finished successfully.
    '''

    cmd = 'eject {}'.format(disk_id)
    _, error, return_code = run_cmd(cmd)

    if not return_code:
        debugger('{} successfully ejected'.format(disk_id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #33
0
    def isFinished(self):
        self.process.poll()
        if self.process.returncode:
            debugger('aria returned {}'.format(self.status.returncode))
            return True  # aria finished; since it's not supposed to until we tell it, it probably died
        if self.failed:
            debugger('aria failed {}'.format(self.failure))
            return True

        self.getAriaStatus()
        result = self.ariaStatus['status']
        finished = result != 'active' and result != 'waiting'
        return finished
Example #34
0
    def isFinished(self):
        self.process.poll()
        if self.process.returncode:
            debugger('aria returned {}'.format(self.status.returncode))
            return True  # aria finished; since it's not supposed to until we tell it, it probably died
        if self.failed:
            debugger('aria failed {}'.format(self.failure))
            return True

        self.getAriaStatus()
        result = self.ariaStatus['status']
        finished = result != 'active' and result != 'waiting'
        return finished
Example #35
0
def get_disk_names():
    cmd = "parted --list | grep 'Model:'"
    output, error, return_code = run_cmd(cmd)

    disk_names = []
    for name in output.splitlines():
        disk_names.append(' '.join(name.split()[1:-1]))

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    # grab the first line of the output and the name is from the 4th word onwards
    return disk_names
Example #36
0
def get_disk_sizes():
    cmd = "fdisk -l | grep 'Disk /dev/'"
    output, error, return_code = run_cmd(cmd)

    disk_sizes = []
    for line in sorted(output.splitlines()):
        size = line.split()[4]
        disk_sizes.append(float(size) / BYTES_IN_GIGABYTE)

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    return disk_sizes
Example #37
0
def get_disk_sizes():
    cmd = "fdisk -l | grep 'Disk /dev/'"
    output, error, return_code = run_cmd(cmd)

    disk_sizes = []
    for line in sorted(output.splitlines()):
        size = line.split()[4]
        disk_sizes.append(float(size) / BYTES_IN_GIGABYTE)

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    return disk_sizes
Example #38
0
def unmount_volumes(disk_id):
    # all volumes on a disk have an index attached e.g. /dev/sdb1, /dev/sdb2
    cmd = "fdisk -l | grep '%s[0-9][0-9]*' | awk '{print $1}'" % disk_id
    output, _, _ = run_cmd(cmd)

    # it may also happen that the disk does not have volumes
    # in which case the loop below won't do anything
    for volume in output.splitlines():
        cmd = 'umount {}'.format(volume)
        _, error, return_code = run_cmd(cmd)
        if not return_code:
            debugger('volume {} successfully unmounted'.format(volume))
        else:
            debugger('[ERROR] ' + error.strip('\n'))
Example #39
0
def is_installed(programs_list):
    cmd = 'where.exe {}'.format(' '.join(programs_list))
    output, error, return_code = run_cmd_no_pipe(cmd)

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))
        return True  # if something goes wrong here, it shouldn't be catastrophic

    programs_found = 0
    for line in output.splitlines():
        if line and 'not find' not in line:
            programs_found += 1

    return programs_found == len(programs_list)
Example #40
0
def unmount_volumes(disk_id):
    # all volumes on a disk have an index attached e.g. /dev/sdb1, /dev/sdb2
    cmd = "fdisk -l | grep '%s[0-9][0-9]*' | awk '{print $1}'" % disk_id
    output, _, _ = run_cmd(cmd)

    # it may also happen that the disk does not have volumes
    # in which case the loop below won't do anything
    for volume in output.splitlines():
        cmd = 'umount {}'.format(volume)
        _, error, return_code = run_cmd(cmd)
        if not return_code:
            debugger('volume {} successfully unmounted'.format(volume))
        else:
            debugger('[ERROR] ' + error.strip('\n'))
Example #41
0
def poll_burning_thread(thread):
    time.sleep(1)  # wait for dd to start
    debugger('Polling burner for progress..')
    cmd = 'kill -INFO `pgrep ^dd`'

    # as long as the burning thread is running, send SIGINFO
    # to dd to trigger progress output
    while thread.is_alive():
        _, error, return_code = run_cmd(cmd)
        if return_code:
            debugger('[ERROR] Sending signal to burning thread failed')
            return False
        time.sleep(0.3)
    return True
Example #42
0
def get_latest_os_info():
    debugger("Downloading latest OS information")

    # we put everything in a try block as urlopen raises URLError
    try:
        # get latest.json from download.kano.me
        response = urllib2.urlopen(LATEST_OS_INFO_URL)
        latest_json = json.load(response)
        latest_json['filename'] += '.gz'  # the .gz will be used on all OSs

        # give the server some time to breathe between requests
        debugger('Latest Kano OS image is {}'.format(latest_json['filename']))
        time.sleep(1)

        # use the url for the latest os version to get info about the image
        latest_image_json = '{base_url}{filename}.json'.format(
            base_url=latest_json['base_url'], filename=latest_json['filename'])

        debugger('Latest Kano OS image json is {}'.format(latest_image_json))
        response = urllib2.urlopen(latest_image_json)
        os_json = json.load(response)

        # give the server some time to breathe between requests
        time.sleep(1)

    except:
        debugger('[ERROR] Downloading OS info failed')
        return None

    # merge the two jsons, add derived values and return a single info dict
    os_info = dict(latest_json.items() + os_json.items())
    return os_info
Example #43
0
def poll_burning_thread(thread):
    time.sleep(1)  # wait for dd to start
    debugger('Polling burner for progress..')
    cmd = 'kill -INFO `pgrep ^dd`'

    # as long as the burning thread is running, send SIGINFO
    # to dd to trigger progress output
    while thread.is_alive():
        _, error, return_code = run_cmd(cmd)
        if return_code:
            debugger('[ERROR] Sending signal to burning thread failed')
            return False
        time.sleep(0.3)
    return True
Example #44
0
def is_sufficient_space(required_mb):
    cmd = "dir {}".format(temp_path)
    output, _, _ = run_cmd_no_pipe(cmd)

    try:
        # grab the last line from the output
        free_space_line = output.splitlines()[-1]

        # grab the number in bytes, remove comma delimiters, and convert to MB
        free_space_mb = float(free_space_line.split()[2].replace(',', '')) / BYTES_IN_MEGABYTE
    except:
        debugger('[ERROR] Failed parsing the line ' + output)
        return True

    debugger('Free space {0:.2f} MB in {1}'.format(free_space_mb, temp_path))
    return free_space_mb > required_mb
Example #45
0
def get_disks_list():
    '''
    This method is used by the BurnerGUI when the user clicks the ComboBox.

    It grabs all disk ids, disk names, and disk sizes separately and then
    matches them by index. Sizes will be converted to GB (not GiB).

    NOTE: We do no return all disks that are found!

    Example:
        disk id: /dev/sda
        disk name: Sandisk Ultra USB
        disk size: 16.03
    '''

    disks = list()

    disk_ids = get_disk_ids()
    disk_names = get_disk_names()
    disk_sizes = get_disk_sizes()

    # check for parsing errors
    if len(disk_ids) != len(disk_names) or len(disk_names) != len(disk_sizes):
        return disks

    for index in range(0, len(disk_ids)):

        # append all data here, this would need changing if logic changes
        disk = {
            'id': disk_ids[index],
            'name': disk_names[index],
            'size': disk_sizes[index]
        }

        # make sure we do not list any potential hard drive or too small SD card
        if disk['size'] < 3.5 or disk['size'] > 64:  # GB
            debugger('Ignoring {}'.format(disk))
        else:
            debugger('Listing {}'.format(disk))
            disks.append(disk)

    return disks
Example #46
0
def get_disks_list():
    '''
    This method is used by the BurnerGUI when the user clicks the ComboBox.

    It grabs all disk ids, disk names, and disk sizes separately and then
    matches them by index. Sizes will be converted to GB (not GiB).

    NOTE: We do no return all disks that are found!

    Example:
        disk id: /dev/sda
        disk name: Sandisk Ultra USB
        disk size: 16.03
    '''

    disks = list()

    disk_ids = get_disk_ids()
    disk_names = get_disk_names()
    disk_sizes = get_disk_sizes()

    # check for parsing errors
    if len(disk_ids) != len(disk_names) or len(disk_names) != len(disk_sizes):
        return disks

    for index in range(0, len(disk_ids)):

        # append all data here, this would need changing if logic changes
        disk = {
            'id': disk_ids[index],
            'name': disk_names[index],
            'size': disk_sizes[index]
        }

        # make sure we do not list any potential hard drive or too small SD card
        if disk['size'] < 3.5 or disk['size'] > 64:  # GB
            debugger('Ignoring {}'.format(disk))
        else:
            debugger('Listing {}'.format(disk))
            disks.append(disk)

    return disks
Example #47
0
def get_disk_name_size(disk_id):
    cmd = "parted {} unit B print".format(disk_id)
    output, error, return_code = run_cmd(cmd)

    disk_name = ''
    disk_size = 0

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    for line in output.splitlines():
        if 'Model:' in line:
            disk_name = ' '.join(line.split()[1:])
        if 'Disk {}:'.format(disk_id) in line:
            disk_size = float(line[:-1].split()[2]) / BYTES_IN_GIGABYTE

    if not disk_name or not disk_size:
        debugger('[ERROR] Parsing disk name and size failed')

    return disk_name, disk_size
Example #48
0
def format_disk(disk_id):
    # TODO: look into cmd = 'format {}: /Q /X'.format(disk_mount)
    TEMP_DIR = 'C:\\temp\\kano-burner\\'

    # extract the id of the physical disk, required by diskpart
    # e.g. \\?\Device\Harddisk[id]\Partition0
    id = int(disk_id.split("Harddisk")[1][0])  # access by string index alone is dangerous!

    # create a diskpart script to format the given disk
    diskpart_format_script = 'select disk {} \nclean'.format(id)
    write_file_contents(TEMP_DIR + "format_disk.txt", diskpart_format_script)

    # run the created diskpart script
    cmd = 'diskpart /s {}'.format(TEMP_DIR + "format_disk.txt")
    _, error, return_code = run_cmd_no_pipe(cmd)

    if not return_code:
        debugger('Formatted disk {} with diskpart'.format(id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
Example #49
0
def get_disk_name_size(disk_id):
    cmd = "diskutil info {}".format(disk_id)
    output, error, return_code = run_cmd(cmd)

    disk_name = ''
    disk_size = 0

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    for line in output.splitlines():
        if 'Device / Media Name:' in line:
            disk_name = ' '.join(line.split()[4:])
        if 'Total Size:' in line:
            disk_size = float(line.split()[4][1:]) / BYTES_IN_GIGABYTE

    if not disk_name or not disk_size:
        debugger('[ERROR] Parsing disk name and size failed')

    return disk_name, disk_size
Example #50
0
def get_disk_name_size(disk_id):
    cmd = "diskutil info {}".format(disk_id)
    output, error, return_code = run_cmd(cmd)

    disk_name = ''
    disk_size = 0

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    for line in output.splitlines():
        if 'Device / Media Name:' in line:
            disk_name = ' '.join(line.split()[4:])
        if 'Total Size:' in line:
            disk_size = float(line.split()[4][1:]) / BYTES_IN_GIGABYTE

    if not disk_name or not disk_size:
        debugger('[ERROR] Parsing disk name and size failed')

    return disk_name, disk_size
Example #51
0
def get_disk_name_size(disk_id):
    cmd = "parted {} unit B print".format(disk_id)
    output, error, return_code = run_cmd(cmd)

    disk_name = ''
    disk_size = 0

    if return_code:
        debugger('[ERROR] ' + error.strip('\n'))

    for line in output.splitlines():
        if 'Model:' in line:
            disk_name = ' '.join(line.split()[1:])
        if 'Disk {}:'.format(disk_id) in line:
            disk_size = float(line[:-1].split()[2]) / BYTES_IN_GIGABYTE

    if not disk_name or not disk_size:
        debugger('[ERROR] Parsing disk name and size failed')

    return disk_name, disk_size
Example #52
0
def get_latest_os_info():
    debugger("Downloading latest OS information")

    # we put everything in a try block as urlopen raises URLError
    try:
        # get latest.json from download.kano.me
        response = urllib2.urlopen(LATEST_OS_INFO_URL)
        latest_json = json.load(response)

        # give the server some time to breathe between requests
        debugger('Latest Kano OS image is {}'.format(latest_json['filename']))
        time.sleep(1)

        # use the url for the latest os version to get info about the image
        response = urllib2.urlopen(latest_json['url'] + '.json')
        os_json = json.load(response)

        # give the server some time to breathe between requests
        time.sleep(1)

    except:
        debugger('[ERROR] Downloading OS info failed')
        return None

    # merge the two jsons and return a single info dict result
    os_info = {key: value for (key, value) in (latest_json.items() + os_json.items())}
    return os_info
Example #53
0
def burn_kano_os(path, disk, size, return_queue, report_progress_ui):
    cmd = 'gzip -dc {} | dd of={} bs=4M'.format(path, disk)
    process = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)

    failed = False
    unparsed_line = ''

    # as long as Popen is running, read it's stderr line by line
    # each time a USR1 signal is sent to dd, it outputs 3 lines
    # and we are only interested in the last one i.e. 'x bytes written in y seconds'
    for line in iter(process.stderr.readline, ''):
        if 'bytes' in line:
            try:
                parts = line.split()

                written_bytes = float(parts[0])
                progress = int(written_bytes / size * 100)

                speed = float(parts[7])

                eta = calculate_eta(written_bytes, size,
                                    speed * BYTES_IN_MEGABYTE)

                report_progress_ui(
                    progress,
                    'speed {0:.2f} MB/s  eta {1:s}  completed {2:d}%'.format(
                        speed, eta, progress))
            except:
                unparsed_line = line

        # watch out for an error output from dd
        if 'error' in line.lower() or 'invalid' in line.lower():
            debugger('[ERROR] ' + line)
            failed = True

    # make sure the progress bar is filled and show an appropriate message
    # if we failed, the UI will immediately show the error screen
    report_progress_ui(100, 'burning finished successfully')

    # making sure we log anything nasty that has happened
    if unparsed_line:
        debugger('[ERROR] Failed parsing the line: ' + unparsed_line)

    if failed:
        debugger('[ERROR] Burning Kano image failed')
        return_queue.put(False)
    else:
        debugger('Burning successfully finished')
        return_queue.put(True)
Example #54
0
def format_disk(disk_id):
    # TODO: look into cmd = 'format {}: /Q /X'.format(disk_mount)

    # extract the id of the physical disk, required by diskpart
    # e.g. \\?\Device\Harddisk[id]\Partition0
    id = int(disk_id['id_num'])  # access by string index alone is dangerous!

    # create a diskpart script to format the given disk
    diskpart_format_script = 'select disk {} \nclean'.format(id)
    diskpart_script_path = os.path.join(temp_path, "format_disk.txt")
    write_file_contents(diskpart_format_script, diskpart_script_path)

    # run the created diskpart script
    cmd = 'diskpart /s {}'.format(diskpart_script_path)
    _, error, return_code = run_cmd_no_pipe(cmd)
    time.sleep(15)  # diskpart requires a timeout between calls

    if not return_code:
        debugger('Formatted disk {} with diskpart'.format(id))
    else:
        debugger('[ERROR] ' + error.strip('\n'))
        raise disk_error(FORMAT_ERROR)
Example #55
0
def get_disks_list():
    '''
    This method is used by the BurnerGUI when the user clicks the ComboBox.

    It grabs all disk ids and then for every disk we get the name and size.
    Sizes will be converted to GB (not GiB).

    NOTE: We do no return all disks that are found!

    Example:
        disk id: /dev/rdisk2
        disk name: APPLE SD Card Reader USB
        disk size: 16.03
    '''

    disks = list()

    for disk_id in get_disk_ids():

        # change disk to raw to increase performance
        disk_id = disk_id[:5] + 'r' + disk_id[5:]

        # get the disk manufacturer and size in GB
        disk_name, disk_size = get_disk_name_size(disk_id)

        disk = {
            'id': disk_id,
            'name': disk_name,
            'size': disk_size
        }

        # make sure we do not list any potential hard drive or too small SD card
        if disk['size'] < 3.5 or disk['size'] > 64:  # GB
            debugger('Ignoring {}'.format(disk))
        else:
            debugger('Listing {}'.format(disk))
            disks.append(disk)

    return disks
Example #56
0
def get_latest_os_info():
    debugger("Downloading latest OS information")

    # we put everything in a try block as urlopen raises URLError
    try:
        # get latest.json from download.kano.me
        response = urllib2.urlopen(LATEST_OS_INFO_URL)
        latest_json = json.load(response)

        # the .gz archive will be used on all OSs
        latest_json['archive'] = latest_json['filename'] + '.gz'

        # give the server some time to breathe between requests
        debugger('Latest Kano OS image is {}'.format(latest_json['filename']))
        time.sleep(1)

        # use the url for the latest os version to get info about the image
        latest_image_json = '{base_url}{filename}.json'.format(
            base_url=latest_json['base_url'],
            filename=latest_json['filename'])

        # aria2 supports more url types, allow option to use these without failing
        # backward compatibility with older burners
        if 'url.v2' in latest_json:
            latest_json['url'] = latest_json['url.v2']

        debugger('Latest Kano OS image json is {}'.format(latest_image_json))
        response = urllib2.urlopen(latest_image_json)
        os_json = json.load(response)

        # give the server some time to breathe between requests
        time.sleep(1)

    except:
        debugger('[ERROR] Downloading OS info failed')
        return None

    # merge the two jsons, add derived values and return a single info dict
    os_info = dict(latest_json.items() + os_json.items())
    return os_info
Example #57
0
    def isSuccessful(self):
        if self.failed:
            return False
        self.getAriaStatus()
        debugger('Final aria status {}'.format(self.ariaStatus))

        # Fixme: check codes present in dict
        # Fixme: check for hash failed code

        if self.ariaStatus['status'] != 'complete' or int(
                self.ariaStatus['errorCode']) != 0:
            debugger('Download status {}'.format(self.ariaStatus['status']))
            debugger('Downloader returned error code {}'.format(
                self.ariaStatus['errorCode']))
            return False

        return True