mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-02-09 21:13:08 +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.3 KiB
C++
128 lines
3.3 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// SPDX-FileCopyrightText: 2026 A-La-Karte Contributors
|
|
|
|
#include "itchimporter.h"
|
|
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QSqlDatabase>
|
|
#include <QSqlError>
|
|
#include <QSqlQuery>
|
|
|
|
ItchImporter::ItchImporter(QObject *parent)
|
|
: PlatformImporter(parent)
|
|
{
|
|
}
|
|
|
|
QString ItchImporter::platformName() const
|
|
{
|
|
return QStringLiteral("itch.io");
|
|
}
|
|
|
|
QString ItchImporter::platformId() const
|
|
{
|
|
return QStringLiteral("itch");
|
|
}
|
|
|
|
QString ItchImporter::getItchDatabasePath() const
|
|
{
|
|
QStringList paths = {
|
|
expandPath(QStringLiteral("~/.config/itch/db/butler.db")),
|
|
expandPath(QStringLiteral("~/.var/app/io.itch.itch/config/itch/db/butler.db")),
|
|
};
|
|
|
|
for (const QString &path : paths) {
|
|
if (QFile::exists(path)) {
|
|
return path;
|
|
}
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
bool ItchImporter::isAvailable() const
|
|
{
|
|
return !getItchDatabasePath().isEmpty();
|
|
}
|
|
|
|
QList<Game *> ItchImporter::parseItchDatabase(const QString &dbPath) const
|
|
{
|
|
QList<Game *> games;
|
|
|
|
// Use a unique connection name
|
|
QString connectionName = QStringLiteral("itch_import_%1").arg(reinterpret_cast<quintptr>(this));
|
|
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
return games;
|
|
}
|
|
|
|
// Query caves table for installed games
|
|
QSqlQuery query(db);
|
|
query.prepare(
|
|
QStringLiteral("SELECT c.id, c.game_id, g.title, g.short_text, g.cover_url, c.install_folder_name "
|
|
"FROM caves c "
|
|
"LEFT JOIN games g ON c.game_id = g.id "
|
|
"WHERE c.install_folder_name IS NOT NULL"));
|
|
|
|
if (!query.exec()) {
|
|
db.close();
|
|
return games;
|
|
}
|
|
|
|
while (query.next()) {
|
|
QString caveId = query.value(0).toString();
|
|
QString gameId = query.value(1).toString();
|
|
QString title = query.value(2).toString();
|
|
QString shortText = query.value(3).toString();
|
|
QString coverUrl = query.value(4).toString();
|
|
QString installFolder = query.value(5).toString();
|
|
|
|
if (title.isEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
QString id = QStringLiteral("itch_%1").arg(gameId);
|
|
|
|
Game *game = new Game(id, title);
|
|
game->setPlatform(platformName());
|
|
game->setPlatformId(platformId());
|
|
|
|
if (!shortText.isEmpty()) {
|
|
game->setDescription(shortText);
|
|
}
|
|
|
|
if (!coverUrl.isEmpty()) {
|
|
game->setCoverUrl(QUrl(coverUrl));
|
|
}
|
|
|
|
// Build launch command using itch app
|
|
QString launchCmd = QStringLiteral("itch://caves/%1/launch").arg(caveId);
|
|
game->setLaunchCommand(QStringLiteral("xdg-open \"%1\"").arg(launchCmd));
|
|
|
|
games.append(game);
|
|
}
|
|
|
|
db.close();
|
|
}
|
|
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
|
|
return games;
|
|
}
|
|
|
|
QList<Game *> ItchImporter::importGames()
|
|
{
|
|
QString dbPath = getItchDatabasePath();
|
|
if (dbPath.isEmpty()) {
|
|
return {};
|
|
}
|
|
|
|
return parseItchDatabase(dbPath);
|
|
}
|