serializer.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Copyright 2017 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package opml // import "miniflux.app/reader/opml"
  5. import (
  6. "bufio"
  7. "bytes"
  8. "encoding/xml"
  9. "sort"
  10. "miniflux.app/logger"
  11. )
  12. // Serialize returns a SubcriptionList in OPML format.
  13. func Serialize(subscriptions SubcriptionList) string {
  14. var b bytes.Buffer
  15. writer := bufio.NewWriter(&b)
  16. writer.WriteString(xml.Header)
  17. feeds := normalizeFeeds(subscriptions)
  18. encoder := xml.NewEncoder(writer)
  19. encoder.Indent(" ", " ")
  20. if err := encoder.Encode(feeds); err != nil {
  21. logger.Error("[OPML:Serialize] %v", err)
  22. return ""
  23. }
  24. return b.String()
  25. }
  26. func groupSubscriptionsByFeed(subscriptions SubcriptionList) map[string]SubcriptionList {
  27. groups := make(map[string]SubcriptionList)
  28. for _, subscription := range subscriptions {
  29. groups[subscription.CategoryName] = append(groups[subscription.CategoryName], subscription)
  30. }
  31. return groups
  32. }
  33. func normalizeFeeds(subscriptions SubcriptionList) *opml {
  34. feeds := new(opml)
  35. feeds.Version = "2.0"
  36. groupedSubs := groupSubscriptionsByFeed(subscriptions)
  37. var categories []string
  38. for k := range groupedSubs {
  39. categories = append(categories, k)
  40. }
  41. sort.Strings(categories)
  42. for _, categoryName := range categories {
  43. category := outline{Text: categoryName}
  44. for _, subscription := range groupedSubs[categoryName] {
  45. category.Outlines = append(category.Outlines, outline{
  46. Title: subscription.Title,
  47. Text: subscription.Title,
  48. FeedURL: subscription.FeedURL,
  49. SiteURL: subscription.SiteURL,
  50. })
  51. }
  52. feeds.Outlines = append(feeds.Outlines, category)
  53. }
  54. return feeds
  55. }