def organize(self): try: dst = self.args[0].lower() except IndexError: raise OrganizerExceptions.CommandLineArgumentException('Must Enter a destination argument.') if dst == 'local': path = '/Users/agreen/.stage/finished/' elif dst == 'papa': path = '/Volumes/Papa/.finished/' elif dst == 'test': path = '/Users/agreen/Desktop/test/' else: raise OrganizerExceptions.CommandLineArgumentException('Must Enter a location argument') files_to_top = True target_path = os.path.join(path, '../.organized') if not os.path.exists(target_path): os.mkdir(target_path) excluded_names = ['random', 'series', 'finished'] names = Names(names_to_exclude=excluded_names) names.get_names_from_files_and_dirs([target_path]) organizer = Organizer(names, path, target_path, files_to_exclude=['.organized']) organizer.moveFilesForFirstAndLastName() if files_to_top: mover = FilesToTop(target_path, excluded_names) mover.moveFilesToTop() return None
def organize(self): try: dst = self.args[0].lower() except IndexError: raise OrganizerExceptions.CommandLineArgumentException( 'Must Enter a destination argument.') if dst == 'local': path = '/Users/agreen/.stage/finished/' elif dst == 'papa': path = '/Volumes/Papa/.finished/' elif dst == 'test': path = '/Users/agreen/Desktop/test/' else: raise OrganizerExceptions.CommandLineArgumentException( 'Must Enter a location argument') files_to_top = True target_path = os.path.join(path, '../.organized') if not os.path.exists(target_path): os.mkdir(target_path) excluded_names = ['random', 'series', 'finished'] names = Names(names_to_exclude=excluded_names) names.get_names_from_files_and_dirs([target_path]) organizer = Organizer(names, path, target_path, files_to_exclude=['.organized']) organizer.moveFilesForFirstAndLastName() if files_to_top: mover = FilesToTop(target_path, excluded_names) mover.moveFilesToTop() return None
def cache_names(self): path_list = ['/Volumes/Papa/.organized/', '/Volumes/Papa/.p/'] excluded_names = ['random', 'series', 'finished'] names = Names(names_to_exclude=excluded_names) names.update_cached_names(path_list, use_current_cache=False) print('cached', len(names.all_names()), 'names') return None
class SymLinker: def __init__(self, base_path): self.base_path = base_path self.names = Names(names_to_exclude=[ '.DS_Store', '.organized', '.finished' ]) self.link_counter = 1 def setup(self): self.names.get_names_from_files_and_dirs(paths_list=[]) return None def link(self): [self._link_helper(file, file, self.base_path) for file in os.listdir(self.base_path) if os.path.isdir(os.path.join(self.base_path, file))] self.link_counter = 1 return None def _link_helper(self, name, dir, parent_path): dir_path = os.path.join(parent_path, dir) files = os.listdir(dir_path) for file in files: file_path = os.path.join(dir_path, file) if os.path.isdir(file_path): self._link_helper(name, file, dir_path) return None names = self.names.names_in_file(file) for p_name in names: underscored_name = self.names.underscored_name(p_name) link_path = os.path.join(self.base_path, underscored_name, file) if underscored_name != name and not os.path.exists(link_path): name_path = os.path.join(self.base_path, underscored_name) if not os.path.exists(name_path): os.makedirs(name_path) print(self.link_counter, ':linking files:\t', file_path, '\n\t\t\t', link_path, '\n') os.symlink(file_path, link_path) self.link_counter += 1 return None def remove_links(self): [self._remove_links_helper(file, self.base_path) for file in os.listdir(self.base_path) if os.path.isdir(os.path.join(self.base_path, file))] self.link_counter = 1 return None def _remove_links_helper(self, dir, base_path): dir_path = os.path.join(base_path, dir) files = os.listdir(dir_path) for file in files: file_path = os.path.join(dir_path, file) if os.path.isdir(file_path): self._remove_links_helper(file, dir_path) else: if os.path.islink(file_path): print(self.link_counter, 'removing link:', file_path) os.remove(file_path) self.link_counter += 1 return None
def print_cached_names(self): excluded_names = ['random', 'series', 'finished'] names = Names(names_to_exclude=excluded_names) names.get_names_from_cached_file() all_names = names.all_names() for i in range(len(all_names)): print(i+1, ': ', all_names[i]) return None
def print_cached_names(self): excluded_names = ['random', 'series', 'finished'] names = Names(names_to_exclude=excluded_names) names.get_names_from_cached_file() all_names = names.all_names() for i in range(len(all_names)): print(i + 1, ': ', all_names[i]) return None
def __init__(self, path, dir_paths, run_local=False, excluded_names=None): self.path = path self.dir_paths = dir_paths self.names = Names() self.excluded_names = set(excluded_names) if excluded_names else set( []) self.run_local = run_local self.files = [] self.name_adder = NameAdder(None, path) self.changed_files = {}
def cache_names(self): path_list = [ '/Volumes/Papa/.organized/', '/Volumes/Papa/.p/' ] excluded_names = ['random', 'series', 'finished'] names = Names(names_to_exclude=excluded_names) names.update_cached_names(path_list, use_current_cache=False) print('cached', len(names.all_names()), 'names') return None
def __init__(self, base_path): self.base_path = base_path self.file_namer = FileNamer() self.files_to_ignore = {'.DS_Store'} self.namer = Names(names_to_exclude=[ 'random', 'series', 'finished' ]) self.names = []
def __init__(self, base_path): self.base_path = base_path self.names = Names(names_to_exclude=[ '.DS_Store', '.organized', '.finished' ]) self.link_counter = 1
def __init__(self, path, dir_paths, run_local=False, excluded_names=None): self.path = path self.dir_paths = dir_paths self.names = Names() self.excluded_names = set(excluded_names) if excluded_names else set([]) self.run_local = run_local self.files = [] self.name_adder = NameAdder(None, path) self.changed_files = {}
def __init__(self, name, root_path, dir_paths, hide=None): self.VERTICAL_START_POINT = 2 self.VERTICAL_SPACER = 1 self.INDENT_SIZE = 4 self.left_position = self.INDENT_SIZE self.line_x0 = 0 self.vertical_position = 0 self.vertical_user_start = 0 self.screen = curses.initscr() self.screen_params = {} self.names = Names() self.current_file_index = 0 self.costars = [] self.phases = _LinkCostarsPhases() self.current_phase = 0 self.current_text = '' self.current_name = name self.root_path = root_path self.colors = Colors() self.first_time = True self.current_files = [] self.changed_files = {} self._setup(dir_paths)
class LinkCostarsController: def __init__(self, name, root_path, dir_paths, hide=None): self.VERTICAL_START_POINT = 2 self.VERTICAL_SPACER = 1 self.INDENT_SIZE = 4 self.left_position = self.INDENT_SIZE self.line_x0 = 0 self.vertical_position = 0 self.vertical_user_start = 0 self.screen = curses.initscr() self.screen_params = {} self.names = Names() self.current_file_index = 0 self.costars = [] self.phases = _LinkCostarsPhases() self.current_phase = 0 self.current_text = '' self.current_name = name self.root_path = root_path self.colors = Colors() self.first_time = True self.current_files = [] self.changed_files = {} self._setup(dir_paths) def _setup(self, dir_paths): self.names.get_names_from_files_and_dirs(dir_paths) self.current_files = list(os.listdir(os.path.join(self.root_path, self.current_name))) self.screen.keypad(True) curses.start_color() for i in range(1, self.colors.count + 1): curses.init_pair( i, self.colors.curses_color(i), curses.COLOR_BLACK ) curses.noecho() self.create_title() self.show_files() self.vertical_user_start = self.vertical_position self.step_through() return None def cleanup(self): self.screen.keypad(False) curses.echo() curses.nocbreak() curses.endwin() return None def reset(self, reset_full): self.print_blank_line() self.left_position = 2*self.INDENT_SIZE self.current_text = '' if reset_full: self.current_phase = self.phases.show_file_name self.vertical_position = self.vertical_user_start self.screen.move(self.vertical_position, self.left_position) self.screen.clrtobot() self.screen.refresh() self.increment_file_index() else: self.step_through() return None def increment_file_index(self): self.current_file_index += 1 if self.current_file_index < len(self.current_files): self.step_through() else: self.summary(on_exit=False) return None def summary(self, on_exit=True): counter = 0 lines = [] for old_name, new_name in self.changed_files.items(): lines.append(str(counter) + '.) ' + old_name + ' became: ' + new_name) counter += 1 if on_exit: print("All done...here is a summary") [print(line) for line in lines] else: self.print_line( "All done...here is a summary", left_position=self.left_position, vertical_position=self.vertical_position, color=self.colors.green ) for line in lines: self.print_line( line, left_position=self.left_position, vertical_position=self.vertical_position, color=self.colors.cyan ) return None def run(self): try: while True: event = self.screen.getch() if event == 127: self.handle_backspace() elif event == 10: self.handle_return() elif event == 9: self.process_autocomplete() elif event == curses.KEY_RESIZE: self.handle_resize() elif event == curses.KEY_RIGHT: self.handle_arrow_press('right') elif event == curses.KEY_LEFT: self.handle_arrow_press('left') else: self.handle_key_press(event) except KeyboardInterrupt: self.cleanup() print("You've killed good unknown files...shame, shame!!") self.summary() except: self.cleanup() print(traceback.format_exc()) return None def create_title(self): self.print_line('UNKNOWN FILES', color=self.colors.blue) return None def show_files(self): y_pos = self.VERTICAL_START_POINT for file in self.current_files[:30]: info = file self.print_line( info, vertical_position=y_pos ) y_pos += 1 self.vertical_position = y_pos + self.VERTICAL_SPACER self.screen.refresh() return None def step_through(self): current_file = self.current_files[self.current_file_index] if self.current_phase == self.phases.show_file_name: self.print_blank_line() self.print_line( 'Current File: ' + current_file, left_position=self.INDENT_SIZE, vertical_position=self.vertical_position, color=self.colors.magenta ) self.current_phase = self.phases.enter_names_for_file if self.current_phase == self.phases.enter_names_for_file: message = 'Enter names to add to ' + current_file + ' ' self.print_line( message, left_position=self.INDENT_SIZE, vertical_position=self.vertical_position, color=self.colors.cyan, increment_vertical=False ) self.left_position = self.INDENT_SIZE + len(message) self.line_x0 = self.left_position elif self.current_phase == self.phases.ask_add_name_to_file: message = 'Add ' + str(self.costars) + ' to: ' + current_file + '? ' self.print_line( message, left_position=self.INDENT_SIZE, vertical_position=self.vertical_position, increment_vertical=False, color=self.colors.cyan ) self.left_position = self.INDENT_SIZE + len(message) self.line_x0 = self.left_position elif self.current_phase == self.phases.add_name_to_file: nameAdder = NameAdder([], os.path.join(self.root_path, self.current_name)) new_name = nameAdder.rename_file(current_file, ','.join(self.costars), should_print=False) self.changed_files[current_file] = new_name self.print_moved_file(current_file, new_name) self.reset(reset_full=True) return None def handle_return(self): current_text = self.current_text.lower() reset_full = False if self.current_phase == self.phases.enter_names_for_file: if current_text == '': self.print_blank_line() self.current_phase = self.phases.show_file_name reset_full = True else: self.costars = [] for unclean_name in self.current_text.split(','): if '_' in unclean_name: unclean_name = unclean_name.replace(' ', '') self.costars.append(unclean_name) else: names = [part for part in unclean_name.split(' ') if part != ''] self.costars.append('_'.join(names)) self.print_blank_line() self.current_phase = self.phases.ask_add_name_to_file elif self.phases.ask_add_name_to_file: if current_text == 'y' or current_text == 'yes': self.print_blank_line() self.current_phase = self.phases.add_name_to_file else: self.current_phase = self.phases.show_file_name reset_full = True self.reset(reset_full=reset_full) return None def handle_backspace(self): x_position = self.left_position - self.line_x0 + 1 #self.print_test(str(x_position)) if x_position > 0 and len(self.current_text) > 0: self.left_position -= 1 # check if cursor is outside of the current text if x_position > len(self.current_text): self.current_text = self.current_text[:len(self.current_text) - 1] else: self.current_text = self.current_text[:x_position] + self.current_text[x_position + 1:] self.screen.clrtoeol() self.print_line( self.current_text, self.line_x0, self.vertical_position, increment_vertical=False ) self.screen.move(self.vertical_position, self.left_position) self.screen.refresh() return None def handle_arrow_press(self, direction): if direction == 'left': movement = -1 else: movement = 1 new_position = self.left_position + movement if (new_position >= self.line_x0 and new_position + movement <= len(self.current_text) + self.line_x0 + 1): self.left_position = new_position self.screen.move(self.vertical_position, self.left_position) self.screen.refresh() return None def handle_key_press(self, event): new_char = chr(event) x = self.left_position - self.line_x0 self.current_text = self.current_text[:x] + new_char + self.current_text[x:] self.print_line( self.current_text, left_position=self.line_x0, vertical_position=self.vertical_position, increment_vertical=False ) self.left_position += 1 self.screen.move(self.vertical_position, self.left_position) self.screen.refresh() return None def print_line( self, message, left_position=0, vertical_position=0, color=0, increment_vertical=True ): self.screen.addstr(vertical_position, left_position, message, curses.color_pair(color)) self.screen.refresh() if increment_vertical: self.vertical_position += 1 return None def print_moved_file(self, previous_name, after_name): self.print_line( 'Moving: ' + previous_name + ' --> ' + after_name, left_position=self.INDENT_SIZE, vertical_position=self.vertical_position, color=self.colors.yellow ) return None def print_blank_line(self): self.print_line('', left_position=0, vertical_position=self.vertical_position) return None def process_autocomplete(self): parts = self.current_text.split(',') current_text_parts = parts[len(parts) - 1].split(' ') if current_text_parts[0] == '': del current_text_parts[0] underscored_name = '_'.join(current_text_parts) matched_names = [] for name in self.names.all_names_underscored(): if len(underscored_name) <= len(name) and underscored_name == name[:len(underscored_name)]: matched_names.append(name) if len(matched_names) == 0: self.print_line( 'No matched found', left_position=self.INDENT_SIZE, vertical_position=self.vertical_position + 1, increment_vertical=False, color=self.colors.yellow ) self.screen.clrtoeol() return None # add common letters to current_text letters_to_add = '' first_name = matched_names[0] for i in range(len(underscored_name), len(first_name)): letter = first_name[i] has_letter = True for j in range(1, len(matched_names)): try: if matched_names[j][i] != letter: has_letter = False break except IndexError: has_letter = False break if has_letter: letters_to_add += letter else: break if letters_to_add != '': self.left_position += len(letters_to_add) self.current_text += letters_to_add left_start = self.left_position - len(self.current_text) self.print_line( self.current_text, left_position=left_start, vertical_position=self.vertical_position, increment_vertical=False ) self.print_line( ', '.join(matched_names[:10]), left_position=self.INDENT_SIZE, vertical_position=self.vertical_position + 1, increment_vertical=False, color=self.colors.yellow ) self.screen.clrtoeol() return None def handle_resize(self): terminal_size = self.terminal_size() return None def terminal_size(self): try: width, height = os.get_terminal_size[0], os.get_terminal_size[1] return { 'width': width, 'height': height } except OSError: return { 'width': 100, 'height': 50 } def print_test(self, message): self.print_line( message, left_position=0, vertical_position=1, increment_vertical=False, color=self.colors.red )
dirs = [ '/Users/agreen/.stage/finished/organized/', '/Volumes/Charlie/.p/', '/Volumes/Charlie/.p/finished/', '/Volumes/Echo/.p/', '/Volumes/Echo/.p/finished/' ] paths = [] for adir in dirs: try: if os.path.isdir(adir): paths.append(adir) except: print('could not find', adir) namer = Names(namesToExclude=['finished']) namer.getNamesFromFilesAndDirs(paths) file = open(fPath_names, 'w') for name in namer.nameList: underScoredName = name.replace(' ', '_') line = underScoredName + '="' + underScoredName + '"\n' file.write(line) file.close() elif state == 'off': file = open(fPath_names, 'r') for line in file: name = line.split('=')[0] cmd = 'unset $' + name suc = call(cmd, shell=True) if suc != 0: print('Error: could not unset $', name)
class FormatFiles: def __init__(self, base_path): self.base_path = base_path self.file_namer = FileNamer() self.files_to_ignore = {'.DS_Store'} self.namer = Names(names_to_exclude=[ 'random', 'series', 'finished' ]) self.names = [] def format(self): self._format_helper(self.base_path) return None def _setup(self): self.namer.get_names_from_files() self.names = self.namer.first_and_last_names() return None def _format_helper(self, base_path): files = os.listdir(base_path) for file in files: if file in self.files_to_ignore: continue print('file:', file) file_path = os.path.join(base_path, file) if os.path.isdir(file_path): self._format_helper(file_path) new_name = self.file_namer.clean_name_for_raw_file(file, base_path) new_path = os.path.join(base_path, new_name) print('Moving:', file_path, '\n', new_path, '\n') shutil.move(file_path, new_path) return None def add_names_no_spaces(self): self._setup() self._add_names_no_spaces_helper(self.base_path) return None def _add_names_no_spaces_helper(self, base_path): files = os.listdir(base_path) for file in files: file_path = os.path.join(base_path, file) if os.path.isdir(file_path): self._add_names_no_spaces_helper(file_path) else: for name in self.names: indexes = self._all_indexes(file, name[0]) for i in indexes: last_name_index = i + len(name[0]) try: last_name = file[last_name_index:last_name_index + len(name[1])] except IndexError: continue if last_name == name[1]: new_file = file[:last_name_index] + '_' + file[last_name_index:] last_name_index += 1 next_index = last_name_index + len(name[1]) if (next_index < len(new_file) - 1 and new_file[next_index] != '_' and new_file[next_index] != '.'): new_file = new_file[:next_index] + '_' + new_file[next_index:] prev_index = i - 1 if prev_index >=0 and new_file[prev_index] != '_': new_file = new_file[:i] + '_' + new_file[i:] new_file_path = os.path.join(base_path, new_file) print('moving:\t', file_path, '\n\t', new_file_path, '\n') shutil.move(file_path, new_file_path) file = new_file file_path = new_file_path return None def _all_indexes(self, input_string, target): indexes = [] i = 0 while True: i = input_string.find(target, i) if i == -1: break indexes.append(i) i += len(target) return indexes
'/Volumes/Charlie/.p/', '/Volumes/Charlie/.p/finished/', '/Volumes/Echo/.p/', '/Volumes/Echo/.p/finished/' ] paths = [] for adir in dirs: try: if os.path.isdir(adir): paths.append(adir) except: print('could not find', adir) namer = Names(namesToExclude=['finished']) namer.getNamesFromFilesAndDirs(paths) file = open(fPath_names, 'w') for name in namer.nameList: underScoredName = name.replace(' ', '_') line = underScoredName + '="' + underScoredName + '"\n' file.write(line) file.close() elif state == 'off': file = open(fPath_names, 'r') for line in file: name = line.split('=')[0] cmd = 'unset $' + name suc = call(cmd, shell=True) if suc != 0: print('Error: could not unset $', name)
class UnknownFiles: def __init__(self, path, dir_paths, run_local=False, excluded_names=None): self.path = path self.dir_paths = dir_paths self.names = Names() self.excluded_names = set(excluded_names) if excluded_names else set( []) self.run_local = run_local self.files = [] self.name_adder = NameAdder(None, path) self.changed_files = {} def fetch_unknown_files(self): if self.run_local: self.names.get_names_from_file() else: self.names.get_names_from_files_and_dirs(self.dir_paths) files = os.listdir(self.path) printList = [] for aFile in files: shouldPrint = True for name in self.names.all_names(): if aFile in self.excluded_names or self.names.file_has_name( name, aFile): shouldPrint = False break printList.append(shouldPrint) counter = 0 for shouldPrint in printList: if shouldPrint: organizer_file = OrganizerFile(files[counter], counter) self.files.append(organizer_file) counter += 1 return None def file_at_index(self, index): return self.files[index] def print_unknown_files(self): [ print(organizer_file.index, '--', organizer_file.file_name) for organizer_file in self.files ] return None def list_files_in_directory(self, dir): print('\tsub-files:') files = os.listdir(os.path.join(self.path, dir)) for i in range(len(files)): file = files[i] print('\t\t', i, ':', file) return None def sub_files_for_file_index(self, fileIndex): organizer_file = self.files[fileIndex] return list( os.listdir(os.path.join(self.path, organizer_file.file_name))) def add_dir_names_to_sub_files(self, organizer_file): name_adder = AddDirNameToFiles(organizer_file.file_name, self.path) name_adder.add(should_print=False) return None def add_names_to_file(self, unknown_file, names): new_name = self.name_adder.rename_file(unknown_file.file_name, ','.join(names), should_print=False) self.changed_files[unknown_file.file_name] = new_name return new_name def is_file_dir(self, file_index): return os.path.isdir( os.path.join(self.path, self.files[file_index].file_name)) def number_of_unknowns(self): return len(self.files) def print_summary(self): print("Here's the summary:") for oldName in self.changed_files: newName = self.changed_files[oldName] print('\t' + oldName, 'became --->', newName) return None
def __init__(self, base_path): self.base_path = base_path self.names = Names( names_to_exclude=['.DS_Store', '.organized', '.finished']) self.link_counter = 1
class SymLinker: def __init__(self, base_path): self.base_path = base_path self.names = Names( names_to_exclude=['.DS_Store', '.organized', '.finished']) self.link_counter = 1 def setup(self): self.names.get_names_from_files_and_dirs(paths_list=[]) return None def link(self): [ self._link_helper(file, file, self.base_path) for file in os.listdir(self.base_path) if os.path.isdir(os.path.join(self.base_path, file)) ] self.link_counter = 1 return None def _link_helper(self, name, dir, parent_path): dir_path = os.path.join(parent_path, dir) files = os.listdir(dir_path) for file in files: file_path = os.path.join(dir_path, file) if os.path.isdir(file_path): self._link_helper(name, file, dir_path) return None names = self.names.names_in_file(file) for p_name in names: underscored_name = self.names.underscored_name(p_name) link_path = os.path.join(self.base_path, underscored_name, file) if underscored_name != name and not os.path.exists(link_path): name_path = os.path.join(self.base_path, underscored_name) if not os.path.exists(name_path): os.makedirs(name_path) print(self.link_counter, ':linking files:\t', file_path, '\n\t\t\t', link_path, '\n') os.symlink(file_path, link_path) self.link_counter += 1 return None def remove_links(self): [ self._remove_links_helper(file, self.base_path) for file in os.listdir(self.base_path) if os.path.isdir(os.path.join(self.base_path, file)) ] self.link_counter = 1 return None def _remove_links_helper(self, dir, base_path): dir_path = os.path.join(base_path, dir) files = os.listdir(dir_path) for file in files: file_path = os.path.join(dir_path, file) if os.path.isdir(file_path): self._remove_links_helper(file, dir_path) else: if os.path.islink(file_path): print(self.link_counter, 'removing link:', file_path) os.remove(file_path) self.link_counter += 1 return None
class UnknownFiles: def __init__(self, path, dir_paths, run_local=False, excluded_names=None): self.path = path self.dir_paths = dir_paths self.names = Names() self.excluded_names = set(excluded_names) if excluded_names else set([]) self.run_local = run_local self.files = [] self.name_adder = NameAdder(None, path) self.changed_files = {} def fetch_unknown_files(self): if self.run_local: self.names.get_names_from_file() else: self.names.get_names_from_files_and_dirs(self.dir_paths) files = os.listdir(self.path) printList = [] for aFile in files: shouldPrint = True for name in self.names.all_names(): if aFile in self.excluded_names or self.names.file_has_name(name, aFile): shouldPrint = False break printList.append(shouldPrint) counter = 0 for shouldPrint in printList: if shouldPrint: organizer_file = OrganizerFile(files[counter], counter) self.files.append(organizer_file) counter += 1 return None def file_at_index(self, index): return self.files[index] def print_unknown_files(self): [print(organizer_file.index, '--', organizer_file.file_name) for organizer_file in self.files] return None def list_files_in_directory(self, dir): print('\tsub-files:') files = os.listdir(os.path.join(self.path, dir)) for i in range(len(files)): file = files[i] print('\t\t',i, ':', file) return None def sub_files_for_file_index(self, fileIndex): organizer_file = self.files[fileIndex] return list(os.listdir(os.path.join(self.path, organizer_file.file_name))) def add_dir_names_to_sub_files(self, organizer_file): name_adder = AddDirNameToFiles(organizer_file.file_name, self.path) name_adder.add(should_print=False) return None def add_names_to_file(self, unknown_file, names): new_name = self.name_adder.rename_file( unknown_file.file_name, ','.join(names), should_print=False ) self.changed_files[unknown_file.file_name] = new_name return new_name def is_file_dir(self, file_index): return os.path.isdir(os.path.join(self.path, self.files[file_index].file_name)) def number_of_unknowns(self): return len(self.files) def print_summary(self): print("Here's the summary:") for oldName in self.changed_files: newName = self.changed_files[oldName] print('\t' + oldName, 'became --->', newName) return None