forked from EDCD/EDMarketConnector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
update.py
108 lines (78 loc) · 3.55 KB
/
update.py
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
import os
from os.path import dirname, join
import sys
from time import time
import threading
# ensure registry is set up on Windows before we start
from config import appname, appversion, update_feed, update_interval, config
if not getattr(sys, 'frozen', False):
# quick and dirty version comparison assuming "strict" numeric only version numbers
def versioncmp(versionstring):
return map(int, versionstring.split('.'))
class Updater():
def __init__(self, master):
self.root = master
def checkForUpdates(self):
thread = threading.Thread(target = self.worker, name = 'update worker')
thread.daemon = True
thread.start()
def worker(self):
import requests
from xml.etree import ElementTree
r = requests.get(update_feed, timeout = 20, verify = (sys.version_info >= (2,7,9)))
feed = ElementTree.fromstring(r.text)
items = dict([(item.find('enclosure').attrib.get('{http://www.andymatuschak.org/xml-namespaces/sparkle}version'),
item.find('title').text) for item in feed.findall('channel/item')])
lastversion = sorted(items, key=versioncmp)[-1]
if versioncmp(lastversion) > versioncmp(appversion):
self.root.nametowidget('.%s.%s' % (appname.lower(), 'status'))['text'] = items[lastversion] + ' is available'
self.root.update_idletasks()
def close(self):
pass
elif sys.platform=='darwin':
import objc
class Updater():
# http://sparkle-project.org/documentation/customization/
def __init__(self, master):
try:
objc.loadBundle('Sparkle', globals(), join(dirname(sys.executable.decode(sys.getfilesystemencoding())), os.pardir, 'Frameworks', 'Sparkle.framework'))
self.updater = SUUpdater.sharedUpdater()
except:
# can't load framework - not frozen or not included in app bundle?
self.updater = None
def checkForUpdates(self):
if self.updater:
self.updater.checkForUpdates_(None)
def close(self):
self.updater = None
elif sys.platform=='win32':
import ctypes
# https://github.com/vslavik/winsparkle/blob/master/include/winsparkle.h#L272
root = None
def shutdown_request():
root.event_generate('<<Quit>>', when="tail")
class Updater():
# https://github.com/vslavik/winsparkle/wiki/Basic-Setup
def __init__(self, master):
try:
sys.frozen # don't want to try updating python.exe
self.updater = ctypes.cdll.WinSparkle
self.updater.win_sparkle_set_appcast_url(update_feed) # py2exe won't let us embed this in resources
# set up shutdown callback
global root
root = master
self.callback_t = ctypes.CFUNCTYPE(None) # keep reference
self.callback_fn = self.callback_t(shutdown_request)
self.updater.win_sparkle_set_shutdown_request_callback(self.callback_fn)
self.updater.win_sparkle_init()
except:
from traceback import print_exc
print_exc()
self.updater = None
def checkForUpdates(self):
if self.updater:
self.updater.win_sparkle_check_update_with_ui()
def close(self):
if self.updater:
self.updater.win_sparkle_cleanup()
self.updater = None