Register Guidelines E-Books Search Today's Posts Mark Forums Read

Go Back   MobileRead Forums > E-Book Software > Calibre

Notices

Reply
 
Thread Tools Search this Thread
Old 12-14-2024, 09:34 PM   #1
mmobes
Enthusiast
mmobes began at the beginning.
 
Posts: 39
Karma: 10
Join Date: Dec 2021
Device: Kindle Oasis
Word Count in Calibre?

Is there any way to get Calibre to automatically add a column for word counts in each book? That way I can tally them all up at the end of the year and know how many words I’ve read instead of counting on page counts which is useless from a statistic standpoint.

Bonus point if it can add that when I do the metadata search while inputting a book.
mmobes is offline   Reply With Quote
Old 12-14-2024, 09:42 PM   #2
BetterRed
null operator (he/him)
BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.
 
Posts: 21,731
Karma: 29711016
Join Date: Mar 2012
Location: Sydney Australia
Device: none
Count Pages plugin can provide word counts, you can probably automate via the Actions Chains plugin ==>> Index of plugins

BR
BetterRed is offline   Reply With Quote
Old 12-14-2024, 09:44 PM   #3
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,611
Karma: 7891011
Join Date: Sep 2020
Device: none
I have a Words column populated by Count Pages Plugin:

https://github.com/kiwidude68/calibr...-custom-column
Comfy.n is offline   Reply With Quote
Old 12-15-2024, 02:01 PM   #4
mmobes
Enthusiast
mmobes began at the beginning.
 
Posts: 39
Karma: 10
Join Date: Dec 2021
Device: Kindle Oasis
Quote:
Originally Posted by Comfy.n View Post
I have a Words column populated by Count Pages Plugin:

https://github.com/kiwidude68/calibr...-custom-column
That looks like what I’m looking for. I’m hoping it’s easy to get it to automatically grab the word count?
mmobes is offline   Reply With Quote
Old 12-15-2024, 03:34 PM   #5
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,611
Karma: 7891011
Join Date: Sep 2020
Device: none
With the following settings, it's a single-click operation:

Click image for larger version

Name:	MWSnap 2024-12-15, 17_24_45.png
Views:	314
Size:	15.4 KB
ID:	212494

It does the count in this case, doesn't get it from anywhere (very fast by the way, thanks @kiwidude). Actually I never used the "Download from sources" option but it's necessary for Pbooks.
Comfy.n is offline   Reply With Quote
Old 12-15-2024, 08:22 PM   #6
BetterRed
null operator (he/him)
BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.BetterRed ought to be getting tired of karma fortunes by now.
 
Posts: 21,731
Karma: 29711016
Join Date: Mar 2012
Location: Sydney Australia
Device: none
@Comfy.n - For me it's a single keystroke — Alt+C

Could Action Chains fire up WC after a metadata download?

BR
BetterRed is offline   Reply With Quote
Old 12-15-2024, 08:49 PM   #7
mmobes
Enthusiast
mmobes began at the beginning.
 
Posts: 39
Karma: 10
Join Date: Dec 2021
Device: Kindle Oasis
Quote:
Originally Posted by BetterRed View Post
@Comfy.n - For me it's a single keystroke — Alt+C

Could Action Chains fire up WC after a metadata download?

BR
Good thinking!
mmobes is offline   Reply With Quote
Old 12-15-2024, 09:06 PM   #8
mmobes
Enthusiast
mmobes began at the beginning.
 
Posts: 39
Karma: 10
Join Date: Dec 2021
Device: Kindle Oasis
Quote:
Originally Posted by Comfy.n View Post
With the following settings, it's a single-click operation:

Attachment 212494

It does the count in this case, doesn't get it from anywhere (very fast by the way, thanks @kiwidude). Actually I never used the "Download from sources" option but it's necessary for Pbooks.
So if I leave all the download sources blank, it actually counts the words itself?
mmobes is offline   Reply With Quote
Old 12-15-2024, 09:14 PM   #9
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,611
Karma: 7891011
Join Date: Sep 2020
Device: none
First make sure you have the Count Page columns as instructed in the plugin Wiki.

Then install Action Chains and create the Download Metadata module:

Click image for larger version

Name:	MWSnap 2024-12-15, 22_57_13.png
Views:	144
Size:	8.5 KB
ID:	212497

This is the module code:

Code:
#!/usr/bin/env python
# ~*~ coding: utf-8 ~*~

__license__ = 'GPL v3'
__copyright__ = '2022, Ahmed Zaki <azaki00.dev@gmail.com>'
__docformat__ = 'restructuredtext en'

from qt.core import (QApplication, Qt, QWidget, QVBoxLayout, QCheckBox,
                     QGroupBox, QRadioButton, QAction)

import copy
import types
from functools import partial


from calibre import prints
from calibre.constants import DEBUG
from calibre.gui2 import Dispatcher, error_dialog

from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2.metadata.bulk_download import Job, download
from calibre.gui2.actions.edit_metadata import EditMetadataAction
from polyglot.builtins import iteritems

from calibre_plugins.action_chains.actions.base import ChainAction
from calibre_plugins.action_chains.common_utils import responsive_wait, responsive_wait_until

def unfinished_job_ids(gui):
    return set([job.id for job in gui.job_manager.unfinished_jobs()])



class ModifiedEditMetadataAction(EditMetadataAction):
    name = 'Modified Edit Metadata'
    action_spec = (_('Modified Edit metadata'), 'edit_input.png', _('Change the title/author/cover etc. of books'), _(''))
    action_type = 'current'
    action_add_menu = True

    def __init__(self, parent, site_customization):
        EditMetadataAction.__init__(self, parent, site_customization)
        self.do_genesis()

    @property
    def unique_name(self):
        bn = self.__class__.__name__
        return 'Interface Action: %s (%s)'%(bn, self.name)

    def genesis(self):
        pass

    def location_selected(self, loc):
        pass

    def library_changed(self):
        pass

    def shutting_down(self):
        pass

    def metadata_downloaded(self, job):
        if job.failed:
            self.gui.job_exception(job, dialog_title=_('Failed to download metadata'))
            return
        from calibre.gui2.metadata.bulk_download import get_job_details
        (aborted, id_map, tdir, log_file, failed_ids, failed_covers, all_failed,
                det_msg, lm_map) = get_job_details(job)
        if aborted:
            return self.cleanup_bulk_download(tdir)
        if all_failed:
            num = len(failed_ids | failed_covers)
            self.cleanup_bulk_download(tdir)
            return error_dialog(self.gui, _('Download failed'), ngettext(
                'Failed to download metadata or cover for the selected book.',
                'Failed to download metadata or covers for any of the {} books.', num
            ).format(num), det_msg=det_msg, show=True)

        self.gui.status_bar.show_message(_('Metadata download completed'), 3000)

        msg = '<p>' + ngettext(
            'Finished downloading metadata for the selected book.',
            'Finished downloading metadata for <b>{} books</b>.', len(id_map)).format(len(id_map)) + ' ' + \
            _('Proceed with updating the metadata in your library?')

        show_copy_button = False
        checkbox_msg = None
        if failed_ids or failed_covers:
            show_copy_button = True
            num = len(failed_ids.union(failed_covers))
            msg += '<p>'+_('Could not download metadata and/or covers for %d of the books. Click'
                    ' "Show details" to see which books.')%num
            checkbox_msg = _('Show the &failed books in the main book list '
                    'after updating metadata')

        if getattr(job, 'metadata_and_covers', None) == (False, True):
            # Only covers, remove failed cover downloads from id_map
            for book_id in failed_covers:
                if hasattr(id_map, 'discard'):
                    id_map.discard(book_id)
        payload = (id_map, tdir, log_file, lm_map,
                failed_ids.union(failed_covers))

        if self.do_review:
            QApplication.setOverrideCursor(Qt.ArrowCursor)
            try:
                self.apply_downloaded_metadata(True, payload, self.restrict_to_failed)
            finally:
                QApplication.restoreOverrideCursor()
        else:
            self.apply_downloaded_metadata(False, payload, self.restrict_to_failed)

class ConfigWidget(QWidget):
    def __init__(self, plugin_action):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        self.gui = plugin_action.gui
        self.db = self.gui.current_db
        self._init_controls()

    def _init_controls(self):

        l = self.l = QVBoxLayout()
        self.setLayout(l)

        opt_gb = QGroupBox(_('Options'))
        opt_gb_l = QVBoxLayout()
        opt_gb.setLayout(opt_gb_l)
        l.addWidget(opt_gb)

        self.metadata_opt = QRadioButton(_('Download Metadata'))
        self.covers_opt = QRadioButton(_('Download Covers'))
        self.both_opt = QRadioButton(_('Download Both'))
        self.both_opt.setChecked(True)

        opt_gb_l.addWidget(self.metadata_opt)
        opt_gb_l.addWidget(self.covers_opt)
        opt_gb_l.addWidget(self.both_opt)

        self.review_chk = QCheckBox(_('Review downloaded metadata before applying them'))
        self.wait_chk = QCheckBox(_('Wait for metadata download jobs to finish'))
        self.wait_chk.setToolTip(_('Check this if this action in not the last action in the chain.'))
        l.addWidget(self.review_chk)
        l.addWidget(self.wait_chk)

        l.addStretch(1)

        self.setMinimumSize(500,300)

    def load_settings(self, settings):
        if settings:
            self.metadata_opt.setChecked(settings.get('download_metadata', False))
            self.covers_opt.setChecked(settings.get('download_covers', False))
            self.both_opt.setChecked(settings.get('download_both', True))
            self.review_chk.setChecked(settings.get('review', True))
            self.wait_chk.setChecked(settings.get('wait_jobs', False))

    def save_settings(self):
        settings = {}
        settings['download_metadata'] = self.metadata_opt.isChecked()
        settings['download_covers'] = self.covers_opt.isChecked()
        settings['download_both'] = self.both_opt.isChecked()
        settings['review'] = self.review_chk.isChecked()
        settings['wait_jobs'] = self.wait_chk.isChecked()
        return settings


class DownloadMetadata(ChainAction):

    name = 'Download Metadata'
    support_scopes = True

    def run(self, gui, settings, chain):
        identify = settings.get('download_metadata') or settings.get('download_both', True)
        covers = settings.get('download_covers') or settings.get('download_both', True)
        wait_jobs = settings.get('wait_jobs', False)
        ensure_fields = None

        edit_metadata = ModifiedEditMetadataAction(gui, '')
        edit_metadata.do_review = settings.get('review', True)
        edit_metadata.restrict_to_failed = settings.get('restrict_to_failed', True)
        callback = Dispatcher(edit_metadata.metadata_downloaded)

        ids = chain.scope().get_book_ids()
        if len(ids) == 0:
            return error_dialog(gui, _('Cannot download metadata'),
                        _('No books selected'), show=True)

        jobs_before_ids = unfinished_job_ids(gui)

        tf = PersistentTemporaryFile('_metadata_bulk.log')
        tf.close()
        job = Job('metadata bulk download',
            ngettext(
                'Download metadata for one book',
                'Download metadata for {} books', len(ids)).format(len(ids)),
            download, (ids, tf.name, gui.current_db, identify, covers,
                ensure_fields), {}, callback)
        job.metadata_and_covers = (identify, covers)
        job.download_debug_log = tf.name
        gui.job_manager.run_threaded_job(job)
        gui.status_bar.show_message(_('Metadata download started'), 3000)

        if wait_jobs:
            # wait for jobs spawned by action to kick in
            responsive_wait(1)
            # save ids of jobs started after running the action
            ids_jobs_by_action = unfinished_job_ids(gui).difference(jobs_before_ids)

            # wait for jobs to finish
            responsive_wait_until(lambda: ids_jobs_by_action.intersection(unfinished_job_ids(gui)) == set())

    def validate(self, settings):
        #if not settings:
            #return (_('Settings Error'), _('You must configure this action before running it'))
        return True

    def config_widget(self):
        return ConfigWidget
Click Action Chains plugin button (or shortcut) -> Manage Modules -> Create -> then paste it

Then import the attached chain this way:

Click image for larger version

Name:	MWSnap 2024-12-15, 23_00_37.png
Views:	146
Size:	32.2 KB
ID:	212496

I tested it and it works fine on a Calibre portable install.
Attached Files
File Type: zip download metadata and run count pages-words.zip (510 Bytes, 147 views)
Comfy.n is offline   Reply With Quote
Old 12-15-2024, 09:21 PM   #10
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,611
Karma: 7891011
Join Date: Sep 2020
Device: none
Quote:
Originally Posted by mmobes View Post
So if I leave all the download sources blank, it actually counts the words itself?
Yep! And you may leave the sources selected. The choice to download or run the word count estimate is up to the user. So you either set that option right-clicking the Count Pages plugin button and going through that plugin customisation dialog (tab 'Other'), or just click the Estimate counts:

Click image for larger version

Name:	MWSnap 2024-12-15, 23_20_42.png
Views:	282
Size:	16.8 KB
ID:	212499
Comfy.n is offline   Reply With Quote
Old 12-16-2024, 10:06 PM   #11
mmobes
Enthusiast
mmobes began at the beginning.
 
Posts: 39
Karma: 10
Join Date: Dec 2021
Device: Kindle Oasis
Quote:
Originally Posted by Comfy.n View Post
Yep! And you may leave the sources selected. The choice to download or run the word count estimate is up to the user. So you either set that option right-clicking the Count Pages plugin button and going through that plugin customisation dialog (tab 'Other'), or just click the Estimate counts:

Attachment 212499
Thank you very much for all the help!

In your experience, which is the most accurate count? I'd assume having the book file itself scanned, but that's just a guess.
mmobes is offline   Reply With Quote
Old 12-16-2024, 10:16 PM   #12
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,611
Karma: 7891011
Join Date: Sep 2020
Device: none
The Ebook Viewer algorithm is what I've only ever used, as I want the words/pages count columns just for comparison and filtering/searching. And for this purpose it is accurate as it reflects the exact number of pages displayed by the Viewer.

Also, at one point I had a custom column like the one in this thread:

https://www.mobileread.com/forums/sh...d.php?t=311272
Comfy.n is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Add page count, word count and reading time ZodWallop Kobo Reader 4 08-12-2024 05:56 AM
Word Count and Page Count? CrossReach Library Management 2 07-19-2018 05:44 PM
Word count in calibre C-novice Library Management 2 03-11-2018 10:57 PM
Word Count? noirverse Marvin 0 11-11-2016 08:23 PM
Possible to get a word count in Calibre? Notjohn Calibre 15 01-23-2016 06:20 PM


All times are GMT -4. The time now is 12:57 PM.


MobileRead.com is a privately owned, operated and funded community.