Skip to content

Commit

Permalink
Refactors towards object-oriented approach
Browse files Browse the repository at this point in the history
  • Loading branch information
derphilipp committed Feb 3, 2016
1 parent 8639739 commit 2678962
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 251 deletions.
9 changes: 2 additions & 7 deletions pwgrep/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,11 @@ def run(args):
printer = printer_helper.ResultPrinter(
colorize=parser_result.color,
print_filename=parser_result.print_filename,
invert_match=parser_result.options.invert_match
invert_match=parser_result.invert_match
)

any_match = False
if not parser_result.options.PATH:
data_from = grepper.grep_stdin()
else:
data_from = grepper.grep_files_from_commandline()

for result in data_from:
for result in grepper.grep():
printer.print_result(result)
if result.match:
any_match = True
Expand Down
33 changes: 25 additions & 8 deletions pwgrep/commandline_parser_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ def __init__(self, options):
:param options: CommandLineParameter options
:return:
"""
self.options = options
self._options = options
self.regexes = RegexContainer(
self.options.PATTERN[0],
self.options.ignore_case
self._options.PATTERN[0],
self._options.ignore_case
)

@property
Expand All @@ -49,21 +49,38 @@ def color(self):
:return: If color should be used
"""
if self.options.color is None or self.options.color == 'never':
if self._options.color is None or self._options.color == 'never':
return False
if self.options.color == 'always':
if self._options.color == 'always':
return True
# can only be 'auto' at this point
return os.isatty(sys.stdout.fileno())

@property
def recursion_any(self):
return self.options.dereference_recursive or self.options.recursive
return self.dereference_recursive or self.normal_recursive

@property
def dereference_recursive(self):
return self._options.dereference_recursive

@property
def normal_recursive(self):
return self._options.recursive

@property
def print_filename(self):
if self.options.no_filename:
if self._options.no_filename:
return False
if len(self.options.PATH) == 1 and not self.recursion_any:
if len(self._options.PATH) == 1 and not self.recursion_any:
return False
return True

@property
def PATH(self):
return self._options.PATH

@property
def invert_match(self):
return self._options.invert_match

88 changes: 1 addition & 87 deletions pwgrep/printer_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,74 +65,7 @@ def print_result(self, result):
elif isinstance(result, search_result.StdinSearchResult):
self.print_stdin_match(result)
else:
print(type(result))
assert(False)


def colorize_match(match):
"""
Colorize matches in a line.
:param match: regex match to be marked
:return: colorized line
"""
return '{}{}{}'.format(colors.ConsoleColors.MATCH, match.group(),
colors.ConsoleColors.ENDC)


def colorize_filename(file_name):
"""
Colorize filename.
:param file_name: filename to be colorized
:return string: colorized filename
"""
return '{}{}{}'.format(colors.ConsoleColors.FILE, file_name,
colors.ConsoleColors.ENDC)


def format_printline(file_name, line, regex, color):
"""
Colorize a given string as a 'match'.
:param file_name: filename with match
:param line: matched line
:param regex: regular expression used for search/colorization
:param color: if result shall be colorized
:return: filename, line
"""
line = line.strip()
if color:
file_name = colorize_filename(file_name)
line = regex.sub(colorize_match, line)
return file_name, line


def print_binary_match(file_name):
"""
Print info for a match in a binary file.
:param file_name: filename to be printed
:return:
"""
print('Binary file {} matches'.format(file_name))


def print_text_match(file_name, line, regex, color, no_filename):
"""
Print info for a match in a textual file.
:param file_name: filename to be printed
:param line: (matched) line to be printed
:param regex: regex to be printed/marked
:param color: output in color
:param no_filename: if the filename printing shall be suppressed
"""
file_name, line = format_printline(file_name, line, regex, color)
if no_filename:
print(line)
else:
print('{}:{}'.format(file_name, line))
assert False, "Invalid type to print: {}".format(typeof(result))


def print_loop_warning(file_name):
Expand All @@ -154,22 +87,3 @@ def print_is_directory(dir_name):
:return:
"""
print('pwgrep: {}: is a directory'.format(dir_name))


def print_match(filename, line, regex, no_filename=False,
file_is_binary=False, color=False):
"""
Print matches from files.
:param filename: filename of match
:param line: complete line of match
:param regex: regular expression used
:param no_filename: if printing of filename shall be suppressed
:param file_is_binary: if file is binary
:param color: if output shall be colorized
:return:
"""
if file_is_binary:
print_binary_match(filename)
else:
print_text_match(filename, line, regex, color, no_filename)
101 changes: 26 additions & 75 deletions pwgrep/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,13 @@
import sys


class RegexSearcher(object):

def __init__(self, regexes):
self.regexes = regexes

def search_line_txt(self, line):
result = []
for m in self.regexes.regex_txt.finditer(line):
result.append([m.start(), m.end()])
return result


class SearchStdin(object):

def __init__(self, regexes, invert_match=False):
"""
Search for regex in stdin.
:param regexes: regex to search with
:param invert_match: if match should be inverted
(i.e. non-matches shall match)
"""
self.regexes = regexes
self.invert_match = invert_match
self.rs = RegexSearcher(self.regexes)

def __iter__(self):
for line_nr, line in enumerate(sys.stdin):
match = self.rs.search_line_txt(line)
if match:
yield search_result.StdinSearchResult(
line_number=line_nr,
match=match, line=line)


class Grepper(object):

def __init__(self, commandline_parser_results):
self.commandline_parser_results = commandline_parser_results
self.options = self.commandline_parser_results.options

self.match_occurred = False
self.regex_searcher = search_helper.RegexSearcher(
self.commandline_parser_results.regexes,
invert_match=self.commandline_parser_results.invert_match)

def grep_stdin(self):
"""
Expand All @@ -56,53 +21,39 @@ def grep_stdin(self):
:return: If any match occurred
"""

searcher = SearchStdin(
self.commandline_parser_results.regexes,
self.commandline_parser_results.options.invert_match)

for result in searcher:
# printer_helper.print_match('', result.match,
# self.commandline_parser_results.
# regexes.regex_txt,
# True, False,
# self.commandline_parser_results.color
# )
for result in self.regex_searcher.search_in_stdin():
yield result

def handle_directory(self, file_name):
if not self.commandline_parser_results.recursion_any:
printer_helper.print_is_directory(file_name)
else:
for filename in file_helper.files_from_directory_recursive(
file_name,
self.commandline_parser_results.dereference_recursive):
for match in self.regex_searcher.search_in_file(filename):
yield match

def grep_files_from_commandline(self):
"""
Process grep operation on files specified via commandline.
following symlinks
:return: If any match occurred
"""
# rs = RegexSearcher(self.commandline_parser_results.regexes)

for file_name in self.commandline_parser_results.options.PATH:
for file_name in self.commandline_parser_results.PATH:
if file_helper.file_is_directory(file_name):
if not (self.options.dereference_recursive or
self.options.recursive):
printer_helper.print_is_directory(file_name)
else:
for filename in file_helper.files_from_directory_recursive(
file_name,
self.options.dereference_recursive
):
for match in search_helper.search_in_file(
filename,
self.commandline_parser_results.regexes,
self.commandline_parser_results.
options.invert_match,
self.commandline_parser_results.print_filename,
self.commandline_parser_results.color
):
yield match
for match in self.handle_directory(file_name):
yield match
else:
for match in search_helper.search_in_file(
file_name,
self.commandline_parser_results.regexes,
self.commandline_parser_results.options.invert_match,
self.commandline_parser_results.options.no_filename,
self.commandline_parser_results.color
):
for match in self.regex_searcher.search_in_file(file_name):
yield match

def grep(self):
if self.commandline_parser_results.PATH:
for result in self.grep_files_from_commandline():
yield result

for result in self.grep_stdin():
yield result
Loading

0 comments on commit 2678962

Please sign in to comment.