diff options
author | Ken Moore <ken@ixsystems.com> | 2017-11-15 14:38:01 -0500 |
---|---|---|
committer | Ken Moore <ken@ixsystems.com> | 2017-11-15 14:38:01 -0500 |
commit | 8d54d01f09760c78d649baed0b88aa0f80069de7 (patch) | |
tree | 7c754cf8208ed2534974dbe53f5c0a76c7cf1081 | |
parent | A bit more background threading magic. (diff) | |
download | lumina-8d54d01f09760c78d649baed0b88aa0f80069de7.tar.gz lumina-8d54d01f09760c78d649baed0b88aa0f80069de7.tar.bz2 lumina-8d54d01f09760c78d649baed0b88aa0f80069de7.zip |
Add a bunch of ZFS information routines to LFileInfo.
Also utilize this ZFS info in lumina-fileinfo (if appropriate)
-rw-r--r-- | src-qt5/core/libLumina/LFileInfo.cpp | 73 | ||||
-rw-r--r-- | src-qt5/core/libLumina/LFileInfo.h | 13 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp | 50 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-fileinfo/MainUI.h | 3 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui | 75 | ||||
-rw-r--r-- | src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp | 2 |
6 files changed, 213 insertions, 3 deletions
diff --git a/src-qt5/core/libLumina/LFileInfo.cpp b/src-qt5/core/libLumina/LFileInfo.cpp index e54ce5cc..e7d2b71a 100644 --- a/src-qt5/core/libLumina/LFileInfo.cpp +++ b/src-qt5/core/libLumina/LFileInfo.cpp @@ -60,6 +60,31 @@ void LFileInfo::loadExtraInfo(){ } } +bool LFileInfo::zfsAvailable(){ + static unsigned int avail = 2; + if(avail == 2){ avail = (LUtils::isValidBinary("zfs") ? 0 : 1); } + return (avail == 0); +} + +void LFileInfo::getZfsDataset(){ + if(zfs_ds.isEmpty()){ + //First run - need to probe the current directory + bool ok = false; + //Use the "atime" property for this check - been around since the earliest versions of ZFS and should take no time to probe + QString out = LUtils::runCommand(ok, "zfs", QStringList() << "get" << "-H" << "atime" << this->canonicalFilePath() ); + if(!ok){ zfs_ds = "."; } //just something that is not empty - but is clearly not a valid dataset + else{ zfs_ds = out.section("\n",0,0).section("\t",0,0).simplified(); } + //qDebug() << "Found Dataset:" << zfs_ds << out << ok; + } +} + +bool LFileInfo::goodZfsDataset(){ + if(!zfsAvailable()){ return false; } + getZfsDataset(); //ensure this field is populated + if(zfs_ds=="." || zfs_ds.isEmpty()){ return false; } + return true; +} + //Functions for accessing the extra information // -- Return the mimetype for the file QString LFileInfo::mimetype(){ @@ -109,3 +134,51 @@ bool LFileInfo::isImage(){ bool LFileInfo::isAVFile(){ return (mime.startsWith("audio/") || mime.startsWith("video/") ); } + +bool LFileInfo::isZfsDataset(){ + if(!goodZfsDataset()){ return false; } + return ( ("/"+zfs_ds.section("/",1,-1)) == this->canonicalFilePath()); +} + +QString LFileInfo::zfsPool(){ + if(!goodZfsDataset()){ return ""; } + return zfs_ds.section("/",0,0); +} + +QStringList LFileInfo::zfsSnapshots(){ + if(!goodZfsDataset()){ return QStringList(); } + QString relpath = this->canonicalFilePath().remove(0, QString("/"+zfs_ds.section("/",1,-1)).length() ); + //qDebug() << "Got Relative path:" << zfs_ds << this->canonicalFilePath() << relpath; + QDir dir("/"+zfs_ds.section("/",1,-1)+"/.zfs/snapshot/"); + QStringList snaps = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time); + for(int i=0; i<snaps.length(); i++){ + if( QFile::exists(dir.absoluteFilePath(snaps[i])+relpath) ){ snaps[i].append("::::" + dir.absoluteFilePath(snaps[i])+relpath ); } + else{ snaps.removeAt(i); i--; } + } + return snaps; +} + +QJsonObject LFileInfo::zfsProperties(){ + QJsonObject props; + if(!goodZfsDataset()){ return props; } + bool ok = false; + QStringList out = LUtils::runCommand(ok, "zfs", QStringList() << "get" << "-H" << "all" << zfs_ds).split("\n"); + //Note: Formating of zfs output: tab-delimited, with columns [dataset, property, value, source] + for(int i=0; i<out.length() && ok; i++){ + if(out[i].simplified().isEmpty()){ continue; } + QJsonObject prop; + prop.insert("property", out[i].section("\t",1,1).simplified()); + prop.insert("value", out[i].section("\t",2,2).simplified()); + prop.insert("source", out[i].section("\t",3,-1).simplified()); + props.insert(prop.value("property").toString(), prop); + } + return props; +} + +bool LFileInfo::zfsSetProperty(QString property, QString value){ + if(!goodZfsDataset()){ return false; } + bool ok = false; + QString info = LUtils::runCommand(ok, "zfs", QStringList() << "set" << property+"="+value << zfs_ds); + if(!ok){ qDebug() << "Error Setting ZFS Property:" << property+"="+value << info; } + return ok; +} diff --git a/src-qt5/core/libLumina/LFileInfo.h b/src-qt5/core/libLumina/LFileInfo.h index 4fbf6353..df1abb65 100644 --- a/src-qt5/core/libLumina/LFileInfo.h +++ b/src-qt5/core/libLumina/LFileInfo.h @@ -13,13 +13,17 @@ #include <LuminaXDG.h> #include <QString> #include <QFileInfo> +#include <QJsonObject> class LFileInfo : public QFileInfo{ private: - QString mime, icon; + QString mime, icon, zfs_ds; XDGDesktop *desk; void loadExtraInfo(); + bool zfsAvailable(); + void getZfsDataset(); //note: only run this if "zfsAvailable" is true + bool goodZfsDataset(); //simplification of the two functions above public: //Couple overloaded contructors @@ -45,6 +49,13 @@ public: bool isImage(); //Is a readable image file (for thumbnail support) bool isVideo(); //Is a readable video file (for thumbnail support) bool isAVFile(); //Is an audio/video file + + bool isZfsDataset(); + QString zfsPool(); + QStringList zfsSnapshots(); //Format: "snapshot name::::path/to/snapshot" + QJsonObject zfsProperties(); + bool zfsSetProperty(QString property, QString value); + }; typedef QList<LFileInfo> LFileInfoList; diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp index e64346ae..c99a781e 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp @@ -191,6 +191,52 @@ void MainUI::SyncFileInfo(){ ui->tabWidget->addTab( ui->tab_deskedit, tr("XDG Shortcut") ); } ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_file) ); + SyncZfsInfo(); +} + +void MainUI::SyncZfsInfo(){ + bool showtab = false; + if(INFO->zfsPool().isEmpty()){ + //Not on a ZFS pool - hide the tab if it is available + showtab = false; + }else{ + qDebug() << "Is a ZFS Dataset:" << INFO->isZfsDataset(); + ui->label_zfs_pool->setText(INFO->zfsPool()); + if(INFO->isZfsDataset()){ + ui->tree_zfs_props->clear(); + QJsonObject props = INFO->zfsProperties(); + QStringList keys = props.keys(); + for(int i=0; i<keys.length(); i++){ + ui->tree_zfs_props->addTopLevelItem( new QTreeWidgetItem(QStringList() << keys[i] << props.value(keys[i]).toObject().value("value").toString() << props.value(keys[i]).toObject().value("source").toString() ) ); + ui->tree_zfs_props->resizeColumnToContents(0); + ui->tree_zfs_props->resizeColumnToContents(1); + } + ui->tree_zfs_props->setVisible(!keys.isEmpty()); + showtab = !keys.isEmpty(); + }else{ + ui->tree_zfs_props->setVisible(false); + } + QStringList snaps = INFO->zfsSnapshots(); + ui->tree_zfs_snaps->clear(); + for(int i=0; i<snaps.length(); i++){ + QFileInfo finfo(snaps[i].section("::::",1,-1)); + ui->tree_zfs_snaps->addTopLevelItem( new QTreeWidgetItem(QStringList() << snaps[i].section("::::",0,0) << finfo.created().toString(Qt::SystemLocaleShortDate) << finfo.lastModified().toString(Qt::SystemLocaleShortDate) ) ); + ui->tree_zfs_snaps->resizeColumnToContents(0); + } + ui->tree_zfs_snaps->setVisible(!snaps.isEmpty()); + showtab = showtab || !snaps.isEmpty(); + } + if(showtab){ + //Make sure the tab is visible + if(ui->tabWidget->indexOf(ui->tab_zfs)<0){ + ui->tabWidget->addTab( ui->tab_zfs, tr("Advanced") ); + } + }else{ + //hide the tab if it is visible right now + if(ui->tabWidget->indexOf(ui->tab_zfs)>=0){ + ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_zfs) ); + } + } } void MainUI::SetupNewFile(){ @@ -209,6 +255,10 @@ void MainUI::SetupNewFile(){ //qDebug() << "Adding the deskedit tab"; ui->tabWidget->addTab(ui->tab_deskedit, tr("XDG Shortcut")); } + //Not on a ZFS pool - hide the tab if it is available + if(ui->tabWidget->indexOf(ui->tab_zfs)>=0){ + ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_zfs) ); + } ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_deskedit) ); } diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h index 3990f643..4e756a97 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h @@ -55,7 +55,7 @@ private: void GetDirSize(const QString dirname) const; //function to get folder size void SyncFileInfo(); - + void SyncZfsInfo(); void syncXdgStruct(XDGDesktop*); bool saveFile(QString path); @@ -66,6 +66,7 @@ signals: private slots: void SetupNewFile(); + //Initialization functions void SetupConnections(); diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui index 217c1a10..5139bbf7 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui @@ -216,6 +216,81 @@ </item> </layout> </widget> + <widget class="QWidget" name="tab_zfs"> + <attribute name="title"> + <string>Advanced</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QFormLayout" name="formLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_9"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>ZFS Pool:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_zfs_pool"> + <property name="text"> + <string notr="true">[pool]</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QTreeWidget" name="tree_zfs_props"> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Property</string> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + </column> + <column> + <property name="text"> + <string>Source</string> + </property> + </column> + </widget> + </item> + <item> + <widget class="QTreeWidget" name="tree_zfs_snaps"> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Snapshot</string> + </property> + </column> + <column> + <property name="text"> + <string>Date Created</string> + </property> + </column> + <column> + <property name="text"> + <string>Date Modified</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> <widget class="QWidget" name="tab_deskedit"> <attribute name="title"> <string>XDG Shortcut</string> diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp index c4b1c8d8..5a08b797 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp @@ -51,7 +51,7 @@ void BrowserWidget::changeDirectory(QString dir){ //videoMap.clear(); } if(BROWSER->currentDirectory()==dir){ return; } //already on this directory - qDebug() << "Change Directory:" << dir << historyList; + //qDebug() << "Change Directory:" << dir << historyList; if( !dir.contains("/.zfs/snapshot/") ){ if(historyList.isEmpty() || !dir.isEmpty()){ historyList << dir; } |