diff --git a/src/blackmisc/network/remotefile.cpp b/src/blackmisc/network/remotefile.cpp index 4c0382974..72e3de83c 100644 --- a/src/blackmisc/network/remotefile.cpp +++ b/src/blackmisc/network/remotefile.cpp @@ -7,7 +7,7 @@ * contained in the LICENSE file. */ -#include "blackmisc/network/remotefile.h" +#include "remotefile.h" #include "blackmisc/stringutils.h" #include #include @@ -20,12 +20,17 @@ namespace BlackMisc : m_name(name), m_description(description) { } + CRemoteFile::CRemoteFile(const QString &name, qint64 size) + : m_name(name), m_size(size) + { } + CRemoteFile::CRemoteFile(const QString &name, qint64 size, const QString &url) : m_name(name), m_url(url), m_size(size) { } QString CRemoteFile::getNameAndSize() const { + if (!this->hasName()) { return QStringLiteral(""); } static const QString s("%1 (%2)"); return s.arg(this->getName(), this->getSizeHumanReadable()); } @@ -39,6 +44,23 @@ namespace BlackMisc return false; } + CUrl CRemoteFile::getSmartUrl() const + { + if (!this->hasName()) { return this->getUrl(); } + if (!this->hasUrl()) { return this->getUrl(); } + return this->getUrl().withAppendedPath(this->getName()); + } + + bool CRemoteFile::isExecutableFile() const + { + return CFileUtils::isExecutableFile(this->getName()); + } + + bool CRemoteFile::isSwiftInstaller() const + { + return CFileUtils::isSwiftInstaller(this->getName()); + } + void CRemoteFile::setUrl(const QString &url) { this->setUrl(CUrl(url)); @@ -51,7 +73,7 @@ namespace BlackMisc QString CRemoteFile::getFormattedCreatedYmdhms() const { - if (this->m_created < 1) { return ""; } + if (m_created < 1) { return ""; } const QDateTime dt = QDateTime::fromMSecsSinceEpoch(m_created); return dt.toString("yyyy-MM-dd HH:mm:ss"); } @@ -74,10 +96,10 @@ namespace BlackMisc const ColumnIndex i = index.frontCasted(); switch (i) { - case IndexName: return CVariant::fromValue(this->m_name); - case IndexDescription: return CVariant::fromValue(this->m_description); - case IndexUrl: return CVariant::fromValue(this->m_url); - case IndexSize: return CVariant::fromValue(this->m_size); + case IndexName: return CVariant::fromValue(m_name); + case IndexDescription: return CVariant::fromValue(m_description); + case IndexUrl: return CVariant::fromValue(m_url); + case IndexSize: return CVariant::fromValue(m_size); default: return CValueObject::propertyByIndex(index); } } @@ -91,7 +113,7 @@ namespace BlackMisc { case IndexName: this->setName(variant.value()); break; case IndexDescription: this->setDescription(variant.value()); break; - case IndexUrl: this->m_url.setPropertyByIndex(index.copyFrontRemoved(), variant); + case IndexUrl: m_url.setPropertyByIndex(index.copyFrontRemoved(), variant); case IndexSize: this->setSize(variant.toInt()); default: CValueObject::setPropertyByIndex(index, variant); break; } diff --git a/src/blackmisc/network/remotefile.h b/src/blackmisc/network/remotefile.h index 38f5676b8..8c83c774d 100644 --- a/src/blackmisc/network/remotefile.h +++ b/src/blackmisc/network/remotefile.h @@ -33,13 +33,13 @@ namespace BlackMisc */ class BLACKMISC_EXPORT CRemoteFile : public CValueObject, - public BlackMisc::ITimestampBased + public ITimestampBased { public: //! Properties by index enum ColumnIndex { - IndexName = BlackMisc::CPropertyIndex::GlobalIndexCRemoteFile, + IndexName = CPropertyIndex::GlobalIndexCRemoteFile, IndexDescription, IndexUrl, IndexSize @@ -51,12 +51,18 @@ namespace BlackMisc //! Constructor CRemoteFile(const QString &name, const QString &description); + //! Constructor + CRemoteFile(const QString &name, qint64 size); + //! Constructor CRemoteFile(const QString &name, qint64 size, const QString &url); //! Name const QString &getName() const { return m_name; } + //! Has name? + bool hasName() const { return !m_name.isEmpty(); } + //! Name + human readable size QString getNameAndSize() const; @@ -75,6 +81,21 @@ namespace BlackMisc //! Get URL const CUrl &getUrl() const { return m_url; } + //! Has an URL + bool hasUrl() const { return !m_url.isEmpty(); } + + //! Automatically concatenates the name if missing + CUrl getSmartUrl() const; + + //! File with appendix + bool isFileWithSuffix() const { return this->getUrl().isFileWithSuffix(); } + + //! \copydoc BlackMisc::CFileUtils::isExecutableFile + bool isExecutableFile() const; + + //! \copydoc BlackMisc::CFileUtils::isSwiftInstaller + bool isSwiftInstaller() const; + //! Set URL void setUrl(const CUrl &url) { m_url = url; } @@ -84,7 +105,7 @@ namespace BlackMisc //! Get size qint64 getSize() const { return m_size; } - //! Human readable file size, e.g. 2KB + //! \copydoc BlackMisc::CFileUtils::humanReadableFileSize QString getSizeHumanReadable() const; //! Set size diff --git a/src/blackmisc/network/remotefilelist.cpp b/src/blackmisc/network/remotefilelist.cpp index d89bcebc3..5763372e8 100644 --- a/src/blackmisc/network/remotefilelist.cpp +++ b/src/blackmisc/network/remotefilelist.cpp @@ -25,6 +25,11 @@ namespace BlackMisc CSequence(other) { } + CRemoteFileList::CRemoteFileList(const CRemoteFile &remoteFile) + { + this->push_back(remoteFile); + } + QStringList CRemoteFileList::getNames(bool sorted) const { QStringList fileNames; @@ -53,15 +58,44 @@ namespace BlackMisc return this->findFirstByOrDefault(&CRemoteFile::getName, name); } - CRemoteFile CRemoteFileList::findFirstMatchingNameOrDefault(const QString &name) const + CRemoteFile CRemoteFileList::findFirstByMatchingNameOrDefault(const QString &name) const { - for (const CRemoteFile &file : *this) + if (name.isEmpty()) { return CRemoteFile(); } + for (const CRemoteFile &rf : *this) { - if (file.matchesName(name)) { return file; } + if (rf.matchesName(name)) { return rf; } } return CRemoteFile(); } + CRemoteFileList CRemoteFileList::findExecutableFiles() const + { + CRemoteFileList files; + for (const CRemoteFile &rf : *this) + { + if (CFileUtils::isExecutableFile(rf.getName())) + { + files.push_back(rf); + } + } + return files; + } + + qint64 CRemoteFileList::getTotalFileSize() const + { + qint64 s = 0; + for (const CRemoteFile &rf : *this) + { + s += rf.getSize(); + } + return s; + } + + QString CRemoteFileList::getTotalFileSizeHumanReadable() const + { + return CFileUtils::humanReadableFileSize(this->getTotalFileSize()); + } + CRemoteFileList CRemoteFileList::fromDatabaseJson(const QJsonArray &array) { CRemoteFileList roles; diff --git a/src/blackmisc/network/remotefilelist.h b/src/blackmisc/network/remotefilelist.h index 4a2cab94b..70cd890da 100644 --- a/src/blackmisc/network/remotefilelist.h +++ b/src/blackmisc/network/remotefilelist.h @@ -30,7 +30,7 @@ namespace BlackMisc //! Value object encapsulating a list of remote files. class BLACKMISC_EXPORT CRemoteFileList : public CSequence, - public BlackMisc::Mixin::MetaType + public Mixin::MetaType { public: BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CRemoteFileList) @@ -41,6 +41,9 @@ namespace BlackMisc //! Construct from a base class object. CRemoteFileList(const CSequence &other); + //! From single file + CRemoteFileList(const CRemoteFile &remoteFile); + //! All file names QStringList getNames(bool sorted = true) const; @@ -51,7 +54,16 @@ namespace BlackMisc CRemoteFile findFirstByNameOrDefault(const QString &name) const; //! Find first matching name of default - CRemoteFile findFirstMatchingNameOrDefault(const QString &name) const; + CRemoteFile findFirstByMatchingNameOrDefault(const QString &name) const; + + //! Find all executable files (decided by appendix) + CRemoteFileList findExecutableFiles() const; + + //! Size of all files + qint64 getTotalFileSize() const; + + //! Size formatted + QString getTotalFileSizeHumanReadable() const; //! From our database JSON format static CRemoteFileList fromDatabaseJson(const QJsonArray &array);