1import logging 2import time 3import sys 4import pkg_resources 5 6from AnyQt.QtCore import QSettings, QThread, pyqtSignal, Qt, QUrl 7from AnyQt.QtGui import QDesktopServices 8from AnyQt.QtWidgets import QMessageBox 9from urllib.request import urlopen, Request 10from Orange.version import version as current 11 12 13log = logging.getLogger(__name__) 14VERSION_URL = 'https://singlecell.biolab.si/version/' 15DOWNLOAD_URL = 'https://singlecell.biolab.si/download/' 16USER_AGENT = 'scOrange{orange_version}:Python{py_version}:{platform}:{conda}' 17UPDATE_AVAILABLE_TITLE = 'scOrange Update Available' 18UPDATE_AVAILABLE_MESSAGE = ( 19 'A newer version of scOrange is available.<br><br>' 20 '<b>Current version:</b> {current_version}<br>' 21 '<b>Latest version:</b> {latest_version}' 22) 23 24 25def check_for_updates(): 26 settings = QSettings() 27 check_updates = settings.value('startup/check-updates', True, type=bool) 28 last_check_time = settings.value('startup/last-update-check-time', 0, type=int) 29 ONE_DAY = 86400 30 31 if check_updates and time.time() - last_check_time > ONE_DAY: 32 settings.setValue('startup/last-update-check-time', int(time.time())) 33 34 thread = GetLatestVersion() 35 thread.resultReady.connect(compare_versions) 36 thread.start() 37 return thread 38 39 40class GetLatestVersion(QThread): 41 resultReady = pyqtSignal(str) 42 43 def run(self): 44 try: 45 request = Request(VERSION_URL, 46 headers={ 47 'Accept': 'text/plain', 48 'Accept-Encoding': 'gzip, deflate', 49 'Connection': 'close', 50 'User-Agent': self.ua_string()}) 51 contents = urlopen(request, timeout=10).read().decode() 52 # Nothing that this fails with should make Orange crash 53 except Exception: # pylint: disable=broad-except 54 log.exception('Failed to check for updates') 55 else: 56 self.resultReady.emit(contents) 57 58 @staticmethod 59 def ua_string(): 60 is_anaconda = 'Continuum' in sys.version or 'conda' in sys.version 61 return USER_AGENT.format( 62 orange_version=current, 63 py_version='.'.join(sys.version[:3]), 64 platform=sys.platform, 65 conda='Anaconda' if is_anaconda else '', 66 ) 67 68 69def current_version(): 70 return pkg_resources.get_distribution("Orange3-SingleCell").version 71 72 73def compare_versions(latest): 74 current = current_version() 75 version = pkg_resources.parse_version 76 if version(latest) <= version(current): 77 return 78 question = QMessageBox( 79 QMessageBox.Information, 80 UPDATE_AVAILABLE_TITLE, 81 UPDATE_AVAILABLE_MESSAGE.format( 82 current_version=current, 83 latest_version=latest), 84 textFormat=Qt.RichText) 85 ok = question.addButton('Download Now', question.AcceptRole) 86 question.setDefaultButton(ok) 87 question.addButton('Remind Later', question.RejectRole) 88 question.finished.connect( 89 lambda: 90 question.clickedButton() == ok and 91 QDesktopServices.openUrl(QUrl(DOWNLOAD_URL))) 92 question.show() 93