ProviderIdParsers.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #nullable enable
  2. using System;
  3. using System.Diagnostics.CodeAnalysis;
  4. namespace MediaBrowser.Common.Providers
  5. {
  6. /// <summary>
  7. /// Parsers for provider ids.
  8. /// </summary>
  9. public static class ProviderIdParsers
  10. {
  11. private const int ImdbMinNumbers = 7;
  12. private const int ImdbMaxNumbers = 8;
  13. private const string ImdbPrefix = "tt";
  14. /// <summary>
  15. /// Parses an IMDb id from a string.
  16. /// </summary>
  17. /// <param name="text">The text to parse.</param>
  18. /// <param name="imdbId">The parsed IMDb id.</param>
  19. /// <returns>True if parsing was successful, false otherwise.</returns>
  20. public static bool TryFindImdbId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> imdbId)
  21. {
  22. // imdb id is at least 9 chars (tt + 7 numbers)
  23. while (text.Length >= 2 + ImdbMinNumbers)
  24. {
  25. var ttPos = text.IndexOf(ImdbPrefix);
  26. if (ttPos == -1)
  27. {
  28. imdbId = default;
  29. return false;
  30. }
  31. text = text.Slice(ttPos);
  32. var i = 2;
  33. var limit = Math.Min(text.Length, ImdbMaxNumbers + 2);
  34. for (; i < limit; i++)
  35. {
  36. var c = text[i];
  37. if (!IsDigit(c))
  38. {
  39. break;
  40. }
  41. }
  42. // skip if more than 8 digits + 2 chars for tt
  43. if (i <= ImdbMaxNumbers + 2 && i >= ImdbMinNumbers + 2)
  44. {
  45. imdbId = text.Slice(0, i);
  46. return true;
  47. }
  48. text = text.Slice(i);
  49. }
  50. imdbId = default;
  51. return false;
  52. }
  53. /// <summary>
  54. /// Parses an TMDb id from a movie url.
  55. /// </summary>
  56. /// <param name="text">The text with the url to parse.</param>
  57. /// <param name="tmdbId">The parsed TMDb id.</param>
  58. /// <returns>True if parsing was successful, false otherwise.</returns>
  59. public static bool TryFindTmdbMovieId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> tmdbId)
  60. => TryFindProviderId(text, "themoviedb.org/movie/", out tmdbId);
  61. /// <summary>
  62. /// Parses an TMDb id from a series url.
  63. /// </summary>
  64. /// <param name="text">The text with the url to parse.</param>
  65. /// <param name="tmdbId">The parsed TMDb id.</param>
  66. /// <returns>True if parsing was successful, false otherwise.</returns>
  67. public static bool TryFindTmdbSeriesId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> tmdbId)
  68. => TryFindProviderId(text, "themoviedb.org/tv/", out tmdbId);
  69. /// <summary>
  70. /// Parses an TVDb id from a url.
  71. /// </summary>
  72. /// <param name="text">The text with the url to parse.</param>
  73. /// <param name="tvdbId">The parsed TVDb id.</param>
  74. /// <returns>True if parsing was successful, false otherwise.</returns>
  75. public static bool TryFindTvdbId(ReadOnlySpan<char> text, [NotNullWhen(true)] out ReadOnlySpan<char> tvdbId)
  76. => TryFindProviderId(text, "thetvdb.com/?tab=series&id=", out tvdbId);
  77. private static bool TryFindProviderId(ReadOnlySpan<char> text, ReadOnlySpan<char> searchString, [NotNullWhen(true)] out ReadOnlySpan<char> providerId)
  78. {
  79. var searchPos = text.IndexOf(searchString);
  80. if (searchPos == -1)
  81. {
  82. providerId = default;
  83. return false;
  84. }
  85. text = text.Slice(searchPos + searchString.Length);
  86. int i = 0;
  87. for (; i < text.Length; i++)
  88. {
  89. var c = text[i];
  90. if (!IsDigit(c))
  91. {
  92. break;
  93. }
  94. }
  95. if (i >= 1)
  96. {
  97. providerId = text.Slice(0, i);
  98. return true;
  99. }
  100. providerId = default;
  101. return false;
  102. }
  103. private static bool IsDigit(char c)
  104. {
  105. return c >= '0' && c <= '9';
  106. }
  107. }
  108. }