mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add format_metadata to get_metadata using a cache. Add formatter functions to deal with the information.
This commit is contained in:
parent
42de0d5ff3
commit
23307b3aa5
@ -8,6 +8,7 @@ The database used to store ebook metadata
|
|||||||
'''
|
'''
|
||||||
import os, sys, shutil, cStringIO, glob, time, functools, traceback, re, \
|
import os, sys, shutil, cStringIO, glob, time, functools, traceback, re, \
|
||||||
json, uuid, tempfile, hashlib
|
json, uuid, tempfile, hashlib
|
||||||
|
from collections import defaultdict
|
||||||
import threading, random
|
import threading, random
|
||||||
from itertools import repeat
|
from itertools import repeat
|
||||||
from math import ceil
|
from math import ceil
|
||||||
@ -487,6 +488,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.refresh_ondevice = functools.partial(self.data.refresh_ondevice, self)
|
self.refresh_ondevice = functools.partial(self.data.refresh_ondevice, self)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
self.last_update_check = self.last_modified()
|
self.last_update_check = self.last_modified()
|
||||||
|
self.format_metadata_cache = defaultdict(dict)
|
||||||
|
|
||||||
def break_cycles(self):
|
def break_cycles(self):
|
||||||
self.data.break_cycles()
|
self.data.break_cycles()
|
||||||
@ -914,11 +916,15 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
mi.book_size = row[fm['size']]
|
mi.book_size = row[fm['size']]
|
||||||
mi.ondevice_col= row[fm['ondevice']]
|
mi.ondevice_col= row[fm['ondevice']]
|
||||||
mi.last_modified = row[fm['last_modified']]
|
mi.last_modified = row[fm['last_modified']]
|
||||||
|
id = idx if index_is_id else self.id(idx)
|
||||||
formats = row[fm['formats']]
|
formats = row[fm['formats']]
|
||||||
|
mi.format_metadata = {}
|
||||||
if not formats:
|
if not formats:
|
||||||
formats = None
|
formats = None
|
||||||
else:
|
else:
|
||||||
formats = formats.split(',')
|
formats = formats.split(',')
|
||||||
|
for f in formats:
|
||||||
|
mi.format_metadata[f] = self.format_metadata(id, f, allow_cache=True)
|
||||||
mi.formats = formats
|
mi.formats = formats
|
||||||
tags = row[fm['tags']]
|
tags = row[fm['tags']]
|
||||||
if tags:
|
if tags:
|
||||||
@ -927,7 +933,6 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if mi.series:
|
if mi.series:
|
||||||
mi.series_index = row[fm['series_index']]
|
mi.series_index = row[fm['series_index']]
|
||||||
mi.rating = row[fm['rating']]
|
mi.rating = row[fm['rating']]
|
||||||
id = idx if index_is_id else self.id(idx)
|
|
||||||
mi.set_identifiers(self.get_identifiers(id, index_is_id=True))
|
mi.set_identifiers(self.get_identifiers(id, index_is_id=True))
|
||||||
mi.application_id = id
|
mi.application_id = id
|
||||||
mi.id = id
|
mi.id = id
|
||||||
@ -1126,13 +1131,16 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if m:
|
if m:
|
||||||
return m['mtime']
|
return m['mtime']
|
||||||
|
|
||||||
def format_metadata(self, id_, fmt):
|
def format_metadata(self, id_, fmt, allow_cache=True):
|
||||||
|
if allow_cache and fmt in self.format_metadata_cache.get(id_, {}):
|
||||||
|
return self.format_metadata_cache[id_][fmt]
|
||||||
path = self.format_abspath(id_, fmt, index_is_id=True)
|
path = self.format_abspath(id_, fmt, index_is_id=True)
|
||||||
ans = {}
|
ans = {}
|
||||||
if path is not None:
|
if path is not None:
|
||||||
stat = os.stat(path)
|
stat = os.stat(path)
|
||||||
ans['size'] = stat.st_size
|
ans['size'] = stat.st_size
|
||||||
ans['mtime'] = utcfromtimestamp(stat.st_mtime)
|
ans['mtime'] = utcfromtimestamp(stat.st_mtime)
|
||||||
|
self.format_metadata_cache[id_][fmt] = ans
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def format_hash(self, id_, fmt):
|
def format_hash(self, id_, fmt):
|
||||||
@ -1254,6 +1262,11 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
ret.name = f.name
|
ret.name = f.name
|
||||||
else:
|
else:
|
||||||
ret = f.read()
|
ret = f.read()
|
||||||
|
try:
|
||||||
|
self.format_metadata(index if index_is_id else self.id(index),
|
||||||
|
format, allow_cache=False)
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def add_format_with_hooks(self, index, format, fpath, index_is_id=False,
|
def add_format_with_hooks(self, index, format, fpath, index_is_id=False,
|
||||||
|
@ -519,6 +519,41 @@ class BuiltinSelect(BuiltinFormatterFunction):
|
|||||||
return v[len(key)+1:]
|
return v[len(key)+1:]
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
class BuiltinFormatsModtimes(BuiltinFormatterFunction):
|
||||||
|
name = 'formats_modtimes'
|
||||||
|
arg_count = 0
|
||||||
|
category = 'Get values from metadata'
|
||||||
|
__doc__ = doc = _('formats_modtimes() -- return a comma-separated list of '
|
||||||
|
'colon_separated items representing modification times '
|
||||||
|
'for the formats of a book. You can use the select '
|
||||||
|
'function to get the mod time for a specific '
|
||||||
|
'format. Note that format names are always uppercase, '
|
||||||
|
'as in EPUB.'
|
||||||
|
)
|
||||||
|
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals):
|
||||||
|
fmt_data = mi.get('format_metadata', {})
|
||||||
|
print fmt_data
|
||||||
|
return ','.join(k.upper()+':'+format_date(v['mtime'], 'iso')
|
||||||
|
for k,v in fmt_data.iteritems())
|
||||||
|
|
||||||
|
class BuiltinFormatsSizes(BuiltinFormatterFunction):
|
||||||
|
name = 'formats_sizes'
|
||||||
|
arg_count = 0
|
||||||
|
category = 'Get values from metadata'
|
||||||
|
__doc__ = doc = _('formats_sizes() -- return a comma-separated list of '
|
||||||
|
'colon_separated items representing sizes '
|
||||||
|
'of the formats of a book. You can use the select '
|
||||||
|
'function to get the size for a specific '
|
||||||
|
'format. Note that format names are always uppercase, '
|
||||||
|
'as in EPUB.'
|
||||||
|
)
|
||||||
|
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals):
|
||||||
|
fmt_data = mi.get('format_metadata', {})
|
||||||
|
print fmt_data
|
||||||
|
return ','.join(k.upper()+':'+str(v['size']) for k,v in fmt_data.iteritems())
|
||||||
|
|
||||||
class BuiltinSublist(BuiltinFormatterFunction):
|
class BuiltinSublist(BuiltinFormatterFunction):
|
||||||
name = 'sublist'
|
name = 'sublist'
|
||||||
arg_count = 4
|
arg_count = 4
|
||||||
@ -814,6 +849,8 @@ builtin_eval = BuiltinEval()
|
|||||||
builtin_first_non_empty = BuiltinFirstNonEmpty()
|
builtin_first_non_empty = BuiltinFirstNonEmpty()
|
||||||
builtin_field = BuiltinField()
|
builtin_field = BuiltinField()
|
||||||
builtin_format_date = BuiltinFormatDate()
|
builtin_format_date = BuiltinFormatDate()
|
||||||
|
builtin_formats_modt= BuiltinFormatsModtimes()
|
||||||
|
builtin_formats_size= BuiltinFormatsSizes()
|
||||||
builtin_identifier_in_list = BuiltinIdentifierInList()
|
builtin_identifier_in_list = BuiltinIdentifierInList()
|
||||||
builtin_ifempty = BuiltinIfempty()
|
builtin_ifempty = BuiltinIfempty()
|
||||||
builtin_in_list = BuiltinInList()
|
builtin_in_list = BuiltinInList()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user