Robot Framework Integrated Development Environment (RIDE)
updatenotifier.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 # Configure wx version to allow running test app in __main__
17 
18 
19 import time
20 import urllib.request as urllib2
21 import xmlrpc.client as xmlrpclib
22 
23 import wx
24 from wx import Colour
25 
26 from .. import version
27 from ..utils.versioncomparator import cmp_versions
28 from ..widgets import ButtonWithHandler, HtmlWindow, RIDEDialog
29 
30 
33 _CHECK_FOR_UPDATES_SETTING = "check for updates"
34 
37 _LAST_UPDATE_CHECK_SETTING = "last update check"
38 
39 
41 
42  VERSION = version.VERSION
43  SECONDS_IN_WEEK = 60*60*24*7
44 
45  def __init__(self, settings):
46  self._settings_settings = settings
47 
48  def notify_update_if_needed(self, update_notification_callback):
49  if self._should_check_should_check() and self._is_new_version_available_is_new_version_available():
50  update_notification_callback(self._newest_version_newest_version, self._download_url_download_url, self._settings_settings)
51 
52  def _should_check(self):
53  if self._settings_settings.get(_CHECK_FOR_UPDATES_SETTING, None) is None:
54  self._settings_settings[_CHECK_FOR_UPDATES_SETTING] = True
55  return True
56  return self._settings_settings[_CHECK_FOR_UPDATES_SETTING] and \
57  time.time() - self._settings_settings.get(_LAST_UPDATE_CHECK_SETTING, 0) > self.SECONDS_IN_WEEKSECONDS_IN_WEEK
58 
60  self._settings_settings[_LAST_UPDATE_CHECK_SETTING] = time.time()
61  try:
62  self._newest_version_newest_version = self._get_newest_version_get_newest_version()
63  self._download_url_download_url = self._get_download_url_get_download_url(self._newest_version_newest_version)
64  except Exception as e:
65  print(e)
66  #There are many possible errors:
67  # - Timeout
68  # - Corrupted data
69  # - Server fault message
70  # - Unexpected change in dataformat
71  return False
72  return cmp_versions(self.VERSIONVERSION, self._newest_version_newest_version) == -1
73 
75  return self._get_response_get_response(('robotframework-ride',), 'package_releases')[0]
76 
77  def _get_download_url(self, version):
78  from time import sleep
79  sleep(1) # To avoid HTTPTooManyRequests
80  return self._get_response_get_response(('robotframework-ride', version), 'release_data')['download_url']
81 
82  def _get_response(self, params, method):
83  xmlparm = xmlrpclib.dumps(params, method)
84  req = urllib2.Request('https://pypi.python.org/pypi',
85  xmlparm.encode('utf-8'),
86  {'Content-Type':'text/xml'})
87  data = urllib2.urlopen(req, timeout=1).read()
88  xml = xmlrpclib.loads(data)[0][0]
89  return xml
90 
91 
92 class LocalHtmlWindow(HtmlWindow):
93  def __init__(self, parent, size=(600,400)):
94  HtmlWindow.__init__(self, parent, size)
95  if "gtk2" or "gtk3" in wx.PlatformInfo:
96  self.SetStandardFonts()
97 
98  def OnLinkClicked(self, link):
99  wx.LaunchDefaultBrowser(link.GetHref())
100 
101 
102 class UpdateDialog(RIDEDialog):
103 
104  def __init__(self, version, url, settings):
105  self._settings_settings = settings
106  RIDEDialog.__init__(self, title="Update available", size=(400, 400),
107  style=wx.DEFAULT_FRAME_STYLE | wx.FRAME_FLOAT_ON_PARENT)
108  # set Left to Right direction (while we don't have localization)
109  self.SetLayoutDirection(wx.Layout_LeftToRight)
110  self.SetBackgroundColour(Colour(self.color_background))
111  self.SetForegroundColour(Colour(self.color_foreground))
112  sizer = wx.BoxSizer(orient=wx.VERTICAL)
113  hwin = LocalHtmlWindow(self, size=(400, 200))
114  hwin.set_content(f"New version {version} available from <a href=\"{url}\">{url}</a><br/>"
115  f"See this version <a href=\"https://github.com/robotframework/RIDE/blob/master/doc"
116  f"/releasenotes/ride-{version}.rst\">Release Notes</a><br/><br/>"
117  f"You can update with the command:<br/><b>pip install -U robotframework-ride</b>"
118  f"<br/><br/>See the latest development <a href=\"https://github.com/robotframework/RIDE"
119  f"/blob/master/CHANGELOG.adoc\">CHANGELOG</a>")
120  irep = hwin.GetInternalRepresentation()
121  hwin.SetSize((irep.GetWidth()+25, irep.GetHeight()+20))
122  sizer.Add(hwin)
123  checkbox = wx.CheckBox(self, -1, label="I\'m using another method for RIDE updates\n and "
124  "do not need automatic update checks")
125  checkbox.Bind(wx.EVT_CHECKBOX, handler=self.OnCheckboxChangeOnCheckboxChange)
126  sizer.Add(checkbox)
127  button = ButtonWithHandler(self, label="remind me later", handler=self.OnRemindMeLaterOnRemindMeLater)
128  button.SetBackgroundColour(Colour(self.color_secondary_background))
129  button.SetForegroundColour(Colour(self.color_secondary_foreground))
130  sizer.Add(button)
131  self.SetSizer(sizer)
132  self.CentreOnParent(wx.BOTH)
133  self.Fit()
134  self.SetFocus()
135  self.ShowModal()
136  self.Destroy()
137 
138  def OnRemindMeLater(self, event):
139  self.Close(True)
140 
141  def OnCheckboxChange(self, event):
142  self._settings_settings[_CHECK_FOR_UPDATES_SETTING] = not event.IsChecked()
143  event.Skip()
def __init__(self, parent, size=(600, 400))
def __init__(self, version, url, settings)
def notify_update_if_needed(self, update_notification_callback)
def cmp_versions(version1, version2)