05 October 2008

Overwrite IE Favorites with Firefox Bookmarks


I love Firefox, but on Windows IE has one big advantage over it: it's made by the same people who made the OS. This lets IE access its favorites from all sorts of places, not just from the browser. I'm a task-oriented person rather than application-oriented: I tend to think "Gotta pay the bills now" not "Gotta open up the browser and then do things that require a browser, such as bill pay." IE 4.0+ (and Windows98) was oriented towards people like me, by putting the Favorites option in the start menu, every folder, etc. It never really caught on, and in fact the Favorites option was quietly removed from the start menu in either XP or Vista, though it can be re-enabled from the taskbar options.

There are a couple of ways to get your Firefox bookmarks in the Favorites. There are lots of bookmark synchronization programs, though they tend to need to be run manually--which is messy for me. There's also the PlainOlFavorites plug-in for Firefox which lets you just use IE favorites instead of Bookmarks. I loved this plug in for a few years, but I like FF's native Bookmark system enough that I wanted to make my own synchronization system.

Here's a little Python script I came up with. It copies YESTERDAY's Firefox backup over your Favorites (copying the current version would just have been too messy). It requires Python 2.6 or you'll need to install the "simplejson" module and replace all references to "json" with "simplejson" in the code. Do not run this if you use IE favorites: it will DELETE THEM ALL and overwrite them with Firefox favorites. You can comment out the "nukeFavorites()" line if you just want to add to your existing IE favorites. I plop this script into my Startup folder and it works great!


# bookmarks_json.py -- Michael Scott Cuthbert
import json
import copy
import sys
import os
import shutil

class BookmarkMaker(object):

startdir = os.environ["USERPROFILE"] + r'\Favorites'
internetShortcut = "[InternetShortcut]\nURL="

folderpath = os.environ["APPDATA"] + "\\Mozilla\\Firefox\\Profiles\\"
backuppath = r'\bookmarkbackups'

def nukeFavorites(self):
'''deletes everything in the Favorites dir -- do not use this if you update Favorites!'''
nukeem = os.listdir(self.startdir)
for thisfile in nukeem:
if thisfile != "desktop.ini":
thisFullFile = self.startdir + os.sep + thisfile
try:
os.remove(thisFullFile)
except OSError:
shutil.rmtree(thisFullFile)

def run(self):
stringFile = self.openRightFile()
self.parse(stringFile)

def openRightFile(self):
backupPath = self.backupPath()
theseFiles = os.listdir(backupPath);
theseFiles.sort(reverse=True)
for thisFile in theseFiles:
if thisFile.startswith('bookmarks-') and thisFile.endswith('.json'):
return self.openJson(backupPath + os.sep + thisFile)

def backupPath(self):
profile = self.mostRecentProfile(self.folderpath)
return profile + self.backuppath

def mostRecentProfile(self, profilesPath):
'''returns the most recently modified Profile in the profilesPath'''
newestName = ""
newestTime = 0

allDirs = os.listdir(profilesPath)
for thisDir in allDirs:
thisFullPath = profilesPath + os.sep + thisDir
try:
thisModTime = os.path.getmtime(thisFullPath + os.sep + "places.sqlite")
if thisModTime > newestTime:
newestTime = thisModTime
newestName = thisFullPath
except:
pass
return newestName

def openJson(self, jsonFile):
try:
myfile = open(jsonFile) #folderpath + '\\' + bookmarkfile)
except:
raise Exception("Could not open file " + jsonFile)
return myfile.read()

def parse(self, stringData):
self.jsonStuff = json.loads(stringData)
self.realBase = self.findRealBase(self.jsonStuff)
self.parseReally(self.realBase)

def findRealBase(self, searchIn):
return searchIn["children"][0]["children"]

def parseReally(self, startingPoint, currentDir = []):
for thing in startingPoint:
if thing.has_key("children"): ## Bookmark folder
tempdir = copy.copy(currentDir)
tempdir.append(thing["title"])
self.parseReally(thing["children"], tempdir)
elif thing.has_key("uri"): ## Bookmark
self.createFavorite(thing["uri"], os.sep.join(currentDir) + os.sep + thing["title"] + ".url")

def createFavorite(self, uri, filename):
shortcutOut = self.internetShortcut + uri
if not(filename.startswith(os.sep)):
filename = os.sep + filename
filename = self.startdir + filename
try:
self.recursiveMakeDir(filename)
filehandle = open(filename, "w")
filehandle.write(shortcutOut)
except:
pass

def recursiveMakeDir(self, filename):
if filename.count(os.sep) > 12:
raise Exception("Whoa, you sure you want to go so deep and make " + filename + "?")

parentDir = os.path.dirname(filename)
if os.path.exists(parentDir):
return True
else:
self.recursiveMakeDir(parentDir)
os.mkdir(parentDir)

if (__name__ == "__main__"):
bmm = BookmarkMaker()
bmm.nukeFavorites()
bmm.run()