'Open a file for writing the image file for an image
with supplied identifier.
:param image_id: Image ID'

@contextmanager
def open_for_write(self, image_id):

    incomplete_path = self.get_image_filepath(image_id, 'incomplete')
    def commit():
        with self.get_db() as db:
            final_path = self.get_image_filepath(image_id)
            LOG.debug("Fetch    finished,    moving    '%(incomplete_path)s'    to    '%(final_path)s'", dict(incomplete_path=incomplete_path, final_path=final_path))
            os.rename(incomplete_path, final_path)
            if self.is_queued(image_id):
                fileutils.delete_if_exists(self.get_image_filepath(image_id, 'queue'))
            filesize = os.path.getsize(final_path)
            now = time.time()
            db.execute('INSERT    INTO    cached_images\n                                                                                                            (image_id,    last_accessed,    last_modified,    hits,    size)\n                                                                                                            VALUES    (?,    ?,    ?,    0,    ?)', (image_id, now, now, filesize))
            db.commit()
    def rollback(e):
        with self.get_db() as db:
            if os.path.exists(incomplete_path):
                invalid_path = self.get_image_filepath(image_id, 'invalid')
                LOG.warn((_LW("Fetch    of    cache    file    failed    (%(e)s),    rolling    back    by    moving    '%(incomplete_path)s'    to    '%(invalid_path)s'") % {'e': e, 'incomplete_path': incomplete_path, 'invalid_path': invalid_path}))
                os.rename(incomplete_path, invalid_path)
            db.execute('DELETE    FROM    cached_images\n                                                                                                            WHERE    image_id    =    ?', (image_id,))
            db.commit()
    try:
        with open(incomplete_path, 'wb') as cache_file:
            (yield cache_file)
    except Exception as e:
        with excutils.save_and_reraise_exception():
            rollback(e)
    else:
        commit()
    finally:
        if os.path.exists(incomplete_path):
            rollback('incomplete    fetch')
