def _remove(self): file_entries = self._selected.values() for index, file_entry in enumerate(file_entries): cursesswitch.print_string( "Removing %s (%d out of %d)" % (file_entry, index + 1, len(file_entries))) os.unlink(file_entry.full_filesystem_path())
def update_from_filesystem(self, max_depth=None, file_extentions=None, dirs_only=False, include_hidden=True): if not self._silent: cursesswitch.print_string("Scanning directory %s..." % (self._rootpath, )) if not dirs_only: entries = findcmdwrapper.find_files(self._rootpath, max_depth, file_extentions, include_hidden) inner_paths = [ self.abs_path_to_inner_path(entry) for entry in entries ] non_existent_paths = [ filepath for filepath in inner_paths if filepath not in self.nodes ] for filepath in non_existent_paths: self._add_file_by_path(filepath) dirnames_fullpath = findcmdwrapper.find_dirs(self._rootpath, max_depth, include_hidden) dirnames_inner_path = [ self.abs_path_to_inner_path(_dir) for _dir in dirnames_fullpath ] for dirpath in dirnames_inner_path: self._get_dir_node(dirpath)
def print_dirs(dirs): cursesswitch.print_string("\tReading device list...") devices_info = json.loads(subprocess.check_output(["lshw", "-json"])) for dir_idx, _dir in enumerate(dirs): device_storing_dir = _get_device_storing_dir(_dir) device_info = _get_device_info(device_storing_dir, devices_info) device_info_output = "" if device_info is None else " ".join( device_info) device_size = _get_dir_size(_dir) cursesswitch.print_string( "%d: \t%s\t%s\t%s" % (dir_idx, _dir, device_size, device_info_output))
def _pick(self, nr_options_to_pick): tree = treelib.Tree() tree.create_node(tag='Options') for index, option in enumerate(self._options): tree.create_node(tag=option, data=option, identifier=index, parent=tree.root) picker = treepicker.TreePicker(tree, max_nr_lines=15, including_root=False, max_nr_options=1) if nr_options_to_pick == 1: cursesswitch.print_string('Please choose a directory to sync') options = picker.pick_one() elif nr_options_to_pick == 2: cursesswitch.print_string('Please choose 2 directories to sync') options = picker.pick() return options
def _search_replicas(nr_replicas, filter_out=None): global invocation_counter invocation_counter += 1 if invocation_counter > 1: cursesswitch.print_string("Don't invoke this function more than once") sys.exit(1) if filter_out is None: filter_out = list() if nr_replicas == 1: cursesswitch.print_string( "Missing 1 replicas from arguments. Searching for it in the filesystem..." ) elif nr_replicas == 2: cursesswitch.print_string( "Missing 2 replicas from arguments. Searching for them in the filesystem..." ) candidates = list() for parentdir in config.POSSIBLE_PARENT_DIRS: cursesswitch.print_string("\tSearching under '%s'..." % (parentdir, )) candidates_paths = _find_dirs_with_matching_name(parentdir) candidates.extend(candidates_paths) candidates = [ candidate for candidate in candidates if candidate not in filter_out ] _validate_enough_replicas(candidates, nr_replicas) picker = optionpicker.OptionPickerByMenuTraverse(candidates) return picker.pick_several(nr_options_to_pick=nr_replicas)
def get(): replica_a = replica_b = None nr_args = len(sys.argv) if nr_args == 2: replica_a = sys.argv[1] elif nr_args == 3: replica_a = sys.argv[1] replica_b = sys.argv[2] elif nr_args > 3: cursesswitch.print_string("Invalid number of arguments.") sys.exit(1) if replica_a is not None: validate_replica(replica_a) replica_a = os.path.realpath(replica_a) if replica_b is not None: validate_replica(replica_b) replica_b = os.path.realpath(replica_b) return replica_a, replica_b
def copy_inner_entries_from_dirtree(self, dirtree): files = list(dirtree.iter_files()) for index, file_entry in enumerate(files): cursesswitch.print_string("Copying %s (%d out of %d)" % (file_entry, index + 1, len(files))) new_file_entry = self._add_file_by_path(file_entry.fullpath()) try: if os.path.exists(new_file_entry.filesystem_dirpath): assert os.path.isdir(new_file_entry.filesystem_dirpath) else: try: os.makedirs(new_file_entry.filesystem_dirpath) except OSError as ex: cursesswitch.print_string( "Copy failed: %s" % (str(ex), ), "red") continue shutil.copy(file_entry.full_filesystem_path(), new_file_entry.full_filesystem_path()) except: self.remove_node(new_file_entry.fullpath()) raise
def sync(self): missing = self._dst.get_unknown_entries_in_given_dirtree(self._src) while True: if not missing.does_dir_contain_any_files(): cursesswitch.print_string( "Nothing to synchronize; Destination dir alread contains all files " "in source dir.") break self._selected = self._chooseFiles(missing) if self._selected is None: cursesswitch.print_string("Sync ended by user's request.") break if not self._selected: break cursesswitch.print_string("%d files were chosen to copy so far." % (len(self._selected), )) option = self._chooseWhatToDoWithFiles() if option == self._OPTION_NOTHING: break elif option == self._OPTION_COPY: self._copy() self._update_from_filesystem() missing = self._dst.get_unknown_entries_in_given_dirtree( self._src) self._selected = dict() elif option == self._OPTION_REMOVE: self._remove() elif option == self._OPTION_RESELECT: pass else: assert False, option
def _pick(self, nr_options_to_pick): assert nr_options_to_pick <= len(self._options) if len(self._options) == nr_options_to_pick: if nr_options_to_pick == 2: cursesswitch.print_string("The following replicas were found:") cursesswitch.print_string("To use them, press enter.") elif nr_options_to_pick == 1: cursesswitch.print_string("The following replica was found: \n\n\t%s\n" % (self._options[0],)) cursesswitch.print_string("To use it, press enter.") self._continue_only_on_enter() picked_options = self._options else: for _ in xrange(nr_options_to_pick): self._pick_option() picked_options = [self._options[index] for index in self._picked_indices] return picked_options
def _pick_option(self): cursesswitch.print_string("Pick an option by typing its number") self._print_options() max_index = len(self._options) - 1 while True: cursesswitch.print_string(">>> ") raw_index = raw_input() try: index = int(raw_index) except ValueError: cursesswitch.print_string("Cannot parse index. please try again.") continue if index > max_index or index < 0: cursesswitch.print_string("Please specify a number between 0 and %d" % (max_index,)) continue break self._picked_indices.append(index)
def _validate_enough_replicas(candidates, nr_replicas): if len(candidates) < nr_replicas: if len(candidates) == 0: cursesswitch.print_string( "Did not find any replica in the filesystem to supplement existing." ) elif len(candidates) == 1: cursesswitch.print_string( "Did not find enough replicas in the filesystem to to pick from." ) cursesswitch.print_string("Only the following was found: %s" % (candidates[0], )) else: assert False sys.exit(1)
def _print_options(self): possible_indices = [index for index in xrange(len(self._options)) if index not in self._picked_indices] for index in possible_indices: cursesswitch.print_string("\t%d: %s" % (index, self._options[index]))
def validate_replica(replica_path): if replica_path is not None and not os.path.isdir(replica_path): cursesswitch.print_string("{} is not a directory".format(replica_path)) sys.exit(1)
def _set_default_subdir(self, parent, name): entry_path = parent.data.fullpath() entry_fullpath = os.path.join(entry_path, name) node = self.get_node(entry_fullpath) if node is None: filesystem_dirpath = os.path.join(parent.data.filesystem_dirpath, parent.data.name) subdir_entry = DirEntry(name, path=entry_path, filesystem_dirpath=filesystem_dirpath) node = self.create_node(identifier=entry_fullpath, tag=name, data=subdir_entry, parent=parent.identifier) return node def fullpath(self): return self._rootpath def __str__(self): return self.fullpath() def __repr__(self): return self.fullpath() if __name__ == '__main__': a = DirTree.factory_from_filesystem('alpha') cursesswitch.print_string(a)