simple program for visiting other townies' home directories
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

131 lignes
2.4 KiB

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "math/rand"
  7. "os"
  8. "os/exec"
  9. "path/filepath"
  10. "time"
  11. "github.com/AlecAivazis/survey/v2"
  12. "github.com/charmbracelet/glamour"
  13. )
  14. func main() {
  15. var err error
  16. if len(os.Args) > 2 {
  17. fmt.Println("expected zero or one arguments")
  18. }
  19. if len(os.Args) > 1 {
  20. arg := os.Args[1]
  21. switch arg {
  22. case "-r", "--random":
  23. err = visitRandomUser()
  24. default:
  25. err = visitUsername(os.Args[1])
  26. }
  27. } else {
  28. err = visitPrompt()
  29. }
  30. if err != nil {
  31. fmt.Fprintf(os.Stderr, "%s\n", err)
  32. os.Exit(1)
  33. }
  34. }
  35. func visitRandomUser() error {
  36. rand.Seed(time.Now().UnixNano())
  37. usernames, err := getUsernames()
  38. if err != nil {
  39. return err
  40. }
  41. return visitUser(usernames[rand.Intn(len(usernames))])
  42. }
  43. func visitUsername(username string) error {
  44. usernames, err := getUsernames()
  45. if err != nil {
  46. return err
  47. }
  48. for _, name := range usernames {
  49. if name == username {
  50. return visitUser(username)
  51. }
  52. }
  53. return fmt.Errorf("no such user: %s", username)
  54. }
  55. func visitPrompt() error {
  56. usernames, err := getUsernames()
  57. if err != nil {
  58. return err
  59. }
  60. username := ""
  61. prompt := &survey.Select{
  62. Message: "Choose a townie to visit!",
  63. Options: usernames,
  64. }
  65. survey.AskOne(prompt, &username)
  66. return visitUser(username)
  67. }
  68. func visitUser(username string) error {
  69. files, err := ioutil.ReadDir(filepath.Join("/home", username))
  70. if err != nil {
  71. return fmt.Errorf("could not read user's home directory: %w", err)
  72. }
  73. for _, filename := range files {
  74. fmt.Println("DEBUG", filename)
  75. if isReadme(filename) {
  76. if isMarkdown(filename) {
  77. // TODO fill in once i know if filename is abs or rel path
  78. /*
  79. r, _ := glamour.NewTermRenderer(glamour.WithAutoStyle())
  80. out, err := r.Render()
  81. */
  82. }
  83. fmt.Println("TODO print raw file")
  84. return nil
  85. }
  86. }
  87. fmt.Println("TODO non-readme fallback")
  88. return nil
  89. }
  90. func isReadme(filename string) bool {
  91. fn := strings.ToLower(filename)
  92. return strings.HasPrefix(fn, "readme")
  93. }
  94. func isMarkdown(filename string) bool {
  95. fn := strings.ToLower(filename)
  96. return strings.HasSuffix(fn, ".md") || strings.HasSuffix(fn, ".markdown")
  97. }
  98. func getUsernames() ([]string, error) {
  99. cmd := exec.Command("/bin/bash", "-c", "town stats | jq -r '.users|map(.username)'")
  100. output, err := cmd.Output()
  101. if err != nil {
  102. return nil, err
  103. }
  104. usernames := []string{}
  105. err = json.Unmarshal(output, &usernames)
  106. if err != nil {
  107. return nil, err
  108. }
  109. return usernames, nil
  110. }