gmantaos/Goirate

View on GitHub
src/series/episode.go

Summary

Maintainability
A
0 mins
Test Coverage
package series

import (
    "fmt"
    "regexp"
    "strconv"
    "strings"
    "time"
)

// Episode represents a unique episode of a series, identified by a
// pair of a season and episode number.
type Episode struct {
    Season  uint       `toml:"season" json:"season"`
    Episode uint       `toml:"episode" json:"episode"`
    Title   string     `toml:"title" json:"title"`
    Aired   *time.Time `toml:"aired" json:"aired"`
}

// ParseEpisodeString will extract the season and episode number from a string
// description, such as S03E07.
func ParseEpisodeString(episodeStr string) Episode {

    episode := Episode{Season: 1, Episode: 1}

    episodeStr = strings.ToLower(episodeStr)

    r, _ := regexp.Compile(`(?:\s*|\d*)(?:s|se|season)\s*(\d+)`)

    m := r.FindStringSubmatch(episodeStr)

    if len(m) > 0 {

        s, _ := strconv.Atoi(m[1])
        episode.Season = uint(s)
    }

    r, _ = regexp.Compile(`(?:\s+|\d+)(?:e|ep|episode)\s*(\d+)`)

    m = r.FindStringSubmatch(episodeStr)

    if len(m) > 0 {

        e, _ := strconv.Atoi(m[1])
        episode.Episode = uint(e)
    }

    return episode
}

// IsAfter returns true if this episode is sequentially after the given episode.
func (ep Episode) IsAfter(episode Episode) bool {

    return ep.Season > episode.Season ||
        (ep.Season == episode.Season && ep.Episode > episode.Episode)
}

// String returns the string SxxEyy representation of an episode.
func (ep Episode) String() string {

    return fmt.Sprintf("S%02dE%02d", ep.Season, ep.Episode)
}

// LongString returns the string Season xx Episode yy representation of an episode.
func (ep Episode) LongString() string {

    return fmt.Sprintf("Season %d, Episode %d", ep.Season, ep.Episode)
}

// HasAired returns true if the episode's airing date and time is prior to the current date and time.
func (ep Episode) HasAired() bool {

    return ep.Aired != nil && time.Since(*ep.Aired).Hours() >= 1
}