X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fqt-console%2Fjob%2Fjob.cpp;h=73926fc0915bde54ea8cde4b0158144a47eeccb4;hb=036d4345007abbaf5063b8ae709617b2803fd33b;hp=5c8568ba1e2c632f2bd2185725d350cf634c6ad8;hpb=a9f64b710534b13114e04f119aecac91471f8165;p=bacula%2Fbacula diff --git a/bacula/src/qt-console/job/job.cpp b/bacula/src/qt-console/job/job.cpp index 5c8568ba1e..73926fc091 100644 --- a/bacula/src/qt-console/job/job.cpp +++ b/bacula/src/qt-console/job/job.cpp @@ -6,7 +6,7 @@ The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or - modify it under the terms of version two of the GNU General Public + modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. @@ -15,7 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -26,39 +26,56 @@ Switzerland, email:ftf@fsfeurope.org. */ -/* - * Version $Id$ - * - * Job Class - * - * Dirk Bartley, March 2007 - * - */ - #include "bat.h" #include "job.h" #include "util/fmtwidgetitem.h" +#include "mediainfo/mediainfo.h" +#include "run/run.h" Job::Job(QString &jobId, QTreeWidgetItem *parentTreeWidgetItem) { setupUi(this); - m_closeable = true; pgInitialize(tr("Job"), parentTreeWidgetItem); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/joblog.png"))); m_cursor = new QTextCursor(textJobLog->document()); + m_bwlimit = 0; m_jobId = jobId; + m_timer = NULL; getFont(); connect(pbRefresh, SIGNAL(clicked()), this, SLOT(populateAll())); connect(pbDelete, SIGNAL(clicked()), this, SLOT(deleteJob())); + connect(pbCancel, SIGNAL(clicked()), this, SLOT(cancelJob())); + connect(pbRun, SIGNAL(clicked()), this, SLOT(rerun())); + connect(list_Volume, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(showInfoVolume(QListWidgetItem *))); + connect(spin_Bwlimit, SIGNAL(valueChanged(int)), this, SLOT(storeBwLimit(int))); populateAll(); dockPage(); setCurrent(); } +void Job::rerun() +{ + new runPage(label_Name->text(), + label_Level->text(), + label_Pool->text(), + QString(""), // storage + label_Client->text(), + label_FileSet->text()); +} + +void Job::showInfoVolume(QListWidgetItem *item) +{ + QString s= item->text(); + QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this); + + MediaInfo *m = new MediaInfo(pageSelectorTreeWidgetItem, s); + connect(m, SIGNAL(destroyed()), this, SLOT(populateTree())); +} + void Job::deleteJob() { if (QMessageBox::warning(this, "Bat", @@ -79,6 +96,18 @@ void Job::deleteJob() closeStackPage(); } +void Job::cancelJob() +{ + if (QMessageBox::warning(this, "Bat", + tr("Are you sure you want to cancel this job?"), + QMessageBox::Ok | QMessageBox::Cancel) + == QMessageBox::Cancel) { return; } + + QString cmd("cancel jobid="); + cmd += m_jobId; + consoleCommand(cmd, false); +} + void Job::getFont() { QFont font = textJobLog->font(); @@ -96,7 +125,7 @@ void Job::getFont() void Job::populateAll() { - Pmsg0(0, "populateAll()\n"); +// Pmsg0(50, "populateAll()\n"); populateText(); populateForm(); populateVolumes(); @@ -122,9 +151,9 @@ void Job::populateText() if (!results.size()) { QMessageBox::warning(this, tr("Bat"), tr("There were no results!\n" - "It is possible you may need to add \"catalog = all\" " - "to the Messages resource for this job.\n"), QMessageBox::Ok); - return; + "It is possible you may need to add \"catalog = all\" " + "to the Messages resource for this job.\n"), QMessageBox::Ok); + return; } QString jobstr("JobId "); /* FIXME: should this be translated ? */ @@ -139,47 +168,47 @@ void Job::populateText() QString lastSvc; foreach (QString resultline, results) { fieldlist = resultline.split("\t"); - - if (fieldlist.size() < 2) - continue; - - QString curTime = fieldlist[0].trimmed(); - - field = fieldlist[1].trimmed(); - int colon = field.indexOf(":"); - if (colon > 0) { - /* string is like : ..." - * we split at ':' then remove the jobId xxxx string (always the same) */ - QString curSvc(field.left(colon).replace(jobstr,"").trimmed()); - if (curSvc == lastSvc && curTime == lastTime) { - curTime.clear(); - curSvc.clear(); - } else { - lastTime = curTime; - lastSvc = curSvc; - } -// htmlbuf += "" + curTime + ""; - htmlbuf += "\n" + curSvc + " "; - - /* rest of string is marked as pre-formatted (here trimming should - * be avoided, to preserve original formatting) */ - QString msg(field.mid(colon+2)); - if (msg.startsWith( tr("Error:")) ) { /* FIXME: should really be translated ? */ - /* error msg, use a specific class */ - htmlbuf += "
" + msg + "
";
-	    } else {
-	       htmlbuf += msg ;
-	    }
-	 } else {
- 	    /* non standard string, place as-is */
-	    if (curTime == lastTime) {
-	       curTime.clear();
-	    } else {
-	       lastTime = curTime;
-	    }
-//	    htmlbuf += "" + curTime + "";
-	    htmlbuf += "\n" + field ;
-	 }
+         
+         if (fieldlist.size() < 2)
+            continue;
+
+         QString curTime = fieldlist[0].trimmed();
+
+         field = fieldlist[1].trimmed();
+         int colon = field.indexOf(":");
+         if (colon > 0) {
+            /* string is like  : ..." 
+             * we split at ':' then remove the jobId xxxx string (always the same) */ 
+            QString curSvc(field.left(colon).replace(jobstr,"").trimmed());
+            if (curSvc == lastSvc  && curTime == lastTime) {
+               curTime.clear();
+               curSvc.clear(); 
+            } else {
+               lastTime = curTime;
+               lastSvc = curSvc;
+            }
+//          htmlbuf += "" + curTime + "";
+            htmlbuf += "\n" + curSvc + " ";
+
+            /* rest of string is marked as pre-formatted (here trimming should
+             * be avoided, to preserve original formatting) */
+            QString msg(field.mid(colon+2));
+            if (msg.startsWith( tr("Error:")) ) { /* FIXME: should really be translated ? */
+               /* error msg, use a specific class */
+               htmlbuf += "
" + msg + "
";
+            } else {
+               htmlbuf += msg ;
+            }
+         } else {
+            /* non standard string, place as-is */
+            if (curTime == lastTime) {
+               curTime.clear();
+            } else {
+               lastTime = curTime;
+            }
+//          htmlbuf += "" + curTime + "";
+            htmlbuf += "\n" + field ;
+         }
   
       } /* foreach resultline */
 
@@ -195,50 +224,98 @@ void Job::populateText()
   
 }
 
-// Need to use the fmtwidgetitem helper instead
-QString convertBytesSI(qint64 qfld)
+void Job::storeBwLimit(int val)
 {
-   static const qint64 KB = Q_INT64_C(1000);
-   static const qint64 MB = (KB * KB);
-   static const qint64 GB = (MB * KB);
-   static const qint64 TB = (GB * KB);
-   static const qint64 PB = (TB * KB);
-   static const qint64 EB = (PB * KB);
-
-   /* note: division is integer, so to have some decimals we divide for a
-      smaller unit (e.g. GB for a TB number and so on) */
-   char suffix;
-   if (qfld >= EB) {
-      qfld /= PB; 
-      suffix = 'E';
-   }
-   else if (qfld >= PB) {
-      qfld /= TB; 
-      suffix = 'P';
-   }
-   else if (qfld >= TB) {
-      qfld /= GB; 
-      suffix = 'T';
-   }
-   else if (qfld >= GB) {
-      qfld /= MB;
-      suffix = 'G';
-   }
-   else if (qfld >= MB) {
-      qfld /= KB;
-      suffix = 'M';
-   }
-   else if (qfld >= KB) {
-      suffix = 'k'; /* SI uses lowercase k */
-   }
-   else  {
-      /* plain bytes, no need to reformat */
-      return QString("%1 B").arg(qfld); 
+   m_bwlimit = val;
+}
+
+void Job::updateRunInfo()
+{
+   QString cmd;
+   QStringList results;
+   QStringList lst;
+   bool parseit=false;
+   QChar equal = '=';
+
+   if (m_bwlimit >= 100) {
+      cmd = QString("setbandwidth limit=" + QString::number(m_bwlimit) 
+                    + " jobid=" + m_jobId);
+      m_console->dir_cmd(cmd, results);
+      results.clear();
+      m_bwlimit = 0;
    }
 
-   /* having divided for a smaller unit, now we can safely convert to double and
-      use the extra room for decimals */
-   return QString("%1 %2B").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
+   cmd = QString(".status client=\"" + m_client + "\" running");
+
+   if (m_console->dir_cmd(cmd, results)) {
+      foreach (QString mline, results) {
+         foreach (QString line, mline.split("\n")) { 
+            line = line.trimmed();
+            lst = line.split(equal);
+            if (lst.count() != 2) {
+               Pmsg1(0, "bad count=%d\n",lst.count());
+               continue;
+            }
+            
+            if (lst[0] == "JobId") {
+               if (lst[1] == m_jobId) {
+                  parseit = true;
+               } else {
+                  parseit = false;
+               }
+            }
+            if (!parseit) {
+               continue;
+            }
+            
+//         } else if (lst[0] == "Job") {
+//            grpRun->setTitle(lst[1]);
+            
+//               
+//         } else if (lst[0] == "VSS") {
+
+//         } else if (lst[0] == "Level") {
+//            Info->setText(lst[1]);
+//
+//         } else if (lst[0] == "JobType") {
+//
+//         } else if (lst[0] == "JobStarted") {
+//            Started->setText(lst[1]);
+
+            if (lst[0] == "Bwlimit") {
+               int val = lst[1].toInt();
+               if (val > 0) {
+                  chk_Bwlimit->setChecked(true);
+                  spin_Bwlimit->setEnabled(true);
+                  spin_Bwlimit->setValue(lst[1].toInt()/1024);
+               } else {
+                  chk_Bwlimit->setEnabled(false);
+                  spin_Bwlimit->setEnabled(false);
+                  spin_Bwlimit->setValue(0);
+               }
+               
+//         } else if (lst[0] == "Errors") {
+//            Errors->setText(lst[1]);
+               
+            } else if (lst[0] == "Bytes/sec") {
+               label_Speed->setText(convertBytesSI(lst[1].toULongLong())+"/s");
+               
+            } else if (lst[0] == "Files") {
+               label_JobFiles->setText(lst[1]);
+               
+            } else if (lst[0] == "Bytes") {
+               label_JobBytes->setText(convertBytesSI(lst[1].toULongLong()));
+               
+            } else if (lst[0] == "FilesExamined") {
+               label_FilesExamined->setText(lst[1]);
+               
+            } else if (lst[0] == "ProcessingFile") {
+               label_CurrentFile->setText(lst[1]);
+               
+            }
+         }
+      }
+   }
 }
 
 /*
@@ -246,17 +323,19 @@ QString convertBytesSI(qint64 qfld)
  */
 void Job::populateForm()
 {
-   QString stat;
+   QString stat, err;
    char buf[256];
    QString query = 
-      "SELECT JobId, Job.Name, Level, Client.Name, Pool.Name, FileSet, SchedTime, StartTime, EndTime, "
-      "EndTime - StartTime AS Duration, JobBytes, JobFiles, JobErrors, JobStatus, PurgedFiles "
-      "FROM Job JOIN Client USING (ClientId) LEFT JOIN Pool USING (PoolId) "
-      "LEFT JOIN FileSet USING (FileSetId)"
+      "SELECT JobId, Job.Name, Level, Client.Name, Pool.Name, FileSet,"
+      "SchedTime, StartTime, EndTime, EndTime-StartTime AS Duration, "
+      "JobBytes, JobFiles, JobErrors, JobStatus, PurgedFiles "
+      "FROM Job JOIN Client USING (ClientId) "
+        "LEFT JOIN Pool ON (Job.PoolId = Pool.PoolId) "
+        "LEFT JOIN FileSet ON (Job.FileSetId = FileSet.FileSetId)"
       "WHERE JobId=" + m_jobId; 
    QStringList results;
    if (m_console->sql_cmd(query, results)) {
-      QString resultline;
+      QString resultline, duration;
       QStringList fieldlist;
 
       foreach (resultline, results) { // should have only one result
@@ -267,19 +346,53 @@ void Job::populateForm()
          
          label_Level->setText(job_level_to_str(fld.next()[0].toAscii()));
 
-         label_Client->setText(fld.next());
+         m_client = fld.next();
+         label_Client->setText(m_client);
          label_Pool->setText(fld.next());
          label_FileSet->setText(fld.next());
          label_SchedTime->setText(fld.next());
          label_StartTime->setText(fld.next());
          label_EndTime->setText(fld.next());
-         label_Duration->setText(fld.next());
+         duration = fld.next();
+         /* 
+          * Note: if we have a negative duration, it is because the EndTime
+          *  is zero (i.e. the Job is still running).  We should use 
+          *  duration = StartTime - current_time
+          */
+         if (duration.left(1) == "-") {
+            duration = "0.0";
+         }
+         label_Duration->setText(duration);
 
          label_JobBytes->setText(convertBytesSI(fld.next().toULongLong()));
          label_JobFiles->setText(fld.next());
-         label_JobErrors->setText(fld.next());
-
-         stat=fld.next();
+         err = fld.next();
+         label_JobErrors->setText(err);
+
+         stat = fld.next();
+         if (stat == "T" && err.toInt() > 0) {
+            stat = "W";
+         }
+         if (stat == "R") {
+            pbDelete->setVisible(false);
+            pbCancel->setVisible(true);
+            grpRun->setVisible(true);
+            if (!m_timer) {
+               m_timer = new QTimer(this);
+               connect(m_timer, SIGNAL(timeout()), this, SLOT(populateAll()));
+               m_timer->start(30000);
+            }
+            updateRunInfo();
+         } else {
+            pbDelete->setVisible(true);
+            pbCancel->setVisible(false);
+            grpRun->setVisible(false);
+            if (m_timer) {
+               m_timer->stop();
+               delete m_timer;
+               m_timer = NULL;
+            }
+         }
          label_JobStatus->setPixmap(QPixmap(":/images/" + stat + ".png"));
          jobstatus_to_ascii_gui(stat[0].toAscii(), buf, sizeof(buf));
          stat = buf;
@@ -297,7 +410,7 @@ void Job::populateVolumes()
       "SELECT DISTINCT VolumeName, InChanger, Slot "
       "FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) "
       "WHERE JobId=" + m_jobId + " ORDER BY VolumeName "; 
-   Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
+   if (mainWin->m_sqlDebug) Pmsg1(0, "Query cmd : %s\n",query.toUtf8().data());
          
 
    QStringList results;