def parse_args(): # Handle '--write-rm-script' option. if '--write-rm-script' in sys.argv: sys.argv.remove('--write-rm-script') global do_write_rm_script do_write_rm_script = True # Handle '--exclude-pathname' option. It can be used multiple times. idx_to_delete = [] for i, argv in enumerate(sys.argv): if argv.startswith('--exclude-pathname'): global exclude_pathnames exclude_pathnames.append(argv.split('=')[1]) idx_to_delete.append(i) idx_to_delete.sort() idx_to_delete.reverse() for idx in idx_to_delete: del sys.argv[idx] try: root = os.path.abspath(sys.argv[1]) except IndexError: utils.exit_with_error_msg('Please provide a dirs as argument') # Ensure the dir is valid. if not os.path.isdir(root): utils.exit_with_error_msg('Please provide a valid dir') return root
def parse_args(): try: target_path = os.path.abspath(sys.argv[1]) except IndexError: utils.exit_with_error_msg('Please provide a file/dir as argument') # Ensure the target is a valid file/dir. if not os.path.isfile(target_path) and not os.path.isdir(target_path): utils.exit_with_error_msg('Please provide a file or dir as target') return target_path
def parse_args(): global filein try: filein = os.path.abspath(os.path.expanduser(sys.argv[1])) except IndexError: utils.exit_with_error_msg('Please provide a file as argument') # Ensure the file is valid. if not os.path.isfile(filein): utils.exit_with_error_msg('Please provide a valid file') return filein
def handle(self): parser = utils.ConfigParserLazy(self.path) is_local = parser.get('target', 'is-local', is_bool=True) target_path = parser.get('target', 'local-path') if not target_path: utils.exit_with_error_msg('{} is not a valid {} file'.format( self.path, utils.NIMLINK_EXT)) if not is_local: utils.mount_remote_offsync_root() self._open_local_file(target_path.strip())
def _compare_checksums(self, paths): checksum_dupes_map = defaultdict(list) for path in paths: # Eg.: $ md5 -q "myfile.jpg" cmd = '{} "{}"'.format(CHECKSUMFILE_CMD, path) output = subprocess.check_output(cmd, shell=True).rstrip() if not output: utils.exit_with_error_msg( 'Couldn\'t compute the checksum for: {}'.format(path)) checksum_dupes_map[output.strip()].append(path) self.checksums_dupes_map.update(checksum_dupes_map) return checksum_dupes_map
def parse_args(): global root try: root = os.path.abspath(sys.argv[1]) except IndexError: utils.exit_with_error_msg("Please provide a dirs as argument") # Ensure the dir is valid. if not os.path.isdir(root): utils.exit_with_error_msg("Please provide a valid dir") return root
def parse_args(): try: dir1 = os.path.abspath(sys.argv[1]) dir2 = os.path.abspath(sys.argv[2]) except IndexError: utils.exit_with_error_msg('Please provide two dirs as arguments') # Ensure the dirs are valid. if not os.path.isdir(dir1) or not os.path.isdir(dir2): utils.exit_with_error_msg('Please provide valid dirs') return dir1, dir2
def _find_all_duplicates_full_path(self, filename): # Eg.: $ find root -type f ! -path "*@eaDir*" ! -name ".DS_Store" -name myfile.jpg cmd = '{} "{}" -type f ! -path "*@eaDir*" ! -name ".DS_Store" -name "{}"'.format( FIND_CMD, self.root, filename) output = subprocess.check_output(cmd, shell=True).rstrip() if not output: utils.exit_with_error_msg( 'Couldn\'t find the actual duplicates for: {}'.format( filename)) paths = [] for line in output.splitlines(): paths.append(line.strip()) return paths
def _open_local_file(path): path = os.path.expanduser(path) # Ensure path is a valid file/dir. if os.path.isfile(path): cmd = utils.config.get('main', 'open-local-file-cmd') elif os.path.isdir(path): cmd = utils.config.get('main', 'open-local-dir-cmd') else: utils.exit_with_error_msg( 'The link points to {} which is not a valid local file/dir'. format(path)) utils.print_msg('> $' + cmd.format(path)) subprocess.check_call(cmd.format(path), shell=True)
def check_remote_offsync_root_content(): """ Ensure that the REMOTE OFFSYNC ROOT contains only (nested) "* | offsync" files/dirs. In other words: no other content apart from the (nested) "* | offsync" files/dirs. Example: valid: /Volumes/home/MYOFFSYNCDOCS/IT/ROUTER/OLD | offsync/FIRMWARE/1897.iso invalid: /Volumes/home/MYOFFSYNCDOCS/IT/ROUTER/info.txt invalid: /Volumes/home/MYOFFSYNCDOCS/IT/ROUTER/ - if empty """ utils.print_msg('\n> Checking REMOTE OFFSYNC ROOT dir content...') remote_offsync_root_mount_path = utils.config.get( 'main', 'remote-offsync-root-mount-path') # Find all (wrong) files with no "| offsync" in their full path. cmd = 'find "{}" -type f \! -path "* | offsync*" \! -name "*.DS_Store"' output = subprocess.check_output( cmd.format(remote_offsync_root_mount_path), shell=True) output = output # Find all (wrong) dirs: # - with no "| offsync" in their full path # - and with no sub dirs # - and with no offsync file. cmd = 'find "{}" -type d \! -path "* | offsync*"' dirs_output = subprocess.check_output( cmd.format(remote_offsync_root_mount_path), shell=True) for adir in dirs_output.strip().splitlines(): found = False for item in os.listdir(adir): if os.path.isdir(os.path.join(adir, item)) or re.match( r'.* \| offsync\..*', item): found = True break if not found: output += adir if output: utils.exit_with_error_msg( 'The following files/dirs are not marked as offsync nor nested in a ' 'offsync dir. Remove them to keep a mirrored structure between REMOTE OFFSYNC ROOT and ' 'LOCAL SYNC ROOT:\n{}'.format(output)) utils.print_msg('The content is OK')
def _create_single_local_sync_nimautolink(path): nimautolink_path = utils.from_remote_offsync_to_local_sync_nimautolink_path( path) # Check if the .nimautolink file already exists. if os.path.isfile(nimautolink_path): utils.print_msg('Already OK') return # Ensure all the parents dirs of .nimautolink already exist in the the SYNC dir. parent_dir = os.path.dirname(nimautolink_path) if not os.path.isdir(parent_dir): utils.exit_with_error_msg( '{} does not exist. Was this path renamed?'.format(parent_dir)) answer = input('Create {} [y/n*]? '.format(nimautolink_path)) if answer == 'y': # Create the file. open(nimautolink_path, 'w').close()
def _select_dupes_with_same_checksum(dupes, total_num): checksums_map = defaultdict(list) for dupe in dupes: full_path = os.path.join(root, dupe) try: hashval = _hash_metadata(full_path) except (MetadataReadingError, SkipMetadataReadingOption) as ex: if isinstance(ex, MetadataReadingError): utils.print_msg( '> Metadata reading failed for: {}\nHashing its content instead...' .format(dupe)) hashval = _hash_content(full_path) checksums_map[hashval].append(dupe) _remove_non_dupes(checksums_map) dupes = checksums_map.values() # A list of lists. if not dupes: return [] if len(dupes) > 1: utils.exit_with_error_msg( 'Found a group of files with the same size and subgroups of checksums, too weird!!' ) return dupes[0]
def parse_args(): try: nimlink_file = os.path.abspath(sys.argv[1]) except IndexError: utils.exit_with_error_msg( 'Please provide an argument (a {} or {} file)'.format( utils.NIMLINK_EXT, utils.NIMAUTOLINK_EXT)) # Ensure link_file is a valid file. if not (nimlink_file.endswith(utils.NIMLINK_EXT) or nimlink_file.endswith(utils.NIMAUTOLINK_EXT)): utils.exit_with_error_msg( 'Please provide a {} or {} file as argument'.format( utils.NIMLINK_EXT, utils.NIMAUTOLINK_EXT)) if not os.path.isfile(nimlink_file): utils.exit_with_error_msg( 'Please provide a valid {} or {} file as argument'.format( utils.NIMLINK_EXT, utils.NIMAUTOLINK_EXT)) return nimlink_file