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

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since 31283ea was 31283ea, checked in by Ken Moore <ken@…>, 14 months ago

Lower the error detection on the "Other" process channel, we expect some of the command here to fail if the PBI does not support things like desktop/menu entries, mim types, etc..)

  • Property mode set to 100644
File size: 11.3 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// =========================
76// ===== PUBLIC ACCESS =====
77// =========================
78void ProcessManager::startProcess(ProcessID ID, QString cmd){
79  if( ID == UPDATE ){
80    qDebug() << "Update Process Started:" << cmd;
81    upLog.clear(); //clear the log for action
82    upProc->start(cmd);   
83  }else if( ID == REMOVE ){
84    qDebug() << "Removal Process Started:" << cmd;
85    remLog.clear();
86    remProc->start(cmd);                 
87  }else if( ID == DOWNLOAD ){
88    qDebug() << "Download Process Started:" << cmd;
89    dlLog.clear();
90    dlProc->start(cmd);           
91  }else if( ID == INSTALL ){
92    qDebug() << "Install Process Started:" << cmd;
93    inLog.clear();
94    inProc->start(cmd);           
95  }else if( ID == OTHER ){
96    qDebug() << "Other Process Started:" << cmd;
97    otProc->start(cmd);           
98  }
99       
100}
101
102void ProcessManager::stopProcess(ProcessID ID){
103  if((ID == ALL) || (ID == UPDATE)){
104    upProc->terminate();         
105  }
106  if((ID == ALL) || (ID == REMOVE)){
107    remProc->terminate();         
108  }
109  if((ID == ALL) || (ID == DOWNLOAD)){
110    dlProc->terminate();         
111  }
112  if((ID == ALL) || (ID == INSTALL)){
113    inProc->terminate();         
114  }
115  if((ID == ALL) || (ID == OTHER)){
116    otProc->terminate();         
117  }     
118}
119
120QStringList ProcessManager::getProcessLog(ProcessID ID){
121  if( ID == UPDATE ){ return upLog; }
122  else if( ID == REMOVE ){ return remLog; }
123  else if( ID == DOWNLOAD ){ return dlLog; }
124  else if( ID == INSTALL ){ return inLog; }
125  else{ return QStringList(); }
126}
127
128// =========================
129// ===== PRIVATE SLOTS =====
130// =========================
131QString ProcessManager::parseDlLine(QString line){
132  /*DOWNLOAD NOTIFICATION CODES:
133  Download complete: "DLDONE"
134  Download running: "DLSTAT::<percent>::<total size>::<download speed>"
135        -- A value of "??" means that it is unknown
136  Download starting: "DLSTART"
137  */
138  QString out;
139  if( line.startsWith("FETCH:") ){ return "DLSTART"; }
140  else if( line == "FETCHDONE"){ return "DLDONE"; }
141  else if(!line.startsWith("SIZE:")){ return out; }
142  //qDebug() << "parse Download Line:" << line;
143  //Line format: SIZE:  <KB> DOWNLOADED:  <KB> SPEED:  <KB/s> KB/s
144  line = line.simplified();
145  line.replace("SIZE: ","");
146  line.replace("DOWNLOADED: ", "");
147  line.replace("SPEED: ","");
148  line.replace("KB/s","");
149  bool totok, curok, spdok;
150  double tot, cur, spd;
151  tot = line.section(" ",0,0).toDouble(&totok);
152  cur = line.section(" ",1,1).toDouble(&curok);
153  spd = line.section(" ",2,2).toDouble(&spdok);
154  //qDebug() << " - DownloadStats:" << tot << cur << spd;
155  if(totok && tot==0){totok=FALSE;}
156  if(curok && cur==0){curok=FALSE;}
157  if(spdok && spd==0){spdok=FALSE;}
158  //Now format the output string
159  QString stats;
160  out = "DLSTAT::";
161  //Get percent and totals
162  if(totok && curok){
163    bool totErr = (tot==cur); //catch for a display error where the cur is always identical to the tot
164    if(!totErr){         
165      //Calculate the percentage
166      double percent = (cur/tot)*100;
167      percent = int(percent*10)/10.0;
168      out.append(QString::number(percent)+"::");
169      //Now list the total
170      out.append( Extras::sizeKToDisplay(QString::number(tot)) +"::" );
171    }else{
172      //Only Total/Current is known (unknown percentage since not complete yet)
173      out.append("??::"+Extras::sizeKToDisplay(QString::number(tot))+"::");
174    }       
175  }else if(curok){
176    //Only Total/Current is known (unknown percentage since not complete yet)
177    out.append("??::"+Extras::sizeKToDisplay(QString::number(cur))+"::");
178  }else if(totok){
179    //Only Total/Current is known (unknown percentage since not complete yet)
180    out.append("??::"+Extras::sizeKToDisplay(QString::number(tot))+"::");
181  }else{
182    //Unknown Total and Current
183    out.append("??::??::");
184  }
185  //Now get the speed
186  if(spdok){
187    out.append( Extras::sizeKToDisplay(QString::number(spd))+"/s" );
188  }else{
189    out.append("??");
190  }
191  return out;
192}
193
194// == UPDATE PROCESS ==
195void ProcessManager::slotUpProcMessage(){
196  while( upProc->canReadLine() ){
197    QString line = upProc->readLine().simplified();
198    if(line.isEmpty()){ continue; }
199    QString dl = parseDlLine(line);
200    if(!dl.isEmpty()){ 
201      emit ProcessMessage(UPDATE,dl); //Download status
202      if( !dl.startsWith("DLSTAT::") ){
203        upLog << line; //not just a status update - add to the log (log download start/stop)   
204      }
205    }else{ 
206      emit ProcessMessage(UPDATE,line); 
207      upLog << line; //not a download line - add to the log
208    }
209  }
210}
211
212void ProcessManager::slotUpProcFinished(){
213  if(upProc->exitStatus() != QProcess::NormalExit || upProc->exitCode() != 0){
214    //Emit the command log
215    qDebug() << "Update Process Error Log:\n"<<upLog.join("\n");
216    emit ProcessError(UPDATE, upLog);
217  }else{
218    qDebug() << "Update Process Finished";
219    emit ProcessFinished(UPDATE);         
220  }
221}
222
223// == REMOVE PROCESS ==
224void ProcessManager::slotRemProcMessage(){
225  while( remProc->canReadLine() ){
226    QString line = remProc->readLine().simplified();
227    if(!line.isEmpty()){ 
228      remLog << line; 
229      emit ProcessMessage(REMOVE,line);
230    }
231  }
232}
233
234void ProcessManager::slotRemProcFinished(){
235  if(remProc->exitStatus() != QProcess::NormalExit || remProc->exitCode() != 0){
236    qDebug() << "Removal Process Error Log:\n"<<remLog.join("\n");
237    emit ProcessError(REMOVE, remLog);
238  }else{
239    qDebug() << "Removal Process Finished";
240    emit ProcessFinished(REMOVE);         
241  }
242}
243
244// == DOWNLOAD PROCESS ==
245void ProcessManager::slotDlProcMessage(){
246  while( dlProc->canReadLine() ){
247    QString line = dlProc->readLine().simplified();
248    if(line.isEmpty()){ continue; }
249    QString dl = parseDlLine(line);
250    if(!dl.isEmpty()){ 
251      emit ProcessMessage(DOWNLOAD,dl); //Download status
252      if( !dl.startsWith("DLSTAT::") ){
253        dlLog << line; //not just a status update - add to the log (log download start/stop)   
254      }
255    }else{ 
256      emit ProcessMessage(DOWNLOAD,line); 
257      dlLog << line; //not a download line - add to the log
258    }
259  }
260}
261
262void ProcessManager::slotDlProcFinished(){
263  if(dlProc->exitStatus() != QProcess::NormalExit || dlProc->exitCode() != 0){
264    qDebug() << "Download Process Error Log:\n"<<dlLog.join("\n");
265    emit ProcessError(DOWNLOAD, dlLog);
266  }else{
267    qDebug() << "Download Process Finished";
268    emit ProcessFinished(DOWNLOAD);       
269  }
270}
271
272// == INSTALL PROCESS ==
273void ProcessManager::slotInProcMessage(){
274  while( inProc->canReadLine() ){
275    QString line = inProc->readLine().simplified();
276    if(!line.isEmpty()){ 
277      inLog << line; 
278      emit ProcessMessage(INSTALL,line);
279    }
280  }
281}
282
283void ProcessManager::slotInProcFinished(){
284  if(inProc->exitStatus() != QProcess::NormalExit || inProc->exitCode() != 0){
285    qDebug() << "Install Process Error Log:\n"<<inLog.join("\n");
286    emit ProcessError(INSTALL, inLog);
287  }else{
288    qDebug() << "Install Process Finished";
289    emit ProcessFinished(INSTALL);       
290  }
291}
292
293// == OTHER PROCESS ==
294void ProcessManager::slotOtProcMessage(){
295  QString msg = otProc->readAllStandardOutput();
296  emit ProcessMessage(OTHER,msg);
297}
298
299void ProcessManager::slotOtProcFinished(){
300  if(otProc->exitStatus() != QProcess::NormalExit){
301    QString msg = otProc->readAllStandardError();
302    if(msg.isEmpty()){ msg = otProc->readAllStandardOutput(); }
303    if(msg.isEmpty()){ msg = tr("Unknown Error"); }
304    qDebug() << "Other Process Error:"<<msg;
305    emit ProcessError(OTHER, QStringList(msg));
306  }else{
307    qDebug() << "Other Process Finished";
308    emit ProcessFinished(OTHER);         
309  }
310}
311
Note: See TracBrowser for help on using the repository browser.