Add watch history

This commit is contained in:
IchBinLeoon 2022-05-28 19:55:56 +02:00
parent 08c46e50bb
commit cf35596985
3 changed files with 55 additions and 13 deletions

View file

@ -591,7 +591,7 @@ func (c *Crunchyroll) Simulcasts() (s []*Simulcast, err error) {
} }
// News returns the top and latest news from crunchyroll for the current locale within the given limits. // News returns the top and latest news from crunchyroll for the current locale within the given limits.
func (c *Crunchyroll) News(topLimit uint, latestLimit uint) (t []*TopNews, l []*LatestNews, err error) { func (c *Crunchyroll) News(topLimit uint, latestLimit uint) (t []*News, l []*News, err error) {
newsFeedEndpoint := fmt.Sprintf("https://beta.crunchyroll.com/content/v1/news_feed?top_news_n=%d&latest_news_n=%d&locale=%s", newsFeedEndpoint := fmt.Sprintf("https://beta.crunchyroll.com/content/v1/news_feed?top_news_n=%d&latest_news_n=%d&locale=%s",
topLimit, latestLimit, c.Locale) topLimit, latestLimit, c.Locale)
resp, err := c.request(newsFeedEndpoint) resp, err := c.request(newsFeedEndpoint)
@ -607,7 +607,7 @@ func (c *Crunchyroll) News(topLimit uint, latestLimit uint) (t []*TopNews, l []*
topNews := jsonBody["top_news"].(map[string]interface{}) topNews := jsonBody["top_news"].(map[string]interface{})
for _, item := range topNews["items"].([]interface{}) { for _, item := range topNews["items"].([]interface{}) {
topNews := &TopNews{} topNews := &News{}
if err := decodeMapToStruct(item, topNews); err != nil { if err := decodeMapToStruct(item, topNews); err != nil {
return nil, nil, err return nil, nil, err
} }
@ -617,7 +617,7 @@ func (c *Crunchyroll) News(topLimit uint, latestLimit uint) (t []*TopNews, l []*
latestNews := jsonBody["latest_news"].(map[string]interface{}) latestNews := jsonBody["latest_news"].(map[string]interface{})
for _, item := range latestNews["items"].([]interface{}) { for _, item := range latestNews["items"].([]interface{}) {
latestNews := &LatestNews{} latestNews := &News{}
if err := decodeMapToStruct(item, latestNews); err != nil { if err := decodeMapToStruct(item, latestNews); err != nil {
return nil, nil, err return nil, nil, err
} }
@ -672,7 +672,7 @@ func (c *Crunchyroll) Recommendations(limit uint) (s []*Series, m []*Movie, err
return s, m, nil return s, m, nil
} }
// UpNext returns the next episodes that you can continue watching based on your account within the given limit. // UpNext returns the episodes that are up next based on your account within the given limit.
func (c *Crunchyroll) UpNext(limit uint) (e []*Episode, err error) { func (c *Crunchyroll) UpNext(limit uint) (e []*Episode, err error) {
upNextAccountEndpoint := fmt.Sprintf("https://beta-api.crunchyroll.com/content/v1/%s/up_next_account?n=%d&locale=%s", upNextAccountEndpoint := fmt.Sprintf("https://beta-api.crunchyroll.com/content/v1/%s/up_next_account?n=%d&locale=%s",
c.Config.AccountID, limit, c.Locale) c.Config.AccountID, limit, c.Locale)
@ -703,7 +703,7 @@ func (c *Crunchyroll) UpNext(limit uint) (e []*Episode, err error) {
return e, nil return e, nil
} }
// SimilarTo returns similar series and movies to the one specified by id within the given limits. // SimilarTo returns similar series and movies according to crunchyroll to the one specified by id within the given limits.
func (c *Crunchyroll) SimilarTo(id string, limit uint) (s []*Series, m []*Movie, err error) { func (c *Crunchyroll) SimilarTo(id string, limit uint) (s []*Series, m []*Movie, err error) {
similarToEndpoint := fmt.Sprintf("https://beta-api.crunchyroll.com/content/v1/%s/similar_to?guid=%s&n=%d&locale=%s", similarToEndpoint := fmt.Sprintf("https://beta-api.crunchyroll.com/content/v1/%s/similar_to?guid=%s&n=%d&locale=%s",
c.Config.AccountID, id, limit, c.Locale) c.Config.AccountID, id, limit, c.Locale)
@ -746,3 +746,41 @@ func (c *Crunchyroll) SimilarTo(id string, limit uint) (s []*Series, m []*Movie,
return s, m, nil return s, m, nil
} }
// WatchHistory returns the history of watched episodes based on your account from the given page with the given size.
func (c *Crunchyroll) WatchHistory(page uint, size uint) (e []*HistoryEpisode, err error) {
watchHistoryEndpoint := fmt.Sprintf("https://beta-api.crunchyroll.com/content/v1/watch-history/%s?page=%d&page_size=%d&locale=%s",
c.Config.AccountID, page, size, c.Locale)
resp, err := c.request(watchHistoryEndpoint)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var jsonBody map[string]interface{}
if err = json.NewDecoder(resp.Body).Decode(&jsonBody); err != nil {
return nil, fmt.Errorf("failed to parse 'watch-history' response: %w", err)
}
for _, item := range jsonBody["items"].([]interface{}) {
panel := item.(map[string]interface{})["panel"]
episode := &Episode{
crunchy: c,
}
if err := decodeMapToStruct(panel, episode); err != nil {
return nil, err
}
historyEpisode := &HistoryEpisode{
Episode: episode,
}
if err := decodeMapToStruct(item, historyEpisode); err != nil {
return nil, err
}
e = append(e, historyEpisode)
}
return e, nil
}

View file

@ -75,6 +75,18 @@ type Episode struct {
StreamID string StreamID string
} }
// HistoryEpisode contains additional information about an episode if the account has watched or started to watch the episode.
type HistoryEpisode struct {
*Episode
ID string `json:"id"`
DatePlayed string `json:"date_played"`
ParentID string `json:"parent_id"`
ParentType MediaType `json:"parent_type"`
Playhead uint `json:"playhead"`
FullyWatched bool `json:"fully_watched"`
}
// EpisodeFromID returns an episode by its api id. // EpisodeFromID returns an episode by its api id.
func EpisodeFromID(crunchy *Crunchyroll, id string) (*Episode, error) { func EpisodeFromID(crunchy *Crunchyroll, id string) (*Episode, error) {
resp, err := crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/episodes/%s?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", resp, err := crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/episodes/%s?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s",

View file

@ -9,11 +9,3 @@ type News struct {
PublishDate string `json:"publish_date"` PublishDate string `json:"publish_date"`
Description string `json:"description"` Description string `json:"description"`
} }
type TopNews struct {
News
}
type LatestNews struct {
News
}