cli

package
v0.0.0-...-3d84361 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2025 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CommandAddAllUsersToCommunity = &cli.Command{
	Name:  "add-all-users-to-community",
	Usage: "Add all users to community",
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()
		return pg.AddAllUsersToCommunity(ctx.Args().First())
	},
}
View Source
var CommandAdmin = &cli.Command{
	Name:  "admin",
	Usage: "Admin commands",
	Subcommands: []*cli.Command{
		{
			Name:  "make",
			Usage: "Make user an admin",
			Action: func(ctx *cli.Context) error {
				return makeUserAdmin(ctx, true)
			},
		},
		{
			Name:  "remove",
			Usage: "Remove user as admin",
			Action: func(ctx *cli.Context) error {
				return makeUserAdmin(ctx, false)
			},
		},
	},
}
View Source
var CommandDeleteUnusedCommunities = &cli.Command{
	Name:  "delete-unused-communities",
	Usage: "Delete all communities with 0 posts older than (by default) " + strconv.Itoa(defaultDays) + " days",
	Flags: []cli.Flag{
		&cli.IntFlag{
			Name:  "days",
			Usage: "Only deletes communities older than this many days",
			Value: defaultDays,
		},
		&cli.BoolFlag{
			Name:  "dry-run",
			Usage: "Run the command without actually deleting any communities",
			Value: false,
		},
	},
	Action: func(ctx *cli.Context) error {
		days := uint(ctx.Int("days"))
		dryRun := ctx.Bool("dry-run")

		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()

		dryText := ""
		if dryRun {
			dryText = " (dry run)"
		}
		log.Printf("Deleting unused communities older than %d days...%s\n", days, dryText)

		return pg.DeleteUnusedCommunities(days, dryRun)
	},
}
View Source
var CommandDeleteUser = &cli.Command{
	Name:  "delete-user",
	Usage: "Delete a user",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:     "user",
			Usage:    "Username",
			Required: true,
		},
		&cli.BoolFlag{
			Name:  "purge",
			Usage: "Delete all posts and comments of the user as well",
		},
	},
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()

		if ok := YesConfirmCommand(); !ok {
			log.Fatal("Cannot continue without a YES.")
		}

		return pg.DeleteUser(ctx.String("user"), ctx.Bool("purge"))
	},
}
View Source
var CommandFixHotness = &cli.Command{
	Name:  "fix-hotness",
	Usage: "Fix hotness of all posts",
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()
		return pg.FixPostHotScores()
	},
}
View Source
var CommandForcePassChange = &cli.Command{
	Name:  "force-pass-change",
	Usage: "Change user password",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:     "user",
			Usage:    "Username",
			Required: true,
		},
		&cli.StringFlag{
			Name:     "password",
			Usage:    "Password",
			Required: true,
		},
	},
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()

		if ok := ConfirmCommand("Are you sure?"); !ok {
			return errors.New("admin's not sure about the password change")
		}

		return pg.ChangeUserPassword(ctx.String("user"), ctx.String("password"))
	},
}
View Source
var CommandHardReset = &cli.Command{
	Name:  "hard-reset",
	Usage: "Hard reset",
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()

		if ok := YesConfirmCommand(); !ok {
			return errors.New("cannot continue without YES")
		}

		return pg.HardReset()
	},
}
View Source
var CommandImagePath = &cli.Command{
	Name:  "image-path",
	Usage: "Show where an image is stored on disk",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name: "image-path",
		},
	},
	Action: func(ctx *cli.Context) error {
		imageIDStr := ctx.Args().First()
		id, err := uid.FromString(imageIDStr)
		if err != nil {
			return fmt.Errorf("%s is not a valid image id: %w", imageIDStr, err)
		}
		fmt.Printf("Image path: %s\n", images.ImagePath(id))
		return nil
	},
}
View Source
var CommandInjectConfig = &cli.Command{
	Name:  "inject-config",
	Usage: "Outputs yaml with injected config",
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(false)
		if err != nil {
			return err
		}
		defer pg.Close()

		yamlData, err := yaml.Marshal(pg.Config())
		if err != nil {
			return fmt.Errorf("failed to marshal yaml: %w", err)
		}

		fmt.Println(string(yamlData))
		return nil
	},
}
View Source
var CommandMigrate = &cli.Command{
	Name:  "migrate",
	Usage: "Run database migrations",
	Subcommands: []*cli.Command{
		{
			Name:  "new",
			Usage: "Create a new pair of migrations files",
			Action: func(ctx *cli.Context) error {
				folder, err := os.Open("./migrations/")
				if err != nil {
					return err
				}
				files, err := folder.Readdirnames(0)
				if err != nil {
					return err
				}
				sort.Strings(files)

				last := files[len(files)-1]
				n := strings.Index(last, "_")
				if n < 0 {
					return errors.New("no underscore found in last filename")
				}
				lastVersion, err := strconv.Atoi(last[0:n])
				if err != nil {
					return err
				}

				scanner := bufio.NewScanner(os.Stdin)
				fmt.Print("New migration name: ")
				scanner.Scan()
				name := strings.TrimSpace(scanner.Text())
				if name == "" {
					return errors.New("migration name cannot be empty")
				}
				newVersion := strconv.Itoa(lastVersion + 1)
				for i := len(newVersion); i < 4; i++ {
					newVersion = "0" + newVersion
				}
				name = newVersion + "_" + strings.ToLower(strings.ReplaceAll(name, " ", "_"))
				newFiles := []string{name + ".down.sql", name + ".up.sql"}
				for _, name := range newFiles {
					file, err := os.Create("./migrations/" + name)
					if err != nil {
						return err
					}
					if err := file.Close(); err != nil {
						return err
					}
				}
				fmt.Print("Created migration!")
				return nil
			},
		},
		{
			Name:  "run",
			Usage: "Run database migrations",
			Flags: []cli.Flag{
				&cli.Int64Flag{
					Name:  "steps",
					Usage: "Migrations steps to run (0 runs all migrations, and value can be negative)",
				},
			},
			Action: func(ctx *cli.Context) error {
				pg, err := program.NewProgram(true)
				if err != nil {
					return err
				}
				defer pg.Close()
				return pg.Migrate(true, ctx.Int("steps"))
			},
		},
		{
			Name:  "status",
			Usage: "Get the current migration status",
			Action: func(ctx *cli.Context) error {
				pg, err := program.NewProgram(true)
				if err != nil {
					return err
				}
				status, err := pg.MigrationsStatus()
				if err != nil {
					return err
				}
				fmt.Printf("version: %d, dirty: %d\n", status.Version, status.Dirty)
				return nil
			},
		},
	},
}
View Source
var CommandMod = &cli.Command{
	Name:  "mod",
	Usage: "Moderator commands",
	Subcommands: []*cli.Command{
		{
			Name:  "make",
			Usage: "Make user a moderator",
			Flags: []cli.Flag{
				&cli.StringFlag{
					Name:     "community",
					Usage:    "Community name",
					Required: true,
				},
				&cli.StringFlag{
					Name:     "user",
					Usage:    "Username",
					Required: true,
				},
			},
			Action: func(ctx *cli.Context) error {
				return makeUserMod(ctx, true)
			},
		},
		{
			Name:  "remove",
			Usage: "Remove user as moderator",
			Flags: []cli.Flag{
				&cli.StringFlag{
					Name:     "community",
					Usage:    "Community name",
					Required: true,
				},
				&cli.StringFlag{
					Name:     "user",
					Usage:    "Username",
					Required: true,
				},
			},
			Action: func(ctx *cli.Context) error {
				return makeUserMod(ctx, false)
			},
		},
	},
}
View Source
var CommandNewBadge = &cli.Command{
	Name:  "new-badge",
	Usage: "New user badge",
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()
		return pg.NewBadgeType(ctx.Args().First())
	},
}
View Source
var CommandServe = &cli.Command{
	Name:  "serve",
	Usage: "Start web server",
	Action: func(ctx *cli.Context) error {
		pg, err := program.NewProgram(true)
		if err != nil {
			return err
		}
		defer pg.Close()
		return pg.Serve()
	},
}

Functions

func ConfirmCommand

func ConfirmCommand(message string) bool

ConfirmCommand shows a y/N confirm prompt and returns true if the user enters y.

func RunCLI

func RunCLI()

func YesConfirmCommand

func YesConfirmCommand() bool

YesConfirmCommand shows type YES to continue prompt and returns true if the user types YES in capital letters.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL