MusicArtistResolver.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #nullable disable
  2. using System;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Emby.Naming.Common;
  6. using Jellyfin.Data.Enums;
  7. using MediaBrowser.Controller.Entities.Audio;
  8. using MediaBrowser.Controller.Library;
  9. using MediaBrowser.Controller.Providers;
  10. using MediaBrowser.Controller.Resolvers;
  11. using MediaBrowser.Model.Entities;
  12. using Microsoft.Extensions.Logging;
  13. namespace Emby.Server.Implementations.Library.Resolvers.Audio
  14. {
  15. /// <summary>
  16. /// The music artist resolver.
  17. /// </summary>
  18. public class MusicArtistResolver : ItemResolver<MusicArtist>
  19. {
  20. private readonly ILogger<MusicAlbumResolver> _logger;
  21. private readonly NamingOptions _namingOptions;
  22. private readonly IDirectoryService _directoryService;
  23. /// <summary>
  24. /// Initializes a new instance of the <see cref="MusicArtistResolver"/> class.
  25. /// </summary>
  26. /// <param name="logger">Instance of the <see cref="MusicAlbumResolver"/> interface.</param>
  27. /// <param name="namingOptions">The <see cref="NamingOptions"/>.</param>
  28. /// <param name="directoryService">The directory service.</param>
  29. public MusicArtistResolver(
  30. ILogger<MusicAlbumResolver> logger,
  31. NamingOptions namingOptions,
  32. IDirectoryService directoryService)
  33. {
  34. _logger = logger;
  35. _namingOptions = namingOptions;
  36. _directoryService = directoryService;
  37. }
  38. /// <summary>
  39. /// Gets the priority.
  40. /// </summary>
  41. /// <value>The priority.</value>
  42. public override ResolverPriority Priority => ResolverPriority.Second;
  43. /// <summary>
  44. /// Resolves the specified resolver arguments.
  45. /// </summary>
  46. /// <param name="args">The resolver arguments.</param>
  47. /// <returns>A <see cref="MusicArtist"/>.</returns>
  48. protected override MusicArtist Resolve(ItemResolveArgs args)
  49. {
  50. if (!args.IsDirectory)
  51. {
  52. return null;
  53. }
  54. // Don't allow nested artists
  55. if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>())
  56. {
  57. return null;
  58. }
  59. var collectionType = args.GetCollectionType();
  60. var isMusicMediaFolder = collectionType == CollectionType.Music;
  61. // If there's a collection type and it's not music, it can't be a music artist
  62. if (!isMusicMediaFolder)
  63. {
  64. return null;
  65. }
  66. if (args.ContainsFileSystemEntryByName("artist.nfo"))
  67. {
  68. return new MusicArtist();
  69. }
  70. // Avoid mis-identifying top folders
  71. if (args.Parent.IsRoot)
  72. {
  73. return null;
  74. }
  75. var albumResolver = new MusicAlbumResolver(_logger, _namingOptions, _directoryService);
  76. var directories = args.FileSystemChildren.Where(i => i.IsDirectory);
  77. var result = Parallel.ForEach(directories, (fileSystemInfo, state) =>
  78. {
  79. // If we contain a artist subfolder assume we are an artist folder
  80. foreach (var subfolder in _namingOptions.ArtistSubfolders)
  81. {
  82. if (fileSystemInfo.Name.Equals(subfolder, StringComparison.OrdinalIgnoreCase))
  83. {
  84. // Stop once we see an artist subfolder
  85. state.Stop();
  86. }
  87. }
  88. // If we contain a music album assume we are an artist folder
  89. if (albumResolver.IsMusicAlbum(fileSystemInfo.FullName, _directoryService))
  90. {
  91. // Stop once we see a music album
  92. state.Stop();
  93. }
  94. });
  95. return !result.IsCompleted ? new MusicArtist() : null;
  96. }
  97. }
  98. }