Yield (digest, fname) tuples for all interesting files
       in `dirname`.

def list_files(dirname='.', digest=True):
    """Yield (digest, fname) tuples for all interesting files
       in `dirname`.
    """
    skipdirs = ['__pycache__', '.git', '.svn', 'htmlcov', 'dist', 'build',
                '.idea', 'tasks', 'static', 'media', 'data', 'migrations',
                '.doctrees', '_static', 'node_modules', 'external',
                'jobs', 'tryout', 'tmp', '_coverage',
               ]
    skipexts = ['.pyc', '~', '.svg', '.txt', '.TTF', '.tmp', '.errmail',
                '.email', '.bat', '.dll', '.exe', '.Dll', '.jpg', '.gif',
                '.png', '.ico', '.db', '.md5']
    dirname = str(dirname)
    skipfiles = read_skipfile(dirname)

    def clean_dirs(directories):
        """Remove directories that should be skipped.
        """
        for d in directories:
            if d.endswith('.egg-info'):
                directories.remove(d)
        for d in skipdirs:
            if d in directories:
                directories.remove(d)

    def keep_file(filename, filepath):
        """Returns False if the file should be skipped.
        """
        if filename.startswith('.'):
            return False
        if filepath in skipfiles:
            return False
        for ext in skipexts:
            if filename.endswith(ext):
                return False
        return True

    for root, dirs, files in os.walk(os.path.abspath(dirname)):
        clean_dirs(dirs)
        for fname in files:
            relpth = os.path.relpath(
                os.path.join(root, fname),
                dirname
            ).replace('\\', '/')

            parts = Path(relpth).parts()
            if not keep_file(fname, relpth) or \
                    any(p.startswith('.') for p in parts):
                continue

            pth = os.path.join(dirname, relpth)
            if digest:
                yield md5(open(pth, 'rb').read()).hexdigest(), relpth
            else:
                yield relpth