Skip to content

Instantly share code, notes, and snippets.

@fepegar
Last active January 20, 2022 15:10
Show Gist options
  • Save fepegar/f49c5062695562370a76222dada47e47 to your computer and use it in GitHub Desktop.
Save fepegar/f49c5062695562370a76222dada47e47 to your computer and use it in GitHub Desktop.
Script I use to automatically update 3D Slicer on Linux every night
#!/usr/bin/env python
import re
import sys
from pathlib import Path
from sys import platform as _platform
import time
import shutil
import urllib.request
import tarfile
import tempfile
# http://stackoverflow.com/questions/5663980/importerror-no-module-named-beautifulsoup
from bs4 import BeautifulSoup # pip install beautifulsoup4
def get_latest_slicer_version(directory):
files = Path(directory).glob('*.ini')
p = 'Slicer-(\d+)'
max_revision = 0
for filepath in files:
rev = re.findall(p, str(filepath))
if rev:
max_revision = max(max_revision, int(rev[0]))
return str(max_revision)
if __name__ == "__main__":
temp_dir = Path(tempfile.mkdtemp())
filepath = temp_dir / 'downloaded_slicer.tar.gz'
unzipped_dir = temp_dir / 'unzipped'
slicer_url = 'https://download.slicer.org'
opt_dir = Path('~/opt/').expanduser()
namic_dir = Path('~/.config/NA-MIC/').expanduser()
if len(sys.argv) == 2:
slicer_bin_dir = Path(sys.argv[1]).expanduser()
else:
slicer_bin_dir = opt_dir / 'Slicer' / 'Nightly'
start_time = time.time()
print(f'Updating Slicer - {time.ctime()}')
# Get download URL
response = urllib.request.urlopen(slicer_url)
html = response.read()
parsed = BeautifulSoup(html, features="html.parser")
o = parsed.findAll('a')
if _platform == "linux" or _platform == "linux2": # linux
button = o[43]
elif _platform == "darwin": # MAC OS X
button = o[42]
elif _platform == "win32": # Windows
button = o[41]
download_url = slicer_url + button.get('href')
button_text = button.getText()
p = r'revision (\d+)'
revisions = re.findall(p, button_text)
if not revisions:
raise RuntimeError(
f'Error retrieving revision number. Button text:\n{button_text}')
revision_number_string = revisions[0]
# Download
print('Downloading nightly build number {} from {}...'.format(
revision_number_string, download_url))
# Set the URL
response = urllib.request.urlopen(download_url)
# Download the data
html = response.read()
# Write
with open(filepath, 'wb') as f:
f.write(html)
# Extract
tar = tarfile.open(filepath, "r:gz")
tar.extractall(unzipped_dir)
tar.close()
unzipped_slicer_dir = unzipped_dir / list(unzipped_dir.iterdir())[0]
print(unzipped_slicer_dir)
# Delete installed version
if slicer_bin_dir.is_dir():
print('Removing', slicer_bin_dir)
shutil.rmtree(slicer_bin_dir)
# Install downloaded version
print('Moving', unzipped_slicer_dir)
print('to', slicer_bin_dir)
shutil.move(unzipped_slicer_dir, slicer_bin_dir)
# TODO: config file
config_filename = f'Slicer-{revision_number_string}.ini'
max_revision = get_latest_slicer_version(namic_dir)
# Cleanup
shutil.rmtree(temp_dir)
end_time = int(time.time() - start_time)
m, s = divmod(end_time, 60)
print(f'Operation finished in {m} minutes and {s} seconds.\n\n')
@BishopWolf
Copy link

namicDir = '/home/fernando/.config/NA-MIC/' shall be namicDir = os.path.join(os.path.expanduser('~'),'.config','NA-MIC')

@fepegar
Copy link
Author

fepegar commented Mar 5, 2020

This is the script I use :)

But sure, I'll change that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment