-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
item.go
144 lines (128 loc) · 3.9 KB
/
item.go
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package podcast
import (
"encoding/xml"
"fmt"
"time"
"unicode/utf8"
)
// Item represents a single entry in a podcast.
//
// Article minimal requirements are:
// - Title
// - Description
// - Link
//
// Audio minimal requirements are:
// - Title
// - Description
// - Enclosure (HREF, Type and Length all required)
//
// Recommendations:
// - Setting the minimal fields sets most of other fields, including iTunes.
// - Use the Published time.Time setting instead of PubDate.
// - Always set an Enclosure.Length, to be nice to your downloaders.
// - Use Enclosure.Type instead of setting TypeFormatted for valid extensions.
type Item struct {
XMLName xml.Name `xml:"item"`
GUID string `xml:"guid"`
Title string `xml:"title"`
Link string `xml:"link"`
Description string `xml:"description"`
Author *Author `xml:"-"`
AuthorFormatted string `xml:"author,omitempty"`
Category string `xml:"category,omitempty"`
Comments string `xml:"comments,omitempty"`
Source string `xml:"source,omitempty"`
PubDate *time.Time `xml:"-"`
PubDateFormatted string `xml:"pubDate,omitempty"`
Enclosure *Enclosure
// https://help.apple.com/itc/podcasts_connect/#/itcb54353390
IAuthor string `xml:"itunes:author,omitempty"`
ISubtitle string `xml:"itunes:subtitle,omitempty"`
ISummary *ISummary
IImage *IImage
IDuration string `xml:"itunes:duration,omitempty"`
IExplicit string `xml:"itunes:explicit,omitempty"`
IIsClosedCaptioned string `xml:"itunes:isClosedCaptioned,omitempty"`
IOrder string `xml:"itunes:order,omitempty"`
}
// AddEnclosure adds the downloadable asset to the podcast Item.
func (i *Item) AddEnclosure(
url string, enclosureType EnclosureType, lengthInBytes int64) {
i.Enclosure = &Enclosure{
URL: url,
Type: enclosureType,
Length: lengthInBytes,
}
}
// AddImage adds the image as an iTunes-only IImage. RSS 2.0 does not have
// the specification of Images at the Item level.
//
// Podcast feeds contain artwork that is a minimum size of
// 1400 x 1400 pixels and a maximum size of 3000 x 3000 pixels,
// 72 dpi, in JPEG or PNG format with appropriate file
// extensions (.jpg, .png), and in the RGB colorspace. To optimize
// images for mobile devices, Apple recommends compressing your
// image files.
func (i *Item) AddImage(url string) {
if len(url) > 0 {
i.IImage = &IImage{HREF: url}
}
}
// AddPubDate adds the datetime as a parsed PubDate.
//
// UTC time is used by default.
func (i *Item) AddPubDate(datetime *time.Time) {
i.PubDate = datetime
i.PubDateFormatted = parseDateRFC1123Z(i.PubDate)
}
// AddSummary adds the iTunes summary.
//
// Limit: 4000 characters
//
// Note that this field is a CDATA encoded field which allows for rich text
// such as html links: `<a href="http://www.apple.com">Apple</a>`.
func (i *Item) AddSummary(summary string) {
count := utf8.RuneCountInString(summary)
if count > 4000 {
s := []rune(summary)
summary = string(s[0:4000])
}
i.ISummary = &ISummary{
Text: summary,
}
}
// AddDuration adds the duration to the iTunes duration field.
func (i *Item) AddDuration(durationInSeconds int64) {
if durationInSeconds <= 0 {
return
}
i.IDuration = parseDuration(durationInSeconds)
}
var parseDuration = func(duration int64) string {
h := duration / 3600
duration = duration % 3600
m := duration / 60
duration = duration % 60
s := duration
// HH:MM:SS
if h > 9 {
return fmt.Sprintf("%02d:%02d:%02d", h, m, s)
}
// H:MM:SS
if h > 0 {
return fmt.Sprintf("%d:%02d:%02d", h, m, s)
}
// MM:SS
if m > 9 {
return fmt.Sprintf("%02d:%02d", m, s)
}
// M:SS
return fmt.Sprintf("%d:%02d", m, s)
}
var parseDateRFC1123Z = func(t *time.Time) string {
if t != nil && !t.IsZero() {
return t.Format(time.RFC1123Z)
}
return time.Now().UTC().Format(time.RFC1123Z)
}