Skip to content

Instantly share code, notes, and snippets.

@cesarizu
Last active May 23, 2019 12:28
Show Gist options
  • Save cesarizu/7a6a5f51d60aeb2bb8286b5118e52eb7 to your computer and use it in GitHub Desktop.
Save cesarizu/7a6a5f51d60aeb2bb8286b5118e52eb7 to your computer and use it in GitHub Desktop.
Update blender beta
#!/usr/bin/env python3
################################################################
# Updates blender to the latest version
#
# Usage: update-blender.py
#
# On execution will search for the latest version on the blender
# website, download it and extract it to the path defined by
# `extract_to`. Will also create a `blender` symlink for the
# folder.
#
# Tested only on linux, YMMV.
################################################################
from bs4 import BeautifulSoup
import tarfile
from tempfile import NamedTemporaryFile
from pathlib import Path
import progressbar
import urllib.request, urllib.error, urllib.parse
################################################################
# Configuration
#
base_url = 'https://builder.blender.org/download/'
version = '2.80'
os = 'linux'
arch = 'x86_64'
extract_to = Path('~/opt').expanduser()
#
################################################################
class DownloadProgressBar():
"""
Used to present a progressbar while downloading the file.
"""
def __init__(self):
self.pbar = None
def __call__(self, block_num, block_size, total_size):
if not self.pbar:
self.pbar=progressbar.ProgressBar(maxval=total_size)
self.pbar.start()
downloaded = block_num * block_size
if downloaded < total_size:
self.pbar.update(downloaded)
else:
self.pbar.finish()
def update_blender():
"""
The main execution point. Downloads and extracts the latests version.
"""
conn = urllib.request.urlopen(base_url)
html = conn.read()
soup = BeautifulSoup(html, features='lxml')
links = soup.find_all('a')
for tag in links:
link = tag.get('href', None)
if link is not None and f'/download/blender-{version}' in link and os in link and arch in link:
url = urllib.parse.urljoin(base_url, link)
name = link.split('/')[-1]
with NamedTemporaryFile(suffix=f'_{name}') as tempf:
print(f'Downloading file from {url} to {tempf.name}')
urllib.request.urlretrieve(url, tempf.name, DownloadProgressBar())
with tarfile.open(tempf.name, 'r:*') as tar:
extract(tar)
def extract(tar):
"""
Extracts the provided tar and creates a symlink to the extracted dir.
"""
dirname = tar.getnames()[0].split('/')[0]
target_dir = extract_to / dirname
if target_dir.is_dir():
print(f'{target_dir.name} already exists, not overwriting!')
return
tar.extractall(extract_to)
target_symlink = extract_to / 'blender'
if target_symlink.is_symlink():
print(f'Removing existing symlink to {target_symlink.resolve().name}')
target_symlink.unlink()
if not target_symlink.exists():
print(f'Linking to extracted directory {dirname}')
target_symlink.symlink_to(target_dir)
if __name__ == '__main__':
update_blender()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment