1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#include "BackgroundWorker.h"
#include <LuminaXDG.h>
#include <QMediaServiceSupportedFormatsInterface>
#include <QImageReader>
#include <QDir>
#include <QFileInfo>
BackgroundWorker::BackgroundWorker() : QObject(){
}
BackgroundWorker::~BackgroundWorker(){
}
void BackgroundWorker::startDirChecks(QString path){
QDir dir(path);
//Make sure to remove any symlinks or redundency in the path
if(dir.canonicalPath()!=path){ path = dir.canonicalPath(); dir.cd(path); }
qDebug() << "Starting Dir Checks:" << path;
//First check for image files
if(imgFilter.isEmpty()){
//Initial Run - load supported image extensions
QList<QByteArray> fmt = QImageReader::supportedImageFormats();
for(int i=0; i<fmt.length(); i++){ imgFilter << "*."+QString(fmt[i]).toLower(); }
qDebug() << "Supported Image Formats:" << imgFilter;
}
QStringList pics = dir.entryList(imgFilter, QDir::Files | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase);
if(!pics.isEmpty() && !imgFilter.isEmpty()){ emit ImagesAvailable(pics); }
//Now check for multimedia files
if(multiFilter.isEmpty()){
//Initial Run - load supported multimedia extensions
// (Auto-detection of supported types broken in Qt5 - just use everythings for now)
multiFilter = LXDG::findAVFileExtensions();
multiFilter.removeDuplicates();
qDebug() << "Supported Multimedia Formats:" << multiFilter;
}
QStringList files = dir.entryList(multiFilter, QDir::Files | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase);
if(!files.isEmpty() && !multiFilter.isEmpty()){ emit MultimediaAvailable(files); }
qDebug() << " - done with audio/multimedia checks";
//Now check for ZFS snapshots of the directory
if(!QFileInfo(path).isWritable() ){ return; } //skip ZFS checks if can't restore to this dir
//cdir = path;
QStringList snapDirs;
QString baseSnapDir;
bool found = false;
qDebug() << " - start searching for base snapshot directory";
if(cdir == path && QFile::exists(csnapdir) ){
//no need to re-search for it - just found it recently
qDebug() << " -- Use previous dir:" << cdir << csnapdir;
baseSnapDir= csnapdir; found=true;
}else{
while(dir.canonicalPath()!="/" && !found){
qDebug() << " -- Checking for snapshot dir:" << dir.canonicalPath();
if(dir.exists(".zfs/snapshot")){
baseSnapDir = dir.canonicalPath()+"/.zfs/snapshot";
found = true;
}else{ dir.cdUp(); }
}
}
qDebug() << " - done with base snapshot directory";
cdir = path; csnapdir = baseSnapDir;
//Now find the snapshots that contain this directory and save them
if(found){
qDebug() << " - start fetching snapshots";
QString reldir = path;
reldir.remove(baseSnapDir.section("/.zfs/snapshot",0,0)); //convert to a relative path
dir.cd(baseSnapDir);
snapDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time);
//Check that the current directory exists in each snapshot
for(int i=0; i<snapDirs.length(); i++){
if( !dir.exists(snapDirs[i]+"/"+reldir) ){
snapDirs.removeAt(i);
i--;
}else{
snapDirs[i] = QFileInfo(dir, snapDirs[i]+"/"+reldir).created().toString("yyyyMMddhhmmsszzz")+"::::"+snapDirs[i];
}
}
qDebug() << " - done fetching snapshots";
snapDirs.sort();
//Sort the snapshots by time (newest last) and format them
for(int i=0; i<snapDirs.length(); i++){
snapDirs[i] = dir.absolutePath()+"/"+snapDirs[i].section("::::",1,50)+"/"+reldir;
}
if(!snapDirs.isEmpty()){ emit SnapshotsAvailable(baseSnapDir, snapDirs); }
qDebug() << "Found snapshots";
}
}
void BackgroundWorker::createStatusBarMsg(QFileInfoList fileList, QString path, QString messageFolders, QString messageFiles){
//collect some statistics of dir and display them in statusbar
//Get the total size of the items
double totalSizes = 0;
int numberFolders = 0;
int numberFiles = 0;
for(int i=0; i<fileList.length(); i++){
if(!fileList[i].isDir()){
numberFiles++;
totalSizes += fileList[i].size(); //in Bytes
}
else { numberFolders++; }
}
//Convert the size into display units
static QStringList units = QStringList() << tr("B") << tr("KB") << tr("MB") << tr("GB") << tr("TB");
int cunit = 0;
while(cunit < units.length() && totalSizes > 1024){
cunit++;
totalSizes = totalSizes/1024;
}
//Assemble the message
QString msgStatusBar = QString(tr("%1: %2 / %3: %4")).arg(messageFolders).arg(numberFolders).arg(messageFiles).arg(numberFiles);
if(totalSizes > 0){
totalSizes = qRound(totalSizes*100)/100.0; //round to 2 decimel places
msgStatusBar += " "+QString(tr("Total size: %1 %2")).arg(QString::number(totalSizes), units[cunit]);
}
//If a path given, get the total capacity of it (percantage)
if (!path.isEmpty()) { //path could be empty when fileList is based on user's selection
QString capacity = LOS::FileSystemCapacity(path) ;
if (msgStatusBar.isEmpty()) msgStatusBar += QString(tr("Capacity: %1")).arg(capacity);
else msgStatusBar += " "+QString(tr("Capacity: %1")).arg(capacity);
}
//Emit the signal to show this on the UI
if (!msgStatusBar.isEmpty()){
emit Si_DisplayStatusBar(msgStatusBar);
}
}
|