├── .github └── workflows │ └── main.yaml ├── .gitignore ├── LICENSE.md ├── Makefile ├── README.md ├── export-chrome-bookmarks ├── export-chrome-history ├── man_pages ├── export-chrome-bookmarks.1 ├── export-chrome-bookmarks.md ├── export-chrome-history.1 └── export-chrome-history.md └── test ├── Bookmarks ├── History ├── bookmarks_expected_output.html ├── history_expected_output.html └── run_tests /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | - push 4 | - pull_request 5 | jobs: 6 | test: 7 | name: Python ${{ matrix.python-version }} (${{ matrix.os }}) 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: 12 | - windows-latest 13 | - ubuntu-latest 14 | - ubuntu-18.04 15 | - macos-latest 16 | - macos-10.15 17 | python-version: 18 | - "2.7" 19 | - "3.3" 20 | - "3.4" 21 | - "3.5" 22 | - "3.6" 23 | - "3.7" 24 | - "3.8" 25 | - "3.9" 26 | - "3.10" 27 | - "3.11.0-alpha.7" 28 | exclude: 29 | - python-version: "2.7" 30 | os: ubuntu-latest 31 | - python-version: "3.3" 32 | os: macos-latest 33 | - python-version: "3.3" 34 | os: macos-10.15 35 | - python-version: "3.3" 36 | os: ubuntu-latest 37 | - python-version: "3.4" 38 | os: ubuntu-latest 39 | - python-version: "3.4" 40 | os: macos-latest 41 | - python-version: "3.4" 42 | os: macos-10.15 43 | steps: 44 | - uses: actions/checkout@v2 45 | 46 | - name: Set up Python ${{ matrix.python-version }} 47 | uses: actions/setup-python@v2 48 | with: 49 | python-version: ${{ matrix.python-version }} 50 | 51 | - name: Confirm the Python version 52 | run: python --version 53 | 54 | - name: Run the test script 55 | run: test/run_tests 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test/bookmarks_actual_output.html 2 | test/history_actual_output.html 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The ISC License 2 | 3 | Copyright © 2011, 2017–2018 Benjamin D. Esham 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 6 | 7 | **The software is provided “as is” and the author disclaims all warranties with regard to this software including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, direct, indirect, or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software.** 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | man: 2 | pandoc --standalone --to man \ 3 | man_pages/export-chrome-bookmarks.md --output man_pages/export-chrome-bookmarks.1 4 | pandoc --standalone --to man \ 5 | man_pages/export-chrome-history.md --output man_pages/export-chrome-history.1 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chrome-export [![Build status](https://github.com/bdesham/chrome-export/actions/workflows/main.yaml/badge.svg)](https://github.com/bdesham/chrome-export/actions/workflows/main.yaml) 2 | 3 | *Formerly called py-chrome-bookmarks* 4 | 5 | Python scripts to convert [Google Chrome]’s bookmarks and history to the [standard HTML-ish bookmarks file format][format]. 6 | 7 | [Google Chrome]: http://www.google.com/chrome/ 8 | [format]: https://msdn.microsoft.com/en-us/library/aa753582(v=vs.85).aspx 9 | 10 | The functionality to do this for bookmarks is already built into Chrome (select Bookmarks → Bookmarks Manager, then click “Organize” and select “Export Bookmarks…”). I wrote this script to be able to perform this conversion in a cron script. 11 | 12 | ## Installation 13 | 14 | ### Homebrew 15 | 16 | If you have [Homebrew] installed, you can install these scripts with 17 | 18 | brew install chrome-export 19 | 20 | [Homebrew]: https://brew.sh 21 | 22 | ### Nix 23 | 24 | If you’re using the [Nix] package manager, run 25 | 26 | nix-env -i -A nixpkgs.chrome-export 27 | 28 | If you use NixOS, run 29 | 30 | nix-env -i -A nixos.chrome-export 31 | 32 | [Nix]: https://nixos.org/nix/ 33 | 34 | ### Manual installation 35 | 36 | Download the .zip or .tar.gz file for the [latest release], extract it, and move the `export-chrome-bookmarks` and/or `export-chrome-history` files to somewhere on your PATH. You may also want to move `export-chrome-bookmarks.1` and `export-chrome-history.1` from the `man_pages` directory to somewhere on your MANPATH (e.g. `/usr/local/share/man/man1`). 37 | 38 | [latest release]: https://github.com/bdesham/chrome-export/releases/latest 39 | 40 | ## Usage 41 | 42 | These scripts require Python, either version 2.7.x or else version 3.2 or later. They should work on Linux, macOS, and Windows. 43 | 44 | ### Bookmarks script 45 | 46 | The usage is 47 | 48 | export-chrome-bookmarks [input_file] output_file 49 | 50 | If you do not specify an input file, the script will try to open the default Chrome bookmarks file. 51 | 52 | The script will ignore URLs that start with “javascript:”. 53 | 54 | ### History script 55 | 56 | The usage is 57 | 58 | export-chrome-history [input_file] output_file 59 | 60 | If you do not specify an input file, the script will try to open the default Chrome history file. 61 | 62 | The script will ignore history entries with empty titles. 63 | 64 | ## Notes for developers 65 | 66 | To test changes to the scripts, run `bash test/run_tests`. This script runs both programs and verifies that their output is identical to what is expected. If you have already installed the programs somewhere and want to test those copies, run `bash test/run_tests /path/to/bin`, where `/path/to/bin` is the directory where export-chrome-bookmarks and export-chrome-history are located. 67 | 68 | The man pages are written in Markdown; run `make man` to use Pandoc to convert them into the man format. The generated versions are checked into Git so that users don’t have to install Pandoc. 69 | 70 | ## Version history 71 | 72 | * 2.0.2 (2019-06-15) 73 | - Added man pages and made the testing script more flexible. No changes to functionality. 74 | * 2.0.1 (2018-02-09) 75 | - Fixed an error that occurred when trying to open the default bookmarks file under Python 2.7. (Thanks [Hridoy Sankar Dutta](https://github.com/hridaydutta123)!) 76 | * 2.0 (2018-02-05) 77 | - Renamed the project from “py-chrome-bookmarks” to “chrome-export”; renamed “py-chrome-bookmarks.py” to “export-chrome-bookmarks”; and renamed “py-chrome-history.py” to “export-chrome-history”. There were no changes in functionality. 78 | * 1.2.1 (2017-06-02) 79 | - Fixed a Unicode decoding error under Windows 7. (Thanks [Boburmirzo Hamraqulov](https://github.com/bzimor)!) 80 | * 1.2 (2017-01-26) 81 | - Added support for Python 3, dropped support for Python 2.6 and earlier, and made this all clear in the readme. 82 | - Giving an input filename is now optional for both scripts. If you omit the input filename then the scripts will try to open Chrome’s bookmarks or history file automatically. 83 | - The history script now makes a copy of the input file before opening it. Previously, it was necessary either to make a copy yourself or to quit Chrome before running the script. (The history file is a SQLite database and it isn’t possible for two programs to have it open at the same time.) 84 | * 1.1 (2011-04-06) 85 | - Added help and version text (and started counting versions). 86 | - Added some checking for errors while opening the input or output files. 87 | * 1.0 88 | - Initial release 89 | 90 | ## Author 91 | 92 | These programs were created by [Benjamin Esham](https://esham.io). 93 | 94 | This project is [hosted on GitHub](https://github.com/bdesham/chrome-export). Please feel free to submit pull requests. 95 | 96 | ## License 97 | 98 | Copyright © 2011, 2017–2018 Benjamin D. Esham. This program is released under the ISC license, which you can find in the file LICENSE.md. 99 | -------------------------------------------------------------------------------- /export-chrome-bookmarks: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # export-chrome-bookmarks 4 | # 5 | # A script to convert Google Chrome's bookmarks file to the standard HTML-ish 6 | # format. 7 | # 8 | # Copyright (c) 2011, 2017-2018 Benjamin D. Esham. This program is released under the 9 | # ISC license, which you can find in the file LICENSE.md. 10 | 11 | from __future__ import print_function 12 | import argparse 13 | import io 14 | from json import loads 15 | from os import environ 16 | from os.path import expanduser 17 | from platform import system 18 | from re import match 19 | from sys import argv, stderr 20 | 21 | script_version = "2.0.2" 22 | 23 | # html escaping code from http://wiki.python.org/moin/EscapingHtml 24 | 25 | html_escape_table = { 26 | "&": "&", 27 | '"': """, 28 | "'": "'", 29 | ">": ">", 30 | "<": "<", 31 | } 32 | 33 | output_file_template = """ 34 | 35 | 36 | Bookmarks 37 |

Bookmarks

38 | 39 |

40 | 41 |

{bookmark_bar}
42 | 43 |
{other}
44 | """ 45 | 46 | def html_escape(text): 47 | return ''.join(html_escape_table.get(c,c) for c in text) 48 | 49 | def sanitize(string): 50 | res = '' 51 | string = html_escape(string) 52 | 53 | for i in range(len(string)): 54 | if ord(string[i]) > 127: 55 | res += '&#x{:x};'.format(ord(string[i])) 56 | else: 57 | res += string[i] 58 | 59 | return res 60 | 61 | def html_for_node(node): 62 | if 'url' in node: 63 | return html_for_url_node(node) 64 | elif 'children' in node: 65 | return html_for_parent_node(node) 66 | else: 67 | return '' 68 | 69 | def html_for_url_node(node): 70 | if not match("javascript:", node['url']): 71 | return '
{}\n'.format(sanitize(node['url']), sanitize(node['name'])) 72 | else: 73 | return '' 74 | 75 | def html_for_parent_node(node): 76 | return '

{}

\n

{}

\n'.format(sanitize(node['name']), 77 | ''.join([html_for_node(n) for n in node['children']])) 78 | 79 | 80 | # Parse the command-line arguments 81 | 82 | parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, 83 | description="Convert Google Chrome's bookmarks file to the standard HTML-based format.", 84 | epilog="(c) 2011, 2017-2018 Benjamin D. Esham\nhttps://github.com/bdesham/chrome-export") 85 | parser.add_argument("input_file", type=argparse.FileType('r'), nargs="?", 86 | help="The location of the Chrome bookmarks file to read. If this is omitted then the script will look for the file in Chrome's default location.") 87 | parser.add_argument("output_file", type=argparse.FileType('w'), 88 | help="The location where the HTML bookmarks file will be written.") 89 | parser.add_argument("-v", "--version", action="version", 90 | version="export-chrome-bookmarks {}".format(script_version)) 91 | 92 | args = parser.parse_args() 93 | 94 | # Determine where the input file is 95 | 96 | if args.input_file: 97 | input_file = args.input_file 98 | else: 99 | if system() == "Darwin": 100 | input_filename = expanduser("~/Library/Application Support/Google/Chrome/Default/Bookmarks") 101 | elif system() == "Linux": 102 | input_filename = expanduser("~/.config/google-chrome/Default/Bookmarks") 103 | elif system() == "Windows": 104 | input_filename = environ["LOCALAPPDATA"] + r"\Google\Chrome\User Data\Default\Bookmarks" 105 | else: 106 | print('Your system ("{}") is not recognized. Please specify the input file manually.'.format(system())) 107 | exit(1) 108 | 109 | try: 110 | input_file = io.open(input_filename, 'r', encoding='utf-8') 111 | except IOError as e: 112 | if e.errno == 2: 113 | print("The bookmarks file could not be found in its default location ({}). ".format(e.filename) + 114 | "Please specify the input file manually.") 115 | exit(1) 116 | 117 | # Read, convert, and write the bookmarks 118 | 119 | contents = loads(input_file.read()) 120 | input_file.close() 121 | 122 | bookmark_bar = html_for_node(contents['roots']['bookmark_bar']) 123 | other = html_for_node(contents['roots']['other']) 124 | 125 | args.output_file.write(output_file_template.format(bookmark_bar=bookmark_bar, other=other)) 126 | args.output_file.close() 127 | -------------------------------------------------------------------------------- /export-chrome-history: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # export-chrome-history 4 | # 5 | # A script to convert Google Chrome's history file to the standard HTML-ish 6 | # bookmarks file format. 7 | # 8 | # Copyright (c) 2011, 2017-2018 Benjamin D. Esham. This program is released under the 9 | # ISC license, which you can find in the file LICENSE.md. 10 | 11 | from __future__ import print_function 12 | import argparse 13 | from os import environ 14 | from os.path import expanduser, join 15 | from platform import system 16 | from shutil import copy, rmtree 17 | import sqlite3 18 | from sys import argv, stderr 19 | from tempfile import mkdtemp 20 | 21 | script_version = "2.0.2" 22 | 23 | # html escaping code from http://wiki.python.org/moin/EscapingHtml 24 | 25 | html_escape_table = { 26 | "&": "&", 27 | '"': """, 28 | "'": "'", 29 | ">": ">", 30 | "<": "<", 31 | } 32 | 33 | output_file_template = """ 34 | 35 | 36 | Bookmarks 37 |

Bookmarks

38 | 39 |

40 | 41 |

History

42 | 43 |

{items}

\n
""" 44 | 45 | def html_escape(text): 46 | return ''.join(html_escape_table.get(c,c) for c in text) 47 | 48 | def sanitize(string): 49 | res = '' 50 | string = html_escape(string) 51 | 52 | for i in range(len(string)): 53 | if ord(string[i]) > 127: 54 | res += '&#x{:x};'.format(ord(string[i])) 55 | else: 56 | res += string[i] 57 | 58 | return res 59 | 60 | 61 | # Parse the command-line arguments 62 | 63 | parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, 64 | description="Convert Google Chrome's history file to the standard HTML-based format.", 65 | epilog="(c) 2011, 2017-2018 Benjamin D. Esham\nhttps://github.com/bdesham/chrome-export") 66 | parser.add_argument("input_file", nargs="?", 67 | help="The location of the Chrome history file to read. If this is omitted then the script will look for the file in Chrome's default location.") 68 | parser.add_argument("output_file", type=argparse.FileType('w'), 69 | help="The location where the HTML bookmarks file will be written.") 70 | parser.add_argument("-v", "--version", action="version", 71 | version="export-chrome-history {}".format(script_version)) 72 | 73 | args = parser.parse_args() 74 | 75 | # Determine where the input file is 76 | 77 | if args.input_file: 78 | input_filename = args.input_file 79 | else: 80 | if system() == "Darwin": 81 | input_filename = expanduser("~/Library/Application Support/Google/Chrome/Default/History") 82 | elif system() == "Linux": 83 | input_filename = expanduser("~/.config/google-chrome/Default/History") 84 | elif system() == "Windows": 85 | input_filename = environ["LOCALAPPDATA"] + r"\Google\Chrome\User Data\Default\History" 86 | else: 87 | print('Your system ("{}") is not recognized. Please specify the input file manually.'.format(system())) 88 | exit(1) 89 | 90 | try: 91 | input_file = open(input_filename, 'r') 92 | except IOError as e: 93 | if e.errno == 2: 94 | print("The history file could not be found in its default location ({}). ".format(e.filename) + 95 | "Please specify the input file manually.") 96 | exit(1) 97 | else: 98 | input_file.close() 99 | 100 | # Make a copy of the database, open it, process its contents, and write the 101 | # output file 102 | 103 | temp_dir = mkdtemp(prefix='export-chrome-history-') 104 | copied_file = join(temp_dir, 'History') 105 | copy(input_filename, copied_file) 106 | 107 | try: 108 | connection = sqlite3.connect(copied_file) 109 | except sqlite3.OperationalError: 110 | # This error message is a *little* misleading, since the problem actually 111 | # occurred when we tried to open copied_file, but chances are that if we got 112 | # to this point then the problem lies with the file itself (e.g. it isn't a 113 | # valid SQLite database), not with our ability to read the file. 114 | print('The file "{}" could not be opened for reading.'.format(input_filename)) 115 | rmtree(temp_dir) 116 | exit(1) 117 | 118 | curs = connection.cursor() 119 | 120 | try: 121 | curs.execute("SELECT url, title FROM urls") 122 | except sqlite3.OperationalError: 123 | print('There was an error reading data from the file "{}".'.format(args.input_file)) 124 | rmtree(temp_dir) 125 | exit(1) 126 | 127 | items = "" 128 | for row in curs: 129 | if len(row[1]) > 0: 130 | items += '
{}\n'.format(sanitize(row[0]), sanitize(row[1])) 131 | 132 | connection.close() 133 | rmtree(temp_dir) 134 | 135 | args.output_file.write(output_file_template.format(items=items)) 136 | args.output_file.close() 137 | -------------------------------------------------------------------------------- /man_pages/export-chrome-bookmarks.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 2.9.2.1 2 | .\" 3 | .TH "EXPORT-CHROME-BOOKMARKS" "1" "" "chrome-export" "" 4 | .hy 5 | .SH NAME 6 | .PP 7 | \f[B]export-chrome-bookmarks\f[R] \[en] convert Google Chrome\[cq]s 8 | bookmarks to the standard bookmarks file format 9 | .SH SYNOPSIS 10 | .PP 11 | \f[B]export-chrome-bookmarks\f[R] \f[C][input_file] output_file\f[R] 12 | .SH OPTIONS 13 | .TP 14 | \f[B]\f[CB]input_file\f[B]\f[R] 15 | The Chrome bookmarks file to read. 16 | If you do not specify one, the script will try to locate and use the 17 | default Chrome bookmarks file. 18 | .TP 19 | \f[B]\f[CB]output_file\f[B]\f[R] 20 | The path where the bookmarks file will be written. 21 | .SH DESCRIPTION 22 | .PP 23 | This script will read the given bookmarks file (attempting to discover 24 | it first, if necessary) and then write these bookmarks in the standard 25 | HTML-ish format described at 26 | . 27 | .PP 28 | Any bookmarks whose URLs start with \[lq]javascript:\[rq] will be 29 | ignored. 30 | .SH EXIT STATUS 31 | .PP 32 | export-chrome-bookmarks will return zero if it successfully reads and 33 | writes the bookmarks files. 34 | It will return a nonzero code otherwise. 35 | .SH AUTHOR 36 | .PP 37 | This program was created by Benjamin Esham (https://esham.io). 38 | .SH PROJECT 39 | .PP 40 | This script is part of the chrome-export project, which is hosted at 41 | . 42 | .SH LICENSE 43 | .PP 44 | Copyright \[co] 2011, 2017\[en]2018 Benjamin D.\ Esham. 45 | This program is released under the ISC license, which you can find at 46 | . 47 | -------------------------------------------------------------------------------- /man_pages/export-chrome-bookmarks.md: -------------------------------------------------------------------------------- 1 | % EXPORT-CHROME-BOOKMARKS(1) chrome-export 2 | 3 | # NAME 4 | 5 | **export-chrome-bookmarks** -- convert Google Chrome's bookmarks to the standard bookmarks file format 6 | 7 | # SYNOPSIS 8 | 9 | **export-chrome-bookmarks** `[input_file] output_file` 10 | 11 | # OPTIONS 12 | 13 | `input_file` 14 | : The Chrome bookmarks file to read. If you do not specify one, the script will try to locate and use the default Chrome bookmarks file. 15 | 16 | `output_file` 17 | : The path where the bookmarks file will be written. 18 | 19 | # DESCRIPTION 20 | 21 | This script will read the given bookmarks file (attempting to discover it first, if necessary) and then write these bookmarks in the standard HTML-ish format described at . 22 | 23 | Any bookmarks whose URLs start with "javascript:" will be ignored. 24 | 25 | # EXIT STATUS 26 | 27 | export-chrome-bookmarks will return zero if it successfully reads and writes the bookmarks files. It will return a nonzero code otherwise. 28 | 29 | # AUTHOR 30 | 31 | This program was created by Benjamin Esham (https://esham.io). 32 | 33 | # PROJECT 34 | 35 | This script is part of the chrome-export project, which is hosted at . 36 | 37 | # LICENSE 38 | 39 | Copyright © 2011, 2017–2018 Benjamin D.\ Esham. This program is released under the ISC license, which you can find at . 40 | -------------------------------------------------------------------------------- /man_pages/export-chrome-history.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 2.9.2.1 2 | .\" 3 | .TH "EXPORT-CHROME-HISTORY" "1" "" "chrome-export" "" 4 | .hy 5 | .SH NAME 6 | .PP 7 | \f[B]export-chrome-history\f[R] \[en] convert Google Chrome\[cq]s 8 | history to the standard bookmarks file format 9 | .SH SYNOPSIS 10 | .PP 11 | \f[B]export-chrome-history\f[R] \f[C][input_file] output_file\f[R] 12 | .SH OPTIONS 13 | .TP 14 | \f[B]\f[CB]input_file\f[B]\f[R] 15 | The Chrome history file to read. 16 | If you do not specify one, the script will try to locate and use the 17 | default Chrome history file. 18 | .TP 19 | \f[B]\f[CB]output_file\f[B]\f[R] 20 | The path where the bookmarks file will be written. 21 | .SH DESCRIPTION 22 | .PP 23 | This script will read the given history file (attempting to discover it 24 | first, if necessary) and then write all of the entries in the standard 25 | HTML-ish bookmarks file format described at 26 | . 27 | .PP 28 | The script will ignore history entries with empty titles. 29 | .SH EXIT STATUS 30 | .PP 31 | export-chrome-history will return zero if it successfully reads the 32 | history file and writes the bookmarks file. 33 | It will return a nonzero code otherwise. 34 | .SH AUTHOR 35 | .PP 36 | This program was created by Benjamin Esham (https://esham.io). 37 | .SH PROJECT 38 | .PP 39 | This script is part of the chrome-export project, which is hosted at 40 | . 41 | .SH LICENSE 42 | .PP 43 | Copyright \[co] 2011, 2017\[en]2018 Benjamin D.\ Esham. 44 | This program is released under the ISC license, which you can find at 45 | . 46 | -------------------------------------------------------------------------------- /man_pages/export-chrome-history.md: -------------------------------------------------------------------------------- 1 | % EXPORT-CHROME-HISTORY(1) chrome-export 2 | 3 | # NAME 4 | 5 | **export-chrome-history** -- convert Google Chrome's history to the standard bookmarks file format 6 | 7 | # SYNOPSIS 8 | 9 | **export-chrome-history** `[input_file] output_file` 10 | 11 | # OPTIONS 12 | 13 | `input_file` 14 | : The Chrome history file to read. If you do not specify one, the script will try to locate and use the default Chrome history file. 15 | 16 | `output_file` 17 | : The path where the bookmarks file will be written. 18 | 19 | # DESCRIPTION 20 | 21 | This script will read the given history file (attempting to discover it first, if necessary) and then write all of the entries in the standard HTML-ish bookmarks file format described at . 22 | 23 | The script will ignore history entries with empty titles. 24 | 25 | # EXIT STATUS 26 | 27 | export-chrome-history will return zero if it successfully reads the history file and writes the bookmarks file. It will return a nonzero code otherwise. 28 | 29 | # AUTHOR 30 | 31 | This program was created by Benjamin Esham (https://esham.io). 32 | 33 | # PROJECT 34 | 35 | This script is part of the chrome-export project, which is hosted at . 36 | 37 | # LICENSE 38 | 39 | Copyright © 2011, 2017–2018 Benjamin D.\ Esham. This program is released under the ISC license, which you can find at . 40 | -------------------------------------------------------------------------------- /test/Bookmarks: -------------------------------------------------------------------------------- 1 | { 2 | "checksum": "ad0ce68d821c76e5336c223ab5bb634f", 3 | "roots": { 4 | "bookmark_bar": { 5 | "children": [ { 6 | "date_added": "13129578793533581", 7 | "id": "9", 8 | "name": "Google", 9 | "type": "url", 10 | "url": "https://www.google.com/" 11 | }, { 12 | "date_added": "13129578805136275", 13 | "id": "10", 14 | "name": "Washington Post", 15 | "type": "url", 16 | "url": "https://www.washingtonpost.com/" 17 | } ], 18 | "date_added": "13129345492533809", 19 | "date_modified": "13129578842701587", 20 | "id": "1", 21 | "name": "Bookmarks Bar", 22 | "type": "folder" 23 | }, 24 | "other": { 25 | "children": [ { 26 | "date_added": "13129578818718337", 27 | "id": "11", 28 | "name": "GitHub", 29 | "type": "url", 30 | "url": "https://github.com/" 31 | }, { 32 | "date_added": "13129345498905796", 33 | "id": "6", 34 | "name": "HBO NOW", 35 | "type": "url", 36 | "url": "https://www.hbonow.com/" 37 | }, { 38 | "date_added": "13129578826613783", 39 | "id": "12", 40 | "name": "Vim", 41 | "type": "url", 42 | "url": "http://www.vim.org/" 43 | }, { 44 | "date_added": "13129777099514435", 45 | "id": "15", 46 | "name": "维基百科,自由的百科全书", 47 | "type": "url", 48 | "url": "https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5" 49 | } ], 50 | "date_added": "13129345492533817", 51 | "date_modified": "13129777099514435", 52 | "id": "2", 53 | "name": "Other Bookmarks", 54 | "type": "folder" 55 | }, 56 | "synced": { 57 | "children": [ ], 58 | "date_added": "13129345492533820", 59 | "date_modified": "0", 60 | "id": "3", 61 | "name": "Mobile Bookmarks", 62 | "type": "folder" 63 | } 64 | }, 65 | "version": 1 66 | } 67 | -------------------------------------------------------------------------------- /test/History: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdesham/chrome-export/173f41c2ee162a7aaa31637df9c009167bb49ede/test/History -------------------------------------------------------------------------------- /test/bookmarks_expected_output.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bookmarks 5 |

Bookmarks

6 | 7 |

8 | 9 |

Bookmarks Bar

10 |

Google 11 |
Washington Post 12 |

13 |

14 | 15 |

Other Bookmarks

16 |

GitHub 17 |
HBO NOW 18 |
Vim 19 |
维基百科,自由的百科全书 20 |

21 |

22 | -------------------------------------------------------------------------------- /test/history_expected_output.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bookmarks 5 |

Bookmarks

6 | 7 |

8 | 9 |

History

10 | 11 |

welcome home : vim online 12 |
How people build software · GitHub 13 |
Google 14 |
Home | HBO NOW 15 |
Washington Post: Breaking News, World, US, DC News & Analysis - The Washington Post 16 |
Chrome Web Store 17 |
维基百科,自由的百科全书 18 |
维基百科:分類索引 - 维基百科,自由的百科全书 19 |

20 |
-------------------------------------------------------------------------------- /test/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: bash run_tests [install_dir] 4 | # 5 | # This script tests export-chrome-bookmarks and export-chrome-history. The 6 | # optional install_dir parameter specifies the directory in which these two 7 | # scripts should be found; the default value is the parent directory of this 8 | # test script. If a relative path is given, it will be interpreted relative to 9 | # the parent directory of this test script. 10 | 11 | failed=0 12 | 13 | cd "$(cd "$(dirname "$0")"; pwd -P)/.." 14 | 15 | bin="${1:-.}" 16 | 17 | $bin/export-chrome-bookmarks test/Bookmarks test/bookmarks_actual_output.html 18 | cmp -s test/bookmarks_expected_output.html test/bookmarks_actual_output.html 19 | 20 | if [[ $? -ne 0 ]]; then 21 | echo "The bookmarks script produced unexpected output:" 22 | diff test/bookmarks_expected_output.html test/bookmarks_actual_output.html 23 | failed=1 24 | fi 25 | 26 | $bin/export-chrome-history test/History test/history_actual_output.html 27 | cmp -s test/history_expected_output.html test/history_actual_output.html 28 | 29 | if [[ $? -ne 0 ]]; then 30 | echo "The history script produced unexpected output:" 31 | diff test/history_expected_output.html test/history_actual_output.html 32 | failed=1 33 | fi 34 | 35 | if [[ "$failed" == "1" ]]; then 36 | exit 1 37 | fi 38 | --------------------------------------------------------------------------------