| Index: cms/bin/generate_static_pages.py | 
| diff --git a/cms/bin/generate_static_pages.py b/cms/bin/generate_static_pages.py | 
| index 5eaeb1b9af236f2833bb27005a0ffe89a3e0b7d2..67b5869f817815279d5c61af0a0ecc716359dde7 100644 | 
| --- a/cms/bin/generate_static_pages.py | 
| +++ b/cms/bin/generate_static_pages.py | 
| @@ -15,11 +15,11 @@ | 
|  | 
| import os | 
| import re | 
| -import errno | 
| import codecs | 
| import ConfigParser | 
| import logging | 
| from argparse import ArgumentParser | 
| +import shutil | 
|  | 
| from cms.utils import get_page_params, process_page | 
| from cms.sources import create_source | 
| @@ -27,6 +27,91 @@ from cms.sources import create_source | 
| MIN_TRANSLATED = 0.3 | 
|  | 
|  | 
| +def ensure_dirs(partial_path, path_parts): | 
| +    """Create an entire path of directories. | 
| + | 
| +    This is a recursive function, that also treats these special cases, if | 
| +    the partial path we reached so far exists and is: | 
| + | 
| +    1. a directory - do nothing, just move on, | 
| +    2. a file - remove the file, create a directory in its place, and move on. | 
| +    3. neither a file, nor a directory - raise and exception. | 
| + | 
| +    Parameters | 
| +    ---------- | 
| +    partial_path: str | 
| +        The path to resolve at this step. | 
| +    path_parts: iterable | 
| +        The remaining directories that will be created. | 
| + | 
| +    Raises | 
| +    ------- | 
| +    Exception | 
| +        If the path we want to resolve at this step exists and is neither a | 
| +        file, nor a directory. | 
| + | 
| +    """ | 
| +    if os.path.isfile(partial_path): | 
| +        os.remove(partial_path) | 
| +    elif os.path.exists(partial_path) and not os.path.isdir(partial_path): | 
| +        raise Exception('The object at {} is not recognisable! It is neither ' | 
| +                        'a file, nor a directory!'.format(partial_path)) | 
| + | 
| +    if not os.path.isdir(partial_path): | 
| +        os.mkdir(partial_path) | 
| + | 
| +    if len(path_parts) == 0: | 
| +        return | 
| + | 
| +    resolve_dirs(os.path.join(partial_path, path_parts[0]), path_parts[1:]) | 
| + | 
| + | 
| +def is_in_previous_version(path, new_contents, encoding): | 
| +    """Test if a file we try to create already is in the output directory. | 
| + | 
| +    It tests if the pre-existent file has all the expected content. | 
| +    It also handles the following two cases: | 
| + | 
| +    1. The path is a directory - If this happens, it removes the directory from | 
| +    the file tree. | 
| +    2. The path exists, but it's neither a file, nor a directory. - If this | 
| +    happens, it will raise an exception. | 
| + | 
| +    Parameters | 
| +    ---------- | 
| +    path: str | 
| +        The path we want to test for existence. | 
| +    new_contents: bytes | 
| +        The contents we want to write to the file in the new version of the | 
| +        website. | 
| +    encoding: str | 
| +        The encoding to open the file in (if the path exists and is a file. | 
| + | 
| +    Returns | 
| +    ------- | 
| +    bool | 
| +        True - if the file exists and has the same contents. | 
| +        False - if the path doesn't exist/ is not a file. | 
| + | 
| +    Raises | 
| +    ------ | 
| +    Exception | 
| +        If the path exists, but is neither a file, nor a directory. | 
| + | 
| +    """ | 
| +    if os.path.isfile(path): | 
| +        with codecs.open(path, 'rb', encoding=encoding) as handle: | 
| +            if handle.read() == new_contents: | 
| +                return True | 
| +    elif os.path.isdir(path): | 
| +        shutil.rmtree(path) | 
| +    elif os.path.exists(path): | 
| +        raise Exception('The object at {} is not recognisable! It is ' | 
| +                        'neither a file, nor a directory!'.format(path)) | 
| + | 
| +    return False | 
| + | 
| + | 
| def generate_pages(repo, output_dir): | 
| known_files = set() | 
|  | 
| @@ -38,16 +123,10 @@ def generate_pages(repo, output_dir): | 
| return | 
| known_files.add(outfile) | 
|  | 
| -        if os.path.exists(outfile): | 
| -            with codecs.open(outfile, 'rb', encoding=encoding) as handle: | 
| -                if handle.read() == contents: | 
| -                    return | 
| +        if is_in_previous_version(outfile, contents, encoding): | 
| +            return | 
|  | 
| -        try: | 
| -            os.makedirs(os.path.dirname(outfile)) | 
| -        except OSError as e: | 
| -            if e.errno != errno.EEXIST: | 
| -                raise | 
| +        resolve_dirs(output_dir, path_parts[:-1]) | 
|  | 
| with codecs.open(outfile, 'wb', encoding=encoding) as handle: | 
| handle.write(contents) | 
|  |