Browse Source

Use QString literals

It covers src/webui and enables `QT_NO_CAST_FROM_ASCII`.
adaptive-webui-19844
Chocobo1 3 years ago
parent
commit
efc04645b7
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 1
      cmake/Modules/MacroQbtCommonConfig.cmake
  2. 11
      src/app/application.cpp
  3. 6
      src/app/main.cpp
  4. 36
      src/app/stacktrace_win.h
  5. 2
      src/app/stacktracedialog.cpp
  6. 2
      src/base/bittorrent/session.cpp
  7. 16
      src/base/utils/foreignapps.cpp
  8. 4
      src/base/utils/misc.h
  9. 5
      src/base/utils/random.cpp
  10. 12
      src/gui/mainwindow.cpp
  11. 11
      src/gui/programupdater.cpp
  12. 4
      src/gui/progressbarpainter.cpp
  13. 2
      src/gui/transferlistmodel.cpp
  14. 1
      src/src.pro
  15. 684
      src/webui/api/appcontroller.cpp
  16. 5
      src/webui/api/authcontroller.cpp
  17. 12
      src/webui/api/logcontroller.cpp
  18. 52
      src/webui/api/rsscontroller.cpp
  19. 88
      src/webui/api/searchcontroller.cpp
  20. 100
      src/webui/api/serialize/serialize_torrent.h
  21. 116
      src/webui/api/synccontroller.cpp
  22. 432
      src/webui/api/torrentscontroller.cpp
  23. 28
      src/webui/api/transfercontroller.cpp
  24. 34
      src/webui/webapplication.cpp
  25. 2
      src/webui/webui.cpp

1
cmake/Modules/MacroQbtCommonConfig.cmake

@ -18,6 +18,7 @@ macro(qbt_common_config)
target_compile_definitions(qbt_common_cfg INTERFACE target_compile_definitions(qbt_common_cfg INTERFACE
QT_DISABLE_DEPRECATED_BEFORE=0x050f02 QT_DISABLE_DEPRECATED_BEFORE=0x050f02
QT_NO_CAST_FROM_ASCII
QT_NO_CAST_TO_ASCII QT_NO_CAST_TO_ASCII
QT_NO_CAST_FROM_BYTEARRAY QT_NO_CAST_FROM_BYTEARRAY
QT_USE_QSTRINGBUILDER QT_USE_QSTRINGBUILDER

11
src/app/application.cpp

@ -44,6 +44,7 @@
#endif #endif
#include <QAtomicInt> #include <QAtomicInt>
#include <QByteArray>
#include <QDebug> #include <QDebug>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QProcess> #include <QProcess>
@ -326,7 +327,7 @@ void Application::runExternalProgram(const BitTorrent::Torrent *torrent) const
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
const auto chopPathSep = [](const QString &str) -> QString const auto chopPathSep = [](const QString &str) -> QString
{ {
if (str.endsWith('\\')) if (str.endsWith(u'\\'))
return str.mid(0, (str.length() -1)); return str.mid(0, (str.length() -1));
return str; return str;
}; };
@ -677,11 +678,11 @@ int Application::exec(const QStringList &params)
+ tr("To control qBittorrent, access the WebUI at: %1").arg(url); + tr("To control qBittorrent, access the WebUI at: %1").arg(url);
printf("%s\n", qUtf8Printable(mesg)); printf("%s\n", qUtf8Printable(mesg));
if (pref->getWebUIPassword() == "ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtHAjU9b3b7uB8NR1Gur2hmQCvCDpm39Q+PsJRJPaCU51dEiz+dTzh8qbPsL8WkFljQYFQ==") if (pref->getWebUIPassword() == QByteArrayLiteral("ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtHAjU9b3b7uB8NR1Gur2hmQCvCDpm39Q+PsJRJPaCU51dEiz+dTzh8qbPsL8WkFljQYFQ=="))
{ {
const QString warning = tr("The Web UI administrator username is: %1").arg(pref->getWebUiUsername()) + '\n' const QString warning = tr("The Web UI administrator username is: %1").arg(pref->getWebUiUsername()) + u'\n'
+ tr("The Web UI administrator password has not been changed from the default: %1").arg("adminadmin") + '\n' + tr("The Web UI administrator password has not been changed from the default: %1").arg(u"adminadmin"_qs) + u'\n'
+ tr("This is a security risk, please change your password in program preferences.") + '\n'; + tr("This is a security risk, please change your password in program preferences.") + u'\n';
printf("%s", qUtf8Printable(warning)); printf("%s", qUtf8Printable(warning));
} }
#endif // DISABLE_WEBUI #endif // DISABLE_WEBUI

6
src/app/main.cpp

@ -416,9 +416,9 @@ bool userAgreesWithLegalNotice()
#ifdef DISABLE_GUI #ifdef DISABLE_GUI
const QString eula = QString::fromLatin1("\n*** %1 ***\n").arg(QObject::tr("Legal Notice")) const QString eula = QString::fromLatin1("\n*** %1 ***\n").arg(QObject::tr("Legal Notice"))
+ QObject::tr("qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.") + "\n\n" + QObject::tr("qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.") + u"\n\n"
+ QObject::tr("No further notices will be issued.") + "\n\n" + QObject::tr("No further notices will be issued.") + u"\n\n"
+ QObject::tr("Press %1 key to accept and continue...").arg("'y'") + '\n'; + QObject::tr("Press %1 key to accept and continue...").arg(u"'y'"_qs) + u'\n';
printf("%s", qUtf8Printable(eula)); printf("%s", qUtf8Printable(eula));
const char ret = getchar(); // Read pressed key const char ret = getchar(); // Read pressed key

36
src/app/stacktrace_win.h

@ -31,6 +31,8 @@
#include <cxxabi.h> #include <cxxabi.h>
#endif #endif
#include "base/global.h"
namespace straceWin namespace straceWin
{ {
void loadHelpStackFrame(IMAGEHLP_STACK_FRAME&, const STACKFRAME64&); void loadHelpStackFrame(IMAGEHLP_STACK_FRAME&, const STACKFRAME64&);
@ -50,7 +52,7 @@ namespace straceWin
#ifdef __MINGW32__ #ifdef __MINGW32__
void straceWin::demangle(QString& str) void straceWin::demangle(QString& str)
{ {
char const* inStr = qPrintable("_" + str); // Really need that underline or demangling will fail char const* inStr = qPrintable(u"_" + str); // Really need that underline or demangling will fail
int status = 0; int status = 0;
size_t outSz = 0; size_t outSz = 0;
char* demangled_name = abi::__cxa_demangle(inStr, 0, &outSz, &status); char* demangled_name = abi::__cxa_demangle(inStr, 0, &outSz, &status);
@ -75,7 +77,7 @@ BOOL CALLBACK straceWin::EnumSymbolsCB(PSYMBOL_INFO symInfo, ULONG size, PVOID u
Q_UNUSED(size) Q_UNUSED(size)
auto params = static_cast<QStringList *>(user); auto params = static_cast<QStringList *>(user);
if (symInfo->Flags & SYMFLAG_PARAMETER) if (symInfo->Flags & SYMFLAG_PARAMETER)
params->append(symInfo->Name); params->append(QString::fromUtf8(symInfo->Name));
return TRUE; return TRUE;
} }
@ -97,16 +99,16 @@ BOOL CALLBACK straceWin::EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVO
{ {
QString moduleBase = QString::fromLatin1("0x%1").arg(BaseOfDll, 16, 16, QLatin1Char('0')); QString moduleBase = QString::fromLatin1("0x%1").arg(BaseOfDll, 16, 16, QLatin1Char('0'));
QString line = QString::fromLatin1("%1 %2 Image: %3") QString line = QString::fromLatin1("%1 %2 Image: %3")
.arg(mod.ModuleName, -25) .arg(QString::fromUtf8(mod.ModuleName), -25)
.arg(moduleBase, -13) .arg(moduleBase, -13)
.arg(mod.LoadedImageName); .arg(QString::fromUtf8(mod.LoadedImageName));
context->stream << line << '\n'; context->stream << line << '\n';
QString pdbName(mod.LoadedPdbName); const auto pdbName = QString::fromUtf8(mod.LoadedPdbName);
if(!pdbName.isEmpty()) if(!pdbName.isEmpty())
{ {
QString line2 = QString::fromLatin1("%1 %2") QString line2 = QString::fromLatin1("%1 %2")
.arg("", 35) .arg(u""_qs, 35)
.arg(pdbName); .arg(pdbName);
context->stream << line2 << '\n'; context->stream << line2 << '\n';
} }
@ -119,7 +121,7 @@ BOOL CALLBACK straceWin::EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVO
* Cuts off leading 'dir' path from 'file' path, otherwise leaves it unchanged * Cuts off leading 'dir' path from 'file' path, otherwise leaves it unchanged
* returns true if 'dir' is an ancestor of 'file', otherwise - false * returns true if 'dir' is an ancestor of 'file', otherwise - false
*/ */
bool straceWin::makeRelativePath(const QString& dir, QString& file) bool straceWin::makeRelativePath(const QString &dir, QString &file)
{ {
QString d = QDir::toNativeSeparators(QDir(dir).absolutePath()); QString d = QDir::toNativeSeparators(QDir(dir).absolutePath());
QString f = QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath()); QString f = QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath());
@ -148,7 +150,7 @@ QString straceWin::getSourcePathAndLineNumber(HANDLE hProcess, DWORD64 addr)
if (SymGetLineFromAddr64(hProcess, addr, &dwDisplacement, &line)) if (SymGetLineFromAddr64(hProcess, addr, &dwDisplacement, &line))
{ {
QString path(line.FileName); auto path = QString::fromUtf8(line.FileName);
#if defined STACKTRACE_WIN_PROJECT_PATH || defined STACKTRACE_WIN_MAKEFILE_PATH #if defined STACKTRACE_WIN_PROJECT_PATH || defined STACKTRACE_WIN_MAKEFILE_PATH
@ -159,14 +161,14 @@ QString straceWin::getSourcePathAndLineNumber(HANDLE hProcess, DWORD64 addr)
bool success = false; bool success = false;
#ifdef STACKTRACE_WIN_PROJECT_PATH #ifdef STACKTRACE_WIN_PROJECT_PATH
QString projectPath(STACKTRACE_WIN_STRING(STACKTRACE_WIN_PROJECT_PATH)); const auto projectPath = QStringLiteral(STACKTRACE_WIN_STRING(STACKTRACE_WIN_PROJECT_PATH));
success = makeRelativePath(projectPath, path); success = makeRelativePath(projectPath, path);
#endif #endif
#ifdef STACKTRACE_WIN_MAKEFILE_PATH #ifdef STACKTRACE_WIN_MAKEFILE_PATH
if (!success) if (!success)
{ {
QString targetPath(STACKTRACE_WIN_STRING(STACKTRACE_WIN_MAKEFILE_PATH)); const auto targetPath = QStringLiteral(STACKTRACE_WIN_STRING(STACKTRACE_WIN_MAKEFILE_PATH));
makeRelativePath(targetPath, path); makeRelativePath(targetPath, path);
} }
#endif #endif
@ -285,11 +287,11 @@ const QString straceWin::getBacktrace()
if(StackFrame.AddrPC.Offset != 0) if(StackFrame.AddrPC.Offset != 0)
{ // Valid frame. { // Valid frame.
QString fileName("???"); auto fileName = u"???"_qs;
if(SymGetModuleInfo64(hProcess, ihsf.InstructionOffset, &mod)) if(SymGetModuleInfo64(hProcess, ihsf.InstructionOffset, &mod))
{ {
fileName = QString(mod.ImageName); fileName = QString::fromUtf8(mod.ImageName);
int slashPos = fileName.lastIndexOf('\\'); int slashPos = fileName.lastIndexOf(u'\\');
if(slashPos != -1) if(slashPos != -1)
fileName = fileName.mid(slashPos + 1); fileName = fileName.mid(slashPos + 1);
} }
@ -297,7 +299,7 @@ const QString straceWin::getBacktrace()
QString sourceFile; QString sourceFile;
if(SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol)) if(SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol))
{ {
funcName = QString(pSymbol->Name); funcName = QString::fromUtf8(pSymbol->Name);
#ifdef __MINGW32__ #ifdef __MINGW32__
demangle(funcName); demangle(funcName);
#endif #endif
@ -317,9 +319,9 @@ const QString straceWin::getBacktrace()
#endif #endif
QString insOffset = QString::fromLatin1("0x%1").arg(ihsf.InstructionOffset, 16, 16, QLatin1Char('0')); QString insOffset = QString::fromLatin1("0x%1").arg(ihsf.InstructionOffset, 16, 16, QLatin1Char('0'));
QString formatLine = "#%1 %2 %3 %4"; auto formatLine = u"#%1 %2 %3 %4"_qs;
#ifndef __MINGW32__ #ifndef __MINGW32__
formatLine += "(%5)"; formatLine += u"(%5)"_qs;
#endif #endif
QString debugLine = formatLine QString debugLine = formatLine
.arg(i, 3, 10) .arg(i, 3, 10)
@ -327,7 +329,7 @@ const QString straceWin::getBacktrace()
.arg(insOffset, -11) .arg(insOffset, -11)
.arg(funcName) .arg(funcName)
#ifndef __MINGW32__ #ifndef __MINGW32__
.arg(params.join(", ")); .arg(params.join(u", "));
if (!sourceFile.isEmpty()) if (!sourceFile.isEmpty())
debugLine += QString::fromLatin1("[ %1 ]").arg(sourceFile); debugLine += QString::fromLatin1("[ %1 ]").arg(sourceFile);

2
src/app/stacktracedialog.cpp

@ -50,7 +50,7 @@ StacktraceDialog::~StacktraceDialog()
void StacktraceDialog::setStacktraceString(const QString &sigName, const QString &trace) void StacktraceDialog::setStacktraceString(const QString &sigName, const QString &trace)
{ {
// try to call Qt function as less as possible // try to call Qt function as less as possible
const QString htmlStr = QString( const QString htmlStr = QStringLiteral(
"<p align=center><b><font size=7 color=red>" "<p align=center><b><font size=7 color=red>"
"qBittorrent has crashed" "qBittorrent has crashed"
"</font></b></p>" "</font></b></p>"

2
src/base/bittorrent/session.cpp

@ -3170,7 +3170,7 @@ void Session::setOSMemoryPriority(const OSMemoryPriority priority)
void Session::applyOSMemoryPriority() const void Session::applyOSMemoryPriority() const
{ {
using SETPROCESSINFORMATION = BOOL (WINAPI *)(HANDLE, PROCESS_INFORMATION_CLASS, LPVOID, DWORD); using SETPROCESSINFORMATION = BOOL (WINAPI *)(HANDLE, PROCESS_INFORMATION_CLASS, LPVOID, DWORD);
const auto setProcessInformation = Utils::Misc::loadWinAPI<SETPROCESSINFORMATION>("Kernel32.dll", "SetProcessInformation"); const auto setProcessInformation = Utils::Misc::loadWinAPI<SETPROCESSINFORMATION>(u"Kernel32.dll"_qs, "SetProcessInformation");
if (!setProcessInformation) // only available on Windows >= 8 if (!setProcessInformation) // only available on Windows >= 8
return; return;

16
src/base/utils/foreignapps.cpp

@ -186,7 +186,7 @@ namespace
bool found = false; bool found = false;
while (!found && !versions.empty()) while (!found && !versions.empty())
{ {
const QString version = versions.takeLast() + "\\InstallPath"; const QString version = versions.takeLast() + u"\\InstallPath";
LPWSTR lpSubkey = new WCHAR[version.size() + 1]; LPWSTR lpSubkey = new WCHAR[version.size() + 1];
version.toWCharArray(lpSubkey); version.toWCharArray(lpSubkey);
lpSubkey[version.size()] = 0; lpSubkey[version.size()] = 0;
@ -205,15 +205,15 @@ namespace
{ {
const QDir baseDir {path}; const QDir baseDir {path};
if (baseDir.exists("python3.exe")) if (baseDir.exists(u"python3.exe"_qs))
{ {
found = true; found = true;
path = baseDir.filePath("python3.exe"); path = baseDir.filePath(u"python3.exe"_qs);
} }
else if (baseDir.exists("python.exe")) else if (baseDir.exists(u"python.exe"_qs))
{ {
found = true; found = true;
path = baseDir.filePath("python.exe"); path = baseDir.filePath(u"python.exe"_qs);
} }
} }
} }
@ -243,14 +243,14 @@ namespace
return path; return path;
// Fallback: Detect python from default locations // Fallback: Detect python from default locations
const QFileInfoList dirs = QDir("C:/").entryInfoList({"Python*"}, QDir::Dirs, (QDir::Name | QDir::Reversed)); const QFileInfoList dirs = QDir(u"C:/"_qs).entryInfoList({u"Python*"_qs}, QDir::Dirs, (QDir::Name | QDir::Reversed));
for (const QFileInfo &info : dirs) for (const QFileInfo &info : dirs)
{ {
const QString py3Path {info.absolutePath() + "/python3.exe"}; const QString py3Path {info.absolutePath() + u"/python3.exe"};
if (QFile::exists(py3Path)) if (QFile::exists(py3Path))
return py3Path; return py3Path;
const QString pyPath {info.absolutePath() + "/python.exe"}; const QString pyPath {info.absolutePath() + u"/python.exe"};
if (QFile::exists(pyPath)) if (QFile::exists(pyPath))
return pyPath; return pyPath;
} }

4
src/base/utils/misc.h

@ -93,8 +93,8 @@ namespace Utils::Misc
T loadWinAPI(const QString &source, const char *funcName) T loadWinAPI(const QString &source, const char *funcName)
{ {
QString path = windowsSystemPath(); QString path = windowsSystemPath();
if (!path.endsWith('\\')) if (!path.endsWith(u'\\'))
path += '\\'; path += u'\\';
path += source; path += source;

5
src/base/utils/random.cpp

@ -43,7 +43,8 @@
#include <QString> #include <QString>
#include "misc.h" #include "base/global.h"
#include "base/utils/misc.h"
namespace namespace
{ {
@ -55,7 +56,7 @@ namespace
using result_type = uint32_t; using result_type = uint32_t;
RandomLayer() RandomLayer()
: m_rtlGenRandom {Utils::Misc::loadWinAPI<PRTLGENRANDOM>("Advapi32.dll", "SystemFunction036")} : m_rtlGenRandom {Utils::Misc::loadWinAPI<PRTLGENRANDOM>(u"Advapi32.dll"_qs, "SystemFunction036")}
{ {
if (!m_rtlGenRandom) if (!m_rtlGenRandom)
qFatal("Failed to load RtlGenRandom()"); qFatal("Failed to load RtlGenRandom()");

12
src/gui/mainwindow.cpp

@ -1604,7 +1604,7 @@ void MainWindow::reloadSessionStats()
} }
else if (!MacUtils::badgeLabelText().isEmpty()) else if (!MacUtils::badgeLabelText().isEmpty())
{ {
MacUtils::setBadgeLabelText(""); MacUtils::setBadgeLabelText({});
} }
#else #else
if (m_systrayIcon) if (m_systrayIcon)
@ -1905,8 +1905,8 @@ void MainWindow::handleUpdateCheckFinished(ProgramUpdater *updater, const bool i
const QString newVersion = updater->getNewVersion(); const QString newVersion = updater->getNewVersion();
if (!newVersion.isEmpty()) if (!newVersion.isEmpty())
{ {
const QString msg {tr("A new version is available.") + "<br/>" const QString msg {tr("A new version is available.") + u"<br/>"
+ tr("Do you want to download %1?").arg(newVersion) + "<br/><br/>" + tr("Do you want to download %1?").arg(newVersion) + u"<br/><br/>"
+ QString::fromLatin1("<a href=\"https://www.qbittorrent.org/news.php\">%1</a>").arg(tr("Open changelog..."))}; + QString::fromLatin1("<a href=\"https://www.qbittorrent.org/news.php\">%1</a>").arg(tr("Open changelog..."))};
auto *msgBox = new QMessageBox {QMessageBox::Question, tr("qBittorrent Update Available"), msg auto *msgBox = new QMessageBox {QMessageBox::Question, tr("qBittorrent Update Available"), msg
, (QMessageBox::Yes | QMessageBox::No), this}; , (QMessageBox::Yes | QMessageBox::No), this};
@ -2082,9 +2082,9 @@ void MainWindow::installPython()
setCursor(QCursor(Qt::WaitCursor)); setCursor(QCursor(Qt::WaitCursor));
// Download python // Download python
#ifdef QBT_APP_64BIT #ifdef QBT_APP_64BIT
const QString installerURL = "https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe"; const auto installerURL = u"https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe"_qs;
#else #else
const QString installerURL = "https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"; const auto installerURL = u"https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"_qs;
#endif #endif
Net::DownloadManager::instance()->download( Net::DownloadManager::instance()->download(
Net::DownloadRequest(installerURL).saveToFile(true) Net::DownloadRequest(installerURL).saveToFile(true)
@ -2109,7 +2109,7 @@ void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result)
const Path exePath = result.filePath + ".exe"; const Path exePath = result.filePath + ".exe";
Utils::Fs::renameFile(result.filePath, exePath); Utils::Fs::renameFile(result.filePath, exePath);
installer.start(exePath.toString(), {"/passive"}); installer.start(exePath.toString(), {u"/passive"_qs});
// Wait for setup to complete // Wait for setup to complete
installer.waitForFinished(10 * 60 * 1000); installer.waitForFinished(10 * 60 * 1000);

11
src/gui/programupdater.cpp

@ -43,6 +43,7 @@
#include <QSysInfo> #include <QSysInfo>
#endif #endif
#include "base/global.h"
#include "base/net/downloadmanager.h" #include "base/net/downloadmanager.h"
#include "base/utils/version.h" #include "base/utils/version.h"
#include "base/version.h" #include "base/version.h"
@ -79,7 +80,7 @@ void ProgramUpdater::checkForUpdates() const
// Don't change this User-Agent. In case our updater goes haywire, // Don't change this User-Agent. In case our updater goes haywire,
// the filehost can identify it and contact us. // the filehost can identify it and contact us.
Net::DownloadManager::instance()->download( Net::DownloadManager::instance()->download(
Net::DownloadRequest(RSS_URL).userAgent("qBittorrent/" QBT_VERSION_2 " ProgramUpdater (www.qbittorrent.org)") Net::DownloadRequest(RSS_URL).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2 " ProgramUpdater (www.qbittorrent.org)"))
, this, &ProgramUpdater::rssDownloadFinished); , this, &ProgramUpdater::rssDownloadFinished);
} }
@ -108,11 +109,11 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
}; };
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
const QString OS_TYPE {"Mac OS X"}; const QString OS_TYPE = u"Mac OS X"_qs;
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
const QString OS_TYPE {(::IsWindows7OrGreater() const QString OS_TYPE = (::IsWindows7OrGreater() && QSysInfo::currentCpuArchitecture().endsWith(u"64"))
&& QSysInfo::currentCpuArchitecture().endsWith("64")) ? u"Windows x64"_qs
? "Windows x64" : "Windows"}; : u"Windows"_qs;
#endif #endif
bool inItem = false; bool inItem = false;

4
src/gui/progressbarpainter.cpp

@ -37,10 +37,12 @@
#include <QProxyStyle> #include <QProxyStyle>
#endif #endif
#include "base/global.h"
ProgressBarPainter::ProgressBarPainter() ProgressBarPainter::ProgressBarPainter()
{ {
#if (defined(Q_OS_WIN) || defined(Q_OS_MACOS)) #if (defined(Q_OS_WIN) || defined(Q_OS_MACOS))
auto *fusionStyle = new QProxyStyle {"fusion"}; auto *fusionStyle = new QProxyStyle {u"fusion"_qs};
fusionStyle->setParent(&m_dummyProgressBar); fusionStyle->setParent(&m_dummyProgressBar);
m_dummyProgressBar.setStyle(fusionStyle); m_dummyProgressBar.setStyle(fusionStyle);
#endif #endif

2
src/gui/transferlistmodel.cpp

@ -168,7 +168,7 @@ QVariant TransferListModel::headerData(int section, Qt::Orientation orientation,
{ {
switch (section) switch (section)
{ {
case TR_QUEUE_POSITION: return u'#'; case TR_QUEUE_POSITION: return QChar(u'#');
case TR_NAME: return tr("Name", "i.e: torrent name"); case TR_NAME: return tr("Name", "i.e: torrent name");
case TR_SIZE: return tr("Size", "i.e: torrent size"); case TR_SIZE: return tr("Size", "i.e: torrent size");
case TR_PROGRESS: return tr("Progress", "% Done"); case TR_PROGRESS: return tr("Progress", "% Done");

1
src/src.pro

@ -57,6 +57,7 @@ include(../version.pri)
# Qt defines # Qt defines
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050f02 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050f02
DEFINES += QT_NO_CAST_FROM_ASCII
DEFINES += QT_NO_CAST_TO_ASCII DEFINES += QT_NO_CAST_TO_ASCII
DEFINES += QT_NO_CAST_FROM_BYTEARRAY DEFINES += QT_NO_CAST_FROM_BYTEARRAY
DEFINES += QT_USE_QSTRINGBUILDER DEFINES += QT_USE_QSTRINGBUILDER

684
src/webui/api/appcontroller.cpp

File diff suppressed because it is too large Load Diff

5
src/webui/api/authcontroller.cpp

@ -30,6 +30,7 @@
#include <QString> #include <QString>
#include "base/global.h"
#include "base/logger.h" #include "base/logger.h"
#include "base/preferences.h" #include "base/preferences.h"
#include "base/utils/password.h" #include "base/utils/password.h"
@ -45,8 +46,8 @@ void AuthController::loginAction()
} }
const QString clientAddr {sessionManager()->clientId()}; const QString clientAddr {sessionManager()->clientId()};
const QString usernameFromWeb {params()["username"]}; const QString usernameFromWeb {params()[u"username"_qs]};
const QString passwordFromWeb {params()["password"]}; const QString passwordFromWeb {params()[u"password"_qs]};
if (isBanned()) if (isBanned())
{ {

12
src/webui/api/logcontroller.cpp

@ -61,13 +61,13 @@ void LogController::mainAction()
{ {
using Utils::String::parseBool; using Utils::String::parseBool;
const bool isNormal = parseBool(params()["normal"]).value_or(true); const bool isNormal = parseBool(params()[u"normal"_qs]).value_or(true);
const bool isInfo = parseBool(params()["info"]).value_or(true); const bool isInfo = parseBool(params()[u"info"_qs]).value_or(true);
const bool isWarning = parseBool(params()["warning"]).value_or(true); const bool isWarning = parseBool(params()[u"warning"_qs]).value_or(true);
const bool isCritical = parseBool(params()["critical"]).value_or(true); const bool isCritical = parseBool(params()[u"critical"_qs]).value_or(true);
bool ok = false; bool ok = false;
int lastKnownId = params()["last_known_id"].toInt(&ok); int lastKnownId = params()[u"last_known_id"_qs].toInt(&ok);
if (!ok) if (!ok)
lastKnownId = -1; lastKnownId = -1;
@ -107,7 +107,7 @@ void LogController::mainAction()
void LogController::peersAction() void LogController::peersAction()
{ {
bool ok = false; bool ok = false;
int lastKnownId = params()["last_known_id"].toInt(&ok); int lastKnownId = params()[u"last_known_id"_qs].toInt(&ok);
if (!ok) if (!ok)
lastKnownId = -1; lastKnownId = -1;

52
src/webui/api/rsscontroller.cpp

@ -47,9 +47,9 @@ using Utils::String::parseBool;
void RSSController::addFolderAction() void RSSController::addFolderAction()
{ {
requireParams({"path"}); requireParams({u"path"_qs});
const QString path = params()["path"].trimmed(); const QString path = params()[u"path"_qs].trimmed();
const nonstd::expected<void, QString> result = RSS::Session::instance()->addFolder(path); const nonstd::expected<void, QString> result = RSS::Session::instance()->addFolder(path);
if (!result) if (!result)
throw APIError(APIErrorType::Conflict, result.error()); throw APIError(APIErrorType::Conflict, result.error());
@ -57,10 +57,10 @@ void RSSController::addFolderAction()
void RSSController::addFeedAction() void RSSController::addFeedAction()
{ {
requireParams({"url", "path"}); requireParams({u"url"_qs, u"path"_qs});
const QString url = params()["url"].trimmed(); const QString url = params()[u"url"_qs].trimmed();
const QString path = params()["path"].trimmed(); const QString path = params()[u"path"_qs].trimmed();
const nonstd::expected<void, QString> result = RSS::Session::instance()->addFeed(url, (path.isEmpty() ? url : path)); const nonstd::expected<void, QString> result = RSS::Session::instance()->addFeed(url, (path.isEmpty() ? url : path));
if (!result) if (!result)
throw APIError(APIErrorType::Conflict, result.error()); throw APIError(APIErrorType::Conflict, result.error());
@ -68,9 +68,9 @@ void RSSController::addFeedAction()
void RSSController::removeItemAction() void RSSController::removeItemAction()
{ {
requireParams({"path"}); requireParams({u"path"_qs});
const QString path = params()["path"].trimmed(); const QString path = params()[u"path"_qs].trimmed();
const nonstd::expected<void, QString> result = RSS::Session::instance()->removeItem(path); const nonstd::expected<void, QString> result = RSS::Session::instance()->removeItem(path);
if (!result) if (!result)
throw APIError(APIErrorType::Conflict, result.error()); throw APIError(APIErrorType::Conflict, result.error());
@ -78,10 +78,10 @@ void RSSController::removeItemAction()
void RSSController::moveItemAction() void RSSController::moveItemAction()
{ {
requireParams({"itemPath", "destPath"}); requireParams({u"itemPath"_qs, u"destPath"_qs});
const QString itemPath = params()["itemPath"].trimmed(); const QString itemPath = params()[u"itemPath"_qs].trimmed();
const QString destPath = params()["destPath"].trimmed(); const QString destPath = params()[u"destPath"_qs].trimmed();
const nonstd::expected<void, QString> result = RSS::Session::instance()->moveItem(itemPath, destPath); const nonstd::expected<void, QString> result = RSS::Session::instance()->moveItem(itemPath, destPath);
if (!result) if (!result)
throw APIError(APIErrorType::Conflict, result.error()); throw APIError(APIErrorType::Conflict, result.error());
@ -89,7 +89,7 @@ void RSSController::moveItemAction()
void RSSController::itemsAction() void RSSController::itemsAction()
{ {
const bool withData {parseBool(params()["withData"]).value_or(false)}; const bool withData {parseBool(params()[u"withData"_qs]).value_or(false)};
const auto jsonVal = RSS::Session::instance()->rootFolder()->toJsonValue(withData); const auto jsonVal = RSS::Session::instance()->rootFolder()->toJsonValue(withData);
setResult(jsonVal.toObject()); setResult(jsonVal.toObject());
@ -97,10 +97,10 @@ void RSSController::itemsAction()
void RSSController::markAsReadAction() void RSSController::markAsReadAction()
{ {
requireParams({"itemPath"}); requireParams({u"itemPath"_qs});
const QString itemPath {params()["itemPath"]}; const QString itemPath {params()[u"itemPath"_qs]};
const QString articleId {params()["articleId"]}; const QString articleId {params()[u"articleId"_qs]};
RSS::Item *item = RSS::Session::instance()->itemByPath(itemPath); RSS::Item *item = RSS::Session::instance()->itemByPath(itemPath);
if (!item) return; if (!item) return;
@ -123,9 +123,9 @@ void RSSController::markAsReadAction()
void RSSController::refreshItemAction() void RSSController::refreshItemAction()
{ {
requireParams({"itemPath"}); requireParams({u"itemPath"_qs});
const QString itemPath {params()["itemPath"]}; const QString itemPath {params()[u"itemPath"_qs]};
RSS::Item *item = RSS::Session::instance()->itemByPath(itemPath); RSS::Item *item = RSS::Session::instance()->itemByPath(itemPath);
if (item) if (item)
item->refresh(); item->refresh();
@ -133,10 +133,10 @@ void RSSController::refreshItemAction()
void RSSController::setRuleAction() void RSSController::setRuleAction()
{ {
requireParams({"ruleName", "ruleDef"}); requireParams({u"ruleName"_qs, u"ruleDef"_qs});
const QString ruleName {params()["ruleName"].trimmed()}; const QString ruleName {params()[u"ruleName"_qs].trimmed()};
const QByteArray ruleDef {params()["ruleDef"].trimmed().toUtf8()}; const QByteArray ruleDef {params()[u"ruleDef"_qs].trimmed().toUtf8()};
const auto jsonObj = QJsonDocument::fromJson(ruleDef).object(); const auto jsonObj = QJsonDocument::fromJson(ruleDef).object();
RSS::AutoDownloader::instance()->insertRule(RSS::AutoDownloadRule::fromJsonObject(jsonObj, ruleName)); RSS::AutoDownloader::instance()->insertRule(RSS::AutoDownloadRule::fromJsonObject(jsonObj, ruleName));
@ -144,19 +144,19 @@ void RSSController::setRuleAction()
void RSSController::renameRuleAction() void RSSController::renameRuleAction()
{ {
requireParams({"ruleName", "newRuleName"}); requireParams({u"ruleName"_qs, u"newRuleName"_qs});
const QString ruleName {params()["ruleName"].trimmed()}; const QString ruleName {params()[u"ruleName"_qs].trimmed()};
const QString newRuleName {params()["newRuleName"].trimmed()}; const QString newRuleName {params()[u"newRuleName"_qs].trimmed()};
RSS::AutoDownloader::instance()->renameRule(ruleName, newRuleName); RSS::AutoDownloader::instance()->renameRule(ruleName, newRuleName);
} }
void RSSController::removeRuleAction() void RSSController::removeRuleAction()
{ {
requireParams({"ruleName"}); requireParams({u"ruleName"_qs});
const QString ruleName {params()["ruleName"].trimmed()}; const QString ruleName {params()[u"ruleName"_qs].trimmed()};
RSS::AutoDownloader::instance()->removeRule(ruleName); RSS::AutoDownloader::instance()->removeRule(ruleName);
} }
@ -172,9 +172,9 @@ void RSSController::rulesAction()
void RSSController::matchingArticlesAction() void RSSController::matchingArticlesAction()
{ {
requireParams({"ruleName"}); requireParams({u"ruleName"_qs});
const QString ruleName {params()["ruleName"]}; const QString ruleName {params()[u"ruleName"_qs]};
const RSS::AutoDownloadRule rule = RSS::AutoDownloader::instance()->ruleByName(ruleName); const RSS::AutoDownloadRule rule = RSS::AutoDownloader::instance()->ruleByName(ruleName);
QJsonObject jsonObj; QJsonObject jsonObj;

88
src/webui/api/searchcontroller.cpp

@ -72,8 +72,8 @@ namespace
{ {
QJsonArray categoriesInfo QJsonArray categoriesInfo
{QJsonObject { {QJsonObject {
{QLatin1String("id"), "all"}, {QLatin1String("id"), u"all"_qs},
{QLatin1String("name"), SearchPluginManager::categoryFullName("all")} {QLatin1String("name"), SearchPluginManager::categoryFullName(u"all"_qs)}
}}; }};
categories.sort(Qt::CaseInsensitive); categories.sort(Qt::CaseInsensitive);
@ -92,22 +92,22 @@ namespace
void SearchController::startAction() void SearchController::startAction()
{ {
requireParams({"pattern", "category", "plugins"}); requireParams({u"pattern"_qs, u"category"_qs, u"plugins"_qs});
if (!Utils::ForeignApps::pythonInfo().isValid()) if (!Utils::ForeignApps::pythonInfo().isValid())
throw APIError(APIErrorType::Conflict, tr("Python must be installed to use the Search Engine.")); throw APIError(APIErrorType::Conflict, tr("Python must be installed to use the Search Engine."));
const QString pattern = params()["pattern"].trimmed(); const QString pattern = params()[u"pattern"_qs].trimmed();
const QString category = params()["category"].trimmed(); const QString category = params()[u"category"_qs].trimmed();
const QStringList plugins = params()["plugins"].split('|'); const QStringList plugins = params()[u"plugins"_qs].split(u'|');
QStringList pluginsToUse; QStringList pluginsToUse;
if (plugins.size() == 1) if (plugins.size() == 1)
{ {
const QString pluginsLower = plugins[0].toLower(); const QString pluginsLower = plugins[0].toLower();
if (pluginsLower == "all") if (pluginsLower == u"all")
pluginsToUse = SearchPluginManager::instance()->allPlugins(); pluginsToUse = SearchPluginManager::instance()->allPlugins();
else if ((pluginsLower == "enabled") || (pluginsLower == "multi")) else if ((pluginsLower == u"enabled") || (pluginsLower == u"multi"))
pluginsToUse = SearchPluginManager::instance()->enabledPlugins(); pluginsToUse = SearchPluginManager::instance()->enabledPlugins();
else else
pluginsToUse << plugins; pluginsToUse << plugins;
@ -134,15 +134,15 @@ void SearchController::startAction()
activeSearches.insert(id); activeSearches.insert(id);
session->setData(ACTIVE_SEARCHES, QVariant::fromValue(activeSearches)); session->setData(ACTIVE_SEARCHES, QVariant::fromValue(activeSearches));
const QJsonObject result = {{"id", id}}; const QJsonObject result = {{u"id"_qs, id}};
setResult(result); setResult(result);
} }
void SearchController::stopAction() void SearchController::stopAction()
{ {
requireParams({"id"}); requireParams({u"id"_qs});
const int id = params()["id"].toInt(); const int id = params()[u"id"_qs].toInt();
ISession *const session = sessionManager()->session(); ISession *const session = sessionManager()->session();
const auto searchHandlers = session->getData<SearchHandlerDict>(SEARCH_HANDLERS); const auto searchHandlers = session->getData<SearchHandlerDict>(SEARCH_HANDLERS);
@ -160,7 +160,7 @@ void SearchController::stopAction()
void SearchController::statusAction() void SearchController::statusAction()
{ {
const int id = params()["id"].toInt(); const int id = params()[u"id"_qs].toInt();
const auto searchHandlers = sessionManager()->session()->getData<SearchHandlerDict>(SEARCH_HANDLERS); const auto searchHandlers = sessionManager()->session()->getData<SearchHandlerDict>(SEARCH_HANDLERS);
if ((id != 0) && !searchHandlers.contains(id)) if ((id != 0) && !searchHandlers.contains(id))
@ -174,9 +174,9 @@ void SearchController::statusAction()
const SearchHandlerPtr searchHandler = searchHandlers[searchId]; const SearchHandlerPtr searchHandler = searchHandlers[searchId];
statusArray << QJsonObject statusArray << QJsonObject
{ {
{"id", searchId}, {u"id"_qs, searchId},
{"status", searchHandler->isActive() ? "Running" : "Stopped"}, {u"status"_qs, searchHandler->isActive() ? u"Running"_qs : u"Stopped"_qs},
{"total", searchHandler->results().size()} {u"total"_qs, searchHandler->results().size()}
}; };
} }
@ -185,11 +185,11 @@ void SearchController::statusAction()
void SearchController::resultsAction() void SearchController::resultsAction()
{ {
requireParams({"id"}); requireParams({u"id"_qs});
const int id = params()["id"].toInt(); const int id = params()[u"id"_qs].toInt();
int limit = params()["limit"].toInt(); int limit = params()[u"limit"_qs].toInt();
int offset = params()["offset"].toInt(); int offset = params()[u"offset"_qs].toInt();
const auto searchHandlers = sessionManager()->session()->getData<SearchHandlerDict>(SEARCH_HANDLERS); const auto searchHandlers = sessionManager()->session()->getData<SearchHandlerDict>(SEARCH_HANDLERS);
if (!searchHandlers.contains(id)) if (!searchHandlers.contains(id))
@ -218,9 +218,9 @@ void SearchController::resultsAction()
void SearchController::deleteAction() void SearchController::deleteAction()
{ {
requireParams({"id"}); requireParams({u"id"_qs});
const int id = params()["id"].toInt(); const int id = params()[u"id"_qs].toInt();
ISession *const session = sessionManager()->session(); ISession *const session = sessionManager()->session();
auto searchHandlers = session->getData<SearchHandlerDict>(SEARCH_HANDLERS); auto searchHandlers = session->getData<SearchHandlerDict>(SEARCH_HANDLERS);
@ -243,28 +243,28 @@ void SearchController::pluginsAction()
void SearchController::installPluginAction() void SearchController::installPluginAction()
{ {
requireParams({"sources"}); requireParams({u"sources"_qs});
const QStringList sources = params()["sources"].split('|'); const QStringList sources = params()[u"sources"_qs].split(u'|');
for (const QString &source : sources) for (const QString &source : sources)
SearchPluginManager::instance()->installPlugin(source); SearchPluginManager::instance()->installPlugin(source);
} }
void SearchController::uninstallPluginAction() void SearchController::uninstallPluginAction()
{ {
requireParams({"names"}); requireParams({u"names"_qs});
const QStringList names = params()["names"].split('|'); const QStringList names = params()[u"names"_qs].split(u'|');
for (const QString &name : names) for (const QString &name : names)
SearchPluginManager::instance()->uninstallPlugin(name.trimmed()); SearchPluginManager::instance()->uninstallPlugin(name.trimmed());
} }
void SearchController::enablePluginAction() void SearchController::enablePluginAction()
{ {
requireParams({"names", "enable"}); requireParams({u"names"_qs, u"enable"_qs});
const QStringList names = params()["names"].split('|'); const QStringList names = params()[u"names"_qs].split(u'|');
const bool enable = Utils::String::parseBool(params()["enable"].trimmed()).value_or(false); const bool enable = Utils::String::parseBool(params()[u"enable"_qs].trimmed()).value_or(false);
for (const QString &name : names) for (const QString &name : names)
SearchPluginManager::instance()->enablePlugin(name.trimmed(), enable); SearchPluginManager::instance()->enablePlugin(name.trimmed(), enable);
@ -344,21 +344,21 @@ QJsonObject SearchController::getResults(const QList<SearchResult> &searchResult
{ {
searchResultsArray << QJsonObject searchResultsArray << QJsonObject
{ {
{"fileName", searchResult.fileName}, {u"fileName"_qs, searchResult.fileName},
{"fileUrl", searchResult.fileUrl}, {u"fileUrl"_qs, searchResult.fileUrl},
{"fileSize", searchResult.fileSize}, {u"fileSize"_qs, searchResult.fileSize},
{"nbSeeders", searchResult.nbSeeders}, {u"nbSeeders"_qs, searchResult.nbSeeders},
{"nbLeechers", searchResult.nbLeechers}, {u"nbLeechers"_qs, searchResult.nbLeechers},
{"siteUrl", searchResult.siteUrl}, {u"siteUrl"_qs, searchResult.siteUrl},
{"descrLink", searchResult.descrLink} {u"descrLink"_qs, searchResult.descrLink}
}; };
} }
const QJsonObject result = const QJsonObject result =
{ {
{"status", isSearchActive ? "Running" : "Stopped"}, {u"status"_qs, isSearchActive ? u"Running"_qs : u"Stopped"_qs},
{"results", searchResultsArray}, {u"results"_qs, searchResultsArray},
{"total", totalResults} {u"total"_qs, totalResults}
}; };
return result; return result;
@ -387,12 +387,12 @@ QJsonArray SearchController::getPluginsInfo(const QStringList &plugins) const
pluginsArray << QJsonObject pluginsArray << QJsonObject
{ {
{"name", pluginInfo->name}, {u"name"_qs, pluginInfo->name},
{"version", QString(pluginInfo->version)}, {u"version"_qs, QString(pluginInfo->version)},
{"fullName", pluginInfo->fullName}, {u"fullName"_qs, pluginInfo->fullName},
{"url", pluginInfo->url}, {u"url"_qs, pluginInfo->url},
{"supportedCategories", getPluginCategories(pluginInfo->supportedCategories)}, {u"supportedCategories"_qs, getPluginCategories(pluginInfo->supportedCategories)},
{"enabled", pluginInfo->enabled} {u"enabled"_qs, pluginInfo->enabled}
}; };
} }

100
src/webui/api/serialize/serialize_torrent.h

@ -30,6 +30,8 @@
#include <QVariant> #include <QVariant>
#include "base/global.h"
namespace BitTorrent namespace BitTorrent
{ {
class Torrent; class Torrent;
@ -37,54 +39,54 @@ namespace BitTorrent
// Torrent keys // Torrent keys
// TODO: Rename it to `id`. // TODO: Rename it to `id`.
inline const char KEY_TORRENT_ID[] = "hash"; inline const QString KEY_TORRENT_ID = u"hash"_qs;
inline const char KEY_TORRENT_INFOHASHV1[] = "infohash_v1"; inline const QString KEY_TORRENT_INFOHASHV1 = u"infohash_v1"_qs;
inline const char KEY_TORRENT_INFOHASHV2[] = "infohash_v2"; inline const QString KEY_TORRENT_INFOHASHV2 = u"infohash_v2"_qs;
inline const char KEY_TORRENT_NAME[] = "name"; inline const QString KEY_TORRENT_NAME = u"name"_qs;
inline const char KEY_TORRENT_MAGNET_URI[] = "magnet_uri"; inline const QString KEY_TORRENT_MAGNET_URI = u"magnet_uri"_qs;
inline const char KEY_TORRENT_SIZE[] = "size"; inline const QString KEY_TORRENT_SIZE = u"size"_qs;
inline const char KEY_TORRENT_PROGRESS[] = "progress"; inline const QString KEY_TORRENT_PROGRESS = u"progress"_qs;
inline const char KEY_TORRENT_DLSPEED[] = "dlspeed"; inline const QString KEY_TORRENT_DLSPEED = u"dlspeed"_qs;
inline const char KEY_TORRENT_UPSPEED[] = "upspeed"; inline const QString KEY_TORRENT_UPSPEED = u"upspeed"_qs;
inline const char KEY_TORRENT_QUEUE_POSITION[] = "priority"; inline const QString KEY_TORRENT_QUEUE_POSITION = u"priority"_qs;
inline const char KEY_TORRENT_SEEDS[] = "num_seeds"; inline const QString KEY_TORRENT_SEEDS = u"num_seeds"_qs;
inline const char KEY_TORRENT_NUM_COMPLETE[] = "num_complete"; inline const QString KEY_TORRENT_NUM_COMPLETE = u"num_complete"_qs;
inline const char KEY_TORRENT_LEECHS[] = "num_leechs"; inline const QString KEY_TORRENT_LEECHS = u"num_leechs"_qs;
inline const char KEY_TORRENT_NUM_INCOMPLETE[] = "num_incomplete"; inline const QString KEY_TORRENT_NUM_INCOMPLETE = u"num_incomplete"_qs;
inline const char KEY_TORRENT_RATIO[] = "ratio"; inline const QString KEY_TORRENT_RATIO = u"ratio"_qs;
inline const char KEY_TORRENT_ETA[] = "eta"; inline const QString KEY_TORRENT_ETA = u"eta"_qs;
inline const char KEY_TORRENT_STATE[] = "state"; inline const QString KEY_TORRENT_STATE = u"state"_qs;
inline const char KEY_TORRENT_SEQUENTIAL_DOWNLOAD[] = "seq_dl"; inline const QString KEY_TORRENT_SEQUENTIAL_DOWNLOAD = u"seq_dl"_qs;
inline const char KEY_TORRENT_FIRST_LAST_PIECE_PRIO[] = "f_l_piece_prio"; inline const QString KEY_TORRENT_FIRST_LAST_PIECE_PRIO = u"f_l_piece_prio"_qs;
inline const char KEY_TORRENT_CATEGORY[] = "category"; inline const QString KEY_TORRENT_CATEGORY = u"category"_qs;
inline const char KEY_TORRENT_TAGS[] = "tags"; inline const QString KEY_TORRENT_TAGS = u"tags"_qs;
inline const char KEY_TORRENT_SUPER_SEEDING[] = "super_seeding"; inline const QString KEY_TORRENT_SUPER_SEEDING = u"super_seeding"_qs;
inline const char KEY_TORRENT_FORCE_START[] = "force_start"; inline const QString KEY_TORRENT_FORCE_START = u"force_start"_qs;
inline const char KEY_TORRENT_SAVE_PATH[] = "save_path"; inline const QString KEY_TORRENT_SAVE_PATH = u"save_path"_qs;
inline const char KEY_TORRENT_DOWNLOAD_PATH[] = "download_path"; inline const QString KEY_TORRENT_DOWNLOAD_PATH = u"download_path"_qs;
inline const char KEY_TORRENT_CONTENT_PATH[] = "content_path"; inline const QString KEY_TORRENT_CONTENT_PATH = u"content_path"_qs;
inline const char KEY_TORRENT_ADDED_ON[] = "added_on"; inline const QString KEY_TORRENT_ADDED_ON = u"added_on"_qs;
inline const char KEY_TORRENT_COMPLETION_ON[] = "completion_on"; inline const QString KEY_TORRENT_COMPLETION_ON = u"completion_on"_qs;
inline const char KEY_TORRENT_TRACKER[] = "tracker"; inline const QString KEY_TORRENT_TRACKER = u"tracker"_qs;
inline const char KEY_TORRENT_TRACKERS_COUNT[] = "trackers_count"; inline const QString KEY_TORRENT_TRACKERS_COUNT = u"trackers_count"_qs;
inline const char KEY_TORRENT_DL_LIMIT[] = "dl_limit"; inline const QString KEY_TORRENT_DL_LIMIT = u"dl_limit"_qs;
inline const char KEY_TORRENT_UP_LIMIT[] = "up_limit"; inline const QString KEY_TORRENT_UP_LIMIT = u"up_limit"_qs;
inline const char KEY_TORRENT_AMOUNT_DOWNLOADED[] = "downloaded"; inline const QString KEY_TORRENT_AMOUNT_DOWNLOADED = u"downloaded"_qs;
inline const char KEY_TORRENT_AMOUNT_UPLOADED[] = "uploaded"; inline const QString KEY_TORRENT_AMOUNT_UPLOADED = u"uploaded"_qs;
inline const char KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION[] = "downloaded_session"; inline const QString KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION = u"downloaded_session"_qs;
inline const char KEY_TORRENT_AMOUNT_UPLOADED_SESSION[] = "uploaded_session"; inline const QString KEY_TORRENT_AMOUNT_UPLOADED_SESSION = u"uploaded_session"_qs;
inline const char KEY_TORRENT_AMOUNT_LEFT[] = "amount_left"; inline const QString KEY_TORRENT_AMOUNT_LEFT = u"amount_left"_qs;
inline const char KEY_TORRENT_AMOUNT_COMPLETED[] = "completed"; inline const QString KEY_TORRENT_AMOUNT_COMPLETED = u"completed"_qs;
inline const char KEY_TORRENT_MAX_RATIO[] = "max_ratio"; inline const QString KEY_TORRENT_MAX_RATIO = u"max_ratio"_qs;
inline const char KEY_TORRENT_MAX_SEEDING_TIME[] = "max_seeding_time"; inline const QString KEY_TORRENT_MAX_SEEDING_TIME = u"max_seeding_time"_qs;
inline const char KEY_TORRENT_RATIO_LIMIT[] = "ratio_limit"; inline const QString KEY_TORRENT_RATIO_LIMIT = u"ratio_limit"_qs;
inline const char KEY_TORRENT_SEEDING_TIME_LIMIT[] = "seeding_time_limit"; inline const QString KEY_TORRENT_SEEDING_TIME_LIMIT = u"seeding_time_limit"_qs;
inline const char KEY_TORRENT_LAST_SEEN_COMPLETE_TIME[] = "seen_complete"; inline const QString KEY_TORRENT_LAST_SEEN_COMPLETE_TIME = u"seen_complete"_qs;
inline const char KEY_TORRENT_LAST_ACTIVITY_TIME[] = "last_activity"; inline const QString KEY_TORRENT_LAST_ACTIVITY_TIME = u"last_activity"_qs;
inline const char KEY_TORRENT_TOTAL_SIZE[] = "total_size"; inline const QString KEY_TORRENT_TOTAL_SIZE = u"total_size"_qs;
inline const char KEY_TORRENT_AUTO_TORRENT_MANAGEMENT[] = "auto_tmm"; inline const QString KEY_TORRENT_AUTO_TORRENT_MANAGEMENT = u"auto_tmm"_qs;
inline const char KEY_TORRENT_TIME_ACTIVE[] = "time_active"; inline const QString KEY_TORRENT_TIME_ACTIVE = u"time_active"_qs;
inline const char KEY_TORRENT_SEEDING_TIME[] = "seeding_time"; inline const QString KEY_TORRENT_SEEDING_TIME = u"seeding_time"_qs;
inline const char KEY_TORRENT_AVAILABILITY[] = "availability"; inline const QString KEY_TORRENT_AVAILABILITY = u"availability"_qs;
QVariantMap serialize(const BitTorrent::Torrent &torrent); QVariantMap serialize(const BitTorrent::Torrent &torrent);

116
src/webui/api/synccontroller.cpp

@ -54,58 +54,58 @@ namespace
const int FREEDISKSPACE_CHECK_TIMEOUT = 30000; const int FREEDISKSPACE_CHECK_TIMEOUT = 30000;
// Sync main data keys // Sync main data keys
const char KEY_SYNC_MAINDATA_QUEUEING[] = "queueing"; const QString KEY_SYNC_MAINDATA_QUEUEING = u"queueing"_qs;
const char KEY_SYNC_MAINDATA_REFRESH_INTERVAL[] = "refresh_interval"; const QString KEY_SYNC_MAINDATA_REFRESH_INTERVAL = u"refresh_interval"_qs;
const char KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS[] = "use_alt_speed_limits"; const QString KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS = u"use_alt_speed_limits"_qs;
// Sync torrent peers keys // Sync torrent peers keys
const char KEY_SYNC_TORRENT_PEERS_SHOW_FLAGS[] = "show_flags"; const QString KEY_SYNC_TORRENT_PEERS_SHOW_FLAGS = u"show_flags"_qs;
// Peer keys // Peer keys
const char KEY_PEER_CLIENT[] = "client"; const QString KEY_PEER_CLIENT = u"client"_qs;
const char KEY_PEER_CONNECTION_TYPE[] = "connection"; const QString KEY_PEER_CONNECTION_TYPE = u"connection"_qs;
const char KEY_PEER_COUNTRY[] = "country"; const QString KEY_PEER_COUNTRY = u"country"_qs;
const char KEY_PEER_COUNTRY_CODE[] = "country_code"; const QString KEY_PEER_COUNTRY_CODE = u"country_code"_qs;
const char KEY_PEER_DOWN_SPEED[] = "dl_speed"; const QString KEY_PEER_DOWN_SPEED = u"dl_speed"_qs;
const char KEY_PEER_FILES[] = "files"; const QString KEY_PEER_FILES = u"files"_qs;
const char KEY_PEER_FLAGS[] = "flags"; const QString KEY_PEER_FLAGS = u"flags"_qs;
const char KEY_PEER_FLAGS_DESCRIPTION[] = "flags_desc"; const QString KEY_PEER_FLAGS_DESCRIPTION = u"flags_desc"_qs;
const char KEY_PEER_IP[] = "ip"; const QString KEY_PEER_IP = u"ip"_qs;
const char KEY_PEER_PORT[] = "port"; const QString KEY_PEER_PORT = u"port"_qs;
const char KEY_PEER_PROGRESS[] = "progress"; const QString KEY_PEER_PROGRESS = u"progress"_qs;
const char KEY_PEER_RELEVANCE[] = "relevance"; const QString KEY_PEER_RELEVANCE = u"relevance"_qs;
const char KEY_PEER_TOT_DOWN[] = "downloaded"; const QString KEY_PEER_TOT_DOWN = u"downloaded"_qs;
const char KEY_PEER_TOT_UP[] = "uploaded"; const QString KEY_PEER_TOT_UP = u"uploaded"_qs;
const char KEY_PEER_UP_SPEED[] = "up_speed"; const QString KEY_PEER_UP_SPEED = u"up_speed"_qs;
// TransferInfo keys // TransferInfo keys
const char KEY_TRANSFER_CONNECTION_STATUS[] = "connection_status"; const QString KEY_TRANSFER_CONNECTION_STATUS = u"connection_status"_qs;
const char KEY_TRANSFER_DHT_NODES[] = "dht_nodes"; const QString KEY_TRANSFER_DHT_NODES = u"dht_nodes"_qs;
const char KEY_TRANSFER_DLDATA[] = "dl_info_data"; const QString KEY_TRANSFER_DLDATA = u"dl_info_data"_qs;
const char KEY_TRANSFER_DLRATELIMIT[] = "dl_rate_limit"; const QString KEY_TRANSFER_DLRATELIMIT = u"dl_rate_limit"_qs;
const char KEY_TRANSFER_DLSPEED[] = "dl_info_speed"; const QString KEY_TRANSFER_DLSPEED = u"dl_info_speed"_qs;
const char KEY_TRANSFER_FREESPACEONDISK[] = "free_space_on_disk"; const QString KEY_TRANSFER_FREESPACEONDISK = u"free_space_on_disk"_qs;
const char KEY_TRANSFER_UPDATA[] = "up_info_data"; const QString KEY_TRANSFER_UPDATA = u"up_info_data"_qs;
const char KEY_TRANSFER_UPRATELIMIT[] = "up_rate_limit"; const QString KEY_TRANSFER_UPRATELIMIT = u"up_rate_limit"_qs;
const char KEY_TRANSFER_UPSPEED[] = "up_info_speed"; const QString KEY_TRANSFER_UPSPEED = u"up_info_speed"_qs;
// Statistics keys // Statistics keys
const char KEY_TRANSFER_ALLTIME_DL[] = "alltime_dl"; const QString KEY_TRANSFER_ALLTIME_DL = u"alltime_dl"_qs;
const char KEY_TRANSFER_ALLTIME_UL[] = "alltime_ul"; const QString KEY_TRANSFER_ALLTIME_UL = u"alltime_ul"_qs;
const char KEY_TRANSFER_AVERAGE_TIME_QUEUE[] = "average_time_queue"; const QString KEY_TRANSFER_AVERAGE_TIME_QUEUE = u"average_time_queue"_qs;
const char KEY_TRANSFER_GLOBAL_RATIO[] = "global_ratio"; const QString KEY_TRANSFER_GLOBAL_RATIO = u"global_ratio"_qs;
const char KEY_TRANSFER_QUEUED_IO_JOBS[] = "queued_io_jobs"; const QString KEY_TRANSFER_QUEUED_IO_JOBS = u"queued_io_jobs"_qs;
const char KEY_TRANSFER_READ_CACHE_HITS[] = "read_cache_hits"; const QString KEY_TRANSFER_READ_CACHE_HITS = u"read_cache_hits"_qs;
const char KEY_TRANSFER_READ_CACHE_OVERLOAD[] = "read_cache_overload"; const QString KEY_TRANSFER_READ_CACHE_OVERLOAD = u"read_cache_overload"_qs;
const char KEY_TRANSFER_TOTAL_BUFFERS_SIZE[] = "total_buffers_size"; const QString KEY_TRANSFER_TOTAL_BUFFERS_SIZE = u"total_buffers_size"_qs;
const char KEY_TRANSFER_TOTAL_PEER_CONNECTIONS[] = "total_peer_connections"; const QString KEY_TRANSFER_TOTAL_PEER_CONNECTIONS = u"total_peer_connections"_qs;
const char KEY_TRANSFER_TOTAL_QUEUED_SIZE[] = "total_queued_size"; const QString KEY_TRANSFER_TOTAL_QUEUED_SIZE = u"total_queued_size"_qs;
const char KEY_TRANSFER_TOTAL_WASTE_SESSION[] = "total_wasted_session"; const QString KEY_TRANSFER_TOTAL_WASTE_SESSION = u"total_wasted_session"_qs;
const char KEY_TRANSFER_WRITE_CACHE_OVERLOAD[] = "write_cache_overload"; const QString KEY_TRANSFER_WRITE_CACHE_OVERLOAD = u"write_cache_overload"_qs;
const char KEY_FULL_UPDATE[] = "full_update"; const QString KEY_FULL_UPDATE = u"full_update"_qs;
const char KEY_RESPONSE_ID[] = "rid"; const QString KEY_RESPONSE_ID = u"rid"_qs;
const char KEY_SUFFIX_REMOVED[] = "_removed"; const QString KEY_SUFFIX_REMOVED = u"_removed"_qs;
void processMap(const QVariantMap &prevData, const QVariantMap &data, QVariantMap &syncData); void processMap(const QVariantMap &prevData, const QVariantMap &data, QVariantMap &syncData);
void processHash(QVariantHash prevData, const QVariantHash &data, QVariantMap &syncData, QVariantList &removedItems); void processHash(QVariantHash prevData, const QVariantHash &data, QVariantMap &syncData, QVariantList &removedItems);
@ -131,11 +131,11 @@ namespace
map[KEY_TRANSFER_ALLTIME_DL] = atd; map[KEY_TRANSFER_ALLTIME_DL] = atd;
map[KEY_TRANSFER_ALLTIME_UL] = atu; map[KEY_TRANSFER_ALLTIME_UL] = atu;
map[KEY_TRANSFER_TOTAL_WASTE_SESSION] = sessionStatus.totalWasted; map[KEY_TRANSFER_TOTAL_WASTE_SESSION] = sessionStatus.totalWasted;
map[KEY_TRANSFER_GLOBAL_RATIO] = ((atd > 0) && (atu > 0)) ? Utils::String::fromDouble(static_cast<qreal>(atu) / atd, 2) : "-"; map[KEY_TRANSFER_GLOBAL_RATIO] = ((atd > 0) && (atu > 0)) ? Utils::String::fromDouble(static_cast<qreal>(atu) / atd, 2) : u"-"_qs;
map[KEY_TRANSFER_TOTAL_PEER_CONNECTIONS] = sessionStatus.peersCount; map[KEY_TRANSFER_TOTAL_PEER_CONNECTIONS] = sessionStatus.peersCount;
const qreal readRatio = cacheStatus.readRatio; // TODO: remove when LIBTORRENT_VERSION_NUM >= 20000 const qreal readRatio = cacheStatus.readRatio; // TODO: remove when LIBTORRENT_VERSION_NUM >= 20000
map[KEY_TRANSFER_READ_CACHE_HITS] = (readRatio > 0) ? Utils::String::fromDouble(100 * readRatio, 2) : "0"; map[KEY_TRANSFER_READ_CACHE_HITS] = (readRatio > 0) ? Utils::String::fromDouble(100 * readRatio, 2) : u"0"_qs;
map[KEY_TRANSFER_TOTAL_BUFFERS_SIZE] = cacheStatus.totalUsedBuffers * 16 * 1024; map[KEY_TRANSFER_TOTAL_BUFFERS_SIZE] = cacheStatus.totalUsedBuffers * 16 * 1024;
map[KEY_TRANSFER_WRITE_CACHE_OVERLOAD] = ((sessionStatus.diskWriteQueue > 0) && (sessionStatus.peersCount > 0)) map[KEY_TRANSFER_WRITE_CACHE_OVERLOAD] = ((sessionStatus.diskWriteQueue > 0) && (sessionStatus.peersCount > 0))
@ -151,8 +151,8 @@ namespace
map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dhtNodes; map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dhtNodes;
map[KEY_TRANSFER_CONNECTION_STATUS] = session->isListening() map[KEY_TRANSFER_CONNECTION_STATUS] = session->isListening()
? (sessionStatus.hasIncomingConnections ? "connected" : "firewalled") ? (sessionStatus.hasIncomingConnections ? u"connected"_qs : u"firewalled"_qs)
: "disconnected"; : u"disconnected"_qs;
return map; return map;
} }
@ -470,7 +470,7 @@ void SyncController::maindataAction()
// Calculated last activity time can differ from actual value by up to 10 seconds (this is a libtorrent issue). // Calculated last activity time can differ from actual value by up to 10 seconds (this is a libtorrent issue).
// So we don't need unnecessary updates of last activity time in response. // So we don't need unnecessary updates of last activity time in response.
const auto iterTorrents = lastResponse.find("torrents"); const auto iterTorrents = lastResponse.find(u"torrents"_qs);
if (iterTorrents != lastResponse.end()) if (iterTorrents != lastResponse.end())
{ {
const QVariantHash lastResponseTorrents = iterTorrents->toHash(); const QVariantHash lastResponseTorrents = iterTorrents->toHash();
@ -495,7 +495,7 @@ void SyncController::maindataAction()
torrents[torrentID.toString()] = map; torrents[torrentID.toString()] = map;
} }
data["torrents"] = torrents; data[u"torrents"_qs] = torrents;
QVariantHash categories; QVariantHash categories;
const QStringList categoriesList = session->categories(); const QStringList categoriesList = session->categories();
@ -508,28 +508,28 @@ void SyncController::maindataAction()
category.insert(QLatin1String("name"), categoryName); category.insert(QLatin1String("name"), categoryName);
categories[categoryName] = category.toVariantMap(); categories[categoryName] = category.toVariantMap();
} }
data["categories"] = categories; data[u"categories"_qs] = categories;
QVariantList tags; QVariantList tags;
for (const QString &tag : asConst(session->tags())) for (const QString &tag : asConst(session->tags()))
tags << tag; tags << tag;
data["tags"] = tags; data[u"tags"_qs] = tags;
QVariantHash trackersHash; QVariantHash trackersHash;
for (auto i = trackers.constBegin(); i != trackers.constEnd(); ++i) for (auto i = trackers.constBegin(); i != trackers.constEnd(); ++i)
{ {
trackersHash[i.key()] = i.value(); trackersHash[i.key()] = i.value();
} }
data["trackers"] = trackersHash; data[u"trackers"_qs] = trackersHash;
QVariantMap serverState = getTransferInfo(); QVariantMap serverState = getTransferInfo();
serverState[KEY_TRANSFER_FREESPACEONDISK] = getFreeDiskSpace(); serverState[KEY_TRANSFER_FREESPACEONDISK] = getFreeDiskSpace();
serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled(); serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled();
serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = session->isAltGlobalSpeedLimitEnabled(); serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = session->isAltGlobalSpeedLimitEnabled();
serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = session->refreshInterval(); serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = session->refreshInterval();
data["server_state"] = serverState; data[u"server_state"_qs] = serverState;
const int acceptedResponseId {params()["rid"].toInt()}; const int acceptedResponseId {params()[u"rid"_qs].toInt()};
setResult(QJsonObject::fromVariantMap(generateSyncData(acceptedResponseId, data, lastAcceptedResponse, lastResponse))); setResult(QJsonObject::fromVariantMap(generateSyncData(acceptedResponseId, data, lastAcceptedResponse, lastResponse)));
sessionManager()->session()->setData(QLatin1String("syncMainDataLastResponse"), lastResponse); sessionManager()->session()->setData(QLatin1String("syncMainDataLastResponse"), lastResponse);
@ -544,7 +544,7 @@ void SyncController::torrentPeersAction()
auto lastResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastResponse")).toMap(); auto lastResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastResponse")).toMap();
auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap(); auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap();
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->findTorrent(id); const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -596,9 +596,9 @@ void SyncController::torrentPeersAction()
peers[pi.address().toString()] = peer; peers[pi.address().toString()] = peer;
} }
data["peers"] = peers; data[u"peers"_qs] = peers;
const int acceptedResponseId {params()["rid"].toInt()}; const int acceptedResponseId {params()[u"rid"_qs].toInt()};
setResult(QJsonObject::fromVariantMap(generateSyncData(acceptedResponseId, data, lastAcceptedResponse, lastResponse))); setResult(QJsonObject::fromVariantMap(generateSyncData(acceptedResponseId, data, lastAcceptedResponse, lastResponse)));
sessionManager()->session()->setData(QLatin1String("syncTorrentPeersLastResponse"), lastResponse); sessionManager()->session()->setData(QLatin1String("syncTorrentPeersLastResponse"), lastResponse);

432
src/webui/api/torrentscontroller.cpp

@ -57,63 +57,63 @@
#include "serialize/serialize_torrent.h" #include "serialize/serialize_torrent.h"
// Tracker keys // Tracker keys
const char KEY_TRACKER_URL[] = "url"; const QString KEY_TRACKER_URL = u"url"_qs;
const char KEY_TRACKER_STATUS[] = "status"; const QString KEY_TRACKER_STATUS = u"status"_qs;
const char KEY_TRACKER_TIER[] = "tier"; const QString KEY_TRACKER_TIER = u"tier"_qs;
const char KEY_TRACKER_MSG[] = "msg"; const QString KEY_TRACKER_MSG = u"msg"_qs;
const char KEY_TRACKER_PEERS_COUNT[] = "num_peers"; const QString KEY_TRACKER_PEERS_COUNT = u"num_peers"_qs;
const char KEY_TRACKER_SEEDS_COUNT[] = "num_seeds"; const QString KEY_TRACKER_SEEDS_COUNT = u"num_seeds"_qs;
const char KEY_TRACKER_LEECHES_COUNT[] = "num_leeches"; const QString KEY_TRACKER_LEECHES_COUNT = u"num_leeches"_qs;
const char KEY_TRACKER_DOWNLOADED_COUNT[] = "num_downloaded"; const QString KEY_TRACKER_DOWNLOADED_COUNT = u"num_downloaded"_qs;
// Web seed keys // Web seed keys
const char KEY_WEBSEED_URL[] = "url"; const QString KEY_WEBSEED_URL = u"url"_qs;
// Torrent keys (Properties) // Torrent keys (Properties)
const char KEY_PROP_TIME_ELAPSED[] = "time_elapsed"; const QString KEY_PROP_TIME_ELAPSED = u"time_elapsed"_qs;
const char KEY_PROP_SEEDING_TIME[] = "seeding_time"; const QString KEY_PROP_SEEDING_TIME = u"seeding_time"_qs;
const char KEY_PROP_ETA[] = "eta"; const QString KEY_PROP_ETA = u"eta"_qs;
const char KEY_PROP_CONNECT_COUNT[] = "nb_connections"; const QString KEY_PROP_CONNECT_COUNT = u"nb_connections"_qs;
const char KEY_PROP_CONNECT_COUNT_LIMIT[] = "nb_connections_limit"; const QString KEY_PROP_CONNECT_COUNT_LIMIT = u"nb_connections_limit"_qs;
const char KEY_PROP_DOWNLOADED[] = "total_downloaded"; const QString KEY_PROP_DOWNLOADED = u"total_downloaded"_qs;
const char KEY_PROP_DOWNLOADED_SESSION[] = "total_downloaded_session"; const QString KEY_PROP_DOWNLOADED_SESSION = u"total_downloaded_session"_qs;
const char KEY_PROP_UPLOADED[] = "total_uploaded"; const QString KEY_PROP_UPLOADED = u"total_uploaded"_qs;
const char KEY_PROP_UPLOADED_SESSION[] = "total_uploaded_session"; const QString KEY_PROP_UPLOADED_SESSION = u"total_uploaded_session"_qs;
const char KEY_PROP_DL_SPEED[] = "dl_speed"; const QString KEY_PROP_DL_SPEED = u"dl_speed"_qs;
const char KEY_PROP_DL_SPEED_AVG[] = "dl_speed_avg"; const QString KEY_PROP_DL_SPEED_AVG = u"dl_speed_avg"_qs;
const char KEY_PROP_UP_SPEED[] = "up_speed"; const QString KEY_PROP_UP_SPEED = u"up_speed"_qs;
const char KEY_PROP_UP_SPEED_AVG[] = "up_speed_avg"; const QString KEY_PROP_UP_SPEED_AVG = u"up_speed_avg"_qs;
const char KEY_PROP_DL_LIMIT[] = "dl_limit"; const QString KEY_PROP_DL_LIMIT = u"dl_limit"_qs;
const char KEY_PROP_UP_LIMIT[] = "up_limit"; const QString KEY_PROP_UP_LIMIT = u"up_limit"_qs;
const char KEY_PROP_WASTED[] = "total_wasted"; const QString KEY_PROP_WASTED = u"total_wasted"_qs;
const char KEY_PROP_SEEDS[] = "seeds"; const QString KEY_PROP_SEEDS = u"seeds"_qs;
const char KEY_PROP_SEEDS_TOTAL[] = "seeds_total"; const QString KEY_PROP_SEEDS_TOTAL = u"seeds_total"_qs;
const char KEY_PROP_PEERS[] = "peers"; const QString KEY_PROP_PEERS = u"peers"_qs;
const char KEY_PROP_PEERS_TOTAL[] = "peers_total"; const QString KEY_PROP_PEERS_TOTAL = u"peers_total"_qs;
const char KEY_PROP_RATIO[] = "share_ratio"; const QString KEY_PROP_RATIO = u"share_ratio"_qs;
const char KEY_PROP_REANNOUNCE[] = "reannounce"; const QString KEY_PROP_REANNOUNCE = u"reannounce"_qs;
const char KEY_PROP_TOTAL_SIZE[] = "total_size"; const QString KEY_PROP_TOTAL_SIZE = u"total_size"_qs;
const char KEY_PROP_PIECES_NUM[] = "pieces_num"; const QString KEY_PROP_PIECES_NUM = u"pieces_num"_qs;
const char KEY_PROP_PIECE_SIZE[] = "piece_size"; const QString KEY_PROP_PIECE_SIZE = u"piece_size"_qs;
const char KEY_PROP_PIECES_HAVE[] = "pieces_have"; const QString KEY_PROP_PIECES_HAVE = u"pieces_have"_qs;
const char KEY_PROP_CREATED_BY[] = "created_by"; const QString KEY_PROP_CREATED_BY = u"created_by"_qs;
const char KEY_PROP_LAST_SEEN[] = "last_seen"; const QString KEY_PROP_LAST_SEEN = u"last_seen"_qs;
const char KEY_PROP_ADDITION_DATE[] = "addition_date"; const QString KEY_PROP_ADDITION_DATE = u"addition_date"_qs;
const char KEY_PROP_COMPLETION_DATE[] = "completion_date"; const QString KEY_PROP_COMPLETION_DATE = u"completion_date"_qs;
const char KEY_PROP_CREATION_DATE[] = "creation_date"; const QString KEY_PROP_CREATION_DATE = u"creation_date"_qs;
const char KEY_PROP_SAVE_PATH[] = "save_path"; const QString KEY_PROP_SAVE_PATH = u"save_path"_qs;
const char KEY_PROP_DOWNLOAD_PATH[] = "download_path"; const QString KEY_PROP_DOWNLOAD_PATH = u"download_path"_qs;
const char KEY_PROP_COMMENT[] = "comment"; const QString KEY_PROP_COMMENT = u"comment"_qs;
// File keys // File keys
const char KEY_FILE_INDEX[] = "index"; const QString KEY_FILE_INDEX = u"index"_qs;
const char KEY_FILE_NAME[] = "name"; const QString KEY_FILE_NAME = u"name"_qs;
const char KEY_FILE_SIZE[] = "size"; const QString KEY_FILE_SIZE = u"size"_qs;
const char KEY_FILE_PROGRESS[] = "progress"; const QString KEY_FILE_PROGRESS = u"progress"_qs;
const char KEY_FILE_PRIORITY[] = "priority"; const QString KEY_FILE_PRIORITY = u"priority"_qs;
const char KEY_FILE_IS_SEED[] = "is_seed"; const QString KEY_FILE_IS_SEED = u"is_seed"_qs;
const char KEY_FILE_PIECE_RANGE[] = "piece_range"; const QString KEY_FILE_PIECE_RANGE = u"piece_range"_qs;
const char KEY_FILE_AVAILABILITY[] = "availability"; const QString KEY_FILE_AVAILABILITY = u"availability"_qs;
namespace namespace
{ {
@ -184,9 +184,9 @@ namespace
const QJsonObject dht const QJsonObject dht
{ {
{KEY_TRACKER_URL, "** [DHT] **"}, {KEY_TRACKER_URL, u"** [DHT] **"_qs},
{KEY_TRACKER_TIER, -1}, {KEY_TRACKER_TIER, -1},
{KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")}, {KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : u""_qs)},
{KEY_TRACKER_STATUS, ((BitTorrent::Session::instance()->isDHTEnabled() && !isTorrentPrivate) ? working : disabled)}, {KEY_TRACKER_STATUS, ((BitTorrent::Session::instance()->isDHTEnabled() && !isTorrentPrivate) ? working : disabled)},
{KEY_TRACKER_PEERS_COUNT, 0}, {KEY_TRACKER_PEERS_COUNT, 0},
{KEY_TRACKER_DOWNLOADED_COUNT, 0}, {KEY_TRACKER_DOWNLOADED_COUNT, 0},
@ -196,9 +196,9 @@ namespace
const QJsonObject pex const QJsonObject pex
{ {
{KEY_TRACKER_URL, "** [PeX] **"}, {KEY_TRACKER_URL, u"** [PeX] **"_qs},
{KEY_TRACKER_TIER, -1}, {KEY_TRACKER_TIER, -1},
{KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")}, {KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : u""_qs)},
{KEY_TRACKER_STATUS, ((BitTorrent::Session::instance()->isPeXEnabled() && !isTorrentPrivate) ? working : disabled)}, {KEY_TRACKER_STATUS, ((BitTorrent::Session::instance()->isPeXEnabled() && !isTorrentPrivate) ? working : disabled)},
{KEY_TRACKER_PEERS_COUNT, 0}, {KEY_TRACKER_PEERS_COUNT, 0},
{KEY_TRACKER_DOWNLOADED_COUNT, 0}, {KEY_TRACKER_DOWNLOADED_COUNT, 0},
@ -208,9 +208,9 @@ namespace
const QJsonObject lsd const QJsonObject lsd
{ {
{KEY_TRACKER_URL, "** [LSD] **"}, {KEY_TRACKER_URL, u"** [LSD] **"_qs},
{KEY_TRACKER_TIER, -1}, {KEY_TRACKER_TIER, -1},
{KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")}, {KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : u""_qs)},
{KEY_TRACKER_STATUS, ((BitTorrent::Session::instance()->isLSDEnabled() && !isTorrentPrivate) ? working : disabled)}, {KEY_TRACKER_STATUS, ((BitTorrent::Session::instance()->isLSDEnabled() && !isTorrentPrivate) ? working : disabled)},
{KEY_TRACKER_PEERS_COUNT, 0}, {KEY_TRACKER_PEERS_COUNT, 0},
{KEY_TRACKER_DOWNLOADED_COUNT, 0}, {KEY_TRACKER_DOWNLOADED_COUNT, 0},
@ -263,14 +263,14 @@ namespace
// - offset (int): set offset (if less than 0 - offset from end) // - offset (int): set offset (if less than 0 - offset from end)
void TorrentsController::infoAction() void TorrentsController::infoAction()
{ {
const QString filter {params()["filter"]}; const QString filter {params()[u"filter"_qs]};
const std::optional<QString> category = getOptionalString(params(), QLatin1String("category")); const std::optional<QString> category = getOptionalString(params(), QLatin1String("category"));
const std::optional<QString> tag = getOptionalString(params(), QLatin1String("tag")); const std::optional<QString> tag = getOptionalString(params(), QLatin1String("tag"));
const QString sortedColumn {params()["sort"]}; const QString sortedColumn {params()[u"sort"_qs]};
const bool reverse {parseBool(params()["reverse"]).value_or(false)}; const bool reverse {parseBool(params()[u"reverse"_qs]).value_or(false)};
int limit {params()["limit"].toInt()}; int limit {params()[u"limit"_qs].toInt()};
int offset {params()["offset"].toInt()}; int offset {params()[u"offset"_qs].toInt()};
const QStringList hashes {params()["hashes"].split('|', Qt::SkipEmptyParts)}; const QStringList hashes {params()[u"hashes"_qs].split(u'|', Qt::SkipEmptyParts)};
std::optional<TorrentIDSet> idSet; std::optional<TorrentIDSet> idSet;
if (!hashes.isEmpty()) if (!hashes.isEmpty())
@ -389,9 +389,9 @@ void TorrentsController::infoAction()
// - "comment": Torrent comment // - "comment": Torrent comment
void TorrentsController::propertiesAction() void TorrentsController::propertiesAction()
{ {
requireParams({"hash"}); requireParams({u"hash"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -463,9 +463,9 @@ void TorrentsController::propertiesAction()
// - "msg": Tracker message (last) // - "msg": Tracker message (last)
void TorrentsController::trackersAction() void TorrentsController::trackersAction()
{ {
requireParams({"hash"}); requireParams({u"hash"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -496,9 +496,9 @@ void TorrentsController::trackersAction()
// - "url": Web seed URL // - "url": Web seed URL
void TorrentsController::webseedsAction() void TorrentsController::webseedsAction()
{ {
requireParams({"hash"}); requireParams({u"hash"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -528,9 +528,9 @@ void TorrentsController::webseedsAction()
// and the second number is the ending piece index (inclusive) // and the second number is the ending piece index (inclusive)
void TorrentsController::filesAction() void TorrentsController::filesAction()
{ {
requireParams({"hash"}); requireParams({u"hash"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -540,7 +540,7 @@ void TorrentsController::filesAction()
const auto idxIt = params().constFind(QLatin1String("indexes")); const auto idxIt = params().constFind(QLatin1String("indexes"));
if (idxIt != params().cend()) if (idxIt != params().cend())
{ {
const QStringList indexStrings = idxIt.value().split('|'); const QStringList indexStrings = idxIt.value().split(u'|');
fileIndexes.reserve(indexStrings.size()); fileIndexes.reserve(indexStrings.size());
std::transform(indexStrings.cbegin(), indexStrings.cend(), std::back_inserter(fileIndexes) std::transform(indexStrings.cbegin(), indexStrings.cend(), std::back_inserter(fileIndexes)
, [&filesCount](const QString &indexString) -> int , [&filesCount](const QString &indexString) -> int
@ -597,9 +597,9 @@ void TorrentsController::filesAction()
// The return value is a JSON-formatted array of strings (hex strings). // The return value is a JSON-formatted array of strings (hex strings).
void TorrentsController::pieceHashesAction() void TorrentsController::pieceHashesAction()
{ {
requireParams({"hash"}); requireParams({u"hash"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -609,7 +609,7 @@ void TorrentsController::pieceHashesAction()
{ {
const QVector<QByteArray> hashes = torrent->info().pieceHashes(); const QVector<QByteArray> hashes = torrent->info().pieceHashes();
for (const QByteArray &hash : hashes) for (const QByteArray &hash : hashes)
pieceHashes.append(QString(hash.toHex())); pieceHashes.append(QString::fromLatin1(hash.toHex()));
} }
setResult(pieceHashes); setResult(pieceHashes);
@ -622,9 +622,9 @@ void TorrentsController::pieceHashesAction()
// 2: piece already downloaded // 2: piece already downloaded
void TorrentsController::pieceStatesAction() void TorrentsController::pieceStatesAction()
{ {
requireParams({"hash"}); requireParams({u"hash"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -646,26 +646,26 @@ void TorrentsController::pieceStatesAction()
void TorrentsController::addAction() void TorrentsController::addAction()
{ {
const QString urls = params()["urls"]; const QString urls = params()[u"urls"_qs];
const QString cookie = params()["cookie"]; const QString cookie = params()[u"cookie"_qs];
const bool skipChecking = parseBool(params()["skip_checking"]).value_or(false); const bool skipChecking = parseBool(params()[u"skip_checking"_qs]).value_or(false);
const bool seqDownload = parseBool(params()["sequentialDownload"]).value_or(false); const bool seqDownload = parseBool(params()[u"sequentialDownload"_qs]).value_or(false);
const bool firstLastPiece = parseBool(params()["firstLastPiecePrio"]).value_or(false); const bool firstLastPiece = parseBool(params()[u"firstLastPiecePrio"_qs]).value_or(false);
const std::optional<bool> addPaused = parseBool(params()["paused"]); const std::optional<bool> addPaused = parseBool(params()[u"paused"_qs]);
const QString savepath = params()["savepath"].trimmed(); const QString savepath = params()[u"savepath"_qs].trimmed();
const QString downloadPath = params()["downloadPath"].trimmed(); const QString downloadPath = params()[u"downloadPath"_qs].trimmed();
const std::optional<bool> useDownloadPath = parseBool(params()["useDownloadPath"]); const std::optional<bool> useDownloadPath = parseBool(params()[u"useDownloadPath"_qs]);
const QString category = params()["category"]; const QString category = params()[u"category"_qs];
const QStringList tags = params()["tags"].split(',', Qt::SkipEmptyParts); const QStringList tags = params()[u"tags"_qs].split(u',', Qt::SkipEmptyParts);
const QString torrentName = params()["rename"].trimmed(); const QString torrentName = params()[u"rename"_qs].trimmed();
const int upLimit = parseInt(params()["upLimit"]).value_or(-1); const int upLimit = parseInt(params()[u"upLimit"_qs]).value_or(-1);
const int dlLimit = parseInt(params()["dlLimit"]).value_or(-1); const int dlLimit = parseInt(params()[u"dlLimit"_qs]).value_or(-1);
const double ratioLimit = parseDouble(params()["ratioLimit"]).value_or(BitTorrent::Torrent::USE_GLOBAL_RATIO); const double ratioLimit = parseDouble(params()[u"ratioLimit"_qs]).value_or(BitTorrent::Torrent::USE_GLOBAL_RATIO);
const int seedingTimeLimit = parseInt(params()["seedingTimeLimit"]).value_or(BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME); const int seedingTimeLimit = parseInt(params()[u"seedingTimeLimit"_qs]).value_or(BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
const std::optional<bool> autoTMM = parseBool(params()["autoTMM"]); const std::optional<bool> autoTMM = parseBool(params()[u"autoTMM"_qs]);
const QString contentLayoutParam = params()["contentLayout"]; const QString contentLayoutParam = params()[u"contentLayout"_qs];
const std::optional<BitTorrent::TorrentContentLayout> contentLayout = (!contentLayoutParam.isEmpty() const std::optional<BitTorrent::TorrentContentLayout> contentLayout = (!contentLayoutParam.isEmpty()
? Utils::String::toEnum(contentLayoutParam, BitTorrent::TorrentContentLayout::Original) ? Utils::String::toEnum(contentLayoutParam, BitTorrent::TorrentContentLayout::Original)
: std::optional<BitTorrent::TorrentContentLayout> {}); : std::optional<BitTorrent::TorrentContentLayout> {});
@ -673,11 +673,11 @@ void TorrentsController::addAction()
QList<QNetworkCookie> cookies; QList<QNetworkCookie> cookies;
if (!cookie.isEmpty()) if (!cookie.isEmpty())
{ {
const QStringList cookiesStr = cookie.split("; "); const QStringList cookiesStr = cookie.split(u"; "_qs);
for (QString cookieStr : cookiesStr) for (QString cookieStr : cookiesStr)
{ {
cookieStr = cookieStr.trimmed(); cookieStr = cookieStr.trimmed();
int index = cookieStr.indexOf('='); int index = cookieStr.indexOf(u'=');
if (index > 1) if (index > 1)
{ {
QByteArray name = cookieStr.left(index).toLatin1(); QByteArray name = cookieStr.left(index).toLatin1();
@ -707,7 +707,7 @@ void TorrentsController::addAction()
addTorrentParams.useAutoTMM = autoTMM; addTorrentParams.useAutoTMM = autoTMM;
bool partialSuccess = false; bool partialSuccess = false;
for (QString url : asConst(urls.split('\n'))) for (QString url : asConst(urls.split(u'\n')))
{ {
url = url.trimmed(); url = url.trimmed();
if (!url.isEmpty()) if (!url.isEmpty())
@ -737,15 +737,15 @@ void TorrentsController::addAction()
void TorrentsController::addTrackersAction() void TorrentsController::addTrackersAction()
{ {
requireParams({"hash", "urls"}); requireParams({u"hash"_qs, u"urls"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
QVector<BitTorrent::TrackerEntry> trackers; QVector<BitTorrent::TrackerEntry> trackers;
for (const QString &urlStr : asConst(params()["urls"].split('\n'))) for (const QString &urlStr : asConst(params()[u"urls"_qs].split(u'\n')))
{ {
const QUrl url {urlStr.trimmed()}; const QUrl url {urlStr.trimmed()};
if (url.isValid()) if (url.isValid())
@ -756,11 +756,11 @@ void TorrentsController::addTrackersAction()
void TorrentsController::editTrackerAction() void TorrentsController::editTrackerAction()
{ {
requireParams({"hash", "origUrl", "newUrl"}); requireParams({u"hash"_qs, u"origUrl"_qs, u"newUrl"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
const QString origUrl = params()["origUrl"]; const QString origUrl = params()[u"origUrl"_qs];
const QString newUrl = params()["newUrl"]; const QString newUrl = params()[u"newUrl"_qs];
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
@ -771,7 +771,7 @@ void TorrentsController::editTrackerAction()
if (origTrackerUrl == newTrackerUrl) if (origTrackerUrl == newTrackerUrl)
return; return;
if (!newTrackerUrl.isValid()) if (!newTrackerUrl.isValid())
throw APIError(APIErrorType::BadParams, "New tracker URL is invalid"); throw APIError(APIErrorType::BadParams, u"New tracker URL is invalid"_qs);
QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers(); QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
bool match = false; bool match = false;
@ -779,7 +779,7 @@ void TorrentsController::editTrackerAction()
{ {
const QUrl trackerUrl(tracker.url); const QUrl trackerUrl(tracker.url);
if (trackerUrl == newTrackerUrl) if (trackerUrl == newTrackerUrl)
throw APIError(APIErrorType::Conflict, "New tracker URL already exists"); throw APIError(APIErrorType::Conflict, u"New tracker URL already exists"_qs);
if (trackerUrl == origTrackerUrl) if (trackerUrl == origTrackerUrl)
{ {
match = true; match = true;
@ -787,7 +787,7 @@ void TorrentsController::editTrackerAction()
} }
} }
if (!match) if (!match)
throw APIError(APIErrorType::Conflict, "Tracker not found"); throw APIError(APIErrorType::Conflict, u"Tracker not found"_qs);
torrent->replaceTrackers(trackers); torrent->replaceTrackers(trackers);
@ -797,14 +797,14 @@ void TorrentsController::editTrackerAction()
void TorrentsController::removeTrackersAction() void TorrentsController::removeTrackersAction()
{ {
requireParams({"hash", "urls"}); requireParams({u"hash"_qs, u"urls"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
const QStringList urls = params()["urls"].split('|'); const QStringList urls = params()[u"urls"_qs].split(u'|');
const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers(); const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
QVector<BitTorrent::TrackerEntry> remainingTrackers; QVector<BitTorrent::TrackerEntry> remainingTrackers;
@ -816,7 +816,7 @@ void TorrentsController::removeTrackersAction()
} }
if (remainingTrackers.size() == trackers.size()) if (remainingTrackers.size() == trackers.size())
throw APIError(APIErrorType::Conflict, "No trackers were removed"); throw APIError(APIErrorType::Conflict, u"No trackers were removed"_qs);
torrent->replaceTrackers(remainingTrackers); torrent->replaceTrackers(remainingTrackers);
@ -826,10 +826,10 @@ void TorrentsController::removeTrackersAction()
void TorrentsController::addPeersAction() void TorrentsController::addPeersAction()
{ {
requireParams({"hashes", "peers"}); requireParams({u"hashes"_qs, u"peers"_qs});
const QStringList hashes = params()["hashes"].split('|'); const QStringList hashes = params()[u"hashes"_qs].split(u'|');
const QStringList peers = params()["peers"].split('|'); const QStringList peers = params()[u"peers"_qs].split(u'|');
QVector<BitTorrent::PeerAddress> peerList; QVector<BitTorrent::PeerAddress> peerList;
peerList.reserve(peers.size()); peerList.reserve(peers.size());
@ -841,7 +841,7 @@ void TorrentsController::addPeersAction()
} }
if (peerList.isEmpty()) if (peerList.isEmpty())
throw APIError(APIErrorType::BadParams, "No valid peers were specified"); throw APIError(APIErrorType::BadParams, u"No valid peers were specified"_qs);
QJsonObject results; QJsonObject results;
@ -854,8 +854,8 @@ void TorrentsController::addPeersAction()
results[torrent->id().toString()] = QJsonObject results[torrent->id().toString()] = QJsonObject
{ {
{"added", peersAdded}, {u"added"_qs, peersAdded},
{"failed", (peers.size() - peersAdded)} {u"failed"_qs, (peers.size() - peersAdded)}
}; };
}); });
@ -864,27 +864,27 @@ void TorrentsController::addPeersAction()
void TorrentsController::pauseAction() void TorrentsController::pauseAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList hashes = params()["hashes"].split('|'); const QStringList hashes = params()[u"hashes"_qs].split(u'|');
applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->pause(); }); applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->pause(); });
} }
void TorrentsController::resumeAction() void TorrentsController::resumeAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList idStrings = params()["hashes"].split('|'); const QStringList idStrings = params()[u"hashes"_qs].split(u'|');
applyToTorrents(idStrings, [](BitTorrent::Torrent *const torrent) { torrent->resume(); }); applyToTorrents(idStrings, [](BitTorrent::Torrent *const torrent) { torrent->resume(); });
} }
void TorrentsController::filePrioAction() void TorrentsController::filePrioAction()
{ {
requireParams({"hash", "id", "priority"}); requireParams({u"hash"_qs, u"id"_qs, u"priority"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
bool ok = false; bool ok = false;
const auto priority = static_cast<BitTorrent::DownloadPriority>(params()["priority"].toInt(&ok)); const auto priority = static_cast<BitTorrent::DownloadPriority>(params()[u"priority"_qs].toInt(&ok));
if (!ok) if (!ok)
throw APIError(APIErrorType::BadParams, tr("Priority must be an integer")); throw APIError(APIErrorType::BadParams, tr("Priority must be an integer"));
@ -900,7 +900,7 @@ void TorrentsController::filePrioAction()
const int filesCount = torrent->filesCount(); const int filesCount = torrent->filesCount();
QVector<BitTorrent::DownloadPriority> priorities = torrent->filePriorities(); QVector<BitTorrent::DownloadPriority> priorities = torrent->filePriorities();
bool priorityChanged = false; bool priorityChanged = false;
for (const QString &fileID : params()["id"].split('|')) for (const QString &fileID : params()[u"id"_qs].split(u'|'))
{ {
const int id = fileID.toInt(&ok); const int id = fileID.toInt(&ok);
if (!ok) if (!ok)
@ -921,9 +921,9 @@ void TorrentsController::filePrioAction()
void TorrentsController::uploadLimitAction() void TorrentsController::uploadLimitAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList idList {params()["hashes"].split('|')}; const QStringList idList {params()[u"hashes"_qs].split(u'|')};
QJsonObject map; QJsonObject map;
for (const QString &id : idList) for (const QString &id : idList)
{ {
@ -939,9 +939,9 @@ void TorrentsController::uploadLimitAction()
void TorrentsController::downloadLimitAction() void TorrentsController::downloadLimitAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList idList {params()["hashes"].split('|')}; const QStringList idList {params()[u"hashes"_qs].split(u'|')};
QJsonObject map; QJsonObject map;
for (const QString &id : idList) for (const QString &id : idList)
{ {
@ -957,35 +957,35 @@ void TorrentsController::downloadLimitAction()
void TorrentsController::setUploadLimitAction() void TorrentsController::setUploadLimitAction()
{ {
requireParams({"hashes", "limit"}); requireParams({u"hashes"_qs, u"limit"_qs});
qlonglong limit = params()["limit"].toLongLong(); qlonglong limit = params()[u"limit"_qs].toLongLong();
if (limit == 0) if (limit == 0)
limit = -1; limit = -1;
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [limit](BitTorrent::Torrent *const torrent) { torrent->setUploadLimit(limit); }); applyToTorrents(hashes, [limit](BitTorrent::Torrent *const torrent) { torrent->setUploadLimit(limit); });
} }
void TorrentsController::setDownloadLimitAction() void TorrentsController::setDownloadLimitAction()
{ {
requireParams({"hashes", "limit"}); requireParams({u"hashes"_qs, u"limit"_qs});
qlonglong limit = params()["limit"].toLongLong(); qlonglong limit = params()[u"limit"_qs].toLongLong();
if (limit == 0) if (limit == 0)
limit = -1; limit = -1;
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [limit](BitTorrent::Torrent *const torrent) { torrent->setDownloadLimit(limit); }); applyToTorrents(hashes, [limit](BitTorrent::Torrent *const torrent) { torrent->setDownloadLimit(limit); });
} }
void TorrentsController::setShareLimitsAction() void TorrentsController::setShareLimitsAction()
{ {
requireParams({"hashes", "ratioLimit", "seedingTimeLimit"}); requireParams({u"hashes"_qs, u"ratioLimit"_qs, u"seedingTimeLimit"_qs});
const qreal ratioLimit = params()["ratioLimit"].toDouble(); const qreal ratioLimit = params()[u"ratioLimit"_qs].toDouble();
const qlonglong seedingTimeLimit = params()["seedingTimeLimit"].toLongLong(); const qlonglong seedingTimeLimit = params()[u"seedingTimeLimit"_qs].toLongLong();
const QStringList hashes = params()["hashes"].split('|'); const QStringList hashes = params()[u"hashes"_qs].split(u'|');
applyToTorrents(hashes, [ratioLimit, seedingTimeLimit](BitTorrent::Torrent *const torrent) applyToTorrents(hashes, [ratioLimit, seedingTimeLimit](BitTorrent::Torrent *const torrent)
{ {
@ -996,35 +996,35 @@ void TorrentsController::setShareLimitsAction()
void TorrentsController::toggleSequentialDownloadAction() void TorrentsController::toggleSequentialDownloadAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->toggleSequentialDownload(); }); applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->toggleSequentialDownload(); });
} }
void TorrentsController::toggleFirstLastPiecePrioAction() void TorrentsController::toggleFirstLastPiecePrioAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->toggleFirstLastPiecePriority(); }); applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->toggleFirstLastPiecePriority(); });
} }
void TorrentsController::setSuperSeedingAction() void TorrentsController::setSuperSeedingAction()
{ {
requireParams({"hashes", "value"}); requireParams({u"hashes"_qs, u"value"_qs});
const bool value {parseBool(params()["value"]).value_or(false)}; const bool value {parseBool(params()[u"value"_qs]).value_or(false)};
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [value](BitTorrent::Torrent *const torrent) { torrent->setSuperSeeding(value); }); applyToTorrents(hashes, [value](BitTorrent::Torrent *const torrent) { torrent->setSuperSeeding(value); });
} }
void TorrentsController::setForceStartAction() void TorrentsController::setForceStartAction()
{ {
requireParams({"hashes", "value"}); requireParams({u"hashes"_qs, u"value"_qs});
const bool value {parseBool(params()["value"]).value_or(false)}; const bool value {parseBool(params()[u"value"_qs]).value_or(false)};
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [value](BitTorrent::Torrent *const torrent) applyToTorrents(hashes, [value](BitTorrent::Torrent *const torrent)
{ {
torrent->resume(value ? BitTorrent::TorrentOperatingMode::Forced : BitTorrent::TorrentOperatingMode::AutoManaged); torrent->resume(value ? BitTorrent::TorrentOperatingMode::Forced : BitTorrent::TorrentOperatingMode::AutoManaged);
@ -1033,10 +1033,10 @@ void TorrentsController::setForceStartAction()
void TorrentsController::deleteAction() void TorrentsController::deleteAction()
{ {
requireParams({"hashes", "deleteFiles"}); requireParams({u"hashes"_qs, u"deleteFiles"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
const DeleteOption deleteOption = parseBool(params()["deleteFiles"]).value_or(false) const DeleteOption deleteOption = parseBool(params()[u"deleteFiles"_qs]).value_or(false)
? DeleteTorrentAndFiles : DeleteTorrent; ? DeleteTorrentAndFiles : DeleteTorrent;
applyToTorrents(hashes, [deleteOption](const BitTorrent::Torrent *torrent) applyToTorrents(hashes, [deleteOption](const BitTorrent::Torrent *torrent)
{ {
@ -1046,54 +1046,54 @@ void TorrentsController::deleteAction()
void TorrentsController::increasePrioAction() void TorrentsController::increasePrioAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
BitTorrent::Session::instance()->increaseTorrentsQueuePos(toTorrentIDs(hashes)); BitTorrent::Session::instance()->increaseTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::decreasePrioAction() void TorrentsController::decreasePrioAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
BitTorrent::Session::instance()->decreaseTorrentsQueuePos(toTorrentIDs(hashes)); BitTorrent::Session::instance()->decreaseTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::topPrioAction() void TorrentsController::topPrioAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
BitTorrent::Session::instance()->topTorrentsQueuePos(toTorrentIDs(hashes)); BitTorrent::Session::instance()->topTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::bottomPrioAction() void TorrentsController::bottomPrioAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
if (!BitTorrent::Session::instance()->isQueueingSystemEnabled()) if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
BitTorrent::Session::instance()->bottomTorrentsQueuePos(toTorrentIDs(hashes)); BitTorrent::Session::instance()->bottomTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::setLocationAction() void TorrentsController::setLocationAction()
{ {
requireParams({"hashes", "location"}); requireParams({u"hashes"_qs, u"location"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
const Path newLocation {params()["location"].trimmed()}; const Path newLocation {params()[u"location"_qs].trimmed()};
if (newLocation.isEmpty()) if (newLocation.isEmpty())
throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty")); throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty"));
@ -1117,10 +1117,10 @@ void TorrentsController::setLocationAction()
void TorrentsController::setSavePathAction() void TorrentsController::setSavePathAction()
{ {
requireParams({"id", "path"}); requireParams({u"id"_qs, u"path"_qs});
const QStringList ids {params()["id"].split('|')}; const QStringList ids {params()[u"id"_qs].split(u'|')};
const Path newPath {params()["path"]}; const Path newPath {params()[u"path"_qs]};
if (newPath.isEmpty()) if (newPath.isEmpty())
throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty")); throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty"));
@ -1142,10 +1142,10 @@ void TorrentsController::setSavePathAction()
void TorrentsController::setDownloadPathAction() void TorrentsController::setDownloadPathAction()
{ {
requireParams({"id", "path"}); requireParams({u"id"_qs, u"path"_qs});
const QStringList ids {params()["id"].split('|')}; const QStringList ids {params()[u"id"_qs].split(u'|')};
const Path newPath {params()["path"]}; const Path newPath {params()[u"path"_qs]};
if (!newPath.isEmpty()) if (!newPath.isEmpty())
{ {
@ -1167,10 +1167,10 @@ void TorrentsController::setDownloadPathAction()
void TorrentsController::renameAction() void TorrentsController::renameAction()
{ {
requireParams({"hash", "name"}); requireParams({u"hash"_qs, u"name"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
QString name = params()["name"].trimmed(); QString name = params()[u"name"_qs].trimmed();
if (name.isEmpty()) if (name.isEmpty())
throw APIError(APIErrorType::Conflict, tr("Incorrect torrent name")); throw APIError(APIErrorType::Conflict, tr("Incorrect torrent name"));
@ -1179,16 +1179,16 @@ void TorrentsController::renameAction()
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
name.replace(QRegularExpression("\r?\n|\r"), " "); name.replace(QRegularExpression(u"\r?\n|\r"_qs), u" "_qs);
torrent->setName(name); torrent->setName(name);
} }
void TorrentsController::setAutoManagementAction() void TorrentsController::setAutoManagementAction()
{ {
requireParams({"hashes", "enable"}); requireParams({u"hashes"_qs, u"enable"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
const bool isEnabled {parseBool(params()["enable"]).value_or(false)}; const bool isEnabled {parseBool(params()[u"enable"_qs]).value_or(false)};
applyToTorrents(hashes, [isEnabled](BitTorrent::Torrent *const torrent) applyToTorrents(hashes, [isEnabled](BitTorrent::Torrent *const torrent)
{ {
@ -1198,26 +1198,26 @@ void TorrentsController::setAutoManagementAction()
void TorrentsController::recheckAction() void TorrentsController::recheckAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->forceRecheck(); }); applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->forceRecheck(); });
} }
void TorrentsController::reannounceAction() void TorrentsController::reannounceAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->forceReannounce(); }); applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->forceReannounce(); });
} }
void TorrentsController::setCategoryAction() void TorrentsController::setCategoryAction()
{ {
requireParams({"hashes", "category"}); requireParams({u"hashes"_qs, u"category"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
const QString category {params()["category"]}; const QString category {params()[u"category"_qs]};
applyToTorrents(hashes, [category](BitTorrent::Torrent *const torrent) applyToTorrents(hashes, [category](BitTorrent::Torrent *const torrent)
{ {
@ -1228,22 +1228,22 @@ void TorrentsController::setCategoryAction()
void TorrentsController::createCategoryAction() void TorrentsController::createCategoryAction()
{ {
requireParams({"category"}); requireParams({u"category"_qs});
const QString category = params()["category"]; const QString category = params()[u"category"_qs];
if (category.isEmpty()) if (category.isEmpty())
throw APIError(APIErrorType::BadParams, tr("Category cannot be empty")); throw APIError(APIErrorType::BadParams, tr("Category cannot be empty"));
if (!BitTorrent::Session::isValidCategoryName(category)) if (!BitTorrent::Session::isValidCategoryName(category))
throw APIError(APIErrorType::Conflict, tr("Incorrect category name")); throw APIError(APIErrorType::Conflict, tr("Incorrect category name"));
const Path savePath {params()["savePath"]}; const Path savePath {params()[u"savePath"_qs]};
const auto useDownloadPath = parseBool(params()["downloadPathEnabled"]); const auto useDownloadPath = parseBool(params()[u"downloadPathEnabled"_qs]);
BitTorrent::CategoryOptions categoryOptions; BitTorrent::CategoryOptions categoryOptions;
categoryOptions.savePath = savePath; categoryOptions.savePath = savePath;
if (useDownloadPath.has_value()) if (useDownloadPath.has_value())
{ {
const Path downloadPath {params()["downloadPath"]}; const Path downloadPath {params()[u"downloadPath"_qs]};
categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath}; categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
} }
@ -1253,19 +1253,19 @@ void TorrentsController::createCategoryAction()
void TorrentsController::editCategoryAction() void TorrentsController::editCategoryAction()
{ {
requireParams({"category", "savePath"}); requireParams({u"category"_qs, u"savePath"_qs});
const QString category = params()["category"]; const QString category = params()[u"category"_qs];
if (category.isEmpty()) if (category.isEmpty())
throw APIError(APIErrorType::BadParams, tr("Category cannot be empty")); throw APIError(APIErrorType::BadParams, tr("Category cannot be empty"));
const Path savePath {params()["savePath"]}; const Path savePath {params()[u"savePath"_qs]};
const auto useDownloadPath = parseBool(params()["downloadPathEnabled"]); const auto useDownloadPath = parseBool(params()[u"downloadPathEnabled"_qs]);
BitTorrent::CategoryOptions categoryOptions; BitTorrent::CategoryOptions categoryOptions;
categoryOptions.savePath = savePath; categoryOptions.savePath = savePath;
if (useDownloadPath.has_value()) if (useDownloadPath.has_value())
{ {
const Path downloadPath {params()["downloadPath"]}; const Path downloadPath {params()[u"downloadPath"_qs]};
categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath}; categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
} }
@ -1275,9 +1275,9 @@ void TorrentsController::editCategoryAction()
void TorrentsController::removeCategoriesAction() void TorrentsController::removeCategoriesAction()
{ {
requireParams({"categories"}); requireParams({u"categories"_qs});
const QStringList categories {params()["categories"].split('\n')}; const QStringList categories {params()[u"categories"_qs].split(u'\n')};
for (const QString &category : categories) for (const QString &category : categories)
BitTorrent::Session::instance()->removeCategory(category); BitTorrent::Session::instance()->removeCategory(category);
} }
@ -1303,10 +1303,10 @@ void TorrentsController::categoriesAction()
void TorrentsController::addTagsAction() void TorrentsController::addTagsAction()
{ {
requireParams({"hashes", "tags"}); requireParams({u"hashes"_qs, u"tags"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)}; const QStringList tags {params()[u"tags"_qs].split(u',', Qt::SkipEmptyParts)};
for (const QString &tag : tags) for (const QString &tag : tags)
{ {
@ -1320,10 +1320,10 @@ void TorrentsController::addTagsAction()
void TorrentsController::removeTagsAction() void TorrentsController::removeTagsAction()
{ {
requireParams({"hashes"}); requireParams({u"hashes"_qs});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()[u"hashes"_qs].split(u'|')};
const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)}; const QStringList tags {params()[u"tags"_qs].split(u',', Qt::SkipEmptyParts)};
for (const QString &tag : tags) for (const QString &tag : tags)
{ {
@ -1345,9 +1345,9 @@ void TorrentsController::removeTagsAction()
void TorrentsController::createTagsAction() void TorrentsController::createTagsAction()
{ {
requireParams({"tags"}); requireParams({u"tags"_qs});
const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)}; const QStringList tags {params()[u"tags"_qs].split(u',', Qt::SkipEmptyParts)};
for (const QString &tag : tags) for (const QString &tag : tags)
BitTorrent::Session::instance()->addTag(tag.trimmed()); BitTorrent::Session::instance()->addTag(tag.trimmed());
@ -1355,9 +1355,9 @@ void TorrentsController::createTagsAction()
void TorrentsController::deleteTagsAction() void TorrentsController::deleteTagsAction()
{ {
requireParams({"tags"}); requireParams({u"tags"_qs});
const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)}; const QStringList tags {params()[u"tags"_qs].split(u',', Qt::SkipEmptyParts)};
for (const QString &tag : tags) for (const QString &tag : tags)
BitTorrent::Session::instance()->removeTag(tag.trimmed()); BitTorrent::Session::instance()->removeTag(tag.trimmed());
} }
@ -1372,15 +1372,15 @@ void TorrentsController::tagsAction()
void TorrentsController::renameFileAction() void TorrentsController::renameFileAction()
{ {
requireParams({"hash", "oldPath", "newPath"}); requireParams({u"hash"_qs, u"oldPath"_qs, u"newPath"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
const Path oldPath {params()["oldPath"]}; const Path oldPath {params()[u"oldPath"_qs]};
const Path newPath {params()["newPath"]}; const Path newPath {params()[u"newPath"_qs]};
try try
{ {
@ -1394,15 +1394,15 @@ void TorrentsController::renameFileAction()
void TorrentsController::renameFolderAction() void TorrentsController::renameFolderAction()
{ {
requireParams({"hash", "oldPath", "newPath"}); requireParams({u"hash"_qs, u"oldPath"_qs, u"newPath"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
const Path oldPath {params()["oldPath"]}; const Path oldPath {params()[u"oldPath"_qs]};
const Path newPath {params()["newPath"]}; const Path newPath {params()[u"newPath"_qs]};
try try
{ {

28
src/webui/api/transfercontroller.cpp

@ -37,14 +37,14 @@
#include "base/global.h" #include "base/global.h"
#include "apierror.h" #include "apierror.h"
const char KEY_TRANSFER_DLSPEED[] = "dl_info_speed"; const QString KEY_TRANSFER_DLSPEED = u"dl_info_speed"_qs;
const char KEY_TRANSFER_DLDATA[] = "dl_info_data"; const QString KEY_TRANSFER_DLDATA = u"dl_info_data"_qs;
const char KEY_TRANSFER_DLRATELIMIT[] = "dl_rate_limit"; const QString KEY_TRANSFER_DLRATELIMIT = u"dl_rate_limit"_qs;
const char KEY_TRANSFER_UPSPEED[] = "up_info_speed"; const QString KEY_TRANSFER_UPSPEED = u"up_info_speed"_qs;
const char KEY_TRANSFER_UPDATA[] = "up_info_data"; const QString KEY_TRANSFER_UPDATA = u"up_info_data"_qs;
const char KEY_TRANSFER_UPRATELIMIT[] = "up_rate_limit"; const QString KEY_TRANSFER_UPRATELIMIT = u"up_rate_limit"_qs;
const char KEY_TRANSFER_DHT_NODES[] = "dht_nodes"; const QString KEY_TRANSFER_DHT_NODES = u"dht_nodes"_qs;
const char KEY_TRANSFER_CONNECTION_STATUS[] = "connection_status"; const QString KEY_TRANSFER_CONNECTION_STATUS = u"connection_status"_qs;
// Returns the global transfer information in JSON format. // Returns the global transfer information in JSON format.
// The return value is a JSON-formatted dictionary. // The return value is a JSON-formatted dictionary.
@ -90,8 +90,8 @@ void TransferController::downloadLimitAction()
void TransferController::setUploadLimitAction() void TransferController::setUploadLimitAction()
{ {
requireParams({"limit"}); requireParams({u"limit"_qs});
qlonglong limit = params()["limit"].toLongLong(); qlonglong limit = params()[u"limit"_qs].toLongLong();
if (limit == 0) limit = -1; if (limit == 0) limit = -1;
BitTorrent::Session::instance()->setUploadSpeedLimit(limit); BitTorrent::Session::instance()->setUploadSpeedLimit(limit);
@ -99,8 +99,8 @@ void TransferController::setUploadLimitAction()
void TransferController::setDownloadLimitAction() void TransferController::setDownloadLimitAction()
{ {
requireParams({"limit"}); requireParams({u"limit"_qs});
qlonglong limit = params()["limit"].toLongLong(); qlonglong limit = params()[u"limit"_qs].toLongLong();
if (limit == 0) limit = -1; if (limit == 0) limit = -1;
BitTorrent::Session::instance()->setDownloadSpeedLimit(limit); BitTorrent::Session::instance()->setDownloadSpeedLimit(limit);
@ -119,9 +119,9 @@ void TransferController::speedLimitsModeAction()
void TransferController::banPeersAction() void TransferController::banPeersAction()
{ {
requireParams({"peers"}); requireParams({u"peers"_qs});
const QStringList peers = params()["peers"].split('|'); const QStringList peers = params()[u"peers"_qs].split(u'|');
for (const QString &peer : peers) for (const QString &peer : peers)
{ {
const BitTorrent::PeerAddress addr = BitTorrent::PeerAddress::parse(peer.trimmed()); const BitTorrent::PeerAddress addr = BitTorrent::PeerAddress::parse(peer.trimmed());

34
src/webui/webapplication.cpp

@ -63,7 +63,7 @@
#include "api/transfercontroller.h" #include "api/transfercontroller.h"
const int MAX_ALLOWED_FILESIZE = 10 * 1024 * 1024; const int MAX_ALLOWED_FILESIZE = 10 * 1024 * 1024;
const char C_SID[] = "SID"; // name of session id cookie const auto C_SID = QByteArrayLiteral("SID"); // name of session id cookie
const QString PATH_PREFIX_ICONS {QStringLiteral("/icons/")}; const QString PATH_PREFIX_ICONS {QStringLiteral("/icons/")};
const QString WWW_FOLDER {QStringLiteral(":/www")}; const QString WWW_FOLDER {QStringLiteral(":/www")};
@ -80,7 +80,7 @@ namespace
for (const auto &cookie : cookies) for (const auto &cookie : cookies)
{ {
const int idx = cookie.indexOf('='); const int idx = cookie.indexOf(u'=');
if (idx < 0) if (idx < 0)
continue; continue;
@ -143,8 +143,8 @@ WebApplication::~WebApplication()
void WebApplication::sendWebUIFile() void WebApplication::sendWebUIFile()
{ {
const QStringList pathItems {request().path.split('/', Qt::SkipEmptyParts)}; const QStringList pathItems {request().path.split(u'/', Qt::SkipEmptyParts)};
if (pathItems.contains(".") || pathItems.contains("..")) if (pathItems.contains(u".") || pathItems.contains(u".."))
throw InternalServerErrorHTTPError(); throw InternalServerErrorHTTPError();
if (!m_isAltUIUsed) if (!m_isAltUIUsed)
@ -178,7 +178,7 @@ void WebApplication::sendWebUIFile()
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
if (!Utils::Fs::isRegularFile(localPath)) if (!Utils::Fs::isRegularFile(localPath))
{ {
status(500, "Internal Server Error"); status(500, u"Internal Server Error"_qs);
print(tr("Unacceptable file type, only regular file is allowed."), Http::CONTENT_TYPE_TXT); print(tr("Unacceptable file type, only regular file is allowed."), Http::CONTENT_TYPE_TXT);
return; return;
} }
@ -199,7 +199,7 @@ void WebApplication::sendWebUIFile()
void WebApplication::translateDocument(QString &data) const void WebApplication::translateDocument(QString &data) const
{ {
const QRegularExpression regex("QBT_TR\\((([^\\)]|\\)(?!QBT_TR))+)\\)QBT_TR\\[CONTEXT=([a-zA-Z_][a-zA-Z0-9_]*)\\]"); const QRegularExpression regex(u"QBT_TR\\((([^\\)]|\\)(?!QBT_TR))+)\\)QBT_TR\\[CONTEXT=([a-zA-Z_][a-zA-Z0-9_]*)\\]"_qs);
int i = 0; int i = 0;
bool found = true; bool found = true;
@ -220,8 +220,8 @@ void WebApplication::translateDocument(QString &data) const
QString translation = loadedText.isEmpty() ? sourceText : loadedText; QString translation = loadedText.isEmpty() ? sourceText : loadedText;
// Use HTML code for quotes to prevent issues with JS // Use HTML code for quotes to prevent issues with JS
translation.replace('\'', "&#39;"); translation.replace(u'\'', u"&#39;"_qs);
translation.replace('\"', "&#34;"); translation.replace(u'\"', u"&#34;"_qs);
data.replace(i, regexMatch.capturedLength(), translation); data.replace(i, regexMatch.capturedLength(), translation);
i += translation.length(); i += translation.length();
@ -349,7 +349,7 @@ void WebApplication::configure()
m_authSubnetWhitelist = pref->getWebUiAuthSubnetWhitelist(); m_authSubnetWhitelist = pref->getWebUiAuthSubnetWhitelist();
m_sessionTimeout = pref->getWebUISessionTimeout(); m_sessionTimeout = pref->getWebUISessionTimeout();
m_domainList = pref->getServerDomains().split(';', Qt::SkipEmptyParts); m_domainList = pref->getServerDomains().split(u';', Qt::SkipEmptyParts);
std::for_each(m_domainList.begin(), m_domainList.end(), [](QString &entry) { entry = entry.trimmed(); }); std::for_each(m_domainList.begin(), m_domainList.end(), [](QString &entry) { entry = entry.trimmed(); });
m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled(); m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled();
@ -384,7 +384,7 @@ void WebApplication::configure()
for (const QStringView line : customHeaderLines) for (const QStringView line : customHeaderLines)
{ {
const int idx = line.indexOf(':'); const int idx = line.indexOf(u':');
if (idx < 0) if (idx < 0)
{ {
// require separator `:` to be present even if `value` field can be empty // require separator `:` to be present even if `value` field can be empty
@ -403,7 +403,7 @@ void WebApplication::configure()
{ {
m_trustedReverseProxyList.clear(); m_trustedReverseProxyList.clear();
const QStringList proxyList = pref->getWebUITrustedReverseProxiesList().split(';', Qt::SkipEmptyParts); const QStringList proxyList = pref->getWebUITrustedReverseProxiesList().split(u';', Qt::SkipEmptyParts);
for (const QString &proxy : proxyList) for (const QString &proxy : proxyList)
{ {
@ -466,7 +466,7 @@ void WebApplication::sendFile(const Path &path)
// Translate the file // Translate the file
if (isTranslatable) if (isTranslatable)
{ {
QString dataStr {data}; auto dataStr = QString::fromUtf8(data);
translateDocument(dataStr); translateDocument(dataStr);
data = dataStr.toUtf8(); data = dataStr.toUtf8();
@ -533,7 +533,7 @@ void WebApplication::sessionInitialize()
{ {
Q_ASSERT(!m_currentSession); Q_ASSERT(!m_currentSession);
const QString sessionId {parseCookie(m_request.headers.value(QLatin1String("cookie"))).value(C_SID)}; const QString sessionId {parseCookie(m_request.headers.value(QLatin1String("cookie"))).value(QString::fromLatin1(C_SID))};
// TODO: Additional session check // TODO: Additional session check
@ -572,7 +572,7 @@ QString WebApplication::generateSid() const
const quint32 tmp[] = const quint32 tmp[] =
{Utils::Random::rand(), Utils::Random::rand(), Utils::Random::rand() {Utils::Random::rand(), Utils::Random::rand(), Utils::Random::rand()
, Utils::Random::rand(), Utils::Random::rand(), Utils::Random::rand()}; , Utils::Random::rand(), Utils::Random::rand(), Utils::Random::rand()};
sid = QByteArray::fromRawData(reinterpret_cast<const char *>(tmp), sizeof(tmp)).toBase64(); sid = QString::fromLatin1(QByteArray::fromRawData(reinterpret_cast<const char *>(tmp), sizeof(tmp)).toBase64());
} }
while (m_sessions.contains(sid)); while (m_sessions.contains(sid));
@ -619,7 +619,7 @@ void WebApplication::sessionStart()
QByteArray cookieRawForm = cookie.toRawForm(); QByteArray cookieRawForm = cookie.toRawForm();
if (m_isCSRFProtectionEnabled) if (m_isCSRFProtectionEnabled)
cookieRawForm.append("; SameSite=Strict"); cookieRawForm.append("; SameSite=Strict");
setHeader({Http::HEADER_SET_COOKIE, cookieRawForm}); setHeader({Http::HEADER_SET_COOKIE, QString::fromLatin1(cookieRawForm)});
} }
void WebApplication::sessionEnd() void WebApplication::sessionEnd()
@ -633,7 +633,7 @@ void WebApplication::sessionEnd()
delete m_sessions.take(m_currentSession->id()); delete m_sessions.take(m_currentSession->id());
m_currentSession = nullptr; m_currentSession = nullptr;
setHeader({Http::HEADER_SET_COOKIE, cookie.toRawForm()}); setHeader({Http::HEADER_SET_COOKIE, QString::fromLatin1(cookie.toRawForm())});
} }
bool WebApplication::isCrossSiteRequest(const Http::Request &request) const bool WebApplication::isCrossSiteRequest(const Http::Request &request) const
@ -733,7 +733,7 @@ QHostAddress WebApplication::resolveClientAddress() const
if (!forwardedFor.isEmpty()) if (!forwardedFor.isEmpty())
{ {
// client address is the 1st global IP in X-Forwarded-For or, if none available, the 1st IP in the list // client address is the 1st global IP in X-Forwarded-For or, if none available, the 1st IP in the list
const QStringList remoteIpList = forwardedFor.split(',', Qt::SkipEmptyParts); const QStringList remoteIpList = forwardedFor.split(u',', Qt::SkipEmptyParts);
if (!remoteIpList.isEmpty()) if (!remoteIpList.isEmpty())
{ {

2
src/webui/webui.cpp

@ -112,7 +112,7 @@ void WebUI::configure()
if (!m_httpServer->isListening()) if (!m_httpServer->isListening())
{ {
const auto address = (serverAddressString == "*" || serverAddressString.isEmpty()) const auto address = ((serverAddressString == u"*") || serverAddressString.isEmpty())
? QHostAddress::Any : QHostAddress(serverAddressString); ? QHostAddress::Any : QHostAddress(serverAddressString);
bool success = m_httpServer->listen(address, m_port); bool success = m_httpServer->listen(address, m_port);
if (success) if (success)

Loading…
Cancel
Save