a-la-karte/src/bottlesimporter.cpp

129 lines
3.6 KiB
C++
Raw Normal View History

// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2026 A-La-Karte Contributors
#include "bottlesimporter.h"
#include <QDir>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
BottlesImporter::BottlesImporter(QObject *parent)
: PlatformImporter(parent)
{
}
QString BottlesImporter::platformName() const
{
return QStringLiteral("Bottles");
}
QString BottlesImporter::platformId() const
{
return QStringLiteral("bottles");
}
QStringList BottlesImporter::getBottlesPaths() const
{
QStringList paths;
// Standard Bottles locations
paths << expandPath(QStringLiteral("~/.local/share/bottles"));
// Flatpak Bottles
paths << expandPath(QStringLiteral("~/.var/app/com.usebottles.bottles/data/bottles"));
return paths;
}
bool BottlesImporter::isAvailable() const
{
for (const QString &path : getBottlesPaths()) {
if (directoryExists(path)) {
return true;
}
}
return false;
}
QList<Game *> BottlesImporter::parseBottle(const QString &bottlePath, const QString &bottleName) const
{
QList<Game *> games;
// Look for programs in the bottle
QString programsPath = bottlePath + QStringLiteral("/programs.json");
QFile programsFile(programsPath);
if (!programsFile.open(QIODevice::ReadOnly)) {
return games;
}
QJsonDocument doc = QJsonDocument::fromJson(programsFile.readAll());
if (!doc.isObject()) {
return games;
}
QJsonObject programs = doc.object();
for (auto it = programs.begin(); it != programs.end(); ++it) {
QString programName = it.key();
QJsonObject programData = it.value().toObject();
QString executable = programData[QStringLiteral("executable")].toString();
QString path = programData[QStringLiteral("path")].toString();
if (programName.isEmpty() || executable.isEmpty()) {
continue;
}
QString gameId = QStringLiteral("bottles_%1_%2").arg(bottleName, programName).replace(QStringLiteral(" "), QStringLiteral("_")).toLower();
Game *game = new Game(gameId, programName);
game->setPlatform(platformName());
game->setPlatformId(platformId());
// Build launch command using bottles CLI
QString launchCmd = QStringLiteral("flatpak run com.usebottles.bottles -e \"%1\" -b \"%2\"").arg(executable, bottleName);
// Check if native bottles is available
if (!findExecutable(QStringLiteral("bottles-cli")).isEmpty()) {
launchCmd = QStringLiteral("bottles-cli run -e \"%1\" -b \"%2\"").arg(executable, bottleName);
}
game->setLaunchCommand(launchCmd);
game->setDescription(QStringLiteral("Wine application from %1 bottle").arg(bottleName));
games.append(game);
}
return games;
}
QList<Game *> BottlesImporter::importGames()
{
QList<Game *> games;
for (const QString &basePath : getBottlesPaths()) {
QString bottlesDir = basePath + QStringLiteral("/bottles");
QDir dir(bottlesDir);
if (!dir.exists()) {
continue;
}
QStringList bottles = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
int total = bottles.count();
int current = 0;
for (const QString &bottleName : bottles) {
current++;
Q_EMIT importProgress(current, total);
QString bottlePath = dir.absoluteFilePath(bottleName);
QList<Game *> bottleGames = parseBottle(bottlePath, bottleName);
games.append(bottleGames);
}
}
return games;
}