Browse Source

fixes and extends #3 - Item.Duration rework (#4)

* fixes #3, removing override, adding clear documentation and changing api name
* adding Item.AddDuration, adding test coverage
* bumping version to 1.3.0
master
Eric Duncan 5 years ago committed by GitHub
parent
commit
b288862667
  1. 1
      .gitignore
  2. 10
      .travis.yml
  3. 58
      README.md
  4. 6
      doc.go
  5. 24
      enclosure.go
  6. 8
      example_test.go
  7. 20
      examples_test.go
  8. 12
      item.go
  9. 36
      item_test.go
  10. 5
      podcast.go

1
.gitignore vendored

@ -0,0 +1 @@
profile.out

10
.travis.yml

@ -1,7 +1,7 @@
language: go
go:
- 1.7
- 1.8
install:
- go get -v -t .
@ -13,5 +13,11 @@ script:
- go test -test.run Benchmark -cpu 1 -bench .
- goveralls -service travis-ci -repotoken $COVERALLS_TOKEN -coverprofile cover.out
branches:
only:
- gh-pages
- /.*/
notifications:
email: false
email: change

58
README.md

@ -40,6 +40,12 @@ RSS 2.0: <a href="https://cyber.harvard.edu/rss/rss.html">https://cyber.harvard.
Podcasts: <a href="https://help.apple.com/itc/podcasts_connect/#/itca5b22233">https://help.apple.com/itc/podcasts_connect/#/itca5b22233</a>
### Release Notes
1.3.0
* fixes Item.Duration being set incorrectly.
* changed Item.AddEnclosure() parameter definition (Bytes not Seconds!).
* added Item.AddDuration formatting and override.
* added more documentation surrounding Item.Enclosure{}
1.2.1
* added Podcast.AddSubTitle() and truncating to 64 chars.
* added a number of Guards to protect against empty fields.
@ -78,7 +84,8 @@ Podcasts: <a href="https://help.apple.com/itc/podcasts_connect/#/itca5b22233">ht
* [type ISummary](#ISummary)
* [type Image](#Image)
* [type Item](#Item)
* [func (i \*Item) AddEnclosure(url string, enclosureType EnclosureType, lengthInSeconds int64)](#Item.AddEnclosure)
* [func (i \*Item) AddDuration(durationInSeconds int64)](#Item.AddDuration)
* [func (i \*Item) AddEnclosure(url string, enclosureType EnclosureType, lengthInBytes int64)](#Item.AddEnclosure)
* [func (i \*Item) AddImage(url string)](#Item.AddImage)
* [func (i \*Item) AddPubDate(datetime \*time.Time)](#Item.AddPubDate)
* [func (i \*Item) AddSummary(summary string)](#Item.AddSummary)
@ -98,6 +105,7 @@ Podcasts: <a href="https://help.apple.com/itc/podcasts_connect/#/itca5b22233">ht
* [type TextInput](#TextInput)
#### <a name="pkg-examples">Examples</a>
* [Item.AddDuration](#example_Item_AddDuration)
* [Item.AddPubDate](#example_Item_AddPubDate)
* [New](#example_New)
* [Podcast.AddAuthor](#example_Podcast_AddAuthor)
@ -126,15 +134,27 @@ Author represents a named author and email.
For iTunes compliance, both Name and Email are required.
## <a name="Enclosure">type</a> [Enclosure](./enclosure.go#L46-L53)
## <a name="Enclosure">type</a> [Enclosure](./enclosure.go#L46-L65)
``` go
type Enclosure struct {
XMLName xml.Name `xml:"enclosure"`
URL string `xml:"url,attr"`
Length int64 `xml:"-"`
LengthFormatted string `xml:"length,attr"`
Type EnclosureType `xml:"-"`
TypeFormatted string `xml:"type,attr"`
XMLName xml.Name `xml:"enclosure"`
// URL is the downloadable url for the content. (Required)
URL string `xml:"url,attr"`
// Length is the size in Bytes of the download. (Required)
Length int64 `xml:"-"`
// LengthFormatted is the size in Bytes of the download. (Required)
//
// This field gets overwritten with the API when setting Length.
LengthFormatted string `xml:"length,attr"`
// Type is MIME type encoding of the download. (Required)
Type EnclosureType `xml:"-"`
// TypeFormatted is MIME type encoding of the download. (Required)
//
// This field gets overwritten with the API when setting Type.
TypeFormatted string `xml:"type,attr"`
}
```
Enclosure represents a download enclosure.
@ -268,10 +288,16 @@ Recommendations:
- Always set an Enclosure.Length, to be nice to your downloaders.
- Use Enclosure.Type instead of setting TypeFormatted for valid extensions.
### <a name="Item.AddDuration">func</a> (\*Item) [AddDuration](./item.go#L101)
``` go
func (i *Item) AddDuration(durationInSeconds int64)
```
AddDuration adds the duration to the iTunes duration field.
### <a name="Item.AddEnclosure">func</a> (\*Item) [AddEnclosure](./item.go#L52-L53)
``` go
func (i *Item) AddEnclosure(
url string, enclosureType EnclosureType, lengthInSeconds int64)
url string, enclosureType EnclosureType, lengthInBytes int64)
```
AddEnclosure adds the downloadable asset to the podcast Item.
@ -436,7 +462,7 @@ Recommendations:
<a href="https://help.apple.com/itc/podcasts_connect/#/itcb54353390">https://help.apple.com/itc/podcasts_connect/#/itcb54353390</a>
### <a name="Podcast.AddLastBuildDate">func</a> (\*Podcast) [AddLastBuildDate](./podcast.go#L250)
### <a name="Podcast.AddLastBuildDate">func</a> (\*Podcast) [AddLastBuildDate](./podcast.go#L247)
``` go
func (p *Podcast) AddLastBuildDate(datetime *time.Time)
```
@ -444,7 +470,7 @@ AddLastBuildDate adds the datetime as a parsed PubDate.
UTC time is used by default.
### <a name="Podcast.AddPubDate">func</a> (\*Podcast) [AddPubDate](./podcast.go#L243)
### <a name="Podcast.AddPubDate">func</a> (\*Podcast) [AddPubDate](./podcast.go#L240)
``` go
func (p *Podcast) AddPubDate(datetime *time.Time)
```
@ -452,7 +478,7 @@ AddPubDate adds the datetime as a parsed PubDate.
UTC time is used by default.
### <a name="Podcast.AddSubTitle">func</a> (\*Podcast) [AddSubTitle](./podcast.go#L259)
### <a name="Podcast.AddSubTitle">func</a> (\*Podcast) [AddSubTitle](./podcast.go#L256)
``` go
func (p *Podcast) AddSubTitle(subTitle string)
```
@ -462,7 +488,7 @@ in iTunes.
Note that this field should be just a few words long according to Apple.
This method will truncate the string to 64 chars if too long with "..."
### <a name="Podcast.AddSummary">func</a> (\*Podcast) [AddSummary](./podcast.go#L276)
### <a name="Podcast.AddSummary">func</a> (\*Podcast) [AddSummary](./podcast.go#L273)
``` go
func (p *Podcast) AddSummary(summary string)
```
@ -473,19 +499,19 @@ Limit: 4000 characters
Note that this field is a CDATA encoded field which allows for rich text
such as html links: <a href="<a href="http://www.apple.com">http://www.apple.com</a>">Apple</a>.
### <a name="Podcast.Bytes">func</a> (\*Podcast) [Bytes](./podcast.go#L290)
### <a name="Podcast.Bytes">func</a> (\*Podcast) [Bytes](./podcast.go#L287)
``` go
func (p *Podcast) Bytes() []byte
```
Bytes returns an encoded []byte slice.
### <a name="Podcast.Encode">func</a> (\*Podcast) [Encode](./podcast.go#L295)
### <a name="Podcast.Encode">func</a> (\*Podcast) [Encode](./podcast.go#L292)
``` go
func (p *Podcast) Encode(w io.Writer) error
```
Encode writes the bytes to the io.Writer stream in RSS 2.0 specification.
### <a name="Podcast.String">func</a> (\*Podcast) [String](./podcast.go#L306)
### <a name="Podcast.String">func</a> (\*Podcast) [String](./podcast.go#L303)
``` go
func (p *Podcast) String() string
```

6
doc.go

@ -37,6 +37,12 @@
//
// Release Notes
//
// 1.3.0
// * fixes Item.Duration being set incorrectly.
// * changed Item.AddEnclosure() parameter definition (Bytes not Seconds!).
// * added Item.AddDuration formatting and override.
// * added more documentation surrounding Item.Enclosure{}
//
// 1.2.1
// * added Podcast.AddSubTitle() and truncating to 64 chars.
// * added a number of Guards to protect against empty fields.

24
enclosure.go

@ -44,10 +44,22 @@ func (et EnclosureType) String() string {
// Enclosure represents a download enclosure.
type Enclosure struct {
XMLName xml.Name `xml:"enclosure"`
URL string `xml:"url,attr"`
Length int64 `xml:"-"`
LengthFormatted string `xml:"length,attr"`
Type EnclosureType `xml:"-"`
TypeFormatted string `xml:"type,attr"`
XMLName xml.Name `xml:"enclosure"`
// URL is the downloadable url for the content. (Required)
URL string `xml:"url,attr"`
// Length is the size in Bytes of the download. (Required)
Length int64 `xml:"-"`
// LengthFormatted is the size in Bytes of the download. (Required)
//
// This field gets overwritten with the API when setting Length.
LengthFormatted string `xml:"length,attr"`
// Type is MIME type encoding of the download. (Required)
Type EnclosureType `xml:"-"`
// TypeFormatted is MIME type encoding of the download. (Required)
//
// This field gets overwritten with the API when setting Type.
TypeFormatted string `xml:"type,attr"`
}

8
example_test.go

@ -76,7 +76,7 @@ func Example_httpHandlers() {
// <title>eduncan911 Podcasts</title>
// <link>http://eduncan911.com/</link>
// <description>An example Podcast</description>
// <generator>go podcast v1.2.1 (github.com/eduncan911/podcast)</generator>
// <generator>go podcast v1.3.0 (github.com/eduncan911/podcast)</generator>
// <language>en-us</language>
// <lastBuildDate>Mon, 06 Feb 2017 08:21:52 +0000</lastBuildDate>
// <managingEditor>me@janedoe.com (Jane Doe)</managingEditor>
@ -97,7 +97,6 @@ func Example_httpHandlers() {
// <itunes:author>me@janedoe.com (Jane Doe)</itunes:author>
// <itunes:summary><![CDATA[item <a href="http://example.com">example.com</a>]]></itunes:summary>
// <itunes:image href="http://example.com/episode-1.png"></itunes:image>
// <itunes:duration>110</itunes:duration>
// </item>
// <item>
// <guid>http://e.com/2.mp3</guid>
@ -109,7 +108,6 @@ func Example_httpHandlers() {
// <itunes:author>me@janedoe.com (Jane Doe)</itunes:author>
// <itunes:summary><![CDATA[item <a href="http://example.com">example.com</a>]]></itunes:summary>
// <itunes:image href="http://example.com/episode-2.png"></itunes:image>
// <itunes:duration>165</itunes:duration>
// </item>
// </channel>
// </rss>
@ -165,7 +163,7 @@ func Example_ioWriter() {
// <title>Sample Podcasts</title>
// <link>http://example.com/</link>
// <description>An example Podcast</description>
// <generator>go podcast v1.2.1 (github.com/eduncan911/podcast)</generator>
// <generator>go podcast v1.3.0 (github.com/eduncan911/podcast)</generator>
// <language>en-us</language>
// <lastBuildDate>Mon, 06 Feb 2017 08:21:52 +0000</lastBuildDate>
// <managingEditor>jane.doe@example.com (Jane Doe)</managingEditor>
@ -188,7 +186,6 @@ func Example_ioWriter() {
// <itunes:subtitle>A simple episode 9</itunes:subtitle>
// <itunes:summary><![CDATA[item k <a href="http://example.com">example.com</a>]]></itunes:summary>
// <itunes:image href="http://example.com/episode-9.png"></itunes:image>
// <itunes:duration>550</itunes:duration>
// </item>
// <item>
// <guid>http://example.com/10.mp3</guid>
@ -201,7 +198,6 @@ func Example_ioWriter() {
// <itunes:subtitle>A simple episode 10</itunes:subtitle>
// <itunes:summary><![CDATA[item k <a href="http://example.com">example.com</a>]]></itunes:summary>
// <itunes:image href="http://example.com/episode-10.png"></itunes:image>
// <itunes:duration>605</itunes:duration>
// </item>
// </channel>
// </rss>

20
examples_test.go

@ -100,7 +100,7 @@ func ExamplePodcast_AddItem() {
pp.IAuthor, pp.IDuration, pp.IExplicit, pp.IIsClosedCaptioned,
pp.IOrder, pp.ISubtitle, pp.ISummary)
// Output:
// http://example.com/1.mp3 Episode 1 http://example.com/1.mp3 Description for Episode 1 &{{ } me@test.com (the name)} 2017-04-22 08:21:52 +0000 UTC Sat, 22 Apr 2017 08:21:52 +0000 {{ } http://example.com/1.mp3 183 183 audio/mpeg audio/mpeg} me@test.com (the name) 183 A simple episode 1 &{{ } See more at <a href="http://example.com">Here</a>}
// http://example.com/1.mp3 Episode 1 http://example.com/1.mp3 Description for Episode 1 &{{ } me@test.com (the name)} 2017-04-22 08:21:52 +0000 UTC Sat, 22 Apr 2017 08:21:52 +0000 {{ } http://example.com/1.mp3 183 183 audio/mpeg audio/mpeg} me@test.com (the name) A simple episode 1 &{{ } See more at <a href="http://example.com">Here</a>}
}
func ExamplePodcast_AddLastBuildDate() {
@ -183,7 +183,7 @@ See more at our website: <a href="http://example.com">example.com</a>
// <title>eduncan911 Podcasts</title>
// <link>http://eduncan911.com/</link>
// <description>An example Podcast</description>
// <generator>go podcast v1.2.1 (github.com/eduncan911/podcast)</generator>
// <generator>go podcast v1.3.0 (github.com/eduncan911/podcast)</generator>
// <language>en-us</language>
// <lastBuildDate>Mon, 06 Feb 2017 08:21:52 +0000</lastBuildDate>
// <managingEditor>me@janedoe.com (Jane Doe)</managingEditor>
@ -240,3 +240,19 @@ func ExampleItem_AddPubDate() {
// Tue, 24 Jan 2017 08:21:52 +0000 2017-01-24 08:21:52 +0000 UTC
// Tue, 24 Jan 2017 08:21:52 +0000 2017-01-24 08:21:52 +0000 UTC
}
func ExampleItem_AddDuration() {
i := podcast.Item{
Title: "item title",
Description: "item desc",
Link: "item link",
}
d := int64(533)
// add the Duration in Seconds
i.AddDuration(d)
fmt.Println(i.IDuration)
// Output:
// 533
}

12
item.go

@ -50,11 +50,11 @@ type Item struct {
// AddEnclosure adds the downloadable asset to the podcast Item.
func (i *Item) AddEnclosure(
url string, enclosureType EnclosureType, lengthInSeconds int64) {
url string, enclosureType EnclosureType, lengthInBytes int64) {
i.Enclosure = &Enclosure{
URL: url,
Type: enclosureType,
Length: lengthInSeconds,
Length: lengthInBytes,
}
}
@ -96,3 +96,11 @@ func (i *Item) AddSummary(summary string) {
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)
}

36
item_test.go

@ -47,3 +47,39 @@ func TestItemAddImageEmptyUrl(t *testing.T) {
// assert
assert.Nil(t, i.IImage)
}
func TestItemAddDurationZero(t *testing.T) {
t.Parallel()
// arrange
i := podcast.Item{
Title: "item.title",
Description: "item.desc",
Link: "http://example.com/article.html",
}
d := int64(0)
// act
i.AddDuration(d)
// assert
assert.EqualValues(t, "", i.IDuration)
}
func TestItemAddDurationLessThanZero(t *testing.T) {
t.Parallel()
// arrange
i := podcast.Item{
Title: "item.title",
Description: "item.desc",
Link: "http://example.com/article.html",
}
d := int64(-13)
// act
i.AddDuration(d)
// assert
assert.EqualValues(t, "", i.IDuration)
}

5
podcast.go

@ -12,7 +12,7 @@ import (
)
const (
pVersion = "1.2.1"
pVersion = "1.3.0"
)
// Podcast represents a podcast.
@ -229,9 +229,6 @@ func (p *Podcast) AddItem(i Item) (int, error) {
i.IImage = &IImage{HREF: p.Image.URL}
}
}
if i.Enclosure != nil {
i.IDuration = parseDuration(i.Enclosure.Length)
}
p.Items = append(p.Items, &i)
return len(p.Items), nil

Loading…
Cancel
Save