From 809a527c88720d78a541739346ed4e8eafb384c7 Mon Sep 17 00:00:00 2001 From: "cheetah.cat" Date: Sun, 7 Apr 2024 18:50:49 +0000 Subject: [PATCH] first commit --- .gitignore | 1 + commands/commands.go | 12 ++ commands/help.go | 13 +++ commands/kickstart.go | 82 ++++++++++++++ commands/test.go | 41 +++++++ commands/worker.go | 50 +++++++++ common/common.go | 5 + db/db.go | 93 +++++++++++++++ downloader/grabber.go | 213 +++++++++++++++++++++++++++++++++++ downloader/grabber_act.go | 115 +++++++++++++++++++ go.mod | 51 +++++++++ go.sum | 231 ++++++++++++++++++++++++++++++++++++++ main.go | 52 +++++++++ settings/settings.go | 35 ++++++ 14 files changed, 994 insertions(+) create mode 100644 .gitignore create mode 100644 commands/commands.go create mode 100644 commands/help.go create mode 100644 commands/kickstart.go create mode 100644 commands/test.go create mode 100644 commands/worker.go create mode 100644 common/common.go create mode 100644 db/db.go create mode 100644 downloader/grabber.go create mode 100644 downloader/grabber_act.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 settings/settings.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/commands/commands.go b/commands/commands.go new file mode 100644 index 0000000..525c5ae --- /dev/null +++ b/commands/commands.go @@ -0,0 +1,12 @@ +package commands + +type BaseCommand struct { + Help HelpCommand `command:"help" description:"Print this help message"` + Verbose bool `long:"verbose" description:"Print API requests and responses"` + //Scan ScanCommand `command:"scan" alias:"s" description:"scans the airband"` + Work WorkerCommand `command:"work" alias:"w" description:"work"` + Kickstart KickstartCommand `command:"kickstart" alias:"ks" description:"kickstart"` + Test TestCommand `command:"test" alias:"t" description:"test"` +} + +var ArchivinatorNG BaseCommand diff --git a/commands/help.go b/commands/help.go new file mode 100644 index 0000000..ed9d79e --- /dev/null +++ b/commands/help.go @@ -0,0 +1,13 @@ +package commands + +import ( + "errors" +) + +var ErrShowHelpMessage = errors.New("help command invoked") + +type HelpCommand struct{} + +func (command *HelpCommand) Execute(args []string) error { + return ErrShowHelpMessage +} diff --git a/commands/kickstart.go b/commands/kickstart.go new file mode 100644 index 0000000..23748de --- /dev/null +++ b/commands/kickstart.go @@ -0,0 +1,82 @@ +package commands + +import ( + "context" + "log" + "time" + + "git.cheetah.cat/archivinator-ng/workerclient/common" + grabber "git.cheetah.cat/archivinator-ng/workerclient/downloader" + "go.temporal.io/api/enums/v1" + "go.temporal.io/sdk/client" +) + +type KickstartCommand struct { + //Token string `long:"token" description:"authenticate with this token"` +} + +func (command *KickstartCommand) Execute(args []string) error { + ctx := context.Background() + + c, err := client.Dial(client.Options{ + HostPort: common.WorkerSettings.TemporalHost, + Namespace: common.WorkerSettings.TemporalNS, + }) + if err != nil { + log.Fatalln("Unable to create client", err) + } + defer c.Close() + + // @@@SNIPSTART samples-go-schedule-create-delete + // This schedule ID can be user business logic identifier as well. + scheduleID := "schedule_periodic_fetch" + workflowID := "RequestProcessingWorkflow" + // Create the schedule, start with no spec so the schedule will not run. + scheduleHandle, err := c.ScheduleClient().Create(ctx, client.ScheduleOptions{ + ID: scheduleID, + Spec: client.ScheduleSpec{ + Intervals: []client.ScheduleIntervalSpec{ + { + Every: 1 * time.Minute, + }, + }, + }, + Action: &client.ScheduleWorkflowAction{ + ID: workflowID, + Workflow: grabber.RequestProcessingWorkflow, + TaskQueue: "request-grabber", + }, + Overlap: enums.SCHEDULE_OVERLAP_POLICY_SKIP, + }) + if err != nil { + log.Fatalln("Unable to create schedule", err) + } + log.Println("Created Schedule", scheduleHandle.GetID()) + /* + // Delete the schedule once the sample is done + defer func() { + log.Println("Deleting schedule", "ScheduleID", scheduleHandle.GetID()) + err = scheduleHandle.Delete(ctx) + if err != nil { + log.Fatalln("Unable to delete schedule", err) + } + }() + */ + // @@@SNIPEND + + /* + // @@@SNIPSTART samples-go-schedule-trigger + // Manually trigger the schedule once + log.Println("Manually triggering schedule", "ScheduleID", scheduleHandle.GetID()) + + err = scheduleHandle.Trigger(ctx, client.ScheduleTriggerOptions{ + Overlap: enums.SCHEDULE_OVERLAP_POLICY_SKIP, + }) + if err != nil { + log.Fatalln("Unable to trigger schedule", err) + } + // @@@SNIPEND + + */ + return nil +} diff --git a/commands/test.go b/commands/test.go new file mode 100644 index 0000000..857dfc6 --- /dev/null +++ b/commands/test.go @@ -0,0 +1,41 @@ +package commands + +import ( + "context" + "log" + + grabber "git.cheetah.cat/archivinator-ng/workerclient/downloader" + "github.com/pborman/uuid" + "go.temporal.io/sdk/client" +) + +type TestCommand struct { + //Token string `long:"token" description:"authenticate with this token"` +} + +func (command *TestCommand) Execute(args []string) error { + //ctx := context.Background() + + c, err := client.Dial(client.Options{ + HostPort: "192.168.133.120:7233", + Namespace: "archivinator-ng", + }) + if err != nil { + log.Fatalln("Unable to create client", err) + } + defer c.Close() + + // This workflow ID can be user business logic identifier as well. + workflowID := "parent-workflow_" + uuid.New() + workflowOptions := client.StartWorkflowOptions{ + ID: workflowID, + TaskQueue: "request-grabber", + } + + we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, grabber.SampleParentWorkflow) + if err != nil { + log.Fatalln("Unable to execute workflow", err) + } + log.Println("Started workflow", "WorkflowID", we.GetID(), "RunID", we.GetRunID()) + return nil +} diff --git a/commands/worker.go b/commands/worker.go new file mode 100644 index 0000000..54632bc --- /dev/null +++ b/commands/worker.go @@ -0,0 +1,50 @@ +package commands + +import ( + "log" + + "git.cheetah.cat/archivinator-ng/workerclient/common" + "git.cheetah.cat/archivinator-ng/workerclient/db" + grabber "git.cheetah.cat/archivinator-ng/workerclient/downloader" + "go.temporal.io/sdk/client" + "go.temporal.io/sdk/worker" +) + +type WorkerCommand struct { + //Token string `long:"token" description:"authenticate with this token"` +} + +func (command *WorkerCommand) Execute(args []string) error { + db.Initialize() + + // The client and worker are heavyweight objects that should be created once per process. + c, err := client.Dial(client.Options{ + HostPort: common.WorkerSettings.TemporalHost, + Namespace: common.WorkerSettings.TemporalNS, + }) + if err != nil { + log.Fatalln("Unable to create client", err) + } + defer c.Close() + + w := worker.New(c, "request-grabber", worker.Options{ + MaxConcurrentActivityExecutionSize: 3, + EnableSessionWorker: true, // Important for a worker to participate in the session + }) + + w.RegisterWorkflow(grabber.RequestProcessingWorkflow) + w.RegisterWorkflow(grabber.FetchRequestContentsWorkflow) + + w.RegisterActivity(grabber.DBSelectOutdatedRequests) + w.RegisterActivity(grabber.DBLoadRequestEntry) + w.RegisterActivity(grabber.FetchRequestContents) + w.RegisterActivity(grabber.DBUpdateRequestLastChecked) + //w.RegisterWorkflow(grabber.SampleParentWorkflow) + //w.RegisterWorkflow(grabber.SampleChildWorkflow) + + err = w.Run(worker.InterruptCh()) + if err != nil { + log.Fatalln("Unable to start worker", err) + } + return nil +} diff --git a/common/common.go b/common/common.go new file mode 100644 index 0000000..3ac96d9 --- /dev/null +++ b/common/common.go @@ -0,0 +1,5 @@ +package common + +import "git.cheetah.cat/archivinator-ng/workerclient/settings" + +var WorkerSettings *settings.App diff --git a/db/db.go b/db/db.go new file mode 100644 index 0000000..fc5fba3 --- /dev/null +++ b/db/db.go @@ -0,0 +1,93 @@ +package db + +import ( + "context" + "database/sql" + "time" + + "git.cheetah.cat/archivinator-ng/workerclient/common" + "github.com/uptrace/bun" + "github.com/uptrace/bun/dialect/pgdialect" + "github.com/uptrace/bun/driver/pgdriver" +) + +var ( + BunDB *bun.DB + ctx context.Context +) + +type Request struct { + bun.BaseModel `bun:"table:requests"` + ID int64 `bun:"id,pk"` + Name string `bun:"column:name,notnull"` + Type string `bun:"column:type,notnull"` + URL string `bun:"column:url"` + Flags []string `bun:"column:flags"` + + DefaultQuality string `bun:"column:defaultquality"` + Tags []Tag `bun:"m2m:tag_to_request,join:Tag=Request"` + + Active bool `bun:"column:chipselect"` + Interval int `bun:"column:interval"` + LastCheck time.Time `bun:"column:lastcheck"` + + CreatedAt time.Time `bun:"createdat"` +} + +type Video struct { + bun.BaseModel `bun:"table:video"` + ID int64 `bun:"id,pk"` + Type string `bun:"column:type,notnull"` + + Title string `bun:"column:title,notnull"` + Description string `bun:"column:description"` + + IsLivestream bool `bun:"column:livestream"` + Duration int `bun:"column:duration"` + + ChannelName string `bun:"column:channel_name"` + + Tags []Tag `bun:"m2m:tag_to_videos,join:Tag=Video"` + + ArchiveDate time.Time `bun:"archive_date"` + UploadDate time.Time `bun:"upload_date"` +} +type Tag struct { + bun.BaseModel `bun:"table:tags"` + ID int64 `bun:"id,pk"` + Name string `bun:"column:name,notnull"` +} +type TagToVideo struct { + bun.BaseModel `bun:"table:tag_to_videos"` + TagID int64 `bun:",pk"` + Tag *Tag `bun:"rel:belongs-to,join:tag_id=id"` + VideoID int64 `bun:",pk"` + Video *Video `bun:"rel:belongs-to,join:video_id=id"` +} +type TagToRequest struct { + bun.BaseModel `bun:"table:tag_to_request"` + TagID int64 `bun:",pk"` + Tag *Tag `bun:"rel:belongs-to,join:tag_id=id"` + RequestID int64 `bun:",pk"` + Request *Request `bun:"rel:belongs-to,join:request_id=id"` +} + +func Initialize() { + ctx = context.Background() + + // Open a PostgreSQL database. + dsn := common.WorkerSettings.PostgresURL + pgdb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn))) + + // Create a Bun db on top of it. + BunDB = bun.NewDB(pgdb, pgdialect.New()) + + // Print all queries to stdout. + //BunDB.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true))) + + // Register M2M Tables + BunDB.RegisterModel((*TagToVideo)(nil)) + BunDB.RegisterModel((*TagToRequest)(nil)) + + //BunDB.ResetModel(context.Background(), (*TagToVideo)(nil), (*TagToRequest)(nil)) +} diff --git a/downloader/grabber.go b/downloader/grabber.go new file mode 100644 index 0000000..82aa953 --- /dev/null +++ b/downloader/grabber.go @@ -0,0 +1,213 @@ +package grabber + +import ( + "errors" + "fmt" + "time" + + "git.cheetah.cat/archivinator-ng/workerclient/db" + "github.com/ttacon/chalk" + "go.temporal.io/sdk/converter" + "go.temporal.io/sdk/workflow" +) + +func RequestProcessingWorkflow(ctx workflow.Context) error { + logger := workflow.GetLogger(ctx) + execution := workflow.GetInfo(ctx).WorkflowExecution + + ao := workflow.ActivityOptions{ + StartToCloseTimeout: 10 * time.Second, + HeartbeatTimeout: 2 * time.Second, + } + ctx1 := workflow.WithActivityOptions(ctx, ao) + + info := workflow.GetInfo(ctx1) + + // Workflow Executions started by a Schedule have the following additional properties appended to their search attributes + scheduledByIDPayload := info.SearchAttributes.IndexedFields["TemporalScheduledById"] + var scheduledByID string + err := converter.GetDefaultDataConverter().FromPayload(scheduledByIDPayload, &scheduledByID) + if err != nil { + return err + } + startTimePayload := info.SearchAttributes.IndexedFields["TemporalScheduledStartTime"] + var startTime time.Time + err = converter.GetDefaultDataConverter().FromPayload(startTimePayload, &startTime) + if err != nil { + return err + } + + logger.Warn(chalk.Red.String(), "RequestProcessingWorkflow started.", scheduledByIDPayload, startTime, chalk.Reset) + // + + var dueRequestIDs []int64 + err = workflow.ExecuteActivity(ctx1, DBSelectOutdatedRequests).Get(ctx1, &dueRequestIDs) + if err != nil { + workflow.GetLogger(ctx).Error("schedule workflow failed.", "Error", err) + return err + } + + if len(dueRequestIDs) > 0 { + logger.Info(fmt.Sprintf("Processing %d Requests", len(dueRequestIDs))) + childID := fmt.Sprintf("FetchRequestContentsWorkflow:%v", execution.RunID) + cwo := workflow.ChildWorkflowOptions{ + WorkflowID: childID, + } + ctx2 := workflow.WithChildOptions(ctx1, cwo) + var result string + err := workflow.ExecuteChildWorkflow(ctx2, FetchRequestContentsWorkflow, dueRequestIDs).Get(ctx2, &result) + if err != nil { + logger.Error("Parent execution received child execution failure.", "Error", err) + return err + } + } + return nil +} + +/* +// SampleFileProcessingWorkflow workflow definition +func SampleFileProcessingWorkflow(ctx workflow.Context, fileName string) (err error) { + ao := workflow.ActivityOptions{ + StartToCloseTimeout: time.Minute, + HeartbeatTimeout: 2 * time.Second, // such a short timeout to make sample fail over very fast + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Second, + BackoffCoefficient: 2.0, + MaximumInterval: time.Minute, + }, + } + ctx = workflow.WithActivityOptions(ctx, ao) + + // Retry the whole sequence from the first activity on any error + // to retry it on a different host. In a real application it might be reasonable to + // retry individual activities as well as the whole sequence discriminating between different types of errors. + // See the retryactivity sample for a more sophisticated retry implementation. + for i := 1; i < 5; i++ { + err = processFile(ctx, fileName) + if err == nil { + break + } + } + if err != nil { + workflow.GetLogger(ctx).Error("Workflow failed.", "Error", err.Error()) + } else { + workflow.GetLogger(ctx).Info("Workflow completed.") + } + return err +} + +func processFile(ctx workflow.Context, fileName string) (err error) { + so := &workflow.SessionOptions{ + CreationTimeout: time.Minute, + ExecutionTimeout: time.Minute, + } + sessionCtx, err := workflow.CreateSession(ctx, so) + if err != nil { + return err + } + defer workflow.CompleteSession(sessionCtx) + + var downloadedName string + var a *Activities + err = workflow.ExecuteActivity(sessionCtx, a.DownloadFileActivity, fileName).Get(sessionCtx, &downloadedName) + if err != nil { + return err + } + + var processedFileName string + err = workflow.ExecuteActivity(sessionCtx, a.ProcessFileActivity, downloadedName).Get(sessionCtx, &processedFileName) + if err != nil { + return err + } + + err = workflow.ExecuteActivity(sessionCtx, a.UploadFileActivity, processedFileName).Get(sessionCtx, nil) + return err +} +*/ + +func FetchRequestContentsWorkflow(ctx workflow.Context, leftoverRequests []int64) error { + logger := workflow.GetLogger(ctx) + ao := workflow.ActivityOptions{ + StartToCloseTimeout: 10 * time.Second, + HeartbeatTimeout: 2 * time.Second, + } + ctx1 := workflow.WithActivityOptions(ctx, ao) + so := &workflow.SessionOptions{ + CreationTimeout: time.Minute, + ExecutionTimeout: 15 * time.Minute, + } + logger.Warn(chalk.Green.String(), "FetchRequestContentsWorkflow started.", chalk.Reset) + sessionCtx, err := workflow.CreateSession(ctx1, so) + if err != nil { + logger.Error(chalk.Green.String(), "FetchRequestContentsWorkflow started.", err, chalk.Reset) + return err + } + defer workflow.CompleteSession(sessionCtx) + + if len(leftoverRequests) > 0 { + var workingRequest db.Request + err := workflow.ExecuteActivity(sessionCtx, DBLoadRequestEntry, leftoverRequests[0]).Get(sessionCtx, &workingRequest) + if err != nil { + return err + } + + err = workflow.ExecuteActivity(sessionCtx, FetchRequestContents, workingRequest).Get(sessionCtx, nil) + if err != nil { + return err + } + err = workflow.ExecuteActivity(sessionCtx, DBUpdateRequestLastChecked, workingRequest).Get(sessionCtx, nil) + if err != nil { + return err + } + } + + if len(leftoverRequests) > 1 { + return workflow.NewContinueAsNewError(ctx1, FetchRequestContentsWorkflow, leftoverRequests[1:]) + } else { + logger.Info("Child workflow completed.") + return nil + } +} + +func SampleParentWorkflow(ctx workflow.Context) error { + logger := workflow.GetLogger(ctx) + execution := workflow.GetInfo(ctx).WorkflowExecution + // Parent Workflows can choose to specify Ids for child executions. + // Make sure Ids are unique for each execution. + // Do not specify if you want the Temporal Server to generate a unique ID for the child execution. + childID := fmt.Sprintf("child_workflow:%v", execution.RunID) + cwo := workflow.ChildWorkflowOptions{ + WorkflowID: childID, + } + ctx = workflow.WithChildOptions(ctx, cwo) + var result string + err := workflow.ExecuteChildWorkflow(ctx, SampleChildWorkflow, 0, 5).Get(ctx, &result) + if err != nil { + logger.Error("Parent execution received child execution failure.", "Error", err) + return err + } + + logger.Info("Parent execution completed.", "Result", result) + return nil +} +func SampleChildWorkflow(ctx workflow.Context, totalCount, runCount int) (string, error) { + logger := workflow.GetLogger(ctx) + + logger.Info(fmt.Sprintf("Processing %d Request", totalCount)) + logger.Info("Child workflow execution started.") + if runCount <= 0 { + logger.Error("Invalid valid for run count.", "RunCount", runCount) + return "", errors.New("invalid run count") + } + workflow.Sleep(ctx, 5*time.Second) + totalCount++ + runCount-- + if runCount == 0 { + result := fmt.Sprintf("Child workflow execution completed after %v runs", totalCount) + logger.Info("Child workflow completed.", "Result", result) + return result, nil + } + + logger.Info("Child workflow starting new run.", "RunCount", runCount, "TotalCount", totalCount) + return "", workflow.NewContinueAsNewError(ctx, SampleChildWorkflow, totalCount, runCount) +} diff --git a/downloader/grabber_act.go b/downloader/grabber_act.go new file mode 100644 index 0000000..8f3625f --- /dev/null +++ b/downloader/grabber_act.go @@ -0,0 +1,115 @@ +package grabber + +import ( + "context" + "fmt" + "time" + + "git.cheetah.cat/archivinator-ng/workerclient/db" + "github.com/lrstanley/go-ytdlp" + "go.temporal.io/sdk/activity" +) + +// returns all database request ids that need a refresh +func DBSelectOutdatedRequests(ctx context.Context) (requestIDs []int64, err error) { + logger := activity.GetLogger(ctx) + if db.BunDB == nil { + db.Initialize() + ytdlp.MustInstall(context.TODO(), nil) + } + + var requests []db.Request + count, err := db.BunDB.NewSelect().Model(&requests).Where("chipselect = true").ScanAndCount(ctx) + if err != nil { + return requestIDs, err + } + activity.RecordHeartbeat(ctx) + + logger.Info("Processing %d Requests", count) + for _, requestItem := range requests { + if time.Since(requestItem.LastCheck).Minutes() > float64(requestItem.Interval) { + requestIDs = append(requestIDs, requestItem.ID) + } + } + return requestIDs, nil +} + +// Returns the Request Entry from the DB +func DBLoadRequestEntry(ctx context.Context, requestId int64) (request db.Request, err error) { + if db.BunDB == nil { + db.Initialize() + } + activity.RecordHeartbeat(ctx) + + logger := activity.GetLogger(ctx) + logger.Info(fmt.Sprintf("started DBLoadRequestEntry for ID=%d", requestId)) + var requestObj db.Request + err = db.BunDB.NewSelect(). + Model(&requestObj). + Where("id = ?", requestId). + Limit(1). + Scan(ctx) + if err != nil { + return request, err + } + return requestObj, nil +} + +// Grabs Data from YT-DLP +func FetchRequestContents(ctx context.Context, workingRequest db.Request) (decision string, err error) { + logger := activity.GetLogger(ctx) + logger.Info("Starting YT-DLP with Activity Context") + + playlistGrabber := ytdlp.New().FlatPlaylist().PrintJSON().UnsetPrintToFile() + + // sends regular heartbeats to temporal + keepAliveKiller := make(chan struct{}) + keepAliveTimer := time.NewTicker(time.Second * 1) + go func() { + for { + select { + case <-keepAliveTimer.C: + activity.RecordHeartbeat(ctx) + case <-keepAliveKiller: + keepAliveTimer.Stop() + return + } + } + }() + defer keepAliveTimer.Stop() + + output, err := playlistGrabber.Run(ctx, workingRequest.URL) + if err != nil { + return "", err + } + + info, err := output.GetExtractedInfo() + if err != nil { + return "", err + } + for _, infoobj := range info { + logger.Info(fmt.Sprint(*infoobj.Title, *infoobj.Duration, infoobj.Type, *infoobj.Extractor, infoobj.Thumbnails)) + } + + return fmt.Sprintf("Request returned %d objects", len(info)), nil +} + +func DBUpdateRequestLastChecked(ctx context.Context, workingRequest db.Request) (err error) { + if db.BunDB == nil { + db.Initialize() + } + activity.RecordHeartbeat(ctx) + + logger := activity.GetLogger(ctx) + logger.Info(fmt.Sprintf("started DBUpdateRequestLastChecked for ID=%d", workingRequest.ID)) + var requestObj db.Request + _, err = db.BunDB.NewUpdate(). + Model(&requestObj). + Where("id = ?", workingRequest.ID). + Set("lastcheck = ?", time.Now()). + Exec(ctx) + if err != nil { + return err + } + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d363058 --- /dev/null +++ b/go.mod @@ -0,0 +1,51 @@ +module git.cheetah.cat/archivinator-ng/workerclient + +go 1.21.0 + +require ( + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/jessevdk/go-flags v1.5.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/kelseyhightower/envconfig v1.4.0 // indirect + github.com/lrstanley/go-ytdlp v0.0.0-20240311044023-72ac15a1911a // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/pborman/uuid v1.2.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/robfig/cron v1.2.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/testify v1.9.0 // indirect + github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect + github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 // indirect + github.com/uptrace/bun v1.1.17 // indirect + github.com/uptrace/bun/dialect/pgdialect v1.1.17 // indirect + github.com/uptrace/bun/driver/pgdriver v1.1.17 // indirect + github.com/uptrace/bun/extra/bundebug v1.1.17 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + go.temporal.io/api v1.29.1 // indirect + go.temporal.io/sdk v1.26.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + mellium.im/sasl v0.3.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..b7b9ae4 --- /dev/null +++ b/go.sum @@ -0,0 +1,231 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= +github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/lrstanley/go-ytdlp v0.0.0-20240311044023-72ac15a1911a h1:I5rh6RTBZM1CiKaD85vnbxC70aC3r2cfwo+n64rLAeE= +github.com/lrstanley/go-ytdlp v0.0.0-20240311044023-72ac15a1911a/go.mod h1:75ujbafjqiJugIGw4K6o52/p8C0m/kt+DrYwgClXYT4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= +github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 h1:OXcKh35JaYsGMRzpvFkLv/MEyPuL49CThT1pZ8aSml4= +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= +github.com/uptrace/bun v1.1.17 h1:qxBaEIo0hC/8O3O6GrMDKxqyT+mw5/s0Pn/n6xjyGIk= +github.com/uptrace/bun v1.1.17/go.mod h1:hATAzivtTIRsSJR4B8AXR+uABqnQxr3myKDKEf5iQ9U= +github.com/uptrace/bun/dialect/pgdialect v1.1.17 h1:NsvFVHAx1Az6ytlAD/B6ty3cVE6j9Yp82bjqd9R9hOs= +github.com/uptrace/bun/dialect/pgdialect v1.1.17/go.mod h1:fLBDclNc7nKsZLzNjFL6BqSdgJzbj2HdnyOnLoDvAME= +github.com/uptrace/bun/driver/pgdriver v1.1.17 h1:hLj6WlvSZk5x45frTQnJrYtyhvgI6CA4r7gYdJ0gpn8= +github.com/uptrace/bun/driver/pgdriver v1.1.17/go.mod h1:c9fa6FiiQjOe9mCaJC9NmFUE6vCGKTEsqrtLjPNz+kk= +github.com/uptrace/bun/extra/bundebug v1.1.17 h1:LcZ8DzyyGdXAmbUqmnCpBq7TPFegMp59FGy+uzEE21c= +github.com/uptrace/bun/extra/bundebug v1.1.17/go.mod h1:FOwNaBEGGChv3qBVh3pz3TPlUuikZ93qKjd/LJdl91o= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.temporal.io/api v1.29.1 h1:L722DCy3xCzpTe3Rvh1sFC9kcSaMJXqvodCF+swHGtQ= +go.temporal.io/api v1.29.1/go.mod h1:wZtsUJ3PySASGWbpXBWYVKJ4aHB2ZODEn/xNcTr9HRs= +go.temporal.io/sdk v1.26.0 h1:QAi7irgKvJI+5cKmvy+1lkdCDJJDDNpIQAoXdr3dcyM= +go.temporal.io/sdk v1.26.0/go.mod h1:rcAf1YWlbWgMsjJEuz7XiQd6UYxTQDOk2AqRRIDwq/U= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 h1:8eadJkXbwDEMNwcB5O0s5Y5eCfyuCLdvaiOIaGTrWmQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 h1:IR+hp6ypxjH24bkMfEJ0yHR21+gwPWdV+/IBrPQyn3k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= +mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= diff --git a/main.go b/main.go new file mode 100644 index 0000000..707fe00 --- /dev/null +++ b/main.go @@ -0,0 +1,52 @@ +package main + +import ( + "fmt" + "os" + + "git.cheetah.cat/archivinator-ng/workerclient/commands" + "git.cheetah.cat/archivinator-ng/workerclient/common" + "git.cheetah.cat/archivinator-ng/workerclient/settings" + "github.com/jessevdk/go-flags" +) + +func main() { + var err error + + common.WorkerSettings, err = settings.LoadSettings() + if err != nil { + panic("config corrupt") + } + + parser := flags.NewParser(&commands.ArchivinatorNG, flags.HelpFlag|flags.PassDoubleDash) + parser.NamespaceDelimiter = "-" + + helpParser := flags.NewParser(&commands.ArchivinatorNG, flags.HelpFlag) + helpParser.NamespaceDelimiter = "-" + + _, err = parser.Parse() + handleError(helpParser, err) +} + +func handleError(helpParser *flags.Parser, err error) { + if err != nil { + if err == commands.ErrShowHelpMessage { + showHelp(helpParser) + } else if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrCommandRequired { + showHelp(helpParser) + } else if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp { + fmt.Println(err) + os.Exit(0) + } else { + fmt.Printf("error: %s\n", err) + } + + os.Exit(1) + } +} + +func showHelp(helpParser *flags.Parser) { + helpParser.ParseArgs([]string{"-h"}) + helpParser.WriteHelp(os.Stdout) + os.Exit(0) +} diff --git a/settings/settings.go b/settings/settings.go new file mode 100644 index 0000000..870b816 --- /dev/null +++ b/settings/settings.go @@ -0,0 +1,35 @@ +package settings + +import ( + "os" + + "github.com/joho/godotenv" + "github.com/kelseyhightower/envconfig" +) + +// App defines the Application Settings structure +type App struct { + PostgresURL string + + TemporalHost string + TemporalNS string +} + +// LoadSettings will pull the application config from the environment, or from +// a .env file +func LoadSettings() (config *App, err error) { + config = &App{} + + if err = godotenv.Load(); err != nil { + // We don't care if an .env is missing, it will be in prod. + if !os.IsNotExist(err) { + return nil, err + } + } + + if err = envconfig.Process("INATOR", config); err != nil { + return nil, err + } + + return config, nil +}