mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Edit Book: Automatically updated the modified timestamp when editing EPUB 3 books on save.
This commit is contained in:
parent
0a94c5420c
commit
b88c6580d7
@ -2,23 +2,32 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import json
|
||||
import re
|
||||
from collections import defaultdict, namedtuple
|
||||
from functools import wraps
|
||||
from future_builtins import map
|
||||
import re, json
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from calibre import prints
|
||||
from calibre.ebooks.metadata import check_isbn, authors_to_string, string_to_authors
|
||||
from calibre.ebooks.metadata import authors_to_string, check_isbn, string_to_authors
|
||||
from calibre.ebooks.metadata.book.base import Metadata
|
||||
from calibre.ebooks.metadata.book.json_codec import object_to_unicode, decode_is_multiple, encode_is_multiple
|
||||
from calibre.ebooks.metadata.utils import parse_opf, pretty_print_opf, ensure_unique, normalize_languages, create_manifest_item
|
||||
from calibre.ebooks.oeb.base import OPF2_NSMAP, OPF, DC
|
||||
from calibre.ebooks.metadata.book.json_codec import (
|
||||
decode_is_multiple, encode_is_multiple, object_to_unicode
|
||||
)
|
||||
from calibre.ebooks.metadata.utils import (
|
||||
create_manifest_item, ensure_unique, normalize_languages, parse_opf,
|
||||
pretty_print_opf
|
||||
)
|
||||
from calibre.ebooks.oeb.base import DC, OPF, OPF2_NSMAP
|
||||
from calibre.utils.config import from_json, to_json
|
||||
from calibre.utils.date import parse_date as parse_date_, fix_only_date, is_date_undefined, isoformat
|
||||
from calibre.utils.date import (
|
||||
fix_only_date, is_date_undefined, isoformat, parse_date as parse_date_, utcnow,
|
||||
w3cdtf
|
||||
)
|
||||
from calibre.utils.iso8601 import parse_iso8601
|
||||
from calibre.utils.localization import canonicalize_lang
|
||||
|
||||
@ -575,23 +584,23 @@ def read_timestamp(root, prefixes, refines):
|
||||
continue
|
||||
|
||||
|
||||
def create_timestamp(m, val):
|
||||
def create_timestamp(root, prefixes, m, val):
|
||||
if not is_date_undefined(val):
|
||||
val = isoformat(val)
|
||||
ensure_prefix(root, prefixes, 'calibre', CALIBRE_PREFIX)
|
||||
ensure_prefix(root, prefixes, 'dcterms')
|
||||
val = w3cdtf(val)
|
||||
d = m.makeelement(OPF('meta'), attrib={'property':'calibre:timestamp', 'scheme':'dcterms:W3CDTF'})
|
||||
d.text = val
|
||||
m.append(d)
|
||||
|
||||
|
||||
def set_timestamp(root, prefixes, refines, val):
|
||||
ensure_prefix(root, prefixes, 'calibre', CALIBRE_PREFIX)
|
||||
ensure_prefix(root, prefixes, 'dcterms')
|
||||
pq = '%s:timestamp' % CALIBRE_PREFIX
|
||||
for meta in XPath('./opf:metadata/opf:meta')(root):
|
||||
prop = expand_prefix(meta.get('property'), prefixes)
|
||||
if prop.lower() == pq or meta.get('name') == 'calibre:timestamp':
|
||||
remove_element(meta, refines)
|
||||
create_timestamp(XPath('./opf:metadata')(root)[0], val)
|
||||
create_timestamp(root, prefixes, XPath('./opf:metadata')(root)[0], val)
|
||||
|
||||
|
||||
def read_last_modified(root, prefixes, refines):
|
||||
@ -607,6 +616,23 @@ def read_last_modified(root, prefixes, refines):
|
||||
return parse_date(val, is_w3cdtf=scheme == sq)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
def set_last_modified(root, prefixes, refines, val=None):
|
||||
pq = '%s:modified' % reserved_prefixes['dcterms']
|
||||
sq = '%s:w3cdtf' % reserved_prefixes['dcterms']
|
||||
val = w3cdtf(val or utcnow())
|
||||
for meta in XPath('./opf:metadata/opf:meta[@property]')(root):
|
||||
prop = expand_prefix(meta.get('property'), prefixes)
|
||||
if prop.lower() == pq:
|
||||
iid = meta.get('id')
|
||||
if not iid or not refines[iid]:
|
||||
break
|
||||
else:
|
||||
ensure_prefix(root, prefixes, 'dcterms')
|
||||
m = XPath('./opf:metadata')(root)[0]
|
||||
meta = m.makeelement(OPF('meta'), attrib={'property':'dcterms:modified', 'scheme':'dcterms:W3CDTF'})
|
||||
m.append(meta)
|
||||
meta.text = val
|
||||
# }}}
|
||||
|
||||
# Comments {{{
|
||||
@ -933,6 +959,11 @@ def first_spine_item(root, prefixes, refines):
|
||||
return item.get('href') or None
|
||||
|
||||
|
||||
def set_last_modified_in_opf(root):
|
||||
prefixes, refines = read_prefixes(root), read_refines(root)
|
||||
set_last_modified(root, prefixes, refines)
|
||||
|
||||
|
||||
def read_metadata(root, ver=None, return_extra_data=False):
|
||||
ans = Metadata(_('Unknown'), [_('Unknown')])
|
||||
prefixes, refines = read_prefixes(root), read_refines(root)
|
||||
|
@ -1294,7 +1294,14 @@ class EpubContainer(Container):
|
||||
f.write(raw)
|
||||
self.obfuscated_fonts[font] = (alg, tkey)
|
||||
|
||||
def update_modified_timestamp(self):
|
||||
from calibre.ebooks.metadata.opf3 import set_last_modified_in_opf
|
||||
set_last_modified_in_opf(self.opf)
|
||||
self.dirty(self.opf_name)
|
||||
|
||||
def commit(self, outpath=None, keep_parsed=False):
|
||||
if self.opf_version_parsed.major == 3:
|
||||
self.update_modified_timestamp()
|
||||
super(EpubContainer, self).commit(keep_parsed=keep_parsed)
|
||||
container_path = join(self.root, 'META-INF', 'container.xml')
|
||||
if not exists(container_path):
|
||||
|
@ -193,6 +193,15 @@ def isoformat(date_time, assume_utc=False, as_utc=True, sep='T'):
|
||||
return unicode(date_time.isoformat(str(sep)))
|
||||
|
||||
|
||||
def w3cdtf(date_time, assume_utc=False):
|
||||
if hasattr(date_time, 'tzinfo'):
|
||||
if date_time.tzinfo is None:
|
||||
date_time = date_time.replace(tzinfo=_utc_tz if assume_utc else
|
||||
_local_tz)
|
||||
date_time = date_time.astimezone(_utc_tz if as_utc else _local_tz)
|
||||
return unicode(date_time.strftime('%Y-%M-%dT%H:%M:%SZ'))
|
||||
|
||||
|
||||
def as_local_time(date_time, assume_utc=True):
|
||||
if not hasattr(date_time, 'tzinfo'):
|
||||
return date_time
|
||||
|
Loading…
x
Reference in New Issue
Block a user