]>
git.saurik.com Git - apt.git/blob - apt-private/acqprogress.cc
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>
33 // AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
34 // ---------------------------------------------------------------------
36 AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth
,unsigned int const Quiet
) :
37 pkgAcquireStatus(), ScreenWidth(ScreenWidth
), 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
)
64 cout
<< '\r' << BlankLine
<< '\r';
66 cout
<< _("Hit ") << Itm
.Description
;
71 // AcqTextStatus::Fetch - An item has started to download /*{{{*/
72 // ---------------------------------------------------------------------
73 /* This prints out the short description and the expected size */
74 void AcqTextStatus::Fetch(pkgAcquire::ItemDesc
&Itm
)
77 if (Itm
.Owner
->Complete
== true)
86 cout
<< '\r' << BlankLine
<< '\r';
88 cout
<< _("Get:") << Itm
.Owner
->ID
<< ' ' << Itm
.Description
;
89 if (Itm
.Owner
->FileSize
!= 0)
90 cout
<< " [" << SizeToStr(Itm
.Owner
->FileSize
) << "B]";
94 // AcqTextStatus::Done - Completed a download /*{{{*/
95 // ---------------------------------------------------------------------
96 /* We don't display anything... */
97 void AcqTextStatus::Done(pkgAcquire::ItemDesc
&/*Itm*/)
102 // AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
103 // ---------------------------------------------------------------------
104 /* We print out the error text */
105 void AcqTextStatus::Fail(pkgAcquire::ItemDesc
&Itm
)
110 // Ignore certain kinds of transient failures (bad code)
111 if (Itm
.Owner
->Status
== pkgAcquire::Item::StatIdle
)
115 cout
<< '\r' << BlankLine
<< '\r';
117 if (Itm
.Owner
->Status
== pkgAcquire::Item::StatDone
)
119 cout
<< _("Ign ") << Itm
.Description
<< endl
;
120 if (Itm
.Owner
->ErrorText
.empty() == false &&
121 _config
->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == true)
122 cout
<< " " << Itm
.Owner
->ErrorText
<< endl
;
126 cout
<< _("Err ") << Itm
.Description
<< endl
;
127 cout
<< " " << Itm
.Owner
->ErrorText
<< endl
;
133 // AcqTextStatus::Stop - Finished downloading /*{{{*/
134 // ---------------------------------------------------------------------
135 /* This prints out the bytes downloaded and the overall average line
137 void AcqTextStatus::Stop()
139 pkgAcquireStatus::Stop();
144 cout
<< '\r' << BlankLine
<< '\r' << flush
;
146 if (_config
->FindB("quiet::NoStatistic", false) == true)
149 if (FetchedBytes
!= 0 && _error
->PendingError() == false)
150 ioprintf(cout
,_("Fetched %sB in %s (%sB/s)\n"),
151 SizeToStr(FetchedBytes
).c_str(),
152 TimeToStr(ElapsedTime
).c_str(),
153 SizeToStr(CurrentCPS
).c_str());
156 // AcqTextStatus::Pulse - Regular event pulse /*{{{*/
157 // ---------------------------------------------------------------------
158 /* This draws the current progress. Each line has an overall percent
159 meter and a per active item status meter along with an overall
160 bandwidth and ETA indicator. */
161 bool AcqTextStatus::Pulse(pkgAcquire
*Owner
)
163 pkgAcquireStatus::Pulse(Owner
);
168 enum {Long
= 0,Medium
,Short
} Mode
= Medium
;
170 char Buffer
[sizeof(BlankLine
)];
171 char *End
= Buffer
+ sizeof(Buffer
);
173 if (ScreenWidth
>= sizeof(Buffer
))
174 ScreenWidth
= sizeof(Buffer
)-1;
176 // Put in the percent done
177 sprintf(S
,"%.0f%%", Percent
);
180 for (pkgAcquire::Worker
*I
= Owner
->WorkersBegin(); I
!= 0;
181 I
= Owner
->WorkerStep(I
))
185 // There is no item running
186 if (I
->CurrentItem
== 0)
188 if (I
->Status
.empty() == false)
190 snprintf(S
,End
-S
," [%s]",I
->Status
.c_str());
199 // Add in the short description
200 if (I
->CurrentItem
->Owner
->ID
!= 0)
201 snprintf(S
,End
-S
," [%lu %s",I
->CurrentItem
->Owner
->ID
,
202 I
->CurrentItem
->ShortDesc
.c_str());
204 snprintf(S
,End
-S
," [%s",I
->CurrentItem
->ShortDesc
.c_str());
207 // Show the short mode string
208 if (I
->CurrentItem
->Owner
->ActiveSubprocess
.empty() == false)
210 snprintf(S
,End
-S
, " %s", I
->CurrentItem
->Owner
->ActiveSubprocess
.c_str());
214 // Add the current progress
216 snprintf(S
,End
-S
," %llu",I
->CurrentSize
);
219 if (Mode
== Medium
|| I
->TotalSize
== 0)
220 snprintf(S
,End
-S
," %sB",SizeToStr(I
->CurrentSize
).c_str());
224 // Add the total size and percent
225 if (I
->TotalSize
> 0 && I
->CurrentItem
->Owner
->Complete
== false)
228 snprintf(S
,End
-S
," %.0f%%",
229 (I
->CurrentSize
*100.0)/I
->TotalSize
);
231 snprintf(S
,End
-S
,"/%sB %.0f%%",SizeToStr(I
->TotalSize
).c_str(),
232 (I
->CurrentSize
*100.0)/I
->TotalSize
);
235 snprintf(S
,End
-S
,"]");
240 snprintf(S
,End
-S
,_(" [Working]"));
242 /* Put in the ETA and cps meter, block off signals to prevent strangeness
244 sigset_t Sigs
,OldSigs
;
246 sigaddset(&Sigs
,SIGWINCH
);
247 sigprocmask(SIG_BLOCK
,&Sigs
,&OldSigs
);
252 unsigned long long ETA
= (TotalBytes
- CurrentBytes
)/CurrentCPS
;
253 sprintf(Tmp
," %sB/s %s",SizeToStr(CurrentCPS
).c_str(),TimeToStr(ETA
).c_str());
254 unsigned int Len
= strlen(Buffer
);
255 unsigned int LenT
= strlen(Tmp
);
256 if (Len
+ LenT
< ScreenWidth
)
258 memset(Buffer
+ Len
,' ',ScreenWidth
- Len
);
259 strcpy(Buffer
+ ScreenWidth
- LenT
,Tmp
);
262 Buffer
[ScreenWidth
] = 0;
263 BlankLine
[ScreenWidth
] = 0;
264 sigprocmask(SIG_SETMASK
,&OldSigs
,0);
266 // Draw the current status
267 if (_config
->FindB("Apt::Color", false) == true)
268 cout
<< _config
->Find("APT::Color::Yellow");
269 if (strlen(Buffer
) == strlen(BlankLine
))
270 cout
<< '\r' << Buffer
<< flush
;
272 cout
<< '\r' << BlankLine
<< '\r' << Buffer
<< flush
;
273 if (_config
->FindB("Apt::Color", false) == true)
274 cout
<< _config
->Find("APT::Color::Neutral") << flush
;
276 memset(BlankLine
,' ',strlen(Buffer
));
277 BlankLine
[strlen(Buffer
)] = 0;
284 // AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
285 // ---------------------------------------------------------------------
286 /* Prompt for a media swap */
287 bool AcqTextStatus::MediaChange(string Media
,string Drive
)
289 // If we do not output on a terminal and one of the options to avoid user
290 // interaction is given, we assume that no user is present who could react
291 // on your media change request
292 if (isatty(STDOUT_FILENO
) != 1 && Quiet
>= 2 &&
293 (_config
->FindB("APT::Get::Assume-Yes",false) == true ||
294 _config
->FindB("APT::Get::Force-Yes",false) == true ||
295 _config
->FindB("APT::Get::Trivial-Only",false) == true))
300 cout
<< '\r' << BlankLine
<< '\r';
301 ioprintf(cout
,_("Media change: please insert the disc labeled\n"
303 "in the drive '%s' and press enter\n"),
304 Media
.c_str(),Drive
.c_str());
308 while (C
!= '\n' && C
!= '\r')
310 int len
= read(STDIN_FILENO
,&C
,1);
311 if(C
== 'c' || len
<= 0)