consolidate Artist & MusicArtist
This commit is contained in:
parent
ee1a746031
commit
17bacee089
|
@ -92,7 +92,7 @@ namespace MediaBrowser.Api
|
|||
private readonly char[] _dashReplaceChars = new[] { '?', '/' };
|
||||
private const char SlugChar = '-';
|
||||
|
||||
protected Artist GetArtist(string name, ILibraryManager libraryManager)
|
||||
protected MusicArtist GetArtist(string name, ILibraryManager libraryManager)
|
||||
{
|
||||
return libraryManager.GetArtist(DeSlugArtistName(name, libraryManager));
|
||||
}
|
||||
|
@ -147,21 +147,7 @@ namespace MediaBrowser.Api
|
|||
return name;
|
||||
}
|
||||
|
||||
return libraryManager.RootFolder.GetRecursiveChildren()
|
||||
.OfType<Audio>()
|
||||
.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
return libraryManager.GetAllArtists()
|
||||
.FirstOrDefault(i =>
|
||||
{
|
||||
i = _dashReplaceChars.Aggregate(i, (current, c) => current.Replace(c, SlugChar));
|
||||
|
|
|
@ -194,20 +194,7 @@ namespace MediaBrowser.Api.DefaultTheme
|
|||
.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
|
||||
.ToList();
|
||||
|
||||
var artists = allItems.OfType<Audio>()
|
||||
.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
var artists = _libraryManager.GetAllArtists(allItems)
|
||||
.Randomize()
|
||||
.Select(i =>
|
||||
{
|
||||
|
|
|
@ -264,16 +264,14 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
var item = _dtoService.GetItemByDtoId(request.Id);
|
||||
|
||||
var folder = item as Folder;
|
||||
|
||||
try
|
||||
{
|
||||
await item.RefreshMetadata(CancellationToken.None, forceRefresh: request.Forced).ConfigureAwait(false);
|
||||
|
||||
if (folder != null)
|
||||
if (item.IsFolder)
|
||||
{
|
||||
// Collection folders don't validate their children so we'll have to simulate that here
|
||||
var collectionFolder = folder as CollectionFolder;
|
||||
var collectionFolder = item as CollectionFolder;
|
||||
|
||||
if (collectionFolder != null)
|
||||
{
|
||||
|
@ -281,6 +279,8 @@ namespace MediaBrowser.Api
|
|||
}
|
||||
else
|
||||
{
|
||||
var folder = (Folder)item;
|
||||
|
||||
await folder.ValidateChildren(new Progress<double>(), CancellationToken.None, request.Recursive, request.Forced).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@ -303,10 +303,10 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
await child.RefreshMetadata(CancellationToken.None, forceRefresh: request.Forced).ConfigureAwait(false);
|
||||
|
||||
var folder = child as Folder;
|
||||
|
||||
if (folder != null)
|
||||
if (child.IsFolder)
|
||||
{
|
||||
var folder = (Folder)child;
|
||||
|
||||
await folder.ValidateChildren(new Progress<double>(), CancellationToken.None, request.Recursive, request.Forced).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,15 +126,6 @@ namespace MediaBrowser.Api
|
|||
UpdateItem(request, item);
|
||||
|
||||
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var musicArtist = Artist.FindMusicArtist(item, _libraryManager);
|
||||
|
||||
if (musicArtist != null)
|
||||
{
|
||||
UpdateItem(request, musicArtist);
|
||||
|
||||
await _libraryManager.UpdateItem(musicArtist, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void Post(UpdateStudio request)
|
||||
|
|
|
@ -367,7 +367,7 @@ namespace MediaBrowser.Api
|
|||
BoxSetCount = boxsets.Count,
|
||||
BookCount = books.Count,
|
||||
|
||||
UniqueTypes = items.Select(i => i.GetType().Name).Distinct().ToList()
|
||||
UniqueTypes = items.Select(i => i.GetClientTypeName()).Distinct().ToList()
|
||||
};
|
||||
|
||||
var people = items.SelectMany(i => i.People)
|
||||
|
@ -390,19 +390,7 @@ namespace MediaBrowser.Api
|
|||
people = request.UserId.HasValue ? FilterItems(people, request, request.UserId.Value).ToList() : people;
|
||||
counts.PersonCount = people.Count;
|
||||
|
||||
var artists = items.OfType<Audio>().SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
var artists = _libraryManager.GetAllArtists(items)
|
||||
.Select(i =>
|
||||
{
|
||||
try
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace MediaBrowser.Api
|
|||
IndexNumber = item.IndexNumber,
|
||||
ParentIndexNumber = item.ParentIndexNumber,
|
||||
ItemId = _dtoService.GetDtoId(item),
|
||||
Type = item.GetType().Name,
|
||||
Type = item.GetClientTypeName(),
|
||||
MediaType = item.MediaType,
|
||||
MatchedTerm = hintInfo.MatchedTerm,
|
||||
DisplayMediaType = item.DisplayMediaType,
|
||||
|
@ -187,9 +187,7 @@ namespace MediaBrowser.Api
|
|||
|
||||
result.SongCount = songs.Count;
|
||||
|
||||
result.Artists = songs
|
||||
.SelectMany(i => i.Artists)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
result.Artists = _libraryManager.GetAllArtists(songs)
|
||||
.ToArray();
|
||||
|
||||
result.AlbumArtist = songs.Select(i => i.AlbumArtist).FirstOrDefault(i => !string.IsNullOrEmpty(i));
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
/// <summary>
|
||||
/// Class ArtistsService
|
||||
/// </summary>
|
||||
public class ArtistsService : BaseItemsByNameService<Artist>
|
||||
public class ArtistsService : BaseItemsByNameService<MusicArtist>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArtistsService" /> class.
|
||||
|
@ -109,24 +109,9 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
/// <param name="request">The request.</param>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
|
||||
protected override IEnumerable<Artist> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
|
||||
protected override IEnumerable<MusicArtist> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
|
||||
{
|
||||
var itemsList = items.OfType<Audio>().ToList();
|
||||
|
||||
return itemsList
|
||||
.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
return LibraryManager.GetAllArtists(items)
|
||||
.Select(name => LibraryManager.GetArtist(name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Artist
|
||||
/// </summary>
|
||||
public class Artist : BaseItem, IItemByName, IHasMusicGenres
|
||||
{
|
||||
public Artist()
|
||||
{
|
||||
UserItemCounts = new Dictionary<Guid, ItemByNameCounts>();
|
||||
}
|
||||
|
||||
public string LastFmImageUrl { get; set; }
|
||||
public string LastFmImageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
public override string GetUserDataKey()
|
||||
{
|
||||
return GetUserDataKey(this);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Finds the music artist.
|
||||
/// </summary>
|
||||
/// <param name="artist">The artist.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <returns>MusicArtist.</returns>
|
||||
public static MusicArtist FindMusicArtist(Artist artist, ILibraryManager libraryManager)
|
||||
{
|
||||
return FindMusicArtist(artist, libraryManager.RootFolder.RecursiveChildren.OfType<MusicArtist>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the music artist.
|
||||
/// </summary>
|
||||
/// <param name="artist">The artist.</param>
|
||||
/// <param name="allMusicArtists">All music artists.</param>
|
||||
/// <returns>MusicArtist.</returns>
|
||||
public static MusicArtist FindMusicArtist(Artist artist, IEnumerable<MusicArtist> allMusicArtists)
|
||||
{
|
||||
var musicBrainzId = artist.GetProviderId(MetadataProviders.Musicbrainz);
|
||||
|
||||
return allMusicArtists.FirstOrDefault(i =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(musicBrainzId) && string.Equals(musicBrainzId, i.GetProviderId(MetadataProviders.Musicbrainz), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return string.Compare(i.Name, artist.Name, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols) == 0;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
public static string GetUserDataKey(BaseItem item)
|
||||
{
|
||||
var id = item.GetProviderId(MetadataProviders.Musicbrainz);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
return "Artist-Musicbrainz-" + id;
|
||||
}
|
||||
|
||||
return "Artist-" + item.Name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,52 @@
|
|||
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MusicArtist
|
||||
/// </summary>
|
||||
public class MusicArtist : Folder
|
||||
public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
|
||||
|
||||
public bool IsAccessedByName { get; set; }
|
||||
|
||||
public override bool IsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return !IsAccessedByName;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<BaseItem> ActualChildren
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
throw new InvalidOperationException("Artists accessed by name do not have children.");
|
||||
}
|
||||
|
||||
return base.ActualChildren;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetClientTypeName()
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
//return "Artist";
|
||||
}
|
||||
|
||||
return base.GetClientTypeName();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last fm image URL.
|
||||
/// </summary>
|
||||
|
@ -13,13 +54,35 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
public string LastFmImageUrl { get; set; }
|
||||
public string LastFmImageSize { get; set; }
|
||||
|
||||
public MusicArtist()
|
||||
{
|
||||
UserItemCounts = new Dictionary<Guid, ItemByNameCounts>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
public override string GetUserDataKey()
|
||||
{
|
||||
return Artist.GetUserDataKey(this);
|
||||
return GetUserDataKey(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
public static string GetUserDataKey(BaseItem item)
|
||||
{
|
||||
var id = item.GetProviderId(MetadataProviders.Musicbrainz);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
return "Artist-Musicbrainz-" + id;
|
||||
}
|
||||
|
||||
return "Artist-" + item.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1145,6 +1145,11 @@ namespace MediaBrowser.Controller.Entities
|
|||
return changed;
|
||||
}
|
||||
|
||||
public virtual string GetClientTypeName()
|
||||
{
|
||||
return GetType().Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the item is considered new based on user settings
|
||||
/// </summary>
|
||||
|
|
|
@ -1038,16 +1038,13 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
if (recursive && child.IsFolder)
|
||||
{
|
||||
var folder = child as Folder;
|
||||
var folder = (Folder)child;
|
||||
|
||||
if (folder != null)
|
||||
if (folder.AddChildrenToList(user, includeLinkedChildren, list, true, filter))
|
||||
{
|
||||
if (folder.AddChildrenToList(user, includeLinkedChildren, list, true, filter))
|
||||
{
|
||||
hasLinkedChildren = true;
|
||||
}
|
||||
hasLinkedChildren = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1150,14 +1147,11 @@ namespace MediaBrowser.Controller.Entities
|
|||
list.Add(child);
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
if (recursive && child.IsFolder)
|
||||
{
|
||||
var folder = child as Folder;
|
||||
var folder = (Folder)child;
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
folder.AddChildrenToList(list, true, filter);
|
||||
}
|
||||
folder.AddChildrenToList(list, true, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@ namespace MediaBrowser.Controller.Entities
|
|||
Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
|
||||
}
|
||||
|
||||
public interface IHasDualAccess : IItemByName
|
||||
{
|
||||
bool IsAccessedByName { get; }
|
||||
}
|
||||
|
||||
public static class IItemByNameExtensions
|
||||
{
|
||||
public static ItemByNameCounts GetItemByNameCounts(this IItemByName item, User user)
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace MediaBrowser.Controller.Library
|
|||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>Task{Artist}.</returns>
|
||||
Artist GetArtist(string name);
|
||||
MusicArtist GetArtist(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Studio
|
||||
|
@ -302,5 +302,18 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <param name="updateType">Type of the update.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveMetadata(BaseItem item, ItemUpdateType updateType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all artists.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{System.String}.</returns>
|
||||
IEnumerable<string> GetAllArtists();
|
||||
|
||||
/// <summary>
|
||||
/// Gets all artists.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <returns>IEnumerable{System.String}.</returns>
|
||||
IEnumerable<string> GetAllArtists(IEnumerable<BaseItem> items);
|
||||
}
|
||||
}
|
|
@ -115,7 +115,6 @@
|
|||
<Compile Include="Session\ISessionManager.cs" />
|
||||
<Compile Include="Drawing\ImageExtensions.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" />
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace MediaBrowser.Providers
|
|||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Folder && item.LocationType == LocationType.FileSystem;
|
||||
return item.IsFolder && item.LocationType == LocationType.FileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -81,11 +81,9 @@
|
|||
<Compile Include="Music\ArtistInfoFromSongProvider.cs" />
|
||||
<Compile Include="Music\ArtistProviderFromXml.cs" />
|
||||
<Compile Include="Music\FanArtAlbumProvider.cs" />
|
||||
<Compile Include="Music\FanArtArtistByNameProvider.cs" />
|
||||
<Compile Include="Music\FanArtArtistProvider.cs" />
|
||||
<Compile Include="Music\FanArtUpdatesPrescanTask.cs" />
|
||||
<Compile Include="Music\LastfmAlbumProvider.cs" />
|
||||
<Compile Include="Music\LastfmArtistByNameProvider.cs" />
|
||||
<Compile Include="Music\LastFmImageProvider.cs" />
|
||||
<Compile Include="Music\LastfmArtistProvider.cs" />
|
||||
<Compile Include="Music\LastfmBaseProvider.cs" />
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Linq;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.MediaInfo;
|
||||
|
@ -11,6 +10,7 @@ using MediaBrowser.Model.Serialization;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
@ -27,10 +27,15 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
|
||||
{
|
||||
// If song metadata has changed
|
||||
if (GetComparisonData((MusicArtist)item) != providerInfo.FileStamp)
|
||||
var artist = (MusicArtist)item;
|
||||
|
||||
if (!artist.IsAccessedByName)
|
||||
{
|
||||
return true;
|
||||
// If song metadata has changed
|
||||
if (GetComparisonData(artist) != providerInfo.FileStamp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.NeedsRefreshInternal(item, providerInfo);
|
||||
|
@ -47,7 +52,7 @@ namespace MediaBrowser.Providers.Music
|
|||
return GetComparisonData(songs);
|
||||
}
|
||||
|
||||
private Guid GetComparisonData(List<Audio> songs)
|
||||
private Guid GetComparisonData(IEnumerable<Audio> songs)
|
||||
{
|
||||
var genres = songs.SelectMany(i => i.Genres)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
|
@ -60,24 +65,27 @@ namespace MediaBrowser.Providers.Music
|
|||
{
|
||||
var artist = (MusicArtist)item;
|
||||
|
||||
BaseProviderInfo data;
|
||||
if (!item.ProviderData.TryGetValue(Id, out data))
|
||||
if (!artist.IsAccessedByName)
|
||||
{
|
||||
data = new BaseProviderInfo();
|
||||
item.ProviderData[Id] = data;
|
||||
BaseProviderInfo data;
|
||||
if (!item.ProviderData.TryGetValue(Id, out data))
|
||||
{
|
||||
data = new BaseProviderInfo();
|
||||
item.ProviderData[Id] = data;
|
||||
}
|
||||
|
||||
var songs = artist.RecursiveChildren.OfType<Audio>().ToList();
|
||||
|
||||
if (!item.LockedFields.Contains(MetadataFields.Genres))
|
||||
{
|
||||
artist.Genres = songs.SelectMany(i => i.Genres)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
data.FileStamp = GetComparisonData(songs);
|
||||
}
|
||||
|
||||
var songs = artist.RecursiveChildren.OfType<Audio>().ToList();
|
||||
|
||||
if (!item.LockedFields.Contains(MetadataFields.Genres))
|
||||
{
|
||||
artist.Genres = songs.SelectMany(i => i.Genres)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
data.FileStamp = GetComparisonData(songs);
|
||||
|
||||
SetLastRefreshed(item, DateTime.UtcNow);
|
||||
return TrueTaskResult;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.Music
|
|||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return (item is Artist || item is MusicArtist) && item.LocationType == LocationType.FileSystem;
|
||||
return (item is MusicArtist) && item.LocationType == LocationType.FileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -88,16 +88,7 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
try
|
||||
{
|
||||
var artist = item as Artist;
|
||||
|
||||
if (artist != null)
|
||||
{
|
||||
new BaseItemXmlParser<Artist>(Logger).Fetch(artist, path, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
new BaseItemXmlParser<MusicArtist>(Logger).Fetch((MusicArtist)item, path, cancellationToken);
|
||||
}
|
||||
new BaseItemXmlParser<MusicArtist>(Logger).Fetch((MusicArtist)item, path, cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
/// <summary>
|
||||
/// Class FanArtArtistByNameProvider
|
||||
/// </summary>
|
||||
public class FanArtArtistByNameProvider : FanArtArtistProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FanArtArtistByNameProvider" /> class.
|
||||
/// </summary>
|
||||
public FanArtArtistByNameProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(httpClient, logManager, configurationManager, providerManager, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Artist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [save local meta].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [save local meta]; otherwise, <c>false</c>.</value>
|
||||
protected override bool SaveLocalMeta
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.Music
|
|||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Artist || item is MusicArtist || item is MusicAlbum;
|
||||
return item is MusicArtist || item is MusicAlbum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
/// <summary>
|
||||
/// Class LastfmArtistByNameProvider
|
||||
/// </summary>
|
||||
public class LastfmArtistByNameProvider : LastfmArtistProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LastfmArtistByNameProvider" /> class.
|
||||
/// </summary>
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
public LastfmArtistByNameProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, ILibraryManager libraryManager)
|
||||
: base(jsonSerializer, httpClient, logManager, configurationManager, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [save local meta].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [save local meta]; otherwise, <c>false</c>.</value>
|
||||
protected override bool SaveLocalMeta
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Artist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the provider version.
|
||||
/// </summary>
|
||||
/// <value>The provider version.</value>
|
||||
protected override string ProviderVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return "7";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the lastfm data.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="musicBrainzId">The music brainz id.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
protected override async Task FetchLastfmData(BaseItem item, string musicBrainzId, bool force, CancellationToken cancellationToken)
|
||||
{
|
||||
var artist = (Artist)item;
|
||||
|
||||
// See if we can avoid an http request by finding the matching MusicArtist entity
|
||||
var musicArtist = Artist.FindMusicArtist(artist, LibraryManager);
|
||||
|
||||
if (musicArtist != null && !force)
|
||||
{
|
||||
LastfmHelper.ProcessArtistData(musicArtist, artist);
|
||||
}
|
||||
else
|
||||
{
|
||||
await base.FetchLastfmData(item, musicBrainzId, force, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -84,17 +84,6 @@ namespace MediaBrowser.Providers.Music
|
|||
/// <returns>Task{System.String}.</returns>
|
||||
private async Task<string> FindId(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
if (item is Artist)
|
||||
{
|
||||
// Since MusicArtists are refreshed first, try to find it from one of them
|
||||
var id = FindIdFromMusicArtistEntity(item);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// If we don't get anything, go directly to music brainz
|
||||
|
|
|
@ -39,21 +39,12 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
var musicArtist = artist as MusicArtist;
|
||||
|
||||
string imageSize;
|
||||
|
||||
if (musicArtist != null)
|
||||
{
|
||||
string imageSize;
|
||||
musicArtist.LastFmImageUrl = GetImageUrl(data, out imageSize);
|
||||
musicArtist.LastFmImageSize = imageSize;
|
||||
}
|
||||
|
||||
var artistByName = artist as Artist;
|
||||
|
||||
if (artistByName != null)
|
||||
{
|
||||
artistByName.LastFmImageUrl = GetImageUrl(data, out imageSize);
|
||||
artistByName.LastFmImageSize = imageSize;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetImageUrl(IHasLastFmImages data, out string size)
|
||||
|
@ -85,15 +76,6 @@ namespace MediaBrowser.Providers.Music
|
|||
return null;
|
||||
}
|
||||
|
||||
public static void ProcessArtistData(MusicArtist source, Artist target)
|
||||
{
|
||||
target.PremiereDate = source.PremiereDate;
|
||||
target.ProductionYear = source.ProductionYear;
|
||||
target.Tags = source.Tags.ToList();
|
||||
target.Overview = source.Overview;
|
||||
target.ProductionLocations = source.ProductionLocations.ToList();
|
||||
}
|
||||
|
||||
public static void ProcessAlbumData(BaseItem item, LastfmAlbum data)
|
||||
{
|
||||
var overview = data.wiki != null ? data.wiki.content : null;
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
public bool Supports(BaseItem item)
|
||||
{
|
||||
return item is MusicArtist || item is Artist;
|
||||
return item is MusicArtist;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
public bool Supports(BaseItem item)
|
||||
{
|
||||
return item is MusicAlbum || item is MusicArtist || item is Artist;
|
||||
return item is MusicAlbum || item is MusicArtist;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
|
||||
|
@ -41,13 +41,6 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
RemoteImageInfo info = null;
|
||||
|
||||
var artist = item as Artist;
|
||||
|
||||
if (artist != null)
|
||||
{
|
||||
info = GetInfo(artist.LastFmImageUrl, artist.LastFmImageSize);
|
||||
}
|
||||
|
||||
var album = item as MusicAlbum;
|
||||
if (album != null)
|
||||
{
|
||||
|
|
|
@ -43,7 +43,8 @@ namespace MediaBrowser.Providers.Savers
|
|||
// If new metadata has been downloaded or metadata was manually edited, proceed
|
||||
if (wasMetadataDownloaded || wasMetadataEdited)
|
||||
{
|
||||
if (item is Artist)
|
||||
var artist = item as MusicArtist;
|
||||
if (artist != null && artist.IsAccessedByName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace MediaBrowser.Providers.Savers
|
|||
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
|
||||
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
|
||||
{
|
||||
if (!(item is Folder))
|
||||
if (!item.IsFolder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
Id = GetDtoId(item),
|
||||
Name = item.Name,
|
||||
MediaType = item.MediaType,
|
||||
Type = item.GetType().Name,
|
||||
Type = item.GetClientTypeName(),
|
||||
RunTimeTicks = item.RunTimeTicks
|
||||
};
|
||||
|
||||
|
@ -932,7 +932,7 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
dto.RemoteTrailers = item.RemoteTrailers;
|
||||
}
|
||||
|
||||
dto.Type = item.GetType().Name;
|
||||
dto.Type = item.GetClientTypeName();
|
||||
dto.CommunityRating = item.CommunityRating;
|
||||
dto.VoteCount = item.VoteCount;
|
||||
|
||||
|
|
|
@ -391,10 +391,23 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <param name="item">The item.</param>
|
||||
private void UpdateItemInLibraryCache(BaseItem item)
|
||||
{
|
||||
if (!(item is IItemByName))
|
||||
if (item is IItemByName)
|
||||
{
|
||||
LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
|
||||
var hasDualAccess = item as IHasDualAccess;
|
||||
if (hasDualAccess != null)
|
||||
{
|
||||
if (hasDualAccess.IsAccessedByName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -656,16 +669,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
return GetItemByName<GameGenre>(ConfigurationManager.ApplicationPaths.GameGenrePath, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Genre
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>Task{Genre}.</returns>
|
||||
public Artist GetArtist(string name)
|
||||
{
|
||||
return GetItemByName<Artist>(ConfigurationManager.ApplicationPaths.ArtistsPath, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The us culture
|
||||
/// </summary>
|
||||
|
@ -687,6 +690,16 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
return GetItemByName<Year>(ConfigurationManager.ApplicationPaths.YearPath, value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Genre
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>Task{Genre}.</returns>
|
||||
public MusicArtist GetArtist(string name)
|
||||
{
|
||||
return GetItemByName<MusicArtist>(ConfigurationManager.ApplicationPaths.ArtistsPath, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The images by name item cache
|
||||
/// </summary>
|
||||
|
@ -697,12 +710,12 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
throw new ArgumentNullException("path");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
var validFilename = _fileSystem.GetValidFilename(name).Trim();
|
||||
|
@ -743,6 +756,20 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
private Tuple<bool, T> CreateItemByName<T>(string path, string name)
|
||||
where T : BaseItem, new()
|
||||
{
|
||||
var isArtist = typeof(T) == typeof(MusicArtist);
|
||||
|
||||
if (isArtist)
|
||||
{
|
||||
var existing = RootFolder.RecursiveChildren
|
||||
.OfType<T>()
|
||||
.FirstOrDefault(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
return new Tuple<bool, T>(false, existing);
|
||||
}
|
||||
}
|
||||
|
||||
var fileInfo = new DirectoryInfo(path);
|
||||
|
||||
var isNew = false;
|
||||
|
@ -779,6 +806,11 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
isNew = true;
|
||||
}
|
||||
|
||||
if (isArtist)
|
||||
{
|
||||
(item as MusicArtist).IsAccessedByName = true;
|
||||
}
|
||||
|
||||
// Set this now so we don't cause additional file system access during provider executions
|
||||
item.ResetResolveArgs(fileInfo);
|
||||
|
||||
|
@ -1363,16 +1395,19 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
{
|
||||
var item = ItemRepository.RetrieveItem(id);
|
||||
|
||||
var folder = item as Folder;
|
||||
|
||||
if (folder != null)
|
||||
if (item != null && item.IsFolder)
|
||||
{
|
||||
folder.LoadSavedChildren();
|
||||
LoadSavedChildren(item as Folder);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void LoadSavedChildren(Folder item)
|
||||
{
|
||||
item.LoadSavedChildren();
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
|
||||
|
||||
/// <summary>
|
||||
|
@ -1470,5 +1505,30 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
return collectionTypes.Count == 1 ? collectionTypes[0] : null;
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<string> GetAllArtists()
|
||||
{
|
||||
return GetAllArtists(RootFolder.RecursiveChildren);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllArtists(IEnumerable<BaseItem> items)
|
||||
{
|
||||
return items
|
||||
.OfType<Audio>()
|
||||
.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,21 +74,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
}));
|
||||
|
||||
// Find artists
|
||||
var artists = items.OfType<Audio>()
|
||||
.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Where(i => !string.IsNullOrEmpty(i))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
var artists = _libraryManager.GetAllArtists(items)
|
||||
.ToList();
|
||||
|
||||
foreach (var item in artists)
|
||||
|
|
|
@ -57,7 +57,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||
{
|
||||
var allItems = _libraryManager.RootFolder.GetRecursiveChildren();
|
||||
|
||||
var allMusicArtists = allItems.OfType<MusicArtist>().ToList();
|
||||
var allSongs = allItems.OfType<Audio>().ToList();
|
||||
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
|
@ -80,36 +79,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
artist.ValidateImages();
|
||||
artist.ValidateBackdrops();
|
||||
|
||||
var musicArtist = Artist.FindMusicArtist(artist, allMusicArtists);
|
||||
|
||||
if (musicArtist != null)
|
||||
{
|
||||
MergeImages(musicArtist.Images, artist.Images);
|
||||
|
||||
// Merge backdrops
|
||||
var additionalBackdrops = musicArtist
|
||||
.BackdropImagePaths
|
||||
.Except(artist.BackdropImagePaths)
|
||||
.ToList();
|
||||
|
||||
var sources = additionalBackdrops
|
||||
.Select(musicArtist.GetImageSourceInfo)
|
||||
.Where(i => i != null)
|
||||
.ToList();
|
||||
|
||||
foreach (var path in additionalBackdrops)
|
||||
{
|
||||
artist.RemoveImageSourceForPath(path);
|
||||
}
|
||||
|
||||
artist.BackdropImagePaths.AddRange(additionalBackdrops);
|
||||
artist.ImageSources.AddRange(sources);
|
||||
}
|
||||
|
||||
if (!artist.LockedFields.Contains(MetadataFields.Genres))
|
||||
// Only do this for artists accessed by name. Folder-based artists use ArtistInfoFromSongsProvider
|
||||
if (artist.IsAccessedByName && !artist.LockedFields.Contains(MetadataFields.Genres))
|
||||
{
|
||||
// Avoid implicitly captured closure
|
||||
var artist1 = artist;
|
||||
|
@ -145,7 +116,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||
/// <param name="artist">The artist.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="allItems">All items.</param>
|
||||
private void SetItemCounts(Artist artist, Guid? userId, IEnumerable<IHasArtist> allItems)
|
||||
private void SetItemCounts(MusicArtist artist, Guid? userId, IEnumerable<IHasArtist> allItems)
|
||||
{
|
||||
var name = artist.Name;
|
||||
|
||||
|
@ -170,25 +141,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges the images.
|
||||
/// </summary>
|
||||
/// <param name="source">The source.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
private void MergeImages(Dictionary<ImageType, string> source, Dictionary<ImageType, string> target)
|
||||
{
|
||||
foreach (var key in source.Keys
|
||||
.Where(k => !target.ContainsKey(k)))
|
||||
{
|
||||
string path;
|
||||
|
||||
if (source.TryGetValue(key, out path))
|
||||
{
|
||||
target[key] = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all artists.
|
||||
/// </summary>
|
||||
|
@ -196,25 +148,12 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <returns>Task{Artist[]}.</returns>
|
||||
private async Task<List<Artist>> GetAllArtists(IEnumerable<Audio> allSongs, CancellationToken cancellationToken, IProgress<double> progress)
|
||||
private async Task<List<MusicArtist>> GetAllArtists(IEnumerable<Audio> allSongs, CancellationToken cancellationToken, IProgress<double> progress)
|
||||
{
|
||||
var allArtists = allSongs
|
||||
.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
var allArtists = _libraryManager.GetAllArtists(allSongs)
|
||||
.ToList();
|
||||
|
||||
var returnArtists = new List<Artist>(allArtists.Count);
|
||||
var returnArtists = new List<MusicArtist>(allArtists.Count);
|
||||
|
||||
var numComplete = 0;
|
||||
var numArtists = allArtists.Count;
|
||||
|
|
|
@ -508,7 +508,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
return new[] { GetSavePathForItemInMixedFolder(item, type, string.Empty, extension) };
|
||||
}
|
||||
|
||||
if (item is MusicAlbum || item is Artist || item is MusicArtist)
|
||||
if (item is MusicAlbum || item is MusicArtist)
|
||||
{
|
||||
return new[] { Path.Combine(item.MetaLocation, "folder" + extension) };
|
||||
}
|
||||
|
|
|
@ -495,6 +495,7 @@ namespace MediaBrowser.WebDashboard.Api
|
|||
"moviestudios.js",
|
||||
"movietrailers.js",
|
||||
"musicalbums.js",
|
||||
"musicalbumartists.js",
|
||||
"musicartists.js",
|
||||
"musicgenres.js",
|
||||
"musicrecommended.js",
|
||||
|
|
|
@ -80,6 +80,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="ApiClient.js" />
|
||||
<Content Include="dashboard-ui\musicalbumartists.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\allusersettings.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -341,6 +344,9 @@
|
|||
<Content Include="dashboard-ui\livetvrecordings.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\musicalbumartists.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\livetvchannels.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
|
Loading…
Reference in New Issue
Block a user