]>
git.saurik.com Git - apt.git/blob - apt-private/acqprogress.cc
e834d7d6ac8e9bcb411565b8154f8d032a5217bf
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: acqprogress.cc,v 1.24 2003/04/27 01:56:48 doogie Exp $
4 /* ######################################################################
6 Acquire Progress - Command line progress meter
8 ##################################################################### */
10 // Include files /*{{{*/
13 #include <apt-pkg/acquire.h>
14 #include <apt-pkg/acquire-item.h>
15 #include <apt-pkg/acquire-worker.h>
16 #include <apt-pkg/configuration.h>
17 #include <apt-pkg/strutl.h>
18 #include <apt-pkg/error.h>
20 #include <apt-private/acqprogress.h>
34 // AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
35 // ---------------------------------------------------------------------
37 AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth
,unsigned int const Quiet
) :
38 pkgAcquireStatus(), ScreenWidth(ScreenWidth
), LastLineLength(0), ID(0), Quiet(Quiet
)
40 // testcases use it to disable pulses without disabling other user messages
41 if (Quiet
== 0 && _config
->FindB("quiet::NoUpdate", false) == true)
45 // AcqTextStatus::Start - Downloading has started /*{{{*/
46 // ---------------------------------------------------------------------
48 void AcqTextStatus::Start()
50 pkgAcquireStatus::Start();
55 // AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/
56 // ---------------------------------------------------------------------
58 void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc
&Itm
)
65 cout
<< _("Hit ") << Itm
.Description
;
70 // AcqTextStatus::Fetch - An item has started to download /*{{{*/
71 // ---------------------------------------------------------------------
72 /* This prints out the short description and the expected size */
73 void AcqTextStatus::Fetch(pkgAcquire::ItemDesc
&Itm
)
76 if (Itm
.Owner
->Complete
== true)
86 cout
<< _("Get:") << Itm
.Owner
->ID
<< ' ' << Itm
.Description
;
87 if (Itm
.Owner
->FileSize
!= 0)
88 cout
<< " [" << SizeToStr(Itm
.Owner
->FileSize
) << "B]";
92 // AcqTextStatus::Done - Completed a download /*{{{*/
93 // ---------------------------------------------------------------------
94 /* We don't display anything... */
95 void AcqTextStatus::Done(pkgAcquire::ItemDesc
&/*Itm*/)
100 // AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
101 // ---------------------------------------------------------------------
102 /* We print out the error text */
103 void AcqTextStatus::Fail(pkgAcquire::ItemDesc
&Itm
)
108 // Ignore certain kinds of transient failures (bad code)
109 if (Itm
.Owner
->Status
== pkgAcquire::Item::StatIdle
)
114 if (Itm
.Owner
->Status
== pkgAcquire::Item::StatDone
)
116 cout
<< _("Ign ") << Itm
.Description
<< endl
;
117 if (Itm
.Owner
->ErrorText
.empty() == false &&
118 _config
->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == true)
119 cout
<< " " << Itm
.Owner
->ErrorText
<< endl
;
123 cout
<< _("Err ") << Itm
.Description
<< endl
;
124 cout
<< " " << Itm
.Owner
->ErrorText
<< endl
;
130 // AcqTextStatus::Stop - Finished downloading /*{{{*/
131 // ---------------------------------------------------------------------
132 /* This prints out the bytes downloaded and the overall average line
134 void AcqTextStatus::Stop()
136 pkgAcquireStatus::Stop();
142 if (_config
->FindB("quiet::NoStatistic", false) == true)
145 if (FetchedBytes
!= 0 && _error
->PendingError() == false)
146 ioprintf(cout
,_("Fetched %sB in %s (%sB/s)\n"),
147 SizeToStr(FetchedBytes
).c_str(),
148 TimeToStr(ElapsedTime
).c_str(),
149 SizeToStr(CurrentCPS
).c_str());
152 // AcqTextStatus::Pulse - Regular event pulse /*{{{*/
153 // ---------------------------------------------------------------------
154 /* This draws the current progress. Each line has an overall percent
155 meter and a per active item status meter along with an overall
156 bandwidth and ETA indicator. */
157 bool AcqTextStatus::Pulse(pkgAcquire
*Owner
)
159 pkgAcquireStatus::Pulse(Owner
);
164 enum {Long
= 0,Medium
,Short
} Mode
= Medium
;
169 for (pkgAcquire::Worker
*I
= Owner
->WorkersBegin(); I
!= 0;
170 I
= Owner
->WorkerStep(I
))
172 // There is no item running
173 if (I
->CurrentItem
== 0)
175 if (I
->Status
.empty() == false)
176 S
<< " [" << I
->Status
<< "]";
181 // Add in the short description
183 if (I
->CurrentItem
->Owner
->ID
!= 0)
184 S
<< I
->CurrentItem
->Owner
->ID
<< " ";
185 S
<< I
->CurrentItem
->ShortDesc
;
187 // Show the short mode string
188 if (I
->CurrentItem
->Owner
->ActiveSubprocess
.empty() == false)
189 S
<< " " << I
->CurrentItem
->Owner
->ActiveSubprocess
;
191 // Add the current progress
193 S
<< " " << I
->CurrentSize
;
196 if (Mode
== Medium
|| I
->TotalSize
== 0)
197 S
<< " " << SizeToStr(I
->CurrentSize
) << "B";
200 // Add the total size and percent
201 if (I
->TotalSize
> 0 && I
->CurrentItem
->Owner
->Complete
== false)
204 ioprintf(S
, " %.0f%%", (I
->CurrentSize
*100.0)/I
->TotalSize
);
206 ioprintf(S
, "/%sB %.0f%%", SizeToStr(I
->TotalSize
).c_str(),
207 (I
->CurrentSize
*100.0)/I
->TotalSize
);
212 // Show at least something
215 if (Line
.empty() == true)
216 Line
= _(" [Working]");
218 // Put in the percent done
221 ioprintf(S
, "%.0f%%", Percent
);
227 /* Put in the ETA and cps meter, block off signals to prevent strangeness
229 sigset_t Sigs
,OldSigs
;
231 sigaddset(&Sigs
,SIGWINCH
);
232 sigprocmask(SIG_BLOCK
,&Sigs
,&OldSigs
);
236 unsigned long long ETA
= (TotalBytes
- CurrentBytes
)/CurrentCPS
;
237 std::string Tmp
= " " + SizeToStr(CurrentCPS
) + "B/s " + TimeToStr(ETA
);
238 size_t alignment
= Line
.length() + Tmp
.length();
239 if (alignment
< ScreenWidth
)
241 alignment
= ScreenWidth
- alignment
;
242 for (size_t i
= 0; i
< alignment
; ++i
)
247 if (Line
.length() > ScreenWidth
)
248 Line
.erase(ScreenWidth
);
249 sigprocmask(SIG_SETMASK
,&OldSigs
,0);
251 // Draw the current status
252 if (_config
->FindB("Apt::Color", false) == true)
253 cout
<< _config
->Find("APT::Color::Yellow");
254 if (LastLineLength
> Line
.length())
258 cout
<< Line
<< flush
;
259 if (_config
->FindB("Apt::Color", false) == true)
260 cout
<< _config
->Find("APT::Color::Neutral") << flush
;
262 LastLineLength
= Line
.length();
268 // AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
269 // ---------------------------------------------------------------------
270 /* Prompt for a media swap */
271 bool AcqTextStatus::MediaChange(string Media
,string Drive
)
273 // If we do not output on a terminal and one of the options to avoid user
274 // interaction is given, we assume that no user is present who could react
275 // on your media change request
276 if (isatty(STDOUT_FILENO
) != 1 && Quiet
>= 2 &&
277 (_config
->FindB("APT::Get::Assume-Yes",false) == true ||
278 _config
->FindB("APT::Get::Force-Yes",false) == true ||
279 _config
->FindB("APT::Get::Trivial-Only",false) == true))
284 ioprintf(cout
,_("Media change: please insert the disc labeled\n"
286 "in the drive '%s' and press enter\n"),
287 Media
.c_str(),Drive
.c_str());
291 while (C
!= '\n' && C
!= '\r')
293 int len
= read(STDIN_FILENO
,&C
,1);
294 if(C
== 'c' || len
<= 0)
303 void AcqTextStatus::clearLastLine() { /*{{{*/
307 // do not try to clear more than the (now smaller) screen
308 if (LastLineLength
> ScreenWidth
)
309 LastLineLength
= ScreenWidth
;
312 for (size_t i
= 0; i
< LastLineLength
; ++i
)
314 std::cout
<< '\r' << std::flush
;