Friday, May 21, 2010

MobiPocket to Kindle format converter


Update (1/3/2012): Overdrive now supports lending directly in Kindle format, so this program is no longer necessary. I'll probably leave it up for a year or two in case anybody finds a use for it, but I am officially declaring it deprecated. If you find that it's still useful for you, please leave a comment to that effect and I'll consider leaving it up longer. I'd like to thank everyone who provided feedback in the form of bug reports and suggestions, and especially those who purchased items through the Amazon links in the program. It was an honor for me to be involved in producing a piece of free software that helped people enjoy free, legal, quality entertainment. Cheers!
Update (6/19/2012): It sounds like folks in Canada aren't getting the automatic Kindle conversions, so I'll leave it up a while yet. Thanks for the feedback. 

Liz and I recently found out that our local library system allows us to check out electronic books. This seemed like a perfect opportunity to use the Kindle I won in a contest at work, until we realized that the Kindle doesn't natively support any of the formats that we could get the books in. Some quick Googling revealed that Amazon actually owns MobiPocket, and the Kindle uses the MobiPocket format, with two tiny differences:
  1. The file name extension is changed to .azw
  2. A flag in the file's metadata is changed to indicate that the file is for the Kindle
I found a post by Igor Skochinsky, who provided python scripts that could figure out your Kindle's MobiPocket PID and convert a MobiPocket file registered to a Kindle's PID to work on the Kindle. But most people don't know how to run python scripts. So I set to work to create a user-friendly front-end for it.

(You will need to install the .NET 4 Framework from Microsoft if you don't have it already)

Here's how to use this program:

The following steps will only need to be performed once for each Kindle:
  1. Open the program.
  2. Click the "Add Device" button to bring up the Add Device window.
  3. Enter your Kindle's serial number. When you finish "Kindle" option should automatically be selected, and a PID should be generated. If it isn't, you've probably entered too many or too few characters: double-check the serial number.
  4. Click the Add Device button to add the PID to your list of devices.
  5. Log in to your library's eBook site and register this PID as a new device on your library account. That way, when you download MobiPocket eBooks they will have a flag on the file indicating that your Kindle is allowed to read the file for the next few weeks.
These steps are necessary for each ebook you check out from the library:
  1. Use the "Browse" button to find and select your downloaded file.
  2. Click the "Convert" button, and choose where you want to save the Kindle-compatible file. If the file you convert does not have your Kindle's PID associated with it, the program will abort with an error message indicating as much. Otherwise you should get a success message.
  3. Connect the Kindle to your computer, and copy the saved (.azw) file to its "documents" folder.
Once the file is copied to your Kindle, you will be allowed to read it until the library's due-date. After that, the Kindle will cease to read the file.

The MobiKindle program will automatically check for updates each time you run it, and will give you the choice to install the update automatically. I've made a few enhancements since the original version.

Current features include:
  • Easy to use
  • Generates Kindle PID from Kindle serial number
  • Saves your Kindle PID(s) for future use. **NEW**
  • Prevents certain data-entry errors by only allowing capital letters
  • Automatically detects Kindle type when you enter your Kindle's serial number
  • Converts MobiPocket (.prc) file to Kindle (.azw) format
  • Unobtrusive advertisements for Kindle books on Amazon. If you use the link to get to Amazon and buy a book while you're there, I'll get a piece of the profits.
A bug in the original version caused some people to get a "The selected item could not be opened..." message if they copied the file to their Kindle before exiting the MobiKindle program. This bug has now been fixed!

Now, just to clarify:
  • The Kindle will natively read MobiPocket files that don't have DRM. For example, if you get a MobiPocket file from the Gutenberg Project, you don't need to use this program. Just copy the file onto your Kindle.
  • From what I understand, you won't be able to register your Kindle with MobiPocket.com. The Kindle PID always has an asterisk (*) in it, and it won't be accepted there. However, many libraries have an eBook lending system set up with Overdrive.com, which does accept Kindle PIDs.
  • This program does not (and never will) modify the DRM on a MobiPocket file. It doesn't "unlock" the file to be used in any way that it was not intended to be used.
  • I won't build any spyware or anything into the program, and I will always be careful to make sure it doesn't do anything you wouldn't expect. However, sometimes accidents happen. In using this software, you're agreeing not to hold me responsible for any harm that comes of it.
  • The program saves your Kindle PID in a config file, but you can remove the devices and they will be removed from the config file. No information about your device or your books gets sent to me.
  • You should make sure you're okay with Amazon's privacy policy, since I include their advertisements.
  • When sharing this program, please send people to this web page. Don't use a direct link to the installer. (But please, share this program with anyone you know who has a Kindle!)
For the geeks out there: this runs on the .NET framework. I began using .NET 3.5, but soon found that things were much, much easier using .NET 4.0 thanks to the new "dynamic" keyword in C#. The program literally includes Igor's python script and runs it in an embedded instance of IronPython.

I'd like to thank:
  • My wife for her patience with me as I continue to spend many late nights on this and other pet projects.
  • Igor Skochinsky for providing the real brains in this program.
  • The users that have reported bugs and helped me to improve the quality of this program.
  • Dropbox.com for providing a free, extremely easy way to host the installer. (Click here to sign up and they'll give you extra space)
  • Amazon for making the Kindle
  • My work for giving me a Kindle, programming experience, and access to development tools
  • Microsoft, for the "dynamic" keyword
  • The IronPython team
Please post your thoughts, and additional ideas for features on this blog posting. When reporting bugs, if you will leave an email address with your comment, and then respond to my emails, it will help me to figure out what's wrong.

I should also have mentioned that I'm using the ClickOnce (or some such) deployer that comes with Visual Studio to create the installer for this program, which requires you to have a working Internet connection when you install it. There are a number of reasons I felt this was reasonable:
  1. It was free.
  2. It was easy.
  3. It makes it really easy for people to install and run the program.
  4. It makes it really easy for people to keep the program updated.
  5. You can't be reading this web page without Internet access.
  6. You can't rent MobiPocket books from the library without Internet access.
  7. You won't see the Amazon advertisements without Internet access.
If you're too paranoid to run programs off the Internet, I would recommend figuring out how to run Igor Schochinsky's python script: that way you can see exactly what the code is doing to your computer.

If you are still getting the message, "The selected item could not be opened. If you purchased this item from Amazon, delete the item and redownload it from Archived Items available in Home": The problem is probably that your Kindle doesn't know the current date, so it thinks that your book hasn't been checked out yet. Please connect your Kindle to the Internet for a few seconds so that it can update its current date and time, and that should fix this problem.