diff --git a/src/calibre/ebooks/metadata/epub.py b/src/calibre/ebooks/metadata/epub.py index 6b57879ee2..8894362766 100644 --- a/src/calibre/ebooks/metadata/epub.py +++ b/src/calibre/ebooks/metadata/epub.py @@ -8,6 +8,7 @@ __copyright__ = '2008, Kovid Goyal ' import os, re, posixpath from cStringIO import StringIO from contextlib import closing +from future_builtins import map from calibre.utils.zipfile import ZipFile, BadZipfile, safe_replace from calibre.utils.localunzip import LocalZipFile @@ -250,17 +251,31 @@ def _write_new_cover(new_cdata, cpath): save_cover_data_to(new_cdata, new_cover.name) return new_cover +def normalize_languages(opf_languages, mi_languages): + ' Preserve original country codes and use 2-letter lang codes where possible ' + from calibre.spell import parse_lang_code + def parse(x): + try: + return parse_lang_code(x) + except ValueError: + return None + opf_languages = filter(None, map(parse, opf_languages)) + cc_map = {c.langcode:c.countrycode for c in opf_languages} + mi_languages = filter(None, map(parse, mi_languages)) + def norm(x): + lc = x.langcode + cc = x.countrycode or cc_map.get(lc, None) + lc = lang_as_iso639_1(lc) or lc + if cc: + lc += '-' + cc + return lc + return list(map(norm, mi_languages)) + def update_metadata(opf, mi, apply_null=False, update_timestamp=False, force_identifiers=False): for x in ('guide', 'toc', 'manifest', 'spine'): setattr(mi, x, None) if mi.languages: - langs = [] - for lc in mi.languages: - lc2 = lang_as_iso639_1(lc) - if lc2: - lc = lc2 - langs.append(lc) - mi.languages = langs + mi.languages = normalize_languages(list(opf.raw_languages) or [], mi.languages) opf.smart_update(mi) if getattr(mi, 'uuid', None): diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 319a72f694..7b71e03cc1 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -27,6 +27,7 @@ from calibre.utils.config import tweaks pretty_print_opf = False class PrettyPrint(object): + def __enter__(self): global pretty_print_opf pretty_print_opf = True @@ -42,6 +43,7 @@ def _pretty_print(root): pretty_xml_tree(root) class Resource(object): # {{{ + ''' Represents a resource (usually a file on the filesystem or a URL pointing to the web. Such resources are commonly referred to in OPF files. @@ -1083,6 +1085,13 @@ class OPF(object): # {{{ return property(fget=fget, fset=fset) + @property + def raw_languages(self): + for match in self.languages_path(self.metadata): + t = self.get_text(match) + if t and t.strip(): + yield t.strip() + @dynamic_property def book_producer(self): @@ -1728,6 +1737,6 @@ def test_user_metadata(): print opf.render() if __name__ == '__main__': - #test_user_metadata() + # test_user_metadata() test_m2o() test()