Use JSON to store conversion options

More portable than using ast.literal_eval()
This commit is contained in:
Kovid Goyal 2018-03-07 13:18:11 +05:30
parent 6906981702
commit 9819acf05f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os, ast import os, ast, json
from calibre.utils.config import config_dir from calibre.utils.config import config_dir
from calibre.utils.lock import ExclusiveFile from calibre.utils.lock import ExclusiveFile
@ -25,8 +25,8 @@ def name_to_path(name):
def save_defaults(name, recs): def save_defaults(name, recs):
path = name_to_path(name) path = name_to_path(name)
raw = str(recs) raw = recs.serialize()
with open(path, 'wb'): with lopen(path, 'wb'):
pass pass
with ExclusiveFile(path) as f: with ExclusiveFile(path) as f:
f.write(raw) f.write(raw)
@ -40,12 +40,12 @@ def load_defaults(name):
raw = f.read() raw = f.read()
r = GuiRecommendations() r = GuiRecommendations()
if raw: if raw:
r.from_string(raw) r.deserialize(raw)
return r return r
def save_specifics(db, book_id, recs): def save_specifics(db, book_id, recs):
raw = str(recs) raw = recs.serialize()
db.set_conversion_options(book_id, 'PIPE', raw) db.set_conversion_options(book_id, 'PIPE', raw)
@ -53,7 +53,7 @@ def load_specifics(db, book_id):
raw = db.conversion_options(book_id, 'PIPE') raw = db.conversion_options(book_id, 'PIPE')
r = GuiRecommendations() r = GuiRecommendations()
if raw: if raw:
r.from_string(raw) r.deserialize(raw)
return r return r
@ -82,14 +82,24 @@ class GuiRecommendations(dict):
ans.append('}') ans.append('}')
return '\n'.join(ans) return '\n'.join(ans)
def from_string(self, raw): def serialize(self):
ans = json.dumps(self, indent=2, ensure_ascii=False)
if isinstance(ans, unicode):
ans = ans.encode('utf-8')
return b'json:' + ans
def deserialize(self, raw):
try: try:
if raw.startswith(b'json:'):
d = json.loads(raw[len(b'json:'):])
else:
d = ast.literal_eval(raw) d = ast.literal_eval(raw)
except Exception: except Exception:
pass pass
else: else:
if d: if d:
self.update(d) self.update(d)
from_string = deserialize
def merge_recommendations(self, get_option, level, options, def merge_recommendations(self, get_option, level, options,
only_existing=False): only_existing=False):