1 #include <apt-pkg/configuration.h>
2 #include <apt-pkg/fileutl.h>
3 #include <apt-pkg/iprogress.h>
4 #include <apt-pkg/strutl.h>
16 bool PackageManager::StatusChanged(std::string PackageName
,
17 unsigned int StepsDone
,
18 unsigned int TotalSteps
,
19 std::string HumanReadableAction
)
21 int reporting_steps
= _config
->FindI("DpkgPM::Reporting-Steps", 1);
22 percentage
= StepsDone
/(float)TotalSteps
* 100.0;
23 strprintf(progress_str
, _("Progress: [%3i%%]"), (int)percentage
);
25 if(percentage
< (last_reported_progress
+ reporting_steps
))
31 PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd
)
33 OutStatusFd
= progress_fd
;
36 void PackageManagerProgressFd::Started()
38 _config
->Set("APT::Keep-Fds::", OutStatusFd
);
40 // send status information that we are about to fork dpkg
42 std::ostringstream status
;
43 status
<< "pmstatus:dpkg-exec:"
44 << (StepsDone
/float(StepsTotal
)*100.0)
45 << ":" << _("Running dpkg")
47 FileFd::Write(OutStatusFd
, status
.str().c_str(), status
.str().size());
51 void PackageManagerProgressFd::Finished()
53 // clear the Keep-Fd again
54 _config
->Clear("APT::Keep-Fds", OutStatusFd
);
57 void PackageManagerProgressFd::Error(std::string PackageName
,
58 unsigned int StepsDone
,
59 unsigned int TotalSteps
,
60 std::string ErrorMessage
)
62 std::ostringstream status
;
63 status
<< "pmerror:" << PackageName
64 << ":" << (StepsDone
/float(TotalSteps
)*100.0)
65 << ":" << ErrorMessage
68 FileFd::Write(OutStatusFd
, status
.str().c_str(), status
.str().size());
71 void PackageManagerProgressFd::ConffilePrompt(std::string PackageName
,
72 unsigned int StepsDone
,
73 unsigned int TotalSteps
,
74 std::string ConfMessage
)
76 std::ostringstream status
;
77 status
<< "pmconffile:" << PackageName
78 << ":" << (StepsDone
/float(TotalSteps
)*100.0)
82 FileFd::Write(OutStatusFd
, status
.str().c_str(), status
.str().size());
86 bool PackageManagerProgressFd::StatusChanged(std::string PackageName
,
87 unsigned int xStepsDone
,
88 unsigned int xTotalSteps
,
89 std::string pkg_action
)
91 StepsDone
= xStepsDone
;
92 StepsTotal
= xTotalSteps
;
94 // build the status str
95 std::ostringstream status
;
96 status
<< "pmstatus:" << PackageName
97 << ":" << (StepsDone
/float(StepsTotal
)*100.0)
101 FileFd::Write(OutStatusFd
, status
.str().c_str(), status
.str().size());
105 void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows
)
107 // scroll down a bit to avoid visual glitch when the screen
108 // area shrinks by one row
112 std::cout
<< "\033[s";
114 // set scroll region (this will place the cursor in the top left)
115 std::cout
<< "\033[1;" << nr_rows
- 1 << "r";
117 // restore cursor but ensure its inside the scrolling area
118 std::cout
<< "\033[u";
119 static const char *move_cursor_up
= "\033[1A";
120 std::cout
<< move_cursor_up
;
122 std::flush(std::cout
);
125 PackageManagerFancy::PackageManagerFancy()
126 : nr_terminal_rows(-1)
129 if(ioctl(STDOUT_FILENO
, TIOCGWINSZ
, (char *)&win
) == 0)
131 nr_terminal_rows
= win
.ws_row
;
135 void PackageManagerFancy::Started()
137 if (nr_terminal_rows
> 0)
138 SetupTerminalScrollArea(nr_terminal_rows
);
141 void PackageManagerFancy::Finished()
143 if (nr_terminal_rows
> 0)
145 SetupTerminalScrollArea(nr_terminal_rows
+ 1);
147 // override the progress line (sledgehammer)
148 static const char* clear_screen_below_cursor
= "\033[J";
149 std::cout
<< clear_screen_below_cursor
;
153 bool PackageManagerFancy::StatusChanged(std::string PackageName
,
154 unsigned int StepsDone
,
155 unsigned int TotalSteps
,
156 std::string HumanReadableAction
)
158 if (!PackageManager::StatusChanged(PackageName
, StepsDone
, TotalSteps
,
159 HumanReadableAction
))
162 int row
= nr_terminal_rows
;
164 static string save_cursor
= "\033[s";
165 static string restore_cursor
= "\033[u";
167 static string set_bg_color
= "\033[42m"; // green
168 static string set_fg_color
= "\033[30m"; // black
170 static string restore_bg
= "\033[49m";
171 static string restore_fg
= "\033[39m";
173 std::cout
<< save_cursor
174 // move cursor position to last row
175 << "\033[" << row
<< ";0f"
182 std::flush(std::cout
);
183 last_reported_progress
= percentage
;
188 bool PackageManagerText::StatusChanged(std::string PackageName
,
189 unsigned int StepsDone
,
190 unsigned int TotalSteps
,
191 std::string HumanReadableAction
)
193 if (!PackageManager::StatusChanged(PackageName
, StepsDone
, TotalSteps
, HumanReadableAction
))
196 std::cout
<< progress_str
<< "\r\n";
197 std::flush(std::cout
);
199 last_reported_progress
= percentage
;
205 }; // namespace progress