serializer.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package opml // import "miniflux.app/v2/internal/reader/opml"
  4. import (
  5. "bufio"
  6. "bytes"
  7. "encoding/xml"
  8. "sort"
  9. "time"
  10. "miniflux.app/v2/internal/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. opmlDocument := convertSubscriptionsToOPML(subscriptions)
  18. encoder := xml.NewEncoder(writer)
  19. encoder.Indent("", " ")
  20. if err := encoder.Encode(opmlDocument); err != nil {
  21. logger.Error("[OPML:Serialize] %v", err)
  22. return ""
  23. }
  24. return b.String()
  25. }
  26. func convertSubscriptionsToOPML(subscriptions SubcriptionList) *opmlDocument {
  27. opmlDocument := NewOPMLDocument()
  28. opmlDocument.Version = "2.0"
  29. opmlDocument.Header.Title = "Miniflux"
  30. opmlDocument.Header.DateCreated = time.Now().Format("Mon, 02 Jan 2006 15:04:05 MST")
  31. groupedSubs := groupSubscriptionsByFeed(subscriptions)
  32. var categories []string
  33. for k := range groupedSubs {
  34. categories = append(categories, k)
  35. }
  36. sort.Strings(categories)
  37. for _, categoryName := range categories {
  38. category := opmlOutline{Text: categoryName}
  39. for _, subscription := range groupedSubs[categoryName] {
  40. category.Outlines = append(category.Outlines, opmlOutline{
  41. Title: subscription.Title,
  42. Text: subscription.Title,
  43. FeedURL: subscription.FeedURL,
  44. SiteURL: subscription.SiteURL,
  45. })
  46. }
  47. opmlDocument.Outlines = append(opmlDocument.Outlines, category)
  48. }
  49. return opmlDocument
  50. }
  51. func groupSubscriptionsByFeed(subscriptions SubcriptionList) map[string]SubcriptionList {
  52. groups := make(map[string]SubcriptionList)
  53. for _, subscription := range subscriptions {
  54. groups[subscription.CategoryName] = append(groups[subscription.CategoryName], subscription)
  55. }
  56. return groups
  57. }