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.
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.
#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();
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();
}
+void Job::storeBwLimit(int val)
+{
+ 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;
+ }
+
+ 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]);
+
+ }
+ }
+ }
+ }
+}
+
/*
* Populate the text in the window
*/
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
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());
+ err = fld.next();
+ label_JobErrors->setText(err);
- stat=fld.next();
+ 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;