Files
zaloopipe/pipeline-runner/src/pipeline.cpp
T
2026-07-16 08:40:05 +03:00

139 lines
4.0 KiB
C++

#include "pipeline.h"
#include <picrypt.h>
#include <pidatetime.h>
#include <pidir.h>
#include <pifile.h>
#include <piiodevice.h>
static PIJSON promptToJSON(const Prompt & p) {
PIJSON j = PIJSON::newObject();
j["id"] = p.id;
j["text"] = p.text;
j["title"] = p.title;
j["order"] = p.order;
return j;
}
static Prompt promptFromJSON(const PIJSON & j) {
Prompt p;
p.id = j["id"].toString();
p.text = j["text"].toString();
p.title = j["title"].toString();
p.order = j["order"].toInt();
return p;
}
static PIJSON pipelineToJSON(const Pipeline & pl) {
PIJSON j = PIJSON::newObject();
j["id"] = pl.id;
j["name"] = pl.name;
j["working_dir"] = pl.working_dir;
j["created_at"] = pl.created_at;
j["updated_at"] = pl.updated_at;
PIJSON arr = PIJSON::newArray();
for (const auto & p: pl.prompts) {
arr << promptToJSON(p);
}
j["prompts"] = arr;
return j;
}
static Pipeline pipelineFromJSON(const PIJSON & j) {
Pipeline pl;
pl.id = j["id"].toString();
pl.name = j["name"].toString();
pl.working_dir = j["working_dir"].toString();
pl.created_at = j["created_at"].toString();
pl.updated_at = j["updated_at"].toString();
PIJSON promptsJ = j["prompts"];
if (promptsJ.isArray()) {
const auto & promptsArr = promptsJ.array();
for (int i = 0; i < promptsArr.size(); ++i) {
if (promptsArr[i].isObject()) {
pl.prompts << promptFromJSON(promptsArr[i]);
}
}
}
return pl;
}
PIVector<Pipeline> loadPipelines(const PIString & pipelines_dir) {
PIVector<Pipeline> result;
PIDir dir(pipelines_dir);
if (!dir.isExists()) return result;
const auto entries = dir.entries();
for (const auto & entry: entries) {
if (!entry.isFile() || entry.extension() != "json") continue;
PIByteArray data = PIFile::readAll(entry.path);
PIJSON j = PIJSON::fromJSON(PIString::fromUTF8(data));
if (j.isObject()) {
result << pipelineFromJSON(j);
}
}
// Sort by updated_at descending
result.sort([](const Pipeline & a, const Pipeline & b) { return a.updated_at > b.updated_at; });
return result;
}
bool savePipeline(const PIString & pipelines_dir, Pipeline & pipeline) {
pipeline.updated_at = nowISO();
PIJSON j = pipelineToJSON(pipeline);
PIString path = pipelines_dir + pipeline.id + ".json";
return PIFile::writeAll(path, j.toJSON(PIJSON::Tree).toUTF8());
}
bool deletePipeline(const PIString & pipelines_dir, const PIString & pipeline_id) {
PIString path = pipelines_dir + pipeline_id + ".json";
return PIFile::remove(path);
}
Pipeline findPipeline(const PIString & pipelines_dir, const PIString & pipeline_id) {
PIString path = pipelines_dir + pipeline_id + ".json";
if (!PIFile::isExists(path)) return Pipeline();
PIByteArray data = PIFile::readAll(path);
PIJSON j = PIJSON::fromJSON(PIString::fromUTF8(data));
if (j.isObject()) {
return pipelineFromJSON(j);
}
return Pipeline();
}
void appendLog(const PIString & logs_dir, const PIString & run_id, const PIString & line) {
PIString path = logs_dir + run_id + ".log";
PIFile f(path, PIIODevice::ReadWrite);
if (f.isOpened()) {
f.seekToEnd();
PIString ts = nowISO();
f.write((ts + " " + line + "\n").toUTF8());
f.close();
}
}
PIString readLog(const PIString & logs_dir, const PIString & run_id) {
PIString path = logs_dir + run_id + ".log";
if (!PIFile::isExists(path)) return PIString();
PIByteArray data = PIFile::readAll(path);
return PIString::fromUTF8(data);
}
PIString generateUUID() {
PIByteArray bytes = PICrypt::generateRandomBuff(16);
PIString hex = bytes.toHex();
// Format as UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
return hex.left(8) + "-" + hex.mid(8, 4) + "-" + hex.mid(12, 4) + "-" + hex.mid(16, 4) + "-" + hex.mid(20, 12);
}
static PIString pad2(int v) {
return v < 10 ? "0" + PIString::fromNumber(v) : PIString::fromNumber(v);
}
PIString nowISO() {
PIDateTime dt = PIDateTime::current();
return PIString::fromNumber(dt.year) + "-" + pad2(dt.month) + "-" + pad2(dt.day) + "T" + pad2(dt.hours) + ":" + pad2(dt.minutes) + ":" +
pad2(dt.seconds) + "Z";
}