diff --git a/Makefile b/Makefile index 61795e74..848e2824 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=1.2.0 +VERSION=1.2.1 BINARY_NAME=crunchy VERSION_BINARY_NAME=$(BINARY_NAME)-v$(VERSION) diff --git a/cmd/crunchyroll-go/cmd/download.go b/cmd/crunchyroll-go/cmd/download.go index 73554174..fff74c6b 100644 --- a/cmd/crunchyroll-go/cmd/download.go +++ b/cmd/crunchyroll-go/cmd/download.go @@ -296,7 +296,7 @@ func parseURLs(urls []string) (allEpisodes []episodeInformation, total, successe var seriesName string var ok bool - if seriesName, _, ok = crunchyroll.MatchEpisode(url); !ok { + if seriesName, _, _, _, ok = crunchyroll.ParseEpisodeURL(url); !ok { seriesName, _ = crunchyroll.MatchVideo(url) } @@ -339,7 +339,7 @@ func parseURLs(urls []string) (allEpisodes []episodeInformation, total, successe var parsed []episodeInformation parsed, localTotal, localSuccesses = parseVideo(dupe, url) allEpisodes = append(allEpisodes, parsed...) - } else if _, _, ok = crunchyroll.MatchEpisode(url); ok { + } else if _, _, _, _, ok = crunchyroll.ParseEpisodeURL(url); ok { out.Debugf("Parsed url %d as episode\n", i+1) if episode := parseEpisodes(dupe.(*utils.EpisodeStructure), url); episode.Format != nil { allEpisodes = append(allEpisodes, episode) diff --git a/crunchyroll.go b/crunchyroll.go index d8e74e96..a14423e5 100644 --- a/crunchyroll.go +++ b/crunchyroll.go @@ -9,7 +9,7 @@ import ( "net/http" "net/url" "regexp" - "strings" + "strconv" ) // LOCALE represents a locale / language @@ -307,8 +307,7 @@ func (c *Crunchyroll) FindVideo(seriesUrl string) (Video, error) { // FindEpisode finds an episode by its crunchyroll link // e.g. https://www.crunchyroll.com/darling-in-the-franxx/episode-1-alone-and-lonesome-759575 func (c *Crunchyroll) FindEpisode(url string) ([]*Episode, error) { - if series, title, ok := MatchEpisode(url); ok { - title = strings.TrimSuffix(title, "-") + if series, title, _, _, ok := ParseEpisodeURL(url); ok { video, err := c.FindVideo(fmt.Sprintf("https://www.crunchyroll.com/%s", series)) if err != nil { return nil, err @@ -351,14 +350,26 @@ func MatchVideo(url string) (seriesName string, ok bool) { } // MatchEpisode tries to extract the crunchyroll series name and title out of the given url +// +// Deprecated: Use ParseEpisodeURL instead func MatchEpisode(url string) (seriesName, title string, ok bool) { - pattern := regexp.MustCompile(`(?m)^https?://(www\.)?crunchyroll\.com(/\w{2}(-\w{2})?)?/(?P[^/]+)/episode-\d+-(?P\D+).*`) + seriesName, title, _, _, ok = ParseEpisodeURL(url) + return +} + +// ParseEpisodeURL tries to extract the crunchyroll series name, title, episode number and web id out of the given url +// Note that the episode number can be misleading. For example if an episode has the episode number 23.5 (slime isekai) +// the episode number will be 235 +func ParseEpisodeURL(url string) (seriesName, title string, episodeNumber int, webId int, ok bool) { + pattern := regexp.MustCompile(`(?m)^https?://(www\.)?crunchyroll\.com(/\w{2}(-\w{2})?)?/(?P<series>[^/]+)/episode-(?P<number>\d+)-(?P<title>\w+)-(?P<webId>\d+).*`) if urlMatch := pattern.FindAllStringSubmatch(url, -1); len(urlMatch) != 0 { groups := regexGroups(urlMatch, pattern.SubexpNames()...) seriesName = groups["series"] - title = strings.TrimSuffix(groups["title"], "-") + episodeNumber, _ = strconv.Atoi(groups["number"]) + title = groups["title"] + webId, _ = strconv.Atoi(groups["webId"]) - if seriesName != "" && title != "" { + if seriesName != "" && title != "" && webId != 0 { ok = true } } diff --git a/utils/structure.go b/utils/structure.go index a958c738..54e0e1d0 100644 --- a/utils/structure.go +++ b/utils/structure.go @@ -2,6 +2,7 @@ package utils import ( "errors" + "fmt" "github.com/ByteDream/crunchyroll-go" "sync" ) @@ -499,11 +500,13 @@ func (es *EpisodeStructure) GetEpisodeByFormat(format *crunchyroll.Format) (*cru // GetEpisodeByURL returns an episode by its url func (es *EpisodeStructure) GetEpisodeByURL(url string) (*crunchyroll.Episode, error) { - _, title, ok := crunchyroll.MatchEpisode(url) + _, title, episodeNumber, _, ok := crunchyroll.ParseEpisodeURL(url) if !ok { return nil, errors.New("invalid url") } + fmt.Println(title) + episodes, err := es.Episodes() if err != nil { return nil, err @@ -514,6 +517,12 @@ func (es *EpisodeStructure) GetEpisodeByURL(url string) (*crunchyroll.Episode, e return episode, nil } } + + for _, episode := range episodes { + if episode.EpisodeNumber == episodeNumber { + return episode, nil + } + } return nil, errors.New("no episode could be found") }