<commit_before>#include "gamerow.h"
#include "ui_gamerow.h"

#include <QPushButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QUrlQuery>
#include <QMenu>
#include <QAction>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QPixmap>

#include <QDebug>

#include "itchioapi.h"
#include <QStandardPaths>
#include <QDir>
#include <QFile>

GameRow::GameRow(QWidget* const parent, const Game& game, const DownloadKey& key, AppController* const controller)
    : QWidget(parent)
    , ui(new Ui::GameRow)
    , game(game)
    , downloadKey(key)
    , controller(controller)
{
    ui->setupUi(this);

    networkManager = new QNetworkAccessManager(this);

    downloadMenu = new QMenu("Choose Download");
    ui->downloadButton->setMenu(downloadMenu);
    connect(downloadMenu, &QMenu::aboutToShow, this, &GameRow::onTriggerDownloadMenu);

    ui->gameCoverLabel->setFixedWidth(
        int(ui->gameCoverLabel->maximumHeight() * double(Game::COVER_WIDTH) / Game::COVER_HEIGHT));

    ui->gameTitleLabel->setText(game.title);
    ui->gameCreatorLabel->setText(game.user.nameForDisplay());

    refreshThumbnail();
}

GameRow::~GameRow()
{
    delete ui;
}

void GameRow::onClickDownload()
{
    qDebug() << "clicked download" << game.title;
}

void GameRow::onDownloadThumbnail()
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
    reply->deleteLater();

    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "Error downloading thumbnail" << reply->errorString();
        return;
    }

    QByteArray imageData = reply->readAll();
    QPixmap pixmap;
    if (pixmap.loadFromData(imageData)) {
        ui->gameCoverLabel->setPixmap(pixmap);
    }
}

void GameRow::onTriggerDownloadMenu()
{
    downloadMenu->clear();

    QAction* loaderAction = new QAction("Loading...", downloadMenu);

    loaderAction->setDisabled(true);
    downloadMenu->addAction(loaderAction);

    controller->api->downloadKeyUploads(downloadKey, [this](QList<Upload> uploads) {
        onUploads(uploads);
    });
}

void GameRow::onTriggerUpload()
{
    QAction* action = qobject_cast<QAction*>(sender());

    int pos = action->data().toInt();

    Upload upload = pendingUploads[pos];

    controller->api->downloadUpload(downloadKey, upload, [=](QString url) {
        QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
        QDir().mkpath(path);

        QString fname = QString::number(upload.id);
        QString fullPath = path + "/" + fname;

        qDebug() << "Download: " << url << "to" << fullPath;

        QFile* file = new QFile(fullPath);
        file->open(QIODevice::WriteOnly);

        QNetworkRequest request;
        request.setUrl(QUrl(url));
        request.setHeader(QNetworkRequest::UserAgentHeader, ItchioApi::USER_AGENT);
        QNetworkReply* reply = networkManager->get(request);

        connect(reply, &QNetworkReply::downloadProgress, this, &GameRow::downloadProgress);<commit_msg>Downloads are now done in a folder on the executable location.<commit_after>#include "gamerow.h"
#include "ui_gamerow.h"

#include <QPushButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QUrlQuery>
#include <QMenu>
#include <QAction>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QPixmap>

#include <QDebug>

#include "itchioapi.h"
#include <QStandardPaths>
#include <QDir>
#include <QFile>

GameRow::GameRow(QWidget* const parent, const Game& game, const DownloadKey& key, AppController* const controller)
    : QWidget(parent)
    , ui(new Ui::GameRow)
    , game(game)
    , downloadKey(key)
    , controller(controller)
{
    ui->setupUi(this);

    networkManager = new QNetworkAccessManager(this);

    downloadMenu = new QMenu("Choose Download");
    ui->downloadButton->setMenu(downloadMenu);
    connect(downloadMenu, &QMenu::aboutToShow, this, &GameRow::onTriggerDownloadMenu);

    ui->gameCoverLabel->setFixedWidth(
        int(ui->gameCoverLabel->maximumHeight() * double(Game::COVER_WIDTH) / Game::COVER_HEIGHT));

    ui->gameTitleLabel->setText(game.title);
    ui->gameCreatorLabel->setText(game.user.nameForDisplay());

    refreshThumbnail();
}

GameRow::~GameRow()
{
    delete ui;
}

void GameRow::onClickDownload()
{
    qDebug() << "clicked download" << game.title;
}

void GameRow::onDownloadThumbnail()
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
    reply->deleteLater();

    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "Error downloading thumbnail" << reply->errorString();
        return;
    }

    QByteArray imageData = reply->readAll();
    QPixmap pixmap;
    if (pixmap.loadFromData(imageData)) {
        ui->gameCoverLabel->setPixmap(pixmap);
    }
}

void GameRow::onTriggerDownloadMenu()
{
    downloadMenu->clear();

    QAction* loaderAction = new QAction("Loading...", downloadMenu);

    loaderAction->setDisabled(true);
    downloadMenu->addAction(loaderAction);

    controller->api->downloadKeyUploads(downloadKey, [this](QList<Upload> uploads) {
        onUploads(uploads);
    });
}

void GameRow::onTriggerUpload()
{
    QAction* action = qobject_cast<QAction*>(sender());

    int pos = action->data().toInt();

    Upload upload = pendingUploads[pos];

    controller->api->downloadUpload(downloadKey, upload, [=](QString url) {
        QString path = QCoreApplication::applicationDirPath() + "/Downloads";
        QDir().mkpath(path);

        QString fname = QString::number(upload.id);
        QString fullPath = path + "/" + fname;

        qDebug() << "Download: " << url << "to" << fullPath;

        QFile* file = new QFile(fullPath);
        file->open(QIODevice::WriteOnly);

        QNetworkRequest request;
        request.setUrl(QUrl(url));
        request.setHeader(QNetworkRequest::UserAgentHeader, ItchioApi::USER_AGENT);
        QNetworkReply* reply = networkManager->get(request);

        connect(reply, &QNetworkReply::downloadProgress, this, &GameRow::downloadProgress);
{'fraction_non_alphanumeric': 0.14611193660227836, 'fraction_numerical': 0.0, 'mean_word_length': 4.337444933920705, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '639373', 'n_tokens_mistral': 1932, 'n_tokens_neox': 1874, 'n_words': 342}