~ubuntu-core-dev/update-manager/main

« back to all changes in this revision

Viewing changes to DistUpgrade/DistUpgradeViewText.py

  • Committer: Michael Terry
  • Date: 2012-05-15 19:43:43 UTC
  • mto: This revision was merged to the branch mainline in revision 2428.
  • Revision ID: michael.terry@canonical.com-20120515194343-tocvo0awttmggie1
update several strings to match the software updater spec; most notably, rename from Update Manager to Software Updater

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# DistUpgradeViewText.py 
 
2
#  
 
3
#  Copyright (c) 2004-2006 Canonical
 
4
#  
 
5
#  Author: Michael Vogt <michael.vogt@ubuntu.com>
 
6
 
7
#  This program is free software; you can redistribute it and/or 
 
8
#  modify it under the terms of the GNU General Public License as 
 
9
#  published by the Free Software Foundation; either version 2 of the
 
10
#  License, or (at your option) any later version.
 
11
 
12
#  This program is distributed in the hope that it will be useful,
 
13
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
#  GNU General Public License for more details.
 
16
 
17
#  You should have received a copy of the GNU General Public License
 
18
#  along with this program; if not, write to the Free Software
 
19
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 
20
#  USA
 
21
 
 
22
from __future__ import absolute_import, print_function
 
23
 
 
24
import sys
 
25
import logging
 
26
import subprocess
 
27
 
 
28
import apt
 
29
import os
 
30
 
 
31
from .DistUpgradeView import DistUpgradeView, InstallProgress, AcquireProgress
 
32
import apt.progress
 
33
 
 
34
import gettext
 
35
from .DistUpgradeGettext import gettext as _
 
36
from .utils import twrap
 
37
 
 
38
class TextAcquireProgress(AcquireProgress, apt.progress.text.AcquireProgress):
 
39
    def __init__(self):
 
40
        apt.progress.text.AcquireProgress.__init__(self)
 
41
        AcquireProgress.__init__(self)
 
42
    def pulse(self, owner):
 
43
        apt.progress.text.AcquireProgress.pulse(self, owner)
 
44
        AcquireProgress.pulse(self, owner)
 
45
        return True
 
46
 
 
47
class TextCdromProgressAdapter(apt.progress.base.CdromProgress):
 
48
    """ Report the cdrom add progress  """
 
49
    def update(self, text, step):
 
50
        """ update is called regularly so that the gui can be redrawn """
 
51
        if text:
 
52
          print("%s (%f)" % (text, step/float(self.totalSteps)*100))
 
53
    def ask_cdrom_name(self):
 
54
        return (False, "")
 
55
    def change_cdrom(self):
 
56
        return False
 
57
 
 
58
 
 
59
class DistUpgradeViewText(DistUpgradeView):
 
60
    " text frontend of the distUpgrade tool "
 
61
    def __init__(self, datadir=None, logdir=None):
 
62
        # indicate that we benefit from using gnu screen
 
63
        self.needs_screen = True
 
64
        # its important to have a debconf frontend for
 
65
        # packages like "quagga"
 
66
        if not os.environ.has_key("DEBIAN_FRONTEND"):
 
67
            os.environ["DEBIAN_FRONTEND"] = "dialog"
 
68
        if not datadir:
 
69
          localedir=os.path.join(os.getcwd(),"mo")
 
70
        else:
 
71
          localedir="/usr/share/locale/update-manager"
 
72
 
 
73
        try:
 
74
          gettext.bindtextdomain("update-manager", localedir)
 
75
          gettext.textdomain("update-manager")
 
76
        except Exception as e:
 
77
          logging.warning("Error setting locales (%s)" % e)
 
78
        
 
79
        self.last_step = 0 # keep a record of the latest step
 
80
        self._opCacheProgress = apt.progress.text.OpProgress()
 
81
        self._acquireProgress = TextAcquireProgress()
 
82
        self._cdromProgress = TextCdromProgressAdapter()
 
83
        self._installProgress = InstallProgress()
 
84
        sys.excepthook = self._handleException
 
85
        #self._process_events_tick = 0
 
86
 
 
87
    def _handleException(self, type, value, tb):
 
88
        import traceback
 
89
        print()
 
90
        lines = traceback.format_exception(type, value, tb)
 
91
        logging.error("not handled exception:\n%s" % "\n".join(lines))
 
92
        self.error(_("A fatal error occurred"),
 
93
                   _("Please report this as a bug and include the "
 
94
                     "files /var/log/dist-upgrade/main.log and "
 
95
                     "/var/log/dist-upgrade/apt.log "
 
96
                     "in your report. The upgrade has aborted.\n"
 
97
                     "Your original sources.list was saved in "
 
98
                     "/etc/apt/sources.list.distUpgrade."),
 
99
                   "\n".join(lines))
 
100
        sys.exit(1)
 
101
 
 
102
    def getAcquireProgress(self):
 
103
        return self._acquireProgress
 
104
    def getInstallProgress(self, cache):
 
105
        self._installProgress._cache = cache
 
106
        return self._installProgress
 
107
    def getOpCacheProgress(self):
 
108
        return self._opCacheProgress
 
109
    def getCdromProgress(self):
 
110
        return self._cdromProgress
 
111
    def updateStatus(self, msg):
 
112
      print()
 
113
      print(msg)
 
114
      sys.stdout.flush()
 
115
    def abort(self):
 
116
      print()
 
117
      print(_("Aborting"))
 
118
    def setStep(self, step):
 
119
      self.last_step = step
 
120
    def showDemotions(self, summary, msg, demotions):
 
121
        self.information(summary, msg, 
 
122
                         _("Demoted:\n")+twrap(", ".join(demotions)))
 
123
    def information(self, summary, msg, extended_msg=None):
 
124
      print()
 
125
      print(twrap(summary))
 
126
      print(twrap(msg))
 
127
      if extended_msg:
 
128
        print(twrap(extended_msg))
 
129
      print(_("To continue please press [ENTER]"))
 
130
      sys.stdin.readline()
 
131
    def error(self, summary, msg, extended_msg=None):
 
132
      print()
 
133
      print(twrap(summary))
 
134
      print(twrap(msg))
 
135
      if extended_msg:
 
136
        print(twrap(extended_msg))
 
137
      return False
 
138
    def showInPager(self, output):
 
139
      " helper to show output in a pager"
 
140
      for pager in ["/usr/bin/sensible-pager", "/bin/more"]:
 
141
          if os.path.exists(pager):
 
142
              p = subprocess.Popen([pager,"-"],stdin=subprocess.PIPE)
 
143
              p.stdin.write(output)
 
144
              p.stdin.close()
 
145
              p.wait()
 
146
              return
 
147
      # if we don't have a pager, just print
 
148
      print(output)
 
149
 
 
150
    def confirmChanges(self, summary, changes, demotions, downloadSize,
 
151
                       actions=None, removal_bold=True):
 
152
      DistUpgradeView.confirmChanges(self, summary, changes, demotions, 
 
153
                                     downloadSize, actions)
 
154
      print()
 
155
      print(twrap(summary))
 
156
      print(twrap(self.confirmChangesMessage))
 
157
      print(" %s %s" % (_("Continue [yN] "), _("Details [d]")), end="")
 
158
      while True:
 
159
        res = sys.stdin.readline()
 
160
        # TRANSLATORS: the "y" is "yes"
 
161
        if res.strip().lower().startswith(_("y")):
 
162
          return True
 
163
        # TRANSLATORS: the "n" is "no"
 
164
        elif res.strip().lower().startswith(_("n")):
 
165
          return False
 
166
        # TRANSLATORS: the "d" is "details"
 
167
        elif res.strip().lower().startswith(_("d")):
 
168
          output = ""
 
169
          if len(self.demotions) > 0:
 
170
              output += "\n"  
 
171
              output += twrap(
 
172
                  _("No longer supported: %s\n") % " ".join([p.name for p in self.demotions]),
 
173
                  subsequent_indent='  ')
 
174
          if len(self.toRemove) > 0:
 
175
              output += "\n"  
 
176
              output += twrap(
 
177
                  _("Remove: %s\n") % " ".join([p.name for p in self.toRemove]),
 
178
                  subsequent_indent='  ')
 
179
          if len(self.toRemoveAuto) > 0:
 
180
              output += twrap(
 
181
                  _("Remove (was auto installed) %s") % " ".join([p.name for p in self.toRemoveAuto]), 
 
182
                  subsequent_indent='  ')
 
183
              output += "\n"
 
184
          if len(self.toInstall) > 0:
 
185
              output += "\n"
 
186
              output += twrap(
 
187
                  _("Install: %s\n") % " ".join([p.name for p in self.toInstall]),
 
188
                  subsequent_indent='  ')
 
189
          if len(self.toUpgrade) > 0:
 
190
              output += "\n"  
 
191
              output += twrap(
 
192
                  _("Upgrade: %s\n") % " ".join([p.name for p in self.toUpgrade]),
 
193
                  subsequent_indent='  ')
 
194
          self.showInPager(output)
 
195
        print("%s %s" % (_("Continue [yN] "), _("Details [d]")), end="")
 
196
 
 
197
    def askYesNoQuestion(self, summary, msg, default='No'):
 
198
      print()
 
199
      print(twrap(summary))
 
200
      print(twrap(msg))
 
201
      if default == 'No':
 
202
          print(_("Continue [yN] "), end="")
 
203
          res = sys.stdin.readline()
 
204
          # TRANSLATORS: first letter of a positive (yes) answer
 
205
          if res.strip().lower().startswith(_("y")):
 
206
              return True
 
207
          return False
 
208
      else:
 
209
          print(_("Continue [Yn] "), end="")
 
210
          res = sys.stdin.readline()
 
211
          # TRANSLATORS: first letter of a negative (no) answer
 
212
          if res.strip().lower().startswith(_("n")):
 
213
              return False
 
214
          return True
 
215
 
 
216
# FIXME: when we need this most the resolver is writing debug logs
 
217
#        and we redirect stdout/stderr    
 
218
#    def processEvents(self):
 
219
#      #time.sleep(0.2)
 
220
#      anim = [".","o","O","o"]
 
221
#      anim = ["\\","|","/","-","\\","|","/","-"]
 
222
#      self._process_events_tick += 1
 
223
#      if self._process_events_tick >= len(anim):
 
224
#          self._process_events_tick = 0
 
225
#      sys.stdout.write("[%s]" % anim[self._process_events_tick])
 
226
#      sys.stdout.flush()
 
227
 
 
228
    def confirmRestart(self):
 
229
      return self.askYesNoQuestion(_("Restart required"),
 
230
                                   _("To finish the upgrade, a restart is "
 
231
                                     "required.\n"
 
232
                                     "If you select 'y' the system "
 
233
                                     "will be restarted."), default='No')
 
234
 
 
235
 
 
236
if __name__ == "__main__":
 
237
  view = DistUpgradeViewText()
 
238
 
 
239
  #while True:
 
240
  #    view.processEvents()
 
241
  
 
242
  print(twrap("89 packages are going to be upgraded.\nYou have to download a total of 82.7M.\nThis download will take about 10 minutes with a 1Mbit DSL connection and about 3 hours 12 minutes with a 56k modem.", subsequent_indent=" "))
 
243
  #sys.exit(1)
 
244
 
 
245
  view = DistUpgradeViewText()
 
246
  print(view.askYesNoQuestion("hello", "Icecream?", "No"))
 
247
  print(view.askYesNoQuestion("hello", "Icecream?", "Yes"))
 
248
  
 
249
 
 
250
  #view.confirmChangesMessage = "89 packages are going to be upgraded.\n You have to download a total of 82.7M.\n This download will take about 10 minutes with a 1Mbit DSL connection and about 3 hours 12 minutes with a 56k modem."
 
251
  #view.confirmChanges("xx",[], 100)
 
252
  sys.exit(0)
 
253
 
 
254
  view.confirmRestart()
 
255
 
 
256
  cache = apt.Cache()
 
257
  fp = view.getAcquireProgress()
 
258
  ip = view.getInstallProgress(cache)
 
259
 
 
260
 
 
261
  for pkg in sys.argv[1:]:
 
262
    cache[pkg].mark_install()
 
263
  cache.commit(fp,ip)
 
264
  
 
265
  sys.exit(0)
 
266
  view.getTerminal().call(["dpkg","--configure","-a"])
 
267
  #view.getTerminal().call(["ls","-R","/usr"])
 
268
  view.error("short","long",
 
269
             "asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
 
270
             "asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
 
271
             "asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
 
272
             "asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
 
273
             "asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
 
274
             "asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
 
275
             "asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
 
276
             )
 
277
  view.confirmChanges("xx",[], 100)
 
278
  print(view.askYesNoQuestion("hello", "Icecream?"))