Files
immich-sync/src/Types.cpp
T

133 lines
3.2 KiB
C++

#include "Types.h"
#include <QJsonArray>
#include <QSet>
#include <QStringList>
using namespace Qt::StringLiterals;
ShareEndpoint ShareEndpoint::fromUserInput(const QString &input, const QString &password, QString *error)
{
ShareEndpoint result;
const QUrl url = QUrl::fromUserInput(input.trimmed());
if (!url.isValid() || (url.scheme() != u"http" && url.scheme() != u"https") || url.host().isEmpty())
{
if (error)
{
*error = u"Enter a valid HTTP or HTTPS Immich share URL."_s;
}
return result;
}
if (!url.userInfo().isEmpty())
{
if (error)
{
*error = u"Credentials in the URL are not supported."_s;
}
return result;
}
const QString path = url.path();
const qsizetype marker = path.lastIndexOf(u"/share/"_s);
if (marker < 0)
{
if (error)
{
*error = u"The URL must contain /share/<key-or-slug>."_s;
}
return result;
}
QString credential = path.sliced(marker + 7);
while (credential.endsWith(u'/'))
{
credential.chop(1);
}
if (credential.isEmpty() || credential.contains(u'/'))
{
if (error)
{
*error = u"The share key or slug is missing or malformed."_s;
}
return result;
}
QUrl cleanUrl = url;
cleanUrl.setQuery({});
cleanUrl.setFragment({});
QUrl root = cleanUrl;
root.setPath(path.first(marker) + u"/api"_s);
result.publicUrl = cleanUrl;
result.apiRoot = root;
result.credential = credential;
result.password = password;
if (error)
{
error->clear();
}
return result;
}
QString ShareEndpoint::origin() const
{
QString value = publicUrl.scheme() + u"://"_s + publicUrl.host();
if (publicUrl.port() > 0)
{
value += u":"_s + QString::number(publicUrl.port());
}
return value;
}
SyncPlan buildSyncPlan(const ShareInfo &left, const ShareInfo &right)
{
QSet<QString> leftChecksums;
QSet<QString> rightChecksums;
for (const auto &asset : left.assets)
{
if (!asset.checksum.isEmpty())
{
leftChecksums.insert(asset.checksum);
}
}
for (const auto &asset : right.assets)
{
if (!asset.checksum.isEmpty())
{
rightChecksums.insert(asset.checksum);
}
}
SyncPlan plan;
for (const auto &asset : left.assets)
{
if (!asset.checksum.isEmpty() && !rightChecksums.contains(asset.checksum))
{
plan.leftToRight.append(asset);
}
}
for (const auto &asset : right.assets)
{
if (!asset.checksum.isEmpty() && !leftChecksums.contains(asset.checksum))
{
plan.rightToLeft.append(asset);
}
}
return plan;
}
QJsonObject shareInfoJson(const ShareEndpoint &endpoint, const ShareInfo &info)
{
return {
{u"origin"_s, endpoint.origin()},
{u"name"_s, info.name},
{u"description"_s, info.description},
{u"type"_s, info.type},
{u"allowDownload"_s, info.allowDownload},
{u"allowUpload"_s, info.allowUpload},
{u"passwordProtected"_s, info.passwordProtected},
{u"assetCount"_s, static_cast<qint64>(info.assets.size())},
};
}