def check_root_path(root_path: str) -> bool: if not os.path.exists(root_path): notify_print('error', 'Invalid path, try again.') return False else: notify_print('success', f'root_path has been successfully set.') return True
def check_shell_line_length(input_str: str) -> bool: if not check_integer(input_str): return False else: if int(input_str) < 30: notify_print( 'error', f'shell_line_length should ' f'be equal or greater than 30.') return False else: notify_print('success', f'shell_line_length has ' f'been successfully set.') return True
def get_bool_choice(notify_type, message, default_choice=False) -> bool: # default_choice: True for Yes, False for No if default_choice: message += ' [Y/n]' else: message += ' [y/N]' while True: notify_print(notify_type, message, end='') choice = input().strip() if default_choice: if choice == '' or choice.lower() == 'y': return True elif choice.lower() == 'n': return False else: if choice == '' or choice.lower() == 'n': return False elif choice.lower() == 'y': return True
def bib_parser(bib_string: str) -> dict: # use re.S flag to match more than one line basic_regexp = re.compile(r'@(?P<type>.*?){(?P<content>.*)}', re.S) basic_res = re.search(basic_regexp, bib_string) if not basic_res: notify_print('error', 'Invalid bib file.') exit(0) bib_type = basic_res.group('type') bib_content = basic_res.group('content').strip() + ',\n' content_regexp = re.compile(r'(?P<name>.*?),(?P<structured_content>.*)', re.S) content_res = re.search(content_regexp, bib_content) if not content_res: notify_print('error', 'Invalid bib content.') exit(0) bib_name = content_res.group('name') bib_structured_content = content_res.group('structured_content') # there should be '\s' after ',' item_regexp = re.compile(r'\s*(?P<key>.*?)\s*=\s*{(?P<value>.*?)}\s*,\s', re.S) bib_item_dict = {} for item in re.finditer(item_regexp, bib_structured_content): if not item: notify_print('error', 'Invalid bib item.') exit(0) bib_item_dict[item.group('key')] = re.sub(r'\s+', ' ', item.group('value')) # print(bib_type) # print(bib_name) # print(bib_item_dict) bib_dict = {'type': bib_type, 'name': bib_name, 'items': bib_item_dict} return bib_dict
def init_exec(): if os.path.exists(config_file_path): if not get_bool_choice( 'warning', 'Configuration file already exists. Would you like to rewrite it?', default_choice=False): return notify_print('info', 'Initializing configuration file.') root_path = l_root_path.get_type_transfer_func()(get_string_input( 'Choose a folder to store the files (absolute path):\n', l_root_path.get_validation_check_func(), default_value=None)) shell_line_length = l_shell_line_length.get_type_transfer_func()( get_string_input('Choose the length of line of your shell: ', l_shell_line_length.get_validation_check_func(), default_value='70')) config_dict = { l_root_path.get_name(): root_path, l_shell_line_length.get_name(): shell_line_length } with open(config_file_path, 'w') as f: json.dump(config_dict, f, indent=2) if os.path.exists(os.path.join(root_path, 'bib_backup')): notify_print('warning', 'Folder \'bib_backup\' has already exists.') else: os.mkdir(os.path.join(root_path, 'bib_backup')) if os.path.exists(os.path.join(root_path, db_file_name)): notify_print('warning', f'File \'{db_file_name}\' has already exists.') else: with open(os.path.join(root_path, db_file_name), 'w') as f: json.dump([], f) notify_print('success', 'Initialization finished!')
def import_exec(folder, single, tags): db_list = get_db_list() id_cnt = len(db_list) root_path = get_root_path() if not (folder or single): notify_print('error', 'Please set either a folder or a single file to import') exit(0) if not os.path.exists(root_path): notify_print('error', 'Folder at root path does not exist.') exit(0) if folder: if not os.path.exists(folder): notify_print('error', 'Folder does not exist.') exit(0) for file in os.listdir(folder): if os.path.splitext(file)[-1] == '.bib': continue bib_dict = import_single(folder, file, root_path) if not bib_dict: continue bib_dict['id'] = id_cnt id_cnt += 1 bib_dict['tags'] = [] if tags: bib_dict['tags'] = tags.split(';') db_list.append(bib_dict) if single: single_folder, single_file = os.path.split(single) bib_dict = import_single(single_folder, single_file, root_path) if not bib_dict: return bib_dict['id'] = id_cnt id_cnt += 1 bib_dict['tags'] = [] if tags: bib_dict['tags'] = tags.split(';') db_list.append(bib_dict) update_db_list(db_list)
def import_single(folder: str, file: str, root_path: str) -> dict or None: if os.path.splitext(file)[-1] != '.pdf' and os.path.splitext( file)[-1] != '.bib': notify_print( 'warning', f'File/folder {file} is neither a PDF file ' f'nor a BIB file, thus it has been ignored.') return None notify_print('info', f'Importing {file}') bib_path = os.path.join(folder, os.path.splitext(file)[0] + '.bib') if not os.path.exists(bib_path): notify_print( 'warning', f'File {file} does not have a corresponding bib file, thus' f'it will be ignored.') return None else: with open(bib_path) as f: bib_dict = bib_parser(f.read()) name: str = bib_dict['name'] title: str = bib_dict['items'].get('title', None) if title: title = title.strip().replace(' ', '-') notify_print('info', f'Using title {title} as the new file name.') shutil.copy( os.path.join(folder, file), os.path.join(root_path, title + os.path.splitext(file)[-1])) shutil.copy( bib_path, os.path.join(root_path, 'bib_backup', title + '.bib')) bib_dict['filename'] = title + os.path.splitext(file)[-1] elif name: name = name.strip().replace(' ', '-') notify_print('info', f'Using name {name} as the new file name.') shutil.copy( bib_path, os.path.join(root_path, 'bib_backup', name + '.bib')) shutil.copy( os.path.join(folder, file), os.path.join(root_path, name + os.path.splitext(file)[-1])) bib_dict['filename'] = name + os.path.splitext(file)[-1] else: notify_print('warning', f'Using the original file name {file}.') shutil.copy(os.path.join(folder, file), os.path.join(root_path, file)) bib_dict['filename'] = file shutil.copy( bib_path, os.path.join(root_path, 'bib_backup', os.path.splitext(file)[0] + '.bib')) return bib_dict
'split tags, and don\'t forget to use \'\' to' 'quote the args') parser_find.add_argument('-t', '--title', help='find by title') parser_find.add_argument('-a', '--author', help='find by author') parser_find.add_argument('-g', '--tags', help='find by tag') parser_open.add_argument('id', help='the id of paper to open') parser_export.add_argument( 'id', help='the id of paper to export the corresponding bib file') args = parser.parse_args() if len(sys.argv) <= 1: notify_print('error', 'Invalid command.') parser.print_help() exit(0) sub_parser_name = sys.argv[1] if sub_parser_name == 'init': init_exec() elif sub_parser_name == 'env': env_exec(args.reset, args.set) elif sub_parser_name == 'import': import_exec(args.folder, args.single, args.tags) elif sub_parser_name == 'find': find_exec(args.title, args.author, args.tags) elif sub_parser_name == 'open': open_exec(int(args.id))
def env_exec(arg_reset, arg_set): if not (arg_reset or arg_set): notify_print( 'error', 'There should be either --reset [env arg] ' 'or --set [env arg] [new value]') exit(0) else: if arg_reset: could_be_reset = [l_shell_line_length.get_name()] if arg_reset not in could_be_reset: notify_print('error', f'{arg_reset} could not be reset') exit(0) else: with open(config_file_path) as f: env_dict = json.load(f) env_dict[arg_reset] = get_param_by_param_name(arg_reset) \ .get_default_value() with open(config_file_path, 'w') as f: json.dump(env_dict, f, indent=2) notify_print('success', f'{arg_reset} has been reset') if arg_set: could_be_set = [l_shell_line_length.get_name()] if arg_set[0] not in could_be_set: notify_print('error', f'{arg_set[0]} could not be set') exit(0) else: param = get_param_by_param_name(arg_set[0]) if not param.get_validation_check_func()(str(arg_set[1])): notify_print('error', f'{arg_set[0]} could not be set') exit(0) with open(config_file_path) as f: env_dict = json.load(f) env_dict[arg_set[0]] = param.get_type_transfer_func()( arg_set[1]) with open(config_file_path, 'w') as f: json.dump(env_dict, f, indent=2) notify_print('success', f'{arg_set[0]} has been set to {arg_set[1]}')