Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 115 lines (93 sloc) 4.22 KB
#! /usr/bin/env python
# Add books to Kobo shelves according to their epub tag.
# Copyright 2015 by Akkana Peck: share and enjoy under the GPL v2 or later.
# Find all books recursively under a given directory,
# and for each book that exists on the Kobo,
# add it to the Kobo's shelves according to its epub tags
# (always lowercased, and limited to a list of valid shelf names).
import os, sys
import zipfile
import xml.dom.minidom
import kobo_utils
import epubtag
# Two variables you might want to change:
# If KOBO_DB is defined, it will use that as the database,
# otherwise it will use the database on the kobo mounted on KOBO_MOUNTED.
KOBO_MOUNTED = '/kobo'
KOBO_DB = os.path.expanduser('~/kobo/mykobo/KoboReader.sqlite')
# Create only shelves in this list. Otherwise ignore tags.
# Don't create shelves for all the zillions of Gutenberg tags.
# Lower-case only.
shelves_wanted = [ "mystery", "science fiction", "science", "astronomy",
"history", "short stories", "politics", "philosophy",
"dogs", "animals", "humor", "biography", "medicine",
"nonfiction", "poetry", "plays", "travel", "writing",
"war", "civil war", "historical fiction", "adventure",
"juvenile", "fantasy", "heroine" ]
booklist = {}
# First, make a dictionary of all the books we want to index.
# Iterate over dirs of epubs provided on the command line:
if len(sys.argv) <= 1 or sys.argv[1][0] == '-':
print "Usage: %s dir dir dir ..." % sys.argv[0]
print " where each dir will be searched recursively for epub books."
print "Will look for a mounted kobo at /kobo"
print "but will modify a database at ~/kobo/mykobo/KoboReader.sqlite"
print "rather than the real one on /kobo"
for dir in sys.argv[1:]:
for root, dirs, files in os.walk(dir):
for f in files:
if f.lower().endswith(".epub"):
filepath = os.path.join(root, f)
book = epubtag.EpubBook()
title = book.get_title()
tags = map(str.lower, book.get_tags())
booklist[title] = tags
print "Local book:", title
# print f, tags
except RuntimeError, e:
print e
# The path where the Kobo is mounted:
koboDB = kobo_utils.KoboDB(KOBO_MOUNTED)
# For testing: for a real Kobo that's mounted, don't specify a path,
# just connect() and it will use the mounted path.
# What books are in shelves on the Kobo?
kobo_shelf_content = koboDB.get_dlist("ShelfContent",
selectors=["ShelfName", "ContentId"])
# Get a list of all books on the Kobo:
kobobooks = koboDB.get_dlist("content",
selectors = [ 'ContentID', 'Title' ],
modifiers="content.BookTitle is null",
# Iterate over books on the Kobo:
for kobobook in kobobooks:
if kobobook['Title'] not in booklist:
# print kobobook['Title'], "is on Kobo but not local"
# The book exists both here and on the Kobo.
# Iterate through the tags and see if it's in appropriate shelves:
print kobobook['Title'], "has tags", booklist[kobobook['Title']]
for tag in booklist[kobobook['Title']]:
if tag not in shelves_wanted:
# See if there's already a shelf for this tag:
if not koboDB.has_shelf(tag):
koboDB.add_to_shelf(kobobook, tag)
# There's already a shelf named tag. Is this book in it?
already_on_shelf = False
for shelf_entry in kobo_shelf_content:
if shelf_entry['ShelfName'] == tag and \
shelf_entry['ContentId'] == kobobook['ContentID']:
# I love how the DB has ContentId and ContentID
# depending on which table you look at
already_on_shelf = True
if already_on_shelf:
print kobobook['Title'], "is already on shelf", tag
koboDB.add_to_shelf(kobobook, tag)
You can’t perform that action at this time.