I use Foxmarks to keep different computers' bookmarks sync'ed to each other. I have one set of bookmarks for use on home computers, and another set for use at work computers. (I also use delicious for low usage bookmarks I know I want available everywhere.)
With Foxmarks, you can sync your bookmarks to their servers, or you can sync to your own webdav server. I prefer to host my own stuff, so I sync to my own webdav server. The bookmarks are stored in JavaScript's json file format.
But, that doesn't give me the option to browse to the server and easily see the other set of bookmarks. (If I sync'ed to Foxmarks' servers, then I could see them at my.foxmarks.com if I login with my other username.)
What's a Pythonista to do? Write a script that displays the bookmarks as URLs on a webpage! Sweet! Now I host my own repository for my bookmarks, and they're available online in case I need to see the other set's bookmarks. Here's the script:
#!/usr/bin/python
# foxmarks_reader.py by David Blume
import urllib
import simplejson # http://www.undefined.org/python/
import types
urls = ( ('Home Computer', r'http://user:pwd@url.com/fm/foxmarks.js on'),
('Work Computer', r'http://user:pwd@url.com/fmw/foxmarks.j son')
)
def do_insert(folders, command):
if 'nid' in command:
args = command['args']
if args.has_key('ntype'):
if args['ntype'] == 'folder':
my_folder = []
folders[command['nid']] = my_folder
if command['nid'] != 'ROOT':
parent = folders[args['pnid']]
parent.append((args['name'], my_folder))
elif args['ntype'] == 'separator':
parent = folders[args['pnid']]
parent.append('---')
else: # 'bookmark'
parent = folders[args['pnid']]
parent.append('<a href="%s">%s</a>' % (args['url'], args['name']))
def print_folders(folders, indent):
for item in folders:
if type(item) == types.ListType or type(item) == types.TupleType:
print '%s%s' % (' '*(indent * 4), item[0].encode('iso-8859-1', 'replace'))
print_folders(item[1], indent + 1)
else:
print '%s%s' % (' '*(indent * 4), item.encode('iso-8859-1', 'replace'))
if __name__=='__main__':
print "Content-type: text/html; charset=ISO-8859-1\n\n"
print '<pre>'
for url in urls:
print '<h2>%s</h2>' % url[0]
sock = urllib.urlopen(url[1])
json = simplejson.load(sock)
sock.close()
folders = {}
for command in json[u'commands']:
do_insert(folders, command)
print_folders(folders['ROOT'], 0)
print '</pre>'
With Foxmarks, you can sync your bookmarks to their servers, or you can sync to your own webdav server. I prefer to host my own stuff, so I sync to my own webdav server. The bookmarks are stored in JavaScript's json file format.
But, that doesn't give me the option to browse to the server and easily see the other set of bookmarks. (If I sync'ed to Foxmarks' servers, then I could see them at my.foxmarks.com if I login with my other username.)
What's a Pythonista to do? Write a script that displays the bookmarks as URLs on a webpage! Sweet! Now I host my own repository for my bookmarks, and they're available online in case I need to see the other set's bookmarks. Here's the script:
#!/usr/bin/python
# foxmarks_reader.py by David Blume
import urllib
import simplejson # http://www.undefined.org/python/
import types
urls = ( ('Home Computer', r'http://user:pwd@url.com/fm/foxmarks.js
('Work Computer', r'http://user:pwd@url.com/fmw/foxmarks.j
)
def do_insert(folders, command):
if 'nid' in command:
args = command['args']
if args.has_key('ntype'):
if args['ntype'] == 'folder':
my_folder = []
folders[command['nid']] = my_folder
if command['nid'] != 'ROOT':
parent = folders[args['pnid']]
parent.append((args['name'], my_folder))
elif args['ntype'] == 'separator':
parent = folders[args['pnid']]
parent.append('---')
else: # 'bookmark'
parent = folders[args['pnid']]
parent.append('<a href="%s">%s</a>' % (args['url'], args['name']))
def print_folders(folders, indent):
for item in folders:
if type(item) == types.ListType or type(item) == types.TupleType:
print '%s%s' % (' '*(indent * 4), item[0].encode('iso-8859-1', 'replace'))
print_folders(item[1], indent + 1)
else:
print '%s%s' % (' '*(indent * 4), item.encode('iso-8859-1', 'replace'))
if __name__=='__main__':
print "Content-type: text/html; charset=ISO-8859-1\n\n"
print '<pre>'
for url in urls:
print '<h2>%s</h2>' % url[0]
sock = urllib.urlopen(url[1])
json = simplejson.load(sock)
sock.close()
folders = {}
for command in json[u'commands']:
do_insert(folders, command)
print_folders(folders['ROOT'], 0)
print '</pre>'
- Mood:accomplished


Comments
This is exactly what I was looking for!
I wonder whether it is possible to have a modified version of the script which accesses the foxmarks.json file from the same directory where the script is, without going through http. In this way I don't need to have my password stored in clear in a DAV server. My proficiency in Python is zero...
cheers
--e.
PS: the OpenID from Yahoo apparently doesn't work for this site :-(
Still, if you insist on syncing to your own webdav server, like I do, you can. The foxmarks.json file will be written to a webdav server.
The python script above could be run from anywhere, it doesn't have to on the server. You could run it from C:\ or /home/username/ depending on your OS.
The script opens the url file just like your web browser does. So if you run it locally and you don't want to see the html formatting, just delete the parts that say:
print "Content-type: text/html; charset=ISO-8859-1\n\n"
print '<pre>'
and
print '</pre>'
There you go! It'll just print out your bookmarks without the formatting cruft.
Edited at 2008-07-24 12:19 am (UTC)
However, I meant something else :-)
I am going to have both the foxmarks.json file and the python script in the same directory in a protected dav accessible directory handled by a web server, say "https://myserver/dav/foxmarks/". I'd like to invoke the python script from a browser as "https://myserver/dav/foxmarks/index.py"
cheers
--e.
Then, urls would be something like:
files = ( ('Home Computer', r'foxmarks/foxmarks.json'), ('Work Computer', r'foxmarks_work/foxmarks.json') )Then the main section becomes:
if __name__=='__main__': for f in files: print '%s' % (f[0],) f = open(os.path.join(os.path.dirname(sys.argv[0]), f[1]), 'r') json = simplejson.load(f) f.close() folders = {} for command in json[u'commands']: do_insert(folders, command) print_folders(folders['ROOT'], 0)Edited at 2008-07-24 03:06 am (UTC)
I have in vain tried to the index.py script. I run FC9 and did install the simplejson module. Still I get only the code of the py script echoed to the script. I am not conversant with python, but something tells me this must be something simple. As usual, any help is most appreciated.
Cheers,
Paul MUnters