Speiseplan der Mensen der Georg-August-Universität Göttingen https://mensa.schneider-hosting.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.7 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "regexp"
  8. "strings"
  9. "time"
  10. "github.com/PuerkitoBio/goquery"
  11. )
  12. type (
  13. // Meal contains the info about a meals
  14. Meal struct {
  15. Category string `json:"category"`
  16. Price string `json:"price"`
  17. Title string `json:"title"`
  18. Diet string `json:"diet"`
  19. }
  20. // Menu contains all info to menues in a mensa on one day
  21. Menu struct {
  22. Day int `json:"day"`
  23. Mensa string `json:"mensa"`
  24. Meals []Meal `json:"meals"`
  25. Date string `json:"date"`
  26. }
  27. )
  28. var (
  29. mensen = map[string]string{
  30. "Zentralmensa": "zentralmensa",
  31. "Nordmensa": "nordmensa",
  32. "Mensa+am+Turm": "turmmensa",
  33. "Mensa+Italia": "mensaitalia",
  34. "Bistro+HAWK": "bistrohawk",
  35. }
  36. trimRegex = regexp.MustCompile(`\s{2,}`)
  37. )
  38. func main() {
  39. path := "./"
  40. if len(os.Args) == 2 {
  41. path = os.Args[1] + "/"
  42. }
  43. for mensa := range mensen {
  44. for day := 1; day < 8; day = day + 1 {
  45. menu, err := operate(mensa, day)
  46. if err != nil {
  47. fmt.Println(err.Error())
  48. return
  49. }
  50. content, err := json.Marshal(menu)
  51. if err != nil {
  52. fmt.Println(err.Error())
  53. return
  54. }
  55. err = ioutil.WriteFile(fmt.Sprintf("%s/%s.%v.json", path, mensen[mensa], day), content, 0644)
  56. if err != nil {
  57. fmt.Println(err.Error())
  58. return
  59. }
  60. }
  61. }
  62. }
  63. func writeToFile(content []byte) error {
  64. err := ioutil.WriteFile(os.Args[1], content, 0644)
  65. if err != nil {
  66. return err
  67. }
  68. return nil
  69. }
  70. func operate(mensa string, day int) (Menu, error) {
  71. currentDay := int(time.Now().Weekday()) // week starts on sunday in go, but thats not relevant, because the canteen is closed on sunday
  72. push := 0
  73. if currentDay > day {
  74. push = 1
  75. }
  76. document, err := goquery.NewDocument(fmt.Sprintf("http://www.studentenwerk-goettingen.de/speiseplan.html?no_cache=1&day=%v&push=%v&selectmensa=%s", day, push, mensa))
  77. if err != nil {
  78. return Menu{}, err
  79. }
  80. meals, err := parseMeals(document)
  81. if err != nil {
  82. return Menu{}, err
  83. }
  84. date := parseDate(document)
  85. return Menu{Day: day, Mensa: mensa, Meals: meals, Date: date}, nil
  86. }
  87. func parseDate(doc *goquery.Document) string {
  88. return strip(doc.Find("#speise-head2_datum").Text())
  89. }
  90. func strip(old string) string {
  91. return strings.TrimSpace(trimRegex.ReplaceAllString(old, " "))
  92. }
  93. func parseMeals(doc *goquery.Document) ([]Meal, error) {
  94. meals := []Meal{}
  95. doc.Find("table.speise-tblmain tbody tr").Each(func(i int, s *goquery.Selection) {
  96. diet, _ := s.Find(".ext_sits_speiseplan_icon").Children().Attr("alt")
  97. meal := Meal{
  98. Category: strip(s.Find(".ext_sits_preis").Text()), // yes, really preis
  99. Title: strip(s.Find(".ext_sits_essen").Text()),
  100. Diet: strip(diet),
  101. }
  102. meals = append(meals, meal)
  103. })
  104. return meals, nil
  105. }