<commit_before>import os
import urllib2

class FileDownloadSettings:
    """ 
    Class that contains the details of a file 
    to be downloaded 
    """
    def __init__(self, url, cache_path):
        self.source = url
        self.cache = cache_path


class MissingFileError(Exception):
    """ An error for when a file could not be found. """
    pass

class NamedFileDownloader:
    """ 
    Class that downloads the requested file 
    """
    def __init__(self, settings):
        self.settings = settings

    def __open_remote(self, filename):
        return urllib2.urlopen(self.settings.source + '/' + filename)

    def __path_to_cached_file(self, filename):
        return os.path.join(self.settings.cache, filename)

    def already_cached(self, filename):
        return os.path.exists(self.__path_to_cached_file(filename))
        
    def download(self, filename):
        try:
            remote = self.__open_remote(filename)
            cache = open(self.__path_to_cached_file(filename), 'w')
            cache.write(remote.read())
            remote.close()
            cache.close()
        except urllib2.HTTPError as ex:
            if ex.code == 404:
                raise MissingFileError("%s is missing in the remote location." % filename)
            else:
                raise
        <commit_msg>Refactors the existing methods to separate concerns. I think there is a case for extracting a new class too<commit_after>import os
import urllib2

class FileDownloadSettings:
    """ 
    Class that contains the details of a file 
    to be downloaded 
    """
    def __init__(self, url, cache_path):
        self.source = url
        self.cache = cache_path


class MissingFileError(Exception):
    """ An error for when a file could not be found. """
    pass

class NamedFileDownloader:
    """ 
    Class that downloads the requested file 
    """
    def __init__(self, settings):
        self.settings = settings

    def __open_remote(self, filename):
        return urllib2.urlopen(self.settings.source + '/' + filename)

    def __path_to_cached_file(self, filename):
        return os.path.join(self.settings.cache, filename)

    def already_cached(self, filename):
        return os.path.exists(self.__path_to_cached_file(filename))
    
    def read_remote(self, filename):
        remote = self.__open_remote(filename)
        content = remote.read()        
        remote.close()        
        return content

    def write_cached(self, filename, content):
        cache = open(self.__path_to_cached_file(filename), 'w')
        cache.write(content)
        cache.close()

    def __handle_http_error(self, http_error, filename):
        if http_error.code == 404:
            raise MissingFileError("%s is missing in the remote location." % filename)
        else:
            raise        
            
    def download(self, filename):
        try:
            remote = self.read_remote(filename)
            self.write_cached(filename, remote)
        except urllib2.HTTPError as ex:
            self.__handle_http_error(ex, filename)
{'fraction_non_alphanumeric': 0.08816855753646677, 'fraction_numerical': 0.0038897893030794164, 'mean_word_length': 2.37636761487965, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2469017', 'n_tokens_mistral': 872, 'n_tokens_neox': 837, 'n_words': 235}