-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: back-convert from JSON/db format to Chrome/Firefox format #115
Comments
Below is a script that actually works that will convert from the universal JSON format back into Chrome format to directly replace the Chrome Bookmarks file. It expects to have a copy of #!/usr/bin/env python3
import glob
import json
import os
import re
import time
from bookmarks_converter import BookmarksConverter
bmc = BookmarksConverter('Bookmarks')
bmc.parse('json')
bmc.convert('json')
bmc.save()
universal_json = json.dumps(bmc.bookmarks, indent=2)
# Override bookmarks_converter's automatic file creation when not using cli:
for f in glob.glob("output*"):
os.remove(f)
# Start creating new dict for new Bookmarks file:
"""
No need to populate 'checksum' or 'guid', as these values are automatically-generated by Chrome
when it starts. They will mess up everything, and the bookmarks will not load correctly.
"""
# top-level
chrome_dict = {
# [NO checksum]
'roots': {},
# [NO sync_metadata]
'version': 1
}
# add the 3 top-level roots:
chrome_dict['roots'] = {
'bookmark_bar': {
'children': [],
'date_added': round(time.time() * 1000),
'date_modified': 0,
# [NO guid]
'id': '1',
'name': 'Bookmarks bar',
'type': 'folder'
},
'other': {
'children': [],
'date_added': round(time.time() * 1000),
'date_modified': 0,
# [NO guid]
'id': '2',
'name': 'Other Bookmarks',
'type': 'folder'
},
'synced': {
'children': [],
'date_added': round(time.time() * 1000),
'date_modified': 0,
# [NO guid],
'id': '3',
'name': 'Mobile Bookmarks',
'type': 'folder'
}
}
# Convert universal_json to Chrome format:
lines = []
for line in universal_json.split('\n'):
# convert id integer back into string
if '"id":' in line:
line = re.sub(r'(.*"id": )(\d+)(.*)', r'\1"\2"\3', line)
# replace "title" with "name"
elif '"title":' in line:
line = line.replace('"title":', '"name":')
# replace "iconuri" with "icon_uri"
elif '"iconuri":' in line:
line = line.replace('"iconuri":', '"icon_uri":')
lines.append(line)
chrome_format = '\n'.join(lines)
# Update new dict with children:
new_chrome_dict = json.loads(chrome_format)
roots = new_chrome_dict['children']
bookmarks_bar = roots[0]['children']
other_bookmarks = roots[1]['children']
mobile_bookmarks = roots[2]['children']
chrome_dict['roots']['bookmark_bar']['children'] = bookmarks_bar
chrome_dict['roots']['other']['children'] = other_bookmarks
chrome_dict['roots']['synced']['children'] = mobile_bookmarks
new_bookmarks = json.dumps(chrome_dict, indent=2)
# Write new Bookmarks file:
with open('Bookmarks_New.json', 'w') as f:
f.write(new_bookmarks)
"""
In the shell, overwrite the old Bookmarks file with the
newly-generated Chrome-formatted JSON Bookmarks file:
cp Bookmarks_New.json ~/.config/google-chrome/Profile\ [profile_number_here]/Bookmarks
Re-open Chrome, and it will be populated with the bookmarks that were converted
from the bookmarks-converter JSON file back into the JSON format that Chrome recognizes.
""" |
This sounds like a good feature, but unfortunately I do not have enough time at the moment to to implement, test and document the change. |
I needed this functionality and wrote bkmk in the meantime. It also fixes some roundtripping bugs I noticed with this package, e.g. as documented here. @phx For your use case of importing into Chrome internal profile directly, you'll want to run something like |
support for exporting bookmarks as Chrome html/json and Firefox html/json has been implemented in #210 |
This is a feature request to implement converting back to Chrome or Firefox-formatted JSON from the currently-implemented JSON and/or sqlite3 format.
The reason for this is simply to keep bookmarks in sync. If someone is using your utility to manage and back up bookmarks, it would be amazing to be able to convert directly to the Chrome and Firefox JSON formats in order to replace their respective Bookmarks files programatically, without having to go through the browser and import an HTML file manually (which could also result in duplicates).
An example workflow would be as follows:
bookmarks.db
bookmarks.db
(which can be easily implemented in other applications that could require thebookmarks-converter
project inrequirements.txt
)bookmarks.db
back to Chrome/Firefox JSON format usingbookmarks-converter
bookmarks-converter
Bingo-bango, bookmarks are kept in sync.
This could also be used as a sync mechanism to keep Chrome and Firefox bookmarks in-sync by running a cron script using
bookmarks-converter
to convert from the Firefox native JSON format to the universal Bookmarkie JSON format, and then from the Bookmarkie format to the Chrome native JSON format (and vice-versa).I feel like this could be an absolute game-changer and would cause this project to absolutely explode, as it is currently the only project on the Internet that implements its current abilities, and with the addition of being backward-compatible, it would make this project absolutely unstoppable.
I also feel like this could be implemented fairly-easily since you have the knowledge of the various necessary JSON formats. I would try and help, but I feel like you could do this in a fraction of the time it would take me. The basic changes (at least for Chrome), would be to [re-]re-structure the
root
object (rename toroots
), remove the extraneous fields, add a checksum (hashlib.sha256(f"fake_placeholder_hash".encode('utf-8')).hexdigest()
), convert the 3 child items to dictionary objects, so thatroots.children
is a dictionary instead of a list, and renaming the appropriate keys back to the Chrome-specific naming conventions.By implementing this back-conversion functionality, you could additionally implement direct Chrome-to-Firefox and Firefox-to-Chrome functionalities that essentially do the exact same thing but hide the middle step from the user. You would convert Firefox JSON to universal JSON/sqlite, then universal JSON/sqlite to Chrome JSON (and vice-versa).
I sincerely hope that you take this into serious consideration, as I believe it could be implemented quite easily. Please let me know of any potential caveats that you could see that could prevent this functionality.
The text was updated successfully, but these errors were encountered: