~ubuntu-branches/ubuntu/vivid/aptitude/vivid

« back to all changes in this revision

Viewing changes to src/generic/controllers/acquire_download_progress.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2011-06-22 12:32:56 UTC
  • mfrom: (1.8.6 sid)
  • Revision ID: james.westby@ubuntu.com-20110622123256-8aox9w9ch3x72dci
Tags: 0.6.4-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  - debian/05aptitude: never autoremove kernels
  - drop aptitude-doc to Suggests
  - 03_branding.dpatch: ubuntu branding
  - 04_changelog.dpatch: take changelogs from changelogs.ubuntu.com
  - 09_ubuntu_fortify_source.dpatch: Suppress a number of warnings (turned
    into errors by -Werror) triggered by Ubuntu's default of
    -D_FORTIFY_SOURCE=2.
  - 11_ubuntu_uses_sudo.dpatch: fix status line of 'Become root' menu entry
    to not refer to su.
  - 12_point_manpage_to_doc_package.dpatch: point Finnish manpage to the
    correct place for further info
  - 14_html2text_preferred.dpatch: switch back to html2text in favor of
    elinks, since html2text is in main and elinks isn't.
* dropped 01_intltool_update.dpatch
* updated 15_ftbfs_new_apt

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** \file acquire_download_progress.cc */
 
2
 
 
3
// Copyright (C) 2010 Daniel Burrows
 
4
//
 
5
// This program is free software; you can redistribute it and/or
 
6
// modify it under the terms of the GNU General Public License as
 
7
// published by the Free Software Foundation; either version 2 of the
 
8
// License, or (at your option) any later version.
 
9
//
 
10
// This program is distributed in the hope that it will be useful, but
 
11
// WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
// General Public License for more details.
 
14
//
 
15
// You should have received a copy of the GNU General Public License
 
16
// along with this program; see the file COPYING.  If not, write to
 
17
// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
// Boston, MA 02111-1307, USA.
 
19
 
 
20
// Local includes:
 
21
#include "acquire_download_progress.h"
 
22
 
 
23
#include <generic/apt/download_signal_log.h>
 
24
#include <generic/views/download_progress.h>
 
25
 
 
26
// System includes:
 
27
#include <apt-pkg/acquire-item.h>
 
28
#include <apt-pkg/acquire-worker.h>
 
29
 
 
30
#include <boost/make_shared.hpp>
 
31
 
 
32
#include <sigc++/bind.h>
 
33
 
 
34
using boost::make_shared;
 
35
using boost::shared_ptr;
 
36
 
 
37
namespace aptitude
 
38
{
 
39
  namespace controllers
 
40
  {
 
41
    namespace
 
42
    {
 
43
      template<typename T>
 
44
      boost::optional<T> if_not_zero(const T &t)
 
45
      {
 
46
        if(t == 0)
 
47
          return boost::optional<T>();
 
48
        else
 
49
          return boost::optional<T>(t);
 
50
      }
 
51
    }
 
52
 
 
53
    class acquire_download_progress::impl : public acquire_download_progress,
 
54
                                            public sigc::trackable
 
55
    {
 
56
      friend shared_ptr<impl>
 
57
      make_shared<impl>();
 
58
 
 
59
      void media_change(const std::string &media,
 
60
                        const std::string &drive,
 
61
                        download_signal_log &manager,
 
62
                        const sigc::slot1<void, bool> &k);
 
63
 
 
64
      void ims_hit(pkgAcquire::ItemDesc &item, download_signal_log &manager);
 
65
      void fetch(pkgAcquire::ItemDesc &item, download_signal_log &manager);
 
66
      void done(pkgAcquire::ItemDesc &item, download_signal_log &manager);
 
67
      void fail(pkgAcquire::ItemDesc &item, download_signal_log &manager);
 
68
      void start(download_signal_log &manager);
 
69
      void stop(download_signal_log &manager, const sigc::slot0<void> &k);
 
70
      void complete(download_signal_log &manager);
 
71
 
 
72
      void pulse(pkgAcquire *owner, download_signal_log &manager,
 
73
                 const sigc::slot1<void, bool> &k);
 
74
 
 
75
 
 
76
      // Keeps track of the next ID to assign to a download item.
 
77
      unsigned long id;
 
78
 
 
79
      shared_ptr<views::download_progress> view;
 
80
 
 
81
      shared_ptr<views::download_progress::status>
 
82
      get_current_status(pkgAcquire *owner, download_signal_log &manager);
 
83
 
 
84
    public:
 
85
      impl(download_signal_log *log,
 
86
           const shared_ptr<views::download_progress> &_view);
 
87
    };
 
88
 
 
89
    acquire_download_progress::impl::impl(download_signal_log *log,
 
90
                                          const shared_ptr<views::download_progress> &_view)
 
91
      : id(1),
 
92
        view(_view)
 
93
    {
 
94
      log->MediaChange_sig.connect(sigc::mem_fun(*this, &impl::media_change));
 
95
      log->IMSHit_sig.connect(sigc::mem_fun(*this, &impl::ims_hit));
 
96
      log->Fetch_sig.connect(sigc::mem_fun(*this, &impl::fetch));
 
97
      log->Done_sig.connect(sigc::mem_fun(*this, &impl::done));
 
98
      log->Fail_sig.connect(sigc::mem_fun(*this, &impl::fail));
 
99
      log->Pulse_sig.connect(sigc::mem_fun(*this, &impl::pulse));
 
100
      log->Start_sig.connect(sigc::mem_fun(*this, &impl::start));
 
101
      log->Stop_sig.connect(sigc::mem_fun(*this, &impl::stop));
 
102
      log->Complete_sig.connect(sigc::mem_fun(*this, &impl::complete));
 
103
    }
 
104
 
 
105
    namespace
 
106
    {
 
107
      // Ensure that the download progress gets an update after a
 
108
      // successful media change, so that we have the same behavior as
 
109
      // the old download progress object.
 
110
      void do_media_change_result(bool result,
 
111
                                  download_signal_log &manager,
 
112
                                  const sigc::slot1<void, bool> &k)
 
113
      {
 
114
        if(result)
 
115
          manager.set_update(true);
 
116
 
 
117
        k(result);
 
118
      }
 
119
    }
 
120
 
 
121
    void acquire_download_progress::impl::media_change(const std::string &media,
 
122
                                                       const std::string &drive,
 
123
                                                       download_signal_log &manager,
 
124
                                                       const sigc::slot1<void, bool> &k)
 
125
    {
 
126
      view->media_change(media,
 
127
                         drive,
 
128
                         sigc::bind(sigc::ptr_fun(&do_media_change_result),
 
129
                                    manager,
 
130
                                    k));
 
131
    }
 
132
 
 
133
    shared_ptr<views::download_progress::status>
 
134
    acquire_download_progress::impl::get_current_status(pkgAcquire *owner,
 
135
                                                        download_signal_log &manager)
 
136
    {
 
137
      typedef views::download_progress::file_progress file_progress;
 
138
      typedef views::download_progress::status status;
 
139
      typedef status::worker_status worker_status;
 
140
 
 
141
      std::vector<worker_status> active_downloads;
 
142
 
 
143
      // Read the workers:
 
144
      for(pkgAcquire::Worker *it = owner->WorkersBegin(); it != 0;
 
145
          it = owner->WorkerStep(it))
 
146
        {
 
147
          if(it->CurrentItem == NULL)
 
148
            {
 
149
              if(!it->Status.empty())
 
150
                active_downloads.push_back(it->Status);
 
151
            }
 
152
          else
 
153
            {
 
154
              file_progress
 
155
                current_file(it->CurrentSize,
 
156
                             it->TotalSize,
 
157
                             it->CurrentItem->Owner->Complete,
 
158
                             it->CurrentItem->ShortDesc,
 
159
                             if_not_zero(it->CurrentItem->Owner->ID),
 
160
                             it->CurrentItem->Owner->Mode == NULL
 
161
                               ? ""
 
162
                               : it->CurrentItem->Owner->Mode);
 
163
 
 
164
              active_downloads.push_back(current_file);
 
165
            }
 
166
        }
 
167
 
 
168
      const double download_rate = manager.get_currentCPS();
 
169
 
 
170
      const double current_bytes = manager.get_current_bytes();
 
171
      const double current_items = manager.get_current_items();
 
172
      const double total_bytes = manager.get_total_bytes();
 
173
      const double total_items = manager.get_total_items();
 
174
 
 
175
      const double fraction_complete =
 
176
        ((double) (current_bytes + current_items)) / (total_bytes + total_items);
 
177
 
 
178
      const unsigned long time_remaining =
 
179
        download_rate == 0
 
180
          ? 0
 
181
          : (total_bytes - current_bytes) / download_rate;
 
182
 
 
183
      return boost::make_shared<status>(manager.get_currentCPS(),
 
184
                                        active_downloads,
 
185
                                        fraction_complete,
 
186
                                        time_remaining);
 
187
    }
 
188
 
 
189
    void acquire_download_progress::impl::ims_hit(pkgAcquire::ItemDesc &item,
 
190
                                                  download_signal_log &manager)
 
191
    {
 
192
      view->file_already_downloaded(item.Description,
 
193
                                    if_not_zero(item.Owner->ID),
 
194
                                    if_not_zero(item.Owner->FileSize));
 
195
 
 
196
      manager.set_update(true);
 
197
    }
 
198
 
 
199
    void acquire_download_progress::impl::fetch(pkgAcquire::ItemDesc &item,
 
200
                                                download_signal_log &manager)
 
201
    {
 
202
      if(item.Owner->Complete)
 
203
        return;
 
204
 
 
205
      item.Owner->ID = id;
 
206
      ++id;
 
207
 
 
208
      view->file_started(item.Description,
 
209
                         if_not_zero(item.Owner->ID),
 
210
                         if_not_zero(item.Owner->FileSize));
 
211
 
 
212
      manager.set_update(true);
 
213
    }
 
214
 
 
215
    void acquire_download_progress::impl::done(pkgAcquire::ItemDesc &item, download_signal_log &manager)
 
216
    {
 
217
      view->file_finished(item.Description,
 
218
                          if_not_zero(item.Owner->ID));
 
219
 
 
220
      manager.set_update(true);
 
221
    }
 
222
 
 
223
    void acquire_download_progress::impl::fail(pkgAcquire::ItemDesc &item,
 
224
                                               download_signal_log &manager)
 
225
    {
 
226
      // Ignore certain kinds of transient failures (bad code)
 
227
      if (item.Owner->Status == pkgAcquire::Item::StatIdle)
 
228
        return;
 
229
 
 
230
      view->error(item.Owner->Status == pkgAcquire::Item::StatDone,
 
231
                  item.Owner->ErrorText,
 
232
                  item.Description,
 
233
                  if_not_zero(item.Owner->ID));
 
234
 
 
235
      manager.set_update(true);
 
236
    }
 
237
 
 
238
    void acquire_download_progress::impl::start(download_signal_log &manager)
 
239
    {
 
240
      id = 1;
 
241
    }
 
242
 
 
243
    void acquire_download_progress::impl::stop(download_signal_log &manager, const sigc::slot0<void> &k)
 
244
    {
 
245
      view->done(manager.get_fetched_bytes(),
 
246
                 manager.get_elapsed_time(),
 
247
                 manager.get_currentCPS());
 
248
 
 
249
      k();
 
250
    }
 
251
 
 
252
    void acquire_download_progress::impl::complete(download_signal_log &manager)
 
253
    {
 
254
      view->complete(manager.get_fetched_bytes(),
 
255
                     manager.get_elapsed_time(),
 
256
                     manager.get_currentCPS());
 
257
    }
 
258
 
 
259
    void acquire_download_progress::impl::pulse(pkgAcquire *owner,
 
260
                                                download_signal_log &manager,
 
261
                                                const sigc::slot1<void, bool> &k)
 
262
    {
 
263
      const shared_ptr<views::download_progress::status> status =
 
264
        get_current_status(owner, manager);
 
265
 
 
266
      manager.set_update(false);
 
267
 
 
268
      k(view->update_progress(*status));
 
269
    }
 
270
 
 
271
    acquire_download_progress::acquire_download_progress()
 
272
    {
 
273
    }
 
274
 
 
275
    acquire_download_progress::~acquire_download_progress()
 
276
    {
 
277
    }
 
278
 
 
279
    shared_ptr<acquire_download_progress>
 
280
    create_acquire_download_progress(download_signal_log *log,
 
281
                                     const shared_ptr<views::download_progress> &view)
 
282
    {
 
283
      return make_shared<acquire_download_progress::impl>(log, view);
 
284
    }
 
285
  }
 
286
}
 
287