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.

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