source: src-qt4/pc-softwaremanager/processManager.cpp @ c71b68c

9.2-releaseenter/10releng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1releng/10.1.1releng/10.1.2releng/10.2
Last change on this file since c71b68c was c71b68c, checked in by Ken Moore <ken@…>, 2 years ago

Add a bunch of error loggin to the backend processes, and also add a new dialog for displaying these error logs. Also fix the detection of an update failure.

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/***************************************************************************
2 *   Copyright (C) 2011 - iXsystems                                       *
3 *   kris@pcbsd.org  *
4 *   tim@pcbsd.org   *
5 *   ken@pcbsd.org   *
6 *                                                                         *
7 *   Permission is hereby granted, free of charge, to any person obtaining *
8 *   a copy of this software and associated documentation files (the       *
9 *   "Software"), to deal in the Software without restriction, including   *
10 *   without limitation the rights to use, copy, modify, merge, publish,   *
11 *   distribute, sublicense, and/or sell copies of the Software, and to    *
12 *   permit persons to whom the Software is furnished to do so, subject to *
13 *   the following conditions:                                             *
14 *                                                                         *
15 *   The above copyright notice and this permission notice shall be        *
16 *   included in all copies or substantial portions of the Software.       *
17 *                                                                         *
18 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
19 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
20 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
21 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
22 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
23 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
24 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
25 ***************************************************************************/
26 #include "processManager.h"
27
28ProcessManager::ProcessManager(){
29  //Get the system environment for all the processes
30  QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
31    env.insert("PBI_FETCH_PARSING","YES"); //For readable download notifications
32    //Initialize the UPDATE Process
33    upProc = new QProcess; upProc->setProcessEnvironment(env);
34    upProc->setProcessChannelMode(QProcess::MergedChannels);
35    connect(upProc, SIGNAL(readyRead()),this,SLOT(slotUpProcMessage()) );
36    connect(upProc, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slotUpProcFinished()) );
37    //Initialize the REMOVE Process
38    remProc = new QProcess; remProc->setProcessEnvironment(env);
39    remProc->setProcessChannelMode(QProcess::MergedChannels);
40    connect(remProc, SIGNAL(readyRead()),this,SLOT(slotRemProcMessage()) );
41    connect(remProc, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slotRemProcFinished()) );
42    //Initialize the DOWNLOAD Process
43    dlProc = new QProcess; dlProc->setProcessEnvironment(env);
44    dlProc->setProcessChannelMode(QProcess::MergedChannels);
45    connect(dlProc, SIGNAL(readyRead()),this,SLOT(slotDlProcMessage()) );
46    connect(dlProc, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slotDlProcFinished()) );
47    //Initialize the INSTALL Process
48    inProc = new QProcess; inProc->setProcessEnvironment(env);
49    inProc->setProcessChannelMode(QProcess::MergedChannels);
50    connect(inProc, SIGNAL(readyRead()),this,SLOT(slotInProcMessage()) );
51    connect(inProc, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slotInProcFinished()) );
52    //Initialize the OTHER Process
53    otProc = new QProcess; otProc->setProcessEnvironment(env);
54    connect(otProc, SIGNAL(readyReadStandardOutput()),this,SLOT(slotOtProcMessage()) );
55    connect(otProc, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slotOtProcFinished()) );
56}
57
58ProcessManager::~ProcessManager(){
59}
60
61void ProcessManager::goToDirectory(ProcessID ID, QString dir){
62  if( ID == UPDATE ){
63    upProc->setWorkingDirectory(dir);     
64  }else if( ID == REMOVE ){
65    remProc->setWorkingDirectory(dir);           
66  }else if( ID == DOWNLOAD ){
67    dlProc->setWorkingDirectory(dir);     
68  }else if( ID == INSTALL ){
69    inProc->setWorkingDirectory(dir);             
70  }else if( ID == OTHER ){
71    otProc->setWorkingDirectory(dir);             
72  }     
73}
74// =========================
75// ===== PUBLIC ACCESS =====
76// =========================
77void ProcessManager::startProcess(ProcessID ID, QString cmd){
78  if( ID == UPDATE ){
79    qDebug() << "Update Process Started:" << cmd;
80    upLog.clear(); //clear the log for action
81    upProc->start(cmd);   
82  }else if( ID == REMOVE ){
83    qDebug() << "Removal Process Started:" << cmd;
84    remLog.clear();
85    remProc->start(cmd);                 
86  }else if( ID == DOWNLOAD ){
87    qDebug() << "Download Process Started:" << cmd;
88    dlLog.clear();
89    dlProc->start(cmd);           
90  }else if( ID == INSTALL ){
91    qDebug() << "Install Process Started:" << cmd;
92    inLog.clear();
93    inProc->start(cmd);           
94  }else if( ID == OTHER ){
95    qDebug() << "Other Process Started:" << cmd;
96    otProc->start(cmd);           
97  }
98       
99}
100
101void ProcessManager::stopProcess(ProcessID ID){
102  if((ID == ALL) || (ID == UPDATE)){
103    upProc->terminate();         
104  }
105  if((ID == ALL) || (ID == REMOVE)){
106    remProc->terminate();         
107  }
108  if((ID == ALL) || (ID == DOWNLOAD)){
109    dlProc->terminate();         
110  }
111  if((ID == ALL) || (ID == INSTALL)){
112    inProc->terminate();         
113  }
114  if((ID == ALL) || (ID == OTHER)){
115    otProc->terminate();         
116  }     
117}
118
119QStringList ProcessManager::getProcessLog(ProcessID ID){
120  if( ID == UPDATE ){ return upLog; }
121  else if( ID == REMOVE ){ return remLog; }
122  else if( ID == DOWNLOAD ){ return dlLog; }
123  else if( ID == INSTALL ){ return inLog; }
124  else{ return QStringList(); }
125}
126
127// =========================
128// ===== PRIVATE SLOTS =====
129// =========================
130QString ProcessManager::parseDlLine(QString line){
131  QString out;
132  if(!line.startsWith("SIZE:")){ return out; }
133  //qDebug() << "parse Download Line:" << line;
134  //Line format: SIZE:  <KB> DOWNLOADED:  <KB> SPEED:  <KB/s> KB/s
135  line = line.simplified();
136  line.replace("SIZE: ","");
137  line.replace("DOWNLOADED: ", "");
138  line.replace("SPEED: ","");
139  line.replace("KB/s","");
140  bool totok, curok, spdok;
141  double tot, cur, spd;
142  tot = line.section(" ",0,0).toDouble(&totok);
143  cur = line.section(" ",1,1).toDouble(&curok);
144  spd = line.section(" ",2,2).toDouble(&spdok);
145  //qDebug() << " - DownloadStats:" << tot << cur << spd;
146  if(totok && tot==0){totok=FALSE;}
147  if(curok && cur==0){curok=FALSE;}
148  if(spdok && spd==0){spdok=FALSE;}
149  //Now format the output string
150  QString stats;
151  if(totok && curok){
152    bool totErr = (tot==cur); //catch for a display error where the cur is always identical to the tot
153    int i=0;
154    QStringList lab; lab << "KB" <<"MB"<<"GB"<<"TB"<<"PB";
155    while( (tot>1000) && (i<lab.length()) ){
156      cur=cur/1024; tot=tot/1024; i++;
157    }
158    float percent = (cur*100)/tot;
159    //round all numbers to one decimel place
160    percent = int(percent*10)/10.0;
161    cur = int(cur*10)/10.0;
162    tot = int(tot*10)/10.0;
163    if(totErr){ // cur==tot
164      stats = QString::number(tot)+" "+lab[i];
165    }else{
166      stats = QString::number(cur)+"/"+QString::number(tot)+" "+lab[i]+" ("+QString::number(percent)+"%)";
167    }
168    // Format:  <current>/<total> <size label> (<percent>%)
169  }else if(curok){
170    stats = Extras::sizeKToDisplay(QString::number(cur));
171  }
172  QString speed;
173  if(spdok){
174    speed = Extras::sizeKToDisplay(QString::number(spd))+"/s";   
175  }
176  //Now put the output string together and return it
177  if(stats.isEmpty() && speed.isEmpty()){}
178  else if(stats.isEmpty()){ out = speed; }
179  else if(speed.isEmpty()){ out = stats; }
180  else{ out = QString( tr("%1 at %2") ).arg(stats,speed); }
181  //qDebug() << " - Result:" << out;
182  return out;
183}
184
185// == UPDATE PROCESS ==
186void ProcessManager::slotUpProcMessage(){
187  while( upProc->canReadLine() ){
188    QString line = upProc->readLine().simplified();
189    if(line.isEmpty()){ continue; }
190    QString dl = parseDlLine(line);
191    if(!dl.isEmpty()){ emit ProcessMessage(UPDATE,dl); }
192    else{ upLog << line; } //not a download line - add to the log
193  }
194}
195
196void ProcessManager::slotUpProcFinished(){
197  if(upProc->exitStatus() != QProcess::NormalExit){
198    //Emit the command log
199    qDebug() << "Update Process Error Log:\n"<<upLog.join("\n");
200    emit ProcessError(UPDATE, upLog);
201  }else{
202    qDebug() << "Update Process Finished";
203    emit ProcessFinished(UPDATE);         
204  }
205}
206
207// == REMOVE PROCESS ==
208void ProcessManager::slotRemProcMessage(){
209  while( remProc->canReadLine() ){
210    QString line = remProc->readLine().simplified();
211    if(!line.isEmpty()){ 
212      remLog << line; 
213      emit ProcessMessage(REMOVE,line);
214    }
215  }
216}
217
218void ProcessManager::slotRemProcFinished(){
219  if(remProc->exitStatus() != QProcess::NormalExit){
220    qDebug() << "Removal Process Error Log:\n"<<remLog.join("\n");
221    emit ProcessError(REMOVE, remLog);
222  }else{
223    qDebug() << "Removal Process Finished";
224    emit ProcessFinished(REMOVE);         
225  }
226}
227
228// == DOWNLOAD PROCESS ==
229void ProcessManager::slotDlProcMessage(){
230  while( dlProc->canReadLine() ){
231    QString line = dlProc->readLine().simplified();
232    if(line.isEmpty()){ continue; }
233    QString dl = parseDlLine(line);
234    if(!dl.isEmpty()){ emit ProcessMessage(DOWNLOAD,dl); }
235    else{ dlLog << line; } //not a download line - add to the log
236  }
237}
238
239void ProcessManager::slotDlProcFinished(){
240  if(dlProc->exitStatus() != QProcess::NormalExit){
241    qDebug() << "Download Process Error Log:\n"<<dlLog.join("\n");
242    emit ProcessError(DOWNLOAD, dlLog);
243  }else{
244    qDebug() << "Download Process Finished";
245    emit ProcessFinished(DOWNLOAD);       
246  }
247}
248
249// == INSTALL PROCESS ==
250void ProcessManager::slotInProcMessage(){
251  while( inProc->canReadLine() ){
252    QString line = inProc->readLine().simplified();
253    if(!line.isEmpty()){ 
254      inLog << line; 
255      emit ProcessMessage(INSTALL,line);
256    }
257  }
258}
259
260void ProcessManager::slotInProcFinished(){
261  if(inProc->exitStatus() != QProcess::NormalExit){
262    qDebug() << "Install Process Error Log:\n"<<inLog.join("\n");
263    emit ProcessError(INSTALL, inLog);
264  }else{
265    qDebug() << "Install Process Finished";
266    emit ProcessFinished(INSTALL);       
267  }
268}
269
270// == OTHER PROCESS ==
271void ProcessManager::slotOtProcMessage(){
272  QString msg = otProc->readAllStandardOutput();
273  emit ProcessMessage(OTHER,msg);
274}
275
276void ProcessManager::slotOtProcFinished(){
277  if(otProc->exitStatus() != QProcess::NormalExit){
278    QString msg = otProc->readAllStandardError();
279    if(msg.isEmpty()){ msg = otProc->readAllStandardOutput(); }
280    if(msg.isEmpty()){ msg = tr("Unknown Error"); }
281    qDebug() << "Other Process Error:"<<msg;
282    emit ProcessError(OTHER, QStringList(msg));
283  }else{
284    qDebug() << "Other Process Finished";
285    emit ProcessFinished(OTHER);         
286  }
287}
288
Note: See TracBrowser for help on using the repository browser.