parser.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  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. "encoding/xml"
  6. "fmt"
  7. "io"
  8. "miniflux.app/v2/internal/reader/encoding"
  9. )
  10. // parse reads an OPML file and returns a list of subscription.
  11. func parse(data io.Reader) ([]subcription, error) {
  12. opmlDocument := &opmlDocument{}
  13. decoder := xml.NewDecoder(data)
  14. decoder.Entity = xml.HTMLEntity
  15. decoder.Strict = false
  16. decoder.CharsetReader = encoding.CharsetReader
  17. err := decoder.Decode(opmlDocument)
  18. if err != nil {
  19. return nil, fmt.Errorf("opml: unable to parse document: %w", err)
  20. }
  21. return getSubscriptionsFromOutlines(opmlDocument.Outlines, ""), nil
  22. }
  23. func getSubscriptionsFromOutlines(outlines opmlOutlineCollection, category string) []subcription {
  24. subscriptions := make([]subcription, 0, len(outlines))
  25. for _, outline := range outlines {
  26. if outline.IsSubscription() {
  27. subscriptions = append(subscriptions, subcription{
  28. Title: outline.GetTitle(),
  29. FeedURL: outline.FeedURL,
  30. SiteURL: outline.GetSiteURL(),
  31. Description: outline.Description,
  32. CategoryName: category,
  33. })
  34. } else if outline.Outlines.HasChildren() {
  35. subscriptions = append(subscriptions, getSubscriptionsFromOutlines(outline.Outlines, outline.GetTitle())...)
  36. }
  37. }
  38. return subscriptions
  39. }