C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Successful in 30s
Rust / build (pull_request) Successful in 49s
Python / verify (pull_request) Successful in 1m35s
Rust / fmt (pull_request) Successful in 36s
Rust / clippy (pull_request) Successful in 54s
90 lines
2.5 KiB
C++
90 lines
2.5 KiB
C++
#include "workspace.hpp"
|
|
|
|
#include "session.hpp"
|
|
|
|
#include <QDebug>
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QFileInfo>
|
|
#include <QMimeDatabase>
|
|
#include <QStandardPaths>
|
|
|
|
namespace ZShell::llm {
|
|
|
|
Workspace::Workspace(ChatSession* session, QObject* parent)
|
|
: QObject(parent), m_session(session) {
|
|
m_path = pathFor(session->id());
|
|
}
|
|
|
|
QString Workspace::pathFor(const QString& sessionId) {
|
|
const QString state =
|
|
QStandardPaths::writableLocation(QStandardPaths::GenericStateLocation);
|
|
return state + QStringLiteral("/zshell/sandboxes/") + sessionId;
|
|
}
|
|
|
|
bool Workspace::ensure() {
|
|
return QDir().mkpath(m_path);
|
|
}
|
|
|
|
QList<Attachment*> Workspace::importFiles(
|
|
const QStringList& paths, QString& error) {
|
|
error.clear();
|
|
if (!ensure()) {
|
|
error = QStringLiteral("Could not create the sandbox directory");
|
|
return {};
|
|
}
|
|
|
|
QMimeDatabase mimeDatabase;
|
|
QList<Attachment*> result;
|
|
for (const QString& rawPath : paths) {
|
|
const QFileInfo info(rawPath);
|
|
if (!info.exists() || !info.isFile()) {
|
|
qWarning() << "Workspace: skipping" << rawPath
|
|
<< ": file not found or not a file";
|
|
error = QStringLiteral("File not found: %1").arg(info.fileName());
|
|
continue;
|
|
}
|
|
|
|
const QString mimeType = mimeDatabase.mimeTypeForFile(info).name();
|
|
const bool isImage =
|
|
mimeType.startsWith(QLatin1String("image/"), Qt::CaseInsensitive);
|
|
const qint64 cap = isImage ? MaxImageBytes : MaxFileBytes;
|
|
if (info.size() > cap) {
|
|
qWarning() << "Workspace: skipping" << rawPath << ": too large ("
|
|
<< info.size() << "bytes, cap" << cap << ")";
|
|
error = QStringLiteral("File too large: %1").arg(info.fileName());
|
|
continue;
|
|
}
|
|
|
|
QString destination = m_path + QLatin1Char('/') + info.fileName();
|
|
int suffix = 1;
|
|
while (QFile::exists(destination)) {
|
|
const QString extension = info.suffix().isEmpty()
|
|
? QString()
|
|
: QLatin1Char('.') + info.suffix();
|
|
destination = m_path + QLatin1Char('/') + info.completeBaseName() +
|
|
QStringLiteral("_%1%2").arg(suffix).arg(extension);
|
|
++suffix;
|
|
}
|
|
|
|
if (!QFile::copy(info.absoluteFilePath(), destination)) {
|
|
qWarning() << "Workspace: skipping" << rawPath << ": copy to"
|
|
<< destination << "failed";
|
|
error =
|
|
QStringLiteral("Could not copy file: %1").arg(info.fileName());
|
|
continue;
|
|
}
|
|
|
|
result.append(new Attachment(
|
|
info.fileName(),
|
|
destination,
|
|
isImage ? Attachment::Kind::Image : Attachment::Kind::File,
|
|
mimeType,
|
|
info.size(),
|
|
m_session));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // namespace ZShell::llm
|