def _device_removed(self, device): logging.debug('Device has been removed from the system: %s' % device) if device in self.sources: if misc.callable(self.source_removed_cb): self.source_removed_cb(device) self.sources.pop(device) elif device in self.targets: if misc.callable(self.target_removed_cb): self.target_removed_cb(device) self.targets.pop(device)
def _udisks_drive_added(self, obj, block, drive, path): logging.debug('drive added: %s' % path) if drive: vendor = drive.get_cached_property('Vendor').get_string() model = drive.get_cached_property('Model').get_string() size = block.get_cached_property('Size').get_uint64() label = block.get_cached_property('IdLabel').get_string() else: vendor = '' model = '' size = block.get_cached_property('Size').get_uint64() label = block.get_cached_property('IdLabel').get_string() if size <= 0: logging.debug('not adding device: 0 byte disk.') return self.targets[path] = { 'vendor': vendor, 'model' : model, 'label' : label, 'free' : -1, 'device': block.get_cached_property('Device').get_bytestring().decode('utf-8'), 'capacity' : size, 'status' : misc.NEED_FORMAT, 'mountpoint' : None, 'parent' : None, } if misc.callable(self.target_added_cb): self.target_added_cb(path) self.update_free()
def event_dispatcher(hwnd, message, wparam, lparam): eh = _event_handlers_ na = {} nas = set() handlers = set() for eh in [eh.get(hwnd, na), eh.get(None, na)]: for eh in [eh.get(message, na), eh.get(None, na)]: for eh in [eh.get(wparam, na), eh.get(None, na)]: if message == WM_NOTIFY: try: nmh = cast(lparam, POINTER(NMHDR)).contents handlers |= eh.get(nmh.hwndFrom, na) handlers |= eh.get(None, nas) except: pass else: handlers |= eh.get(lparam, nas) handlers |= eh.get(None, nas) for obj, handler_name in handlers: handler = getattr(obj, handler_name, None) if not callable(handler): continue result = handler((hwnd, message, wparam, lparam)) if bool(result): return result return windll.user32.DefWindowProcW(c_int(hwnd), c_int(message), c_int(wparam), c_int(lparam))
def _udisks_cdrom_added(self, obj, block, drive, path): logging.debug('cd added: %s' % path) fs = obj.get_filesystem() if not fs: logging.debug('cd %s has no filesystem.' % path) return mount_points = fs.get_cached_property( 'MountPoints').get_bytestring_array() if len(mount_points) == 0: try: mount = fs.call_mount_sync(no_options, None) except GLib.GError as e: logging.exception('Could not mount the device: %s' % e.message) else: mount = mount_points[0] total, free = misc.fs_size(mount) self.sources[path] = { 'device': block.get_cached_property('Device').get_bytestring().decode( 'utf-8'), 'size': total, 'label': block.get_cached_property('IdLabel').get_string(), 'type': misc.SOURCE_CD, 'mount': mount, } if misc.callable(self.source_added_cb): self.source_added_cb(path)
def _add_cd(self, device): logging.debug('cd added: %s' % device) dk = self.bus.get_object(DISKS_IFACE, device) def get(prop): return dk.Get(device, prop, dbus_interface=PROPS_IFACE) label = get('id-label') if not get('device-is-mounted'): try: dk.FilesystemMount('', [], dbus_interface=DEVICE_IFACE) except dbus.DBusException as e: logging.exception('Could not mount the device: %s' % e) return mount = get('device-mount-paths')[0] device_file = get('device-file') total, free = misc.fs_size(mount) self.sources[device] = { 'device': device_file, 'size': total, 'label': label, 'type': misc.SOURCE_CD, } if misc.callable(self.source_added_cb): self.source_added_cb(device)
def _failure(self, message=None): logging.critical(message) if self.progress_thread and self.progress_thread.is_alive(): self.progress_thread.join() if callable(self.failure): self.failure(message) sys.exit(1)
def on_uevent(self, action, device): logging.debug('action: %s' % action) logging.debug('device: %s' % device.get_sysfs_path()) for key,ids in KNOWN_IDS.items(): result = device.get_property(key) if result not in ids: logging.debug('Unknown %s: %s' % (key, result)) return [logging.debug('%s=%s' % (k, device.get_property(k))) for k in device.get_property_keys()] key = device.get_property('ID_SERIAL_SHORT') if action == 'add': self.targets[key] = { 'vendor' : device.get_property('ID_VENDOR_FROM_DATABASE'), 'model' : device.get_property('ID_MODEL'), 'label' : '', 'device' : device.get_property('ID_SERIAL_SHORT'), 'status' : misc.CAN_USE, } if misc.callable(self.target_added_cb): self.target_added_cb(key) elif action == 'remove': self._device_removed(key)
def _device_added(self, drive): drive_buf = ctypes.create_unicode_buffer(512) fs_buf = ctypes.create_unicode_buffer(512) vol_i = ctypes.windll.kernel32.GetVolumeInformationW drive_type = ctypes.windll.kernel32.GetDriveTypeW(drive) if vol_i(drive, drive_buf, 512, None, None, None, fs_buf, 512): volume = drive_buf.value fs = fs_buf.value else: logging.error('Could not get volume information for %s' % drive) return if drive_type > len(DRIVE_TYPES): drive_type = 0 drive_type = DRIVE_TYPES[drive_type] if drive_type == 'cdrom': if os.path.exists(os.path.join(drive, '.disk/info')): self.sources[drive] = { 'device': drive, 'size': misc.fs_size(drive)[0], 'label': volume, 'type': misc.SOURCE_CD, } if misc.callable(self.source_added_cb): self.source_added_cb(drive) elif drive_type == 'removeable': # and fs == u'fat32': tot, free = misc.fs_size(drive) self.targets[drive] = { 'capacity': tot, 'free': free, 'device': drive, # FIXME evand 2009-07-16: How does Windows get the volume name? # GetVolumeInformation returns NULL here. 'label': '', 'mountpoint': drive, 'status': misc.CAN_USE, } if misc.callable(self.target_added_cb): self.target_added_cb(drive) else: tot, free = misc.fs_size(drive) logging.debug('Not adding %s (%s %s %s volume, %d total bytes, ' '%d bytes free)' % (drive, volume, drive_type, fs, tot, free))
def add_image(self, filename): logging.debug('Backend told to add: %s' % filename) filename = os.path.abspath(os.path.expanduser(filename)) if not os.path.isfile(filename): return if filename in self.sources: logging.warn('Source already added.') # TODO evand 2009-07-27: Scroll to source and select. return extension = os.path.splitext(filename)[1] # TODO evand 2009-07-25: What's the equivalent of `file` on Windows? # Going by extension is a bit rough. if not extension: logging.error('File did not have an extension. ' 'Could not determine file type.') # TODO evand 2009-07-26: Error dialog. return extension = extension.lower() if extension == '.iso': label = self._is_casper_cd(filename) if label: self.sources[filename] = { 'device': filename, 'size': os.path.getsize(filename), 'label': label, 'type': misc.SOURCE_ISO, } if misc.callable(self.source_added_cb): self.source_added_cb(filename) elif extension == '.img': self.sources[filename] = { 'device': filename, 'size': os.path.getsize(filename), 'label': '', 'type': misc.SOURCE_IMG, } if misc.callable(self.source_added_cb): self.source_added_cb(filename) else: logging.error('Filename extension type not supported.')
def update_free(self): if not self.current_source: return True for k in self.targets: status = self.targets[k]['status'] changed = self._update_free(k) if status == misc.NEED_FORMAT or status == misc.CANNOT_USE: continue if changed and misc.callable(self.target_changed_cb): self.target_changed_cb(k) return True
def run(self): try: while not self._stopevent.isSet(): free = fs_size(self.device)[1] written = self.start_free - free v = int((written / float(self.to_write)) * 100) est = self.remtime.estimate(written, self.to_write) if callable(self.progress): self.progress(v, est[0], est[1]) self._stopevent.wait(2) except Exception: logging.exception('Could not update progress:')
def _udisks_drive_added(self, obj, block, drive, path): logging.debug('drive added: %s' % path) if drive: vendor = drive.get_cached_property('Vendor').get_string() model = drive.get_cached_property('Model').get_string() size = drive.get_cached_property('Size').get_uint64() else: vendor = '' model = '' size = block.get_cached_property('Size').get_uint64() if size <= 0: logging.debug('not adding device: 0 byte disk.') return self.targets[path] = { 'vendor': vendor, 'model': model, 'label': '', 'free': -1, 'device': block.get_cached_property('Device').get_bytestring().decode( 'utf-8'), 'capacity': size, 'status': misc.NEED_FORMAT, 'mountpoint': None, 'persist': 0, 'parent': None, 'formatting': False, } if misc.callable(self.target_added_cb): if self.show_all: self.target_added_cb(path) else: children = [ x for x in self.targets if self.targets[x]['parent'] == path and self.targets[x]['status'] != misc.NEED_FORMAT ] if not children: self.target_added_cb(path)
def _register_handlers(self): for key in dir(self): handler = getattr(self, key) handled_event = getattr(handler, "_handled_event_", None) if callable(handler) and handled_event: handled_event = list(handled_event) for i, subkey in enumerate(handled_event): if subkey is SELF_HWND: handled_event[i] = self._hwnd elif subkey is PARENT_HWND: handled_event[i] = self.parent._hwnd elif subkey is APPLICATION_HINSTANCE: handled_event[i] = self.frontend._hinstance self._add_event_handler(key, handled_event)
def _add_drive(self, device): logging.debug('disk added: %s' % device) dk = self.bus.get_object(DISKS_IFACE, device) def get(prop): return dk.Get(device, prop, dbus_interface=PROPS_IFACE) model = get('DriveModel') vendor = get('DriveVendor') device_file = get('device-file') size = get('device-size') if size > 0: self.targets[misc.text_type(device)] = { 'vendor': vendor, 'model': model, 'label': '', 'free': -1, 'device': misc.text_type(device_file), 'capacity': size, 'status': misc.NEED_FORMAT, 'mountpoint': None, 'persist': 0, 'parent': None, 'formatting': False, } if misc.callable(self.target_added_cb): if self.show_all: self.target_added_cb(device) else: children = [ x for x in self.targets if self.targets[x]['parent'] == misc.text_type(device) and self.targets[x]['status'] != misc.NEED_FORMAT ] if not children: self.target_added_cb(device) else: logging.debug('not adding device: 0 byte disk.')
def _success(self): if self.progress_thread and self.progress_thread.is_alive(): logging.debug('Shutting down the progress thread.') self.progress_thread.join() if callable(self.success): self.success()
def copy_file(self, sourcepath, targetpath): self.check() sourcefh = None targetfh = None # TODO evand 2009-07-24: Allow the user to disable this with a command # line option. md5_check = True try: while 1: sourcefh = open(sourcepath, 'rb') targetfh = open(targetpath, 'wb') if md5_check: sourcehash = md5() while 1: self.check() buf = sourcefh.read(16 * 1024) if not buf: break try: targetfh.write(buf) except IOError: # TODO evand 2009-07-23: Catch exceptions around the # user removing the flash drive mid-write. Give the # user the option of selecting the re-inserted disk # from a drop down list and continuing. # TODO evand 2009-07-23: Fail more gracefully. self._failure( _('Could not read from %s') % self.source) if md5_check: sourcehash.update(buf) if not md5_check: break targethash = md5() # TODO evand 2009-07-25: First check the MD5SUMS.txt file for # the hash. If it exists, and matches the source hash, # continue on. If it exists and does not match the source hash, # or it does not exist, calculate a new hash and compare again. targetfh.close() targetfh = open(targetpath, 'rb') while 1: buf = targetfh.read(16 * 1024) if not buf: break targethash.update(buf) if targethash.digest() != sourcehash.digest(): if targetfh: targetfh.close() if sourcefh: sourcefh.close() logging.error('Checksums do not match.') if callable(self.retry): response = self.retry( _('Checksums do not match. Retry?')) else: response = False if not response: self._failure(_('Checksums do not match.')) else: break finally: if targetfh: targetfh.close() if sourcefh: sourcefh.close()
def _add_partition(self, device): logging.debug('partition added: %s' % device) dk = self.bus.get_object(DISKS_IFACE, device) def get(prop): return dk.Get(device, prop, dbus_interface=PROPS_IFACE) model = get('DriveModel') vendor = get('DriveVendor') fstype = get('id-type') logging.debug('id-type: %s' % fstype) if fstype == 'vfat': status = misc.CAN_USE else: status = misc.NEED_FORMAT label = get('id-label') logging.debug('id-label: %s' % label) parent = get('partition-slave') if fstype == 'vfat' and not get('device-is-mounted'): parent_i = self.bus.get_object(DISKS_IFACE, parent) parent_i.Get(parent, 'device-file', dbus_interface=PROPS_IFACE) if device not in self.formatting and parent not in self.formatting: try: self.retry_mount(device) except: logging.exception('Could not mount the device:') return mount = get('device-mount-paths') or '' if mount: mount = mount[0] total, free = misc.fs_size(mount) else: # FIXME evand 2009-09-11: This is going to have weird side effects. # If the device cannot be mounted, but is a vfat filesystem, that # is. Is this really the right approach? total = get('partition-size') free = -1 logging.debug('mount: %s' % mount) device_file = get('device-file') if total > 0: self.targets[misc.text_type(device)] = { 'vendor': vendor, 'model': model, 'label': misc.text_type(label), 'free': free, 'device': misc.text_type(device_file), 'capacity': total, 'status': status, 'mountpoint': mount, 'persist': 0, 'parent': misc.text_type(parent), 'formatting': False, } self._update_free(misc.text_type(device)) if self.show_all: if misc.callable(self.target_added_cb): self.target_added_cb(device) else: if status != misc.NEED_FORMAT: if misc.text_type(parent) in self.targets: if misc.callable(self.target_removed_cb): self.target_removed_cb(parent) if misc.callable(self.target_added_cb): self.target_added_cb(device) else: logging.debug('not adding device: 0 byte partition.')
def _udisks_partition_added(self, obj, block, drive, path): logging.debug('partition added: %s' % path) fstype = block.get_cached_property('IdType').get_string() logging.debug('id-type: %s' % fstype) if fstype == 'vfat': status = misc.CAN_USE else: status = misc.NEED_FORMAT if drive: vendor = drive.get_cached_property('Vendor').get_string() model = drive.get_cached_property('Model').get_string() size = drive.get_cached_property('Size').get_uint64() else: vendor = '' model = '' size = block.get_cached_property('Size').get_uint64() partition = obj.get_partition() parent = partition.get_cached_property('Table').get_string() fs = obj.get_filesystem() if fs: mount_points = fs.get_cached_property( 'MountPoints').get_bytestring_array() if (fstype == 'vfat' and len(mount_points) == 0 and path not in self.formatting and parent not in self.formatting): try: mount = self.retry_mount(fs) except: logging.exception('Could not mount the device: %s' % path) return else: mount = mount_points and mount_points[0] else: mount = None if mount: total, free = misc.fs_size(mount) else: # FIXME evand 2009-09-11: This is going to have weird side effects. # If the device cannot be mounted, but is a vfat filesystem, that # is. Is this really the right approach? total = size free = -1 mount = '' logging.debug('mount: %s' % mount) if total > 1: self.targets[path] = { 'vendor': vendor, 'model': model, 'label': block.get_cached_property('IdLabel').get_string(), 'free': free, 'device': block.get_cached_property('Device').get_bytestring().decode( 'utf-8'), 'capacity': total, 'status': status, 'mountpoint': mount, 'persist': 0, 'parent': misc.text_type(parent), 'formatting': False, } self._update_free(path) if self.show_all: if misc.callable(self.target_added_cb): self.target_added_cb(device) else: if status != misc.NEED_FORMAT: if parent in self.targets: if misc.callable(self.target_removed_cb): self.target_removed_cb(parent) if misc.callable(self.target_added_cb): self.target_added_cb(path) else: logging.debug('not adding device: 0 byte partition.')
def _success(self): if callable(self.success): self.success()
def _failure(self, message=None): logging.critical(message) if callable(self.failure): self.failure(message) sys.exit(1)