48 if (reply->error() != QNetworkReply::NoError) {
49 outErrorMessage = reply->errorString();
53 int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
54 if (statusCode < 200 || statusCode > 300) {
55 outErrorMessage = i18n(
"Server responded with error %1.").arg(statusCode);
70 QString content = QString::fromUtf8(reply->readAll());
81 QRegularExpression re(QStringLiteral(
"\\A\\s*([0-9]+)\\s+([0-9a-fA-F]+)\\b"));
82 QRegularExpressionMatch match = re.match(content);
83 if (!match.hasMatch()) {
89 unsigned int expectedVersion = match.captured(1).toUInt(&ok);
90 dbgResources <<
"Expected version from fetched check0.txt:" << expectedVersion;
96 QString expectedHash = match.captured(2);
97 dbgResources <<
"Expected hash from fetched check0.txt:" << expectedHash;
108 QRegularExpression re(QStringLiteral(
"\\A!failure=([a-zA-Z0-9]*)"), QRegularExpression::CaseInsensitiveOption);
109 QRegularExpressionMatch match = re.match(content);
110 if (!match.hasMatch()) {
114 QString failureType = match.captured(1);
115 QString errorMessage;
116 if (failureType.compare(QStringLiteral(
"outdated"), Qt::CaseInsensitive) == 0) {
117 errorMessage = i18n(
"You have to update Krita to use this service.");
118 }
else if (failureType.compare(QStringLiteral(
"region"), Qt::CaseInsensitive) == 0) {
119 errorMessage = i18n(
"This service is not available in your region.");
120 }
else if (failureType.compare(QStringLiteral(
"unavailable"), Qt::CaseInsensitive) == 0) {
121 errorMessage = i18n(
"This service is currently unavailable.");
122 }
else if (failureType.compare(QStringLiteral(
"discontinued"), Qt::CaseInsensitive) == 0) {
123 errorMessage = i18n(
"This service has been discontinued.");
125 errorMessage = i18n(
"Unknown service error %1.").arg(failureType);
172 unsigned int expectedVersion,
173 const QString &expectedHash)
175 QString errorMessage;
181 QByteArray bytes = reply->readAll();
182 unsigned int version;
190 if (version != expectedVersion) {
195 QString hash = QCryptographicHash::hash(bytes, QCryptographicHash::Md5).toHex();
198 if (hash != expectedHash) {
204 if (!QDir().mkpath(dirName)) {
210 saveFile.setDirectWriteFallback(
true);
211 if (!saveFile.open(QIODevice::WriteOnly)) {
216 qint64 written = saveFile.write(bytes);
217 if (written != qint64(bytes.size()) || !saveFile.commit()) {
227 QString errorMessage;
228 bool ok =
doWithIndexDb(errorMessage, [
this](QSqlDatabase &db, QString &outErrorMessage) {
231 QString selectBundlesSql = QStringLiteral(
232 "select bundle_id, file_name, size_in_bytes, source, title,\n"
233 " description, author, license, checksum, thumbnail\n"
235 if (!query.exec(selectBundlesSql)) {
236 outErrorMessage = query.lastError().text();
240 QHash<long long, KisSupporterBundle> bundlesById;
241 while (query.next()) {
242 long long id = query.value(0).toLongLong();
244 query.value(1).toString(),
245 query.value(2).toLongLong(),
246 query.value(3).toString(),
247 query.value(4).toString(),
248 query.value(5).toString(),
249 query.value(6).toString(),
250 query.value(7).toString(),
251 query.value(8).toString(),
254 QHash<QString, int>(),
256 bundle.
thumbnail.loadFromData(query.value(9).toByteArray());
257 bundlesById.insert(
id, bundle);
260 QString selectTagsSql = QStringLiteral(
"select bundle_id, tag from bundle_tag");
261 if (!query.exec(selectTagsSql)) {
262 outErrorMessage = query.lastError().text();
266 while (query.next()) {
267 long long id = query.value(0).toLongLong();
268 QHash<long long, KisSupporterBundle>::iterator it = bundlesById.find(
id);
269 if (it != bundlesById.end()) {
270 it->tags.insert(query.value(1).toString());
274 QString selectResourceCountsSql = QStringLiteral(
275 "select bundle_id, media_type, amount\n"
276 "from bundle_resource_count");
277 if (query.exec(selectResourceCountsSql)) {
278 while (query.next()) {
279 long long id = query.value(0).toLongLong();
280 QHash<long long, KisSupporterBundle>::iterator it = bundlesById.find(
id);
281 if (it != bundlesById.end()) {
282 it->resourceCountByMediaType.insert(query.value(1).toString(), query.value(2).toInt());
286 warnResources <<
"Error querying bundle resource counts:" << query.lastError().text();
332 const std::function<
bool(QSqlDatabase &, QString &)> &block)
334 QString connectionName = QStringLiteral(
"KisSupporterBundlesFetcher");
337 QSqlDatabase db = QSqlDatabase::addDatabase(QStringLiteral(
"QSQLITE"), connectionName);
340 ok = block(db, outErrorMessage);
344 outErrorMessage = db.lastError().text();
347 QSqlDatabase::removeDatabase(connectionName);