/// <summary> /// Checks if a number follows the specified <code>token</code> /// </summary> /// <param name="category">the category to set if a number follows the <code>token</code></param> /// <param name="token">the token</param> /// <returns>true if a number follows the token; false otherwise</returns> private bool NumberComesAfterPrefix(Element.ElementCategory category, Token token) { var numberBegin = ParserHelper.IndexOfFirstDigit(token.Content); var prefix = StringHelper.SubstringWithCheck(token.Content, 0, numberBegin).ToUpperInvariant(); if (KeywordManager.Instance.Contains(category, prefix)) { var number = StringHelper.SubstringWithCheck(token.Content, numberBegin, token.Content.Length - numberBegin); switch (category) { case Element.ElementCategory.ElementEpisodePrefix: if (!MatchEpisodePatterns(number, token)) { SetEpisodeNumber(number, token, false); } return(true); case Element.ElementCategory.ElementVolumePrefix: if (!MatchVolumePatterns(number, token)) { SetVolumeNumber(number, token, false); } return(true); } } return(false); }
/// <summary> /// A Method to find the correct volume/episode number when prefixed (i.e. Vol.4). /// </summary> /// <param name="category">the category we're searching for</param> /// <param name="currentTokenPos">the current token position</param> /// <param name="token">the token</param> /// <returns>true if we found the volume/episode number</returns> public bool CheckExtentKeyword(Element.ElementCategory category, int currentTokenPos, Token token) { var nToken = Token.FindNextToken(_parser.Tokens, currentTokenPos, Token.TokenFlag.FlagNotDelimiter); if (!IsTokenCategory(nToken, Token.TokenCategory.Unknown)) { return(false); } if (IndexOfFirstDigit(_parser.Tokens[nToken].Content) != 0) { return(false); } switch (category) { case Element.ElementCategory.ElementEpisodeNumber: if (!_parser.ParseNumber.MatchEpisodePatterns(_parser.Tokens[nToken].Content, _parser.Tokens[nToken])) { _parser.ParseNumber.SetEpisodeNumber(_parser.Tokens[nToken].Content, _parser.Tokens[nToken], false); } break; case Element.ElementCategory.ElementVolumeNumber: if (!_parser.ParseNumber.MatchVolumePatterns(_parser.Tokens[nToken].Content, _parser.Tokens[nToken])) { _parser.ParseNumber.SetVolumeNumber(_parser.Tokens[nToken].Content, _parser.Tokens[nToken], false); } break; } token.Category = Token.TokenCategory.Identifier; return(true); }
/// <summary> /// Returns whether or not the <code>category</code> is searchable. /// </summary> public bool IsElementCategorySearchable(Element.ElementCategory category) { switch (category) { case Element.ElementCategory.ElementAnimeSeasonPrefix: case Element.ElementCategory.ElementAnimeType: case Element.ElementCategory.ElementAudioTerm: case Element.ElementCategory.ElementDeviceCompatibility: case Element.ElementCategory.ElementEpisodePrefix: case Element.ElementCategory.ElementFileChecksum: case Element.ElementCategory.ElementLanguage: case Element.ElementCategory.ElementOther: case Element.ElementCategory.ElementReleaseGroup: case Element.ElementCategory.ElementReleaseInformation: case Element.ElementCategory.ElementReleaseVersion: case Element.ElementCategory.ElementSource: case Element.ElementCategory.ElementSubtitles: case Element.ElementCategory.ElementVideoResolution: case Element.ElementCategory.ElementVideoTerm: case Element.ElementCategory.ElementVolumePrefix: return(true); default: return(false); } }
/// Adds a <code>category</code>, <code>options</code>, and <code>keywords</code> to the internal keywords list. private static void Add(Element.ElementCategory category, KeywordOptions options, IEnumerable <string> keywords) { var keys = GetKeywordContainer(category); foreach (var key in keywords.Where(k => !string.IsNullOrEmpty(k) && !keys.ContainsKey(k))) { keys[key] = new Keyword(category, options); } }
public void BuildElement(Element.ElementCategory category, bool keepDelimiters, List <Token> tokens) { var element = new StringBuilder(); for (var i = 0; i < tokens.Count; i++) { var token = tokens[i]; switch (token.Category) { case Token.TokenCategory.Unknown: element.Append(token.Content); token.Category = Token.TokenCategory.Identifier; break; case Token.TokenCategory.Bracket: element.Append(token.Content); break; case Token.TokenCategory.Delimiter: var delimiter = ""; if (!string.IsNullOrEmpty(token.Content)) { delimiter = token.Content[0].ToString(); } if (keepDelimiters) { element.Append(delimiter); } else if (Token.InListRange(i, tokens)) { switch (delimiter) { case ",": case "&": element.Append(delimiter); break; default: element.Append(' '); break; } } break; } } if (!keepDelimiters) { element = new StringBuilder(element.ToString().Trim(DashesWithSpace.ToCharArray())); } if (!string.IsNullOrEmpty(element.ToString())) { _parser.Elements.Add(new Element(category, element.ToString())); } }
public static bool Contains(Element.ElementCategory category, string keyword) { var keys = GetKeywordContainer(category); if (keys.TryGetValue(keyword, out var foundEntry)) { return(foundEntry.Category == category); } return(false); }
/// <summary> /// Returns the value of a particular category /// </summary> /// <param name="category"></param> /// <returns></returns> private string Get(Element.ElementCategory category) { var foundElement = Elements.Find(element => element.Category == category); if (foundElement == null) { Element e = new Element(category, ""); Elements.Add(e); foundElement = e; } return foundElement.Value; }
/// <summary> /// Finds a particular <code>keyword</code>. If found sets <code>category</code> and <code>options</code> to the found search result. /// </summary> /// <param name="keyword">the keyword to search for</param> /// <param name="category">the reference that will be set/changed to the found keyword category</param> /// <param name="options">the reference that will be set/changed to the found keyword options</param> /// <returns>if the keyword was found</returns> public static bool FindAndSet(string keyword, ref Element.ElementCategory category, ref KeywordOptions options) { var keys = GetKeywordContainer(category); if (!keys.TryGetValue(keyword, out var foundEntry)) { return(false); } if (category == Element.ElementCategory.ElementUnknown) { category = foundEntry.Category; } else if (foundEntry.Category != category) { return(false); } options = foundEntry.Options; return(true); }
/// <summary> /// Returns whether the <code>category</code> is singular. /// </summary> public bool IsElementCategorySingular(Element.ElementCategory category) { switch (category) { case Element.ElementCategory.ElementAnimeSeason: case Element.ElementCategory.ElementAnimeType: case Element.ElementCategory.ElementAudioTerm: case Element.ElementCategory.ElementDeviceCompatibility: case Element.ElementCategory.ElementEpisodeNumber: case Element.ElementCategory.ElementLanguage: case Element.ElementCategory.ElementOther: case Element.ElementCategory.ElementReleaseInformation: case Element.ElementCategory.ElementSource: case Element.ElementCategory.ElementVideoTerm: return(false); default: return(false); } }
/// <summary> /// Constructs a new Keyword /// </summary> /// <param name="category">the category of the keyword</param> /// <param name="options">the keyword's options</param> public Keyword(Element.ElementCategory category, KeywordOptions options) { Category = category; Options = options; }
// Private API /** Returns the appropriate keyword container. */ private static Dictionary <string, Keyword> GetKeywordContainer(Element.ElementCategory category) { return(category == Element.ElementCategory.ElementFileExtension ? Extensions : Keys); }
/// <summary> /// Returns whether or not the parser contains this category /// </summary> /// <param name="category"></param> /// <returns></returns> private bool Empty(Element.ElementCategory category) { return Elements.All(element => element.Category != category); }