diff options
Diffstat (limited to 'sourcehut-builds/poller.luau')
| -rw-r--r-- | sourcehut-builds/poller.luau | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/sourcehut-builds/poller.luau b/sourcehut-builds/poller.luau new file mode 100644 index 0000000..39cfa5b --- /dev/null +++ b/sourcehut-builds/poller.luau @@ -0,0 +1,121 @@ +--!nonstrict +-- Poller for sourcehut, checks the actual poll + +local K = require("./constants.luau") +local ErrorUtils = require("./error_utils.luau") +local DateUtils = require("./date_utils.luau") +local TableUtils = require("./table_utils.luau") + +-------------------------------------------------------------------------------- +-- Internal Functions +-------------------------------------------------------------------------------- + +--------------------------------------------------------------- State Management + +local function notifyStateChange(state: PollerStatus) + noctalia.state.set(K.events.poller_state_updated, state) +end + +local function notifyError(error: string) + notifyStateChange({type = "error", error = error}) +end + +local function notifyBuildsChange(state: SourcehutBuildsState) + noctalia.state.set(K.events.builds_state_updated, state) +end + +------------------------------------------------------------------------ Parsing + +local function parseBuilds(builds: SourcehutBuildResponse) + local successful = 0 + local failed = 0 + local inProgress = 0 + local cutoff = noctalia.getConfig(K.poller.cutoff_configuration_key) + local build_count = noctalia.getConfig(K.poller.build_count_configuration_key) + local now = os.time() + local eligible_builds = TableUtils.trim(builds.data.me.jobs.results, build_count) + for _, job in ipairs(eligible_builds) do + local jobDate = DateUtils.parseDate(job.created) + if now - jobDate > cutoff then + continue + end + if job.status == "SUCCESS" then + successful += 1 + end + if job.status == "FAILED" then + failed += 1 + end + if job.status == "RUNNING" then + inProgress += 1 + end + end + local state = { + successful = successful, + failed = failed, + inProgress = inProgress, + user = builds.data.me.canonicalName, + builds = eligible_builds + } + notifyStateChange(K.poller.state.ok) + notifyBuildsChange(state) +end + +------------------------------------------------------------------------ Network + +local function onBuildsFetched(response: HttpResponse) + if not response.ok then + notifyError(K.poller.errors.request_failed) + return + end + local builds, error = noctalia.json.decode(response.body) + if error or builds == nil then + notifyError(K.poller.errors.bad_response) + return + end + if response.status == 400 then + if type(builds.errors) == "table" then + for _, error_response in ipairs(builds.errors) do + if ErrorUtils.isUnauthorized(error_response) then + notifyError(K.poller.errors.unauthorized) + return + end + end + end + notifyError(K.poller.errors.bad_response) + return + end + parseBuilds(builds) +end + +local function fetchBuilds() + local request: HttpRequest = { + url = K.sourcehut.builds_url, + method = "GET", + body = K.sourcehut.query, + headers = { + "Content-Type: application/json", + "Authorization: Bearer " .. noctalia.getConfig(K.sourcehut.token_configuration_key) + }, + } + noctalia.http(request, onBuildsFetched) +end + +---------------------------------------------------------------------- Lifecycle + +local function run() + noctalia.setUpdateInterval(K.poller.update_interval) + update() +end + +-------------------------------------------------------------------------------- +-- Public API +-------------------------------------------------------------------------------- +function update() + fetchBuilds() +end + +function onConfigChanged() + fetchBuilds() +end + +run() |