~ubuntu-core-dev/ubuntu-release-upgrader/trunk

2515 by Michael Terry
add DistUpgradeFetcher code and related bits to this package instead of update-manager
1
# DistUpgradeFetcher.py
2
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
3
#
4
#  Copyright (c) 2006 Canonical
5
#
6
#  Author: Michael Vogt <michael.vogt@ubuntu.com>
7
#
8
#  This program is free software; you can redistribute it and/or
9
#  modify it under the terms of the GNU General Public License as
10
#  published by the Free Software Foundation; either version 2 of the
11
#  License, or (at your option) any later version.
12
#
13
#  This program is distributed in the hope that it will be useful,
14
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
#  GNU General Public License for more details.
17
#
18
#  You should have received a copy of the GNU General Public License
19
#  along with this program; if not, write to the Free Software
20
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21
#  USA
22
23
from gi.repository import Gtk, Gdk
24
25
from .ReleaseNotesViewer import ReleaseNotesViewer
2524.1.1 by Michael Terry
add back symlinks to update-manager code for the dist-release tarball's sake
26
from .utils import error, inhibit_sleep, allow_sleep
2515 by Michael Terry
add DistUpgradeFetcher code and related bits to this package instead of update-manager
27
from .DistUpgradeFetcherCore import DistUpgradeFetcherCore
28
from .SimpleGtk3builderApp import SimpleGtkbuilderApp
29
from gettext import gettext as _
2792 by Michael Vogt
- remove gtk2/py2 DistUpgradeViewGtk view
30
from urllib.request import urlopen
31
from urllib.error import HTTPError
2515 by Michael Terry
add DistUpgradeFetcher code and related bits to this package instead of update-manager
32
import os
33
import socket
34
35
36
class DistUpgradeFetcherGtk(DistUpgradeFetcherCore):
37
38
    def __init__(self, new_dist, progress, parent, datadir):
39
        DistUpgradeFetcherCore.__init__(self, new_dist, progress)
2611.1.1 by Michael Terry
make check-new-release-gtk work again
40
        uifile = os.path.join(datadir, "gtkbuilder", "ReleaseNotes.ui")
2515 by Michael Terry
add DistUpgradeFetcher code and related bits to this package instead of update-manager
41
        self.widgets = SimpleGtkbuilderApp(uifile, "ubuntu-release-upgrader")
42
        self.window_main = parent
43
44
    def error(self, summary, message):
2703 by Brian Murray
Properly display error messages encountered by DistUpgradeFetcherCore.
45
        return error(self.window_main, summary, message)
2515 by Michael Terry
add DistUpgradeFetcher code and related bits to this package instead of update-manager
46
47
    def runDistUpgrader(self):
48
        inhibit_sleep()
49
        # now run it as root
50
        if os.getuid() != 0:
51
            os.execv("/usr/bin/gksu",
52
                     ["gksu",
53
                      "--desktop",
54
                      "/usr/share/applications/update-manager.desktop",
55
                      "--",
56
                      self.script] + self.run_options)
57
        else:
58
            os.execv(self.script, [self.script] + self.run_options)
59
        # we shouldn't come to this point, but if we do, undo our
60
        # inhibit sleep
61
        allow_sleep()
62
63
    def showReleaseNotes(self):
64
        # first try showing the webkit version, this may fail (return None
65
        # because e.g. there is no webkit installed)
66
        res = self._try_show_release_notes_webkit()
67
        if res is not None:
68
            return res
69
        else:
70
            # fallback to text
71
            return self._try_show_release_notes_textview()
72
73
    def _try_show_release_notes_webkit(self):
74
        if self.new_dist.releaseNotesHtmlUri is not None:
75
            try:
76
                from .ReleaseNotesViewerWebkit import ReleaseNotesViewerWebkit
77
                webkit_release_notes = ReleaseNotesViewerWebkit(
78
                    self.new_dist.releaseNotesHtmlUri)
79
                webkit_release_notes.show()
80
                self.widgets.scrolled_notes.add(webkit_release_notes)
81
                res = self.widgets.dialog_release_notes.run()
82
                self.widgets.dialog_release_notes.hide()
83
                if res == Gtk.ResponseType.OK:
84
                    return True
85
                return False
86
            except ImportError:
87
                pass
88
        return None
89
90
    def _try_show_release_notes_textview(self):
91
        # FIXME: care about i18n! (append -$lang or something)
92
        if self.new_dist.releaseNotesURI is not None:
93
            uri = self._expandUri(self.new_dist.releaseNotesURI)
2516.1.1 by Michael Terry
allow do-release-upgrade to act with a gtk frontend, moving that code from u-m
94
            if self.window_main:
95
                self.window_main.set_sensitive(False)
96
                self.window_main.get_window().set_cursor(
97
                    Gdk.Cursor.new(Gdk.CursorType.WATCH))
2515 by Michael Terry
add DistUpgradeFetcher code and related bits to this package instead of update-manager
98
            while Gtk.events_pending():
99
                Gtk.main_iteration()
100
101
            # download/display the release notes
102
            # FIXME: add some progress reporting here
103
            res = Gtk.ResponseType.CANCEL
104
            timeout = socket.getdefaulttimeout()
105
            try:
106
                socket.setdefaulttimeout(5)
107
                release_notes = urlopen(uri)
108
                notes = release_notes.read().decode("UTF-8", "replace")
109
                textview_release_notes = ReleaseNotesViewer(notes)
110
                textview_release_notes.show()
111
                self.widgets.scrolled_notes.add(textview_release_notes)
112
                release_widget = self.widgets.dialog_release_notes
113
                release_widget.set_transient_for(self.window_main)
114
                res = self.widgets.dialog_release_notes.run()
115
                self.widgets.dialog_release_notes.hide()
116
            except HTTPError:
117
                primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \
118
                          _("Could not find the release notes")
119
                secondary = _("The server may be overloaded. ")
120
                dialog = Gtk.MessageDialog(self.window_main,
121
                                           Gtk.DialogFlags.MODAL,
122
                                           Gtk.MessageType.ERROR,
123
                                           Gtk.ButtonsType.CLOSE, "")
124
                dialog.set_title("")
125
                dialog.set_markup(primary)
126
                dialog.format_secondary_text(secondary)
127
                dialog.run()
128
                dialog.destroy()
129
            except IOError:
130
                primary = "<span weight=\"bold\" size=\"larger\">%s</span>" % \
131
                          _("Could not download the release notes")
132
                secondary = _("Please check your internet connection.")
133
                dialog = Gtk.MessageDialog(self.window_main,
134
                                           Gtk.DialogFlags.MODAL,
135
                                           Gtk.MessageType.ERROR,
136
                                           Gtk.ButtonsType.CLOSE, "")
137
                dialog.set_title("")
138
                dialog.set_markup(primary)
139
                dialog.format_secondary_text(secondary)
140
                dialog.run()
141
                dialog.destroy()
142
            socket.setdefaulttimeout(timeout)
2516.1.1 by Michael Terry
allow do-release-upgrade to act with a gtk frontend, moving that code from u-m
143
            if self.window_main:
144
                self.window_main.set_sensitive(True)
145
                self.window_main.get_window().set_cursor(None)
2515 by Michael Terry
add DistUpgradeFetcher code and related bits to this package instead of update-manager
146
            # user clicked cancel
147
            if res == Gtk.ResponseType.OK:
148
                return True
149
        return False