github / src / updater.py @ 05b173a7
1 |
# Copyright (c) 2016, LE GOFF Vincent |
---|---|
2 |
# All rights reserved.
|
3 |
|
4 |
# Redistribution and use in source and binary forms, with or without
|
5 |
# modification, are permitted provided that the following conditions are met:
|
6 |
|
7 |
# * Redistributions of source code must retain the above copyright notice, this
|
8 |
# list of conditions and the following disclaimer.
|
9 |
|
10 |
# * Redistributions in binary form must reproduce the above copyright notice,
|
11 |
# this list of conditions and the following disclaimer in the documentation
|
12 |
# and/or other materials provided with the distribution.
|
13 |
|
14 |
# * Neither the name of ytranslate nor the names of its
|
15 |
# contributors may be used to endorse or promote products derived from
|
16 |
# this software without specific prior written permission.
|
17 |
|
18 |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19 |
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21 |
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24 |
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25 |
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26 |
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27 |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28 |
|
29 |
|
30 |
"""Auto-updater of the CocoMUD client."""
|
31 |
|
32 |
import os |
33 |
|
34 |
from configobj import ConfigObj |
35 |
from ytranslate import init, select, t |
36 |
import wx |
37 |
from wx.lib.pubsub import pub |
38 |
|
39 |
from autoupdate import AutoUpdate |
40 |
from version import BUILD |
41 |
|
42 |
# Determines the user's language
|
43 |
AVAILABLE_LANGUAGES = ("en", "fr") |
44 |
DEFAULT_LANGUAGE = "en"
|
45 |
path = os.path.join("settings", "options.conf") |
46 |
config = ConfigObj(path) |
47 |
try:
|
48 |
lang = config["general"]["language"] |
49 |
assert lang in AVAILABLE_LANGUAGES |
50 |
except (KeyError, AssertionError): |
51 |
lang = DEFAULT_LANGUAGE |
52 |
|
53 |
# Translation
|
54 |
init(root_dir="translations")
|
55 |
select(lang) |
56 |
|
57 |
# Classes
|
58 |
|
59 |
class DummyUpdater(wx.Frame): |
60 |
|
61 |
"""Dummy updater, to which updaters should inherit."""
|
62 |
|
63 |
def __init__(self, parent): |
64 |
wx.Frame.__init__(self, parent)
|
65 |
self.autoupdater = None |
66 |
self.default_text = t("ui.message.update.loading") |
67 |
self.progress = 0 |
68 |
|
69 |
# Event binding
|
70 |
pub.subscribe(self.OnGauge, "gauge") |
71 |
pub.subscribe(self.OnText, "text") |
72 |
pub.subscribe(self.OnForceDestroy, "forceDestroy") |
73 |
pub.subscribe(self.OnResponseUpdate, "responseUpdate") |
74 |
|
75 |
def create_updater(self, just_checking=False): |
76 |
"""Create a new autoupdater instance."""
|
77 |
self.autoupdate = AutoUpdate(BUILD, self, just_checking=just_checking) |
78 |
self.autoupdate.start()
|
79 |
|
80 |
def OnGauge(self, value=0): |
81 |
"""The progress indicator changes."""
|
82 |
pass
|
83 |
|
84 |
def OnText(self, text=""): |
85 |
"""The text of the indicator changes."""
|
86 |
pass
|
87 |
|
88 |
def OnForceDestroy(self): |
89 |
"""Ask for the window's destruction."""
|
90 |
pass
|
91 |
|
92 |
def OnResponseUpdate(self, build=None): |
93 |
"""The check for updates is complete."""
|
94 |
pass
|
95 |
|
96 |
def UpdateGauge(self, value): |
97 |
"""Change the level indicator."""
|
98 |
wx.CallAfter(pub.sendMessage, "gauge", value=value)
|
99 |
|
100 |
def UpdateText(self, text): |
101 |
"""Change the text."""
|
102 |
wx.CallAfter(pub.sendMessage, "text", text=text)
|
103 |
|
104 |
def AskDestroy(self): |
105 |
wx.CallAfter(pub.sendMessage, "forceDestroy")
|
106 |
|
107 |
def ResponseUpdate(self, build): |
108 |
"""The check for updates has responded.
|
109 |
|
110 |
Note: the build parameter may be None (no update is available)
|
111 |
or a number (updates are available).
|
112 |
|
113 |
"""
|
114 |
wx.CallAfter(pub.sendMessage, "responseUpdate", build=build)
|
115 |
|
116 |
|
117 |
class Updater(DummyUpdater): |
118 |
|
119 |
"""Graphical updater with a gauge."""
|
120 |
|
121 |
def __init__(self, parent, just_checking=False): |
122 |
DummyUpdater.__init__(self, parent)
|
123 |
self.create_updater(just_checking)
|
124 |
self.InitUI()
|
125 |
self.SetTitle(t("ui.message.update.updating")) |
126 |
self.Show()
|
127 |
self.Center()
|
128 |
|
129 |
def InitUI(self): |
130 |
panel = wx.Panel(self)
|
131 |
sizer = wx.BoxSizer(wx.VERTICAL) |
132 |
panel.SetSizer(sizer) |
133 |
self.text = wx.TextCtrl(panel, value=self.default_text, |
134 |
size=(600, 100), style=wx.TE_MULTILINE | wx.TE_READONLY) |
135 |
self.gauge = wx.Gauge(panel, range=100, size=(250, 25)) |
136 |
self.cancel = wx.Button(panel, wx.ID_CANCEL)
|
137 |
|
138 |
# Window design
|
139 |
sizer.Add(self.text)
|
140 |
sizer.Add(self.gauge)
|
141 |
sizer.Add(self.cancel)
|
142 |
|
143 |
# Event binding
|
144 |
self.Bind(wx.EVT_BUTTON, self.OnCancel, self.cancel) |
145 |
|
146 |
def OnGauge(self, value=0): |
147 |
self.gauge.SetValue(value)
|
148 |
text = self.default_text
|
149 |
text += " ({}%)".format(value)
|
150 |
self.text.SetValue(text)
|
151 |
|
152 |
def OnText(self, text): |
153 |
self.default_text = t(text)
|
154 |
self.text.SetValue(self.default_text) |
155 |
|
156 |
def OnForceDestroy(self): |
157 |
self.Destroy()
|
158 |
|
159 |
def OnCancel(self, e): |
160 |
"""The user clicks on 'cancel'."""
|
161 |
value = wx.MessageBox(t("ui.message.update.confirm_cancel"),
|
162 |
t("ui.dialog.confirm"), wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
|
163 |
|
164 |
if value == wx.YES:
|
165 |
self.Destroy()
|
166 |
|
167 |
|
168 |
# AppMainLoop
|
169 |
if __name__ == "__main__": |
170 |
app = wx.App() |
171 |
frame = Updater(None)
|
172 |
app.MainLoop() |