# Path: talon/signature/bruteforce.py
# def get_signature_candidate(lines):
#     """Return lines that could hold signature
# 
#     The lines should:
# 
#     * be among last SIGNATURE_MAX_LINES non-empty lines.
#     * not include first line
#     * be shorter than TOO_LONG_SIGNATURE_LINE
#     * not include more than one line that starts with dashes
#     """
#     # non empty lines indexes
#     non_empty = [i for i, line in enumerate(lines) if line.strip()]
# 
#     # if message is empty or just one line then there is no signature
#     if len(non_empty) <= 1:
#         return []
# 
#     # we don't expect signature to start at the 1st line
#     candidate = non_empty[1:]
#     # signature shouldn't be longer then SIGNATURE_MAX_LINES
#     candidate = candidate[-SIGNATURE_MAX_LINES:]
# 
#     markers = _mark_candidate_indexes(lines, candidate)
#     candidate = _process_marked_candidate_indexes(candidate, markers)
# 
#     # get actual lines for the candidate instead of indexes
#     if candidate:
#         candidate = lines[candidate[0]:]
#         return candidate
# 
#     return []
# 
# Path: talon/signature/learning/featurespace.py
# def features(sender=''):
#     '''Returns a list of signature features.'''
#     return [
#         # This one isn't from paper.
#         # Meant to match companies names, sender's names, address.
#         many_capitalized_words,
#         # This one is not from paper.
#         # Line is too long.
#         # This one is less aggressive than `Line is too short`
#         lambda line: 1 if len(line) > TOO_LONG_SIGNATURE_LINE else 0,
#         # Line contains email pattern.
#         binary_regex_search(RE_EMAIL),
#         # Line contains url.
#         binary_regex_search(RE_URL),
#         # Line contains phone number pattern.
#         binary_regex_search(RE_RELAX_PHONE),
#         # Line matches the regular expression "^[\s]*---*[\s]*$".
#         binary_regex_match(RE_SEPARATOR),
#         # Line has a sequence of 10 or more special characters.
#         binary_regex_search(RE_SPECIAL_CHARS),
#         # Line contains any typical signature words.
#         binary_regex_search(RE_SIGNATURE_WORDS),
#         # Line contains a pattern like Vitor R. Carvalho or William W. Cohen.
#         binary_regex_search(RE_NAME),
#         # Percentage of punctuation symbols in the line is larger than 50%
#         lambda line: 1 if punctuation_percent(line) > 50 else 0,
#         # Percentage of punctuation symbols in the line is larger than 90%
#         lambda line: 1 if punctuation_percent(line) > 90 else 0,
#         contains_sender_names(sender)
#         ]
# 
# def build_pattern(body, features):
#     '''Converts body into a pattern i.e. a point in the features space.
# 
#     Applies features to the body lines and sums up the results.
#     Elements of the pattern indicate how many times a certain feature occurred
#     in the last lines of the body.
#     '''
#     line_patterns = apply_features(body, features)
#     return reduce(lambda x, y: [i + j for i, j in zip(x, y)], line_patterns)
# 
# Path: talon/signature/learning/helpers.py
# def has_signature(body, sender):
#     """Checks if the body has signature. Returns True or False."""
#     non_empty = [line for line in body.splitlines() if line.strip()]
#     candidate = non_empty[-SIGNATURE_MAX_LINES:]
#     upvotes = 0
#     sender_check = contains_sender_names(sender)
#     for line in candidate:
#         # we check lines for sender's name, phone, email and url,
#         # those signature lines don't take more then 27 lines
#         if len(line.strip()) > 27:
#             continue
# 
#         if sender_check(line):
#             return True
# 
#         if (binary_regex_search(RE_RELAX_PHONE)(line) +
#                 binary_regex_search(RE_EMAIL)(line) +
#                 binary_regex_search(RE_URL)(line) == 1):
#             upvotes += 1
# 
#     if upvotes > 1:
#         return True
# 
#     return False
# 
# Path: talon/utils.py
# def get_delimiter(msg_body):
#     delimiter = RE_DELIMITER.search(msg_body)
#     if delimiter:
#         delimiter = delimiter.group()
#     else:
#         delimiter = '\n'
# 
#     return delimiter


import logging
import numpy
import regex as re
from talon.signature.bruteforce import get_signature_candidate
from talon.signature.learning.featurespace import features, build_pattern
from talon.signature.learning.helpers import has_signature
from talon.utils import get_delimiter
# -*- coding: utf-8 -*-

from __future__ import absolute_import



log = logging.getLogger(__name__)

EXTRACTOR = None

# regex signature pattern for reversed lines
# assumes that all long lines have been excluded
RE_REVERSE_SIGNATURE = re.compile(r'''
# signature should consists of blocks like this
(?:
   # it could end with empty line
   e*
   # there could be text lines but no more than 2 in a row
   (te*){,2}
   # every block should end with signature line

# Path: talon/signature/bruteforce.py
# def get_signature_candidate(lines):
#     """Return lines that could hold signature
# 
#     The lines should:
# 
#     * be among last SIGNATURE_MAX_LINES non-empty lines.
#     * not include first line
#     * be shorter than TOO_LONG_SIGNATURE_LINE
#     * not include more than one line that starts with dashes
#     """
#     # non empty lines indexes
#     non_empty = [i for i, line in enumerate(lines) if line.strip()]
# 
#     # if message is empty or just one line then there is no signature
#     if len(non_empty) <= 1:
#         return []
# 
#     # we don't expect signature to start at the 1st line
#     candidate = non_empty[1:]
#     # signature shouldn't be longer then SIGNATURE_MAX_LINES
#     candidate = candidate[-SIGNATURE_MAX_LINES:]
# 
#     markers = _mark_candidate_indexes(lines, candidate)
#     candidate = _process_marked_candidate_indexes(candidate, markers)
# 
#     # get actual lines for the candidate instead of indexes
#     if candidate:
#         candidate = lines[candidate[0]:]
#         return candidate
# 
#     return []
# 
# Path: talon/signature/learning/featurespace.py
# def features(sender=''):
#     '''Returns a list of signature features.'''
#     return [
#         # This one isn't from paper.
#         # Meant to match companies names, sender's names, address.
#         many_capitalized_words,
#         # This one is not from paper.
#         # Line is too long.
#         # This one is less aggressive than `Line is too short`
#         lambda line: 1 if len(line) > TOO_LONG_SIGNATURE_LINE else 0,
#         # Line contains email pattern.
#         binary_regex_search(RE_EMAIL),
#         # Line contains url.
#         binary_regex_search(RE_URL),
#         # Line contains phone number pattern.
#         binary_regex_search(RE_RELAX_PHONE),
#         # Line matches the regular expression "^[\s]*---*[\s]*$".
#         binary_regex_match(RE_SEPARATOR),
#         # Line has a sequence of 10 or more special characters.
#         binary_regex_search(RE_SPECIAL_CHARS),
#         # Line contains any typical signature words.
#         binary_regex_search(RE_SIGNATURE_WORDS),
#         # Line contains a pattern like Vitor R. Carvalho or William W. Cohen.
#         binary_regex_search(RE_NAME),
#         # Percentage of punctuation symbols in the line is larger than 50%
#         lambda line: 1 if punctuation_percent(line) > 50 else 0,
#         # Percentage of punctuation symbols in the line is larger than 90%
#         lambda line: 1 if punctuation_percent(line) > 90 else 0,
#         contains_sender_names(sender)
#         ]
# 
# def build_pattern(body, features):
#     '''Converts body into a pattern i.e. a point in the features space.
# 
#     Applies features to the body lines and sums up the results.
#     Elements of the pattern indicate how many times a certain feature occurred
#     in the last lines of the body.
#     '''
#     line_patterns = apply_features(body, features)
#     return reduce(lambda x, y: [i + j for i, j in zip(x, y)], line_patterns)
# 
# Path: talon/signature/learning/helpers.py
# def has_signature(body, sender):
#     """Checks if the body has signature. Returns True or False."""
#     non_empty = [line for line in body.splitlines() if line.strip()]
#     candidate = non_empty[-SIGNATURE_MAX_LINES:]
#     upvotes = 0
#     sender_check = contains_sender_names(sender)
#     for line in candidate:
#         # we check lines for sender's name, phone, email and url,
#         # those signature lines don't take more then 27 lines
#         if len(line.strip()) > 27:
#             continue
# 
#         if sender_check(line):
#             return True
# 
#         if (binary_regex_search(RE_RELAX_PHONE)(line) +
#                 binary_regex_search(RE_EMAIL)(line) +
#                 binary_regex_search(RE_URL)(line) == 1):
#             upvotes += 1
# 
#     if upvotes > 1:
#         return True
# 
#     return False
# 
# Path: talon/utils.py
# def get_delimiter(msg_body):
#     delimiter = RE_DELIMITER.search(msg_body)
#     if delimiter:
#         delimiter = delimiter.group()
#     else:
#         delimiter = '\n'
# 
#     return delimiter


# Path: talon/signature/extraction.py
import logging
import numpy
import regex as re
from talon.signature.bruteforce import get_signature_candidate
from talon.signature.learning.featurespace import features, build_pattern
from talon.signature.learning.helpers import has_signature
from talon.utils import get_delimiter

# -*- coding: utf-8 -*-

from __future__ import absolute_import



log = logging.getLogger(__name__)

EXTRACTOR = None

# regex signature pattern for reversed lines
# assumes that all long lines have been excluded
RE_REVERSE_SIGNATURE = re.compile(r'''
# signature should consists of blocks like this
(?:
   # it could end with empty line
   e*
   # there could be text lines but no more than 2 in a row
   (te*){,2}
   # every block should end with signature line

   s