/// <summary> /// Removes the extension from the <see cref="filename"/> /// </summary> /// <param name="filename">the ref that will be updated with the new filename</param> /// <param name="extension">the ref that will be updated with the file extension</param> /// <returns>if the extension was successfully separated from the filename</returns> private static bool RemoveExtensionFromFilename(ref string filename, ref string extension) { int position; if (string.IsNullOrEmpty(filename) || (position = filename.LastIndexOf('.')) == -1) { return(false); } /** remove file extension */ extension = filename.Substring(position + 1); if (extension.Length > 4 || !extension.All(char.IsLetterOrDigit)) { return(false); } /** check if valid anime extension */ var keyword = KeywordManager.Normalize(extension); if (!KeywordManager.Instance.Contains(Element.ElementCategory.ElementFileExtension, keyword)) { return(false); } filename = filename.Substring(0, position); return(true); }
/// <summary> /// Validate Elements /// </summary> private void ValidateElements() { if (!Empty(Element.ElementCategory.ElementAnimeType) && !Empty(Element.ElementCategory.ElementEpisodeTitle)) { var episodeTitle = Get(Element.ElementCategory.ElementEpisodeTitle); for (var i = 0; i < Elements.Count;) { var el = Elements[i]; if (el.Category == Element.ElementCategory.ElementAnimeType) { if (episodeTitle.Contains(el.Value)) { if (episodeTitle.Length == el.Value.Length) { Elements.RemoveAll(element => element.Category == Element.ElementCategory.ElementEpisodeTitle); // invalid episode title } else { var keyword = KeywordManager.Normalize(el.Value); if (KeywordManager.Instance.Contains(Element.ElementCategory.ElementAnimeType, keyword)) { i = Erase(el); // invalid anime type continue; } } } } ++i; } } }
/// <summary> /// Match type and episode. e.g. "ED1", "OP4a", "OVA2". /// </summary> /// <param name="word">the word</param> /// <param name="token">the token</param> /// <returns>true if the token matched</returns> private bool MatchTypeAndEpisodePattern(string word, Token token) { var numberBegin = ParserHelper.IndexOfFirstDigit(word); var prefix = StringHelper.SubstringWithCheck(word, 0, numberBegin); var category = Element.ElementCategory.ElementAnimeType; var options = new KeywordOptions(); if (KeywordManager.Instance.FindAndSet(KeywordManager.Normalize(prefix), ref category, ref options)) { _parser.Elements.Add(new Element(Element.ElementCategory.ElementAnimeType, prefix)); var number = word.Substring(numberBegin); if (MatchEpisodePatterns(number, token) || SetEpisodeNumber(number, token, true)) { var foundIdx = _parser.Tokens.IndexOf(token); if (foundIdx != -1) { token.Content = number; _parser.Tokens.Insert(foundIdx, new Token(options.Identifiable ? Token.TokenCategory.Identifier : Token.TokenCategory.Unknown, prefix, token.Enclosed)); } return(true); } } return(false); }
/** Search for anime keywords. */ private void SearchForKeywords() { for (var i = 0; i < Tokens.Count; i++) { var token = Tokens[i]; if (token.Category != Token.TokenCategory.Unknown) continue; var word = token.Content; word = word.Trim(" -".ToCharArray()); if (string.IsNullOrEmpty(word)) continue; // Don't bother if the word is a number that cannot be CRC if (word.Length != 8 && StringHelper.IsNumericString(word)) continue; var keyword = KeywordManager.Normalize(word); var category = Element.ElementCategory.ElementUnknown; var options = new KeywordOptions(); if (KeywordManager.Instance.FindAndSet(keyword, ref category, ref options)) { if (!Options.ParseReleaseGroup && category == Element.ElementCategory.ElementReleaseGroup) continue; if (!ParseHelper.IsElementCategorySearchable(category) || !options.Searchable) continue; if (ParseHelper.IsElementCategorySingular(category) && !Empty(category)) continue; if (category == Element.ElementCategory.ElementAnimeSeasonPrefix) { ParseHelper.CheckAndSetAnimeSeasonKeyword(token, i); continue; } if (category == Element.ElementCategory.ElementEpisodePrefix) { if (options.Valid) { ParseHelper.CheckExtentKeyword(Element.ElementCategory.ElementEpisodeNumber, i, token); continue; } } else if (category == Element.ElementCategory.ElementReleaseVersion) { word = word.Substring(1); } else if (category == Element.ElementCategory.ElementVolumePrefix) { ParseHelper.CheckExtentKeyword(Element.ElementCategory.ElementVolumeNumber, i, token); continue; } } else { if (Empty(Element.ElementCategory.ElementFileChecksum) && ParserHelper.IsCrc32(word)) { category = Element.ElementCategory.ElementFileChecksum; } else if (Empty(Element.ElementCategory.ElementVideoResolution) && ParserHelper.IsResolution(word)) { category = Element.ElementCategory.ElementVideoResolution; } } if (category != Element.ElementCategory.ElementUnknown) { Elements.Add(new Element(category, word)); if (options.Identifiable) { token.Category = Token.TokenCategory.Identifier; } } } }