예제 #1
0
def static_with_build(path, with_build=True):
    """
    We need a way for the client browser to load the newly updated static
        files because some browsers cache the static files and does not
        load them up automatically when we release new versions but with
        the same name.

    REF: https://github.com/learningequality/ka-lite/issues/1161

    One way is to add a Get paramater to the static file's path so it becomes
        unique and the browser invalidates it's cached version.

    We re-use django's `{% static <path> %}` template tag to add build version
        to the filenames of static files.

    REF: https://www.quora.com/What-are-the-best-practices-for-versioning-CSS-and-JS-files

    Option 1: Use the `fle_utils.config.models.Settings`
        Pros: It works and more flexible.
        Cons: Requires us to update the BUILD_ID key at admin page.

    Option 2: Use the BUILD as Get parameter.
        Pros: It works.
        Cons: We need to maintain the `kalite/version.py` hard-coded values
            every time we make a release.

    Option 3: Use the SHA hash of the file's bytes as querystring.
        Pros: It works and more reliable.
        Cons: Requires us to open the static files to generate the hash.
                TODO(cpauya): Benchmark this!
                TODO(cpauya): Inefficient!  This is called everytime the static file is used.

    We try all options which does not throw exception.
    """
    global BUILD_HASH_CACHE

    new_path = static_lib(path)
    if with_build:
        build_id = ''

        # try fle_utils`s Settings
        try:
            if BUILD_HASH_CACHE:
                build_id = BUILD_HASH_CACHE
            else:
                build_id = BUILD_HASH_CACHE = Settings.get(BUILD_HASH, '')
        except Exception:
            pass

        # try the BUILD data from `version.py`
        if not build_id:
            try:
                build_id = BUILD_HASH_CACHE = version.VERSION_INFO[version.VERSION]["git_commit"][0:8]
            except:
                pass

        # attempt to use hash
        if not build_id:
            try:
                # REF: http://stackoverflow.com/questions/16874598/how-do-i-calculate-the-md5-checksum-of-a-file-in-python
                file_path = os.path.realpath(os.path.join(settings.STATIC_ROOT, path))
                with open(file_path, 'rb') as file_to_check:
                    # REF: http://stackoverflow.com/questions/1131220/get-md5-hash-of-big-files-in-python
                    filehash = hashlib.sha256()
                    while True:
                        data = file_to_check.read(8192)
                        if not data:
                            break
                        filehash.update(data)
                    build_id = filehash.hexdigest()
            except Exception:
                pass

        if build_id:
            new_path = '%s?%s' % (new_path, build_id,)
    return new_path
예제 #2
0
def static_with_build(path, with_build=True):
    """
    We need a way for the client browser to load the newly updated static
        files because some browsers cache the static files and does not
        load them up automatically when we release new versions but with
        the same name.

    REF: https://github.com/learningequality/ka-lite/issues/1161

    One way is to add a Get paramater to the static file's path so it becomes
        unique and the browser invalidates it's cached version.

    We re-use django's `{% static <path> %}` template tag to add build version
        to the filenames of static files.

    REF: https://www.quora.com/What-are-the-best-practices-for-versioning-CSS-and-JS-files

    Option 1: Use the `fle_utils.config.models.Settings`
        Pros: It works and more flexible.
        Cons: Requires us to update the BUILD_ID key at admin page.

    Option 2: Use the BUILD as Get parameter.
        Pros: It works.
        Cons: We need to maintain the `kalite/version.py` hard-coded values
            every time we make a release.

    Option 3: Use the SHA hash of the file's bytes as querystring.
        Pros: It works and more reliable.
        Cons: Requires us to open the static files to generate the hash.
                TODO(cpauya): Benchmark this!
                TODO(cpauya): Inefficient!  This is called everytime the static file is used.

    We try all options which does not throw exception.
    """
    global BUILD_HASH_CACHE

    new_path = static_lib(path)
    if with_build:
        build_id = ''

        # try fle_utils`s Settings
        try:
            if BUILD_HASH_CACHE:
                build_id = BUILD_HASH_CACHE
            else:
                build_id = BUILD_HASH_CACHE = Settings.get(BUILD_HASH, '')
        except Exception:
            pass

        # try the BUILD data from `version.py`
        if not build_id:
            try:
                build_id = BUILD_HASH_CACHE = version.VERSION_INFO[
                    version.VERSION]["git_commit"][0:8]
            except:
                pass

        # attempt to use hash
        if not build_id:
            try:
                # REF: http://stackoverflow.com/questions/16874598/how-do-i-calculate-the-md5-checksum-of-a-file-in-python
                file_path = os.path.realpath(
                    os.path.join(settings.STATIC_ROOT, path))
                with open(file_path, 'rb') as file_to_check:
                    # REF: http://stackoverflow.com/questions/1131220/get-md5-hash-of-big-files-in-python
                    filehash = hashlib.sha256()
                    while True:
                        data = file_to_check.read(8192)
                        if not data:
                            break
                        filehash.update(data)
                    build_id = filehash.hexdigest()
            except Exception:
                pass

        if build_id:
            new_path = '%s?%s' % (
                new_path,
                build_id,
            )
    return new_path
예제 #3
0
def static(path, with_build=False):
    """
    This is a dummy/passthrough template tag to make templates (such as coach reports) from the
    distributed server work on the central server.
    """
    return static_lib(path)