diff --git a/.gitignore b/.gitignore index de54ee9..a354b92 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -/lure-updater.toml -/lure-updater +/alr-updater.toml +/alr-updater /dist/ *.star -.gigaide -.idea -.claude \ No newline at end of file +.gigaide/ +.idea/ +.claude/ +CLAUDE.md \ No newline at end of file diff --git a/README.md b/README.md index 062df68..3052fc3 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ ALR-Updater — это модульный бот, предназначенный ```bash # Клонирование репозитория -git clone https://github.com/your-username/ALR-updater.git +git clone https://gitea.plemya-x.ru/Plemya-x/ALR-updater.git cd ALR-updater # Сборка @@ -70,7 +70,7 @@ sudo cp alr-updater.example.toml /etc/alr-updater/config.toml ```toml [git] - repoURL = "https://gitverse.ru/Xpamych/xpamych-alr-repo" + repoURL = "https://gitea.plemya-x.ru/Plemya-x/alr-repo.git" repoDir = "/etc/alr-updater/repo" [git.commit] @@ -411,7 +411,7 @@ def update_package_with_notification(package_name, new_version): Вы можете использовать переменные окружения вместо файла конфигурации: ```bash -export GIT_REPO_URL="https://gitverse.ru/Xpamych/xpamych-alr-repo" +export GIT_REPO_URL="https://gitea.plemya-x.ru/Plemya-x/alr-repo.git" export GIT_REPO_DIR="/tmp/alr-repo" export GIT_COMMIT_NAME="ALR Updater" export GIT_COMMIT_EMAIL="bot@example.com" diff --git a/alr-updater.example.toml b/alr-updater.example.toml index 68a538f..361ca31 100644 --- a/alr-updater.example.toml +++ b/alr-updater.example.toml @@ -1,12 +1,12 @@ [git] - repoURL = "https://gitverse.ru/Xpamych/xpamych-alr-repo" + repoURL = "https://gitea.plemya-x.ru/Plemya-x/alr-repo.git" repoDir = "/etc/alr-updater/repo" [git.commit] # Имя и адрес электронной почты, которые будут использоваться при фиксации git name = "CHANGE ME" email = "CHANGE ME" [git.credentials] - # Имя пользователя и пароль для git push. Используйте личный токен доступа в качестве пароля для Github. + # Имя пользователя и пароль для git push. Используйте личный токен доступа в качестве пароля для Gitea. username = "CHANGE ME" password = "CHANGE ME" diff --git a/go.mod b/go.mod index 6ed0e44..519fc42 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module lure.sh/lure-updater +module gitea.plemya-x.ru/Plemya-x/ALR-updater go 1.20 diff --git a/internal/builtins/http.go b/internal/builtins/http.go index 54ab524..65dfc46 100644 --- a/internal/builtins/http.go +++ b/internal/builtins/http.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +27,7 @@ import ( "strings" "go.elara.ws/logger/log" - "lure.sh/lure-updater/internal/config" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config" "go.starlark.net/starlark" "go.starlark.net/starlarkstruct" "golang.org/x/crypto/bcrypt" diff --git a/internal/builtins/log.go b/internal/builtins/log.go index 0b653b7..7f66bd0 100644 --- a/internal/builtins/log.go +++ b/internal/builtins/log.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/internal/builtins/reader.go b/internal/builtins/reader.go index 0915214..6edf1b9 100644 --- a/internal/builtins/reader.go +++ b/internal/builtins/reader.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/vmihailenco/msgpack/v5" - "lure.sh/lure-updater/internal/convert" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/convert" "go.starlark.net/starlark" "go.starlark.net/starlarkstruct" ) diff --git a/internal/builtins/regex.go b/internal/builtins/regex.go index a30312d..c9cb8aa 100644 --- a/internal/builtins/regex.go +++ b/internal/builtins/regex.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,6 +36,8 @@ var regexModule = &starlarkstruct.Module{ Members: starlark.StringDict{ "compile": starlark.NewBuiltin("regex.compile", regexCompile), "compile_glob": starlark.NewBuiltin("regex.compile_glob", regexCompileGlob), + "find": starlark.NewBuiltin("regex.find", regexFind), + "replace": starlark.NewBuiltin("regex.replace", regexReplace), }, } @@ -143,3 +145,55 @@ func matchesToStarlark1D(match []string) *starlark.List { } return starlark.NewList(list) } + +func regexFind(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var pattern, text string + err := starlark.UnpackArgs("regex.find", args, kwargs, "pattern", &pattern, "text", &text) + if err != nil { + return nil, err + } + + cacheMtx.Lock() + regex, ok := regexCache[pattern] + if !ok { + regex, err = pcre.Compile(pattern) + if err != nil { + cacheMtx.Unlock() + return nil, err + } + regexCache[pattern] = regex + } + cacheMtx.Unlock() + + matches := regex.FindStringSubmatch(text) + if len(matches) > 1 { + return starlark.String(matches[1]), nil + } + if len(matches) > 0 { + return starlark.String(matches[0]), nil + } + return starlark.String(""), nil +} + +func regexReplace(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var text, pattern, replacement string + err := starlark.UnpackArgs("regex.replace", args, kwargs, "text", &text, "pattern", &pattern, "replacement", &replacement) + if err != nil { + return nil, err + } + + cacheMtx.Lock() + regex, ok := regexCache[pattern] + if !ok { + regex, err = pcre.Compile(pattern) + if err != nil { + cacheMtx.Unlock() + return nil, err + } + regexCache[pattern] = regex + } + cacheMtx.Unlock() + + result := regex.ReplaceAllString(text, replacement) + return starlark.String(result), nil +} diff --git a/internal/builtins/register.go b/internal/builtins/register.go index 24976c4..4af4e4b 100644 --- a/internal/builtins/register.go +++ b/internal/builtins/register.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ package builtins import ( "net/http" - "lure.sh/lure-updater/internal/config" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config" "go.etcd.io/bbolt" "go.starlark.net/starlark" "go.starlark.net/starlarkjson" @@ -35,7 +35,7 @@ type Options struct { } func Register(sd starlark.StringDict, opts *Options) { - sd["run_every"] = starlark.NewBuiltin("run_every", runEvery) + sd["run_every"] = runEveryModule sd["sleep"] = starlark.NewBuiltin("sleep", sleep) sd["http"] = httpModule sd["regex"] = regexModule diff --git a/internal/builtins/run_every.go b/internal/builtins/run_every.go index 994d717..848f6c8 100644 --- a/internal/builtins/run_every.go +++ b/internal/builtins/run_every.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -100,3 +100,76 @@ func newTickerHandle(handle int) starlark.Value { "stop": stopTicker(handle), }) } + +var runEveryModule = &starlarkstruct.Module{ + Name: "run_every", + Members: starlark.StringDict{ + "minute": starlark.NewBuiltin("run_every.minute", runEveryMinute), + "hour": starlark.NewBuiltin("run_every.hour", runEveryHour), + "day": starlark.NewBuiltin("run_every.day", runEveryDay), + "week": starlark.NewBuiltin("run_every.week", runEveryWeek), + }, +} + +func runEveryMinute(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var fn *starlark.Function + err := starlark.UnpackArgs("run_every.minute", args, kwargs, "function", &fn) + if err != nil { + return nil, err + } + return runScheduled(thread, fn, "1m") +} + +func runEveryHour(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var fn *starlark.Function + err := starlark.UnpackArgs("run_every.hour", args, kwargs, "function", &fn) + if err != nil { + return nil, err + } + return runScheduled(thread, fn, "1h") +} + +func runEveryDay(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var fn *starlark.Function + err := starlark.UnpackArgs("run_every.day", args, kwargs, "function", &fn) + if err != nil { + return nil, err + } + return runScheduled(thread, fn, "24h") +} + +func runEveryWeek(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var fn *starlark.Function + err := starlark.UnpackArgs("run_every.week", args, kwargs, "function", &fn) + if err != nil { + return nil, err + } + return runScheduled(thread, fn, "168h") +} + +func runScheduled(thread *starlark.Thread, fn *starlark.Function, duration string) (starlark.Value, error) { + d, err := time.ParseDuration(duration) + if err != nil { + return nil, err + } + + tickerMtx.Lock() + t := time.NewTicker(d) + handle := tickerCount + tickers[handle] = t + tickerCount++ + tickerMtx.Unlock() + log.Debug("Created new scheduled ticker").Int("handle", handle).Str("duration", duration).Stringer("pos", thread.CallFrame(1).Pos).Send() + + go func() { + for range t.C { + log.Debug("Calling scheduled function").Str("name", fn.Name()).Stringer("pos", fn.Position()).Send() + _, err := starlark.Call(thread, fn, nil, nil) + if err != nil { + log.Warn("Error while executing scheduled function").Str("name", fn.Name()).Stringer("pos", fn.Position()).Err(err).Send() + } + } + }() + + return newTickerHandle(handle), nil +} diff --git a/internal/builtins/store.go b/internal/builtins/store.go index a150cac..a01e17f 100644 --- a/internal/builtins/store.go +++ b/internal/builtins/store.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/internal/builtins/updater.go b/internal/builtins/updater.go index fd55c43..e3d30fd 100644 --- a/internal/builtins/updater.go +++ b/internal/builtins/updater.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ import ( "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/transport/http" "go.elara.ws/logger/log" - "lure.sh/lure-updater/internal/config" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config" "go.starlark.net/starlark" "go.starlark.net/starlarkstruct" ) diff --git a/internal/config/config.go b/internal/config/config.go index 61b2b37..430e250 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lure-updater.example.toml b/lure-updater.example.toml deleted file mode 100644 index da16945..0000000 --- a/lure-updater.example.toml +++ /dev/null @@ -1,15 +0,0 @@ -[git] - repoURL = "https://github.com/lure-sh/lure-repo.git" - repoDir = "/etc/lure-updater/repo" - [git.commit] - # The name and email to use in the git commit - name = "CHANGE ME" - email = "CHANGE ME" - [git.credentials] - # Username and password for git push. Use a personal access token as the password for Github. - username = "CHANGE ME" - password = "CHANGE ME" - -[webhook] - # A hash of the webhook password. Generate one using `lure-updater -g`. - pwd_hash = "CHANGE ME" \ No newline at end of file diff --git a/main.go b/main.go index 6360799..9cb943b 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ /* - * LURE Updater - Automated updater bot for LURE packages - * Copyright (C) 2023 Elara Musayelyan + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,8 +31,8 @@ import ( "github.com/spf13/pflag" "go.elara.ws/logger" "go.elara.ws/logger/log" - "lure.sh/lure-updater/internal/builtins" - "lure.sh/lure-updater/internal/config" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/builtins" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config" "go.etcd.io/bbolt" "go.starlark.net/starlark" "golang.org/x/crypto/bcrypt" @@ -44,9 +44,9 @@ func init() { } func main() { - configPath := pflag.StringP("config", "c", "/etc/lure-updater/config.toml", "Path to config file") - dbPath := pflag.StringP("database", "d", "/etc/lure-updater/db", "Path to database file") - pluginDir := pflag.StringP("plugin-dir", "p", "/etc/lure-updater/plugins", "Path to plugin directory") + configPath := pflag.StringP("config", "c", "/etc/alr-updater/config.toml", "Path to config file") + dbPath := pflag.StringP("database", "d", "/etc/alr-updater/db", "Path to database file") + pluginDir := pflag.StringP("plugin-dir", "p", "/etc/alr-updater/plugins", "Path to plugin directory") serverAddr := pflag.StringP("address", "a", ":8080", "Webhook server address") genHash := pflag.BoolP("gen-hash", "g", false, "Generate a password hash for webhooks") useEnv := pflag.BoolP("use-env", "E", false, "Use environment variables for configuration") diff --git a/template.nomad b/template.nomad index 997c1c9..e307db4 100644 --- a/template.nomad +++ b/template.nomad @@ -1,37 +1,37 @@ -job "lure-updater" { +job "alr-updater" { region = "global" datacenters = ["dc1"] type = "service" - group "lure-updater" { + group "alr-updater" { network { port "webhook" { to = 8080 } } - volume "lure-updater-data" { + volume "alr-updater-data" { type = "host" - source = "lure-updater-data" + source = "alr-updater-data" read_only = false } - task "lure-updater" { + task "alr-updater" { driver = "docker" volume_mount { - volume = "lure-updater-data" - destination = "/etc/lure-updater" + volume = "alr-updater-data" + destination = "/etc/alr-updater" read_only = false } env { - GIT_REPO_DIR = "/etc/lure-updater/repo" - GIT_REPO_URL = "https://github.com/lure-sh/lure-repo.git" - GIT_CREDENTIALS_USERNAME = "lure-repo-bot" - GIT_CREDENTIALS_PASSWORD = "${GITHUB_PASSWORD}" - GIT_COMMIT_NAME = "lure-repo-bot" - GIT_COMMIT_EMAIL = "lure@elara.ws" + GIT_REPO_DIR = "/etc/alr-updater/repo" + GIT_REPO_URL = "https://gitea.plemya-x.ru/Plemya-x/alr-repo.git" + GIT_CREDENTIALS_USERNAME = "alr-repo-bot" + GIT_CREDENTIALS_PASSWORD = "${GITEA_PASSWORD}" + GIT_COMMIT_NAME = "alr-repo-bot" + GIT_COMMIT_EMAIL = "bot@plemya-x.ru" WEBHOOK_PASSWORD_HASH = "${PASSWORD_HASH}" // Hack to force Nomad to re-deploy the service @@ -41,25 +41,25 @@ job "lure-updater" { config { image = "alpine:latest" - command = "/opt/lure-updater/lure-updater" + command = "/opt/alr-updater/alr-updater" args = ["-DE"] ports = ["webhook"] - volumes = ["local/lure-updater/:/opt/lure-updater:ro"] + volumes = ["local/alr-updater/:/opt/alr-updater:ro"] } artifact { - source = "https://api.minio.elara.ws/lure-updater/lure-updater-$${attr.cpu.arch}.tar.gz" - destination = "local/lure-updater" + source = "https://gitea.plemya-x.ru/api/v1/repos/Plemya-x/ALR-updater/releases/latest/alr-updater-$${attr.cpu.arch}.tar.gz" + destination = "local/alr-updater" } service { - name = "lure-updater" + name = "alr-updater" port = "webhook" tags = [ "traefik.enable=true", - "traefik.http.routers.lure-updater.rule=Host(`updater.lure.sh`)", - "traefik.http.routers.lure-updater.tls.certResolver=letsencrypt", + "traefik.http.routers.alr-updater.rule=Host(`updater.plemya-x.ru`)", + "traefik.http.routers.alr-updater.tls.certResolver=letsencrypt", ] } }