diff --git a/scripts/importer.py b/scripts/importer.py index 1b3be4d32..9171bbbb6 100755 --- a/scripts/importer.py +++ b/scripts/importer.py @@ -28,50 +28,176 @@ Currently only importing bookmarks from Netscape Bookmark files is supported. import argparse +browser_default_input_format = { + 'chromium': 'netscape', + 'ie': 'netscape', + 'firefox': 'netscape', + 'seamonkey': 'netscape', + 'palemoon': 'netscape' +} + def main(): args = get_args() - if args.browser in ['chromium', 'firefox', 'ie']: - import_netscape_bookmarks(args.bookmarks, args.bookmark_format) + bookmark_types = [] + output_format = None + input_format = args.input_format + if args.search_output: + bookmark_types = ['search'] + if args.oldconfig: + output_format = 'oldsearch' + else: + output_format = 'search' + else: + if args.bookmark_output: + output_format = 'bookmark' + elif args.quickmark_output: + output_format = 'quickmark' + if args.import_bookmarks: + bookmark_types.append('bookmark') + if args.import_keywords: + bookmark_types.append('keyword') + if not bookmark_types: + bookmark_types = ['bookmark', 'keyword'] + if not output_format: + output_format = 'quickmark' + if not input_format: + if args.browser: + input_format = browser_default_input_format[args.browser] + else: + #default to netscape + input_format = 'netscape' + + import_function = {'netscape': import_netscape_bookmarks} + import_function[input_format](args.bookmarks, bookmark_types, + output_format) def get_args(): """Get the argparse parser.""" parser = argparse.ArgumentParser( epilog="To import bookmarks from Chromium, Firefox or IE, " - "export them to HTML in your browsers bookmark manager. " - "By default, this script will output in a quickmarks format.") - parser.add_argument('browser', help="Which browser? (chromium, firefox)", - choices=['chromium', 'firefox', 'ie'], - metavar='browser') - parser.add_argument('-b', help="Output in bookmark format.", - dest='bookmark_format', action='store_true', - default=False, required=False) + "export them to HTML in your browsers bookmark manager. ") + parser.add_argument( + 'browser', + help="Which browser? {%(choices)s}", + choices=browser_default_input_format.keys(), + nargs='?', + metavar='browser') + parser.add_argument( + '-i', + '--input-format', + help='Which input format? (overrides browser default; "netscape" if ' + 'neither given)', + choices=set(browser_default_input_format.values()), + required=False) + parser.add_argument( + '-b', + '--bookmark-output', + help="Output in bookmark format.", + action='store_true', + default=False, + required=False) + parser.add_argument( + '-q', + '--quickmark-output', + help="Output in quickmark format (default).", + action='store_true', + default=False, + required=False) + parser.add_argument( + '-s', + '--search-output', + help="Output config.py search engine format (negates -B and -K)", + action='store_true', + default=False, + required=False) + parser.add_argument( + '--oldconfig', + help="Output search engine format for old qutebrowser.conf format", + default=False, + action='store_true', + required=False) + parser.add_argument( + '-B', + '--import-bookmarks', + help="Import plain bookmarks (can be combiend with -K)", + action='store_true', + default=False, + required=False) + parser.add_argument( + '-K', + '--import-keywords', + help="Import keywords (can be combined with -B)", + action='store_true', + default=False, + required=False) parser.add_argument('bookmarks', help="Bookmarks file (html format)") args = parser.parse_args() return args -def import_netscape_bookmarks(bookmarks_file, is_bookmark_format): +def search_escape(url): + """Escape URLs such that preexisting { and } are handled properly. + + Will obviously trash a properly-formatted Qutebrowser URL. + """ + return url.replace('{', '{{').replace('}', '}}') + + +def import_netscape_bookmarks(bookmarks_file, bookmark_types, output_format): """Import bookmarks from a NETSCAPE-Bookmark-file v1. - Generated by Chromium, Firefox, IE and possibly more browsers + Generated by Chromium, Firefox, IE and possibly more browsers. Not all + export all possible bookmark types: + - Firefox mostly works with everything + - Chrome doesn't support keywords at all; searches are a separate + database """ import bs4 with open(bookmarks_file, encoding='utf-8') as f: soup = bs4.BeautifulSoup(f, 'html.parser') - - html_tags = soup.findAll('a') - if is_bookmark_format: - output_template = '{tag[href]} {tag.string}' - else: - output_template = '{tag.string} {tag[href]}' - + bookmark_query = { + 'search': lambda tag: ( + (tag.name == 'a') and + ('shortcuturl' in tag.attrs) and + ('%s' in tag['href'])), + 'keyword': lambda tag: ( + (tag.name == 'a') and + ('shortcuturl' in tag.attrs) and + ('%s' not in tag['href'])), + 'bookmark': lambda tag: ( + (tag.name == 'a') and + ('shortcuturl' not in tag.attrs) and + (tag.string)), + } + output_template = { + 'search': { + 'search': + "c.url.searchengines['{tag[shortcuturl]}'] = " + "'{tag[href]}' #{tag.string}" + }, + 'oldsearch': { + 'search': '{tag[shortcuturl]} = {tag[href]} #{tag.string}', + }, + 'bookmark': { + 'bookmark': '{tag[href]} {tag.string}', + 'keyword': '{tag[href]} {tag.string}' + }, + 'quickmark': { + 'bookmark': '{tag.string} {tag[href]}', + 'keyword': '{tag[shortcuturl]} {tag[href]}' + } + } bookmarks = [] - for tag in html_tags: - if tag['href'] not in bookmarks: - bookmarks.append(output_template.format(tag=tag)) - + for typ in bookmark_types: + tags = soup.findAll(bookmark_query[typ]) + for tag in tags: + if typ == 'search': + tag['href'] = search_escape(tag['href']).replace('%s', '{}') + if tag['href'] not in bookmarks: + bookmarks.append( + output_template[output_format][typ].format(tag=tag)) for bookmark in bookmarks: print(bookmark)