コード例 #1
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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
コード例 #2
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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
コード例 #3
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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
コード例 #4
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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'))
コード例 #5
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #6
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #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'))
コード例 #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'))
コード例 #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'))
コード例 #10
0
ファイル: disk.py プロジェクト: KanoComputing/kano-burners
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'))
コード例 #11
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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'))
コード例 #12
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #13
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #14
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #15
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #16
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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'))
コード例 #17
0
ファイル: dependency.py プロジェクト: wooyek/kano-burners
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)
コード例 #18
0
ファイル: disk.py プロジェクト: langgaibo/kano-burners
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)
コード例 #19
0
ファイル: dependency.py プロジェクト: elyscape/kano-burners
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)
コード例 #20
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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)
コード例 #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))
コード例 #22
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #23
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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'))
コード例 #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))
コード例 #25
0
ファイル: dependency.py プロジェクト: wooyek/kano-burners
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
コード例 #26
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #27
0
ファイル: dependency.py プロジェクト: elyscape/kano-burners
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
コード例 #28
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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
コード例 #29
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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
コード例 #30
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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
コード例 #31
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #32
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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'))
コード例 #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
コード例 #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
コード例 #35
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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
コード例 #36
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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
コード例 #37
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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
コード例 #38
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #39
0
ファイル: dependency.py プロジェクト: wooyek/kano-burners
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)
コード例 #40
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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'))
コード例 #41
0
ファイル: burn.py プロジェクト: KanoComputing/kano-burners
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
コード例 #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
コード例 #43
0
ファイル: burn.py プロジェクト: wooyek/kano-burners
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
コード例 #44
0
ファイル: dependency.py プロジェクト: wooyek/kano-burners
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
コード例 #45
0
ファイル: disk.py プロジェクト: gerito1/kano-burners
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
コード例 #46
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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
コード例 #47
0
ファイル: disk.py プロジェクト: KanoComputing/kano-burners
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
コード例 #48
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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'))
コード例 #49
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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
コード例 #50
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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
コード例 #51
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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
コード例 #52
0
ファイル: download.py プロジェクト: elyscape/kano-burners
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
コード例 #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)
コード例 #54
0
ファイル: disk.py プロジェクト: wooyek/kano-burners
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)
コード例 #55
0
ファイル: disk.py プロジェクト: elyscape/kano-burners
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
コード例 #56
0
ファイル: download.py プロジェクト: wooyek/kano-burners
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
コード例 #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