Beispiel #1
0
        /// <summary>
        /// Add folder to Library asynchronously.
        /// </summary>
        /// <param name="queryResult">The query result after querying in a specific folder.</param>
        /// <returns></returns>
        public async Task AddFolderToLibraryAsync(StorageFileQueryResult queryResult)
        {
            if (queryResult != null)
            {
                //so that no new event is raised. We want to focus on loading.
                isLibraryLoading = true;

                //this is a temporary list to collect all the processed Mediafiles. We use List because it is fast. Faster than using ObservableCollection directly because of the events firing on every add.
                var tempList = new List <Mediafile>();

                //'count' is for total files got after querying.
                var count = await queryResult.GetItemCountAsync().AsTask().ConfigureAwait(false);

                if (count == 0)
                {
                    string error = "No songs found!";
                    BLogger.Logger.Error("No songs were found!");
                    await NotificationManager.ShowMessageAsync(error);

                    return;
                }

                AlbumArtistViewModel model   = new AlbumArtistViewModel();
                LibraryService       service = new LibraryService(new DatabaseService());
                int failedCount = 0;
                //'i' is a variable for the index of currently processing file
                short i = 0;

                try
                {
                    foreach (StorageFile file in await queryResult.GetFilesAsync().AsTask().ConfigureAwait(false))
                    {
                        try
                        {
                            //A null Mediafile which we will use afterwards.
                            Mediafile mp3file = null;
                            i++; //Notice here that we are increasing the 'i' variable by one for each file.
                                 //we send a message to anyone listening relaying that song count has to be updated.
                            Messenger.Instance.NotifyColleagues(MessageTypes.MSG_UPDATE_SONG_COUNT, i);
                            await Task.Run(async() =>
                            {
                                //here we load into 'mp3file' variable our processed Song. This is a long process, loading all the properties and the album art.
                                mp3file            = await CreateMediafile(file, false); //the core of the whole method.
                                mp3file.FolderPath = Path.GetDirectoryName(file.Path);
                                await SaveSingleFileAlbumArtAsync(mp3file).ConfigureAwait(false);
                            });

                            //this methods notifies the Player that one song is loaded. We use both 'count' and 'i' variable here to report current progress.
                            await NotificationManager.ShowMessageAsync(i.ToString() + "\\" + count.ToString() + " Song(s) Loaded");

                            //we then add the processed song into 'tempList' very silently without anyone noticing and hence, efficiently.
                            tempList.Add(mp3file);
                        }
                        catch (Exception ex)
                        {
                            BLogger.Logger.Error("Loading of a song in folder failed.", ex);
                            //we catch and report any exception without distrubing the 'foreach flow'.
                            await NotificationManager.ShowMessageAsync(ex.Message + " || Occured on: " + file.Path);

                            failedCount++;
                        }
                    }
                    BLogger.Logger.Info(string.Format("{0} out of {1} songs loaded. {2} is iteration count.", tempList.Count, count, i));
                }
                catch (Exception ex)
                {
                    BLogger.Logger.Error("Failed to import songs in library.", ex);
                    string message1 = ex.Message + "||" + ex.InnerException;
                    await NotificationManager.ShowMessageAsync(message1);
                }
                //now we add 100 songs directly into our TracksCollection which is an ObservableCollection. This is faster because only one event is invoked.
                tempList.Sort();
                TracksCollection.AddRange(tempList);
                //now we load 100 songs into database.
                service.AddMediafiles(tempList);
                Messenger.Instance.NotifyColleagues(MessageTypes.MSG_ADD_ALBUMS, tempList);
                Messenger.Instance.NotifyColleagues(MessageTypes.MSG_UPDATE_SONG_COUNT, "Done!");
                //we send the message to load the album. This comes first so there is enough time to load all albums before new list come up.
                isLibraryLoading = false;
                string message = string.Format("Songs successfully imported! Total Songs: {0}; Failed: {1}; Loaded: {2}", count, failedCount, i);

                BLogger.Logger.Info(message);
                await NotificationManager.ShowMessageAsync(message);

                service.Dispose();
                model = null;
                await DeleteDuplicates(tempList).ConfigureAwait(false);

                tempList.Clear();
            }
        }
        /// <summary>
        /// Add folder to Library asynchronously.
        /// </summary>
        /// <param name="queryResult">The query result after querying in a specific folder.</param>
        /// <returns></returns>
        public static async Task AddFolderToLibraryAsync(StorageFileQueryResult queryResult)
        {
            if (queryResult != null)
            {
                var stop = Stopwatch.StartNew();
                //we create two uints. 'index' for the index of current block/batch of files and 'stepSize' for the size of the block. This optimizes the loading operation tremendously.
                uint index = 0, stepSize = 200;
                //a list containing the files we recieved after querying using the two uints we created above.
                IReadOnlyList <StorageFile> files = await queryResult.GetFilesAsync(index, stepSize);

                //we move forward the index 100 steps because first 100 files are loaded when we called the above method.
                index += 200;

                //this is a temporary list to collect all the processed Mediafiles. We use List because it is fast. Faster than using ObservableCollection directly because of the events firing on every add.
                var tempList = new List <Mediafile>();

                //'count' is for total files got after querying.
                var count = await queryResult.GetItemCountAsync();

                if (count == 0)
                {
                    string error = "No songs found!";
                    await NotificationManager.ShowAsync(error);

                    return;
                }

                AlbumArtistViewModel model   = new AlbumArtistViewModel();
                LibraryService       service = new LibraryService(new DatabaseService());
                int failedCount = 0;
                //'i' is a variable for the index of currently processing file
                short i = 0;
                //using while loop until number of files become 0. This is to confirm that we process all files without leaving anything out.
                while (files.Count != 0)
                {
                    try
                    {
                        foreach (StorageFile file in files)
                        {
                            try
                            {
                                //we use 'if' conditional so that we don't add any duplicates
                                if (TracksCollection.Elements.All(t => t.Path != file.Path))
                                {
                                    //A null Mediafile which we will use afterwards.
                                    Mediafile mp3file = null;
                                    i++; //Notice here that we are increasing the 'i' variable by one for each file.
                                    //we send a message to anyone listening relaying that song count has to be updated.
                                    Messenger.Instance.NotifyColleagues(MessageTypes.MSG_UPDATE_SONG_COUNT, i);
                                    await Task.Run(async() =>
                                    {
                                        //here we load into 'mp3file' variable our processed Song. This is a long process, loading all the properties and the album art.
                                        mp3file            = await CreateMediafile(file, false); //the core of the whole method.
                                        mp3file.FolderPath = Path.GetDirectoryName(file.Path);
                                        await SaveSingleFileAlbumArtAsync(mp3file).ConfigureAwait(false);
                                    });

                                    //this methods notifies the Player that one song is loaded. We use both 'count' and 'i' variable here to report current progress.
                                    await NotificationManager.ShowAsync(i.ToString() + "\\" + count.ToString() + " Song(s) Loaded", "Loading...");

                                    //we then add the processed song into 'tempList' very silently without anyone noticing and hence, efficiently.
                                    tempList.Add(mp3file);
                                }
                            }
                            catch (Exception ex)
                            {
                                //we catch and report any exception without distrubing the 'foreach flow'.
                                await NotificationManager.ShowAsync(ex.Message + " || Occured on: " + file.Path);

                                failedCount++;
                            }
                        }
                        //await SaveMultipleAlbumArtsAsync(tempList).ConfigureAwait(false);
                        //we send the message to load the album. This comes first so there is enough time to load all albums before new list come up.
                        Messenger.Instance.NotifyColleagues(MessageTypes.MSG_ADD_ALBUMS, tempList);
                        //now we add 100 songs directly into our TracksCollection which is an ObservableCollection. This is faster because only one event is invoked.
                        TracksCollection.AddRange(tempList);
                        //now we load 100 songs into database.
                        service.AddMediafiles(tempList);
                        //we clear the 'tempList' so it can come with only 100 songs again.
                        tempList.Clear();
                        //Since the no. of files in 'files' list is 100, only 100 files will be loaded after which we will step out of while loop.
                        //To avoid this, we create and run a task that loads the next 100 files. Stepping forward 100 steps without increasing the index.
                        files = await queryResult.GetFilesAsync(index, stepSize).AsTask().ConfigureAwait(false);

                        //consequently we have to increase the index by 100 so that songs are not repeated.
                        index += 200;
                    }
                    catch (Exception ex)
                    {
                        string message1 = ex.Message + "||" + ex.InnerException;
                        await NotificationManager.ShowAsync(message1);
                    }
                }
                stop.Stop();
                string message = string.Format("Library successfully loaded! Total Songs: {0}; Failed: {1}; Loaded: {2}; Time Taken: {3}", count, failedCount, i, stop.Elapsed.TotalSeconds);
                await NotificationManager.ShowAsync(message);

                service.Dispose();
                model = null;
            }
        }