diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rwxr-xr-x | epubgrep.py | 61 |
2 files changed, 30 insertions, 32 deletions
@@ -7,3 +7,4 @@ __pycache__/ MANIFEST .tox/ .coverage +.vscode/ diff --git a/epubgrep.py b/epubgrep.py index 8a9cfa8..c66a326 100755 --- a/epubgrep.py +++ b/epubgrep.py @@ -12,7 +12,7 @@ from typing import Any, Dict, List, Optional, Tuple import epub_meta logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s', - level=logging.INFO) + level=logging.DEBUG) log = logging.getLogger('epubgrep') @@ -40,28 +40,26 @@ def _colorize_found(dline: str, res: re.Match, col: bool) -> str: return out -def _multiline_search(inf, sought_RE, printed_booktitle, filename, +def _multiline_search(inf, sought_RE, filename, counting, w_counting, metadata, zif) -> Tuple[int, str]: out = "" count = 0 decoded_str = inf.read().decode(errors='replace') res = sought_RE.search(decoded_str) if res: - if not printed_booktitle: - out += '{}\n'.format(filename) - printed_booktitle = True if counting or w_counting: count += 1 else: chap_info = get_chapter_title(metadata.toc, zif.filename) - out += "{}. {}:\n\n".format(chap_info[1], chap_info[0]) + if chap_info: + out += "{}. {}:\n\n".format(chap_info[1], chap_info[0]) out += '{}\n\n'.format(res.group(0)) return count, out def _singleline_search(inf, sought_RE, out_title, filename, counting, - w_counting, printed_booktitle, metadata, zif, color, + w_counting, metadata, zif, color, count) -> Tuple[int, str]: out = "" count = 0 @@ -75,9 +73,6 @@ def _singleline_search(inf, sought_RE, out_title, filename, counting, if counting or w_counting: count += 1 else: - if not printed_booktitle: - out += out_title + '\n' - printed_booktitle = True if not printed_title: chap_info = get_chapter_title(metadata.toc, zif.filename) @@ -99,24 +94,23 @@ def _description_search(mdata: dict, sre: re.Pattern, fname: str, res = sre.search(decoded_line) if res: - title = '{}'.format(fname) + title = '\n{}'.format(fname) out += title + '\n' out += _colorize_found(decoded_line, res, col) return out -def grep_book(filename: str, pattern: str, flags: int, desc: bool = False, - counting: bool = False, w_counting: bool = False, - color: bool = False) -> Optional[str]: +def grep_book(filename: str, opts: argparse.Namespace, + re_flags: int) -> Optional[str]: assert os.path.isfile(filename), "{} is not EPub file.".format(filename) - sought_RE = re.compile('(' + pattern + ')', flags) + sought_RE = re.compile('(' + opts.pattern + ')', re_flags) count = 0 icount = 0 out_title = '' out = '' iout = '' - mline = flags & re.M == re.M + mline = re_flags & re.M == re.M try: metadata = epub_meta.get_epub_metadata(filename) @@ -126,33 +120,39 @@ def grep_book(filename: str, pattern: str, flags: int, desc: bool = False, book = zipfile.ZipFile(filename) printed_booktitle = False - if desc: - return _description_search(metadata, sought_RE, filename, color) + if opts.description: + return _description_search(metadata, sought_RE, filename, opts.color) for zif in book.infolist(): with book.open(zif) as inf: if mline: icount, iout = _multiline_search(inf, sought_RE, - printed_booktitle, filename, - counting, w_counting, + filename, opts.count, + opts.weighted_count, metadata, zif) + if (not printed_booktitle) and iout: + out += '\n{}\n'.format(filename) + printed_booktitle = True count += icount out += iout else: icount, iout = _singleline_search(inf, sought_RE, out_title, - filename, counting, - w_counting, - printed_booktitle, metadata, - zif, color, count) + filename, opts.count, + opts.weighted_count, + metadata, zif, opts.color, + count) + if (not printed_booktitle) and iout: + out += '\n{}\n'.format(filename) + printed_booktitle = True count += icount out += iout if count > 0: - if counting: - out += '{:02d}:{}'.format(count, out_title) - if w_counting: + if opts.count: + out += '{:02d}:{}'.format(count, filename) + if opts.weighted_count: size = metadata['file_size_in_bytes'] - out += '{:05d}:{}'.format(int((count/size)*1e5), out_title) + out += '{:05d}:{}'.format(int((count/size)*1e5), filename) return out @@ -192,10 +192,7 @@ def main(): with concurrent.futures.ProcessPoolExecutor() as executor: fut_to_fname = {executor.submit(grep_book, os.path.realpath(filename), - args.pattern, search_flags, - args.description, - args.count, args.weighted_count, - args.color): + args, search_flags): filename for filename in args.files} for future in concurrent.futures.as_completed(fut_to_fname): try: |