1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-21 20:27:45 +00:00

Move fetchAvatar from Account to LauncherCore

This is to head towards removing the LauncherCore dependency inside of
Account (and by extension, AccountManager.) This function should really
belong here anyway, since it uses a lot of functionality from
LauncherCore.
This commit is contained in:
Joshua Goins 2024-08-22 18:46:45 -04:00
parent 9876cb0aab
commit c602f01062
6 changed files with 74 additions and 57 deletions

View file

@ -74,6 +74,8 @@ public:
Q_INVOKABLE QString getPassword();
void setPassword(const QString &password);
void setAvatarUrl(const QString &url);
Q_INVOKABLE QString getOTP();
Q_INVOKABLE void setOTPSecret(const QString &secret);
@ -101,7 +103,6 @@ Q_SIGNALS:
bool needsPasswordChanged();
private:
void fetchAvatar();
QCoro::Task<> fetchPassword();
/**

View file

@ -43,6 +43,8 @@ public:
Q_SIGNALS:
void accountsChanged();
void accountAdded(Account *account);
void accountLodestoneIdChanged(Account *account);
private:
void insertAccount(Account *account);

View file

@ -99,7 +99,10 @@ public:
Q_INVOKABLE BenchmarkInstaller *createBenchmarkInstaller(Profile *profile);
Q_INVOKABLE BenchmarkInstaller *createBenchmarkInstallerFromExisting(Profile *profile, const QString &filePath);
/// Fetches the avatar for @p account
void fetchAvatar(Account *account);
Q_INVOKABLE void clearAvatarCache();
Q_INVOKABLE void refreshNews();
Q_INVOKABLE void refreshLogoImage();

View file

@ -21,7 +21,6 @@ Account::Account(LauncherCore &launcher, const QString &key, QObject *parent)
, m_key(key)
, m_launcher(launcher)
{
fetchAvatar();
fetchPassword();
}
@ -68,7 +67,6 @@ void Account::setLodestoneId(const QString &id)
if (m_config.lodestoneId() != id) {
m_config.setLodestoneId(id);
m_config.save();
fetchAvatar();
Q_EMIT lodestoneIdChanged();
}
}
@ -191,6 +189,14 @@ void Account::setPassword(const QString &password)
}
}
void Account::setAvatarUrl(const QString &url)
{
if (m_avatarUrl != url) {
m_avatarUrl = url;
Q_EMIT avatarUrlChanged();
}
}
QString Account::getOTP()
{
const auto otpSecret = QCoro::waitFor(getKeychainValue(QStringLiteral("otp-secret")));
@ -227,60 +233,6 @@ QString Account::getConfigPath() const
return getConfigDir().absolutePath();
}
void Account::fetchAvatar()
{
if (lodestoneId().isEmpty()) {
return;
}
const QString cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");
Utility::createPathIfNeeded(cacheLocation);
const QString filename = QStringLiteral("%1/%2.jpg").arg(cacheLocation, lodestoneId());
if (!QFile(filename).exists()) {
qDebug(ASTRA_LOG) << "Did not find lodestone character " << lodestoneId() << " in cache, fetching from Lodestone.";
QUrl url;
url.setScheme(m_launcher.settings()->preferredProtocol());
url.setHost(QStringLiteral("na.%1").arg(m_launcher.settings()->mainServer())); // TODO: NA isnt the only thing in the world...
url.setPath(QStringLiteral("/lodestone/character/%1").arg(lodestoneId()));
const QNetworkRequest request(url);
Utility::printRequest(QStringLiteral("GET"), request);
const auto reply = m_launcher.mgr()->get(request);
connect(reply, &QNetworkReply::finished, [this, filename, reply] {
const QString document = QString::fromUtf8(reply->readAll());
if (!document.isEmpty()) {
const static QRegularExpression re(
QStringLiteral(R"lit(<div\s[^>]*class=["|']frame__chara__face["|'][^>]*>\s*<img\s[&>]*src=["|']([^"']*))lit"));
const QRegularExpressionMatch match = re.match(document);
if (match.hasCaptured(1)) {
const QString newAvatarUrl = match.captured(1);
const auto avatarRequest = QNetworkRequest(QUrl(newAvatarUrl));
Utility::printRequest(QStringLiteral("GET"), avatarRequest);
auto avatarReply = m_launcher.mgr()->get(avatarRequest);
connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply] {
QFile file(filename);
file.open(QIODevice::ReadWrite);
file.write(avatarReply->readAll());
file.close();
m_avatarUrl = QStringLiteral("file:///%1").arg(filename);
Q_EMIT avatarUrlChanged();
});
}
}
});
} else {
m_avatarUrl = QStringLiteral("file:///%1").arg(filename);
Q_EMIT avatarUrlChanged();
}
}
void Account::setKeychainValue(const QString &key, const QString &value)
{
if (m_launcher.isSteamDeck()) {

View file

@ -111,10 +111,14 @@ void AccountManager::deleteAccount(Account *account)
void AccountManager::insertAccount(Account *account)
{
connect(account, &Account::avatarUrlChanged, this, [this, account] {
Q_EMIT accountLodestoneIdChanged(account);
});
beginInsertRows(QModelIndex(), static_cast<int>(m_accounts.size()), static_cast<int>(m_accounts.size()));
m_accounts.append(account);
endInsertRows();
Q_EMIT accountsChanged();
Q_EMIT accountAdded(account);
}
bool AccountManager::hasAnyAccounts() const

View file

@ -40,6 +40,9 @@ LauncherCore::LauncherCore()
m_accountManager = new AccountManager(*this, this);
m_runner = new GameRunner(*this, this);
connect(m_accountManager, &AccountManager::accountAdded, this, &LauncherCore::fetchAvatar);
connect(m_accountManager, &AccountManager::accountLodestoneIdChanged, this, &LauncherCore::fetchAvatar);
connect(this, &LauncherCore::gameClosed, this, &LauncherCore::handleGameExit);
#ifdef BUILD_SYNC
@ -154,6 +157,58 @@ BenchmarkInstaller *LauncherCore::createBenchmarkInstallerFromExisting(Profile *
return new BenchmarkInstaller(*this, *profile, filePath, this);
}
void LauncherCore::fetchAvatar(Account *account)
{
if (account->lodestoneId().isEmpty()) {
return;
}
const QString cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");
Utility::createPathIfNeeded(cacheLocation);
const QString filename = QStringLiteral("%1/%2.jpg").arg(cacheLocation, account->lodestoneId());
if (!QFile(filename).exists()) {
qDebug(ASTRA_LOG) << "Did not find lodestone character " << account->lodestoneId() << " in cache, fetching from Lodestone.";
QUrl url;
url.setScheme(settings()->preferredProtocol());
url.setHost(QStringLiteral("na.%1").arg(settings()->mainServer())); // TODO: NA isnt the only thing in the world...
url.setPath(QStringLiteral("/lodestone/character/%1").arg(account->lodestoneId()));
const QNetworkRequest request(url);
Utility::printRequest(QStringLiteral("GET"), request);
const auto reply = mgr()->get(request);
connect(reply, &QNetworkReply::finished, [this, filename, reply, account] {
const QString document = QString::fromUtf8(reply->readAll());
if (!document.isEmpty()) {
const static QRegularExpression re(
QStringLiteral(R"lit(<div\s[^>]*class=["|']frame__chara__face["|'][^>]*>\s*<img\s[&>]*src=["|']([^"']*))lit"));
const QRegularExpressionMatch match = re.match(document);
if (match.hasCaptured(1)) {
const QString newAvatarUrl = match.captured(1);
const auto avatarRequest = QNetworkRequest(QUrl(newAvatarUrl));
Utility::printRequest(QStringLiteral("GET"), avatarRequest);
auto avatarReply = mgr()->get(avatarRequest);
connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply, account] {
QFile file(filename);
file.open(QIODevice::ReadWrite);
file.write(avatarReply->readAll());
file.close();
account->setAvatarUrl(QStringLiteral("file:///%1").arg(filename));
});
}
}
});
} else {
account->setAvatarUrl(QStringLiteral("file:///%1").arg(filename));
}
}
void LauncherCore::clearAvatarCache()
{
const QString cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");