package parsers import ( "regexp" "git.milar.in/nyaanime/model" ) // TorrentParseOptions holds the subgroup index in which information can be found in a given regex // as well as some parser specific functions type TorrentParseOptions struct { // regex group references Name int Episode int Languages int Subtitles int Resolution int // language parsers LanguageParser LanguageParserFunc SubtitleParser LanguageParserFunc // default values used when group reference is 0 DefaultLanguages []string DefaultSubtitles []string DefaultResolution model.Resolution } func RegexTorrentParser(regex string, options TorrentParseOptions) model.TorrentParserFunc { pattern := regexp.MustCompile(regex) // handle faulty regexes if options.Name == 0 || options.Episode == 0 { panic(ErrTorrentParserInsufficientData.New(regex)) } else if options.Languages == 0 && options.DefaultLanguages == nil { panic(ErrTorrentParserInsufficientLanguageData.New(regex)) } else if options.Subtitles == 0 && options.DefaultSubtitles == nil { panic(ErrTorrentParserInsufficientSubtitleData.New(regex)) } else if options.Resolution == 0 && options.DefaultResolution == 0 { panic(ErrTorrentParserInsufficientResolutionData.New(regex)) } // handle faulty group references for _, g := range []int{options.Name, options.Episode, options.Languages, options.Subtitles, options.Resolution} { if g > pattern.NumSubexp() { panic(ErrTorrentParserInvalidGroupReference.New(g, pattern.NumSubexp())) } } return func(parser *model.Parser, torrent *model.Torrent) (ParsedTorrent *model.ParsedTorrent, ok bool) { var err error matches := pattern.FindStringSubmatch(torrent.Title) if matches == nil { return nil, false } episode, ok := atoi(matches[options.Episode]) if !ok { return nil, false } resolution := options.DefaultResolution if options.Resolution != 0 { resolution, err = model.ParseResolution(matches[options.Resolution]) if err != nil { return nil, false } } languages := options.DefaultLanguages if options.Languages != 0 { languages = options.LanguageParser(matches[options.Languages]) } subtitles := options.DefaultSubtitles if options.Subtitles != 0 { subtitles = options.SubtitleParser(matches[options.Subtitles]) } return &model.ParsedTorrent{ OriginalAnimeTitle: matches[options.Name], Episode: episode, Resolution: resolution, Parser: parser, Languages: ParseLanguages(languages), Subtitles: ParseLanguages(subtitles), Torrent: torrent, }, true } }