Adding some GNU options of grep (#2)
This commit is contained in:
parent
f8389efc87
commit
6ab1393875
125
pogrep.py
125
pogrep.py
|
@ -1,75 +1,164 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Find translations exemples by grepping in .po files.
|
||||
"""Find translations examples by grepping in .po files.
|
||||
"""
|
||||
|
||||
__version__ = "0.1.1"
|
||||
|
||||
import argparse
|
||||
import curses
|
||||
from glob import glob
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
from textwrap import fill
|
||||
|
||||
import regex
|
||||
import polib
|
||||
from tabulate import tabulate
|
||||
|
||||
|
||||
def red_color():
|
||||
"""Just returns the CSI codes for red and reset color.
|
||||
def get_colors():
|
||||
"""Just returns the CSI codes for red, green, magenta, and reset color.
|
||||
"""
|
||||
try:
|
||||
curses.setupterm()
|
||||
fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or ""
|
||||
red = str(curses.tparm(fg_color, 1), "ascii")
|
||||
green = str(curses.tparm(fg_color, 2), "ascii")
|
||||
magenta = str(curses.tparm(fg_color, 5), "ascii")
|
||||
no_color = str(curses.tigetstr("sgr0"), "ascii")
|
||||
except Exception:
|
||||
red = ""
|
||||
except curses.error:
|
||||
red, green, magenta = "", "", ""
|
||||
no_color = ""
|
||||
return red, no_color
|
||||
return red, green, magenta, no_color
|
||||
|
||||
|
||||
RED, NO_COLOR = red_color()
|
||||
RED, GREEN, MAGENTA, NO_COLOR = get_colors()
|
||||
|
||||
|
||||
def get_term_width():
|
||||
scr = curses.initscr()
|
||||
width = scr.getmaxyx()[1]
|
||||
curses.endwin()
|
||||
try:
|
||||
curses.endwin()
|
||||
except curses.error:
|
||||
pass
|
||||
return width
|
||||
|
||||
|
||||
WIDTH = get_term_width()
|
||||
|
||||
|
||||
def colorize(text, pattern):
|
||||
return regex.sub(pattern, RED + r"\g<0>" + NO_COLOR, text)
|
||||
def colorize(text, pattern, prefixes):
|
||||
result = regex.sub(pattern, RED + r"\g<0>" + NO_COLOR, text)
|
||||
for pnum, pfile in prefixes:
|
||||
prefix = " " + pfile + pnum
|
||||
prefix_colored = regex.escape(regex.sub(pattern, RED + r"\g<0>" + NO_COLOR, prefix))
|
||||
if regex.escape(RED) in prefix_colored:
|
||||
prefix = prefix_colored
|
||||
prefix_replace = " " + MAGENTA + pfile + GREEN + pnum + NO_COLOR
|
||||
result = regex.sub(prefix, prefix_replace, result, count=1)
|
||||
return result
|
||||
|
||||
|
||||
def find_in_po(pattern):
|
||||
def find_in_po(pattern, path, linenum, file_match, no_messages):
|
||||
table = []
|
||||
for file in glob("**/*.po"):
|
||||
pofile = polib.pofile(file)
|
||||
prefixes = []
|
||||
for filename in path:
|
||||
try:
|
||||
pofile = polib.pofile(filename)
|
||||
except OSError:
|
||||
if not no_messages:
|
||||
print("{} doesn't seem to be a .po file".format(filename), file=sys.stderr)
|
||||
continue
|
||||
for entry in pofile:
|
||||
if entry.msgstr and regex.search(pattern, entry.msgid):
|
||||
if file_match:
|
||||
print(MAGENTA + filename + NO_COLOR)
|
||||
break
|
||||
left = entry.msgid
|
||||
if linenum:
|
||||
pnum = str(entry.linenum) + ":"
|
||||
if len(path) > 1:
|
||||
pfile = filename + ":"
|
||||
else:
|
||||
pfile = ""
|
||||
left = pfile + pnum + left
|
||||
prefixes.append((pnum, pfile))
|
||||
table.append(
|
||||
[
|
||||
fill(entry.msgid, width=(WIDTH - 7) // 2),
|
||||
fill(left, width=(WIDTH - 7) // 2),
|
||||
fill(entry.msgstr, width=(WIDTH - 7) // 2),
|
||||
]
|
||||
)
|
||||
print(colorize(tabulate(table, tablefmt="fancy_grid"), pattern))
|
||||
if not file_match:
|
||||
print(colorize(tabulate(table, tablefmt="fancy_grid"), pattern, prefixes))
|
||||
|
||||
|
||||
def process_path(path, recursive, exclude_dir):
|
||||
files = []
|
||||
if len(path) == 0:
|
||||
if recursive:
|
||||
files = glob.glob("**/*.po", recursive=True)
|
||||
if exclude_dir:
|
||||
return [elt for elt in files if exclude_dir.rstrip(os.sep) + os.sep not in elt]
|
||||
else:
|
||||
return files
|
||||
else:
|
||||
sys.exit(0)
|
||||
for elt in path:
|
||||
if os.path.isfile(elt):
|
||||
files.append(elt)
|
||||
elif os.path.isdir(elt):
|
||||
if recursive:
|
||||
files.extend(glob.glob(elt + os.sep + "**/*.po", recursive=True))
|
||||
else:
|
||||
print("{}: {}: Is a directory".format(sys.argv[0], elt), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("{}: {}: No such file or directory".format(sys.argv[0], elt), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if exclude_dir:
|
||||
files = [elt for elt in files if exclude_dir.rstrip(os.sep) + os.sep not in elt]
|
||||
return files
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Find translated words.")
|
||||
parser.add_argument("-F", "--fixed-strings", action="store_true",
|
||||
help="Interpret pattern as fixed string, not regular expressions.")
|
||||
parser.add_argument("-i", "--ignore-case", action="store_true",
|
||||
help="Ignore case distinctions, so that characters that differ only in case match each other.")
|
||||
parser.add_argument("-w", "--word-regexp", action="store_true",
|
||||
help="Select only those lines containing matches that form whole words.")
|
||||
parser.add_argument('-n', "--line-number", action="store_true",
|
||||
help="Prefix each line of output with the 1-based line number within its input file.")
|
||||
parser.add_argument("-l", "--files-with-matches", action="store_true",
|
||||
help="Suppress normal output; instead print the name of each input file from which output "
|
||||
"would normally have been printed. The scanning will stop on the first match.")
|
||||
parser.add_argument("-s", "--no-messages", action="store_true",
|
||||
help="Suppress error messages about nonexistent or unreadable files.")
|
||||
parser.add_argument("-r", "--recursive", action="store_true",
|
||||
help="Read all files under each directory, recursively, following symbolic links only "
|
||||
"if they are on the command line. Note that if no file operand is given, pogrep searches "
|
||||
"the working directory.")
|
||||
parser.add_argument("--exclude-dir",
|
||||
help="Skip any command-line directory with a name suffix that matches the pattern. "
|
||||
"When searching recursively, skip any subdirectory whose base name matches GLOB. "
|
||||
"Ignore any redundant trailing slashes in GLOB.")
|
||||
parser.add_argument("pattern")
|
||||
parser.add_argument("path", nargs='*')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
find_in_po(args.pattern)
|
||||
if args.fixed_strings:
|
||||
args.pattern = regex.escape(args.pattern)
|
||||
if args.word_regexp:
|
||||
args.pattern = r"\b" + args.pattern + r"\b"
|
||||
if args.ignore_case:
|
||||
args.pattern = r"(?i)" + args.pattern
|
||||
files = process_path(args.path, args.recursive, args.exclude_dir)
|
||||
find_in_po(args.pattern, files, args.line_number, args.files_with_matches, args.no_messages)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in New Issue
Block a user