9
9
'Marshall T. Vandegrift <llasram@gmail.com>'
10
10
__docformat__ = 'restructuredtext en'
14
12
from struct import pack, unpack
15
13
from cStringIO import StringIO
16
from calibre.ebooks.metadata import get_parser
14
from datetime import datetime
17
16
from calibre.ebooks.mobi import MobiError
18
from calibre.ebooks.mobi.reader import get_metadata
19
17
from calibre.ebooks.mobi.writer import rescale_image, MAX_THUMB_DIMEN
20
18
from calibre.ebooks.mobi.langcodes import iana2mobi
22
20
class StreamSlicer(object):
23
22
def __init__(self, stream, start=0, stop=None):
24
23
self._stream = stream
88
87
flags, = unpack('>I', record0[128:132])
89
88
have_exth = self.have_exth = (flags & 0x40) != 0
90
89
self.cover_record = self.thumbnail_record = None
93
93
exth_off = unpack('>I', record0[20:24])[0] + 16 + record0.start
94
94
exth = self.exth = StreamSlicer(stream, exth_off, record0.stop)
95
95
nitems, = unpack('>I', exth[8:12])
97
# Store any EXTH fields not specifiable in GUI
97
98
for i in xrange(nitems):
98
99
id, size = unpack('>II', exth[pos:pos + 8])
99
100
content = exth[pos + 8: pos + size]
104
self.timestamp = content
102
106
rindex, = self.cover_rindex, = unpack('>I', content)
103
107
self.cover_record = self.record(rindex + image_base)
118
122
def update(self, mi):
120
from calibre.ebooks.mobi.from_any import config
121
if mi.author_sort and config().parse().prefer_author_sort:
125
from calibre.ebooks.conversion.config import load_defaults
126
prefs = load_defaults('mobi_output')
127
pas = prefs.get('prefer_author_sort', False)
130
if mi.author_sort and pas:
122
131
authors = mi.author_sort
123
132
recs.append((100, authors.encode(self.codec, 'replace')))
134
143
subjects = '; '.join(mi.tags)
135
144
recs.append((105, subjects.encode(self.codec, 'replace')))
147
recs.append((106, str(mi.pubdate).encode(self.codec, 'replace')))
149
recs.append((106, str(mi.timestamp).encode(self.codec, 'replace')))
151
recs.append((106, self.timestamp))
153
recs.append((106, str(datetime.now()).encode(self.codec, 'replace')))
136
155
if self.cover_record is not None:
137
156
recs.append((201, pack('>I', self.cover_rindex)))
138
157
recs.append((203, pack('>I', 0)))
182
201
mu = MetadataUpdater(stream)
188
parser = get_parser('mobi')
189
parser.remove_option('--category')
190
parser.add_option('--tags', default=None,
191
help=_('Set the subject tags'))
192
parser.add_option('--language', default=None,
193
help=_('Set the language'))
194
parser.add_option('--publisher', default=None,
195
help=_('Set the publisher'))
196
parser.add_option('--isbn', default=None,
197
help=_('Set the ISBN'))
200
def main(args=sys.argv):
201
parser = option_parser()
202
opts, args = parser.parse_args(args)
205
print >>sys.stderr, 'Usage: %s file.mobi' % args[0]
209
with open(fname, 'r+b') as stream:
210
mi = get_metadata(stream)
212
mi.title = opts.title
215
mi.authors = opts.authors.split(',')
218
mi.comments = opts.comment
220
if opts.tags is not None:
221
mi.tags = opts.tags.split(',')
223
if opts.language is not None:
224
mi.language = opts.language
226
if opts.publisher is not None:
227
mi.publisher = opts.publisher
229
if opts.isbn is not None:
233
set_metadata(stream, mi)
234
print unicode(get_metadata(stream))
235
if not changed and mi.cover_data[1]:
236
cover = os.path.abspath(
237
'.'.join((os.path.splitext(os.path.basename(fname))[0],
238
mi.cover_data[0].lower())))
239
open(cover, 'wb').write(mi.cover_data[1])
240
print _('Cover saved to'), cover
243
if __name__ == '__main__':