OpenSlides/openslides/core/management/commands/getgeiss.py
2017-09-03 18:34:55 +02:00

92 lines
3.1 KiB
Python

import distutils
import json
import os
import stat
import sys
from urllib.request import urlopen, urlretrieve
from django.core.management.base import BaseCommand, CommandError
from openslides.utils.main import get_geiss_path
class Command(BaseCommand):
"""
Command to get the latest release of Geiss from GitHub.
"""
help = 'Get the latest Geiss release from GitHub.'
FIRST_NOT_SUPPORTED_VERSION = '1.0.0'
def handle(self, *args, **options):
geiss_github_name = self.get_geiss_github_name()
download_file = get_geiss_path()
if os.path.isfile(download_file):
# Geiss does probably exist. Do nothing.
# TODO: Add an update flag, that Geiss is downloaded anyway.
return
release = self.get_release()
download_url = None
for asset in release['assets']:
if asset['name'] == geiss_github_name:
download_url = asset['browser_download_url']
break
if download_url is None:
raise CommandError("Could not find download URL in release.")
urlretrieve(download_url, download_file)
# Set the executable bit on the file. This will do nothing on windows
st = os.stat(download_file)
os.chmod(download_file, st.st_mode | stat.S_IEXEC)
self.stdout.write(self.style.SUCCESS('Geiss {} successfully downloaded.'.format(release['tag_name'])))
def get_release(self):
"""
Returns API data for the latest supported Geiss release.
"""
response = urlopen(self.get_geiss_url()).read()
releases = json.loads(response.decode())
for release in releases:
version = distutils.version.StrictVersion(release['tag_name']) # type: ignore
if version < self.FIRST_NOT_SUPPORTED_VERSION:
break
else:
raise CommandError('Could not find Geiss release.')
return release
def get_geiss_url(self):
"""
Returns the URL to the API which gives the information which Geiss
binary has to be downloaded.
Currently this is a static GitHub URL to the repository where Geiss
is hosted at the moment.
"""
# TODO: Use a settings variable or a command line flag in the future.
return 'https://api.github.com/repos/ostcar/geiss/releases'
def get_geiss_github_name(self):
"""
Returns the name of the Geiss executable for the current operating
system.
For example geiss_windows_64 on a windows64 platform.
"""
# This will be 32 if the current python interpreter has only
# 32 bit, even if it is run on a 64 bit operating sysem.
bits = '64' if sys.maxsize > 2**32 else '32'
geiss_names = {
'linux': 'geiss_linux_{bits}',
'win32': 'geiss_windows_{bits}.exe', # Yes, it is win32, even on a win64 system!
'darwin': 'geiss_mac_{bits}'}
try:
return geiss_names[sys.platform].format(bits=bits)
except KeyError:
raise CommandError("Plattform {} is not supported by Geiss".format(sys.platform))