From 364924c3834defd586aa6bea4bff82a6a0ebfbaa Mon Sep 17 00:00:00 2001 From: Maurice ONeal Date: Thu, 26 Sep 2019 19:04:04 -0400 Subject: [PATCH] Added a new internal command. Added a new fs_tree command that list all files and directories in a directory tree. Just like fs_list, it has the option to output human readable text or FILE_INFO frames. Also added the option to hide hidden files for both commands. 1.1.2 --> 1.1.3 --- cmd_docs.qrc | 1 + docs/intern_commands/fs_list.md | 4 +- docs/intern_commands/fs_tree.md | 11 +++ src/commands/command.h | 21 ++--- src/commands/fs.cpp | 133 +++++++++++++++++++++++++++++--- src/commands/fs.h | 24 ++++++ src/commands/mods.cpp | 8 +- src/db.h | 2 +- src/int_loader.cpp | 2 + src/main.cpp | 1 + 10 files changed, 174 insertions(+), 33 deletions(-) create mode 100644 docs/intern_commands/fs_tree.md diff --git a/cmd_docs.qrc b/cmd_docs.qrc index 9225231..b18e228 100644 --- a/cmd_docs.qrc +++ b/cmd_docs.qrc @@ -27,6 +27,7 @@ docs/intern_commands/fs_list.md docs/intern_commands/fs_mkpath.md docs/intern_commands/fs_move.md + docs/intern_commands/fs_tree.md docs/intern_commands/fs_upload.md docs/intern_commands/host_config.md docs/intern_commands/host_info.md diff --git a/docs/intern_commands/fs_list.md b/docs/intern_commands/fs_list.md index 11f1d29..b45d6da 100644 --- a/docs/intern_commands/fs_list.md +++ b/docs/intern_commands/fs_list.md @@ -4,8 +4,8 @@ list all files or sub-directories in a directory. ### IO ### -```[{-path (text)} {-info_frame}]/[text] or [FILE_INFO]``` +```[{-path (text)} {-info_frame} {-no_hidden}]/[text] or [FILE_INFO]``` ### Description ### -this list all files in the current directory or the directory specified in -path. this command normally returns human readable text for each file or sub-directory that is listed but you can pass -info_frame to make the command return FILE_INFO frames for each file/sub-directory instead. note: if displaying as text, all directory names are displayed with a '/' at the end. \ No newline at end of file +this list all files in the current directory or the directory specified in -path. this command normally returns human readable text for each file or sub-directory that is listed but you can pass -info_frame to make the command return FILE_INFO frames for each file/sub-directory instead. note: if displaying as text, all directory names are displayed with a '/' at the end. by default, this command will list all hidden files and directories among the visible but you can pass the -no_hidden option to have it not list the hidden files or directories. \ No newline at end of file diff --git a/docs/intern_commands/fs_tree.md b/docs/intern_commands/fs_tree.md new file mode 100644 index 0000000..da47cd4 --- /dev/null +++ b/docs/intern_commands/fs_tree.md @@ -0,0 +1,11 @@ +### Summary ### + +list all files and sub-directories of an entire directory tree. + +### IO ### + +```[{-path (text)} {-info_frame} {-no_hidden}]/[text] or [FILE_INFO]``` + +### Description ### + +this list all files and sub-directories in the entire tree of the current directory or the directory specified in -path. this command normally returns human readable text for each file or sub-directory that is listed but you can pass -info_frame to make the command return FILE_INFO frames for each file/sub-directory instead. note: if displaying as text, all directory names are displayed with a '/' at the end. by default, this command will list all hidden files and directories among the visible but you can pass the -no_hidden option to have it not list the hidden files or directories. \ No newline at end of file diff --git a/src/commands/command.h b/src/commands/command.h index d6953ec..1d12473 100644 --- a/src/commands/command.h +++ b/src/commands/command.h @@ -19,13 +19,10 @@ #define TXT_CODEC "UTF-16LE" #define TXT_CODEC_BITS 16 -#define MOD_LOADER_IID "MCRI.host.module" #include #include -#include #include -#include enum TypeID { @@ -111,14 +108,14 @@ public: virtual void procBin(const SharedObjs *, const QByteArray &, uchar) {} virtual void aboutToDelete() {} - virtual void term() {} - virtual bool handlesGenfile() {return false;} + virtual void term() {} virtual bool errState(); - virtual QString shortText() {return "";} - virtual QString ioText() {return "";} - virtual QString longText() {return "";} - virtual QString libText() {return "";} - virtual QStringList internRequest() {return QStringList();} + virtual bool handlesGenfile() {return false;} + virtual QString shortText() {return "";} + virtual QString ioText() {return "";} + virtual QString longText() {return "";} + virtual QString libText() {return "";} + virtual QStringList internRequest() {return QStringList();} QHash internCommands; quint16 cmdId; @@ -163,8 +160,4 @@ public: virtual ExternCommand *cmdObj(const QString &) {return nullptr;} }; -QT_BEGIN_NAMESPACE -Q_DECLARE_INTERFACE(CommandLoader, MOD_LOADER_IID) -QT_END_NAMESPACE - #endif // EXTERN_COMMAND_H diff --git a/src/commands/fs.cpp b/src/commands/fs.cpp index 9220865..681b760 100644 --- a/src/commands/fs.cpp +++ b/src/commands/fs.cpp @@ -20,11 +20,12 @@ DownloadFile::DownloadFile(QObject *parent) : InternCommand(parent) {file = new UploadFile::UploadFile(QObject *parent) : InternCommand(parent) {file = new QFile(this);} Delete::Delete(QObject *parent) : InternCommand(parent) {} Copy::Copy(QObject *parent) : InternCommand(parent) {src = new QFile(this); dst = new QFile(this);} -Move::Move(QObject *parent) : Copy(parent) {} +Move::Move(QObject *parent) : Copy(parent) {} MakePath::MakePath(QObject *parent) : InternCommand(parent) {} ListFiles::ListFiles(QObject *parent) : InternCommand(parent) {} FileInfo::FileInfo(QObject *parent) : InternCommand(parent) {} ChangeDir::ChangeDir(QObject *parent) : InternCommand(parent) {} +Tree::Tree(QObject *parent) : InternCommand(parent) {} QString DownloadFile::cmdName() {return "fs_download";} QString UploadFile::cmdName() {return "fs_upload";} @@ -35,6 +36,7 @@ QString MakePath::cmdName() {return "fs_mkpath";} QString ListFiles::cmdName() {return "fs_list";} QString FileInfo::cmdName() {return "fs_info";} QString ChangeDir::cmdName() {return "fs_cd";} +QString Tree::cmdName() {return "fs_tree";} bool DownloadFile::handlesGenfile() { @@ -74,7 +76,7 @@ void DownloadFile::sendChunk() void DownloadFile::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if ((dType == GEN_FILE) && (moreInputEnabled() || loopEnabled())) { @@ -196,7 +198,7 @@ void UploadFile::run() void UploadFile::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (((dType == GEN_FILE) || (dType == TEXT)) && confirm) { @@ -299,7 +301,7 @@ void Delete::run() void Delete::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (moreInputEnabled() && (dType == TEXT)) { @@ -460,7 +462,7 @@ void Copy::run() void Copy::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (loopEnabled()) { @@ -652,7 +654,7 @@ bool Move::permissionsOk(bool dstExists) void MakePath::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (dType == TEXT) { @@ -672,13 +674,14 @@ void MakePath::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uc void ListFiles::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (dType == TEXT) { - QStringList args = parseArgs(binIn, 3); + QStringList args = parseArgs(binIn, 4); QString path = getParam("-path", args); bool infoFrame = argExists("-info_frame", args); + bool noHidden = argExists("-no_hidden", args); if (path.isEmpty()) { @@ -703,7 +706,15 @@ void ListFiles::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, u { QDir dir(path); - dir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); + if (noHidden) + { + dir.setFilter(QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot); + } + else + { + dir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); + } + dir.setSorting(QDir::DirsFirst | QDir::Name); QFileInfoList list = dir.entryInfoList(); @@ -729,7 +740,7 @@ void ListFiles::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, u void FileInfo::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (dType == TEXT) { @@ -783,7 +794,7 @@ void FileInfo::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uc void ChangeDir::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (dType == TEXT) { @@ -810,3 +821,103 @@ void ChangeDir::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, u } } } + +void Tree::term() +{ + queue.clear(); + + infoFrames = false; + noHidden = false; +} + +void Tree::printList(const QString &path) +{ + QDir dir(path); + + if (noHidden) + { + dir.setFilter(QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot); + } + else + { + dir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); + } + + dir.setSorting(QDir::DirsFirst | QDir::Name); + + QFileInfoList list = dir.entryInfoList(); + + for (auto&& info : list) + { + if (infoFrames) + { + emit dataToClient(toFILE_INFO(info), FILE_INFO); + } + else if (info.isDir()) + { + mainTxt(info.filePath() + "/" + "\n"); + } + else + { + mainTxt(info.filePath() + "\n"); + } + + if (info.isDir()) + { + queue.append(info); + } + } + + if (queue.isEmpty()) + { + term(); + + emit enableLoop(false); + } + else + { + emit enableLoop(true); + } +} + +void Tree::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) +{ + Q_UNUSED(sharedObjs) + + if (loopEnabled()) + { + printList(queue.takeFirst().filePath()); + } + else if (dType == TEXT) + { + QStringList args = parseArgs(binIn, 4); + QString path = getParam("-path", args); + + infoFrames = argExists("-info_frame", args); + noHidden = argExists("-no_hidden", args); + + if (path.isEmpty()) + { + path = QDir::currentPath(); + } + + QFileInfo pathInfo(path); + + if (!pathInfo.exists()) + { + errTxt("err: '" + path + "' does not exists.\n"); + } + else if (!pathInfo.isDir()) + { + errTxt("err: '" + path + "' is not a directory.\n"); + } + else if (!pathInfo.isReadable()) + { + errTxt("err: Cannot read '" + path + "' permission denied.\n"); + } + else + { + printList(path); + } + } +} diff --git a/src/commands/fs.h b/src/commands/fs.h index a29b2ab..06722fc 100644 --- a/src/commands/fs.h +++ b/src/commands/fs.h @@ -217,4 +217,28 @@ public: explicit ChangeDir(QObject *parent = nullptr); }; +//-------------------------- + +class Tree : public InternCommand +{ + Q_OBJECT + +private: + + QFileInfoList queue; + bool infoFrames; + bool noHidden; + + void printList(const QString &path); + +public: + + static QString cmdName(); + + void term(); + void procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType); + + explicit Tree(QObject *parent = nullptr); +}; + #endif // FS_H diff --git a/src/commands/mods.cpp b/src/commands/mods.cpp index b0dbbb2..1d975a8 100644 --- a/src/commands/mods.cpp +++ b/src/commands/mods.cpp @@ -125,13 +125,11 @@ void UploadMod::procFinished(int exStatus) } else if (!libExists(modPath + "/main")) { - errTxt("\nerr: The module's main library file does not exists.\n"); + errTxt("\nerr: The module's main library file does not exists or is not supported.\n"); clearOnfailure(); } else { - modPath = modPath + "/main"; - Query db(this); db.setType(Query::UPDATE, TABLE_MODULES); @@ -229,7 +227,7 @@ void UploadMod::setup() void UploadMod::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (moreInputEnabled() && (dType == GEN_FILE) && (proc->state() == QProcess::NotRunning)) { @@ -322,7 +320,7 @@ void UploadMod::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, u void DelMod::procBin(const SharedObjs *sharedObjs, const QByteArray &binIn, uchar dType) { - Q_UNUSED(sharedObjs); + Q_UNUSED(sharedObjs) if (dType == TEXT) { diff --git a/src/db.h b/src/db.h index 31f2f1f..d106654 100644 --- a/src/db.h +++ b/src/db.h @@ -37,7 +37,7 @@ #include "shell.h" #define APP_NAME "MRCI" -#define APP_VER "1.1.2" +#define APP_VER "1.1.3" #define APP_TARGET "mrci" #ifdef Q_OS_WIN diff --git a/src/int_loader.cpp b/src/int_loader.cpp index bec5cc4..56d7ae9 100644 --- a/src/int_loader.cpp +++ b/src/int_loader.cpp @@ -117,6 +117,7 @@ InternalCommandLoader::InternalCommandLoader(RWSharedObjs *sharedData, QObject * objNames << SetGroupRank::cmdName(); objNames << CmdInfo::cmdName(); objNames << OwnerOverride::cmdName(); + objNames << Tree::cmdName(); } void InternalCommandLoader::loadSettings() @@ -292,6 +293,7 @@ InternCommand *InternalCommandLoader::cmdObj(const QString &name) else if (noCaseMatch(name, SetGroupRank::cmdName())) ret = new SetGroupRank(this); else if (noCaseMatch(name, CmdInfo::cmdName())) ret = new CmdInfo(this); else if (noCaseMatch(name, OwnerOverride::cmdName())) ret = new OwnerOverride(this); + else if (noCaseMatch(name, Tree::cmdName())) ret = new Tree(this); if (ret == nullptr) { diff --git a/src/main.cpp b/src/main.cpp index 934e0ed..083f730 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,6 +77,7 @@ int main(int argc, char *argv[]) serializeThread(app.thread()); + QDir::setCurrent(QDir::homePath()); QCoreApplication::setApplicationName(APP_NAME); QCoreApplication::setApplicationVersion(APP_VER);