Source code for fsleyes.actions.updatecheck

#
# updatecheck.py - The UpdateCheckAction class.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module provides the :class:`.UpdateCheckAction`, which checks to see
if a new version of FSLeyes is available.
"""


import logging

import urllib.request as request
import ssl
import json

import wx
import wx.adv as wxadv

import fsl.version                  as fslversion

import fsleyes_widgets.utils.status as status
import fsleyes.version              as version
import fsleyes.strings              as strings
from . import                          base


log = logging.getLogger(__name__)


_FSLEYES_URL = 'https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSLeyes'
"""A url to direct the user towards to download the latest version of FSLeyes.
"""


_FSLEYES_VERSION_URL = 'https://api.anaconda.org/package/conda-forge/fsleyes'
"""A url which points to a JSON file that contains information about the
FSLeyes package on conda-forge.
"""


[docs]class UpdateCheckAction(base.Action): """The :class:`.UpdateCheckAction` is an :class:`.Action` which checks to see if a new version of FSLeyes is available, and tells the user if there is. """
[docs] def __init__(self, overlayList, displayCtx): """Create an ``UpdateCheckAction``. """ base.Action.__init__( self, overlayList, displayCtx, self.__checkForUpdates)
def __checkForUpdates(self, showUpToDateMessage=True, showErrorMessage=True, ignorePoint=False): """Run this action. Downloads a text file from a URL which contains the latest available version of FSLeyes. Compares that version with the running version. Displays a message to the user. :arg showUpToDateMessage: Defaults to ``True``. If ``False``, and the current version of FSLeyes is up to date, the user is not informed. :arg showErrorMessage: Defaults to ``True``. If ``False``, and some error occurs while checking for updates, the user is not informed. :arg ignorePoint: Defaults to ``False``. If ``True``, the point release number is ignored in the comparison. """ errMsg = strings.messages[self, 'newVersionError'] errTitle = strings.titles[ self, 'newVersionError'] with status.reportIfError(errTitle, errMsg, raiseError=False, report=showErrorMessage): log.debug('Checking for FSLeyes updates ({})'.format( _FSLEYES_VERSION_URL)) ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE with request.urlopen(_FSLEYES_VERSION_URL, context=ctx) as f: info = json.loads(f.read().decode('utf-8')) latest = info['latest_version'] current = version.__version__ upToDate = fslversion.compareVersions(latest, current, ignorePoint) <= 0 log.debug('This version of FSLeyes ({}) is ' '{} date (latest: {})'.format( current, 'up to' if upToDate else 'out of', latest)) if upToDate and not showUpToDateMessage: return urlMsg = strings.messages[self, 'updateUrl'] if upToDate: title = strings.titles[ self, 'upToDate'] msg = strings.messages[self, 'upToDate'] msg = msg.format(current) else: title = strings.titles[ self, 'newVersionAvailable'] msg = strings.messages[self, 'newVersionAvailable'] msg = msg.format(current, latest, _FSLEYES_URL) parent = wx.GetTopLevelWindows()[0] dlg = UrlDialog(parent, title, msg, urlMsg, _FSLEYES_URL) dlg.CentreOnParent() dlg.ShowModal()
[docs]class UrlDialog(wx.Dialog): """Custom ``wx.Dialog`` used by the :class:`UpdateCheckAction` to display a message containing the FSLeyes download URL to the user. """
[docs] def __init__(self, parent, title, msg, urlMsg=None, url=None): """Create a ``UrlDialog``. :arg parent: ``wx`` parent object :arg title: Dialog title :arg msg: Message to display :arg urlMsg: Message to display next to the URL. Not shown if a URL is not provided. :arg url: URL to display. """ wx.Dialog.__init__(self, parent, title=title, style=wx.DEFAULT_DIALOG_STYLE) ok = wx.Button( self, label='Ok', id=wx.ID_OK) msg = wx.StaticText(self, label=msg) self.__ok = ok if urlMsg is not None: urlMsg = wx.StaticText(self, label=urlMsg) if url is not None: url = wxadv.HyperlinkCtrl(self, url=url) sizer = wx.BoxSizer(wx.VERTICAL) btnSizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add((1, 20), flag=wx.EXPAND, proportion=1) sizer.Add(msg, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=20) sizer.Add((1, 20), flag=wx.EXPAND, proportion=1) if urlMsg is not None and url is not None: sizer.Add(urlMsg, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=20) sizer.Add((1, 5), flag=wx.EXPAND, proportion=1) if url is not None: sizer.Add(url, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=20) sizer.Add((1, 20), flag=wx.EXPAND, proportion=1) btnSizer.Add((20, 1), flag=wx.EXPAND, proportion=1) btnSizer.Add(ok, flag=wx.EXPAND) btnSizer.Add((20, 1), flag=wx.EXPAND) sizer.Add(btnSizer, flag=wx.EXPAND) sizer.Add((1, 20), flag=wx.EXPAND, proportion=1) ok.SetDefault() self.SetSizer(sizer) self.Layout() self.Fit()
@property def ok(self): """Return a reference to the OK button. """ return self.__ok