Ref T203, utility functions for URL

This commit is contained in:
Klaus Basan
2017-12-09 19:44:52 +01:00
parent 16a4731389
commit 6445444fbf
4 changed files with 101 additions and 16 deletions

View File

@@ -162,7 +162,7 @@ namespace BlackMisc
QUrl qurl(this->toQUrl()); QUrl qurl(this->toQUrl());
qurl.setPort(port); qurl.setPort(port);
qurl.setScheme(scheme); qurl.setScheme(scheme);
CUrl url(qurl); const CUrl url(qurl);
return url; return url;
} }
@@ -171,6 +171,54 @@ namespace BlackMisc
return m_path.endsWith(ending, cs); return m_path.endsWith(ending, cs);
} }
bool CUrl::isFile() const
{
const QString f(this->getFileName());
return !f.isEmpty();
}
bool CUrl::isFileWithSuffix(const QString &suffix) const
{
const QString f(this->getFileName());
if (suffix.isEmpty()) { return f.contains('.'); }
return f.endsWith(suffix, Qt::CaseInsensitive);
}
bool CUrl::isExecutableFile() const
{
return CFileUtils::isExecutableFile(this->getFileName());
}
bool CUrl::isSwiftInstaller() const
{
return CFileUtils::isSwiftInstaller(this->getFileName());
}
QString CUrl::getFileSuffix() const
{
const QString f(this->getFileName());
const int i = f.lastIndexOf('.');
if (i < 0) return "";
if (f.length() <= i + 1) return ""; // ends with "."
return f.mid(i + 1); // suffix without dot
}
QString CUrl::getFileSuffixPlusDot() const
{
const QString f(this->getFileName());
const int i = f.lastIndexOf('.');
if (i < 0) return "";
if (f.length() <= i + 1) return ""; // ends with "."
return f.mid(i); // suffix with dot
}
bool CUrl::isHavingHtmlSuffix() const
{
static const QString h1(".html");
static const QString h2(".htm");
return this->isFileWithSuffix(h1) || this->isFileWithSuffix(h2);
}
CUrl CUrl::withAppendedQuery(const QString &query) const CUrl CUrl::withAppendedQuery(const QString &query) const
{ {
if (query.isEmpty()) { return *this; } if (query.isEmpty()) { return *this; }
@@ -187,8 +235,8 @@ namespace BlackMisc
QJsonObject CUrl::toJson() const QJsonObject CUrl::toJson() const
{ {
QPair<QString, QJsonValue> v("url", getFullUrl()); const QPair<QString, QJsonValue> v("url", getFullUrl());
QJsonObject json({ v }); const QJsonObject json({ v });
return json; return json;
} }
@@ -210,7 +258,7 @@ namespace BlackMisc
bool CUrl::isDefaultPort(const QString &protocol, int port) bool CUrl::isDefaultPort(const QString &protocol, int port)
{ {
int p = protocolToDefaultPort(protocol); const int p = protocolToDefaultPort(protocol);
if (p < 0) { return false; } if (p < 0) { return false; }
return port == p; return port == p;
} }
@@ -240,10 +288,10 @@ namespace BlackMisc
const ColumnIndex i = index.frontCasted<ColumnIndex>(); const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i) switch (i)
{ {
case IndexHost: return CVariant::fromValue(this->m_host); case IndexHost: return CVariant::fromValue(m_host);
case IndexPort: return CVariant::fromValue(this->m_port); case IndexPort: return CVariant::fromValue(m_port);
case IndexScheme: return CVariant::fromValue(this->m_scheme); case IndexScheme: return CVariant::fromValue(m_scheme);
case IndexPath: return CVariant::fromValue(this->m_path); case IndexPath: return CVariant::fromValue(m_path);
default: return CValueObject::propertyByIndex(index); default: return CValueObject::propertyByIndex(index);
} }
} }

View File

@@ -142,6 +142,29 @@ namespace BlackMisc
//! Path ending with? //! Path ending with?
bool pathEndsWith(const QString &ending, Qt::CaseSensitivity cs = Qt::CaseInsensitive) const; bool pathEndsWith(const QString &ending, Qt::CaseSensitivity cs = Qt::CaseInsensitive) const;
//! A path ends with "/", and file is anythingy beyond that, e.g. "path/file"
//! \sa isFile with appendix
bool isFile() const;
//! Stricter version of isFile()
bool isFileWithSuffix(const QString &suffix = {}) const;
//! File appendix if any, otherwise empty, does not include the "."
//! \remark similar to QFileInfo::suffix()
QString getFileSuffix() const;
//! Suffix plus dot
QString getFileSuffixPlusDot() const;
//! Likely a HTM file?
bool isHavingHtmlSuffix() const;
//! \copydoc BlackMisc::CFileUtils::isExecutableFile
bool isExecutableFile() const;
//! \copydoc BlackMisc::CFileUtils::isSwiftInstaller
bool isSwiftInstaller() const;
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex //! \copydoc BlackMisc::Mixin::Index::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;

View File

@@ -147,13 +147,13 @@ namespace BlackMisc
bool CFailoverUrlList::addFailedUrl(const CUrl &failedUrl) bool CFailoverUrlList::addFailedUrl(const CUrl &failedUrl)
{ {
Q_ASSERT_X(!failedUrl.isEmpty(), Q_FUNC_INFO, "empty URL as failed"); Q_ASSERT_X(!failedUrl.isEmpty(), Q_FUNC_INFO, "empty URL as failed");
this->m_failedUrls.push_back(failedUrl); m_failedUrls.push_back(failedUrl);
return hasMoreUrlsToTry(); return hasMoreUrlsToTry();
} }
bool CFailoverUrlList::addFailedUrls(const CUrlList &failedUrls) bool CFailoverUrlList::addFailedUrls(const CUrlList &failedUrls)
{ {
this->m_failedUrls.push_back(failedUrls); m_failedUrls.push_back(failedUrls);
return hasMoreUrlsToTry(); return hasMoreUrlsToTry();
} }
@@ -173,21 +173,29 @@ namespace BlackMisc
bool CFailoverUrlList::hasMoreUrlsToTry() const bool CFailoverUrlList::hasMoreUrlsToTry() const
{ {
if (this->isEmpty()) { return false; } return this->numberOfStillValidUrls() > 0;
return (m_failedUrls.size() < this->size() && m_failedUrls.size() < m_maxTrials); }
int CFailoverUrlList::numberOfStillValidUrls() const
{
if (this->isEmpty()) { return 0; }
if (m_failedUrls.size() >= m_maxTrials) { return 0; }
const int trailsLeft1 = qMax(m_maxTrials - m_failedUrls.size(), 0);
const int trailsLeft2 = qMax(this->size() - m_failedUrls.size(), 0);
return qMin(trailsLeft1, trailsLeft2);
} }
CUrl CFailoverUrlList::obtainNextWorkingUrl(bool random, int connectTimeoutMs) CUrl CFailoverUrlList::obtainNextWorkingUrl(bool random, int connectTimeoutMs)
{ {
if (!hasMoreUrlsToTry()) { return CUrl(); } if (!hasMoreUrlsToTry()) { return CUrl(); }
const CUrl url(this->obtainNextUrlWithout(random, this->m_failedUrls)); const CUrl url(this->obtainNextUrlWithout(random, m_failedUrls));
QString msg; QString msg;
if (CNetworkUtils::canConnect(url, msg, connectTimeoutMs)) { return url; } if (CNetworkUtils::canConnect(url, msg, connectTimeoutMs)) { return url; }
if (addFailedUrl(url)) if (addFailedUrl(url))
{ {
if (!msg.isEmpty()) if (!msg.isEmpty())
{ {
this->m_errorMsgs.append(QString("URL: %1 error: %2").arg(url.toQString(), msg)); m_errorMsgs.append(QString("URL: %1 error: %2").arg(url.toQString(), msg));
} }
return obtainNextWorkingUrl(random, connectTimeoutMs); return obtainNextWorkingUrl(random, connectTimeoutMs);
} }
@@ -226,8 +234,8 @@ namespace BlackMisc
void CFailoverUrlList::reset(int maxTrials) void CFailoverUrlList::reset(int maxTrials)
{ {
this->m_failedUrls.clear(); m_failedUrls.clear();
if (maxTrials >= 0) { this->m_maxTrials = maxTrials; } if (maxTrials >= 0) { m_maxTrials = maxTrials; }
} }
} // namespace } // namespace
} // namespace } // namespace

View File

@@ -87,6 +87,9 @@ namespace BlackMisc
//! All failed URLs //! All failed URLs
const CUrlList &getFailedUrls() const { return m_failedUrls; } const CUrlList &getFailedUrls() const { return m_failedUrls; }
//! Size of failed URLs
int getFailedUrlsSize() const { return m_failedUrls.size(); }
//! Get without the failed URLs //! Get without the failed URLs
CUrlList getWithoutFailed() const; CUrlList getWithoutFailed() const;
@@ -105,6 +108,9 @@ namespace BlackMisc
//! More URLs to try //! More URLs to try
bool hasMoreUrlsToTry() const; bool hasMoreUrlsToTry() const;
//! Number of URLs which can be used for a retry
int numberOfStillValidUrls() const;
//! Next utl from this list //! Next utl from this list
CUrl obtainNextUrl(bool randomStart = false); CUrl obtainNextUrl(bool randomStart = false);