Annotate Vivaldi Bookmarks

Copying Properties      Importing Bookmarks      Installation      Usage      Options      Log File      Technical Notes


Script annotate_vivaldi_bookmarks.pl copies bookmark properties from a Firefox bookmarks HTML file to existing Vivaldi bookmarks, even if their folder paths are different.  It includes properties omitted by Vivaldi's Bookmark Import, including Descriptions, Nicknames, Tags,  and Separators.  It supports some conventions for copying Firefox Tags to Nicknames and/or Descriptions (see Firefox Tags below). The log file lists the changes made and those that failed.  Log entries for failures include property values that you can copy/paste into bookmarks manually if desired.

The script works by modifying a Vivaldi profile's Bookmarks file (JSON format).  It first makes a dated backup copy of the Bookmarks file, then replaces it.  To undo the script's changes, you can copy the backup Bookmarks file into your Vivaldi profile.

Scenario 1 - Copying Properties

In 2019, before Firefox abandoned support for Bookmark Descriptions, I saved mine by exporting a Firefox HTML Bookmarks file.  Subsequently in Firefox I added, deleted, and reorganized various bookmarks.  Eventually I imported the new bookmarks tree into Vivaldi (losing Separators), and made further additions and changes (including Descriptions and Nicknames).  Now I wanted to restore the Descriptions etc. from the old HTML file into my current Vivaldi bookmarks, wherever they may be in the current bookmarks tree.

That is the purpose of this script.  Steps are as follows:

Dry run:

  1. Run the script on the <bookmarks>.html file and the <profile>/Bookmarks file, with -preview and -trees options.  You can also specify -backup to make an initial backup copy of the <profile>/Bookmarks JSON  file.
  2. Review the resulting log file to see what changes would be made and what changes cannot be made.
  3. The log also shows the UPDATED JSON Tree Structure and the incoming HTML Tree Structure, which you can compare for placement of added separators.
Full run:
  1. Exit Vivaldi, all profiles, to flush any cached data.
  2. Run the script again without the -preview option.
  3. Restart Vivaldi, and review the bookmarks to decide whether you want to keep the changes.
  4. Edit bookmarks and separators as needed, based on WARNINGs, NOTEs, and search markers in the log file.

If you want to back out the changes entirely:

  1. Exit Vivaldi, all profiles.
  2. In the directory where you ran the script, copy the backed-up Bookmarks file into the Vivaldi profile.  For example (on Windows):
    > copy "Default\Checkpoints\Bookmarks 2021-02-25 1755" "%LOCALAPPDATA%\Vivaldi\User Data\Default\Bookmarks"
  3. Restart Vivaldi and check that the bookmarks have been restored.

Scenario 2 - Importing Bookmarks

If you want to import a Bookmarks HTML file complete with Descriptions and/or Separators etc, this script cannot do that.  However, you can use Vivaldi to import the HTML Bookmarks file (Folders, Bookmarks, URLs, Favicons), and then run this script to finish the job:

  1. Edit any desired adjustments into the <bookmarks>.html file (such as Personal Toolbar Folder).
  2. In Vivaldi, File > Import Bookmarks and Settings > Bookmarks HTML File, and choose the file.
  3. Note the name of the folder where the bookmarks were imported, normally Imported, or Imported (1), etc.
  4. Exit Vivaldi, all profiles, to flush any cached data.
  5. Run the script as described in Scenario 1, adding the -root option to specify the name of the import folder to be updated, e.g. -root "Imported (1)".
  6. Restart Vivaldi and review the bookmarks.

Note that Vivaldi Import from a Firefox installation works a little differently.  It fills in HTML Meta Descriptions by querying the URL in each bookmark.  That can take a long time and may not be what you want.

Installation

  1. Download annotate_vivaldi_bookmarks.zip, which contains the script, libraries, and this document. 
  2. Create a directory in which to store the log file, temporary files, and backup copies of your Vivaldi Bookmarks JSON file.
  3. Unzip the downloaded zip file into that directory, or into another which is on your PATH..

To run the script you need a Perl interpreter and libraries.  The script has been tested on Windows 10 Home 20H2 with ActivePerl and Strawberry Perl, both of which include everything needed.  ActivePerl is also available for Linux and Mac.

Usage

Synopsis:
   Copies bookmark properties from a Firefox bookmarks HTML file to EXISTING
   Vivaldi bookmarks, including Descriptions, Nicknames, Tags, and Separators.

Usage:
   [perl [-S]] annotate_vivaldi_bookmarks.pl [options] <bookmarks>.html <profile>/Bookmarks

Options (One or two dashes.  Names may be abbreviated):

  -descriptions Update only Descriptions.       (Default: All four)
  -tags         Update only Tags.                ''
  -shortcuts    Update only Keywords/Shortcuts.  ''
  -separators   Update only Separators (<HR>).   ''

  -keep         Do not change existing property values; just add new ones.
  -append       Append new values to old if different.
  -replace      Replace existing property values with new (non-blank) values.
  -preview      Log changes that would  be made; Do not apply them.
  -backup       Back up Vivaldi Bookmarks file even in -preview mode.

  -root <name>  Root folder of tree to copy properties to.
  -log <file>   Log messages to file (Default: annotate_vivaldi_bookmarks.log).

  -details      Print more messages in the log.
  -trees        Log JSON and HTML tree structures.
  -debug [1]    Include debug output.
  -debug 2|3    Include more debug output.

  -quiet        Suppress console messages other than ERRORs and WARNINGs.
  -help         Print this usage message.
  -version      Print version information.

  If none of -descriptions, -tags, -shortcuts, or -separators is specified,
  the default is to do all four of them.

  Only one of -keep, -append, or -replace may be specified.

Arguments:
   <bookmarks>.html     Firefox HTML bookmarks file to be copied from.
   <profile>/Bookmarks  Bookmarks file to be updated in a Vivaldi profile.

Example (Windows):

The thirty warnings and notes in this example may seem like a lot, but it's only 2% compared to the number of changes made.

> set BOOKMARKS="%LOCALAPPDATA%\Vivaldi\User Data\Default\Bookmarks"
> set HTML="C:\Data\WWW\Checkpoints\GJS Bookmarks 2019-07-18 1732.html"
> perl -S  annotate_vivaldi_bookmarks.pl  -trees  %HTML%  %BOOKMARKS%

annotate_vivaldi_bookmarks.pl - Checking Vivaldi Profile Lock ...
annotate_vivaldi_bookmarks.pl - Backing up Vivaldi Bookmarks (JSON file) ...
annotate_vivaldi_bookmarks.pl - NOTE: 'Default/Bookmarks' backup copy is still current.
annotate_vivaldi_bookmarks.pl     (./Default/Checkpoints/Bookmarks 2021-02-25 1755).
annotate_vivaldi_bookmarks.pl - Reading JSON Bookmarks ...
annotate_vivaldi_bookmarks.pl - Processing HTML Bookmarks ...

annotate_vivaldi_bookmarks.pl - WARNING: Folder not found: New Bookmarks
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: TT18D: Formosa Oolong Choicest - 160g
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: TJ06: Bancha First Grade Organic - 100g
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: TJ31: Japanese Ku-Ki Ho-Ji Cha - 100g?
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: TJ31: Japanese Ku-Ki Ho-Ji Cha - 100g?
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: Interlotto.com
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: WU - Northeast Radar (NY)
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: NOAA - Cleveland Snow Forecast Map
annotate_vivaldi_bookmarks.pl - WARNING: Folder not found: * Geo Filters 30 x 36 x 2
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: Bill Wenzel Heating & A/C
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: Garage Door Track Options
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: Miller Dowel Company | Using Miller Dow...
annotate_vivaldi_bookmarks.pl - NOTE: Duplicate bookmarks: Jennifer L. Flanagan
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: Men's Dress Pants at Lands' End
annotate_vivaldi_bookmarks.pl - NOTE: Duplicate bookmarks: Ryobi Outdoor Products :: Pruner Attac...
annotate_vivaldi_bookmarks.pl - NOTE: Duplicate bookmarks: Trim Saw Circular Saw - 5 1/2" Trim Sa...
annotate_vivaldi_bookmarks.pl - NOTE: Duplicate bookmarks: Twist Locks
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: Boch Honda West - Service
annotate_vivaldi_bookmarks.pl - NOTE: Duplicate bookmarks: Michelin
annotate_vivaldi_bookmarks.pl - WARNING: Folder not found: Visited Links Background
annotate_vivaldi_bookmarks.pl - WARNING: Folder not found: Batteries - Disposal
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: Luigi Cherubini, Hausmusik London - Che...
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: About Config
annotate_vivaldi_bookmarks.pl - WARNING: Folder not unique: Forums
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: CT-80 Thermostat - Provisioning
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: Using the viewport meta tag to control ...
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: CPU Widgets - Apps on Google Play
annotate_vivaldi_bookmarks.pl - NOTE: Bookmark has moved: Coffee Terms - Cupping and Tasting
annotate_vivaldi_bookmarks.pl - WARNING: Bookmark not found: d some

annotate_vivaldi_bookmarks.pl - Writing JSON Bookmarks ...
annotate_vivaldi_bookmarks.pl - Copying JSON Bookmarks to Vivaldi Profile ...

annotate_vivaldi_bookmarks.pl - Checked 12,372 bookmarks and 2,571 folders in 13 seconds.
annotate_vivaldi_bookmarks.pl - Updated 790 Descriptions, 6 Shortcuts, and 0 Tags.
annotate_vivaldi_bookmarks.pl - Checked 1,037 Separators, added 997.  23 were already present.
annotate_vivaldi_bookmarks.pl - Logged 16 WARNINGs and 14 NOTEs.
annotate_vivaldi_bookmarks.pl - For details see 'annotate_vivaldi_bookmarks.log'.

Options

Command-line options may be specified using one or two dashes, and may be abbreviated to any unique prefix.  For example, -v , --V, --version, and -VE are all equivalent.

Update Options

The following options apply to bookmarks and folders, but not to separators:

Logging Options

Console Message Options

The Log File

The purpose of the log file is to show all updates (for review), and to show the data for failed updates so that you can edit them manually in Vivaldi using copy/paste.  Each script execution appends to the log file, so you may want to clean it out or delete it occasionally.

Bookmarks and Folders

Each log entry includes messages, the bookmark/folder path(s), bookmark URL, and properties.  The log uses the following notations to help you make any manual corrections needed in Vivaldi:

WARNING: Describes changes that could not be made.
NOTE: Provides information such as alternatives chosen.
x Marks old/removed values.
> Marks new/added values.
+++++ Marker between an old value and an appended new value.  Use this string in a Vivaldi Bookmarks search to find bookmarks/folders which need to be edited.

Example log entry for a bookmark updated with Tags appended to Description:

NOTE: Tags copied to Description.
UPDATED Bookmark:
  Bookmarks > Export Test > CRB | Classical 99.5
  https://www.classicalwcrb.org/#stream/0
  Date Added:  21 Jan 2021, 6:14:28 PM
  Nickname:    wcrb
x Description: WCRB Classical 99.5
x              Tags = WCRB, FM, Radio, PBS
x              TV stations are WGBH (2) and WGBX (44)
> Description: WCRB Classical 99.5
>              Tags = WCRB, FM, Radio, PBS
>              TV stations are WGBH (2) and WGBX (44)
>              +++++
>              TAGS: WCRB,FM,Radio,PBS,Boston

Example log entry for a bookmark found at a different folder path, with a Description added:

NOTE: Bookmark has moved: Coffee Terms - Cupping and Tasting
UPDATED Bookmark:
x Bookmarks > Other Bookmarks > Coffee Terms - Cupping and Tasting
> Bookmarks > Home > Food / Cooking > Coffee > Coffee Terms - Cupping and Tasting
  http://www.zecuppa.com/coffeeterms-cupping-tasting.htm
  Date Added:  06 Sep 2018, 9:47:17 AM
> Description: Coffee Terms
>              Cupping, Tasting
>              Coffee term descriptions and illustrations

Example log entry for a bookmark no longer in the Vivaldi Bookmarks file, whose Description therefore could not be updated:

WARNING: Bookmark not found: About Config
  Bookmarks > Bookmarks Toolbar > Pages > About Config
  about:config
  Date Added:  07 Dec 2008, 4:46:47 PM
  Description: Firefox Advanced Configuration
Could not update bookmark properties.

Example log entry for an HTML folder which could not be uniquely matched to a Vivaldi folder, and therefore its separators were not copied:

WARNING: Folder not unique: Forums
  Bookmarks > Bookmarks Toolbar > Search > Forums
Could not add separators in this folder.
Possible Match:
  Bookmarks > Toad Hall Home Page > Forums
  Date Added:  27 Nov 2020, 8:09:12 PM
Possible Match:
  Bookmarks > Electronics - Audio > CD/DVD Changer > Forums
  Date Added:  27 Nov 2020, 8:09:17 PM

Separators

The log shows separators in the three Tree Structures (-trees option) as follows:

--- Existing separators in -preview mode; all separators if updating Vivaldi.
---------- Added separators in -preview mode.
---+++++--- Added separators which could not be definitively placed (so that you can search for them easily in Vivaldi).

To review separator positioning, run the script with the -preview and -trees option, and compare the HTML Tree Structure with the UPDATED JSON Tree Structure in the log file.  After updating Vivaldi, you can search Bookmarks for '---+++++---'.  (Searching for '---' shows all separators, which seems weird, but that's their internal name.)

Example log entry for separators added above duplicate bookmarks (same Name, URL, and Date Added), and the resulting Updated Tree structure:

NOTE: Duplicate bookmarks: Jennifer L. Flanagan
  Bookmarks > Home > Green Energy > Legislators > Ways & Means > Jennifer L. Flanagan
  https://malegislature.gov/people/profile/jlf0
  Date Added:  16 Jan 2015, 2:09:14 PM
Added a separator above each of 2 duplicate bookmarks in this folder.

2/25/2021  6:51:06 PM  UPDATED JSON Tree Structure:
  Bookmarks >
  |   ...
  |   Home >
  |   |   ...
  |   |   Green Energy >
  |   |   |   ...
  |   |   |   Legislators >
  |   |   |   |   Ways & Means >
  |   |   |   |   |   Joint Committee on Ways and Means
  |   |   |   |   |   Stephen M. Brewer
  |   |   |   |   |   Brian S. Dempsey
  |   |   |   |   |   ---+++++---
  |   |   |   |   |   Jennifer L. Flanagan
  |   |   |   |   |   Stephen Kulik
  |   |   |   |   |   ---+++++---
  |   |   |   |   |   Jennifer L. Flanagan
  |   |   |   |   |   Stephen Kulik
  |   |   |   |   |   Jennifer L. Flanagan
  |   |   |   |   |   Stephen Kulik
  |   |   |   |   |   Jennifer L. Flanagan
  |   |   |   |   |   Stephen Kulik

Technical Notes

Personal Toolbar Folder

If an HTML folder has attribute PERSONAL_TOOLBAR_FOLDER="true", then Vivaldi imports the folder at the top level (under Imported rather than under Imported/Bookmarks).  This script then reports those bookmarks/folders as "moved".  You can prevent that by editing the HTML file and removing the PERSONAL_TOOLBAR_FOLDER attribute before importing the HTML into Vivaldi.  Or you can move the folder back to its desired location in Vivaldi after importing the HTML and before running this script.

Bookmark/Folder Matching

The script attempts to match bookmarks from the HTML with identical bookmarks in Vivaldi, even if they have been moved to a different folder path.  It compares Date Added, URL, Name, and shortest unique tail sub-path (... > Grandparent > Parent > Bookmark).  The script does not match bookmarks which have been renamed or whose URLs have changed (names are case-sensitive; URLs are not).  The algorithm works about as well as could be expected. 

For example, if the HTML file contains bookmarks:

And those bookmarks in Vivaldi have been moved and others added, so that they now include:

Then the script will match up the tail sub-path 'Radio > FM > WGBH' for the first, and 'TV > WGBH' for the second. 

The script reports properties of HTML bookmarks for which it cannot find a unique match, so that you can search for them in Vivaldi and then copy/paste the information if successful.  See The Log File.

If a folder contains duplicate (identical) bookmarks, then the script updates all of them with the same property values.

Separator Positioning

The code for copying separators is not as precise as the bookmark/folder matching, but further code improvements seem to provide diminishing returns.

The script inserts separators by searching for the item (bookmark, folder or end of list) which follows the separator in the corresponding JSON folder.  If the item before that is not already a separator, then the script inserts one.  The script matches bookmarks by Name, and either Date Added or URL or both.  It matches Folders by Name only, since Date Added is often the date/time of import and there is no URL.

This approach works fairly well in folders which have not been rearranged (much).  If the item following a separator has been moved, then a separator will still be added above it.  If the item no longer exists, no separator will be added.  If the folder contains duplicate copies of the item, and none of them is already preceded by a separator, then a separator will be added above each one.  Details are in the log file

Firefox Tags

Vivaldi bookmarks do not support Tags.  This script copies Firefox Tags into either Nickname of Description, depending on what is already there, so that the Tags can be used in searches.

Replacing the Bookmarks JSON File

Vivaldi stores bookmarks in a JSON format file named Bookmarks in a Vivaldi profile.  It can be easily replaced, but Vivaldi usually ignores any modified version and restores the previous bookmarks.  One difficulty is that the file contains a checksum entry which is essentially impossible to recalculate for modified contents.  In order for Vivaldi to read the new Bookmarks file in a profile, all of the following must be true:

If a Vivaldi session using the profile has been started, it is not sufficient to exit just that profile.  Apparently Vivaldi caches a profile's bookmarks until Vivaldi exits completely. 

This script checks all of these conditions and replaces the Bookmarks file automatically.