mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-03-27 01:03:09 +00:00
Initial release of A-La-Karte, a unified game launcher for KDE Plasma. Includes the QML UI, platform importers, AppStream metadata, icons, and developer documentation.
128 lines
3.6 KiB
C++
128 lines
3.6 KiB
C++
// 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;
|
|
}
|