~ubuntu-branches/ubuntu/maverick/aptdaemon/maverick-proposed

« back to all changes in this revision

Viewing changes to aptdaemon/progress.py

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Heinlein
  • Date: 2010-05-25 12:09:50 UTC
  • mfrom: (1.1.20 upstream)
  • Revision ID: james.westby@ubuntu.com-20100525120950-mjx614j9wj0kk08s
Tags: 0.31+bzr403-0ubuntu1
* First release of the new 0.3X development branch 
* debian/patches:
  - Remove 01_enable_component: Merged upstream
  - Remove 02_fix_errback: Merged upstream
  - Remove 04_caution_is_good: Merged upstream
  - Remove 05_conffile_not_exists: Merged upstream
  - Update 03_auth_me_less: Remove cherry-picked PolicyKit enhancements
* aptdaemon.install: Ship the man pages
* control: Fix location of vcs

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 
13
13
__author__  = "Sebastian Heinlein <devel@glatzor.de>"
14
14
 
 
15
__all__ = ("DaemonAcquireProgress", "DaemonOpenProgress",
 
16
           "DaemonInstallProgress", "DaemonDpkgInstallProgress",
 
17
           "DaemonDpkgRecoverProgress")
 
18
 
15
19
from gettext import gettext as _
 
20
import gettext
16
21
import locale
17
22
import logging
18
23
import os
26
31
import warnings
27
32
 
28
33
import apt_pkg
29
 
import apt.progress
 
34
import apt.progress.base
30
35
import apt.debfile
31
36
import gobject
32
37
 
47
52
 
48
53
REGEX_ANSI_ESCAPE_CODE = chr(27) + "\[[;?0-9]*[A-Za-z]"
49
54
 
50
 
class DaemonOpenProgress(apt.progress.OpProgress):
 
55
class DaemonOpenProgress(apt.progress.base.OpProgress):
51
56
 
52
57
    """Handles the progress of the cache opening."""
53
58
 
60
65
        end -- end of the progress range (defaults to 100)
61
66
        quiet -- do not emit any progress information for the transaction
62
67
        """
63
 
        apt.progress.OpProgress.__init__(self)
 
68
        apt.progress.base.OpProgress.__init__(self)
64
69
        self._transaction = transaction
65
70
        self.steps = [begin + (end - begin) * modifier
66
71
                      for modifier in [0.12, 0.25, 0.50, 0.75, 1.00]]
81
86
            if not self.quiet:
82
87
                self._transaction.progress = progress
83
88
            self.progress = progress
84
 
        while gobject.main_context_default().pending():
85
 
            gobject.main_context_default().iteration()
86
89
 
87
90
    def done(self):
88
91
        """Callback after completing a step.
95
98
            log.warning("An additional step to open the cache is required")
96
99
 
97
100
 
98
 
class DaemonFetchProgress(apt.progress.FetchProgress):
 
101
class DaemonAcquireProgress(apt.progress.base.AcquireProgress):
99
102
    '''
100
103
    Handle the package download process
101
104
    '''
102
105
    def __init__(self, transaction, begin=0, end=100):
103
 
        apt.progress.FetchProgress.__init__(self)
 
106
        apt.progress.base.AcquireProgress.__init__(self)
104
107
        self.transaction = transaction
105
108
        self.progress_end = end
106
109
        self.progress_begin = begin
107
110
        self.progress = 0
108
 
        self.items = {}
109
 
        #FIXME: This should already be part of python-apt
110
 
        self.currentItems = 0
111
 
        self.totalItems = 0
112
 
        self.currentBytes = 0
113
 
        self.totalBytes = 0
114
 
        self.currentCPS = 0
115
111
 
116
 
    def pulse(self):
 
112
    def pulse(self, owner):
117
113
        """Callback to update progress information"""
118
 
        apt.progress.FetchProgress.pulse(self)
119
114
        if self.transaction.cancelled:
120
115
            return False
121
 
        self.transaction.progress_details = (self.currentItems, self.totalItems,
122
 
                                             self.currentBytes, self.totalBytes,
123
 
                                             self.currentCPS, self.eta)
124
 
        progress = int(self.progress_begin + self.percent/100 * \
 
116
        self.transaction.progress_details = (self.current_items,
 
117
                                             self.total_items,
 
118
                                             self.current_bytes,
 
119
                                             self.total_bytes,
 
120
                                             self.current_cps,
 
121
                                             self.elapsed_time)
 
122
        percent = (((self.current_bytes + self.current_items) * 100.0) /
 
123
                    float(self.total_bytes + self.total_items))
 
124
        progress = int(self.progress_begin + percent/100 * \
125
125
                       (self.progress_end - self.progress_begin))
126
126
        # If the progress runs backwards emit an illegal progress value
127
127
        # e.g. during cache updates.
130
130
        else:
131
131
            self.transaction.progress = progress
132
132
            self.progress = progress
 
133
        # Show all currently downloaded files
 
134
        items = []
 
135
        for worker in owner.workers:
 
136
            if not worker.current_item or not \
 
137
               worker.current_item.owner.status == \
 
138
                   apt_pkg.AcquireItem.STAT_FETCHING:
 
139
                continue
 
140
            if worker.current_item.owner.id:
 
141
                items.append(worker.current_item.owner.id)
 
142
            else:
 
143
                items.append(worker.current_item.shortdesc)
 
144
        if items:
 
145
            #FIXME: Would be nice to have a subprogress signal
 
146
            msg = gettext.ngettext("Downloading %s", "Downloading %s",
 
147
                                   len(items)) % " ".join(items)
 
148
            self.transaction.status_details = msg
 
149
 
133
150
        while gobject.main_context_default().pending():
134
151
            gobject.main_context_default().iteration()
135
152
        return True
136
153
 
137
 
    def updateStatus(self, uri, descr, shortDescr, status):
138
 
        """Callback to update the status information"""
139
 
        if status != self.dlQueued:
140
 
            log.debug("%s %s" % (self.dlStatusStr[status], uri))
141
 
        if status == self.dlQueued:
142
 
            self.transaction.status_details = _("Downloading %s") % shortDescr
143
 
        self.items[uri] = status
144
 
 
145
154
    def start(self):
146
155
        """Callback at the beginning of the operation"""
147
156
        self.transaction.status = enums.STATUS_DOWNLOADING
153
162
        self.transaction.progress = self.progress_end
154
163
        self.transaction.cancellable = False
155
164
 
156
 
    def mediaChange(self, medium, drive):
 
165
    def media_change(self, medium, drive):
157
166
        """Callback for media changes"""
158
167
        #FIXME: make use of DeviceKit/hal
159
168
        self.transaction.required_medium = medium, drive
182
191
        self.output = ""
183
192
        self._line_buffer = ""
184
193
 
185
 
    def startUpdate(self):
 
194
    def start_update(self):
186
195
        log.debug("Start update")
187
196
        self.transaction.status = enums.STATUS_COMMITTING
188
197
        self.transaction.term_attached = True
189
198
        self.last_activity = time.time()
190
199
        self.start_time = time.time()
191
200
 
192
 
    def finishUpdate(self):
 
201
    def finish_update(self):
193
202
        """Callback at the end of the operation"""
194
 
        #if self.conffile_prompts:
195
 
        #    self._transaction.Message(MESSAGE_CONFIG_FILES_CHANGED, 
196
 
        #                          "The following conffile prompts were found "
197
 
        #                          "and need investiagtion: %s" % \
198
 
        #                          "\n".join(self.conffile_prompts))
199
 
        # Check for required restarts
200
 
        #if os.path.exists("/var/run/reboot-required") and \
201
 
        #   os.path.getmtime("/var/run/reboot-required") > self.start_time:
202
 
        #self._transaction.RequireRestart(RESTART_SYSTEM, "")
203
203
        self.transaction.term_attached = False
204
204
 
205
205
    def _child(self, pm):
206
206
        try:
207
 
            res = pm.DoInstall(self.status_child_fd)
 
207
            res = pm.do_install(self.status_child_fd)
208
208
        except:
209
 
            os._exit(pm.ResultFailed)
 
209
            os._exit(apt_pkg.PackageManager.RESULT_FAILED)
210
210
        else:
211
211
            os._exit(res)
212
212
 
301
301
        """Fork and create a master/slave pty pair by which the forked process
302
302
        can be controlled.
303
303
        """
304
 
        # process all pending events in the main loop, since we will quit
305
 
        # the loop in the child process
306
 
        context = gobject.main_context_default()
307
 
        while context.pending():
308
 
            context.iteration()
309
304
        pid, self.master_fd = os.forkpty()
310
305
        if pid == 0:
311
306
            mainloop.quit()
331
326
                os.putenv("DEBIAN_FRONTEND", "noninteractive")
332
327
            # Proxy configuration
333
328
            if self.transaction.http_proxy:
334
 
                apt_pkg.Config.Set("Acquire::http::Proxy", self.transaction.http_proxy)
 
329
                apt_pkg.config.set("Acquire::http::Proxy",
 
330
                                   self.transaction.http_proxy)
335
331
        return pid
336
332
 
337
333
    def _copy_io_master(self, source, condition, target):