aboutsummaryrefslogtreecommitdiff
path: root/internal/reader/opml/opml.go
blob: c6caa9c92476de10c7aedc1586dd3eb0b9abaf53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package opml // import "miniflux.app/v2/internal/reader/opml"

import (
	"encoding/xml"
	"strings"
)

// Specs: http://opml.org/spec2.opml
type opmlDocument struct {
	XMLName  xml.Name              `xml:"opml"`
	Version  string                `xml:"version,attr"`
	Header   opmlHeader            `xml:"head"`
	Outlines opmlOutlineCollection `xml:"body>outline"`
}

func NewOPMLDocument() *opmlDocument {
	return &opmlDocument{}
}

type opmlHeader struct {
	Title       string `xml:"title,omitempty"`
	DateCreated string `xml:"dateCreated,omitempty"`
	OwnerName   string `xml:"ownerName,omitempty"`
}

type opmlOutline struct {
	Title       string                `xml:"title,attr,omitempty"`
	Text        string                `xml:"text,attr"`
	FeedURL     string                `xml:"xmlUrl,attr,omitempty"`
	SiteURL     string                `xml:"htmlUrl,attr,omitempty"`
	Description string                `xml:"description,attr,omitempty"`
	Outlines    opmlOutlineCollection `xml:"outline,omitempty"`
}

func (outline opmlOutline) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type opmlOutlineXml opmlOutline

	outlineType := ""
	if outline.IsSubscription() {
		outlineType = "rss"
	}

	return e.EncodeElement(struct {
		opmlOutlineXml
		Type string `xml:"type,attr,omitempty"`
	}{
		opmlOutlineXml: opmlOutlineXml(outline),
		Type:           outlineType,
	}, start)
}

func (o *opmlOutline) IsSubscription() bool {
	return strings.TrimSpace(o.FeedURL) != ""
}

func (o *opmlOutline) GetTitle() string {
	if o.Title != "" {
		return o.Title
	}

	if o.Text != "" {
		return o.Text
	}

	if o.SiteURL != "" {
		return o.SiteURL
	}

	if o.FeedURL != "" {
		return o.FeedURL
	}

	return ""
}

func (o *opmlOutline) GetSiteURL() string {
	if o.SiteURL != "" {
		return o.SiteURL
	}

	return o.FeedURL
}

type opmlOutlineCollection []opmlOutline

func (o opmlOutlineCollection) HasChildren() bool {
	return len(o) > 0
}