Merge lp:~mterry/update-manager/update-at-start into lp:update-manager

Proposed by Michael Terry on 2012-06-01
Status: Merged
Approved by: Barry Warsaw on 2012-06-25
Approved revision: 2441
Merged at revision: 2504
Proposed branch: lp:~mterry/update-manager/update-at-start
Merge into: lp:update-manager
Diff against target: 896 lines (+148/-397) 8 files modified
To merge this branch: bzr merge lp:~mterry/update-manager/update-at-start
Reviewer Review Type Date Requested Status
Barry Warsaw Approve on 2012-06-25
Michael Vogt 2012-06-01 Pending
Review via email: mp+108369@code.launchpad.net

Description of the Change

Implements the 'update on start' aspect of the new spec.

This means that all ways to manually start an update are gone from the UI. We no longer warn about how long it's been since the last update, etc.

I've added a new class to handle the initial progress dialog. It just seemed cleaner to me to do it that way rather than introduce more possible states to the main dialog's class. Especially since so little of that class is relevant to the progress dialog.

The progress dialog doesn't look quite like it does in the spec yet. That will require changes to aptdaemon's progress dialog widget. But those can be done separately.

To post a comment you must log in.
Michael Terry (mterry) wrote :

Note that I also filed https://code.launchpad.net/~mterry/update-notifier/use-no-update/+merge/108377 to have update-notifier pass --no-update when launching update-manager.

2439. By Michael Terry on 2012-06-13

merge from trunk

Barry Warsaw (barry) wrote :

When I run ./update-manager from your branch I get the following errors on the console:

% ./update-manager
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 354, in _full_callback
    raise AttributeError('Handler %s not found' % handler_name)
AttributeError: Handler on_button_reload_clicked not found
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 354, in _full_callback
    raise AttributeError('Handler %s not found' % handler_name)
AttributeError: Handler on_checkbutton_reminder_toggled not found

Probably some additional left over cruft that isn't removed in your branch?

Also, you mention a spec, but I'm not aware of it. Do you have a link?

Minor misspelling at the top of UpdateProgress.py

You might want to run pyflakes over UpdateProgress.py. Unused imports include Gtk, _, ngettext
Also, you can probably collapse the .Core.utils import onto one line
Spaces around the = sign when setting os.environ[]
4 space indents please! :)

Could you add some tests for the new functionality and files?

review: Needs Fixing
Michael Terry (mterry) wrote :

The spec is https://wiki.ubuntu.com/SoftwareUpdates

The AttributeError is likely because you need to point at the new glade files too (update-manager isn't smart enough to look in the local location). So either futz with XDG_DATA_DIRS or just do "sudo cp data/gtkbuilder/* /usr/share/update-manager/gtkbuilder/"

I'll update UpdateProgress.py and fix the nits. You're killing me with the 4-indents. Not that I care, but update-manager source is very inconsistent with 2 or 4, even inside a file, so I've tried to always stick with 2 in all my pending branches. :(

2440. By Michael Terry on 2012-06-19

review style nits and pyflakes fixes

Michael Terry (mterry) wrote :

OK, I've updated to fix nits. I'm not going to do the 4-indent change, because that would cause massive headache with all my chain of pending merges. I'd rather just do a big flag-day indent fixup branch at the end, which will fix existing inconsistencies too.

As for tests, I'd like to talk to mvo first about what his plans were for tests going forward. (tests right now are very hodge-pogde; some rely on internal test-only flags for detecting if a dialog was shown, some just use direct imports of modules and poke around, I don't think any use a UI-driving framework) It's fine if that's a blocker, but it's not something I can fix right this second.

Michael Vogt (mvo) wrote :

On Tue, Jun 19, 2012 at 09:56:18PM -0000, Michael Terry wrote:
> The spec is https://wiki.ubuntu.com/SoftwareUpdates
>
> The AttributeError is likely because you need to point at the new glade files too (update-manager isn't smart enough to look in the local location). So either futz with XDG_DATA_DIRS or just do "sudo cp data/gtkbuilder/* /usr/share/update-manager/gtkbuilder/"

Alternatively:
$ ./update-manager --data-dir ./data
should work too.

> I'll update UpdateProgress.py and fix the nits. You're killing me with the 4-indents. Not that I care, but update-manager source is very inconsistent with 2 or 4, even inside a file, so I've tried to always stick with 2 in all my pending branches. :(

Yeah, its a big pain, given the restructure that is going on, it
sounds like a good time to make it consistently 4 spaces, wdyt?

Cheers,
 Michael

Michael Vogt (mvo) wrote :

On Tue, Jun 19, 2012 at 10:07:18PM -0000, Michael Terry wrote:
> OK, I've updated to fix nits. I'm not going to do the 4-indent change, because that would cause massive headache with all my chain of pending merges. I'd rather just do a big flag-day indent fixup branch at the end, which will fix existing inconsistencies too.

That sounds like a reasonable approach.

> As for tests, I'd like to talk to mvo first about what his plans were for tests going forward. (tests right now are very hodge-pogde; some rely on internal test-only flags for detecting if a dialog was shown, some just use direct imports of modules and poke around, I don't think any use a UI-driving framework) It's fine if that's a blocker, but it's not something I can fix right this second.

Indeed, there is no UI-driving framework, my experience with all of
them wasn't that great, so its importing and poking around at the
modules/classes. I'm happy about u-m moving towards a UI-driving
framework, suggestions for a good one welcome.

Cheers,
 Michael

Michael Terry (mterry) wrote :

<mterry> mvo, darn, I was hoping you had been hiding some amazing UI driving framework that you had been too lazy to use. :-/
<mterry> mvo, the best I've used is ldtp, but it's very rickety
<mvo> mterry: yeah, excatly, I wasn't overly impressed with that one :/
<mterry> mvo, well, I'm happy to write various tests, but since doing so might involve various code changes (for instrumentation) and since code is moving around a lot in my branches, would you mind if I did a big test branch after all these intermediate branches land? (ala the indentation one)
<mvo> mterry: that is fine with me (for the given reasons)

So I'll start working on an indentation branch and a testing branch after my branches land on trunk. I believe that means there's no outstanding issue with this particular branch. Could I get a re-review?

Ken VanDine (ken-vandine) wrote :

I got a very minor merge conflict for UpdateManager/UpdateManager.py

<<<<<<< TREE
          if self._get_last_apt_get_update_text() is not None:
              text_label_main = self._get_last_apt_get_update_text()
              ago_minutes = self._get_last_apt_get_update_minutes()
              if ago_minutes is not None and ago_minutes > self.NO_UPDATE_WARNING_DAYS*24*60:
                  text_header = _("Software updates may be available for your computer.")
          # add timer to ensure we update the information when the
          # last package count update was performed
          GObject.timeout_add_seconds(10, self.update_last_updated_text, None)
=======
>>>>>>> MERGE-SOURCE

I manually fixed the merge and tested. After applying updates I noticed the "Details of updates" expander doesn't get hidden. Perhaps that is expected at this point and fixed in another branch.

Still reviewing... more to come later.

Barry Warsaw (barry) wrote :

On Jun 22, 2012, at 06:36 PM, Ken VanDine wrote:

>I got a very minor merge conflict for UpdateManager/UpdateManager.py
>
><<<<<<< TREE
> if self._get_last_apt_get_update_text() is not None:
> text_label_main = self._get_last_apt_get_update_text()
> ago_minutes = self._get_last_apt_get_update_minutes()
> if ago_minutes is not None and ago_minutes > self.NO_UPDATE_WARNING_DAYS*24*60:
> text_header = _("Software updates may be available for your computer.")
> # add timer to ensure we update the information when the
> # last package count update was performed
> GObject.timeout_add_seconds(10, self.update_last_updated_text, None)
>=======
>>>>>>>> MERGE-SOURCE

I get the same conflict against trunk. I suppose that chunk of code is
supposed to be removed?

Barry Warsaw (barry) wrote :

On Jun 19, 2012, at 10:07 PM, Michael Terry wrote:

>OK, I've updated to fix nits. I'm not going to do the 4-indent change,
>because that would cause massive headache with all my chain of pending
>merges. I'd rather just do a big flag-day indent fixup branch at the end,
>which will fix existing inconsistencies too.

I think it's fine to defer the reindentation, and I agree the code base is
fairly inconsistent about indentation right now. It would be nice at some
point to do a thorough PEP-8-ification of the code.

>As for tests, I'd like to talk to mvo first about what his plans were for
>tests going forward. (tests right now are very hodge-pogde; some rely on
>internal test-only flags for detecting if a dialog was shown, some just use
>direct imports of modules and poke around, I don't think any use a UI-driving
>framework) It's fine if that's a blocker, but it's not something I can fix
>right this second.

I guess not. This is another thing I'd really like to do at some point,
i.e. refactor the code to be more testable and have better coverage.

Right now your branch is conflicting with trunk. Can you resolve that and
push an update?

Ken VanDine (ken-vandine) wrote :

On Fri, 2012-06-22 at 18:22 -0400, Barry Warsaw wrote:
> On Jun 22, 2012, at 06:36 PM, Ken VanDine wrote:
>
> >I got a very minor merge conflict for UpdateManager/UpdateManager.py
> >
> ><<<<<<< TREE
> > if self._get_last_apt_get_update_text() is not None:
> > text_label_main = self._get_last_apt_get_update_text()
> > ago_minutes = self._get_last_apt_get_update_minutes()
> > if ago_minutes is not None and ago_minutes > self.NO_UPDATE_WARNING_DAYS*24*60:
> > text_header = _("Software updates may be available for your computer.")
> > # add timer to ensure we update the information when the
> > # last package count update was performed
> > GObject.timeout_add_seconds(10, self.update_last_updated_text, None)
> >=======
> >>>>>>>> MERGE-SOURCE
>
> I get the same conflict against trunk. I suppose that chunk of code is
> supposed to be removed?
>

Looks like it to me.

--
Ken VanDine
Ubuntu Desktop Integration Engineer
Canonical, Ltd.

2441. By Michael Terry on 2012-06-25

merge from trunk

Michael Terry (mterry) wrote :

Yup, the conflicting code just needed to be removed. How about now?

Barry Warsaw (barry) wrote :

Looks good now, thanks.

review: Approve
Barry Warsaw (barry) wrote :

On Jun 25, 2012, at 03:06 PM, Michael Terry wrote:

>Yup, the conflicting code just needed to be removed. How about now?

Looks good, thanks. I've merged this into trunk, but didn't upload it, in
case there are other upcoming changes for u-m. Happy to upload it if you
prefer though.

Preview Diff

1=== modified file 'UpdateManager/UnitySupport.py'
2--- UpdateManager/UnitySupport.py 2011-08-11 11:47:34 +0000
3+++ UpdateManager/UnitySupport.py 2012-06-25 15:02:27 +0000
4@@ -51,15 +51,6 @@
5
6 def _add_quicklist(self, parent):
7 quicklist = Dbusmenu.Menuitem.new()
8- # update
9- update_dbusmenuitem = Dbusmenu.Menuitem.new()
10- update_dbusmenuitem.property_set(
11- Dbusmenu.MENUITEM_PROP_LABEL, _("Check for Updates"))
12- update_dbusmenuitem.property_set_bool(
13- Dbusmenu.MENUITEM_PROP_VISIBLE, True)
14- update_dbusmenuitem.connect (
15- "item-activated", parent.on_button_reload_clicked, None)
16- quicklist.child_append(update_dbusmenuitem)
17 # install
18 self.install_dbusmenuitem = Dbusmenu.Menuitem.new()
19 self.install_dbusmenuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL,
20
21=== modified file 'UpdateManager/UpdateManager.py'
22--- UpdateManager/UpdateManager.py 2012-06-14 21:14:13 +0000
23+++ UpdateManager/UpdateManager.py 2012-06-25 15:02:27 +0000
24@@ -1,6 +1,6 @@
25 # UpdateManager.py
26 #
27-# Copyright (c) 2004-2010 Canonical
28+# Copyright (c) 2004-2012 Canonical
29 # 2004 Michiel Sikkes
30 # 2005 Martin Willemoes Hansen
31 # 2010 Mohamed Amine IL Idrissi
32@@ -10,6 +10,7 @@
33 # Martin Willemoes Hansen <mwh@sysrq.dk>
34 # Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com>
35 # Alex Launi <alex.launi@canonical.com>
36+# Michael Terry <michael.terry@canonical.com>
37 #
38 # This program is free software; you can redistribute it and/or
39 # modify it under the terms of the GNU General Public License as
40@@ -40,12 +41,10 @@
41
42 import apt_pkg
43
44-import gettext
45 import sys
46 import os
47 import stat
48 import re
49-import locale
50 import logging
51 import operator
52 import subprocess
53@@ -66,7 +65,6 @@
54
55
56 from .Core.utils import (humanize_size,
57- init_proxy,
58 on_battery,
59 inhibit_sleep,
60 allow_sleep)
61@@ -91,9 +89,6 @@
62 # list constants
63 (LIST_CONTENTS, LIST_NAME, LIST_PKG, LIST_ORIGIN, LIST_TOGGLE_CHECKED) = range(5)
64
65-# actions for "invoke_manager"
66-(INSTALL, UPDATE) = range(2)
67-
68 # file that signals if we need to reboot
69 REBOOT_REQUIRED_FILE = "/var/run/reboot-required"
70
71@@ -140,27 +135,14 @@
72 return True
73
74 @dbus.service.method('org.freedesktop.UpdateManagerIFace')
75- def update(self):
76- try:
77- self.alert_watcher.check_alert_state ()
78- self.parent.invoke_manager(UPDATE)
79- return self.connected
80- except:
81- return False
82-
83- @dbus.service.method('org.freedesktop.UpdateManagerIFace')
84 def upgrade(self):
85 try:
86 self.parent.cache.checkFreeSpace()
87- self.parent.invoke_manager(INSTALL)
88+ self.parent.invoke_manager()
89 return True
90 except:
91 return False
92
93- @dbus.service.signal('org.freedesktop.UpdateManagerIFace', 'b')
94- def updated(self, success):
95- pass
96-
97 def _on_network_alert(self, watcher, state):
98 if state in NetworkManagerHelper.NM_STATE_CONNECTED_LIST:
99 self.connected = True
100@@ -169,21 +151,12 @@
101
102 class UpdateManager(SimpleGtkbuilderApp):
103
104- # how many days until u-m warns about manual pressing "check"
105- NO_UPDATE_WARNING_DAYS = 7
106-
107 def __init__(self, datadir, options):
108 self.setupDbus()
109- Gtk.Window.set_default_icon_name("system-software-update")
110 self.datadir = datadir
111+ self.options = options
112 SimpleGtkbuilderApp.__init__(self, datadir+"gtkbuilder/UpdateManager.ui",
113 "update-manager")
114- gettext.bindtextdomain("update-manager", "/usr/share/locale")
115- gettext.textdomain("update-manager")
116- try:
117- locale.setlocale(locale.LC_ALL, "")
118- except:
119- logging.exception("setlocale failed")
120
121 # Used for inhibiting power management
122 self.sleep_cookie = None
123@@ -192,7 +165,6 @@
124 # workaround for LP: #945536
125 self.clearing_store = False
126
127- self.image_logo.set_from_icon_name("system-software-update", Gtk.IconSize.DIALOG)
128 self.window_main.set_sensitive(False)
129 self.window_main.grab_focus()
130 self.button_close.grab_focus()
131@@ -257,13 +229,10 @@
132 self.button_settings.set_sensitive(False)
133
134 self.settings = Gio.Settings("com.ubuntu.update-manager")
135- init_proxy(self.settings)
136 # init show version
137 self.show_versions = self.settings.get_boolean("show-versions")
138 # init summary_before_name
139 self.summary_before_name = self.settings.get_boolean("summary-before-name")
140- # keep track when we run (for update-notifier)
141- self.settings.set_int("launch-time", int(time.time()))
142
143 # get progress object
144 self.progress = GtkOpProgressInline(
145@@ -366,10 +335,6 @@
146 self.dbusController = UpdateManagerDbusController(self, bus_name)
147
148
149- def on_checkbutton_reminder_toggled(self, checkbutton):
150- self.settings.set_boolean("remind-reload",
151- not checkbutton.get_active())
152-
153 def close(self, widget, data=None):
154 if self.window_main.get_property("sensitive") is False:
155 return True
156@@ -600,74 +565,11 @@
157 self.hbox_downsize.show()
158 self.vbox_alerts.show()
159
160- def _get_last_apt_get_update_minutes(self):
161- """
162- Return the number of minutes since the last successful apt-get update
163-
164- If the date is unknown, return "None"
165- """
166- if not os.path.exists("/var/lib/apt/periodic/update-success-stamp"):
167- return None
168- # calculate when the last apt-get update (or similar operation)
169- # was performed
170- mtime = os.stat("/var/lib/apt/periodic/update-success-stamp")[stat.ST_MTIME]
171- ago_minutes = int((time.time() - mtime) / 60 )
172- return ago_minutes
173-
174- def _get_last_apt_get_update_text(self):
175- """
176- return a human readable string with the information when
177- the last apt-get update was run
178- """
179- ago_minutes = self._get_last_apt_get_update_minutes()
180- if ago_minutes is None:
181- return _("It is unknown when the package information was "
182- "updated last. Please click the 'Check' "
183- "button to update the information.")
184- ago_hours = int( ago_minutes / 60 )
185- ago_days = int( ago_hours / 24 )
186- if ago_days > self.NO_UPDATE_WARNING_DAYS:
187- return _("The package information was last updated %(days_ago)s "
188- "days ago.\n"
189- "Press the 'Check' button below to check for new software "
190- "updates.") % { "days_ago" : ago_days, }
191- elif ago_days > 0:
192- return ngettext("The package information was last updated %(days_ago)s day ago.",
193- "The package information was last updated %(days_ago)s days ago.",
194- ago_days) % { "days_ago" : ago_days, }
195- elif ago_hours > 0:
196- return ngettext("The package information was last updated %(hours_ago)s hour ago.",
197- "The package information was last updated %(hours_ago)s hours ago.",
198- ago_hours) % { "hours_ago" : ago_hours, }
199- elif ago_minutes >= 45:
200- # TRANSLATORS: only in plural form, as %s minutes ago is one of 15, 30, 45 minutes ago
201- return _("The package information was last updated about %s minutes ago.")%45
202- elif ago_minutes >= 30:
203- return _("The package information was last updated about %s minutes ago.")%30
204- elif ago_minutes >= 15:
205- return _("The package information was last updated about %s minutes ago.")%15
206- else:
207- return _("The package information was just updated.")
208- return None
209-
210- def update_last_updated_text(self, user_data):
211- """timer that updates the last updated text """
212- #print("update_last_updated_text")
213- num_updates = self.cache.install_count
214- if num_updates == 0:
215- if self._get_last_apt_get_update_text() is not None:
216- text_label_main = self._get_last_apt_get_update_text()
217- self.label_main_details.set_text(text_label_main)
218- return True
219- # stop the timer if there are upgrades now
220- return False
221-
222 def update_count(self):
223 """activate or disable widgets and show dialog texts correspoding to
224 the number of available updates"""
225 self.refresh_updates_count()
226 num_updates = self.cache.install_count
227- text_label_main = ""
228
229 # setup unity stuff
230 self.unity.set_updates_count(num_updates)
231@@ -683,14 +585,6 @@
232 self.button_close.grab_default()
233 self.textview_changes.get_buffer().set_text("")
234 self.textview_descr.get_buffer().set_text("")
235- if self._get_last_apt_get_update_text() is not None:
236- text_label_main = self._get_last_apt_get_update_text()
237- ago_minutes = self._get_last_apt_get_update_minutes()
238- if ago_minutes is not None and ago_minutes > self.NO_UPDATE_WARNING_DAYS*24*60:
239- text_header = _("Software updates may be available for your computer.")
240- # add timer to ensure we update the information when the
241- # last package count update was performed
242- GObject.timeout_add_seconds(10, self.update_last_updated_text, None)
243 else:
244 # show different text on first run (UX team suggestion)
245 firstrun = self.settings.get_boolean("first-run")
246@@ -704,7 +598,6 @@
247 self.button_install.grab_default()
248 self.treeview_update.set_cursor(Gtk.TreePath.new_from_string("1"), None, False)
249 self.label_header.set_markup(text_header)
250- self.label_main_details.set_text(text_label_main)
251 return True
252
253 # Before we shrink the window, capture the size
254@@ -725,11 +618,6 @@
255 expanded = self.expander_desc.get_expanded()
256 self.expander_desc.set_vexpand(expanded)
257
258- def on_button_reload_clicked(self, widget, menuitem = None, data = None):
259- #print("on_button_reload_clicked")
260- self.check_metarelease()
261- self.invoke_manager(UPDATE)
262-
263 #def on_button_help_clicked(self, widget):
264 # self.help_viewer.run()
265
266@@ -774,7 +662,7 @@
267 return
268 except SystemError as e:
269 logging.exception("free space check failed")
270- self.invoke_manager(INSTALL)
271+ self.invoke_manager()
272
273 def on_button_restart_required_clicked(self, button=None):
274 self._request_reboot_via_session_manager()
275@@ -807,7 +695,7 @@
276 except dbus.DBusException:
277 pass
278
279- def invoke_manager(self, action):
280+ def invoke_manager(self):
281 # check first if no other package manager is runing
282
283 # don't display apt-listchanges, we already showed the changelog
284@@ -819,30 +707,23 @@
285 # set window to insensitive
286 self.window_main.set_sensitive(False)
287 self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
288-#
289- # do it
290- if action == UPDATE:
291- self.install_backend.update()
292- elif action == INSTALL:
293- # If the progress dialog should be closed automatically afterwards
294- settings = Gio.Settings("com.ubuntu.update-manager")
295- close_on_done = settings.get_boolean("autoclose-install-window")
296- # Get the packages which should be installed and update
297- pkgs_install = []
298- pkgs_upgrade = []
299- for pkg in self.cache:
300- if pkg.marked_install:
301- pkgs_install.append(pkg.name)
302- elif pkg.marked_upgrade:
303- pkgs_upgrade.append(pkg.name)
304- self.install_backend.commit(pkgs_install, pkgs_upgrade, close_on_done)
305+
306+ # If the progress dialog should be closed automatically afterwards
307+ settings = Gio.Settings("com.ubuntu.update-manager")
308+ close_on_done = settings.get_boolean("autoclose-install-window")
309+ # Get the packages which should be installed and update
310+ pkgs_install = []
311+ pkgs_upgrade = []
312+ for pkg in self.cache:
313+ if pkg.marked_install:
314+ pkgs_install.append(pkg.name)
315+ elif pkg.marked_upgrade:
316+ pkgs_upgrade.append(pkg.name)
317+ self.install_backend.commit(pkgs_install, pkgs_upgrade, close_on_done)
318
319 def _on_backend_done(self, backend, action, authorized, success):
320- if (action == UPDATE):
321- self.dbusController.updated(success)
322 # check if there is a new reboot required notification
323- if (action == INSTALL and
324- os.path.exists(REBOOT_REQUIRED_FILE)):
325+ if os.path.exists(REBOOT_REQUIRED_FILE):
326 self.show_reboot_required_info()
327 if authorized:
328 msg = _("Reading package information")
329@@ -861,7 +742,6 @@
330 # can deal with dialup connections properly
331 if state in NetworkManagerHelper.NM_STATE_CONNECTING_LIST:
332 self.label_offline.set_text(_("Connecting..."))
333- #self.button_reload.set_sensitive(False)
334 self.refresh_updates_count()
335 self.hbox_offline.show()
336 self.vbox_alerts.show()
337@@ -869,7 +749,6 @@
338 # in doubt (STATE_UNKNOWN), assume connected
339 elif (state in NetworkManagerHelper.NM_STATE_CONNECTED_LIST or
340 state == NetworkManagerHelper.NM_STATE_UNKNOWN):
341- #self.button_reload.set_sensitive(True)
342 self.refresh_updates_count()
343 self.hbox_offline.hide()
344 self.connected = True
345@@ -878,7 +757,6 @@
346 else:
347 self.connected = False
348 self.label_offline.set_text(_("You may not be able to check for updates or download new updates."))
349- #self.button_reload.set_sensitive(False)
350 self.refresh_updates_count()
351 self.hbox_offline.show()
352 self.vbox_alerts.show()
353@@ -1022,11 +900,7 @@
354
355 # fill them again
356 try:
357- # This is a quite nasty hack to stop the initial update
358- if not self.options.no_update:
359- self.list.update(self.cache)
360- else:
361- self.options.no_update = False
362+ self.list.update(self.cache)
363 except SystemError as e:
364 msg = ("<big><b>%s</b></big>\n\n%s\n'%s'" %
365 (_("Could not calculate the upgrade"),
366@@ -1167,22 +1041,6 @@
367 else:
368 self.progress.all_done()
369
370- def check_auto_update(self):
371- # Check if automatic update is enabled. If not show a dialog to inform
372- # the user about the need of manual "reloads"
373- remind = self.settings.get_boolean("remind-reload")
374- if remind == False:
375- return
376-
377- update_days = apt_pkg.config.find_i("APT::Periodic::Update-Package-Lists")
378- if update_days < 1:
379- self.dialog_manual_update.set_transient_for(self.window_main)
380- self.dialog_manual_update.set_title("")
381- res = self.dialog_manual_update.run()
382- self.dialog_manual_update.hide()
383- if res == Gtk.ResponseType.YES:
384- self.on_button_reload_clicked(None)
385-
386 def check_all_updates_installable(self):
387 """ Check if all available updates can be installed and suggest
388 to run a distribution upgrade if not """
389@@ -1214,9 +1072,7 @@
390 self.meta.connect("new_dist_available",self.new_dist_available)
391
392
393- def main(self, options):
394- self.options = options
395-
396+ def main(self):
397 # check for new distributin information
398 self.check_metarelease()
399
400@@ -1224,6 +1080,4 @@
401 Gtk.main_iteration()
402
403 self.fillstore()
404- self.check_auto_update()
405 self.alert_watcher.check_alert_state()
406- Gtk.main()
407
408=== added file 'UpdateManager/UpdateProgress.py'
409--- UpdateManager/UpdateProgress.py 1970-01-01 00:00:00 +0000
410+++ UpdateManager/UpdateProgress.py 2012-06-25 15:02:27 +0000
411@@ -0,0 +1,84 @@
412+# UpdateProgress.py
413+#
414+# Copyright (c) 2004-2012 Canonical
415+# 2004 Michiel Sikkes
416+# 2005 Martin Willemoes Hansen
417+# 2010 Mohamed Amine IL Idrissi
418+#
419+# Author: Michiel Sikkes <michiel@eyesopened.nl>
420+# Michael Vogt <mvo@debian.org>
421+# Martin Willemoes Hansen <mwh@sysrq.dk>
422+# Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com>
423+# Alex Launi <alex.launi@canonical.com>
424+# Michael Terry <michael.terry@canonical.com>
425+#
426+# This program is free software; you can redistribute it and/or
427+# modify it under the terms of the GNU General Public License as
428+# published by the Free Software Foundation; either version 2 of the
429+# License, or (at your option) any later version.
430+#
431+# This program is distributed in the hope that it will be useful,
432+# but WITHOUT ANY WARRANTY; without even the implied warranty of
433+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
434+# GNU General Public License for more details.
435+#
436+# You should have received a copy of the GNU General Public License
437+# along with this program; if not, write to the Free Software
438+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
439+# USA
440+
441+from __future__ import absolute_import, print_function
442+
443+from gi.repository import GLib
444+
445+import warnings
446+warnings.filterwarnings("ignore", "Accessed deprecated property", DeprecationWarning)
447+
448+import os
449+import sys
450+
451+from .backend import get_backend
452+
453+from UpdateManager.UpdateManager import UpdateManager
454+from .Core.utils import inhibit_sleep, allow_sleep
455+
456+class UpdateProgress(object):
457+
458+ def __init__(self, datadir, options):
459+ self.datadir = datadir
460+ self.options = options
461+
462+ # Used for inhibiting power management
463+ self.sleep_cookie = None
464+ self.sleep_dev = None
465+
466+ # get the install backend
467+ self.install_backend = get_backend(None)
468+ self.install_backend.connect("action-done", self._on_backend_done)
469+
470+ def invoke_manager(self):
471+ # don't display apt-listchanges
472+ os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
473+
474+ # Do not suspend during the update process
475+ (self.sleep_dev, self.sleep_cookie) = inhibit_sleep()
476+
477+ self.install_backend.update()
478+
479+ def _on_backend_done(self, backend, action, authorized, success):
480+ # Allow suspend after synaptic is finished
481+ if self.sleep_cookie:
482+ allow_sleep(self.sleep_dev, self.sleep_cookie)
483+ self.sleep_cookie = self.sleep_dev = None
484+
485+ # Either launch main dialog and continue or quit altogether
486+ if success:
487+ app = UpdateManager(self.datadir, self.options)
488+ # Run app.main at idle time so the progress dialog can close before we
489+ # do lengthy recalculation in app.main
490+ GLib.idle_add(app.main)
491+ else:
492+ sys.exit(0)
493+
494+ def main(self):
495+ self.invoke_manager()
496
497=== modified file 'UpdateManager/backend/InstallBackendAptdaemon.py'
498--- UpdateManager/backend/InstallBackendAptdaemon.py 2012-05-01 00:29:04 +0000
499+++ UpdateManager/backend/InstallBackendAptdaemon.py 2012-06-25 15:02:27 +0000
500@@ -12,6 +12,8 @@
501 from UpdateManager.backend import InstallBackend
502 from UpdateManager.UnitySupport import UnitySupport
503
504+from gettext import gettext as _
505+
506 import apt
507 import dbus
508
509@@ -33,7 +35,7 @@
510 pass
511 try:
512 trans = yield self.client.update_cache(defer=True)
513- yield self._run_in_dialog(trans, self.UPDATE)
514+ yield self._run_in_dialog(trans, self.UPDATE, False)
515 except errors.NotAuthorizedError:
516 self.emit("action-done", self.UPDATE, False, False)
517 except:
518@@ -53,7 +55,7 @@
519 pkgs_install, reinstall, remove, purge, pkgs_upgrade,
520 downgrade, defer=True)
521 trans.connect("progress-changed", self._on_progress_changed)
522- yield self._run_in_dialog(trans, self.INSTALL)
523+ yield self._run_in_dialog(trans, self.INSTALL, True)
524 except errors.NotAuthorizedError as e:
525 self.emit("action-done", self.INSTALL, False, False)
526 except dbus.DBusException as e:
527@@ -70,18 +72,22 @@
528 self.unity.set_progress(progress)
529
530 @inline_callbacks
531- def _run_in_dialog(self, trans, action):
532+ def _run_in_dialog(self, trans, action, show_details):
533 dia = AptProgressDialog(trans, parent=self.window_main)
534 dia.set_icon_name("system-software-update")
535+ dia.set_title(_("Software Updater"))
536+ if not show_details:
537+ dia.expander.set_no_show_all(True)
538+ dia.expander.hide()
539 dia.connect("finished", self._on_finished, action)
540- yield dia.run()
541+ yield dia.run(close_on_finished=False)
542
543 def _on_finished(self, dialog, action):
544- dialog.hide()
545 # tell unity to hide the progress again
546 self.unity.set_progress(-1)
547 self.emit("action-done", action,
548 True, dialog._transaction.exit == EXIT_SUCCESS)
549+ dialog.hide()
550
551 if __name__ == "__main__":
552 b = InstallBackendAptdaemon(None)
553
554=== modified file 'data/com.ubuntu.update-manager.gschema.xml.in'
555--- data/com.ubuntu.update-manager.gschema.xml.in 2012-05-31 22:18:33 +0000
556+++ data/com.ubuntu.update-manager.gschema.xml.in 2012-06-25 15:02:27 +0000
557@@ -1,10 +1,5 @@
558 <schemalist>
559 <schema id="com.ubuntu.update-manager" path="/apps/update-manager/">
560- <key name="remind-reload" type="b">
561- <default>true</default>
562- <summary>Remind to reload the channel list</summary>
563- <description>If automatic checking for updates is disabled, you have to reload the channel list manually. This option allows to hide the reminder shown in this case.</description>
564- </key>
565 <key name="show-details" type="b">
566 <default>false</default>
567 <summary>Show details of an update</summary>
568
569=== modified file 'data/gtkbuilder/UpdateManager.ui'
570--- data/gtkbuilder/UpdateManager.ui 2012-05-31 22:18:33 +0000
571+++ data/gtkbuilder/UpdateManager.ui 2012-06-25 15:02:27 +0000
572@@ -230,153 +230,6 @@
573 <action-widget response="-7">okbutton3</action-widget>
574 </action-widgets>
575 </object>
576- <object class="GtkDialog" id="dialog_manual_update">
577- <property name="can_focus">False</property>
578- <property name="border_width">6</property>
579- <property name="resizable">False</property>
580- <property name="modal">True</property>
581- <property name="window_position">center-on-parent</property>
582- <property name="type_hint">dialog</property>
583- <property name="skip_taskbar_hint">True</property>
584- <property name="skip_pager_hint">True</property>
585- <child internal-child="vbox">
586- <object class="GtkBox" id="dialog-vbox4">
587- <property name="visible">True</property>
588- <property name="can_focus">False</property>
589- <property name="spacing">12</property>
590- <child internal-child="action_area">
591- <object class="GtkButtonBox" id="dialog-action_area4">
592- <property name="visible">True</property>
593- <property name="can_focus">False</property>
594- <property name="layout_style">end</property>
595- <child>
596- <object class="GtkButton" id="cancelbutton1">
597- <property name="label" translatable="yes">Chec_k</property>
598- <property name="use_action_appearance">False</property>
599- <property name="visible">True</property>
600- <property name="can_focus">True</property>
601- <property name="can_default">True</property>
602- <property name="receives_default">False</property>
603- <property name="use_action_appearance">False</property>
604- <property name="image">image-refresh</property>
605- <property name="use_underline">True</property>
606- </object>
607- <packing>
608- <property name="expand">False</property>
609- <property name="fill">False</property>
610- <property name="position">0</property>
611- </packing>
612- </child>
613- <child>
614- <object class="GtkButton" id="okbutton2">
615- <property name="label">gtk-close</property>
616- <property name="use_action_appearance">False</property>
617- <property name="visible">True</property>
618- <property name="can_focus">True</property>
619- <property name="can_default">True</property>
620- <property name="receives_default">False</property>
621- <property name="use_action_appearance">False</property>
622- <property name="use_stock">True</property>
623- </object>
624- <packing>
625- <property name="expand">False</property>
626- <property name="fill">False</property>
627- <property name="position">1</property>
628- </packing>
629- </child>
630- </object>
631- <packing>
632- <property name="expand">False</property>
633- <property name="fill">True</property>
634- <property name="pack_type">end</property>
635- <property name="position">0</property>
636- </packing>
637- </child>
638- <child>
639- <object class="GtkHBox" id="hbox16">
640- <property name="visible">True</property>
641- <property name="can_focus">False</property>
642- <property name="border_width">6</property>
643- <property name="spacing">11</property>
644- <child>
645- <object class="GtkImage" id="image12">
646- <property name="visible">True</property>
647- <property name="can_focus">False</property>
648- <property name="xalign">0</property>
649- <property name="yalign">0</property>
650- <property name="stock">gtk-dialog-info</property>
651- <property name="icon-size">6</property>
652- </object>
653- <packing>
654- <property name="expand">False</property>
655- <property name="fill">True</property>
656- <property name="position">0</property>
657- </packing>
658- </child>
659- <child>
660- <object class="GtkVBox" id="vbox17">
661- <property name="visible">True</property>
662- <property name="can_focus">False</property>
663- <property name="spacing">12</property>
664- <child>
665- <object class="GtkLabel" id="label27">
666- <property name="visible">True</property>
667- <property name="can_focus">True</property>
668- <property name="xalign">0</property>
669- <property name="yalign">0</property>
670- <property name="label" translatable="yes">&lt;b&gt;&lt;big&gt;You must check for updates manually&lt;/big&gt;&lt;/b&gt;
671-
672-Your system does not check for updates automatically. You can configure this behavior in &lt;i&gt;Software Sources&lt;/i&gt; on the &lt;i&gt;Updates&lt;/i&gt; tab.</property>
673- <property name="use_markup">True</property>
674- <property name="wrap">True</property>
675- <property name="selectable">True</property>
676- </object>
677- <packing>
678- <property name="expand">False</property>
679- <property name="fill">False</property>
680- <property name="position">0</property>
681- </packing>
682- </child>
683- <child>
684- <object class="GtkCheckButton" id="checkbutton_reminder">
685- <property name="label" translatable="yes">_Hide this information in the future</property>
686- <property name="use_action_appearance">False</property>
687- <property name="visible">True</property>
688- <property name="can_focus">True</property>
689- <property name="receives_default">False</property>
690- <property name="use_action_appearance">False</property>
691- <property name="use_underline">True</property>
692- <property name="xalign">0.5</property>
693- <property name="draw_indicator">True</property>
694- <signal name="toggled" handler="on_checkbutton_reminder_toggled" swapped="no"/>
695- </object>
696- <packing>
697- <property name="expand">False</property>
698- <property name="fill">False</property>
699- <property name="position">1</property>
700- </packing>
701- </child>
702- </object>
703- <packing>
704- <property name="expand">False</property>
705- <property name="fill">False</property>
706- <property name="position">1</property>
707- </packing>
708- </child>
709- </object>
710- <packing>
711- <property name="expand">True</property>
712- <property name="fill">True</property>
713- <property name="position">1</property>
714- </packing>
715- </child>
716- </object>
717- </child>
718- <action-widgets>
719- <action-widget response="-8">cancelbutton1</action-widget>
720- <action-widget response="-7">okbutton2</action-widget>
721- </action-widgets>
722- </object>
723 <object class="GtkDialog" id="dialog_on_battery">
724 <property name="can_focus">False</property>
725 <property name="border_width">6</property>
726@@ -607,11 +460,6 @@
727 <property name="can_focus">False</property>
728 <property name="stock">gtk-apply</property>
729 </object>
730- <object class="GtkImage" id="image-refresh">
731- <property name="visible">True</property>
732- <property name="can_focus">False</property>
733- <property name="stock">gtk-refresh</property>
734- </object>
735 <object class="GtkWindow" id="window_fetch">
736 <property name="can_focus">False</property>
737 <property name="border_width">6</property>
738@@ -796,6 +644,8 @@
739 <property name="visible">True</property>
740 <property name="can_focus">False</property>
741 <property name="yalign">0</property>
742+ <property name="pixel_size">48</property>
743+ <property name="icon_name">system-software-update</property>
744 </object>
745 <packing>
746 <property name="expand">False</property>
747@@ -804,46 +654,19 @@
748 </packing>
749 </child>
750 <child>
751- <object class="GtkVBox" id="vbox_label_main">
752+ <object class="GtkLabel" id="label_header">
753 <property name="visible">True</property>
754 <property name="can_focus">False</property>
755- <property name="spacing">6</property>
756- <child>
757- <object class="GtkLabel" id="label_header">
758- <property name="visible">True</property>
759- <property name="can_focus">False</property>
760- <property name="xalign">0</property>
761- <property name="yalign">0</property>
762- <property name="label" translatable="yes">Starting Software Updater</property>
763- <property name="use_underline">True</property>
764- <property name="wrap">True</property>
765- <attributes>
766- <attribute name="weight" value="bold"/>
767- <attribute name="scale" value="1.25"/>
768- </attributes>
769- </object>
770- <packing>
771- <property name="expand">False</property>
772- <property name="fill">False</property>
773- <property name="position">0</property>
774- </packing>
775- </child>
776- <child>
777- <object class="GtkLabel" id="label_main_details">
778- <property name="visible">True</property>
779- <property name="can_focus">False</property>
780- <property name="xalign">0</property>
781- <property name="wrap">True</property>
782- </object>
783- <packing>
784- <property name="expand">False</property>
785- <property name="fill">False</property>
786- <property name="position">1</property>
787- </packing>
788- </child>
789+ <property name="xalign">0</property>
790+ <property name="use_underline">True</property>
791+ <property name="wrap">True</property>
792+ <attributes>
793+ <attribute name="weight" value="bold"/>
794+ <attribute name="scale" value="1.25"/>
795+ </attributes>
796 </object>
797 <packing>
798- <property name="expand">True</property>
799+ <property name="expand">False</property>
800 <property name="fill">True</property>
801 <property name="position">1</property>
802 </packing>
803@@ -998,6 +821,9 @@
804 </child>
805 <signal name="cursor-changed" handler="on_treeview_update_cursor_changed" swapped="no"/>
806 <signal name="row-activated" handler="on_treeview_update_row_activated" swapped="no"/>
807+ <child internal-child="selection">
808+ <object class="GtkTreeSelection" id="treeview-selection2"/>
809+ </child>
810 </object>
811 </child>
812 </object>
813@@ -1365,24 +1191,6 @@
814 </packing>
815 </child>
816 <child>
817- <object class="GtkButton" id="button_reload">
818- <property name="label" translatable="yes">Chec_k</property>
819- <property name="use_action_appearance">False</property>
820- <property name="visible">True</property>
821- <property name="can_focus">True</property>
822- <property name="receives_default">True</property>
823- <property name="use_action_appearance">False</property>
824- <property name="image">image-refresh</property>
825- <property name="use_underline">True</property>
826- <signal name="clicked" handler="on_button_reload_clicked" swapped="no"/>
827- </object>
828- <packing>
829- <property name="expand">False</property>
830- <property name="fill">True</property>
831- <property name="position">1</property>
832- </packing>
833- </child>
834- <child>
835 <object class="GtkButton" id="button_close">
836 <property name="label">gtk-close</property>
837 <property name="use_action_appearance">False</property>
838
839=== modified file 'data/update-manager.convert'
840--- data/update-manager.convert 2012-05-31 22:18:33 +0000
841+++ data/update-manager.convert 2012-06-25 15:02:27 +0000
842@@ -1,5 +1,4 @@
843 [com.ubuntu.update-manager]
844-remind-reload = /apps/update-manager/remind_reload
845 show-details = /apps/update-manager/show_details
846 check-dist-upgrades = /apps/update-manager/check_dist_upgrades
847 autoclose-install-window = /apps/update-manager/autoclose_install_window
848
849=== modified file 'update-manager'
850--- update-manager 2012-06-13 22:45:57 +0000
851+++ update-manager 2012-06-25 15:02:27 +0000
852@@ -26,13 +26,17 @@
853 from __future__ import print_function
854
855 from gi.repository import Gtk
856+from gi.repository import Gio
857 import gi
858 gi.require_version("Gtk", "3.0")
859
860 import os
861 import sys
862+import time
863
864 from UpdateManager.UpdateManager import UpdateManager
865+from UpdateManager.UpdateProgress import UpdateProgress
866+from UpdateManager.Core.utils import init_proxy
867 from DistUpgrade.DistUpgradeVersion import VERSION
868 import locale
869 import gettext
870@@ -42,7 +46,8 @@
871 if __name__ == "__main__":
872
873 Gtk.init_check(sys.argv)
874-
875+ Gtk.Window.set_default_icon_name("system-software-update")
876+
877 #FIXME: Workaround a bug in optparser which doesn't handle unicode/str
878 # correctly, see http://bugs.python.org/issue4391
879 # Should be resolved by Python3
880@@ -117,5 +122,14 @@
881 controller = DistUpgradeController(view, datadir=data_dir)
882 controller.doPartialUpgrade()
883 else:
884- app = UpdateManager(data_dir, options)
885- app.main(options)
886+ # keep track when we run (for update-notifier)
887+ settings = Gio.Settings("com.ubuntu.update-manager")
888+ settings.set_int("launch-time", int(time.time()))
889+ init_proxy(settings)
890+
891+ if options.no_update:
892+ app = UpdateManager(data_dir, options)
893+ else:
894+ app = UpdateProgress(data_dir, options)
895+ app.main()
896+ Gtk.main()

Subscribers

People subscribed via source and target branches

to status/vote changes: