Beispiel #1
0
def add_quick_start_guide(library_view, refresh_cover_browser=None):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks import calibre_cover
    from calibre.utils.zipfile import safe_replace
    from calibre.utils.localization import get_lang, canonicalize_lang
    from calibre.ptempfile import PersistentTemporaryFile
    l = canonicalize_lang(get_lang()) or 'eng'
    gprefs['quick_start_guide_added'] = True
    imgbuf = BytesIO(calibre_cover(_('Quick Start Guide'), '', author_size=8))
    try:
        with open(P('quick_start/%s.epub' % l), 'rb') as src:
            buf = BytesIO(src.read())
    except EnvironmentError as err:
        if err.errno != errno.ENOENT:
            raise
        with open(P('quick_start/eng.epub'), 'rb') as src:
            buf = BytesIO(src.read())
    safe_replace(buf, 'images/cover.jpg', imgbuf)
    buf.seek(0)
    mi = get_metadata(buf, 'epub')
    with PersistentTemporaryFile('.epub') as tmp:
        tmp.write(buf.getvalue())
    library_view.model().add_books([tmp.name], ['epub'], [mi])
    os.remove(tmp.name)
    library_view.model().books_added(1)
    if refresh_cover_browser is not None:
        refresh_cover_browser()
    if library_view.model().rowCount(None) < 3:
        library_view.resizeColumnsToContents()
Beispiel #2
0
    def default_cover(self):
        '''
        Create a generic cover for books that dont have a cover
        '''
        from calibre.ebooks.metadata import authors_to_string, fmt_sidx
        if self.no_default_cover:
            return None
        self.log('Generating default cover')
        m = self.oeb.metadata
        title = unicode(m.title[0])
        authors = [unicode(x) for x in m.creator if x.role == 'aut']
        series_string = None
        if m.series and m.series_index:
            series_string = _('Book %(sidx)s of %(series)s')%dict(
                    sidx=fmt_sidx(m.series_index[0], use_roman=True),
                    series=unicode(m.series[0]))

        try:
            from calibre.ebooks import calibre_cover
            img_data = calibre_cover(title, authors_to_string(authors),
                    series_string=series_string)
            id, href = self.oeb.manifest.generate('cover',
                    u'cover_image.jpg')
            item = self.oeb.manifest.add(id, href, guess_type('t.jpg')[0],
                        data=img_data)
            m.clear('cover')
            m.add('cover', item.id)

            return item.href
        except:
            self.log.exception('Failed to generate default cover')
        return None
Beispiel #3
0
def add_quick_start_guide(library_view, refresh_cover_browser=None):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks import calibre_cover
    from calibre.utils.zipfile import safe_replace
    from calibre.utils.localization import get_lang, canonicalize_lang
    from calibre.ptempfile import PersistentTemporaryFile
    l = canonicalize_lang(get_lang()) or 'eng'
    gprefs['quick_start_guide_added'] = True
    imgbuf = BytesIO(calibre_cover(_('Quick Start Guide'), '', author_size=8))
    try:
        with open(P('quick_start/%s.epub' % l), 'rb') as src:
            buf = BytesIO(src.read())
    except EnvironmentError as err:
        if err.errno != errno.ENOENT:
            raise
        with open(P('quick_start/eng.epub'), 'rb') as src:
            buf = BytesIO(src.read())
    safe_replace(buf, 'images/cover.jpg', imgbuf)
    buf.seek(0)
    mi = get_metadata(buf, 'epub')
    with PersistentTemporaryFile('.epub') as tmp:
        tmp.write(buf.getvalue())
    library_view.model().add_books([tmp.name], ['epub'], [mi])
    os.remove(tmp.name)
    library_view.model().books_added(1)
    if refresh_cover_browser is not None:
        refresh_cover_browser()
    if library_view.model().rowCount(None) < 3:
        library_view.resizeColumnsToContents()
Beispiel #4
0
def add_quick_start_guide(library_view, db_images):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks import calibre_cover
    from calibre.utils.zipfile import safe_replace
    from calibre.utils.localization import get_lang, canonicalize_lang
    from calibre.ptempfile import PersistentTemporaryFile

    l = canonicalize_lang(get_lang()) or "eng"
    gprefs["quick_start_guide_added"] = True
    imgbuf = BytesIO(calibre_cover(_("Quick Start Guide"), "", author_size=8))
    try:
        with open(P("quick_start/%s.epub" % l), "rb") as src:
            buf = BytesIO(src.read())
    except EnvironmentError as err:
        if err.errno != errno.ENOENT:
            raise
        with open(P("quick_start/eng.epub"), "rb") as src:
            buf = BytesIO(src.read())
    safe_replace(buf, "images/cover.jpg", imgbuf)
    buf.seek(0)
    mi = get_metadata(buf, "epub")
    with PersistentTemporaryFile(".epub") as tmp:
        tmp.write(buf.getvalue())
    library_view.model().add_books([tmp.name], ["epub"], [mi])
    os.remove(tmp.name)
    library_view.model().books_added(1)
    if hasattr(db_images, "reset"):
        db_images.reset()
    if library_view.model().rowCount(None) < 3:
        library_view.resizeColumnsToContents()
Beispiel #5
0
    def default_cover(self):
        '''
        Create a generic cover for books that dont have a cover
        '''
        from calibre.ebooks.metadata import authors_to_string, fmt_sidx
        if self.no_default_cover:
            return None
        self.log('Generating default cover')
        m = self.oeb.metadata
        title = unicode(m.title[0])
        authors = [unicode(x) for x in m.creator if x.role == 'aut']
        series_string = None
        if m.series and m.series_index:
            series_string = _('Book %(sidx)s of %(series)s') % dict(
                sidx=fmt_sidx(m.series_index[0], use_roman=True),
                series=unicode(m.series[0]))

        try:
            from calibre.ebooks import calibre_cover
            img_data = calibre_cover(title,
                                     authors_to_string(authors),
                                     series_string=series_string)
            id, href = self.oeb.manifest.generate('cover', u'cover_image.jpg')
            item = self.oeb.manifest.add(id,
                                         href,
                                         guess_type('t.jpg')[0],
                                         data=img_data)
            m.clear('cover')
            m.add('cover', item.id)

            return item.href
        except:
            self.log.exception('Failed to generate default cover')
        return None
Beispiel #6
0
 def replace_wmf(self, name):
     from calibre.ebooks import calibre_cover
     if self.default_img is None:
         self.default_img = calibre_cover('Conversion of WMF images is not supported',
         'Use Microsoft Word or OpenOffice to save this RTF file'
         ' as HTML and convert that in calibre.', title_size=36,
         author_size=20)
     name = name.replace('.wmf', '.jpg')
     with open(name, 'wb') as f:
         f.write(self.default_img)
     return name
Beispiel #7
0
def test_imaging():
    from calibre.ebooks import calibre_cover
    data = calibre_cover('test', 'ok')
    if len(data) > 1000:
        print ('ImageMagick OK!')
    else:
        raise RuntimeError('ImageMagick choked!')
    from PIL import Image
    i = Image.open(cStringIO.StringIO(data))
    if i.size < (20, 20):
        raise RuntimeError('PIL choked!')
    print ('PIL OK!')
def test_imaging():
    from calibre.ebooks import calibre_cover
    data = calibre_cover('test', 'ok')
    if len(data) > 1000:
        print('ImageMagick OK!')
    else:
        raise RuntimeError('ImageMagick choked!')
    from PIL import Image
    i = Image.open(cStringIO.StringIO(data))
    if i.size < (20, 20):
        raise RuntimeError('PIL choked!')
    print('PIL OK!')
Beispiel #9
0
 def replace_wmf(self, name):
     from calibre.ebooks import calibre_cover
     if self.default_img is None:
         self.default_img = calibre_cover(
             'Conversion of WMF images is not supported',
             'Use Microsoft Word or OpenOffice to save this RTF file'
             ' as HTML and convert that in calibre.',
             title_size=36,
             author_size=20)
     name = name.replace('.wmf', '.jpg')
     with open(name, 'wb') as f:
         f.write(self.default_img)
     return name
 def default_cover(self, cover_file):
     """
     Create a generic cover for recipes that don't have a cover
     This override adds time to the cover
     """
     try:
         from calibre.ebooks import calibre_cover
         title = self.title if isinstance(self.title, unicode) else \
             self.title.decode('utf-8', 'replace')
         date = strftime(self.timefmt)
         time = strftime('[%I:%M %p]')
         img_data = calibre_cover(title, date, time)
         cover_file.write(img_data)
         cover_file.flush()
     except:
         self.log.exception('Failed to generate default cover')
         return False
     return True
Beispiel #11
0
    def upload_cover(self, path, filename, metadata, filepath):
        from calibre.ebooks import calibre_cover
        from calibre.utils.magick.draw import thumbnail
        coverdata = getattr(metadata, 'thumbnail', None)
        if coverdata and coverdata[2]:
            cover = coverdata[2]
        else:
            cover = calibre_cover(metadata.get('title', _('Unknown')),
                    metadata.get('authors', _('Unknown')))

        cover = thumbnail(cover, width=self.THUMBNAIL_HEIGHT,
                height=self.THUMBNAIL_HEIGHT, fmt='png')[-1]

        cpath = self.alex_cpath(os.path.join(path, filename))
        cdir = os.path.dirname(cpath)
        if not os.path.exists(cdir):
            os.makedirs(cdir)
        with open(cpath, 'wb') as coverfile:
            coverfile.write(cover)
Beispiel #12
0
 def generate_cover(self, *args):
     from calibre.ebooks import calibre_cover
     from calibre.ebooks.metadata import fmt_sidx
     from calibre.gui2 import config
     title = self.dialog.title.current_val
     author = authors_to_string(self.dialog.authors.current_val)
     if not title or not author:
         return error_dialog(self, _('Specify title and author'),
                 _('You must specify a title and author before generating '
                     'a cover'), show=True)
     series = self.dialog.series.current_val
     series_string = None
     if series:
         series_string = _('Book %(sidx)s of %(series)s')%dict(
                 sidx=fmt_sidx(self.dialog.series_index.current_val,
                 use_roman=config['use_roman_numerals_for_series_number']),
                 series=series)
     self.current_val = calibre_cover(title, author,
             series_string=series_string)
Beispiel #13
0
def test_imaging():
    from calibre.ebooks import calibre_cover

    data = calibre_cover("test", "ok")
    if len(data) > 1000:
        print("ImageMagick OK!")
    else:
        raise RuntimeError("ImageMagick choked!")
    from PIL import Image

    try:
        import _imaging, _imagingmath, _imagingft

        _imaging, _imagingmath, _imagingft
    except ImportError:
        from PIL import _imaging, _imagingmath, _imagingft
    _imaging, _imagingmath, _imagingft
    i = Image.open(cStringIO.StringIO(data))
    if i.size < (20, 20):
        raise RuntimeError("PIL choked!")
    print("PIL OK!")
Beispiel #14
0
    def upload_cover(self, path, filename, metadata, filepath):
        from calibre.ebooks import calibre_cover
        from calibre.utils.magick.draw import thumbnail
        coverdata = getattr(metadata, 'thumbnail', None)
        if coverdata and coverdata[2]:
            cover = coverdata[2]
        else:
            cover = calibre_cover(metadata.get('title', _('Unknown')),
                                  metadata.get('authors', _('Unknown')))

        cover = thumbnail(cover,
                          width=self.THUMBNAIL_HEIGHT,
                          height=self.THUMBNAIL_HEIGHT,
                          fmt='png')[-1]

        cpath = self.alex_cpath(os.path.join(path, filename))
        cdir = os.path.dirname(cpath)
        if not os.path.exists(cdir):
            os.makedirs(cdir)
        with open(cpath, 'wb') as coverfile:
            coverfile.write(cover)
            fsync(coverfile)
Beispiel #15
0
 def generate_cover(self, *args):
     from calibre.ebooks import calibre_cover
     from calibre.ebooks.metadata import fmt_sidx
     from calibre.gui2 import config
     title = self.dialog.title.current_val
     author = authors_to_string(self.dialog.authors.current_val)
     if not title or not author:
         return error_dialog(
             self,
             _('Specify title and author'),
             _('You must specify a title and author before generating '
               'a cover'),
             show=True)
     series = self.dialog.series.current_val
     series_string = None
     if series:
         series_string = _('Book %(sidx)s of %(series)s') % dict(
             sidx=fmt_sidx(
                 self.dialog.series_index.current_val,
                 use_roman=config['use_roman_numerals_for_series_number']),
             series=series)
     self.current_val = calibre_cover(title,
                                      author,
                                      series_string=series_string)
Beispiel #16
0
                    if cpath and os.path.exists(cpath):
                        existing_cover = True
            except:
                pass

            if self.opts.use_existing_cover and not existing_cover:
                log.warning("no existing catalog cover found")

            if self.opts.use_existing_cover and existing_cover:
                recommendations.append(
                    ('cover', cpath, OptionRecommendation.HIGH))
                log.info("using existing catalog cover")
            else:
                log.info("replacing catalog cover")
                new_cover_path = PersistentTemporaryFile(suffix='.jpg')
                new_cover = calibre_cover(
                    opts.catalog_title.replace('"', '\\"'), 'calibre')
                new_cover_path.write(new_cover)
                new_cover_path.close()
                recommendations.append(
                    ('cover', new_cover_path.name, OptionRecommendation.HIGH))

            # Run ebook-convert
            from calibre.ebooks.conversion.plumber import Plumber
            plumber = Plumber(os.path.join(catalog.catalog_path,
                                           opts.basename + '.opf'),
                              path_to_output,
                              log,
                              report_progress=notification,
                              abort_after_input_dump=False)
            plumber.merge_ui_recommendations(recommendations)
            plumber.run()
Beispiel #17
0
                    cpath = db.cover(matches[0], index_is_id=True, as_path=True)
                    if cpath and os.path.exists(cpath):
                        existing_cover = True
            except:
                pass

            if self.opts.use_existing_cover and not existing_cover:
                log.warning("no existing catalog cover found")

            if self.opts.use_existing_cover and existing_cover:
                recommendations.append(('cover', cpath, OptionRecommendation.HIGH))
                log.info("using existing catalog cover")
            else:
                log.info("replacing catalog cover")
                new_cover_path = PersistentTemporaryFile(suffix='.jpg')
                new_cover = calibre_cover(opts.catalog_title.replace('"', '\\"'), 'calibre')
                new_cover_path.write(new_cover)
                new_cover_path.close()
                recommendations.append(('cover', new_cover_path.name, OptionRecommendation.HIGH))

            # Run ebook-convert
            from calibre.ebooks.conversion.plumber import Plumber
            plumber = Plumber(os.path.join(catalog.catalog_path, opts.basename + '.opf'),
                            path_to_output, log, report_progress=notification,
                            abort_after_input_dump=False)
            plumber.merge_ui_recommendations(recommendations)
            plumber.run()

            try:
                os.remove(cpath)
            except:
Beispiel #18
0
    def do_one(self, id):
        remove_all, remove, add, au, aus, do_aus, rating, pub, do_series, \
            do_autonumber, do_remove_format, remove_format, do_swap_ta, \
            do_remove_conv, do_auto_author, series, do_series_restart, \
            series_start_value, do_title_case, cover_action, clear_series, \
            pubdate, adddate, do_title_sort, languages, clear_languages, \
            restore_original = self.args


        # first loop: All changes that modify the filesystem and commit
        # immediately. We want to
        # try hard to keep the DB and the file system in sync, even in the face
        # of exceptions or forced exits.
        if self.current_phase == 1:
            title_set = False
            if do_swap_ta:
                title = self.db.title(id, index_is_id=True)
                aum = self.db.authors(id, index_is_id=True)
                if aum:
                    aum = [a.strip().replace('|', ',') for a in aum.split(',')]
                    new_title = authors_to_string(aum)
                    if do_title_case:
                        new_title = titlecase(new_title)
                    self.db.set_title(id, new_title, notify=False)
                    title_set = True
                if title:
                    new_authors = string_to_authors(title)
                    self.db.set_authors(id, new_authors, notify=False)
            if do_title_case and not title_set:
                title = self.db.title(id, index_is_id=True)
                self.db.set_title(id, titlecase(title), notify=False)
            if do_title_sort:
                title = self.db.title(id, index_is_id=True)
                if languages:
                    lang = languages[0]
                else:
                    lang = self.db.languages(id, index_is_id=True)
                    if lang:
                        lang = lang.partition(',')[0]
                self.db.set_title_sort(id, title_sort(title, lang=lang),
                        notify=False)
            if au:
                self.db.set_authors(id, string_to_authors(au), notify=False)
            if cover_action == 'remove':
                self.db.remove_cover(id)
            elif cover_action == 'generate':
                from calibre.ebooks import calibre_cover
                from calibre.ebooks.metadata import fmt_sidx
                from calibre.gui2 import config
                mi = self.db.get_metadata(id, index_is_id=True)
                series_string = None
                if mi.series:
                    series_string = _('Book %(sidx)s of %(series)s')%dict(
                        sidx=fmt_sidx(mi.series_index,
                        use_roman=config['use_roman_numerals_for_series_number']),
                        series=mi.series)

                cdata = calibre_cover(mi.title, mi.format_field('authors')[-1],
                        series_string=series_string)
                self.db.set_cover(id, cdata)
            elif cover_action == 'fromfmt':
                fmts = self.db.formats(id, index_is_id=True, verify_formats=False)
                if fmts:
                    covers = []
                    for fmt in fmts.split(','):
                        fmtf = self.db.format(id, fmt, index_is_id=True,
                                as_file=True)
                        if fmtf is None: continue
                        cdata, area = get_cover_data(fmtf, fmt)
                        if cdata:
                            covers.append((cdata, area))
                    covers.sort(key=lambda x: x[1])
                    if covers:
                        self.db.set_cover(id, covers[-1][0])
                    covers = []

            if do_remove_format:
                self.db.remove_format(id, remove_format, index_is_id=True,
                        notify=False, commit=True)

            if restore_original:
                formats = self.db.formats(id, index_is_id=True)
                formats = formats.split(',') if formats else []
                originals = [x.upper() for x in formats if
                        x.upper().startswith('ORIGINAL_')]
                for ofmt in originals:
                    fmt = ofmt.replace('ORIGINAL_', '')
                    with SpooledTemporaryFile(SPOOL_SIZE) as stream:
                        self.db.copy_format_to(id, ofmt, stream,
                                index_is_id=True)
                        stream.seek(0)
                        self.db.add_format(id, fmt, stream, index_is_id=True,
                                notify=False)
                    self.db.remove_format(id, ofmt, index_is_id=True,
                            notify=False, commit=True)

        elif self.current_phase == 2:
            # All of these just affect the DB, so we can tolerate a total rollback
            if do_auto_author:
                x = self.db.author_sort_from_book(id, index_is_id=True)
                if x:
                    self.db.set_author_sort(id, x, notify=False, commit=False)

            if aus and do_aus:
                self.db.set_author_sort(id, aus, notify=False, commit=False)

            if rating != -1:
                self.db.set_rating(id, 2*rating, notify=False, commit=False)

            if pub:
                self.db.set_publisher(id, pub, notify=False, commit=False)

            if clear_series:
                self.db.set_series(id, '', notify=False, commit=False)

            if pubdate is not None:
                self.db.set_pubdate(id, pubdate, notify=False, commit=False)

            if adddate is not None:
                self.db.set_timestamp(id, adddate, notify=False, commit=False)

            if do_series:
                if do_series_restart:
                    if self.series_start_value is None:
                        self.series_start_value = series_start_value
                    next = self.series_start_value
                    self.series_start_value += 1
                else:
                    next = self.db.get_next_series_num_for(series)
                self.db.set_series(id, series, notify=False, commit=False)
                if not series:
                    self.db.set_series_index(id, 1.0, notify=False, commit=False)
                elif do_autonumber: # is True if do_series_restart is True
                    self.db.set_series_index(id, next, notify=False, commit=False)
                elif tweaks['series_index_auto_increment'] != 'no_change':
                    self.db.set_series_index(id, 1.0, notify=False, commit=False)

            if do_remove_conv:
                self.db.delete_conversion_options(id, 'PIPE', commit=False)

            if clear_languages:
                self.db.set_languages(id, [], notify=False, commit=False)
            elif languages:
                self.db.set_languages(id, languages, notify=False, commit=False)

        elif self.current_phase == 3:
            # both of these are fast enough to just do them all
            for w in self.cc_widgets:
                w.commit(self.ids)
            if remove_all:
                self.db.remove_all_tags(self.ids)
            self.db.bulk_modify_tags(self.ids, add=add, remove=remove,
                                         notify=False)
            self.current_index = len(self.ids)
        elif self.current_phase == 4:
            self.s_r_func(id)
        # do the next one
        self.current_index += 1
        self.do_one_signal.emit()
Beispiel #19
0
    def do_all(self):
        cache = self.db.new_api
        args = self.args

        # Title and authors
        if args.do_swap_ta:
            title_map = cache.all_field_for('title', self.ids)
            authors_map = cache.all_field_for('authors', self.ids)
            def new_title(authors):
                ans = authors_to_string(authors)
                return titlecase(ans) if args.do_title_case else ans
            new_title_map = {bid:new_title(authors) for bid, authors in authors_map.iteritems()}
            new_authors_map = {bid:string_to_authors(title) for bid, title in title_map.iteritems()}
            cache.set_field('authors', new_authors_map)
            cache.set_field('title', new_title_map)

        if args.do_title_case and not args.do_swap_ta:
            title_map = cache.all_field_for('title', self.ids)
            cache.set_field('title', {bid:titlecase(title) for bid, title in title_map.iteritems()})

        if args.do_title_sort:
            lang_map = cache.all_field_for('languages', self.ids)
            title_map = cache.all_field_for('title', self.ids)
            def get_sort(book_id):
                if args.languages:
                    lang = args.languages[0]
                else:
                    try:
                        lang = lang_map[book_id][0]
                    except (KeyError, IndexError, TypeError, AttributeError):
                        lang = 'eng'
                return title_sort(title_map[book_id], lang=lang)
            cache.set_field('sort', {bid:get_sort(bid) for bid in self.ids})

        if args.au:
            authors = string_to_authors(args.au)
            cache.set_field('authors', {bid:authors for bid in self.ids})

        if args.do_auto_author:
            aus_map = cache.author_sort_strings_for_books(self.ids)
            cache.set_field('author_sort', {book_id:' & '.join(aus_map[book_id]) for book_id in aus_map})

        if args.aus and args.do_aus:
            cache.set_field('author_sort', {bid:args.aus for bid in self.ids})

        # Covers
        if args.cover_action == 'remove':
            cache.set_cover({bid:None for bid in self.ids})
        elif args.cover_action == 'generate':
            from calibre.ebooks import calibre_cover
            from calibre.ebooks.metadata import fmt_sidx
            from calibre.gui2 import config
            for book_id in self.ids:
                mi = self.db.get_metadata(book_id, index_is_id=True)
                series_string = None
                if mi.series:
                    series_string = _('Book %(sidx)s of %(series)s')%dict(
                        sidx=fmt_sidx(mi.series_index,
                        use_roman=config['use_roman_numerals_for_series_number']),
                        series=mi.series)

                cdata = calibre_cover(mi.title, mi.format_field('authors')[-1],
                        series_string=series_string)
                cache.set_cover({book_id:cdata})
        elif args.cover_action == 'fromfmt':
            for book_id in self.ids:
                fmts = cache.formats(book_id, verify_formats=False)
                if fmts:
                    covers = []
                    for fmt in fmts:
                        fmtf = cache.format(book_id, fmt, as_file=True)
                        if fmtf is None:
                            continue
                        cdata, area = get_cover_data(fmtf, fmt)
                        if cdata:
                            covers.append((cdata, area))
                    covers.sort(key=lambda x: x[1])
                    if covers:
                        cache.set_cover({book_id:covers[-1][0]})
        elif args.cover_action == 'trim':
            from calibre.utils.magick import Image
            for book_id in self.ids:
                cdata = cache.cover(book_id)
                if cdata:
                    im = Image()
                    im.load(cdata)
                    im.trim(tweaks['cover_trim_fuzz_value'])
                    cdata = im.export('jpg')
                    cache.set_cover({book_id:cdata})
        elif args.cover_action == 'clone':
            cdata = None
            for book_id in self.ids:
                cdata = cache.cover(book_id)
                if cdata:
                    break
            if cdata:
                cache.set_cover({bid:cdata for bid in self.ids if bid != book_id})

        # Formats
        if args.do_remove_format:
            cache.remove_formats({bid:(args.remove_format,) for bid in self.ids})

        if args.restore_original:
            for book_id in self.ids:
                formats = cache.formats(book_id)
                originals = tuple(x.upper() for x in formats if x.upper().startswith('ORIGINAL_'))
                for ofmt in originals:
                    cache.restore_original_format(book_id, ofmt)

        # Various fields
        if args.rating != -1:
            cache.set_field('rating', {bid:args.rating*2 for bid in self.ids})

        if args.clear_pub:
            cache.set_field('publisher', {bid:'' for bid in self.ids})

        if args.pub:
            cache.set_field('publisher', {bid:args.pub for bid in self.ids})

        if args.clear_series:
            cache.set_field('series', {bid:'' for bid in self.ids})

        if args.pubdate is not None:
            cache.set_field('pubdate', {bid:args.pubdate for bid in self.ids})

        if args.adddate is not None:
            cache.set_field('timestamp', {bid:args.adddate for bid in self.ids})

        if args.do_series:
            sval = args.series_start_value if args.do_series_restart else cache.get_next_series_num_for(args.series, current_indices=True)
            cache.set_field('series', {bid:args.series for bid in self.ids})
            if not args.series:
                cache.set_field('series_index', {bid:1.0 for bid in self.ids})
            else:
                def next_series_num(bid, i):
                    if args.do_series_restart:
                        return sval + i
                    next_num = _get_next_series_num_for_list(sorted(sval.itervalues()), unwrap=False)
                    sval[bid] = next_num
                    return next_num

                smap = {bid:next_series_num(bid, i) for i, bid in enumerate(self.ids)}
                if args.do_autonumber:
                    cache.set_field('series_index', smap)
                elif tweaks['series_index_auto_increment'] != 'no_change':
                    cache.set_field('series_index', {bid:1.0 for bid in self.ids})

        if args.comments is not null:
            cache.set_field('comments', {bid:args.comments for bid in self.ids})

        if args.do_remove_conv:
            cache.delete_conversion_options(self.ids)

        if args.clear_languages:
            cache.set_field('languages', {bid:() for bid in self.ids})
        elif args.languages:
            cache.set_field('languages', {bid:args.languages for bid in self.ids})

        if args.remove_all:
            cache.set_field('tags', {bid:() for bid in self.ids})
        if args.add or args.remove:
            self.db.bulk_modify_tags(self.ids, add=args.add, remove=args.remove)

        if self.do_sr:
            for book_id in self.ids:
                self.s_r_func(book_id)
            if self.sr_calls:
                for field, book_id_val_map in self.sr_calls.iteritems():
                    self.refresh_books.update(self.db.new_api.set_field(field, book_id_val_map))