]> git.sur5r.net Git - bacula/bacula/commitdiff
bat: get a simple working brestore file browser using bvfs API
authorEric Bollengier <eric@eb.homelinux.org>
Fri, 1 Oct 2010 13:13:34 +0000 (15:13 +0200)
committerEric Bollengier <eric@eb.homelinux.org>
Wed, 6 Oct 2010 09:10:56 +0000 (11:10 +0200)
bacula/src/qt-console/bat.pro.in
bacula/src/qt-console/restore/brestore.cpp
bacula/src/qt-console/restore/brestore.ui
bacula/src/qt-console/restore/restore.h

index b22b3f15b219f390a411df98e85c0174eda5e91d..94b9b962e88bd3b97f410d62272324651cd3f525 100644 (file)
@@ -20,7 +20,7 @@ TEMPLATE     = app
 TARGET       = bat
 DEPENDPATH  += .
 INCLUDEPATH += .. . ./console ./restore ./select
-LIBS        += -L../lib -lbaccfg -lbac @OPENSSL_LIBS@
+LIBS        += -L../lib -lbaccfg -lbac -L../findlib -lbacfind @OPENSSL_LIBS@
 LIBTOOL_LINK = @QMAKE_LIBTOOL@ --silent --tag=CXX --mode=link
 LIBTOOL_INSTALL = @QMAKE_LIBTOOL@ --silent --mode=install
 QMAKE_LINK   = $${LIBTOOL_LINK} $(CXX)
index 240dc90344657371488519f3a95cb41a10f4077a..6f51d053321820cd78953cac3d222d327ab69f27 100644 (file)
@@ -27,7 +27,6 @@
 */
  
 /*
- *   Version $Id$
  *
  *  bRestore Class  (Eric's brestore)
  *
@@ -37,6 +36,7 @@
 
 #include "bat.h"
 #include "restore.h"
+#include "util/fmtwidgetitem.h"
 
 bRestore::bRestore()
 {
@@ -46,8 +46,8 @@ bRestore::bRestore()
    pgInitialize();
    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
    thisitem->setIcon(0, QIcon(QString::fromUtf8(":images/browse.png")));
-   dockPage();
    m_populated = false;
+   m_current = NULL;
 }
 
 void bRestore::setClient()
@@ -65,6 +65,7 @@ void bRestore::setClient()
    LocationEntry->clear();
 
    if (ClientList->currentIndex() < 1) {
+      JobList->setEnabled(false);
       return;
    }
 
@@ -82,13 +83,12 @@ void bRestore::setClient()
    QString job;
    QStringList results;
    if (m_console->sql_cmd(jobQuery, results)) {
-      QString field;
       QStringList fieldlist;
 
       /* Iterate through the record returned from the query */
       foreach (QString resultline, results) {
          fieldlist = resultline.split("\t");
-         job = fieldlist[1] + " " + fieldlist[3] + "(" + fieldlist[2] + ")";
+         job = fieldlist[1] + " " + fieldlist[3] + "(" + fieldlist[2] + ") " + fieldlist[0];
          JobList->addItem(job, QVariant(fieldlist[0]));
       }
    }
@@ -98,34 +98,109 @@ void bRestore::setClient()
 void bRestore::setJob()
 {
    if (JobList->currentIndex() < 1) {
+      FileList->clearContents();
+      FileList->setRowCount(0);
+      FileRevisions->clearContents();
+      FileRevisions->setRowCount(0);
       return ;
    }
    QStringList results;
    QVariant tmp = JobList->itemData(JobList->currentIndex(), Qt::UserRole);
-   m_jobids = tmp.toString(); 
-   QString cmd = ".bvfs_update jobid=" + m_jobids;
+
+   m_jobids = tmp.toString();
+   QString cmd = ".bvfs_get_jobids jobid=" + m_jobids;
    m_console->dir_cmd(cmd, results);
-   displayFiles("/");
-   Pmsg0(000, "update done\n");
-}
 
-void bRestore::displayFiles(uint64_t pathid)
-{
+   if (results.size() < 1) {
+      FileList->clearContents();
+      FileList->setRowCount(0);
+      FileRevisions->clearContents();
+      FileRevisions->setRowCount(0);
+      return;
+   }
 
+   m_jobids = results.at(0);
+   cmd = ".bvfs_update jobid=" + m_jobids;
+   m_console->dir_cmd(cmd, results);
+
+   Pmsg1(0, "jobids=%s\n", m_jobids.toLocal8Bit().constData());
+
+   displayFiles(0, "/");
+   Pmsg0(000, "update done\n");
 }
 
-void bRestore::displayFiles(QString path)
+extern int decode_stat(char *buf, struct stat *statp, int32_t *LinkFI);
+
+void bRestore::displayFiles(int64_t pathid, QString path)
 {
-   QString q = ".bvfs_lsdir jobid=" + m_jobids + " path=" + path;
+   QString arg;
    QStringList results;
+   QStringList fieldlist;
+   struct stat statp;
+   int32_t LinkFI;
+   int nb;
+   int row=0;
+   Freeze frz_lst(*FileList); /* disable updating*/
+   Freeze frz_rev(*FileRevisions); /* disable updating*/
+   FileList->clearContents();
+   FileRevisions->clearContents();
+   FileRevisions->setRowCount(0);
+
+   if (pathid > 0) {
+      arg = " pathid=" + QString().setNum(pathid);
+
+      if (path == "..") {
+         path = LocationEntry->text();
+         if (path != "/") {
+            LocationEntry->setText(path.remove(QRegExp("[^/]+/$")));
+         }
+      } else if (path != ".") {
+         LocationEntry->setText(LocationEntry->text() + path);
+      }
+   } else {
+      LocationEntry->setText(path);
+      arg = " path=\"" + path + "\"";
+   }
+
+   QString q = ".bvfs_lsdir jobid=" + m_jobids + arg;
    if (m_console->dir_cmd(q, results)) {
-      QString field;
-      QStringList fieldlist;
+      nb = results.size();
+      FileList->setRowCount(nb);
+      foreach (QString resultline, results) {
+         //PathId, FilenameId, fileid, jobid, lstat, path
+         Pmsg1(0, "dir=%s\n", resultline.toLocal8Bit().constData());
+         fieldlist = resultline.split("\t");
+         TableItemFormatter item(*FileList, row++);
+         item.setTextFld(0, resultline); // keep info
+         item.setFileType(1, QString("folder")); // folder or file
+         item.setTextFld(2, fieldlist.at(5)); // path
+         decode_stat(fieldlist.at(4).toLocal8Bit().data(), 
+                     &statp, &LinkFI);
+         item.setDateFld(4, statp.st_mtime); // date
+      }
+   }
 
+   results.clear();
+   q = ".bvfs_lsfiles jobid=" + m_jobids + arg;
+   if (m_console->dir_cmd(q, results)) {
+      FileList->setRowCount(results.size() + nb);
       foreach (QString resultline, results) {
+         //PathId, FilenameId, fileid, jobid, lstat, name
+         Pmsg1(0, "file=%s\n", resultline.toLocal8Bit().constData());
          fieldlist = resultline.split("\t");
+         TableItemFormatter item(*FileList, row++);
+         item.setTextFld(0, resultline); // keep info
+         item.setTextFld(2, fieldlist.at(5)); // path
+         decode_stat(fieldlist.at(4).toLocal8Bit().data(), 
+                     &statp, &LinkFI);
+         item.setBytesFld(3, QString().setNum(statp.st_size));
+         item.setDateFld(4, statp.st_mtime);
       }
    }
+   FileList->verticalHeader()->hide();
+   FileList->resizeColumnsToContents();
+   FileList->resizeRowsToContents();
+   FileList->setEditTriggers(QAbstractItemView::NoEditTriggers);
 }
 
 void bRestore::PgSeltreeWidgetClicked()
@@ -138,6 +213,78 @@ void bRestore::PgSeltreeWidgetClicked()
    }
 }
 
+void bRestore::displayFileVersion(QString pathid, QString fnid, QString client)
+{
+   int row=0;
+   struct stat statp;
+   int32_t LinkFI;
+   Freeze frz_rev(*FileRevisions); /* disable updating*/
+   FileRevisions->clearContents();
+   
+   QString q = ".bvfs_versions jobid=" + m_jobids +
+      " pathid=" + pathid + 
+      " fnid=" + fnid + 
+      " client=" + client;
+
+   if (VersionsChk->checkState() == Qt::Checked) {
+      q.append(" versions");
+   }
+
+   QStringList results;
+   QStringList fieldlist;
+
+   if (m_console->dir_cmd(q, results)) {
+      FileRevisions->setRowCount(results.size());
+      foreach (QString resultline, results) {
+         int col=0;
+         // 0        1          2        3      4    5      6        7
+         //PathId, FilenameId, fileid, jobid, lstat, Md5, VolName, Inchanger
+         Pmsg1(0, "dir=%s\n", resultline.toLocal8Bit().constData());
+         fieldlist = resultline.split("\t");
+         TableItemFormatter item(*FileRevisions, row++);
+         item.setTextFld(col++, resultline); // keep info
+         item.setInChanger(col++, fieldlist.at(7));    // inchanger
+         item.setTextFld(col++, fieldlist.at(6)); // Volume
+         item.setNumericFld(col++, fieldlist.at(3)); // JobId
+         decode_stat(fieldlist.at(4).toLocal8Bit().data(), 
+                     &statp, &LinkFI);
+         item.setBytesFld(col++, QString().setNum(statp.st_size)); // size
+         item.setDateFld(col++, statp.st_mtime); // date
+         item.setTextFld(col++, fieldlist.at(5)); // chksum
+      }
+   }
+   FileRevisions->verticalHeader()->hide();
+   FileRevisions->resizeColumnsToContents();
+   FileRevisions->resizeRowsToContents();
+   FileRevisions->setEditTriggers(QAbstractItemView::NoEditTriggers);
+}
+
+void bRestore::showInfoForFile(QTableWidgetItem *widget)
+{
+   m_current = widget;
+   QTableWidgetItem *first = FileList->item(widget->row(), 0);
+   QStringList lst = first->text().split("\t");
+   if (lst.at(1) == "0") {      // no filenameid, should be a path
+      displayFiles(lst.at(0).toLongLong(), lst.at(5));
+   } else {
+      displayFileVersion(lst.at(0), lst.at(1), m_client);
+   }
+}
+
+void bRestore::applyLocation()
+{
+   displayFiles(0, LocationEntry->text());
+}
+
+void bRestore::clearVersions(QTableWidgetItem *item)
+{
+   if (item != m_current) {
+      FileRevisions->clearContents();
+      FileRevisions->setRowCount(0);
+   }
+   m_current = item ;
+}
+
 void bRestore::setupPage()
 {
    Pmsg0(000, "Setup page\n");
@@ -145,6 +292,14 @@ void bRestore::setupPage()
    ClientList->addItems(m_console->client_list);
    connect(ClientList, SIGNAL(currentIndexChanged(int)), this, SLOT(setClient()));
    connect(JobList, SIGNAL(currentIndexChanged(int)), this, SLOT(setJob()));
+   connect(FileList, SIGNAL(itemClicked(QTableWidgetItem*)), 
+           this, SLOT(clearVersions(QTableWidgetItem *)));
+   connect(FileList, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), 
+           this, SLOT(showInfoForFile(QTableWidgetItem *)));
+   connect(LocationBp, SIGNAL(pressed()), this, SLOT(applyLocation()));
+   FileList->setColumnHidden(0, true);
+   FileRevisions->setColumnHidden(0, true);
+   RestoreList->setColumnHidden(0, true);
    m_populated = true;
 }
 
index c67b0202ab6463833dafd5d576134676847eff59..31f83836f172aa5028e394bc4fb270d693e6ea8c 100644 (file)
             <verstretch>5</verstretch>
            </sizepolicy>
           </property>
+          <property name="dragEnabled">
+           <bool>true</bool>
+          </property>
+          <property name="alternatingRowColors">
+           <bool>true</bool>
+          </property>
+          <property name="selectionBehavior">
+           <enum>QAbstractItemView::SelectRows</enum>
+          </property>
+          <property name="showGrid">
+           <bool>false</bool>
+          </property>
+          <property name="sortingEnabled">
+           <bool>false</bool>
+          </property>
+          <attribute name="verticalHeaderVisible">
+           <bool>false</bool>
+          </attribute>
+          <column>
+           <property name="text">
+            <string>Data</string>
+           </property>
+          </column>
           <column>
            <property name="text">
             <string>Type</string>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
+          <property name="dragEnabled">
+           <bool>true</bool>
+          </property>
+          <property name="alternatingRowColors">
+           <bool>true</bool>
+          </property>
+          <property name="selectionMode">
+           <enum>QAbstractItemView::SingleSelection</enum>
+          </property>
+          <property name="selectionBehavior">
+           <enum>QAbstractItemView::SelectRows</enum>
+          </property>
+          <property name="showGrid">
+           <bool>false</bool>
+          </property>
+          <column>
+           <property name="text">
+            <string>Data</string>
+           </property>
+          </column>
           <column>
            <property name="text">
             <string>InChanger</string>
@@ -205,6 +248,11 @@ p, li { white-space: pre-wrap; }
          <property name="acceptDrops">
           <bool>true</bool>
          </property>
+         <column>
+          <property name="text">
+           <string>Data</string>
+          </property>
+         </column>
          <column>
           <property name="text">
            <string>Type</string>
@@ -217,22 +265,27 @@ p, li { white-space: pre-wrap; }
          </column>
          <column>
           <property name="text">
-           <string>JobId</string>
+           <string>Size</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>FileIndex</string>
+           <string>Date</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>Nb Files</string>
+           <string>JobId</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>Size</string>
+           <string>FileIndex</string>
+          </property>
+         </column>
+         <column>
+          <property name="text">
+           <string>Nb Files</string>
           </property>
          </column>
         </widget>
@@ -294,6 +347,13 @@ p, li { white-space: pre-wrap; }
        </property>
       </spacer>
      </item>
+     <item>
+      <widget class="QCheckBox" name="VersionsChk">
+       <property name="text">
+        <string>View all Versions</string>
+       </property>
+      </widget>
+     </item>
      <item>
       <widget class="QPushButton" name="LocationBp">
        <property name="text">
index 2a8fa5b49ffbe52a623bee9c10d81e5a2adc32e0..f5e87c8957ced67f22cce1b1f530cdb250c6d2bf 100644 (file)
@@ -126,14 +126,18 @@ public:
 public slots:
    void setClient();
    void setJob();
-
-
+   void showInfoForFile(QTableWidgetItem *);
+   void applyLocation();
+   void clearVersions(QTableWidgetItem *);
+   
 private:
    QString m_client;
+   QString m_jobids;
+   QTableWidgetItem *m_current;
    void setupPage();
    bool m_populated;
-   void displayFiles(QString path);
-   void displayFiles(uint64_t pathid);
+   void displayFiles(int64_t pathid, QString path);
+   void displayFileVersion(QString pathid, QString fnid, QString client);
 };
 
 #endif /* _RESTORE_H_ */