DogMelon

Lesson 5: Importing and Exporting Books

filename: lesson05-import_export.py
getName() Lesson 05 - Import/Export
getDescription() Lesson 05 - Importing and Exporting Books


A common plugin task is to automatically import or export a book. For example, combined with the power of the Python libraries, you could automate a task such as exporting a book to HTML and uploading it to a website.


There are two different formats you can export a book to:

There is only one format you can import a book from:

There is no capacity import from HTML.

Export a book

The Note Studio XML format is documented in the main Help File. Using the Note Studio Plugin API you can both read and write that format. In this lesson we don't care about the internals of the XML format - we will just see that we can export it and then reimport the resulting file.

Export to XML

To use the XML loader, you must first import the xml I/O module:

from WikiLoaderXML import *

One quirk of the XML IO module is that it needs to be initialised with a datasource object. This is so that Note Studio knows which collection to import a book into, but unfortunately you must pass it a collection even if you only intend to export a book.


In this lesson, we're going to export the first book in the library - book '0'. First, there is a guard in the execute() function, to avoid running if there are no books.

	if( theAppData.library.getNumBooks() == 0 ):
		return

So, how do we get the collection a book belongs to? Well, we can do it as follows:

	collectionName, bookId = theAppData.library.getBookSignature( 0 )
	collectionIndex = theAppData.library.findDataSourceIndex( collectionName )
	collection = theAppData.library.getDataSource( collectionIndex )

We can now go to the function which actually does the work. We construct the XML i/o loader by passing it the book's collection:

	loader = WikiLoaderXML( collection )

Then we can save the xml file, specifying the book we want to export, and the filename we want to write.

	loader.save( outputFilename, bookName)

Pretty easy - we've just written an XML book. Later in this lesson, we're going to re-import that book.

Export to Html

Exporting to Html is slightly different in that we're not exporting a single file. When we export to Html, we generate a separate file for each page in the book. We also export a css (cascading stylesheet) file called 'notestudio.css'. The css file is only exported if none exists in the output directory. If one is found in that directory, a new one is not created. This allows you to substitute your own stylesheet for the default one, without it being overwritten all the time.


So without delay, let's look at the HTML export code. Again, we must import the correct module at the top of the file:

from WikiLoaderHtml import *

This time, it's easier to construct the i/o object because it doesn't require any parameters:

	loader = WikiLoaderHtml()

Now, due to a quirk in the Html API, we have to specify a filename, whereas really only a directory name is required. The actual filename is ignored - only the directory name is honoured. As stated earlier, actual filenames are determined from the page names included in the book.


Our plugin code spells this out by indicating that it is a bogus filename:

	loader.save( outputDirectory + bogusFilename, bookName)

When you pass a directory to this routine, that directory must already exist. Neither the XML or the Html exporter will construct the directory for you. You will need to ensure that the directory tree exists first.

If you need to, you can create it using Python's file manipulation library. See 'mkdir()' and 'mkdirs()' in the 'os' module.

Import a book

Importing a book can be used for a number of tasks. You might be restoring books from a previous location, you might be generating XML books using another process, which then need to be loaded into Note Studio.

Import from XML

We have already imported the WikiLoaderXML module, so there's no further initialisation to be done.


One thing to take care of, when importing a book, is that the import will fail if a book of that name already exists. Earlier in this lesson, we exported book number '0' to XML. We can't simply import that book again, because then there would be two books with the same name. So first, we rename book number '0' in our library. This does not involve any new code - you already know how to rename a book:

	bookName = book.getDisplayName()
	newName = "Copy of " + bookName
	book.setDisplayName( newName )

Now we are ready to re-import the book. Here's how we do it:

	loader = WikiLoaderXML( collection )

We create the WikiLoaderXML object, again passing in a collection. This is the collection which the book will be added to, once it is loaded. Then, we simply load the book, supplying the filename, which should be a full path for safety.

	filename = "C:/lesson05.xml"
	loader.load( filename )

Finally, because we've updated the contents of the library, we need to call '0nRefresh()', which we do back in execute():

	theAppData.appFrame.onRefresh()

When this plugin finishes, you will have duplicated the first book in your library. If it was called 'Book 0', now you will also have 'Copy of Book 0'.

Conclusion:

Importing and exporting books is a very useful task for some applications, and now you have everything you need to do it when the need arises.

API Functions:

WikiLibrary.getBookSignature( index )

WikiLibrary.findDataSourceIndex( collectionName )

WikiLoaderXML( datasource )

WikiLoaderXML.load( filename )

WikiLoaderXML.save( filename, bookname )

WikiLoaderHtml()

WikiLoaderHtml.save( filename, bookname )


View Plugin Source