def search_file (pattern, f):
    """
    Function to searach a single file for a single search pattern.
    """

    fn_matched = False
    contents_matched = False

    # Use mimetypes to exclude binary files where possible
    if not re.match(r'.+_mqc\.(png|jpg|jpeg)', f['fn']):
        (ftype, encoding) = mimetypes.guess_type(os.path.join(f['root'], f['fn']))
        if encoding is not None:
            return False
        if ftype is not None and ftype.startswith('image'):
            return False

    # Search pattern specific filesize limit
    if pattern.get('max_filesize') is not None and 'filesize' in f:
        if f['filesize'] > pattern.get('max_filesize'):
            logger.debug("Ignoring because exceeded search pattern filesize limit: {}".format(f['fn']))
            return False

    # Search by file name (glob)
    if pattern.get('fn') is not None:
        if fnmatch.fnmatch(f['fn'], pattern['fn']):
            fn_matched = True
            if pattern.get('contents') is None and pattern.get('contents_re') is None:
                return True

    # Search by file name (regex)
    if pattern.get('fn_re') is not None:
        if re.match( pattern['fn_re'], f['fn']):
            fn_matched = True
            if pattern.get('contents') is None and pattern.get('contents_re') is None:
                return True

    # Search by file contents
    if pattern.get('contents') is not None or pattern.get('contents_re') is not None:
        if pattern.get('contents_re') is not None:
            repattern = re.compile(pattern['contents_re'])
        try:
            with io.open (os.path.join(f['root'],f['fn']), "r", encoding='utf-8') as f:
                l = 1
                for line in f:
                    # Search by file contents (string)
                    if pattern.get('contents') is not None:
                        if pattern['contents'] in line:
                            contents_matched = True
                            if pattern.get('fn') is None and pattern.get('fn_re') is None:
                                return True
                            break
                    # Search by file contents (regex)
                    elif pattern.get('contents_re') is not None:
                        if re.search(repattern, line):
                            contents_matched = True
                            if pattern.get('fn') is None and pattern.get('fn_re') is None:
                                return True
                            break
                    # Break if we've searched enough lines for this pattern
                    if pattern.get('num_lines') and l >= pattern.get('num_lines'):
                        break
                    l += 1
        except (IOError, OSError, ValueError, UnicodeDecodeError):
            if config.report_readerrors:
                logger.debug("Couldn't read file when looking for output: {}".format(f['fn']))
                return False

    return fn_matched and contents_matched
def search_file ( pattern , f ) : fn_matched = False contents_matched = False if not re . match ( r'.+_mqc\.(png|jpg|jpeg)' , f [ 'fn' ] ) : ( ftype , encoding ) = mimetypes . guess_type ( os . path . join ( f [ 'root' ] , f [ 'fn' ] ) ) if encoding is not None : return False if ftype is not None and ftype . startswith ( 'image' ) : return False if pattern . get ( 'max_filesize' ) is not None and 'filesize' in f : if f [ 'filesize' ] > pattern . get ( 'max_filesize' ) : logger . debug ( "Ignoring because exceeded search pattern filesize limit: {}" . format ( f [ 'fn' ] ) ) return False if pattern . get ( 'fn' ) is not None : if fnmatch . fnmatch ( f [ 'fn' ] , pattern [ 'fn' ] ) : fn_matched = True if pattern . get ( 'contents' ) is None and pattern . get ( 'contents_re' ) is None : return True if pattern . get ( 'fn_re' ) is not None : if re . match ( pattern [ 'fn_re' ] , f [ 'fn' ] ) : fn_matched = True if pattern . get ( 'contents' ) is None and pattern . get ( 'contents_re' ) is None : return True if pattern . get ( 'contents' ) is not None or pattern . get ( 'contents_re' ) is not None : if pattern . get ( 'contents_re' ) is not None : repattern = re . compile ( pattern [ 'contents_re' ] ) try : with io . open ( os . path . join ( f [ 'root' ] , f [ 'fn' ] ) , "r" , encoding = 'utf-8' ) as f : l = 1 for line in f : if pattern . get ( 'contents' ) is not None : if pattern [ 'contents' ] in line : contents_matched = True if pattern . get ( 'fn' ) is None and pattern . get ( 'fn_re' ) is None : return True break elif pattern . get ( 'contents_re' ) is not None : if re . search ( repattern , line ) : contents_matched = True if pattern . get ( 'fn' ) is None and pattern . get ( 'fn_re' ) is None : return True break if pattern . get ( 'num_lines' ) and l >= pattern . get ( 'num_lines' ) : break l += 1 except ( IOError , OSError , ValueError , UnicodeDecodeError ) : if config . report_readerrors : logger . debug ( "Couldn't read file when looking for output: {}" . format ( f [ 'fn' ] ) ) return False return fn_matched and contents_matched
Function to searach a single file for a single search pattern.