package main import ( "embed" "fmt" "math/rand" "os" "os/exec" "os/user" "path" "strings" "git.tilde.town/tildetown/town/email" "github.com/charmbracelet/glamour" "github.com/charmbracelet/huh" "gopkg.in/yaml.v3" ) //go:embed banners/* var banners embed.FS //go:embed md/* var md embed.FS func banner() (string, error) { dirs, err := banners.ReadDir("banners") if err != nil { return "", err } mx := len(dirs) ix := rand.Intn(mx) content, err := banners.ReadFile(path.Join("banners", dirs[ix].Name())) if err != nil { return "", err } return string(content), nil } func info() error { infoContent, err := md.ReadFile("md/info.md") if err != nil { return err } out, err := glamour.Render(string(infoContent), "dracula") if err != nil { return err } cmd := exec.Command("/usr/bin/bat") cmd.Stdin = strings.NewReader(out) cmd.Stdout = os.Stdout return cmd.Run() } type physicalData struct { Arriving string Departing string Transportation bool Lodging bool Allergies string Couch bool } type rsvpData struct { Being string PhysicalData *physicalData `yaml:"PhysicalData,omitempty"` Freeform string } func sendRSVPEmail(rd rsvpData) error { bs, err := yaml.Marshal(rd) if err != nil { return err } return email.SendLocalEmail("vilmibm", "RSVP TOWNCON24", string(bs)) } func rsvp(o opts) error { var being string var arriving string var departing string var transportation bool lodging := true var allergies string couch := true var freeform string form := huh.NewForm( huh.NewGroup( huh.NewSelect[string]().Title("How will you be attending?"). Options( huh.NewOption("Digitally", "digital"), huh.NewOption("Phyiscally", "physical"), ).Value(&being)), // Physical attendee form huh.NewGroup( huh.NewInput().Title("When (day/time) are you arriving?"). Value(&arriving), huh.NewInput().Title("When (day/time) are you departing?"). Value(&departing), ).WithHideFunc(func() bool { return being != "physical" }), huh.NewGroup( huh.NewConfirm().Title("Will you be staying overnight at the venue?"). Value(&lodging), ).WithHideFunc(func() bool { return being != "physical" }), huh.NewGroup( huh.NewConfirm().Title("If the need arises are you ok sleeping on a couch?"). Value(&couch), ).WithHideFunc(func() bool { return being != "physical" && !lodging }), huh.NewGroup( huh.NewInput().Title("Do you have any food allergies I should be aware of?"). Value(&allergies), huh.NewConfirm().Title("Will you need any help getting to the venue?"). Description("I have a car and have some ability to help getting people to the venue"). Value(&transportation), ).WithHideFunc(func() bool { return being != "physical" }), // Catch all freeform huh.NewGroup( huh.NewText(). Title("Anything you want me to know? Any questions?"). Value(&freeform))) err := form.Run() if err != nil { return err } var pd *physicalData if being == "physical" { pd = &physicalData{ Arriving: arriving, Departing: departing, Transportation: transportation, Lodging: lodging, Allergies: allergies, Couch: couch, } } rd := rsvpData{ Being: being, Freeform: freeform, PhysicalData: pd} return sendRSVPEmail(rd) } type opts struct { Username string } func _main() error { b, err := banner() if err != nil { return err } fmt.Println(b) u, err := user.Current() if err != nil { return err } o := opts{ Username: u.Username, } fmt.Printf("\t\t^_^_^_^_^_^_^ hi ~%s ^_^_^_^_^_^_^\n", o.Username) fmt.Println() var mode string huh.NewSelect[string]().Title("whuddyu wanna doo?"). Options( huh.NewOption("Get an info dump", "info"), huh.NewOption("RSVP", "rsvp"), huh.NewOption("Submit a talk proposal or finished work", "submit"), huh.NewOption("Propose a creative jam", "jam"), huh.NewOption("Quit", "quit"), ).Value(&mode).Run() switch mode { case "info": return info() case "rsvp": return rsvp(o) case "submit": case "jam": case "quit": default: return fmt.Errorf("wtf '%s'", mode) } return nil } func main() { if err := _main(); err != nil { fmt.Fprintf(os.Stderr, ":( failed: %s\n", err.Error()) os.Exit(1) } }