Exemple #1
0
        private ItemsResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func <BaseItem, List <PersonInfo>, List <PersonInfo>, BaseItem, int> getSimilarityScore)
        {
            var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;

            var item = string.IsNullOrEmpty(request.Id) ?
                       (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
                        _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);

            var inputItems = _libraryManager.GetArtists(user.RootFolder.GetRecursiveChildren(user, i => i is IHasArtist).OfType <IHasArtist>());

            var list = inputItems.ToList();

            var items = SimilarItemsHelper.GetSimilaritems(item, _libraryManager, list, getSimilarityScore).ToList();

            IEnumerable <BaseItem> returnItems = items;

            if (request.Limit.HasValue)
            {
                returnItems = returnItems.Take(request.Limit.Value);
            }

            var dtoOptions = GetDtoOptions(request);

            var result = new ItemsResult
            {
                Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(),

                TotalRecordCount = items.Count
            };

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Runs the specified progress.
        /// </summary>
        /// <param name="progress">The progress.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        public async Task Run(IProgress <double> progress, CancellationToken cancellationToken)
        {
            var allSongs = _libraryManager.RootFolder
                           .GetRecursiveChildren(i => !i.IsFolder && (i is IHasArtist))
                           .Cast <IHasArtist>()
                           .ToList();

            var allArtists = _libraryManager.GetArtists(allSongs).ToList();

            var numComplete = 0;
            var numArtists  = allArtists.Count;

            foreach (var artistItem in allArtists)
            {
                cancellationToken.ThrowIfCancellationRequested();

                try
                {
                    await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                }
                catch (IOException ex)
                {
                    _logger.ErrorException("Error validating Artist {0}", ex, artistItem.Name);
                }

                // Update progress
                numComplete++;
                double percent = numComplete;
                percent /= numArtists;

                progress.Report(100 * percent);
            }
        }
Exemple #3
0
        private QueryResult <ServerItem> GetMusicArtists(BaseItem parent, User user, InternalItemsQuery query)
        {
            var artists = _libraryManager.GetArtists(new InternalItemsQuery(user)
            {
                AncestorIds = new[] { parent.Id.ToString("N") },
                StartIndex  = query.StartIndex,
                Limit       = query.Limit
            });

            var result = new QueryResult <BaseItem>
            {
                TotalRecordCount = artists.TotalRecordCount,
                Items            = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length)
            };

            return(ToResult(result));
        }
        private QueryResult <BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, string[] includeItemTypes)
        {
            var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;

            var item = string.IsNullOrEmpty(request.Id) ?
                       (!request.UserId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() :
                        _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);

            var dtoOptions = GetDtoOptions(_authContext, request);

            var query = new InternalItemsQuery(user)
            {
                Limit                  = request.Limit,
                IncludeItemTypes       = includeItemTypes,
                SimilarTo              = item,
                DtoOptions             = dtoOptions,
                EnableTotalRecordCount = false
            };

            // ExcludeArtistIds
            if (!string.IsNullOrEmpty(request.ExcludeArtistIds))
            {
                query.ExcludeArtistIds = BaseApiService.GetGuids(request.ExcludeArtistIds);
            }

            List <BaseItem> itemsResult;

            if (item is MusicArtist)
            {
                query.IncludeItemTypes = Array.Empty <string>();

                itemsResult = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
            }
            else
            {
                itemsResult = _libraryManager.GetItemList(query);
            }

            var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);

            var result = new QueryResult <BaseItemDto>
            {
                Items = returnList,

                TotalRecordCount = itemsResult.Count
            };

            return(result);
        }
        public ActionResult <QueryResult <BaseItemDto> > GetArtists(
            [FromQuery] double?minCommunityRating,
            [FromQuery] int?startIndex,
            [FromQuery] int?limit,
            [FromQuery] string?searchTerm,
            [FromQuery] string?parentId,
            [FromQuery] string?fields,
            [FromQuery] string?excludeItemTypes,
            [FromQuery] string?includeItemTypes,
            [FromQuery] string?filters,
            [FromQuery] bool?isFavorite,
            [FromQuery] string?mediaTypes,
            [FromQuery] string?genres,
            [FromQuery] string?genreIds,
            [FromQuery] string?officialRatings,
            [FromQuery] string?tags,
            [FromQuery] string?years,
            [FromQuery] bool?enableUserData,
            [FromQuery] int?imageTypeLimit,
            [FromQuery] string?enableImageTypes,
            [FromQuery] string?person,
            [FromQuery] string?personIds,
            [FromQuery] string?personTypes,
            [FromQuery] string?studios,
            [FromQuery] string?studioIds,
            [FromQuery] Guid?userId,
            [FromQuery] string?nameStartsWithOrGreater,
            [FromQuery] string?nameStartsWith,
            [FromQuery] string?nameLessThan,
            [FromQuery] bool?enableImages           = true,
            [FromQuery] bool enableTotalRecordCount = true)
        {
            var dtoOptions = new DtoOptions()
                             .AddItemFields(fields)
                             .AddClientFields(Request)
                             .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);

            User?    user = null;
            BaseItem parentItem;

            if (userId.HasValue && !userId.Equals(Guid.Empty))
            {
                user       = _userManager.GetUserById(userId.Value);
                parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId);
            }
            else
            {
                parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.RootFolder : _libraryManager.GetItemById(parentId);
            }

            var excludeItemTypesArr = RequestHelpers.Split(excludeItemTypes, ',', true);
            var includeItemTypesArr = RequestHelpers.Split(includeItemTypes, ',', true);
            var mediaTypesArr       = RequestHelpers.Split(mediaTypes, ',', true);

            var query = new InternalItemsQuery(user)
            {
                ExcludeItemTypes        = excludeItemTypesArr,
                IncludeItemTypes        = includeItemTypesArr,
                MediaTypes              = mediaTypesArr,
                StartIndex              = startIndex,
                Limit                   = limit,
                IsFavorite              = isFavorite,
                NameLessThan            = nameLessThan,
                NameStartsWith          = nameStartsWith,
                NameStartsWithOrGreater = nameStartsWithOrGreater,
                Tags                   = RequestHelpers.Split(tags, ',', true),
                OfficialRatings        = RequestHelpers.Split(officialRatings, ',', true),
                Genres                 = RequestHelpers.Split(genres, ',', true),
                GenreIds               = RequestHelpers.GetGuids(genreIds),
                StudioIds              = RequestHelpers.GetGuids(studioIds),
                Person                 = person,
                PersonIds              = RequestHelpers.GetGuids(personIds),
                PersonTypes            = RequestHelpers.Split(personTypes, ',', true),
                Years                  = RequestHelpers.Split(years, ',', true).Select(int.Parse).ToArray(),
                MinCommunityRating     = minCommunityRating,
                DtoOptions             = dtoOptions,
                SearchTerm             = searchTerm,
                EnableTotalRecordCount = enableTotalRecordCount
            };

            if (!string.IsNullOrWhiteSpace(parentId))
            {
                if (parentItem is Folder)
                {
                    query.AncestorIds = new[] { new Guid(parentId) };
                }
                else
                {
                    query.ItemIds = new[] { new Guid(parentId) };
                }
            }

            // Studios
            if (!string.IsNullOrEmpty(studios))
            {
                query.StudioIds = studios.Split('|').Select(i =>
                {
                    try
                    {
                        return(_libraryManager.GetStudio(i));
                    }
                    catch
                    {
                        return(null);
                    }
                }).Where(i => i != null).Select(i => i !.Id).ToArray();
            }

            foreach (var filter in RequestHelpers.GetFilters(filters))
            {
                switch (filter)
                {
                case ItemFilter.Dislikes:
                    query.IsLiked = false;
                    break;

                case ItemFilter.IsFavorite:
                    query.IsFavorite = true;
                    break;

                case ItemFilter.IsFavoriteOrLikes:
                    query.IsFavoriteOrLiked = true;
                    break;

                case ItemFilter.IsFolder:
                    query.IsFolder = true;
                    break;

                case ItemFilter.IsNotFolder:
                    query.IsFolder = false;
                    break;

                case ItemFilter.IsPlayed:
                    query.IsPlayed = true;
                    break;

                case ItemFilter.IsResumable:
                    query.IsResumable = true;
                    break;

                case ItemFilter.IsUnplayed:
                    query.IsPlayed = false;
                    break;

                case ItemFilter.Likes:
                    query.IsLiked = true;
                    break;
                }
            }

            var result = _libraryManager.GetArtists(query);

            var dtos = result.Items.Select(i =>
            {
                var(baseItem, itemCounts) = i;
                var dto = _dtoService.GetItemByNameDto(baseItem, dtoOptions, null, user);

                if (!string.IsNullOrWhiteSpace(includeItemTypes))
                {
                    dto.ChildCount   = itemCounts.ItemCount;
                    dto.ProgramCount = itemCounts.ProgramCount;
                    dto.SeriesCount  = itemCounts.SeriesCount;
                    dto.EpisodeCount = itemCounts.EpisodeCount;
                    dto.MovieCount   = itemCounts.MovieCount;
                    dto.TrailerCount = itemCounts.TrailerCount;
                    dto.AlbumCount   = itemCounts.AlbumCount;
                    dto.SongCount    = itemCounts.SongCount;
                    dto.ArtistCount  = itemCounts.ArtistCount;
                }

                return(dto);
            });

            return(new QueryResult <BaseItemDto>
            {
                Items = dtos.ToArray(),
                TotalRecordCount = result.TotalRecordCount
            });
        }
Exemple #6
0
        private QueryResult <BaseItemDto> GetSimilarItemsResult(
            BaseItem item,
            string?excludeArtistIds,
            Guid?userId,
            int?limit,
            string?fields,
            string[] includeItemTypes,
            bool isMovie)
        {
            var user = userId.HasValue && !userId.Equals(Guid.Empty)
                ? _userManager.GetUserById(userId.Value)
                : null;
            var dtoOptions = new DtoOptions()
                             .AddItemFields(fields)
                             .AddClientFields(Request);

            var query = new InternalItemsQuery(user)
            {
                Limit                    = limit,
                IncludeItemTypes         = includeItemTypes,
                IsMovie                  = isMovie,
                SimilarTo                = item,
                DtoOptions               = dtoOptions,
                EnableTotalRecordCount   = !isMovie,
                EnableGroupByMetadataKey = isMovie
            };

            // ExcludeArtistIds
            if (!string.IsNullOrEmpty(excludeArtistIds))
            {
                query.ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds);
            }

            List <BaseItem> itemsResult;

            if (isMovie)
            {
                var itemTypes = new List <string> {
                    nameof(MediaBrowser.Controller.Entities.Movies.Movie)
                };
                if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
                {
                    itemTypes.Add(nameof(Trailer));
                    itemTypes.Add(nameof(LiveTvProgram));
                }

                query.IncludeItemTypes = itemTypes.ToArray();
                itemsResult            = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
            }
            else if (item is MusicArtist)
            {
                query.IncludeItemTypes = Array.Empty <string>();

                itemsResult = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
            }
            else
            {
                itemsResult = _libraryManager.GetItemList(query);
            }

            var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);

            var result = new QueryResult <BaseItemDto>
            {
                Items            = returnList,
                TotalRecordCount = itemsResult.Count
            };

            return(result);
        }
        public ActionResult <QueryResult <BaseItemDto> > GetArtists(
            [FromQuery] double?minCommunityRating,
            [FromQuery] int?startIndex,
            [FromQuery] int?limit,
            [FromQuery] string?searchTerm,
            [FromQuery] Guid?parentId,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
            [FromQuery] bool?isFavorite,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
            [FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] genreIds,
            [FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] officialRatings,
            [FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] tags,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] int[] years,
            [FromQuery] bool?enableUserData,
            [FromQuery] int?imageTypeLimit,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
            [FromQuery] string?person,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] personIds,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] personTypes,
            [FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] studios,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] studioIds,
            [FromQuery] Guid?userId,
            [FromQuery] string?nameStartsWithOrGreater,
            [FromQuery] string?nameStartsWith,
            [FromQuery] string?nameLessThan,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
            [FromQuery] bool?enableImages           = true,
            [FromQuery] bool enableTotalRecordCount = true)
        {
            var dtoOptions = new DtoOptions {
                Fields = fields
            }
            .AddClientFields(Request)
            .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);

            User?    user       = null;
            BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);

            if (userId.HasValue && !userId.Equals(Guid.Empty))
            {
                user = _userManager.GetUserById(userId.Value);
            }

            var query = new InternalItemsQuery(user)
            {
                ExcludeItemTypes        = excludeItemTypes,
                IncludeItemTypes        = includeItemTypes,
                MediaTypes              = mediaTypes,
                StartIndex              = startIndex,
                Limit                   = limit,
                IsFavorite              = isFavorite,
                NameLessThan            = nameLessThan,
                NameStartsWith          = nameStartsWith,
                NameStartsWithOrGreater = nameStartsWithOrGreater,
                Tags                   = tags,
                OfficialRatings        = officialRatings,
                Genres                 = genres,
                GenreIds               = genreIds,
                StudioIds              = studioIds,
                Person                 = person,
                PersonIds              = personIds,
                PersonTypes            = personTypes,
                Years                  = years,
                MinCommunityRating     = minCommunityRating,
                DtoOptions             = dtoOptions,
                SearchTerm             = searchTerm,
                EnableTotalRecordCount = enableTotalRecordCount,
                OrderBy                = RequestHelpers.GetOrderBy(sortBy, sortOrder)
            };

            if (parentId.HasValue)
            {
                if (parentItem is Folder)
                {
                    query.AncestorIds = new[] { parentId.Value };
                }
                else
                {
                    query.ItemIds = new[] { parentId.Value };
                }
            }

            // Studios
            if (studios.Length != 0)
            {
                query.StudioIds = studios.Select(i =>
                {
                    try
                    {
                        return(_libraryManager.GetStudio(i));
                    }
                    catch
                    {
                        return(null);
                    }
                }).Where(i => i != null).Select(i => i !.Id).ToArray();
            }

            foreach (var filter in filters)
            {
                switch (filter)
                {
                case ItemFilter.Dislikes:
                    query.IsLiked = false;
                    break;

                case ItemFilter.IsFavorite:
                    query.IsFavorite = true;
                    break;

                case ItemFilter.IsFavoriteOrLikes:
                    query.IsFavoriteOrLiked = true;
                    break;

                case ItemFilter.IsFolder:
                    query.IsFolder = true;
                    break;

                case ItemFilter.IsNotFolder:
                    query.IsFolder = false;
                    break;

                case ItemFilter.IsPlayed:
                    query.IsPlayed = true;
                    break;

                case ItemFilter.IsResumable:
                    query.IsResumable = true;
                    break;

                case ItemFilter.IsUnplayed:
                    query.IsPlayed = false;
                    break;

                case ItemFilter.Likes:
                    query.IsLiked = true;
                    break;
                }
            }

            var result = _libraryManager.GetArtists(query);

            var dtos = result.Items.Select(i =>
            {
                var(baseItem, itemCounts) = i;
                var dto = _dtoService.GetItemByNameDto(baseItem, dtoOptions, null, user);

                if (includeItemTypes.Length != 0)
                {
                    dto.ChildCount   = itemCounts.ItemCount;
                    dto.ProgramCount = itemCounts.ProgramCount;
                    dto.SeriesCount  = itemCounts.SeriesCount;
                    dto.EpisodeCount = itemCounts.EpisodeCount;
                    dto.MovieCount   = itemCounts.MovieCount;
                    dto.TrailerCount = itemCounts.TrailerCount;
                    dto.AlbumCount   = itemCounts.AlbumCount;
                    dto.SongCount    = itemCounts.SongCount;
                    dto.ArtistCount  = itemCounts.ArtistCount;
                }

                return(dto);
            });

            return(new QueryResult <BaseItemDto>(
                       query.StartIndex,
                       result.TotalRecordCount,
                       dtos.ToArray()));
        }
Exemple #8
0
        /// <summary>
        /// Gets the search hints.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="user">The user.</param>
        /// <returns>IEnumerable{SearchHintResult}.</returns>
        /// <exception cref="System.ArgumentNullException">searchTerm</exception>
        private Task <IEnumerable <SearchHintInfo> > GetSearchHints(SearchQuery query, User user)
        {
            var searchTerm = query.SearchTerm;

            if (searchTerm != null)
            {
                searchTerm = searchTerm.Trim().RemoveDiacritics();
            }

            if (string.IsNullOrWhiteSpace(searchTerm))
            {
                throw new ArgumentNullException("searchTerm");
            }

            var terms = GetWords(searchTerm);

            var excludeItemTypes = query.ExcludeItemTypes.ToList();
            var includeItemTypes = (query.IncludeItemTypes ?? new string[] { }).ToList();

            excludeItemTypes.Add(typeof(Year).Name);
            excludeItemTypes.Add(typeof(Folder).Name);

            if (query.IncludeGenres && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Genre", StringComparer.OrdinalIgnoreCase)))
            {
                if (!query.IncludeMedia)
                {
                    AddIfMissing(includeItemTypes, typeof(Genre).Name);
                    AddIfMissing(includeItemTypes, typeof(GameGenre).Name);
                    AddIfMissing(includeItemTypes, typeof(MusicGenre).Name);
                }
            }
            else
            {
                AddIfMissing(excludeItemTypes, typeof(Genre).Name);
                AddIfMissing(excludeItemTypes, typeof(GameGenre).Name);
                AddIfMissing(excludeItemTypes, typeof(MusicGenre).Name);
            }

            if (query.IncludePeople && (includeItemTypes.Count == 0 || includeItemTypes.Contains("People", StringComparer.OrdinalIgnoreCase) || includeItemTypes.Contains("Person", StringComparer.OrdinalIgnoreCase)))
            {
                if (!query.IncludeMedia)
                {
                    AddIfMissing(includeItemTypes, typeof(Person).Name);
                }
            }
            else
            {
                AddIfMissing(excludeItemTypes, typeof(Person).Name);
            }

            if (query.IncludeStudios && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Studio", StringComparer.OrdinalIgnoreCase)))
            {
                if (!query.IncludeMedia)
                {
                    AddIfMissing(includeItemTypes, typeof(Studio).Name);
                }
            }
            else
            {
                AddIfMissing(excludeItemTypes, typeof(Studio).Name);
            }

            if (query.IncludeArtists && (includeItemTypes.Count == 0 || includeItemTypes.Contains("MusicArtist", StringComparer.OrdinalIgnoreCase)))
            {
                if (!query.IncludeMedia)
                {
                    AddIfMissing(includeItemTypes, typeof(MusicArtist).Name);
                }
            }
            else
            {
                AddIfMissing(excludeItemTypes, typeof(MusicArtist).Name);
            }

            AddIfMissing(excludeItemTypes, typeof(CollectionFolder).Name);
            AddIfMissing(excludeItemTypes, typeof(Folder).Name);
            var mediaTypes = query.MediaTypes.ToList();

            if (includeItemTypes.Count > 0)
            {
                excludeItemTypes.Clear();
                mediaTypes.Clear();
            }

            var searchQuery = new InternalItemsQuery(user)
            {
                NameContains       = searchTerm,
                ExcludeItemTypes   = excludeItemTypes.ToArray(excludeItemTypes.Count),
                IncludeItemTypes   = includeItemTypes.ToArray(includeItemTypes.Count),
                Limit              = query.Limit,
                IncludeItemsByName = string.IsNullOrWhiteSpace(query.ParentId),
                ParentId           = string.IsNullOrWhiteSpace(query.ParentId) ? (Guid?)null : new Guid(query.ParentId),
                OrderBy            = new[] { new Tuple <string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) },
                Recursive          = true,

                IsKids     = query.IsKids,
                IsMovie    = query.IsMovie,
                IsNews     = query.IsNews,
                IsSeries   = query.IsSeries,
                IsSports   = query.IsSports,
                MediaTypes = mediaTypes.ToArray(),

                DtoOptions = new DtoOptions
                {
                    Fields = new ItemFields[]
                    {
                        ItemFields.AirTime,
                        ItemFields.DateCreated,
                        ItemFields.ChannelInfo
                    }
                }
            };

            List <BaseItem> mediaItems;

            if (searchQuery.IncludeItemTypes.Length == 1 && string.Equals(searchQuery.IncludeItemTypes[0], "MusicArtist", StringComparison.OrdinalIgnoreCase))
            {
                if (searchQuery.ParentId.HasValue)
                {
                    searchQuery.AncestorIds = new string[] { searchQuery.ParentId.Value.ToString("N") };
                }
                searchQuery.ParentId           = null;
                searchQuery.IncludeItemsByName = true;
                searchQuery.IncludeItemTypes   = new string[] { };
                mediaItems = _libraryManager.GetArtists(searchQuery).Items.Select(i => i.Item1).ToList();
            }
            else
            {
                mediaItems = _libraryManager.GetItemList(searchQuery);
            }

            var returnValue = mediaItems.Select(item =>
            {
                var index = GetIndex(item.Name, searchTerm, terms);

                return(new Tuple <BaseItem, string, int>(item, index.Item1, index.Item2));
            }).OrderBy(i => i.Item3).ThenBy(i => i.Item1.SortName).Select(i => new SearchHintInfo
            {
                Item        = i.Item1,
                MatchedTerm = i.Item2
            });

            return(Task.FromResult(returnValue));
        }
Exemple #9
0
        private async Task SyncDataforUserByArtistBulk(User user, IProgress <double> progress, CancellationToken cancellationToken, double maxProgress, double progressOffset)
        {
            LastfmUser lastFmUser = UserHelpers.GetUser(user);

            if (!lastFmUser.Options.SyncFavourites)
            {
                return;
            }

            _logger.LogInformation("Syncing LastFM favourties for {0}", user.Username);

            List <MusicArtist> artists = _libraryManager.GetArtists(new InternalItemsQuery(user))
                                         .Items
                                         .Select(i => i.Item1)
                                         .Cast <MusicArtist>()
                                         .ToList();

            int matchedSongs = 0;

            // Fetch the user's loved tracks from LastFM API.
            List <LastfmLovedTrack> lovedTracks = await GetLovedTracksLibrary(lastFmUser, progress, cancellationToken, maxProgress, progressOffset);

            if (lovedTracks.Count == 0)
            {
                _logger.LogInformation("User {0} has no loved tracks in last.fm", user.Username);
                return;
            }

            // Group the list of loved tracks by artist
            List <IGrouping <string, LastfmLovedTrack> > groupedLovedTracks = lovedTracks.GroupBy(t => t.Artist.MusicBrainzId).ToList();

            // Iterate over each artist in user's library
            // iterate over each song by artist
            // for each song, compare against the list of song/track in the lastfm loved track list
            foreach (MusicArtist artist in artists)
            {
                cancellationToken.ThrowIfCancellationRequested();

                string artistMBid = Helpers.GetMusicBrainzArtistId(artist);
                if (artistMBid == null)
                {
                    continue;
                }

                if (groupedLovedTracks.FirstOrDefault(t => t.Key.Equals(artistMBid)) == null || !groupedLovedTracks.FirstOrDefault(t => t.Key.Equals(artistMBid)).Any())
                {
                    continue;
                }

                _logger.LogDebug("Found {0} LastFM lovedtracks for {1}",
                                 groupedLovedTracks.FirstOrDefault(t => t.Key.Equals(artistMBid)).ToList().Count,
                                 artist.Name);
                // Loop through each song
                foreach (Audio song in artist.GetTaggedItems(new InternalItemsQuery(user)
                {
                    IncludeItemTypes = new[] { "Audio" },
                    EnableTotalRecordCount = false
                }).OfType <Audio>().ToList())
                {
                    LastfmLovedTrack matchedSong = Helpers.FindMatchedLastfmSong(groupedLovedTracks.FirstOrDefault(t => t.Key.Equals(artistMBid)).ToList(), song);

                    if (matchedSong == null)
                    {
                        continue;
                    }

                    // We have found a match
                    matchedSongs++;

                    var userData = _userDataManager.GetUserData(user, song);
                    userData.IsFavorite = true;
                    _userDataManager.SaveUserData(user, song, userData, UserDataSaveReason.UpdateUserRating, cancellationToken);
                    _logger.LogDebug("Found library match for {0} = {1}", song.Name, matchedSong.Name);
                }
            }

            _logger.LogInformation("Finished Last.fm lovedTracks sync for {0}. Matched Songs: {2}", user.Username, matchedSongs);
        }
Exemple #10
0
        private async Task SyncDataforUserByArtistBulk(User user, IProgress <double> progress, CancellationToken cancellationToken, double maxProgress, double progressOffset)
        {
            var artists = _libraryManager.GetArtists(new InternalItemsQuery(user))
                          .Items
                          .Select(i => i.Item1)
                          .Cast <MusicArtist>()
                          .ToList();

            var lastFmUser = UserHelpers.GetUser(user);

            var totalSongs   = 0;
            var matchedSongs = 0;

            //Get loved tracks
            var lovedTracksReponse = await _apiClient.GetLovedTracks(lastFmUser).ConfigureAwait(false);

            var hasLovedTracks = lovedTracksReponse.HasLovedTracks();

            var trackCount = 0;

            //Loop through each artist
            foreach (var artist in artists)
            {
                cancellationToken.ThrowIfCancellationRequested();

                //Get all the tracks by the current artist
                var artistMBid = Helpers.GetMusicBrainzArtistId(artist);

                if (artistMBid == null)
                {
                    continue;
                }

                var allArtistTracks = await GetArtistTracks(lastFmUser, artist, progress, cancellationToken, maxProgress, progressOffset).ConfigureAwait(false);

                //Get the tracks from lastfm for the current artist
                var artistTracks = allArtistTracks.Where(t => t.Artist.MusicBrainzId.Equals(artistMBid));
                trackCount += artistTracks.Count();

                if (artistTracks == null || !artistTracks.Any())
                {
                    Plugin.Logger.Info("{0} has no tracks in last.fm library for {1}", user.Name, artist.Name);
                    continue;
                }

                var artistTracksList = artistTracks.ToList();

                Plugin.Logger.Info("Found {0} tracks in last.fm library for {1}", artistTracksList.Count, artist.Name);

                //Loop through each song
                foreach (var song in artist.GetTaggedMediaItems(new InternalItemsQuery
                {
                    IncludeItemTypes = new[] { "Audio" }
                }).OfType <Audio>().ToList())
                {
                    totalSongs++;

                    var matchedSong = Helpers.FindMatchedLastfmSong(artistTracksList, song);

                    if (matchedSong == null)
                    {
                        continue;
                    }

                    //We have found a match
                    matchedSongs++;

                    Plugin.Logger.Debug("Found match for {0} = {1}", song.Name, matchedSong.Name);

                    var userData = _userDataManager.GetUserData(user, song);

                    //Check if its a favourite track
                    if (hasLovedTracks && lastFmUser.Options.SyncFavourites)
                    {
                        //Use MBID if set otherwise match on song name
                        var favourited = lovedTracksReponse.LovedTracks.Tracks.Any(
                            t => String.IsNullOrWhiteSpace(t.MusicBrainzId)
                                ? StringHelper.IsLike(t.Name, matchedSong.Name)
                                : t.MusicBrainzId.Equals(matchedSong.MusicBrainzId)
                            );

                        userData.IsFavorite = favourited;

                        Plugin.Logger.Debug("{0} Favourite: {1}", song.Name, favourited);
                    }

                    //Update the play count

                    /*if (matchedSong.PlayCount > 0)
                     * {
                     *  userData.Played = true;
                     *  userData.PlayCount = Math.Max(userData.PlayCount, matchedSong.PlayCount);
                     * }
                     * else
                     * {
                     *  userData.Played = false;
                     *  userData.PlayCount = 0;
                     *  userData.LastPlayedDate = null;
                     * }*/

                    _userDataManager.SaveUserData(user.InternalId, song, userData, UserDataSaveReason.UpdateUserRating, cancellationToken);
                }
            }

            //The percentage might not actually be correct but I'm pretty tired and don't want to think about it
            Plugin.Logger.Info("Finished import Last.fm library for {0}. Local Songs: {1} | Last.fm Songs: {2} | Matched Songs: {3} | {4}% match rate",
                               user.Name, totalSongs, trackCount, matchedSongs, Math.Round(((double)matchedSongs / Math.Min(trackCount, totalSongs)) * 100));
        }