serializer.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. "time"
  11. "miniflux.app/logger"
  12. )
  13. // Serialize returns a SubcriptionList in OPML format.
  14. func Serialize(subscriptions SubcriptionList) string {
  15. var b bytes.Buffer
  16. writer := bufio.NewWriter(&b)
  17. writer.WriteString(xml.Header)
  18. opmlDocument := convertSubscriptionsToOPML(subscriptions)
  19. encoder := xml.NewEncoder(writer)
  20. encoder.Indent("", " ")
  21. if err := encoder.Encode(opmlDocument); err != nil {
  22. logger.Error("[OPML:Serialize] %v", err)
  23. return ""
  24. }
  25. return b.String()
  26. }
  27. func convertSubscriptionsToOPML(subscriptions SubcriptionList) *opmlDocument {
  28. opmlDocument := NewOPMLDocument()
  29. opmlDocument.Version = "2.0"
  30. opmlDocument.Header.Title = "Miniflux"
  31. opmlDocument.Header.DateCreated = time.Now().Format("Mon, 02 Jan 2006 15:04:05 MST")
  32. groupedSubs := groupSubscriptionsByFeed(subscriptions)
  33. var categories []string
  34. for k := range groupedSubs {
  35. categories = append(categories, k)
  36. }
  37. sort.Strings(categories)
  38. for _, categoryName := range categories {
  39. category := opmlOutline{Text: categoryName}
  40. for _, subscription := range groupedSubs[categoryName] {
  41. category.Outlines = append(category.Outlines, opmlOutline{
  42. Title: subscription.Title,
  43. Text: subscription.Title,
  44. FeedURL: subscription.FeedURL,
  45. SiteURL: subscription.SiteURL,
  46. })
  47. }
  48. opmlDocument.Outlines = append(opmlDocument.Outlines, category)
  49. }
  50. return opmlDocument
  51. }
  52. func groupSubscriptionsByFeed(subscriptions SubcriptionList) map[string]SubcriptionList {
  53. groups := make(map[string]SubcriptionList)
  54. for _, subscription := range subscriptions {
  55. groups[subscription.CategoryName] = append(groups[subscription.CategoryName], subscription)
  56. }
  57. return groups
  58. }