')%newloc
books = self.conn.get('SELECT id, path, title FROM books')
@@ -1263,7 +1263,7 @@ class LibraryDatabase2(LibraryDatabase):
old_dirs.add(srcdir)
if progress is not None:
progress.setValue(i+1)
-
+
dbpath = os.path.join(newloc, os.path.basename(self.dbpath))
shutil.copyfile(self.dbpath, dbpath)
opath = self.dbpath
@@ -1279,22 +1279,22 @@ class LibraryDatabase2(LibraryDatabase):
if progress is not None:
progress.reset()
progress.hide()
-
-
+
+
def __iter__(self):
for record in self.data._data:
if record is not None:
yield record
-
+
def all_ids(self):
for i in iter(self):
yield i['id']
-
+
def get_data_as_dict(self, prefix=None, authors_as_string=False):
'''
Return all metadata stored in the database as a dict. Includes paths to
the cover and each format.
-
+
:param prefix: The prefix for all paths. By default, the prefix is the absolute path
to the library folder.
'''
@@ -1325,9 +1325,9 @@ class LibraryDatabase2(LibraryDatabase):
x['formats'].append(path%fmt.lower())
x['fmt_'+fmt.lower()] = path%fmt.lower()
x['available_formats'] = [i.upper() for i in formats.split(',')]
-
+
return data
-
+
def migrate_old(self, db, progress):
header = _(u'Migrating old database to ebook library in %s
')%self.library_path
progress.setValue(0)
@@ -1338,23 +1338,23 @@ class LibraryDatabase2(LibraryDatabase):
books = db.conn.get('SELECT id, title, sort, timestamp, uri, series_index, author_sort, isbn FROM books ORDER BY id ASC')
progress.setAutoReset(False)
progress.setRange(0, len(books))
-
+
for book in books:
self.conn.execute('INSERT INTO books(id, title, sort, timestamp, uri, series_index, author_sort, isbn) VALUES(?, ?, ?, ?, ?, ?, ?, ?);', book)
-
+
tables = '''
-authors ratings tags series books_tags_link
+authors ratings tags series books_tags_link
comments publishers
-books_authors_link conversion_options
-books_publishers_link
-books_ratings_link
+books_authors_link conversion_options
+books_publishers_link
+books_ratings_link
books_series_link feeds
'''.split()
for table in tables:
- rows = db.conn.get('SELECT * FROM %s ORDER BY id ASC'%table)
+ rows = db.conn.get('SELECT * FROM %s ORDER BY id ASC'%table)
for row in rows:
self.conn.execute('INSERT INTO %s VALUES(%s)'%(table, ','.join(repeat('?', len(row)))), row)
-
+
self.conn.commit()
self.refresh('timestamp', True)
for i, book in enumerate(books):
@@ -1379,7 +1379,7 @@ books_series_link feeds
self.vacuum()
progress.reset()
return len(books)
-
+
def export_to_dir(self, dir, indices, byauthor=False, single_dir=False,
index_is_id=False, callback=None):
if not os.path.exists(dir):
@@ -1425,7 +1425,7 @@ books_series_link feeds
opf = OPFCreator(base, mi)
opf.render(f)
f.close()
-
+
fmts = self.formats(idx, index_is_id=index_is_id)
if not fmts:
fmts = ''
@@ -1449,7 +1449,7 @@ books_series_link feeds
if not callback(count, mi.title):
return
- def export_single_format_to_dir(self, dir, indices, format,
+ def export_single_format_to_dir(self, dir, indices, format,
index_is_id=False, callback=None):
dir = os.path.abspath(dir)
if not index_is_id:
@@ -1476,7 +1476,7 @@ books_series_link feeds
f.write(data)
f.seek(0)
try:
- set_metadata(f, self.get_metadata(id, index_is_id=True, get_cover=True),
+ set_metadata(f, self.get_metadata(id, index_is_id=True, get_cover=True),
stream_type=format.lower())
except:
pass
@@ -1485,7 +1485,7 @@ books_series_link feeds
if not callback(count, title):
break
return failures
-
+
def find_books_in_directory(self, dirpath, single_book_per_directory):
dirpath = os.path.abspath(dirpath)
if single_book_per_directory:
@@ -1514,12 +1514,12 @@ books_series_link feeds
ext = ext[1:].lower()
if ext not in BOOK_EXTENSIONS:
continue
-
+
key = os.path.splitext(path)[0]
if not books.has_key(key):
books[key] = []
books[key].append(path)
-
+
for formats in books.values():
yield formats
@@ -1543,7 +1543,7 @@ books_series_link feeds
formats = self.find_books_in_directory(dirpath, True)
if not formats:
return
-
+
mi = metadata_from_formats(formats)
if mi.title is None:
return
@@ -1552,7 +1552,7 @@ books_series_link feeds
self.import_book(mi, formats)
if callable(callback):
callback(mi.title)
-
+
def recursive_import(self, root, single_book_per_directory=True, callback=None):
root = os.path.abspath(root)
duplicates = []
@@ -1565,8 +1565,5 @@ books_series_link feeds
if callable(callback):
if callback(''):
break
-
+
return duplicates
-
-
-
diff --git a/src/calibre/library/sqlite.py b/src/calibre/library/sqlite.py
index cc30f6dd5c..58a1cd8d91 100644
--- a/src/calibre/library/sqlite.py
+++ b/src/calibre/library/sqlite.py
@@ -14,7 +14,7 @@ from Queue import Queue
from threading import RLock
from datetime import tzinfo, datetime, timedelta
-from calibre.library import title_sort
+from calibre.ebooks.metadata import title_sort
global_lock = RLock()
diff --git a/src/calibre/linux.py b/src/calibre/linux.py
index 7b89e50dcb..427b41ca5f 100644
--- a/src/calibre/linux.py
+++ b/src/calibre/linux.py
@@ -16,66 +16,56 @@ if os.environ.has_key('DESTDIR'):
entry_points = {
'console_scripts': [ \
- 'prs500 = calibre.devices.prs500.cli.main:main',
- 'lrf-meta = calibre.ebooks.lrf.meta:main',
- 'rtf-meta = calibre.ebooks.metadata.rtf:main',
- 'pdf-meta = calibre.ebooks.metadata.pdf:main',
- 'lit-meta = calibre.ebooks.metadata.lit:main',
- 'imp-meta = calibre.ebooks.metadata.imp:main',
- 'rb-meta = calibre.ebooks.metadata.rb:main',
- 'opf-meta = calibre.ebooks.metadata.opf2:main',
- 'odt-meta = calibre.ebooks.metadata.odt:main',
- 'epub-meta = calibre.ebooks.metadata.epub:main',
- 'mobi-meta = calibre.ebooks.metadata.mobi:main',
- 'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main',
- 'html2lrf = calibre.ebooks.lrf.html.convert_from:main',
- 'html2oeb = calibre.ebooks.html:main',
- 'html2epub = calibre.ebooks.epub.from_html:main',
- 'odt2oeb = calibre.ebooks.odt.to_oeb:main',
- 'markdown-calibre = calibre.ebooks.markdown.markdown:main',
- 'lit2lrf = calibre.ebooks.lrf.lit.convert_from:main',
- 'epub2lrf = calibre.ebooks.lrf.epub.convert_from:main',
- 'rtf2lrf = calibre.ebooks.lrf.rtf.convert_from:main',
- 'web2disk = calibre.web.fetch.simple:main',
- 'feeds2disk = calibre.web.feeds.main:main',
- 'calibre-server = calibre.library.server:main',
- 'feeds2lrf = calibre.ebooks.lrf.feeds.convert_from:main',
- 'feeds2epub = calibre.ebooks.epub.from_feeds:main',
- 'feeds2mobi = calibre.ebooks.mobi.from_feeds:main',
- 'web2lrf = calibre.ebooks.lrf.web.convert_from:main',
- 'pdf2lrf = calibre.ebooks.lrf.pdf.convert_from:main',
- 'mobi2lrf = calibre.ebooks.lrf.mobi.convert_from:main',
- 'fb22lrf = calibre.ebooks.lrf.fb2.convert_from:main',
- 'fb2-meta = calibre.ebooks.metadata.fb2:main',
- 'any2lrf = calibre.ebooks.lrf.any.convert_from:main',
- 'any2epub = calibre.ebooks.epub.from_any:main',
- 'any2lit = calibre.ebooks.lit.from_any:main',
- 'any2mobi = calibre.ebooks.mobi.from_any:main',
- 'any2pdf = calibre.ebooks.pdf.from_any:main',
- 'lrf2lrs = calibre.ebooks.lrf.lrfparser:main',
- 'lrs2lrf = calibre.ebooks.lrf.lrs.convert_from:main',
- 'pdfreflow = calibre.ebooks.lrf.pdf.reflow:main',
- 'isbndb = calibre.ebooks.metadata.isbndb:main',
- 'librarything = calibre.ebooks.metadata.library_thing:main',
- 'mobi2oeb = calibre.ebooks.mobi.reader:main',
- 'oeb2mobi = calibre.ebooks.mobi.writer:main',
- 'lit2oeb = calibre.ebooks.lit.reader:main',
- 'oeb2lit = calibre.ebooks.lit.writer:main',
- 'comic2lrf = calibre.ebooks.lrf.comic.convert_from:main',
- 'comic2epub = calibre.ebooks.epub.from_comic:main',
- 'comic2mobi = calibre.ebooks.mobi.from_comic:main',
- 'comic2pdf = calibre.ebooks.pdf.from_comic:main',
- 'calibre-debug = calibre.debug:main',
- 'calibredb = calibre.library.cli:main',
- 'calibre-fontconfig = calibre.utils.fontconfig:main',
- 'calibre-parallel = calibre.parallel:main',
- 'calibre-customize = calibre.customize.ui:main',
- 'pdftrim = calibre.ebooks.pdf.pdftrim:main' ,
- ],
+ 'ebook-device = calibre.devices.prs500.cli.main:main',
+ 'ebook-meta = calibre.ebooks.metadata.cli:main',
+ 'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main',
+ 'html2lrf = calibre.ebooks.lrf.html.convert_from:main',
+ 'html2oeb = calibre.ebooks.html:main',
+ 'html2epub = calibre.ebooks.epub.from_html:main',
+ 'odt2oeb = calibre.ebooks.odt.to_oeb:main',
+ 'markdown-calibre = calibre.ebooks.markdown.markdown:main',
+ 'lit2lrf = calibre.ebooks.lrf.lit.convert_from:main',
+ 'epub2lrf = calibre.ebooks.lrf.epub.convert_from:main',
+ 'rtf2lrf = calibre.ebooks.lrf.rtf.convert_from:main',
+ 'web2disk = calibre.web.fetch.simple:main',
+ 'feeds2disk = calibre.web.feeds.main:main',
+ 'calibre-server = calibre.library.server:main',
+ 'feeds2lrf = calibre.ebooks.lrf.feeds.convert_from:main',
+ 'feeds2epub = calibre.ebooks.epub.from_feeds:main',
+ 'feeds2mobi = calibre.ebooks.mobi.from_feeds:main',
+ 'web2lrf = calibre.ebooks.lrf.web.convert_from:main',
+ 'pdf2lrf = calibre.ebooks.lrf.pdf.convert_from:main',
+ 'mobi2lrf = calibre.ebooks.lrf.mobi.convert_from:main',
+ 'fb22lrf = calibre.ebooks.lrf.fb2.convert_from:main',
+ 'any2lrf = calibre.ebooks.lrf.any.convert_from:main',
+ 'any2epub = calibre.ebooks.epub.from_any:main',
+ 'any2lit = calibre.ebooks.lit.from_any:main',
+ 'any2mobi = calibre.ebooks.mobi.from_any:main',
+ 'lrf2lrs = calibre.ebooks.lrf.lrfparser:main',
+ 'lrs2lrf = calibre.ebooks.lrf.lrs.convert_from:main',
+ 'pdfreflow = calibre.ebooks.lrf.pdf.reflow:main',
+ 'isbndb = calibre.ebooks.metadata.isbndb:main',
+ 'librarything = calibre.ebooks.metadata.library_thing:main',
+ 'mobi2oeb = calibre.ebooks.mobi.reader:main',
+ 'oeb2mobi = calibre.ebooks.mobi.writer:main',
+ 'lit2oeb = calibre.ebooks.lit.reader:main',
+ 'oeb2lit = calibre.ebooks.lit.writer:main',
+ 'comic2lrf = calibre.ebooks.lrf.comic.convert_from:main',
+ 'comic2epub = calibre.ebooks.epub.from_comic:main',
+ 'comic2mobi = calibre.ebooks.mobi.from_comic:main',
+ 'comic2pdf = calibre.ebooks.pdf.from_comic:main',
+ 'calibre-debug = calibre.debug:main',
+ 'calibredb = calibre.library.cli:main',
+ 'calibre-fontconfig = calibre.utils.fontconfig:main',
+ 'calibre-parallel = calibre.parallel:main',
+ 'calibre-customize = calibre.customize.ui:main',
+ 'pdftrim = calibre.ebooks.pdf.pdftrim:main' ,
+ 'any2pdf = calibre.ebooks.pdf.from_any:main',
+ ],
'gui_scripts' : [
- __appname__+' = calibre.gui2.main:main',
- 'lrfviewer = calibre.gui2.lrf_renderer.main:main',
- 'ebook-viewer = calibre.gui2.viewer.main:main',
+ __appname__+' = calibre.gui2.main:main',
+ 'lrfviewer = calibre.gui2.lrf_renderer.main:main',
+ 'ebook-viewer = calibre.gui2.viewer.main:main',
],
}
@@ -177,7 +167,7 @@ def setup_completion(fatal_errors):
sys.stdout.flush()
from calibre.ebooks.lrf.html.convert_from import option_parser as htmlop
from calibre.ebooks.lrf.txt.convert_from import option_parser as txtop
- from calibre.ebooks.lrf.meta import option_parser as metaop
+ from calibre.ebooks.metadata.cli import option_parser as metaop, filetypes as meta_filetypes
from calibre.ebooks.lrf.lrfparser import option_parser as lrf2lrsop
from calibre.gui2.lrf_renderer.main import option_parser as lrfviewerop
from calibre.ebooks.lrf.pdf.reflow import option_parser as pdfhtmlop
@@ -186,7 +176,6 @@ def setup_completion(fatal_errors):
from calibre.web.feeds.main import option_parser as feeds2disk
from calibre.web.feeds.recipes import titles as feed_titles
from calibre.ebooks.lrf.feeds.convert_from import option_parser as feeds2lrf
- from calibre.ebooks.metadata.epub import option_parser as epub_meta
from calibre.ebooks.lrf.comic.convert_from import option_parser as comicop
from calibre.ebooks.epub.from_html import option_parser as html2epub
from calibre.ebooks.html import option_parser as html2oeb
@@ -225,15 +214,7 @@ def setup_completion(fatal_errors):
f.write(opts_and_exts('any2mobi', any2mobi, any_formats))
f.write(opts_and_exts('oeb2mobi', oeb2mobi, ['opf']))
f.write(opts_and_exts('lrf2lrs', lrf2lrsop, ['lrf']))
- f.write(opts_and_exts('lrf-meta', metaop, ['lrf']))
- f.write(opts_and_exts('rtf-meta', metaop, ['rtf']))
- f.write(opts_and_exts('pdf-meta', metaop, ['pdf']))
- f.write(opts_and_exts('lit-meta', metaop, ['lit']))
- f.write(opts_and_exts('imp-meta', metaop, ['imp']))
- f.write(opts_and_exts('rb-meta', metaop, ['rb']))
- f.write(opts_and_exts('opf-meta', metaop, ['opf']))
- f.write(opts_and_exts('odt-meta', metaop, ['odt', 'ods', 'odf', 'odg', 'odp']))
- f.write(opts_and_exts('epub-meta', epub_meta, ['epub']))
+ f.write(opts_and_exts('ebook-meta', metaop, list(meta_filetypes())))
f.write(opts_and_exts('lrfviewer', lrfviewerop, ['lrf']))
f.write(opts_and_exts('pdfrelow', pdfhtmlop, ['pdf']))
f.write(opts_and_exts('mobi2oeb', mobioeb, ['mobi', 'prc']))
@@ -423,10 +404,8 @@ def install_man_pages(fatal_errors):
os.environ['PATH'] += ':'+os.path.expanduser('~/bin')
for src in entry_points['console_scripts']:
prog = src[:src.index('=')].strip()
- if prog in ('prs500', 'pdf-meta', 'epub-meta', 'lit-meta',
- 'markdown-calibre', 'calibre-debug', 'fb2-meta',
- 'calibre-fontconfig', 'calibre-parallel', 'odt-meta',
- 'rb-meta', 'imp-meta', 'mobi-meta'):
+ if prog in ('ebook-device', 'markdown-calibre',
+ 'calibre-fontconfig', 'calibre-parallel'):
continue
help2man = ('help2man', prog, '--name', 'part of %s'%__appname__,
diff --git a/src/calibre/utils/logging.py b/src/calibre/utils/logging.py
new file mode 100644
index 0000000000..ae2e1a792b
--- /dev/null
+++ b/src/calibre/utils/logging.py
@@ -0,0 +1,92 @@
+from __future__ import with_statement
+__license__ = 'GPL 3'
+__copyright__ = '2009, Kovid Goyal '
+__docformat__ = 'restructuredtext en'
+
+'A simplified logging system'
+
+DEBUG = 0
+INFO = 1
+WARN = 2
+ERROR = 3
+
+import sys, traceback
+from functools import partial
+
+from calibre import prints
+from calibre.utils.terminfo import TerminalController
+
+class ANSIStream:
+
+ def __init__(self, stream=sys.stdout):
+ self.stream = stream
+ tc = TerminalController(stream)
+ self.color = {
+ DEBUG: tc.GREEN,
+ INFO:'',
+ WARN: tc.YELLOW,
+ ERROR: tc.RED
+ }
+ self.normal = tc.NORMAL
+
+ def prints(self, level, *args, **kwargs):
+ self.stream.write(self.color[level])
+ kwargs['file'] = self.stream
+ prints(*args, **kwargs)
+ self.stream.write(self.normal)
+
+ def flush(self):
+ self.stream.flush()
+
+class HTMLStream:
+
+ def __init__(self, stream=sys.stdout):
+ self.stream = stream
+ self.color = {
+ DEBUG: '',
+ INFO:'',
+ WARN: '',
+ ERROR: ''
+ }
+ self.normal = ''
+
+ def prints(self, level, *args, **kwargs):
+ self.stream.write(self.color[level])
+ kwargs['file'] = self.stream
+ prints(*args, **kwargs)
+ self.stream.write(self.normal)
+
+ def flush(self):
+ self.stream.flush()
+
+class Log(object):
+
+ DEBUG = DEBUG
+ INFO = INFO
+ WARN = WARN
+ ERROR = ERROR
+
+ def __init__(self, level=INFO):
+ self.filter_level = level
+ default_output = ANSIStream()
+ self.outputs = [default_output]
+
+ self.debug = partial(self.prints, DEBUG)
+ self.info = partial(self.prints, INFO)
+ self.warn = self.warning = partial(self.prints, WARN)
+ self.error = partial(self.prints, ERROR)
+
+
+ def prints(self, level, *args, **kwargs):
+ if level < self.filter_level:
+ return
+ for output in self.outputs:
+ output.prints(level, *args, **kwargs)
+
+ def exception(self, *args, **kwargs):
+ limit = kwargs.pop('limit', None)
+ self.prints(ERROR, *args, **kwargs)
+ self.prints(DEBUG, traceback.format_exc(limit))
+
+ def __call__(self, *args, **kwargs):
+ self.prints(INFO, *args, **kwargs)
\ No newline at end of file
diff --git a/src/calibre/utils/terminfo.py b/src/calibre/utils/terminfo.py
index 075c0e694d..fd394cbfe9 100644
--- a/src/calibre/utils/terminfo.py
+++ b/src/calibre/utils/terminfo.py
@@ -33,7 +33,7 @@ class TerminalController:
>>> term = TerminalController()
>>> if term.CLEAR_SCREEN:
- ... print 'This terminal supports clearning the screen.'
+ ... print 'This terminal supports clearing the screen.'
Finally, if the width and height of the terminal are known, then
they will be stored in the `COLS` and `LINES` attributes.