<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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