diff --git a/crunchyroll.go b/crunchyroll.go index e7ca172..70ec77e 100644 --- a/crunchyroll.go +++ b/crunchyroll.go @@ -5,10 +5,10 @@ import ( "encoding/json" "errors" "fmt" + "github.com/ByteDream/crunchyroll-go/utils" "io/ioutil" "net/http" "net/url" - "regexp" "strings" ) @@ -283,15 +283,12 @@ func (c *Crunchyroll) Search(query string, limit uint) (s []*Series, m []*Movie, // FindVideo fins a Video (Season or Movie) by a crunchyroll link // e.g. https://www.crunchyroll.com/darling-in-the-franxx func (c *Crunchyroll) FindVideo(seriesUrl string) (Video, error) { - pattern := regexp.MustCompile(`(?m)^https?://(www\.)?crunchyroll\.com(/\w{2}(-\w{2})?)?/(?P[^/]+)/?$`) - if urlMatch := pattern.FindAllStringSubmatch(seriesUrl, -1); len(urlMatch) != 0 { - groups := regexGroups(urlMatch, pattern.SubexpNames()...) - title, ok := groups["series"] + if series, ok := utils.MatchVideo(seriesUrl); ok { if !ok { return nil, errors.New("series could not be found") } - s, m, err := c.Search(title, 1) + s, m, err := c.Search(series, 1) if err != nil { return nil, err } @@ -310,16 +307,9 @@ 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) { - pattern := regexp.MustCompile(`(?m)^https?://(www\.)?crunchyroll\.com(/\w{2}(-\w{2})?)?/(?P[^/]+)/episode-\d+-(?P\D+).*`) - if urlMatch := pattern.FindAllStringSubmatch(url, -1); len(urlMatch) != 0 { - groups := regexGroups(urlMatch, pattern.SubexpNames()...) - var slugTitle string - var ok bool - if slugTitle, ok = groups["title"]; !ok { - return nil, errors.New("invalid url") - } - slugTitle = strings.TrimSuffix(slugTitle, "-") - video, err := c.FindVideo(fmt.Sprintf("https://www.crunchyroll.com/%s", groups["series"])) + if series, title, ok := utils.MatchEpisode(url); ok { + title = strings.TrimSuffix(title, "-") + video, err := c.FindVideo(fmt.Sprintf("https://www.crunchyroll.com/%s", series)) if err != nil { return nil, err } @@ -335,7 +325,7 @@ func (c *Crunchyroll) FindEpisode(url string) ([]*Episode, error) { return nil, err } for _, episode := range episodes { - if episode.SlugTitle == slugTitle { + if episode.SlugTitle == title { matchingEpisodes = append(matchingEpisodes, episode) } } diff --git a/utils.go b/utils.go index 5983a60..142fdd5 100644 --- a/utils.go +++ b/utils.go @@ -43,15 +43,3 @@ func pkcs5UnPadding(origData []byte) []byte { unPadding := int(origData[length-1]) return origData[:(length - unPadding)] } - -func regexGroups(parsed [][]string, subexpNames ...string) map[string]string { - groups := map[string]string{} - for _, match := range parsed { - for i, content := range match { - if subexpName := subexpNames[i]; subexpName != "" { - groups[subexpName] = content - } - } - } - return groups -} diff --git a/utils/match.go b/utils/match.go new file mode 100644 index 0000000..4a58859 --- /dev/null +++ b/utils/match.go @@ -0,0 +1,44 @@ +package utils + +import "regexp" + +// MatchVideo tries to extract the crunchyroll series / movie name out of the given url +func MatchVideo(url string) (seriesName string, ok bool) { + pattern := regexp.MustCompile(`(?m)^https?://(www\.)?crunchyroll\.com(/\w{2}(-\w{2})?)?/(?P<series>[^/]+)/?$`) + if urlMatch := pattern.FindAllStringSubmatch(url, -1); len(urlMatch) != 0 { + groups := regexGroups(urlMatch, pattern.SubexpNames()...) + seriesName = groups["series"] + + if seriesName != "" { + ok = true + } + } + return +} + +// MatchEpisode tries to extract the crunchyroll series name and title out of the given url +func MatchEpisode(url string) (seriesName, title string, ok bool) { + pattern := regexp.MustCompile(`(?m)^https?://(www\.)?crunchyroll\.com(/\w{2}(-\w{2})?)?/(?P<series>[^/]+)/episode-\d+-(?P<title>\D+).*`) + if urlMatch := pattern.FindAllStringSubmatch(url, -1); len(urlMatch) != 0 { + groups := regexGroups(urlMatch, pattern.SubexpNames()...) + seriesName = groups["series"] + title = groups["title"] + + if seriesName != "" && title != "" { + ok = true + } + } + return +} + +func regexGroups(parsed [][]string, subexpNames ...string) map[string]string { + groups := map[string]string{} + for _, match := range parsed { + for i, content := range match { + if subexpName := subexpNames[i]; subexpName != "" { + groups[subexpName] = content + } + } + } + return groups +}