feedsResponse.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // SPDX-FileCopyrightText: Adam Evyčędo
  2. //
  3. // SPDX-License-Identifier: AGPL-3.0-or-later
  4. package api
  5. import (
  6. "apiote.xyz/p/szczanieckiej/traffic"
  7. "time"
  8. "golang.org/x/text/language"
  9. )
  10. type AcceptVersionError struct{}
  11. func (e AcceptVersionError) Error() string {
  12. return ""
  13. }
  14. var AcceptError AcceptVersionError
  15. func selectLanguage(descriptions, attributions map[string]string, preferredLanguages []language.Tag) (language.Tag, language.Tag) {
  16. descriptionTags := []language.Tag{}
  17. for t := range descriptions {
  18. descriptionTags = append(descriptionTags, language.MustParse(t)) // NOTE tag is internally stringified, must parse
  19. }
  20. attributionTags := []language.Tag{}
  21. for t := range attributions {
  22. attributionTags = append(attributionTags, language.MustParse(t)) // NOTE tag is internally stringified, must parse
  23. }
  24. matcher := language.NewMatcher(preferredLanguages)
  25. _, index, _ := matcher.Match(descriptionTags...)
  26. descriptionTag := preferredLanguages[index]
  27. _, index, _ = matcher.Match(attributionTags...)
  28. attributionTag := preferredLanguages[index]
  29. return descriptionTag, attributionTag
  30. }
  31. func selectLanguageByTag(messages map[language.Tag]string, preferredLanguages []language.Tag) language.Tag {
  32. tags := []language.Tag{}
  33. for t := range messages {
  34. tags = append(tags, t)
  35. }
  36. matcher := language.NewMatcher(preferredLanguages)
  37. _, index, _ := matcher.Match(tags...)
  38. return preferredLanguages[index]
  39. }
  40. func MakeFeedsResponse(feedInfos map[string]traffic.FeedInfo, lastUpdates map[string]time.Time, accept map[uint]struct{}, preferredLanguages []language.Tag) (FeedsResponse, error) {
  41. if _, ok := accept[0]; ok {
  42. response := FeedsResponseDev{
  43. Feeds: []FeedInfoV2{},
  44. }
  45. for id, feedInfo := range feedInfos {
  46. response.Feeds = append(response.Feeds, makeFeedInfoV2(id, feedInfo, lastUpdates[id], preferredLanguages))
  47. }
  48. return response, nil
  49. }
  50. if _, ok := accept[2]; ok {
  51. response := FeedsResponseV2{
  52. Feeds: []FeedInfoV2{},
  53. }
  54. for id, feedInfo := range feedInfos {
  55. response.Feeds = append(response.Feeds, makeFeedInfoV2(id, feedInfo, lastUpdates[id], preferredLanguages))
  56. }
  57. return response, nil
  58. }
  59. if _, ok := accept[1]; ok {
  60. response := FeedsResponseV1{
  61. Feeds: []FeedInfoV1{},
  62. }
  63. for id, feedInfo := range feedInfos {
  64. response.Feeds = append(response.Feeds, makeFeedInfoV1(id, feedInfo, lastUpdates[id], preferredLanguages))
  65. }
  66. return response, nil
  67. }
  68. return FeedsResponseDev{}, AcceptError
  69. }
  70. func makeFeedInfoV2(id string, feedInfo traffic.FeedInfo, lastUpdate time.Time, preferredLanguages []language.Tag) FeedInfoV2 {
  71. descriptionTag, attributionTag := selectLanguage(feedInfo.Descriptions, feedInfo.Attributions, preferredLanguages)
  72. return FeedInfoV2{
  73. Name: feedInfo.Name,
  74. Id: id,
  75. Attribution: feedInfo.Attributions[attributionTag.String()],
  76. Description: feedInfo.Descriptions[descriptionTag.String()],
  77. LastUpdate: lastUpdate.Format(traffic.DateFormat),
  78. QrHost: feedInfo.QrHost,
  79. QrIn: QRLocationV1(feedInfo.QrLocation),
  80. QrSelector: feedInfo.QrSelector,
  81. ValidSince: feedInfo.ValidSince,
  82. ValidTill: feedInfo.ValidTill,
  83. }
  84. }
  85. func makeFeedInfoV1(id string, feedInfo traffic.FeedInfo, lastUpdate time.Time, preferredLanguages []language.Tag) FeedInfoV1 {
  86. descriptionTag, attributionTag := selectLanguage(feedInfo.Descriptions, feedInfo.Attributions, preferredLanguages)
  87. return FeedInfoV1{
  88. Name: feedInfo.Name,
  89. Id: id,
  90. Attribution: feedInfo.Attributions[attributionTag.String()],
  91. Description: feedInfo.Descriptions[descriptionTag.String()],
  92. LastUpdate: lastUpdate.Format(traffic.DateTimeFormat),
  93. }
  94. }