ProviderIdParsers.cs 4.1 KB

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