Skip to content

Instantly share code, notes, and snippets.

@metal3d
Created September 8, 2018 16:17
Show Gist options
  • Save metal3d/c417a20fd5ce6abde9941ba547621813 to your computer and use it in GitHub Desktop.
Save metal3d/c417a20fd5ce6abde9941ba547621813 to your computer and use it in GitHub Desktop.

Revisions

  1. metal3d created this gist Sep 8, 2018.
    112 changes: 112 additions & 0 deletions dlblender
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,112 @@
    #!/bin/env python3
    # -*- encoding: utf8 -*-
    """
    Download latest build for Blender 2.7x and 2.8x
    How to use:
    - get that source code and name it "dlblender"
    - change vars INSTALL_PATH and LINK_PATH is you want
    - INSTALL_PATH is where will reside new and old version of blender.
    I'm using hidden path "~/.blender"
    - LINK_PATH is where symbolic link to blender-2.79 and blender-2.80 will reside.
    I'm using ~/Apps
    - set it executable, and put it in ~/.local/bin or /usr/local/bin (PATH)
    Then, call "dlblender" in a terminal
    Note:
    - I'm detecting CPU architecture to get archives
    - actually, not compatible with Mac and Windows, but I can do it later, that's why
    I made a function to detect archive type (tar, zip...) and CPU architecture. Right now
    I only tested that on my Fedora 28
    - If you like it, or want more, maybe I'll create a real repository
    Author: Patrice Ferlet <[email protected]>
    License: WTFPL http://www.wtfpl.net/
    """

    import os
    import re
    import platform
    import shutil
    import tarfile
    import tempfile
    import requests


    BASE = "https://builder.blender.org"
    INSTALL_DIR = os.path.expanduser("~/.blender")
    LINK_DIR = os.path.expanduser("~/Apps")

    def get_download():
    """ Find download links """
    arch = platform.machine()
    find = r'href="(/?download/+blender-[a-z0-9-\.]+-%s[^"]+)"' % arch
    resp = requests.get(BASE + "/download")
    body = resp.text

    matches = re.findall(find, body, re.DOTALL|re.MULTILINE)
    matches = [m.replace("//", "/") for m in matches]
    return matches

    def download(link):
    """ Downlad chunked file """
    bname = os.path.basename(link)
    link = BASE + link
    tmp = tempfile.gettempdir()
    dest = os.path.join(tmp, bname)

    if os.path.exists(dest):
    print("File %s already downloaded" % dest)
    else:
    print("Downloading %s to %s" % (link, dest))
    data = requests.get(link, stream=True)
    if data.status_code == 200:
    with open(dest, "wb+") as fdest:
    for chunk in data:
    fdest.write(chunk)
    return dest


    def install(blender):
    """ Install blender from archive """
    version = re.findall(r"blender-(\d+.\d+)-.*", blender)
    version = version[0]
    extracted = extract(blender)
    new_version = os.path.join(INSTALL_DIR, extracted)
    dest = os.path.join(LINK_DIR, "blender-" + version)

    print("Linking %s -> %s" % (new_version, dest))
    os.unlink(dest)
    os.symlink(new_version, dest, target_is_directory=True)




    def extract(archive):
    """ Universal archive extractor """
    blender_dir = None
    if archive_type(archive):
    print("Extracting %s" % archive)
    with tarfile.open(archive) as tfile:
    blender_dir = os.path.dirname(tfile.firstmember.path)
    if not os.path.exists(blender_dir):
    tfile.extractall()
    os.unlink(archive)
    return blender_dir


    def archive_type(archive):
    """ Return archive type for a given filename """
    if ".tar.gz" in archive or ".tar.bz2" in archive:
    return "tar"
    if "zip" in archive:
    return "zip"
    return None

    if __name__ == "__main__":
    os.chdir(INSTALL_DIR)
    dl = get_download()
    for d in dl:
    d = download(d)
    install(d)