diff --git a/crunchyroll.go b/crunchyroll.go index 3d5adf4..8c402d6 100644 --- a/crunchyroll.go +++ b/crunchyroll.go @@ -51,6 +51,9 @@ type Crunchyroll struct { ExternalID string MaturityRating string } + + // If cache is true, internal caching is enabled + cache bool } // LoginWithCredentials logs in via crunchyroll email and password @@ -86,6 +89,7 @@ func LoginWithSessionID(sessionID string, locale LOCALE, client *http.Client) (* Client: client, Locale: locale, SessionID: sessionID, + cache: true, } var endpoint string var err error @@ -231,6 +235,20 @@ func (c *Crunchyroll) request(endpoint string) (*http.Response, error) { return resp, err } +// IsCaching returns if data gets cached or not. +// See SetCaching for more information +func (c *Crunchyroll) IsCaching() bool { + return c.cache +} + +// SetCaching enables or disables internal caching of requests made. +// Caching is enabled by default. +// If it is disabled the already cached data still gets called. +// The best way to prevent this is to create a complete new Crunchyroll struct +func (c *Crunchyroll) SetCaching(caching bool) { + c.cache = caching +} + // Search searches a query and returns all found series and movies within the given limit func (c *Crunchyroll) Search(query string, limit uint) (s []*Series, m []*Movie, err error) { searchEndpoint := fmt.Sprintf("https://beta-api.crunchyroll.com/content/v1/search?q=%s&n=%d&type=&locale=%s", diff --git a/episode.go b/episode.go index 712f8cb..36a8c34 100644 --- a/episode.go +++ b/episode.go @@ -10,6 +10,8 @@ import ( type Episode struct { crunchy *Crunchyroll + children []*Stream + siteCache map[string]interface{} ID string `json:"id"` @@ -134,7 +136,11 @@ func (e *Episode) AudioLocale() (LOCALE, error) { // Streams returns all streams which are available for the episode func (e *Episode) Streams() ([]*Stream, error) { - return fromVideoStreams(e.crunchy, fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/videos/%s/streams?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", + if e.children != nil { + return e.children, nil + } + + streams, err := fromVideoStreams(e.crunchy, fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/videos/%s/streams?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", e.crunchy.Config.CountryCode, e.crunchy.Config.MaturityRating, e.crunchy.Config.Channel, @@ -143,4 +149,12 @@ func (e *Episode) Streams() ([]*Stream, error) { e.crunchy.Config.Signature, e.crunchy.Config.Policy, e.crunchy.Config.KeyPairID)) + if err != nil { + return nil, err + } + + if e.crunchy.cache { + e.children = streams + } + return streams, nil } diff --git a/season.go b/season.go index 9021af7..16bc6d6 100644 --- a/season.go +++ b/season.go @@ -9,6 +9,8 @@ import ( type Season struct { crunchy *Crunchyroll + children []*Episode + ID string `json:"id"` ChannelID string `json:"channel_id"` @@ -69,6 +71,10 @@ func SeasonFromID(crunchy *Crunchyroll, id string) (*Season, error) { // Episodes returns all episodes which are available for the season func (s *Season) Episodes() (episodes []*Episode, err error) { + if s.children != nil { + return s.children, nil + } + resp, err := s.crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/episodes?season_id=%s&locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", s.crunchy.Config.CountryCode, s.crunchy.Config.MaturityRating, @@ -101,5 +107,8 @@ func (s *Season) Episodes() (episodes []*Episode, err error) { episodes = append(episodes, episode) } + if s.crunchy.cache { + s.children = episodes + } return } diff --git a/stream.go b/stream.go index 59ab3c9..5fe0f96 100644 --- a/stream.go +++ b/stream.go @@ -11,6 +11,8 @@ import ( type Stream struct { crunchy *Crunchyroll + children []*Format + HardsubLocale LOCALE AudioLocale LOCALE Subtitles []*Subtitle @@ -35,6 +37,10 @@ func StreamsFromID(crunchy *Crunchyroll, id string) ([]*Stream, error) { // Formats returns all formats which are available for the stream func (s *Stream) Formats() ([]*Format, error) { + if s.children != nil { + return s.children, nil + } + resp, err := s.crunchy.Client.Get(s.streamURL) if err != nil { return nil, err @@ -57,6 +63,10 @@ func (s *Stream) Formats() ([]*Format, error) { Subtitles: s.Subtitles, }) } + + if s.crunchy.cache { + s.children = formats + } return formats, nil } diff --git a/video.go b/video.go index c39a4d0..1b83c90 100644 --- a/video.go +++ b/video.go @@ -38,6 +38,8 @@ type Movie struct { crunchy *Crunchyroll + children []*MovieListing + // not generated when calling MovieFromID MovieListingMetadata struct { AvailabilityNotes string `json:"availability_notes"` @@ -95,6 +97,10 @@ func MovieFromID(crunchy *Crunchyroll, id string) (*Movie, error) { // Beside the normal movie, sometimes movie previews are returned too, but you can try to get the actual movie // by sorting the returning MovieListing slice with the utils.MovieListingByDuration interface func (m *Movie) MovieListing() (movieListings []*MovieListing, err error) { + if m.children != nil { + return m.children, nil + } + resp, err := m.crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/movies?movie_listing_id=%s&locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", m.crunchy.Config.CountryCode, m.crunchy.Config.MaturityRating, @@ -120,6 +126,10 @@ func (m *Movie) MovieListing() (movieListings []*MovieListing, err error) { } movieListings = append(movieListings, movieListing) } + + if m.crunchy.cache { + m.children = movieListings + } return movieListings, nil } @@ -129,6 +139,8 @@ type Series struct { crunchy *Crunchyroll + children []*Season + PromoDescription string `json:"promo_description"` PromoTitle string `json:"promo_title"` @@ -179,6 +191,10 @@ func SeriesFromID(crunchy *Crunchyroll, id string) (*Series, error) { // Seasons returns all seasons of a series func (s *Series) Seasons() (seasons []*Season, err error) { + if s.children != nil { + return s.children, nil + } + resp, err := s.crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/seasons?series_id=%s&locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", s.crunchy.Config.CountryCode, s.crunchy.Config.MaturityRating, @@ -204,5 +220,9 @@ func (s *Series) Seasons() (seasons []*Season, err error) { } seasons = append(seasons, season) } + + if s.crunchy.cache { + s.children = seasons + } return }