1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
|
import numbers
# Is this true? Dont understand this
def get_stable_release_from_server_string(stri):
return stri
# needs testing!
def get_stable_release_from_coot_version():
s = coot.coot_version()
ls = s.split(" ")
return ls[0]
# return True or False (None on error, maybe should return some Error!?)
# although if no return, then var becomes None anyway.. FIXME).
def new_version_on_server(stri, is_pre_release):
from types import StringType
if is_pre_release:
# pre-releases are handle with svn revision numbers (as ints).
#
server_rev = coot_utils.get_revision_from_string(stri)
if server_rev:
return server_rev > coot.svn_revision()
else:
return None
else:
# For a stable release:
#
# The Coot release number (e.g. "0.6.4") is a string that can
# be compared lexographically.
#
server_version = get_stable_release_from_server_string(stri)
this_build_version = get_stable_release_from_coot_version()
if (server_version is StringType):
return server_version > this_build_version
return None
# show the dialog
#
def notify_of_new_version(stri, use_curl=False):
#print "notify_of_new_version given string:", stri
# Maybe protect from being called again (download is running)
download_binary_dialog(coot_utils.coot_split_version_string(stri), use_curl)
# version_string is something like: "coot-0.6-pre-1-revision-2060"
def download_binary_dialog(version_string, use_curl=False):
import os
import operator
global pending_install_in_place
global stop_download
global file_name_for_progress_bar
stop_download = False
file_name_for_progress_bar = False
if (pending_install_in_place == "cancelled"):
pending_install_in_place = False
#print "BL DEBUG:: in download binary with version", version_string
#print "BL DEBUG:: download_binary_dialog with", version_string, use_curl
def do_download_dialog(use_curl=False):
#
# print "running download-binary-dialog with version-string arg:", version_string
#
def update_progress_bar(progress_bar):
if file_name_for_progress_bar:
curl_info = curl_progress_info(file_name_for_progress_bar)
if curl_info:
v1 = curl_info['content-length-download']
v2 = curl_info['size-download']
if isinstance(v1, numbers.Number):
if isinstance(v2, numbers.Number):
f = v2 / v1
#print "count %s, active_count %s, f: %s" %(count, active_count, f)
progress_bar.set_fraction(f)
def set_progress_bar_full(progress_bar):
progress_bar.set_fraction(1)
def set_file_name_func(file_name):
global file_name_for_progress_bar
file_name_for_progress_bar = file_name
def pending_install_in_place_func(val):
global pending_install_in_place
pending_install_in_place = val
def delete_event(*args):
# only close window (BL says:: maybe should be hide and a global window
# in case we want to go back to it!?)
window.destroy()
return False
def cancel_event(*args):
# stop the download process(es) if
# they were running (they get set to
# False when they are not running)
#
global pending_install_in_place
if file_name_for_progress_bar:
coot.stop_curl_download(file_name_for_progress_bar)
pending_install_in_place = "cancelled" # not fail!
return False
def ok_button_event(*args):
global pending_install_in_place
import operator
# only start when ok button is pressed
gobject.timeout_add(500, idle_func) # update every 500ms is god enough?!
if not isinstance(revision, numbers.Number):
coot.info_dialog("Failed to communicate with server")
else:
# BL says:: check if we have a download available already?! (from before)
if (version_string in get_latest_pending_version()):
# installer already here (win only?!)
pending_install_in_place = True
else:
# download
ok_button.set_sensitive(False)
#align.show()
progress_bar.show()
cancel_button.show()
def threaded_func():
global pending_install_in_place
ret = run_download_binary_curl(revision, version_string,
pending_install_in_place_func,
set_file_name_func,
progress_bar,
use_curl)
if ((not ret) and
(not pending_install_in_place == "cancelled")):
print("run_download_binary_curl failed")
pending_install_in_place = "fail"
coot_gui.run_python_thread(threaded_func, [])
# and a timeout checking the progress of the download:
def idle_func():
global pending_install_in_place
if (pending_install_in_place == "fail"):
window.destroy()
coot.info_dialog("Failure to download and install binary")
return False # stop idle func
if (pending_install_in_place == "cancelled"):
window.destroy()
return False # stop idle func when download cancelled
if (pending_install_in_place == "full"): # dont go yet!? Why?
set_progress_bar_full(progress_bar)
if pending_install_in_place:
window.destroy()
restart_dialog()
return False # stop idle func
else:
update_progress_bar(progress_bar)
return True # continue running
s = " New revision available " + \
"for this binary type: \n" + \
coot_sys_build_type() + \
"\n" + \
"\n" + \
version_string
revision = coot_utils.get_revision_from_string(version_string)
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
dialog_name = "Download "
if coot_utils.is_windows():
dialog_name += "installer"
else:
dialog_name += "binary"
main_vbox = gtk.VBox(False, 6)
cancel_button = gtk.Button(" Cancel ")
close_button = gtk.Button(" Close ")
ok_button = gtk.Button(" Download and Pre-install ")
buttons_hbox = gtk.HBox(False, 6)
progress_bar = gtk.ProgressBar()
h_sep = gtk.HSeparator()
info_string = gtk.Label(s)
# needed?
#align = gtk.Alignment(0.5, 0.5, 0, 0)
#align.add(pbar)
window.set_title(dialog_name)
buttons_hbox.pack_start(ok_button, True, False, 6)
buttons_hbox.pack_start(cancel_button, True, False, 6)
buttons_hbox.pack_start(close_button, True, False, 6)
main_vbox.pack_start(info_string, True, False, 6)
main_vbox.pack_start(h_sep, True, False, 6)
main_vbox.pack_start(buttons_hbox, True, False, 6)
main_vbox.pack_start(progress_bar, True, False, 6)
#main_vbox.pack_start(align, True, False, 6)
main_vbox.set_border_width(6)
window.add(main_vbox)
window.set_border_width(6)
cancel_button.connect("clicked", cancel_event)
close_button.connect("clicked", delete_event)
ok_button.connect("clicked", ok_button_event)
window.show_all()
progress_bar.hide()
#align.hide()
cancel_button.hide()
idle_func() # call once for to get existing updates
# main line
coot_prefix = os.getenv("COOT_PREFIX")
coot_prefix = os.path.normpath(coot_prefix) # needed for WinCoot?! FIXME
if not coot_utils.directory_is_modifiable_qm(coot_prefix):
if not coot_prefix:
coot.info_dialog("COOT_PREFIX is not set. Download not started.")
else:
coot.info_dialog("Directory " + coot_prefix + \
" is not modifiable.\n" + \
"Download/install not started.")
else:
do_download_dialog(use_curl)
if (pending_install_in_place == "cancelled"):
pending_install_in_place = False # reset for next run
def restart_dialog(extra_text=""):
def delete_event(*args):
window.destroy()
return False
def ok_button_event(*args):
coot_command = "coot"
coot_args =[]
if coot_utils.is_windows():
# we need the name of the installer, should be in pending-install
coot_command = get_latest_pending_version() # shall be full path name
prefix_dir = os.getenv("COOT_PREFIX")
coot_args =["/instdir=" + prefix_dir,
"/startdir=" + os.getcwd(),
"/autoupdate"]
# create a coot background subprocess
coot_utils.run_concurrently(coot_command, coot_args)
window.destroy()
coot.coot_real_exit(0)
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
dialog_name = "Restart Required to complete installation"
main_vbox = gtk.VBox(False, 6)
cancel_button = gtk.Button(" Later ")
ok_button = gtk.Button(" Restart Now ")
label = gtk.Label(" Restart required to complete install " + extra_text)
buttons_hbox = gtk.HBox(False, 6)
h_sep = gtk.HSeparator()
window.set_title(dialog_name)
window.add(main_vbox)
window.set_border_width(6)
main_vbox.pack_start(label, False, False, 6)
main_vbox.pack_start(h_sep, False, False, 5)
main_vbox.pack_start(buttons_hbox, False, False, 6)
buttons_hbox.pack_start(ok_button, False, False, 6)
buttons_hbox.pack_start(cancel_button, False, False, 6)
cancel_button.connect("clicked", delete_event)
ok_button.connect("clicked", ok_button_event)
window.show_all()
# Paul's test binary?
# http://www.biop.ox.ac.uk/coot/software/binaries/pre-releases/coot-0.6-pre-1-revision-2535-binary-Linux-i386-centos-4-gtk2.tar.gz
def check_for_updates_gui(use_curl=False):
from types import StringType
import time
global server_info_status
server_info_status = False
def handle_latest_version_server_response(txt_from_server):
global server_info_status
# OK, so the server said something.
# Set the status here, so that the
# function that looks to see whether
# or not the server responded is
# notified.
#
if ("The requested URL" and "was not found on this server" in txt_from_server):
server_info_status = "file-not-found"
else:
server_info_status = txt_from_server
def get_server_info_status_thread():
url = coot_utils.make_latest_version_url()
print("INFO:: get URL", url)
if use_curl:
# non pythonic
#x=get_url_as_string(url) # FIXME to trick the firewall
latest_version_server_response = coot_get_url_as_string(url)
else:
# pythonic version
import urllib.request, urllib.parse, urllib.error
try:
latest_version_server_response = urllib.request.urlopen(url).read()
except:
coot.info_dialog("Could not establish connection to get latest version on server")
return
try:
handle_latest_version_server_response(latest_version_server_response)
except:
print("BL INFO:: problem getting server response from for url", url) # for now we give file-not-found, there should be some other form
# of error
handle_latest_version_server_response("The requested URL was not found on this server")
# main line
#
coot_gui.run_python_thread(get_server_info_status_thread, ())
is_pre_release = coot_utils.pre_release_qm() # BL: why?
global count
count = 0
def timeout_count():
global count
global server_info_status
if (count > 2000): # try for 20 seconds, otherwise timeout.
# fail_with_timeout
print("final fail: server_info_status:", server_info_status)
# maybe some info here too?!!?
return False # stop running this idle function
elif (server_info_status == "file-not-found"):
s = "No " + \
("pre-release" if is_pre_release else "release") + \
" binary for this system (" + \
coot_sys_build_type() + \
") on the binary server."
coot.info_dialog(s)
return False # stop running idle function
elif (server_info_status == ""):
# BL says:: supposedly - havent checked
# this happens when coot can't get past the proxy
#
coot.info_dialog("Can't communicate with server")
elif server_info_status:
if (new_version_on_server(server_info_status, is_pre_release)):
notify_of_new_version(server_info_status, use_curl)
else:
s = "No version newer than this revision (" + \
str(coot.svn_revision()) + \
")."
coot.info_dialog(s)
return False # stop running idle function
else:
time.sleep(0.010)
# print "server_info_status", server_info_status
count += 1
return True
#run_with_gtk_threading(timeout_count)
gobject.idle_add(timeout_count)
# returns latest installer version in pending-install or empty string ""
# if no installer for windows use only!
def get_latest_pending_version():
if coot_utils.is_windows():
import glob
prefix_dir = os.getenv("COOT_PREFIX")
pending_dir = os.path.join(prefix_dir, "pending-install")
if os.path.isdir(pending_dir):
installer_glob = os.path.join(pending_dir, "WinCoot*.exe")
installer_filenames = glob.glob(installer_glob)
installer_name = ""
if installer_filenames:
installer_name = installer_filenames[0]
if (len(installer_filenames) > 1):
# shall use the newest?!
tmp_time = 0
for filename in installer_filenames:
mtime = os.path.getmtime(filename)
if mtime > tmp_time:
tmp_time = mtime
installer_name = filename
# now delete the other ones
for filename in installer_filenames:
if (filename != installer_name):
os.remove(filename)
return installer_name
return ""
# hack to check if a pending install for WinCoot?!
# if so, show the restart dialog?!
# not sure yet how to do it otherwise (without chaning runwincoot.bat)
if coot_utils.is_windows():
pending_version_full = get_latest_pending_version()
if pending_version_full:
pending_version = os.path.basename(pending_version_full)
restart_dialog("\n\nFound %s to install\n" %pending_version + \
"Please \"Restart Now\"")
|