forked from tildetown/town
433 lines
9.2 KiB
Go
433 lines
9.2 KiB
Go
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), "auto")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmd := exec.Command("/usr/bin/bat")
|
|
cmd.Stdin = strings.NewReader(out)
|
|
cmd.Stdout = os.Stdout
|
|
return cmd.Run()
|
|
}
|
|
|
|
func schedule() error {
|
|
scheduleContent, err := md.ReadFile("md/schedule.md")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
r, _ := glamour.NewTermRenderer(
|
|
// detect background color and pick either the default dark or light theme
|
|
glamour.WithAutoStyle(),
|
|
// wrap output at specific width (default is 80)
|
|
glamour.WithWordWrap(120),
|
|
)
|
|
out, err := r.Render(string(scheduleContent))
|
|
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 {
|
|
Username string
|
|
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))).WithTheme(huh.ThemeBase())
|
|
|
|
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{
|
|
Username: o.Username,
|
|
Being: being,
|
|
Freeform: freeform,
|
|
PhysicalData: pd}
|
|
|
|
if err = sendRSVPEmail(rd); err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println("THANK YOUUUU!U!U!UU!U!!!!~~~!~!~~!!!!!UUU")
|
|
|
|
return nil
|
|
}
|
|
|
|
type submitData struct {
|
|
Username string
|
|
Live bool
|
|
When string
|
|
Desc string
|
|
Length string
|
|
Interactive bool
|
|
Freeform string
|
|
}
|
|
|
|
func sendSubmitEmail(sd submitData) error {
|
|
bs, err := yaml.Marshal(sd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return email.SendLocalEmail("vilmibm", "SUBMISSION TOWNCON24", string(bs))
|
|
}
|
|
|
|
func submit(o opts) error {
|
|
submitContent, err := md.ReadFile("md/submit.md")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
out, err := glamour.Render(string(submitContent), "auto")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Println(out)
|
|
|
|
submitting := true
|
|
var live bool
|
|
var talkWhen string
|
|
var length string
|
|
var desc string
|
|
var freeform string
|
|
var interactive bool
|
|
|
|
notSubmitting := func() bool {
|
|
return !submitting
|
|
}
|
|
|
|
form := huh.NewForm(
|
|
huh.NewGroup(
|
|
huh.NewConfirm().Title("So...wanna submit a thing?").Value(&submitting),
|
|
),
|
|
huh.NewGroup(
|
|
huh.NewConfirm().Title("Excellent. Is it a live talk?").Value(&live),
|
|
).WithHideFunc(notSubmitting),
|
|
huh.NewGroup(
|
|
huh.NewInput().Title("During what time frame can you give the talk").
|
|
Description("please include relevant time zone information!").Value(&talkWhen),
|
|
).WithHideFunc(func() bool { return !live || !submitting }),
|
|
huh.NewGroup(
|
|
huh.NewText().Title("Please describe your submission").
|
|
Description("Include details like media format, topic, whether it's text or browser based.").Value(&desc),
|
|
).WithHideFunc(notSubmitting),
|
|
huh.NewGroup(
|
|
huh.NewInput().TitleFunc(func() string {
|
|
if live {
|
|
return "About how long is your talk?"
|
|
} else {
|
|
return "If your piece has a duration (eg audio/video), approximately what is it?"
|
|
}
|
|
}, &live).Value(&length),
|
|
).WithHideFunc(notSubmitting),
|
|
huh.NewGroup(
|
|
huh.NewConfirm().Title("Is your submission interactive?").
|
|
Description("for example a game or website").
|
|
Value(&interactive),
|
|
).WithHideFunc(func() bool { return !submitting || live }),
|
|
huh.NewGroup(
|
|
huh.NewText().Title("Anything else I should know?").Value(&freeform),
|
|
).WithHideFunc(notSubmitting),
|
|
).WithTheme(huh.ThemeBase())
|
|
|
|
if err := form.Run(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !submitting {
|
|
fmt.Println("ok! just run the command again if you change your mind~")
|
|
return nil
|
|
}
|
|
|
|
sd := submitData{
|
|
Username: o.Username,
|
|
Live: live,
|
|
When: talkWhen,
|
|
Length: length,
|
|
Desc: desc,
|
|
Freeform: freeform,
|
|
Interactive: interactive,
|
|
}
|
|
|
|
if err = sendSubmitEmail(sd); err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println("THANK YOU!! I'll be in touch~")
|
|
|
|
return nil
|
|
}
|
|
|
|
type jamData struct {
|
|
Username string
|
|
Desc string
|
|
Physical bool
|
|
}
|
|
|
|
func jam(o opts) error {
|
|
jamContent, err := md.ReadFile("md/jam.md")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
out, err := glamour.Render(string(jamContent), "auto")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Println(out)
|
|
|
|
submitting := true
|
|
var desc string
|
|
var physical bool
|
|
|
|
notSubmitting := func() bool {
|
|
return !submitting
|
|
}
|
|
|
|
form := huh.NewForm(
|
|
huh.NewGroup(
|
|
huh.NewConfirm().Title("So...wanna propose a jam?").Value(&submitting),
|
|
),
|
|
huh.NewGroup(
|
|
huh.NewConfirm().Title("Excellent. Does it require being in person?").Value(&physical),
|
|
).WithHideFunc(notSubmitting),
|
|
huh.NewGroup(
|
|
huh.NewText().Title("Describe the jam.").
|
|
Description("Include details like required knowledge or tools").Value(&desc),
|
|
).WithHideFunc(notSubmitting),
|
|
).WithTheme(huh.ThemeBase())
|
|
|
|
if err := form.Run(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !submitting {
|
|
fmt.Println("ok! just run the command again if you change your mind~")
|
|
return nil
|
|
}
|
|
|
|
jd := jamData{
|
|
Username: o.Username,
|
|
Desc: desc,
|
|
Physical: physical,
|
|
}
|
|
|
|
if err = sendJamEmail(jd); err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println("THANK YOU!! I'll be in touch~")
|
|
|
|
return nil
|
|
}
|
|
|
|
func sendJamEmail(jd jamData) error {
|
|
bs, err := yaml.Marshal(jd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return email.SendLocalEmail("vilmibm", "JAMPROP TOWNCON24", string(bs))
|
|
}
|
|
|
|
type opts struct {
|
|
Username string
|
|
}
|
|
|
|
func _main() error {
|
|
u, err := user.Current()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
o := opts{
|
|
Username: u.Username,
|
|
}
|
|
|
|
b, err := banner()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println(b)
|
|
|
|
fmt.Print(fmt.Sprintf("\t\t^_^_^_^_^_^_^ hi ~%s ^_^_^_^_^_^_^\n", o.Username))
|
|
fmt.Println()
|
|
|
|
var mode string
|
|
|
|
// NB: this could be a standalone prompt but when it is, ctrl+c behavior is goofed up.
|
|
form := huh.NewForm(
|
|
huh.NewGroup(
|
|
huh.NewSelect[string]().Title("whadduyu wanna doo?").
|
|
Options(
|
|
huh.NewOption("Get an info dump", "info"),
|
|
huh.NewOption("SEE SCHEDULE", "schedule"),
|
|
huh.NewOption("RSVP", "rsvp"),
|
|
huh.NewOption("Submit or propose a work (talk, art, etc)", "submit"),
|
|
huh.NewOption("Propose a creative jam", "jam"),
|
|
huh.NewOption("Quit", "quit"),
|
|
).Value(&mode))).WithTheme(huh.ThemeBase())
|
|
|
|
err = form.Run()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
switch mode {
|
|
case "info":
|
|
return info()
|
|
case "schedule":
|
|
return schedule()
|
|
case "rsvp":
|
|
return rsvp(o)
|
|
case "submit":
|
|
return submit(o)
|
|
case "jam":
|
|
return jam(o)
|
|
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)
|
|
}
|
|
}
|