Browse Source

made Audio.Artist plural and removed duplicated of artists into the people collection

Luke Pulverenti 12 years ago
parent
commit
19d21a246d

+ 1 - 1
MediaBrowser.Controller/Dto/DtoBuilder.cs

@@ -427,7 +427,7 @@ namespace MediaBrowser.Controller.Dto
                 {
                     dto.Album = audio.Album;
                     dto.AlbumArtist = audio.AlbumArtist;
-                    dto.Artist = audio.Artist;
+                    dto.Artists = audio.Artists;
                 }
             }
 

+ 18 - 0
MediaBrowser.Controller/Entities/Audio/Artist.cs

@@ -0,0 +1,18 @@
+
+namespace MediaBrowser.Controller.Entities.Audio
+{
+    /// <summary>
+    /// Class Artist
+    /// </summary>
+    public class Artist : BaseItem
+    {
+        /// <summary>
+        /// Gets the user data key.
+        /// </summary>
+        /// <returns>System.String.</returns>
+        public override string GetUserDataKey()
+        {
+            return Name;
+        }
+    }
+}

+ 31 - 2
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -1,5 +1,7 @@
 using MediaBrowser.Model.Entities;
+using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Runtime.Serialization;
 
 namespace MediaBrowser.Controller.Entities.Audio
@@ -14,7 +16,7 @@ namespace MediaBrowser.Controller.Entities.Audio
         /// </summary>
         /// <value>The media streams.</value>
         public List<MediaStream> MediaStreams { get; set; }
-        
+
         /// <summary>
         /// Override this to true if class should be grouped under a container in indicies
         /// The container class should be defined via IndexContainer
@@ -51,7 +53,8 @@ namespace MediaBrowser.Controller.Entities.Audio
         /// Gets or sets the artist.
         /// </summary>
         /// <value>The artist.</value>
-        public string Artist { get; set; }
+        public List<string> Artists { get; set; }
+
         /// <summary>
         /// Gets or sets the album.
         /// </summary>
@@ -75,6 +78,32 @@ namespace MediaBrowser.Controller.Entities.Audio
             }
         }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Audio"/> class.
+        /// </summary>
+        public Audio()
+        {
+            Artists = new List<string>();
+        }
+
+        /// <summary>
+        /// Adds the artist.
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <exception cref="System.ArgumentNullException">name</exception>
+        public void AddArtist(string name)
+        {
+            if (string.IsNullOrWhiteSpace(name))
+            {
+                throw new ArgumentNullException("name");
+            }
+
+            if (!Artists.Contains(name, StringComparer.OrdinalIgnoreCase))
+            {
+                Artists.Add(name);
+            }
+        }
+
         /// <summary>
         /// Creates the name of the sort.
         /// </summary>

+ 43 - 9
MediaBrowser.Controller/Entities/Folder.cs

@@ -127,7 +127,7 @@ namespace MediaBrowser.Controller.Entities
         /// <returns>IEnumerable{BaseItem}.</returns>
         protected IEnumerable<BaseItem> GetIndexByPerformer(User user)
         {
-            return GetIndexByPerson(user, new List<string> { PersonType.Actor, PersonType.MusicArtist, PersonType.GuestStar }, LocalizedStrings.Instance.GetString("PerformerDispPref"));
+            return GetIndexByPerson(user, new List<string> { PersonType.Actor, PersonType.GuestStar }, true, LocalizedStrings.Instance.GetString("PerformerDispPref"));
         }
 
         /// <summary>
@@ -137,7 +137,7 @@ namespace MediaBrowser.Controller.Entities
         /// <returns>IEnumerable{BaseItem}.</returns>
         protected IEnumerable<BaseItem> GetIndexByDirector(User user)
         {
-            return GetIndexByPerson(user, new List<string> { PersonType.Director }, LocalizedStrings.Instance.GetString("DirectorDispPref"));
+            return GetIndexByPerson(user, new List<string> { PersonType.Director }, false, LocalizedStrings.Instance.GetString("DirectorDispPref"));
         }
 
         /// <summary>
@@ -145,9 +145,10 @@ namespace MediaBrowser.Controller.Entities
         /// </summary>
         /// <param name="user">The user.</param>
         /// <param name="personTypes">The person types we should match on</param>
+        /// <param name="includeAudio">if set to <c>true</c> [include audio].</param>
         /// <param name="indexName">Name of the index.</param>
         /// <returns>IEnumerable{BaseItem}.</returns>
-        protected IEnumerable<BaseItem> GetIndexByPerson(User user, List<string> personTypes, string indexName)
+        private IEnumerable<BaseItem> GetIndexByPerson(User user, List<string> personTypes, bool includeAudio, string indexName)
         {
 
             // Even though this implementation means multiple iterations over the target list - it allows us to defer
@@ -158,9 +159,12 @@ namespace MediaBrowser.Controller.Entities
                 var currentIndexName = indexName;
 
                 var us = this;
-                var candidates = RecursiveChildren.Where(i => i.IncludeInIndex && i.AllPeople != null).ToList();
+                var recursiveChildren = GetRecursiveChildren(user).Where(i => i.IncludeInIndex).ToList();
 
-                return candidates.AsParallel().SelectMany(i => i.AllPeople.Where(p => personTypes.Contains(p.Type))
+                // Get the candidates, but handle audio separately
+                var candidates = recursiveChildren.Where(i => i.AllPeople != null && !(i is Audio.Audio)).ToList();
+
+                var indexFolders = candidates.AsParallel().SelectMany(i => i.AllPeople.Where(p => personTypes.Contains(p.Type))
                     .Select(a => a.Name))
                     .Distinct()
                     .Select(i =>
@@ -183,8 +187,38 @@ namespace MediaBrowser.Controller.Entities
                     .Where(i => i != null)
                     .Select(a => new IndexFolder(us, a,
                                         candidates.Where(i => i.AllPeople.Any(p => personTypes.Contains(p.Type) && p.Name.Equals(a.Name, StringComparison.OrdinalIgnoreCase))
-                                        ), currentIndexName));
+                                        ), currentIndexName)).AsEnumerable();
+
+                if (includeAudio)
+                {
+                    var songs = recursiveChildren.OfType<Audio.Audio>().ToList();
+
+                    indexFolders = songs.SelectMany(i => i.Artists)
+                        .Distinct()
+                    .Select(i =>
+                    {
+                        try
+                        {
+                            return LibraryManager.GetArtist(i).Result;
+                        }
+                        catch (IOException ex)
+                        {
+                            Logger.ErrorException("Error getting artist {0}", ex, i);
+                            return null;
+                        }
+                        catch (AggregateException ex)
+                        {
+                            Logger.ErrorException("Error getting artist {0}", ex, i);
+                            return null;
+                        }
+                    })
+                    .Where(i => i != null)
+                    .Select(a => new IndexFolder(us, a,
+                                        songs.Where(i => i.Artists.Contains(a.Name, StringComparer.OrdinalIgnoreCase)
+                                        ), currentIndexName)).Concat(indexFolders); 
+                }
 
+                return indexFolders;
             }
         }
 
@@ -201,7 +235,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 var indexName = LocalizedStrings.Instance.GetString("StudioDispPref");
 
-                var candidates = RecursiveChildren.Where(i => i.IncludeInIndex && i.Studios != null).ToList();
+                var candidates = GetRecursiveChildren(user).Where(i => i.IncludeInIndex && i.Studios != null).ToList();
 
                 return candidates.AsParallel().SelectMany(i => i.Studios)
                     .Distinct()
@@ -241,7 +275,7 @@ namespace MediaBrowser.Controller.Entities
                 var indexName = LocalizedStrings.Instance.GetString("GenreDispPref");
 
                 //we need a copy of this so we don't double-recurse
-                var candidates = RecursiveChildren.Where(i => i.IncludeInIndex && i.Genres != null).ToList();
+                var candidates = GetRecursiveChildren(user).Where(i => i.IncludeInIndex && i.Genres != null).ToList();
 
                 return candidates.AsParallel().SelectMany(i => i.Genres)
                     .Distinct()
@@ -282,7 +316,7 @@ namespace MediaBrowser.Controller.Entities
                 var indexName = LocalizedStrings.Instance.GetString("YearDispPref");
 
                 //we need a copy of this so we don't double-recurse
-                var candidates = RecursiveChildren.Where(i => i.IncludeInIndex && i.ProductionYear.HasValue).ToList();
+                var candidates = GetRecursiveChildren(user).Where(i => i.IncludeInIndex && i.ProductionYear.HasValue).ToList();
 
                 return candidates.AsParallel().Select(i => i.ProductionYear.Value)
                     .Distinct()

+ 6 - 0
MediaBrowser.Controller/IServerApplicationPaths.cs

@@ -40,6 +40,12 @@ namespace MediaBrowser.Controller
         /// <value>The genre path.</value>
         string GenrePath { get; }
 
+        /// <summary>
+        /// Gets the artists path.
+        /// </summary>
+        /// <value>The artists path.</value>
+        string ArtistsPath { get; }
+        
         /// <summary>
         /// Gets the path to the Studio directory
         /// </summary>

+ 9 - 0
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Sorting;
@@ -65,6 +66,14 @@ namespace MediaBrowser.Controller.Library
         /// <returns>Task{Person}.</returns>
         Task<Person> GetPerson(string name, bool allowSlowProviders = false);
 
+        /// <summary>
+        /// Gets the artist.
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
+        /// <returns>Task{Artist}.</returns>
+        Task<Artist> GetArtist(string name, bool allowSlowProviders = false);
+
         /// <summary>
         /// Gets a Studio
         /// </summary>

+ 1 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -71,6 +71,7 @@
     <Compile Include="Drawing\ImageManager.cs" />
     <Compile Include="Dto\UserDtoBuilder.cs" />
     <Compile Include="Entities\AggregateFolder.cs" />
+    <Compile Include="Entities\Audio\Artist.cs" />
     <Compile Include="Entities\Audio\Audio.cs" />
     <Compile Include="Entities\Audio\MusicAlbum.cs" />
     <Compile Include="Entities\Audio\MusicArtist.cs" />

+ 26 - 9
MediaBrowser.Controller/Providers/MediaInfo/FFProbeAudioInfoProvider.cs

@@ -96,11 +96,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
 
             if (!string.IsNullOrWhiteSpace(composer))
             {
-                // Only use the comma as a delimeter if there are no slashes or pipes. 
-                // We want to be careful not to split names that have commas in them
-                var delimeter = composer.IndexOf('/') == -1 && composer.IndexOf('|') == -1 ? new[] { ',' } : new[] { '/', '|' };
-
-                foreach (var person in composer.Split(delimeter, StringSplitOptions.RemoveEmptyEntries))
+                foreach (var person in Split(composer))
                 {
                     var name = person.Trim();
 
@@ -112,12 +108,19 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
             }
 
             audio.Album = GetDictionaryValue(tags, "album");
-            audio.Artist = GetDictionaryValue(tags, "artist");
 
-            if (!string.IsNullOrWhiteSpace(audio.Artist))
+            var artists = GetDictionaryValue(tags, "artist");
+            if (!string.IsNullOrWhiteSpace(artists))
             {
-                // Add to people too
-                audio.AddPerson(new PersonInfo {Name = audio.Artist, Type = PersonType.MusicArtist});
+                foreach (var artist in Split(artists))
+                {
+                    var name = artist.Trim();
+
+                    if (!string.IsNullOrEmpty(name))
+                    {
+                        audio.AddArtist(name);
+                    }
+                }
             }
 
             // Several different forms of albumartist
@@ -150,6 +153,20 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
             FetchStudios(audio, tags, "publisher");
         }
 
+        /// <summary>
+        /// Splits the specified val.
+        /// </summary>
+        /// <param name="val">The val.</param>
+        /// <returns>System.String[][].</returns>
+        private string[] Split(string  val)
+        {
+            // Only use the comma as a delimeter if there are no slashes or pipes. 
+            // We want to be careful not to split names that have commas in them
+            var delimeter = val.IndexOf('/') == -1 && val.IndexOf('|') == -1 ? new[] { ',' } : new[] { '/', '|' };
+
+            return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries);
+        }
+
         /// <summary>
         /// Gets the studios from the tags collection
         /// </summary>

+ 0 - 7
MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs

@@ -55,14 +55,7 @@ namespace MediaBrowser.Controller.Providers.Music
             var artist = (MusicArtist)item.Parent;
 
             var cover = artist.AlbumCovers != null ? GetValueOrDefault(artist.AlbumCovers, mbid, null) : null;
-            if (cover == null)
-            {
-                // Not there - maybe it is new since artist last refreshed so refresh it and try again
-                await artist.RefreshMetadata(cancellationToken).ConfigureAwait(false);
-                cancellationToken.ThrowIfCancellationRequested();
 
-                cover = artist.AlbumCovers != null ? GetValueOrDefault(artist.AlbumCovers, mbid, null) : null;
-            }
             if (cover == null)
             {
                 Logger.Warn("Unable to find cover art for {0}", item.Name);

+ 1 - 1
MediaBrowser.Model/DTO/BaseItemDto.cs

@@ -268,7 +268,7 @@ namespace MediaBrowser.Model.Dto
         /// Gets or sets the artist.
         /// </summary>
         /// <value>The artist.</value>
-        public string Artist { get; set; }
+        public List<string> Artists { get; set; }
 
         /// <summary>
         /// Gets or sets the album.

+ 0 - 4
MediaBrowser.Model/Entities/PersonType.cs

@@ -23,10 +23,6 @@ namespace MediaBrowser.Model.Entities
         /// </summary>
         public const string Writer = "Writer";
         /// <summary>
-        /// The music artist
-        /// </summary>
-        public const string MusicArtist = "MusicArtist";
-        /// <summary>
         /// The guest star
         /// </summary>
         public const string GuestStar = "GuestStar";

+ 12 - 0
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
@@ -551,6 +552,17 @@ namespace MediaBrowser.Server.Implementations.Library
             return GetImagesByNameItem<Genre>(ConfigurationManager.ApplicationPaths.GenrePath, name, CancellationToken.None, allowSlowProviders);
         }
 
+        /// <summary>
+        /// Gets a Genre
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
+        /// <returns>Task{Genre}.</returns>
+        public Task<Artist> GetArtist(string name, bool allowSlowProviders = false)
+        {
+            return GetImagesByNameItem<Artist>(ConfigurationManager.ApplicationPaths.ArtistsPath, name, CancellationToken.None, allowSlowProviders);
+        }
+
         /// <summary>
         /// The us culture
         /// </summary>

+ 28 - 0
MediaBrowser.Server.Implementations/ServerApplicationPaths.cs

@@ -18,6 +18,9 @@ namespace MediaBrowser.Server.Implementations
         {
         }
 #else
+/// <summary>
+/// Initializes a new instance of the <see cref="ServerApplicationPaths"/> class.
+/// </summary>
         public ServerApplicationPaths()
             : base(false)
         {
@@ -345,5 +348,30 @@ namespace MediaBrowser.Server.Implementations
                 return _downloadedImagesDataPath;
             }
         }
+
+        /// <summary>
+        /// The _music artists path
+        /// </summary>
+        private string _musicArtistsPath;
+        /// <summary>
+        /// Gets the artists path.
+        /// </summary>
+        /// <value>The artists path.</value>
+        public string ArtistsPath
+        {
+            get
+            {
+                if (_musicArtistsPath == null)
+                {
+                    _musicArtistsPath = Path.Combine(ImagesByNamePath, "Artists");
+                    if (!Directory.Exists(_musicArtistsPath))
+                    {
+                        Directory.CreateDirectory(_musicArtistsPath);
+                    }
+                }
+
+                return _musicArtistsPath;
+            }
+        }
     }
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Sorting;
 using MediaBrowser.Model.Querying;
 using System;
+using System.Linq;
 
 namespace MediaBrowser.Server.Implementations.Sorting
 {
@@ -31,7 +32,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
         {
             var audio = x as Audio;
 
-            return audio == null ? string.Empty : audio.Artist;
+            return audio == null ? string.Empty : audio.Artists.OrderBy(i => i).FirstOrDefault() ?? string.Empty;
         }
 
         /// <summary>