visit/main.go

144 lines
2.6 KiB
Go
Raw Permalink Normal View History

2020-10-27 05:04:45 +00:00
package main
import (
"encoding/json"
"fmt"
2020-10-27 05:45:20 +00:00
"io/ioutil"
2020-10-27 05:04:45 +00:00
"math/rand"
"os"
"os/exec"
2020-10-27 05:45:20 +00:00
"path/filepath"
2020-10-27 17:27:59 +00:00
"strings"
2020-10-27 05:04:45 +00:00
"time"
"github.com/AlecAivazis/survey/v2"
2020-10-27 05:45:20 +00:00
"github.com/charmbracelet/glamour"
2020-10-27 05:04:45 +00:00
)
func main() {
var err error
if len(os.Args) > 2 {
fmt.Println("expected zero or one arguments")
}
if len(os.Args) > 1 {
arg := os.Args[1]
switch arg {
case "-r", "--random":
err = visitRandomUser()
default:
2020-10-27 05:10:37 +00:00
err = visitUsername(os.Args[1])
2020-10-27 05:04:45 +00:00
}
} else {
err = visitPrompt()
}
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
}
func visitRandomUser() error {
rand.Seed(time.Now().UnixNano())
usernames, err := getUsernames()
if err != nil {
return err
}
2020-10-27 05:10:37 +00:00
return visitUser(usernames[rand.Intn(len(usernames))])
2020-10-27 05:04:45 +00:00
}
2020-10-27 05:10:37 +00:00
func visitUsername(username string) error {
2020-10-27 05:04:45 +00:00
usernames, err := getUsernames()
if err != nil {
return err
}
for _, name := range usernames {
if name == username {
2020-10-27 05:10:37 +00:00
return visitUser(username)
2020-10-27 05:04:45 +00:00
}
}
return fmt.Errorf("no such user: %s", username)
}
func visitPrompt() error {
usernames, err := getUsernames()
if err != nil {
return err
}
username := ""
prompt := &survey.Select{
Message: "Choose a townie to visit!",
Options: usernames,
}
survey.AskOne(prompt, &username)
2020-10-27 05:10:37 +00:00
return visitUser(username)
}
2020-10-27 05:04:45 +00:00
2020-10-27 05:10:37 +00:00
func visitUser(username string) error {
2020-10-27 05:45:20 +00:00
files, err := ioutil.ReadDir(filepath.Join("/home", username))
if err != nil {
2020-10-27 17:27:59 +00:00
return fmt.Errorf("user is not accepting visitors (could not read user's home directory: %w)", err)
2020-10-27 05:45:20 +00:00
}
2020-10-27 17:27:59 +00:00
for _, file := range files {
if !isReadme(file.Name()) {
continue
}
path := filepath.Join("/home", username, file.Name())
data, err := ioutil.ReadFile(path)
if err != nil {
break
}
2020-10-27 05:45:20 +00:00
2020-10-27 17:27:59 +00:00
if isMarkdown(file.Name()) {
r, _ := glamour.NewTermRenderer(glamour.WithAutoStyle())
out, err := r.RenderBytes(data)
if err == nil {
fmt.Println(string(out))
return nil
2020-10-27 05:45:20 +00:00
}
}
2020-10-27 17:27:59 +00:00
fmt.Println(string(data))
return nil
2020-10-27 05:45:20 +00:00
}
2020-10-27 17:38:11 +00:00
// TODO handle .plan and .project files
2020-10-27 05:45:20 +00:00
fmt.Println("TODO non-readme fallback")
2020-10-27 05:04:45 +00:00
return nil
}
2020-10-27 05:45:20 +00:00
func isReadme(filename string) bool {
fn := strings.ToLower(filename)
2020-10-27 17:27:59 +00:00
return strings.HasPrefix(fn, "readme") || strings.HasPrefix(fn, "welcome")
2020-10-27 05:45:20 +00:00
}
func isMarkdown(filename string) bool {
fn := strings.ToLower(filename)
return strings.HasSuffix(fn, ".md") || strings.HasSuffix(fn, ".markdown")
}
2020-10-27 05:04:45 +00:00
func getUsernames() ([]string, error) {
cmd := exec.Command("/bin/bash", "-c", "town stats | jq -r '.users|map(.username)'")
output, err := cmd.Output()
if err != nil {
return nil, err
}
usernames := []string{}
err = json.Unmarshal(output, &usernames)
if err != nil {
return nil, err
}
return usernames, nil
}