Just wrote Python script to export all the Tomboy notes into an HTML file.
The following script connects Tomboy via DBus Interface, creates XHTML file and converts it to HTML by means of an XSL. Conversion powered by
xsltproc utility.
tomboy2html.py
#!/usr/bin/python
# Copyright (C) 2011 - Ruslan Osmanov <rrosmanov@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# See <http://www.gnu.org/licenses/>
#
##
# @file tomboy2html.py
# @brief Export all Tomboy notes in XHTML/HTML file(s)
# @author Ruslan Osmanov
# @version 1.0
# @date 08.02.2011
# @details xsltproc utility required
# @copyright Copyright (C) 2011 - Ruslan Osmanov
import dbus, dbus.glib
try:
import gobject
except ImportError:
# gobject functions are moved to dbus.glib in this Python version
pass
import os, sys, getopt
import re
def usage():
print __file__ + " [OPTIONS]"
print """Options:
-h, --help Display help
-p, --prefix Optional. Output filename prefix. Default: notes
-x, --xhtml Optional. Generate XHTML file also. Default: off
-s, --xsl Optional. XSL for XML-HTML conversion. Default: tomboy-notes.xsl
-d, --debug Optional. Debug mode. Default: off
"""
def main(argv):
debug_mode = False
prefix = 'notes'
xhtml = False
xsl_filename = os.path.dirname(__file__) + '/tomboy-notes.xsl'
# Get CLI options
try:
opts, args = getopt.getopt(argv[1:], "s:p:xhd",
("xsl=", "prefix=", "debug", "xhtml", "help"))
except getopt.GetoptError:
usage()
sys.exit(2)
# Save CLI options
for o, a in opts:
if o in ('-h', '--help'):
usage();
sys.exit();
elif o in ('-x', '--xhtml'):
xhtml = True
elif o in ('-d', '--debug'):
debug_mode = True
elif o in ("-p", "--prefix"):
prefix = os.path.expanduser(a)
elif o in ("-s", "--xsl"):
xsl_filename = os.path.expanduser(a)
xhtml_filename = prefix + '.xhtml'
html_filename = prefix + '.html'
if False == os.path.exists(xsl_filename):
print "XSL file '"+xsl_filename+"' doesn't exist"
sys.exit(2)
if debug_mode:
print "xhtml =", xhtml_filename, "\nhtml =", html_filename
print "\nxsl =", xsl_filename
# Access the Tomboy remote control interface
bus = dbus.SessionBus()
obj = bus.get_object("org.gnome.Tomboy", "/org/gnome/Tomboy/RemoteControl")
tomboy = dbus.Interface(obj, "org.gnome.Tomboy.RemoteControl")
# Get note URIs
all_notes = tomboy.ListAllNotes()
# Write each note XML to the XHTML file
f = open(xhtml_filename, "w")
f.write('<?xml version="1.0" encoding="utf-8"?>' +
'<?xml-stylesheet type="text/xsl" href="' +xsl_filename+'"?>'
'<notes>')
for n in all_notes:
if (debug_mode):
print "NOTE '"+n+"'"
xml = re.sub(r'<\?xml[^<]*\?>', '', tomboy.GetNoteCompleteXml(n))
xml = re.sub(r'\&\#x?.*\;', '', xml)
f.write(unicode(xml).encode("utf-8"))
f.write('</notes>')
f.close()
# Generate HTML
cmd = "xsltproc -o '%(html)s' '%(xsl)s' '%(xhtml)s'" % \
{'html': html_filename.replace("'", "\\'"),
'xsl': xsl_filename,
'xhtml': xhtml_filename}
if debug_mode:
print cmd
os.system(cmd)
if xhtml == False:
os.unlink(xhtml_filename)
if __name__ == "__main__":
main(sys.argv)
tomboy-notes.xsl
<?xml version='1.0' encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tomboy="http://beatniksoftware.com/tomboy"
xmlns:notes="http://beatniksoftware.com/tomboy/notes"
xmlns:size="http://beatniksoftware.com/tomboy/size"
xmlns:link="http://beatniksoftware.com/tomboy/link"
version='1.0'>
<xsl:output method="html" indent="no" />
<xsl:preserve-space elements="*" />
<xsl:param name="font" />
<xsl:param name="export-linked" />
<xsl:param name="export-linked-all" />
<xsl:param name="root-note" />
<xsl:param name="newline" select="'
'" />
<xsl:template match="/">
<html>
<head>
<title>Tomboy Notes Export</title>
<style type="text/css">/*<![CDATA[*/
body { <xsl:value-of select="$font" /> }
h1 {
font-size: xx-large;
font-weight: bold;
border-bottom: 1px solid black;
}
div.note {
position: relative;
display: block;
padding: 5pt;
margin: 5pt;
white-space: -moz-pre-wrap; /* Mozilla */
white-space: -pre-wrap; /* Opera 4 - 6 */
white-space: -o-pre-wrap; /* Opera 7 */
white-space: pre-wrap; /* CSS3 */
word-wrap: break-word; /* IE 5.5+ */
}
table.note-info{
margin: 20px 0 5px;
font-size:xx-small;
border-width: 0 1px 1px 0;
border-style: solid;
}
table.note-info td{
padding: 2px 5px;
border-width: 1px 0 0 1px;
border-style: solid;
}
/*//]]>*/
</style>
</head>
<body>
<xsl:for-each select="notes/tomboy:note">
<div class="note">
<xsl:apply-templates select="tomboy:text | tomboy:title"/>
<table class="note-info" boder="0" cellpadding="0" cellspacing="0"
summary="Note Info">
<tr>
<td>Last updated:</td>
<td><xsl:value-of select="tomboy:last-change-date" /></td>
</tr>
<tr>
<td>Tags:</td>
<td>
<xsl:for-each select="tomboy:tags">
<div><xsl:value-of select="tomboy:tag"/></div>
</xsl:for-each>
</td>
</tr>
</table>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="child::tomboy:text">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="tomboy:title">
<h1><xsl:value-of select="text()"/></h1>
</xsl:template>
<xsl:template match="tomboy:bold">
<strong><xsl:apply-templates select="node()"/></strong>
</xsl:template>
<xsl:template match="tomboy:italic">
<i><xsl:apply-templates select="node()"/></i>
</xsl:template>
<xsl:template match="tomboy:monospace">
<code><xsl:apply-templates select="node()"/></code>
</xsl:template>
<xsl:template match="tomboy:strikethrough">
<strike><xsl:apply-templates select="node()"/></strike>
</xsl:template>
<xsl:template match="tomboy:highlight">
<span style="background:yellow"><xsl:apply-templates select="node()"/></span>
</xsl:template>
<xsl:template match="tomboy:datetime">
<span style="font-style:italic;font-size:small;color:#888A85">
<xsl:apply-templates select="node()"/>
</span>
</xsl:template>
<xsl:template match="size:small">
<span style="font-size:small"><xsl:apply-templates select="node()"/></span>
</xsl:template>
<xsl:template match="size:large">
<span style="font-size:large"><xsl:apply-templates select="node()"/></span>
</xsl:template>
<xsl:template match="size:huge">
<span style="font-size:xx-large"><xsl:apply-templates select="node()"/></span>
</xsl:template>
<xsl:template match="link:broken">
<span style="color:#555753;text-decoration:underline">
<xsl:value-of select="node()"/>
</span>
</xsl:template>
<xsl:template match="link:internal">
<a style="color:#204A87" href="#{node()}">
<xsl:value-of select="node()"/>
</a>
</xsl:template>
<xsl:template match="link:url">
<a style="color:#3465A4" href="{node()}"><xsl:value-of select="node()"/></a>
</xsl:template>
<xsl:template match="tomboy:list">
<ul>
<xsl:apply-templates select="tomboy:list-item" />
</ul>
</xsl:template>
<xsl:template match="tomboy:list-item">
<li>
<xsl:if test="normalize-space(text()) = ''">
<xsl:attribute name="style">list-style-type: none</xsl:attribute>
</xsl:if>
<xsl:attribute name="dir">
<xsl:value-of select="@dir"/>
</xsl:attribute>
<xsl:apply-templates select="node()" />
</li>
</xsl:template>
<xsl:template match="//tomboy:x | //tomboy:y | //tomboy:width | //tomboy:height | //tomboy:cursor-position | //tomboy:create-date | tomboy:last-change-date | tomboy:open-on-startup | tomboy:last-metadata-change-date | tomboy:tags">
<xsl:comment>literal</xsl:comment>
</xsl:template>
</xsl:stylesheet>
Usage
I saved the files here in
~/scripts/python/tomboy2html/. Thus, to save all the Tomboy notes in all_notes.xhtml and all_notes.html, I can issue the following:
$ chmod +x ~/scripts/python/tomboy2html/tomboy2html.py
$ ~/scripts/python/tomboy2html/tomboy2html.py -p "all_notes" -x -s \
~/scripts/python/tomboy2html/tomboy-notes.xsl
It creates all_notes.xhtml and all_notes.html files in current directory.
Update 09 February 2011
Clone the Git repo:
$ git clone git://github.com/rosmanov/Tomboy2HTML.git
Hey,
ReplyDeleteThanks for the script, but when I tried, it just exported title's note and urls indide the notes, not the text.
Can I provide you anything to fix it? using Ubuntu 10.04.2 LTS.
Thanks in advance.
I suspect it is some kind of indentation issue, if you copied the code directly. Try this:
ReplyDelete$ git clone git://github.com/rosmanov/Tomboy2HTML.git
$ cd Tomboy2HTML/
$ python tomboy2html.py -p mynotes -d -s tomboy-notes.xsl
$ firefox mynotes.html
If it fails, please, send me the output.
Thank you for the report.
Hey,
ReplyDeletethanks for the quick answer. From git repo, the script is exporting great! Totally was an indentation issue, my bad.
Best regards osmanov!
Thanks for writing this .. really really handy. Worked like a charm on my ~300 notes.
ReplyDeleteThank you very much!
ReplyDeleteThanks for this script!
ReplyDelete(There is a "Tomboy" label missing for this post :P)
Ruslan - thanks for sharing the script with us. Running Lucid, had same problem (indentation?) as above, but git worked great. Thanks!
ReplyDeleteThank you for the script! It *almost* works in my case. But something a little bit strange occurs: The "F" "1" "x" disappear in the .html file but not in the .xhtml file. Do you know what I should do?
ReplyDeleteFixed. Pull it please:
ReplyDelete$ git pull
Thank you
ReplyDeleteI just tried this and got the following message:
ReplyDeletedbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
The output file was not created.
Kupp, is Tomboy really running? Try to checkout the latest version please:
ReplyDeletegit clone git://github.com/rosmanov/Tomboy2HTML.git
cd Tomboy2HTML/
./tomboy2html.py -x
If the problem still persists, post the output of the following command:
tomboy --debug
Also make sure dbus is running:
ps aux | grep dbus
Great utility, you should propose it to become an official Plugin of Tomboy:
ReplyDeletehttp://live.gnome.org/Tomboy/PluginList
or you could add an install script (I am not a pro python dev, but I may help if you need).
Thank you.
Cristian
Great tool ! Exactly what I was looking for !! Thank you very much !
ReplyDeleteI have one question: In the html/xhtml document the links are highlighted, but when I click on them, the focus does not turn to the linked note. Is this supposed to work and hence a problem of my settings ? Sorry, if this is a stupid question, I don't konw much about html. External links do work (like opening my jabref database when clicking on a .bib - file in the note).
Luuuzi
Luuuzi, indeed. It's a bug. I'll make anchors for that.
DeleteE-mail links didn't work either. Fixed it in v1.3.
DeleteCheckout the git repo please.
I'm glad you found it useful:)
Thanks.
Thanks a lot !! Works great !!!
Deletegreat! you saved me a lot of work! thanks!
ReplyDeleteI am having a problem having this script run with Cron.
ReplyDeleteI get the following Error:
###
Subject: Cron
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
Traceback (most recent call last):
File "/home/ld50/Sync_Folder/tomboy2html.py", line 126, in
main(sys.argv)
File "/home/ld50/Sync_Folder/tomboy2html.py", line 91, in main
bus = dbus.SessionBus()
File "/usr/lib/pymodules/python2.6/dbus/_dbus.py", line 219, in __new__
mainloop=mainloop)
File "/usr/lib/pymodules/python2.6/dbus/_dbus.py", line 108, in __new__
bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
File "/usr/lib/pymodules/python2.6/dbus/bus.py", line 125, in __new__
bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.Spawn.ExecFailed: /usr/bin/dbus-launch terminated abnormally with the following error: Autolaunch error: X11 initialization failed.
:
###
My current cron job looks like this.
# m h dom mon dow command
* */1 * * * /home/ld50/Sync_Folder/tomboy2html.py
Something prevents DBus connection via crond. Here is a workaround:
Delete#!/bin/bash
#
# tomboy2html.sh
#
sessionfile=`find "${HOME}/.dbus/session-bus/" -type f`
export `grep "DBUS_SESSION_BUS_ADDRESS" "${sessionfile}" | sed '/^#/d'`
cd /home/ld50/Sync_Folder/
./tomboy2html.py
#
# crontab
#
* */1 * * * /bin/bash /home/ld50/Sync_Folder/tomboy2html.sh
thanks! great script.
ReplyDeleteWhat he said. Worked instantly. Very nice output!
Delete