View Full Version : exlibris - add a nice ex libris to your EPUB eBook!


AlPe
06-02-2012, 12:20 PM
Hi all,

I would like to share a Python script that I have developed to add an ex libris to a (not DRM-ed) EPUB. The project was prompted by eBookLuke.

You can download it (it is released under GNU GPL 3) from this link:
https://www.wuala.com/pettarin/EBCI/exlibris.1.0.14.zip/?key=eIUNfmKr7aB2

UPDATED to v. 1.0.14: added ex libris removal

UPDATED to v. 1.0.13: fixed a bug under Windows, forcing reading the input files in UTF8, alignment with the Calibre plugin

UPDATED to v. 1.0.10: fixed a bug in the path sanitization function, alignment with the Calibre plugin

UPDATED to v. 1.08: added a GUI, in English and in Italian.

UPDATED to v. 1.07: now the user can also select the insertion point of the ex libris in the TOC; added --no-guide, --guide-string and --toc-string switches
IMPORTANT: the option switch -i, which was used to specify the insertion point of the ex libris in the spine, has been renamed to -s (spine) to be consistent with -t (TOC) switch.

UPDATED to v. 1.06: solved a CDATA bug in metadata, added --spine and --toc options, better examples in the zip file
UPDATED to v. 1.05: added support for string (metadata/user specified) string replacement in the ex libris page, and other minor improvements.

You will get a ZIP file with several Python .py files (exlibris.py, exlibris-cli.py, exlibris-gui.py and exlibris-gui-it.py) and four directories containing an ex libris example each.

I have developed it as a command line tool, but now there is also a GUI written in Tkinter, for the maximum portability and the least code footprint.

The Calibre plugin can be installed via the Calibre plugin manager (look for "Ex libris") or downloaded from this discussion: http://www.mobileread.com/forums/showthread.php?t=188619

I have tested it on several EPUBs (under Debian and Windows) and it should be quite robust; however if you find out bugs or strange behaviors, please let me know.

If you like this project, I ask you to consider supporting the eBook Club Italia (http://ebci.it/), a non-profit association that promotes reading -- especially digital reading --- in Italy. It also runs the wonderful Museum of the eBook (http://museo.ebci.it/) (you can browse it in English!).
You can help through a donation or by becoming a member.

For screenshots of the GUI version, please visit this post (http://www.mobileread.com/forums/showpost.php?p=2121071&postcount=18).

I report here the usage message of the command line version:

NAME
exlibris-cli - CLI frontend to exlibris: add a nice ex libris to your EPUB eBook

SYNOPSIS
$ python exlibris-cli.py --help
$ python exlibris-cli.py --supported-mimetype-identifiers
$ python exlibris-cli.py --supported-metadata-identifiers
$ python exlibris-cli.py book.epub --spine
$ python exlibris-cli.py book.epub --toc
$ python exlibris-cli.py book.epub [new.epub] --remove
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml [OPTIONS]

DESCRIPTION
Insert exlibris.xhtml inside book.epub and create new.epub.
If -h or --help option is given, display this usage message.
If -s option is not given, add the exlibris page as the last element of the spine.
If -t option is not given, add the exlibris page as the last element of the TOC.
If --spine (resp., --toc) option is given, print the elements of the spine (resp., TOC).
If --remove option is given, remove the ex libris from book.epub [and create new.epub].

OPTIONS
-d DIR: include all the recognized files contained in DIR.
Use this option if your ex libris XHTML page references CSS or image files.
-k: do not delete the temporary directory ('tmp').
-r DIC: replace the given strings in the ex libris page.
DIC must have the following format: "key1=value1; key2=value2; ... ; keyN=valueN".
exlibris will replace [%key1%] in the ex libris XHTML page with value1, and so on.
exlibris automagically replaces placeholders like [%title%], [%aut%], ... with the eBook metadata.
(Use --supported-metadata-identifiers to list all the supported metadata identifiers.)
-s NUM: insert the exlibris as the NUM-th element of the spine.
Use '1' or 'first' to insert the exlibris as the first element.
Use 'last' to insert the exlibris as the last element (default behavior).
Use 'ask' to get a list of possible insertion points and select it interactively.
-t NUM: insert the exlibris as the NUM-th element of the TOC.
Use '1' or 'first' to insert the exlibris as the first element.
Use 'last' to insert the exlibris as the last element (default behavior).
Use 'ask' to get a list of possible insertion points and select it interactively.

--guide-string STR: use STR as the guide string for the ex libris
--keep: do not delete the temporary directory ('tmp').
--no-guide: do not insert the ex libris in the guide section
--toc-string STR: use STR as the TOC string for the ex libris

EXAMPLES
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s 1
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s first
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s 1984
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s last
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s first -t last
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s ask -t ask
$ python exlibris-cli.py book.epub new.epub res/exlibris.xhtml -d res/
$ python exlibris-cli.py book.epub new.epub res/exlibris.xhtml -s first -t first -d res/
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -r "owner=Alberto; phrase=Happy Birthday! "
$ python exlibris-cli.py book.epub --spine
$ python exlibris-cli.py book.epub --toc
$ python exlibris-cli.py book.epub --remove
$ python exlibris-cli.py book.epub new.epub --remove
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s ask -t ask --toc-string "Happy Birthday!"
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml --guide-string "Ex Libris"
$ python exlibris-cli.py book.epub new.epub exlibris.xhtml -s first -t first --no-guide

LIMITATIONS
1) Your eBook input file must be "EPUB 2.0.1"-compliant,
and your ex libris input file must be "XHTML 1.1 strict"-compliant,
otherwise exlibris is not guaranteed to work properly and might produce an invalid EPUB file.
2) Currently exlibris includes the additional files specified by '-d' option
using their extension to get the proper media-type field.
Please name your file consistently.
For example, do not name a JPEG image 'image.svg' but use 'image.jpg' or 'image.jpeg'.
(Use --supported-mimetype-identifiers to list all the supported extensions.)

AUTHOR
Written by Alberto Pettarin, suggested by Luca "Luke" Calcinai.

REPORTING BUGS
Please write an email to alberto AT albertopettarin DOT it
or visit <http://www.albertopettarin.it/>

COPYRIGHT
Copyright (c) 2012 Alberto Pettarin.
License GNU GPL version 3 <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Indiana Joe
06-03-2012, 06:06 AM
Good work AlPe.


Anyway if you want to set up the correct link, now you can. ;)

AlPe
06-03-2012, 07:28 AM
Thanks Indiana, but since the eBook Club Italia forum is mainly in Italian, I decided to drop here the direct link to my wuala space.

However, for the interested reader: I posted the "main" discussion thread about exlibris on the EBCI forum at the following URL: http://forum.ebci.it/index.php?topic=67.0

Terisa de morgan
06-03-2012, 07:32 AM
I'll give a try (and I'll pass to my friends), thank you very much. And 'll talk about your ebook club to a friend of mine who is very fluent in Italian (I'm only a basic student).

BTW, it's very very nice for me because I missed my ex-libris.

AlPe
06-03-2012, 07:47 AM
Excellent, thanks!

PeterT
06-03-2012, 12:06 PM
@AlPe: Have you considered making this into a calibre plugin?

AlPe
06-03-2012, 03:07 PM
I must confess that I do not like Calibre that much... but I can think about this idea, thank you for suggesting it.

AlPe
06-04-2012, 01:32 PM
Ok here's my plan: I will decouple the library that actually adds the ex libris from the command line parsing stuff, and I will code three front-ends: CLI, GUI and a calibre plugin.

In the next release:

1) Parametric fields in the ex libris: you will write "EXLIBRIS_TITLE" in your XHTML source and exlibris will substitute it with the EPUB title read from its metadata (and the same for other fields).

2) Better support for external files referenced from the ex libris XHTML page.

3) A security check before unzipping the EPUB (hey, I assume you know what you are doing, but better safe than sorry...).

4) Insertion point in the TOC.

5) Time permitting: Calibre plugin and GUI.

Freeshadow
06-04-2012, 04:32 PM
If I'm not misunderstanding how it works, it might also be usable as an autograph insertion tool for authors. If I'm right, you might be interested in crosspost this to the writer's corner subforum.

AlPe
06-05-2012, 03:22 AM
That's correct. I will post there as soon as I have coded a GUI.

I am considering passing strings as command line parameters, so that the ex libris template can be "personalized" on the fly, allowing the personalization of each copy.

Note that this tool can be used to watermark EPUBs as well, if one does not care about inserting hidden markers in the files and is fine with just a page summing up the book owner's data.

Freeshadow
06-05-2012, 09:54 AM
In fact the 1st use case I saw was an author handwriting a dedication on a small graphic tablet, saving said file as svg and using your tool to stick it to the book.

AlPe
06-07-2012, 04:17 PM
A brief update: I decoupled the code inserting the ex libris into the EPUB from the command line argument parsing, creating a single "function library". Then, I moved the CLI stuff to a single CLI front-end.

I will include the ability of defining templates in the ex libris file, to be replaced by your own string(s) or the book metadata.

If anyone has already tried exlibris out and discovered any problems, I would like to try to correct them before the next release. You might want to post a message here or write me a PM, many thanks!

AlPe
06-08-2012, 02:38 PM
I have just updated the initial post, with a link to v. 1.04, which includes:

1) solved a bug with backslashes under Windows;
2) better handling of command line options;
3) decoupled the library from the CLI frontend.

In the next release I plan to include templates (supporting reading the original EPUB metadata) and possibly a GUI. I am studying how to write a Calibre plugin, so that it will be added as well, but not before a couple of weeks.

AlPe
06-13-2012, 08:29 AM
I have just updated the initial post, with a link to v. 1.05, which includes:

1) added a sanity check before uncompressing the original EPUB file;
2) added the support for string replacement in the ex libris page, from metadata or user-specified strings provided as -r argument on the command line;
3) added --supported-mimetype-identifiers and --supported-metadata-identifiers help options;
4) other minor improvements.

The GUI (and Calibre plugin) must wait until the next release, since I am quite busy job hunting...

If you find out bugs, please let me know, thank you!

AlPe
06-14-2012, 01:31 PM
I have just updated the initial post, with a link to v. 1.06, which includes:

1) solved a CDATA bug in metadata;
2) added --spine and --toc options;
3) better examples in the zip file.

The GUI (and Calibre plugin) must wait until the next release, since I am quite busy job hunting...

If you find out bugs, please let me know, thank you!

AlPe
06-16-2012, 02:38 PM
I have just updated the initial post, with a link to v. 1.07, which includes:

1) now the user can also select the insertion point of the ex libris in the TOC;
2) added --no-guide switch to prevent inserting the ex libris in the guide;
3) added --guide-string and --toc-string switches to specify the strings to be used for the ex libris in the guide and in the TOC lists.

IMPORTANT: the option switch -i, which was used to specify the insertion point of the ex libris in the spine, has been renamed to -s (spine) to be consistent with -t (TOC) switch.

AlPe
06-18-2012, 05:42 PM
I'm working on the GUI, with Tkinter.

You might want to check the first screenshot (plus the resulting ex libris as seen in ADE) out, that I attach to this post.

AlPe
06-19-2012, 05:05 PM
I have just updated the initial post, with a link to v. 1.08, which includes:

1) the GUI version, both in English (exlibris-gui.py) and in Italian (exlibris-gui-it.py).

I attach several screenshots taken under Windows.

AlPe
06-23-2012, 03:07 PM
Hi guys,

I was informed that the exlibris-gui does not start under Mac OS X.

Unfortunately I do not own an Apple machine, so I cannot confirm or provide help on that; I think it might depend on the Tkinter port, but I do not want to shoot too wild guesses. Both on my linux box (Debian + awesome) and on Windows XP it works well.

Is there anyone who successfully ran exlibris-gui under Mac OS X ?

Besides this problem, is there anyone using it? Would you like to provide some feedback?

AlPe
06-24-2012, 03:42 PM
Update on the Mac OS X "error".

Another source reported that exlibris-gui works fine on his Mac OS X machine.

The error might depend on some conflict between Apple's development tools and a previous user installation of Python. Also, renaming the Python files to .pyw might help as well.

AlPe
06-30-2012, 08:23 AM
They told me that you might want to rename exlibris-gui.py to exlibris-gui.pyw, but NOT exlibris.py, or associate the files to the Python launcher. (sorry for being vague, I do not have an OS X box to try)

AlPe
07-07-2012, 10:38 AM
Big news coming... stay tuned!

Jozawun
07-10-2012, 07:18 PM
Great idea, this.
Did you get any further with the Calibre plug-in?

AlPe
07-12-2012, 04:56 PM
Hi, thank you for your interest in exlibris.

I planned to release the Calibre plugin during this weekend, but a very strange and unanticipated series of coincidences and duties will keep me away from coding in the next 5-7 days.

I guess I might be able to release it at the end of the next week or at the beginning of the subsequent one.

Jozawun
07-12-2012, 05:13 PM
No worries mate, she'll be jake.

AlPe
08-10-2012, 04:56 AM
I want to apologize for the shameful delay, but I am currently developing the calibre plugin of exlibris.

I plan to release it after my (supposed-to-be-)vacation, around 8/20.

Hitch
08-11-2012, 05:35 PM
I want to apologize for the shameful delay, but I am currently developing the calibre plugin of exlibris.

I plan to release it after my (supposed-to-be-)vacation, around 8/20.

Hi:

Not to be particularly dense (and heavens knows, I can be), but what's the advantage of this over simply creating a templated page, inserting it into the ePUB and typing 2-3 things?

I ask because I looked at this for a form of watermarking (as we occasionally have had issues with client theft, which forced us to move to payment upfront for everything), but obviously, during editing rounds, that gets cumbersome; I'd rather do the editing invoicing at the end, than during. A watermark might help solve some of this, but I'm not sure I see the advantage of using this, given that we can just make a file/page and insert it?

Thanks,
Hitch

AlPe
08-12-2012, 02:50 AM
Hi:
Not to be particularly dense (and heavens knows, I can be), but what's the advantage of this over simply creating a templated page, inserting it into the ePUB and typing 2-3 things?


Hi,

I am not sure about what "this" refers to (the Calibre plugin or the entire exlibris project?), so let me explain the rationale of exlibris.

Initially exlibris has been developed as a command line tool, with the idea of using it inside a massive EPUB production loop. In particular, I had in mind the needs a friend who wanted to have a personalized ex libris inside each of his 1000+ EPUBs. He just needed to run a (Bash) command like:

$ for book in `ls *.epub`; do python exlibris-cli.py "$book" "$book.epub.new" exlibris.xhtml; mv "$book.epub.new" "$book"; done

to have the task accomplished. No manual editing at all!

Later, someone suggested that exlibris should have had the capability of replacing strings in the exlibris.xhtml template with the book metadata or strings passed on the command line. The latter was requested exactly for a watermarking-like process, aimed at creating "personalized" ebooks:

while read member
do
id=`echo $member | cut -d" " -f1`
name=`echo $member | cut -d" " -f2`
python exlibris-cli.py book.epub "book-$id.epub" exlibris.xhtml -r "name=$name;"
done < members.txt

This would personalize book.epub by creating a different file for each member and inserting a personalized "Happy Birthday $name !" ex libris in it.
Again, besides creating the file members.txt (in my case, exporting it from a database, and containing id and name for each "member", one member per line) there is no manual editing at all. In the specific case, I had to create a personalized EPUB for more than 100 people.

Finally, someone suggested the idea of providing a GUI for those that are not in friendly terms with the command line and, eventually, a Calibre plugin, given the popularity of the latter. But these are intended just as different ways of invoking the main exlibris library. To continue the analogy, for example by selecting a subset of your calibre library rather than using the for loop of my first example.

Let me know if something is still unclear.

Hitch
08-12-2012, 10:56 PM
I see. You're contemplating an environment in which all the ePUBs already exist. In that instance, yes, I can see how this would be very helpful.

In my shop, obviously, we make ePUBs one at a time, and we ship them to clients the same way, with certain very few exceptions, like when a client has several books in production. Having to use this one book at a time wouldn't be a time-saver; it's easier just to use an image for watermarking with house CSS and delete the watermarking code and image than to do this. I mean..it's six of one, half-dozen of another. (We do not use Calibre for eBook-making or conversion). As I said, I can see how exlibris would be useful in a large-scale situation, in which you had a bunch of books to watermark, but when you're shipping 20/books a day, (none all sitting in the same dir), it's probably easier just to have the Crews simply have it in the CSS, I suspect. I'm certainly open to thoughts or concepts of time to the contrary. ;-)

Hitch

Jellby
08-13-2012, 03:31 AM
An exlibris is usually added by the book owner, not by the publisher/printer. I guess it's similar in this case: the script is intended for ebook owners to mark their books, not for the ebook creator to add a watermark.

Hitch
08-13-2012, 01:44 PM
Jellby:

Yes, of course--I was looking for a way to make something we need to do easier. ;-) I looked at this first out of curiosity as to the software, but he mentioned it was being used for watermarking, specifically, and thus I pursued it further. However, as I said, it doesn't really suit our purposes, in terms of the process. For us, it's easier to watermark the books via css or an existing page until they are paid for. I mean--a page is a page is a page. If one has a thousand books sitting in a dir, yes, this would be spiffy; but if you're crafting them one at a time, regardless of how many are being done in a day, it's just another step, no different than adding a page that's already made by hand. (Because, of course, we'd also have to REMOVE them as the book went to its "new home.") Thus, probably easier to either wipe a class in CSS and pull an image, OR delete a pre-made page. As I said two posts ago, six of one, half-dozen of the other, as we say here (they are equivalent in terms of pros and cons).

Thanks,
Hitch

AlPe
08-21-2012, 07:13 AM
Hi all,

I have just opened a thread for the Calibre plugin of Ex Libris at http://www.mobileread.com/forums/showthread.php?t=188619

Terisa de morgan
08-24-2012, 05:07 PM
One question, I'm trying to add an exlibris from your examples and I'm always obtaining: "String index out of Range". Any idea? Perhaps the books?

AlPe
08-24-2012, 05:19 PM
Hi, it might be a bug in the exlibris code* or a problem with the book. Has the latter been validated (with an EPUB validator like FlightCrew or EpubCheck)?

I can have a look at the problem if you send me the EPUB (if it does not infringe any copyright). In case, you can send me a link or the EPUB itself at alberto AT albertopettarin.it , thanks.



* I have purposedly avoided standard XML parsers (which require a well-formed input) in order to be lenient towards slightly-incorrect content/toc files (I tested it on a couple of invalid EPUBs as well); but clearly my code can still fail.

Terisa de morgan
08-24-2012, 06:27 PM
I've checked with four books: three created with calibre and a purchased one (no DRM). The books created by calibre give the same error: string index out of range (and calibre plugin fails too). The purchased book give an error about a bad reference in opf.

None of them are validated by EpubCheck, so if it's necessary, I think I'll pass.

The log at the plugin is:

Traceback (most recent call last):
File "calibre_plugins.exlibris_plugin.ui", line 60, in show_dialog
File "calibre_plugins.exlibris_plugin.main", line 70, in __init__
File "calibre_plugins.exlibris_plugin.main", line 327, in populateSpineList
File "site-packages\calibre\gui2\init.py", line 193, in show_message
TypeError: QStatusBar.showMessage(QString, int msecs=0): argument 1 has unexpected type 'int'

If you want one of the epubs, I can send it to you.

AlPe
08-25-2012, 03:27 AM
Hi, I have fixed the problem, you can find a new release (1.0.10) of the plugin at http://www.mobileread.com/forums/showthread.php?t=188619 .

(Please report problems with the Calibre plugin there.)

AlPe
08-25-2012, 03:33 AM
I have just updated the initial post, with a link to v. 1.0.10, which includes the bug fix for the problem reported by Terisa de Morgan (thanks!).

ImNotToby
10-25-2012, 03:31 AM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>
<head>

<title></title>
</head>

<body>

<p>
<img src="Location/msjuanita/Desktop/Rayexlibris/exlibris.jpg" width="498" height="577"></P>

</body>
</html>

ok this is a code i wrote to insert a jpeg as my exlibris but im having an XML parsing issue please help

AlPe
10-25-2012, 04:23 AM
ok this is a code i wrote to insert a jpeg as my exlibris but im having an XML parsing issue please help

I have already replied via PM. No need to post this here, since it is not related to exlibris per se.

AlPe
11-17-2012, 03:02 PM
I have just updated the initial post, with a link to v. 1.0.14, which includes a function to remove the ex libris.