Initial codex telegram bot source
This commit is contained in:
172
cmd/admin/main.go
Normal file
172
cmd/admin/main.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"codex-telegram-bot/internal/store"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(context.Background(), os.Args[1:]); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run(ctx context.Context, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return usage()
|
||||
}
|
||||
dbPath := os.Getenv("DB_PATH")
|
||||
if dbPath == "" {
|
||||
dbPath = filepath.Join("data", "bot.db")
|
||||
}
|
||||
st, err := store.Open(ctx, dbPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer st.Close()
|
||||
|
||||
switch args[0] {
|
||||
case "allow-user":
|
||||
return allowUser(ctx, st, args[1:])
|
||||
case "remove-user":
|
||||
return removeUser(ctx, st, args[1:])
|
||||
case "list-users":
|
||||
return listUsers(ctx, st)
|
||||
case "add-workspace":
|
||||
return addWorkspace(ctx, st, args[1:])
|
||||
case "list-workspaces":
|
||||
return listWorkspaces(ctx, st)
|
||||
default:
|
||||
return usage()
|
||||
}
|
||||
}
|
||||
|
||||
func usage() error {
|
||||
return errors.New(`usage:
|
||||
admin allow-user TELEGRAM_USER_ID [username] [notes...]
|
||||
admin remove-user TELEGRAM_USER_ID
|
||||
admin list-users
|
||||
admin add-workspace ABSOLUTE_PATH [label] [--default]
|
||||
admin list-workspaces`)
|
||||
}
|
||||
|
||||
func allowUser(ctx context.Context, st *store.Store, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return errors.New("allow-user requires TELEGRAM_USER_ID")
|
||||
}
|
||||
userID, err := strconv.ParseInt(args[0], 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid telegram user id: %w", err)
|
||||
}
|
||||
username := ""
|
||||
notes := ""
|
||||
if len(args) >= 2 {
|
||||
username = args[1]
|
||||
}
|
||||
if len(args) >= 3 {
|
||||
notes = strings.Join(args[2:], " ")
|
||||
}
|
||||
if err := st.AddAllowedUser(ctx, userID, username, notes); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("allowed user %d\n", userID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeUser(ctx context.Context, st *store.Store, args []string) error {
|
||||
if len(args) != 1 {
|
||||
return errors.New("remove-user requires TELEGRAM_USER_ID")
|
||||
}
|
||||
userID, err := strconv.ParseInt(args[0], 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid telegram user id: %w", err)
|
||||
}
|
||||
if err := st.RemoveAllowedUser(ctx, userID); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("removed user %d\n", userID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func listUsers(ctx context.Context, st *store.Store) error {
|
||||
users, err := st.ListAllowedUsers(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(users) == 0 {
|
||||
fmt.Println("no allowed users")
|
||||
return nil
|
||||
}
|
||||
for _, user := range users {
|
||||
if user.Username == "" && user.Notes == "" {
|
||||
fmt.Printf("%d\n", user.TelegramUserID)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("%d\t%s\t%s\n", user.TelegramUserID, user.Username, user.Notes)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addWorkspace(ctx context.Context, st *store.Store, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return errors.New("add-workspace requires ABSOLUTE_PATH")
|
||||
}
|
||||
path := args[0]
|
||||
label := ""
|
||||
isDefault := false
|
||||
for _, arg := range args[1:] {
|
||||
if arg == "--default" {
|
||||
isDefault = true
|
||||
continue
|
||||
}
|
||||
if label == "" {
|
||||
label = arg
|
||||
continue
|
||||
}
|
||||
label += " " + arg
|
||||
}
|
||||
clean, err := store.ValidateWorkspacePath(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := os.Stat(clean)
|
||||
if err != nil {
|
||||
return fmt.Errorf("workspace path is not accessible: %w", err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return errors.New("workspace path must be a directory")
|
||||
}
|
||||
workspace, err := st.AddWorkspace(ctx, clean, label, isDefault)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("workspace %d\t%s\t%s\n", workspace.ID, workspace.Label, workspace.Path)
|
||||
return nil
|
||||
}
|
||||
|
||||
func listWorkspaces(ctx context.Context, st *store.Store) error {
|
||||
workspaces, err := st.ListWorkspaces(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(workspaces) == 0 {
|
||||
fmt.Println("no workspaces")
|
||||
return nil
|
||||
}
|
||||
for _, workspace := range workspaces {
|
||||
marker := ""
|
||||
if workspace.IsDefault {
|
||||
marker = "default"
|
||||
}
|
||||
fmt.Printf("%d\t%s\t%s\t%s\n", workspace.ID, marker, workspace.Label, workspace.Path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user