Пример #1
0
        public async Task <IEnumerable <StorageFile> > GetStorageFilesInFolderAsync(StorageFolder folder)
        {
            //Get query options with which we search for files in the specified folder
            var options = DirectoryWalker.GetQueryOptions();

            /*
             * options.FileTypeFilter.Add(".mp3");
             * options.FileTypeFilter.Add(".wav");
             * options.FileTypeFilter.Add(".ogg");
             * options.FileTypeFilter.Add(".flac");
             * options.FileTypeFilter.Add(".m4a");
             * options.FileTypeFilter.Add(".aif");
             * options.FileTypeFilter.Add(".wma");*/

            //this is the query result which we recieve after querying in the folder
            StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(options);

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

            //the event for files changed
            queryResult.ContentsChanged += QueryResult_ContentsChanged;

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

                return(null);
            }

            return(await queryResult.GetFilesAsync());
        }
Пример #2
0
        /// Lifecycle



        public MonitoredFolder(StorageFolder folderToObserve, EventHandler <MonitoredFolderChangedArgs> changedEventHandler)
        {
            _monitoredFolder     = folderToObserve ?? throw new ArgumentNullException(nameof(folderToObserve));
            _changedEventHandler = changedEventHandler ?? throw new ArgumentNullException(nameof(changedEventHandler));

            StartMonitoringFolderForChanges();

            // Hookup user's handler for our changed event
            this.Changed += changedEventHandler;

            // Create cancellation token
            _cancellationToken = _cancellationTokenSource.Token;

            ReportLine($"Monitoring folder '{_monitoredFolder.Name}'");

            // Start producing results
            _ = InitialScan();


            return;


            /// Local Functions


            /// <summary>Sets up monitoring _rootFolder for changes. NOTE: Not used for scans.</summary>
            void StartMonitoringFolderForChanges()
            {
                var options = new QueryOptions();

                _contentChangedMonitor = _monitoredFolder.CreateFileQueryWithOptions(options);
                _contentChangedMonitor.ContentsChanged += OnContentsChanged;
                _ = _contentChangedMonitor.GetItemCountAsync();                 // Starts monitoring for changes
            }
        }
        public async Task <ulong> GetFolderSizeAsync(CancellationToken CancelToken = default)
        {
            if (WIN_Native_API.CheckLocationAvailability(Path))
            {
                return(await Task.Run(() =>
                {
                    return WIN_Native_API.CalulateSize(Path, CancelToken);
                }));
            }
            else
            {
                try
                {
                    LogTracer.Log($"Native API could not found the path: \"{Path}\", fall back to UWP storage API");

                    if (await GetStorageItemAsync() is StorageFolder Folder)
                    {
                        QueryOptions Options = new QueryOptions
                        {
                            FolderDepth   = FolderDepth.Deep,
                            IndexerOption = IndexerOption.UseIndexerWhenAvailable
                        };
                        Options.SetPropertyPrefetch(Windows.Storage.FileProperties.PropertyPrefetchOptions.BasicProperties, new string[] { "System.Size" });

                        StorageFileQueryResult Query = Folder.CreateFileQueryWithOptions(Options);

                        uint FileCount = await Query.GetItemCountAsync();

                        ulong TotalSize = 0;

                        for (uint Index = 0; Index < FileCount && !CancelToken.IsCancellationRequested; Index += 50)
                        {
                            foreach (StorageFile File in await Query.GetFilesAsync(Index, 50))
                            {
                                TotalSize += await File.GetSizeRawDataAsync().ConfigureAwait(false);

                                if (CancelToken.IsCancellationRequested)
                                {
                                    break;
                                }
                            }
                        }

                        return(TotalSize);
                    }
                    else
                    {
                        return(0);
                    }
                }
                catch (Exception ex)
                {
                    LogTracer.Log(ex, $"{nameof(GetFolderSizeAsync)} failed for uwp API");
                    return(0);
                }
            }
        }
Пример #4
0
        /// <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 <IEnumerable <Mediafile> > GetSongsFromFolderAsync(StorageFolder folder, bool useIndexer = true, uint stepSize = 20)
        {
            StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(DirectoryWalker.GetQueryOptions(null, useIndexer));

            uint index = 0;
            IReadOnlyList <StorageFile> files = await queryResult.GetFilesAsync(index, stepSize);

            index += stepSize;

            var count = await queryResult.GetItemCountAsync();

            if (count <= 0)
            {
                BLogger.I("No songs found.");
                await SharedLogic.Instance.NotificationManager.ShowMessageAsync("No songs found! Please try again.");

                return(null);
            }
            var   tempList = new List <Mediafile>((int)count);
            short progress = 0;

            try
            {
                // Note that I'm paging in the files as described
                while (files.Count != 0)
                {
                    var fileTask = queryResult.GetFilesAsync(index, stepSize).AsTask();
                    for (int i = 0; i < files.Count; i++)
                    {
                        if (files[i]?.IsAvailable == true)
                        {
                            progress++;
                            Messenger.Instance.NotifyColleagues(MessageTypes.MsgUpdateSongCount, progress);
                            Mediafile mp3File = await TagReaderHelper.CreateMediafile(files[i], false).ConfigureAwait(false); //the core of the whole method.

                            if (mp3File != null)
                            {
                                mp3File.FolderPath = Path.GetDirectoryName(files[i].Path);
                                await SaveSingleFileAlbumArtAsync(mp3File, files[i]).ConfigureAwait(false);

                                SharedLogic.Instance.NotificationManager.ShowStaticMessage(progress + "\\" + count + " Song(s) Loaded");
                                tempList.Add(mp3File);
                            }
                        }
                    }
                    files  = await fileTask;
                    index += stepSize;
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + "||" + ex.InnerException;
                BLogger.E("Error while importing folder.", ex);
                await SharedLogic.Instance.NotificationManager.ShowMessageAsync(message);
            }
            return(tempList.DistinctBy(f => f.OrginalFilename));
        }
Пример #5
0
        async Task UpdateCount()
        {
            _count = (int)await _queryResult.GetItemCountAsync();

            if (CollectionChanged != null)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
            }
        }
Пример #6
0
        public async static void SetupDirectoryWatcher(IEnumerable <StorageFolder> folderCollection)
        {
            foreach (var folder in folderCollection)
            {
                StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(GetQueryOptions());
                var files = await queryResult.GetItemCountAsync();

                queryResult.ContentsChanged += QueryResult_ContentsChanged;;
            }
        }
Пример #7
0
        public static async Task <List <StorageFile> > GetModifiedFiles(IEnumerable <StorageFolder> folderCollection, string TimeModified)
        {
            List <StorageFile> modifiedFiles = new List <StorageFile>();

            foreach (var folder in folderCollection)
            {
                StorageFileQueryResult modifiedqueryResult = folder.CreateFileQueryWithOptions(GetQueryOptions("datemodified:> " + TimeModified));
                if (await modifiedqueryResult.GetItemCountAsync() > 0)
                {
                    modifiedFiles.AddRange(await modifiedqueryResult.GetFilesAsync());
                }
            }
            return(modifiedFiles);
        }
 public async static Task PerformWatcherWorkAsync(StorageFolder folder)
 {
     StorageFileQueryResult modifiedqueryResult = folder.CreateFileQueryWithOptions(Common.DirectoryWalker.GetQueryOptions("datemodified:>" + SettingsVM.TimeOpened));
     var files = await modifiedqueryResult.GetFilesAsync();
     if (await modifiedqueryResult.GetItemCountAsync() > 0)
     {
         await AddStorageFilesToLibrary(modifiedqueryResult);
     }
     //since there were no modifed files returned yet the event was raised, this means that some file was renamed or deleted. To acknowledge that change we need to reload everything in the modified folder
     else
     {
         //this is the query result which we recieve after querying in the folder
         StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(Common.DirectoryWalker.GetQueryOptions());
         files = await queryResult.GetFilesAsync();
         RenameAddOrDeleteFiles(files);
     }
 }
Пример #9
0
 /// <summary>
 /// Auto loads the User's Music Libary on first load.
 /// </summary>
 private async Task AutoLoadMusicLibraryAsync()
 {
     try
     {
         var options = Common.DirectoryWalker.GetQueryOptions();
         //this is the query result which we recieve after querying in the folder
         StorageFileQueryResult queryResult = KnownFolders.MusicLibrary.CreateFileQueryWithOptions(options);
         //the event for files changed
         queryResult.ContentsChanged += QueryResult_ContentsChanged;
         if (await queryResult.GetItemCountAsync() > 0)
         {
             await AddFolderToLibraryAsync(queryResult);
         }
     }
     catch (Exception ex)
     {
         await NotificationManager.ShowAsync(ex.Message, "");
     }
 }
Пример #10
0
        async Task FetchData()
        {
            _count = (int)await _queryResult.GetItemCountAsync();

            this._cache.Clear();
            this._cache.AddRange(new FileItem[_count]);
            for (int i = 0; i < _count; i += BATCHSIZE)
            {
                await fetchBatch(i);
            }

            if (VectorChanged != null)
            {
                VectorChanged(this, new VectorChangedEventArgs()
                {
                    CollectionChange = CollectionChange.Reset
                });
            }
            if (CollectionChanged != null)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
            }
        }
Пример #11
0
        async Task UpdateCount()
        {
            _count = (int)await _queryResult.GetItemCountAsync();

            CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
Пример #12
0
        private async void FileContentsChanged(IStorageQueryResultBase sender, object args)
        {
            if (_filesRefreshing)
            {
                Debug.WriteLine("Filesystem change event fired but refresh is already running");
                return;
            }
            else
            {
                Debug.WriteLine("Filesystem change event fired. Refreshing...");
            }

            _filesRefreshing = true;

            //query options have to be reapplied otherwise old results are returned
            _fileQueryResult.ApplyNewQueryOptions(_options);
            _folderQueryResult.ApplyNewQueryOptions(_options);

            var fileCount = await _fileQueryResult.GetItemCountAsync();

            var folderCount = await _folderQueryResult.GetItemCountAsync();

            var files = await _fileQueryResult.GetFilesAsync();

            var folders = await _folderQueryResult.GetFoldersAsync();

            var cancellationTokenSourceCopy = _cancellationTokenSource;

            // modifying a file also results in a new unique FolderRelativeId so no need to check for DateModified explicitly

            var addedFiles             = files.Select(f => f.FolderRelativeId).Except(_filesAndFolders.Select(f => f.FolderRelativeId));
            var addedFolders           = folders.Select(f => f.FolderRelativeId).Except(_filesAndFolders.Select(f => f.FolderRelativeId));
            var removedFilesAndFolders = _filesAndFolders
                                         .Select(f => f.FolderRelativeId)
                                         .Except(files.Select(f => f.FolderRelativeId))
                                         .Except(folders.Select(f => f.FolderRelativeId))
                                         .ToArray();

            foreach (var file in addedFiles)
            {
                var toAdd = files.First(f => f.FolderRelativeId == file);
                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                                                                              async() =>
                {
                    await AddFile(toAdd, _pageName, cancellationTokenSourceCopy.Token);
                });
            }
            foreach (var folder in addedFolders)
            {
                var toAdd = folders.First(f => f.FolderRelativeId == folder);
                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                                                                              async() =>
                {
                    await AddFolder(toAdd, _pageName, cancellationTokenSourceCopy.Token);
                });
            }
            foreach (var item in removedFilesAndFolders)
            {
                var toRemove = _filesAndFolders.First(f => f.FolderRelativeId == item);
                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                                                                              () =>
                {
                    RemoveFileOrFolder(toRemove);
                });
            }

            _filesRefreshing = false;
            Debug.WriteLine("Filesystem refresh complete");
        }
Пример #13
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();
            }
        }
Пример #14
0
        public async Task LoadFolderContents(int imageSize, IProgress <int> progress, ICollection <MediaData> mediaDatas = null)
        {
            if (!StorageApplicationPermissions.FutureAccessList.ContainsItem("gallery"))
            {
                return;
            }

            ImageSize = imageSize;

            _folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync("gallery");

            if (_folder != null)
            {
                // Time and log file query.
                using (new DisposableLogger(GalleryLog.FileQueryBegin, (sw) => GalleryLog.FileQueryEnd(sw, FilesFound)))
                {
                    var queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, FileTypes.Extensions)
                    {
                        FolderDepth   = FolderDepth.Deep,
                        IndexerOption = IndexerOption.UseIndexerWhenAvailable,
                    };

                    // Sort results.
                    queryOptions.SortOrder.Clear();
                    var sortEntry = QueryUtils.GetSortEntryFromSettings();
                    queryOptions.SortOrder.Add(sortEntry);

                    // Prefetch thumbnails.
                    queryOptions.SetThumbnailPrefetch(ThumbnailMode.SingleItem, (uint)imageSize, ThumbnailOptions.UseCurrentScale);
                    queryOptions.SetPropertyPrefetch(PropertyPrefetchOptions.ImageProperties, new[] { "System.DateModified" });

                    // Create query.
                    _query = _folder.CreateFileQueryWithOptions(queryOptions);

                    // Register tracker.
                    _query.ContentsChanged += Query_ContentsChanged;

                    FilesFound = (int)await _query.GetItemCountAsync();
                }

                // Time and log file parsing.
                using (new DisposableLogger(GalleryLog.FileParseBegin, (sw) => GalleryLog.FileParseEnd(sw, FilesFound)))
                {
                    uint index = 0, stepSize = SettingsService.Instance.MediaLoadBatchSize;
                    var  files = await _query.GetFilesAsync(index, stepSize);

                    index += stepSize;
                    while (files.Count != 0)
                    {
                        var fileTask = _query.GetFilesAsync(index, stepSize).AsTask();
                        for (var i = 0; i < files.Count; i++)
                        {
                            var mediaFile = files[i];

                            // Don't bother with files not supported by MIME.
                            if (!FileTypes.IsSupportedExtension(mediaFile.FileType))
                            {
                                continue;
                            }

                            if (mediaDatas == null)
                            {
                                await AddFileAsync(imageSize, mediaFile, false);
                            }
                            else
                            {
                                // Find mediaData in mediaDatas based on path of mediaFile.
                                var matchingMediaDatas = mediaDatas.Where(data => data?.Meta?.MediaFilePath?.Equals(mediaFile?.Path) ?? false).ToList();

                                var mediaData = matchingMediaDatas.FirstOrDefault();

                                if (mediaData is null)
                                {
                                    // Track the lost media files.
                                    _lostMediaFiles.Add(mediaFile);
                                    continue;
                                }
                                if (mediaData.Meta is null)
                                {
                                    continue;
                                }
                                if (string.IsNullOrEmpty(mediaData.Meta.MediaFilePath))
                                {
                                    continue;
                                }

                                // Tell the mediaData which file belongs to it.
                                mediaData.MediaFile = mediaFile;

                                await AddFileAsync(imageSize, mediaFile, false, mediaData);
                            }
                        }
                        files  = await fileTask;
                        index += stepSize;
                        // Report progress to UI.
                        progress?.Report(MediaDatas.Count);
                    }
                }

                // Register tracker.
                RegisterFolderContentTracker();

                // Run tracker once to pick up on any file changes since last application boot.
                Query_ContentsChanged(_query, null);
            }
        }
Пример #15
0
        /// <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;
            }
        }
Пример #16
0
        public async void AddItemsToCollectionAsync(string path, Page currentPage)
        {
            CancelLoadAndClearFiles();

            _cancellationTokenSource = new CancellationTokenSource();
            var tokenSourceCopy = _cancellationTokenSource;

            TextState.isVisible = Visibility.Collapsed;

            _pageName      = currentPage.Name;
            Universal.path = path;

            if (!_pageName.Contains("Classic"))
            {
                _filesAndFolders.Clear();
            }

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            PVIS.isVisible = Visibility.Visible;

            switch (Universal.path)
            {
            case "Desktop":
                Universal.path = MainPage.DesktopPath;
                break;

            case "Downloads":
                Universal.path = MainPage.DownloadsPath;
                break;

            case "Documents":
                Universal.path = MainPage.DocumentsPath;
                break;

            case "Pictures":
                Universal.path = MainPage.PicturesPath;
                break;

            case "Music":
                Universal.path = MainPage.MusicPath;
                break;

            case "Videos":
                Universal.path = MainPage.VideosPath;
                break;

            case "OneDrive":
                Universal.path = MainPage.OneDrivePath;
                break;
            }

            try
            {
                _rootFolder = await StorageFolder.GetFolderFromPathAsync(Universal.path);

                History.AddToHistory(Universal.path);
                if (History.HistoryList.Count == 1)     // If this is the only item present in History, we don't want back button to be enabled
                {
                    BS.isEnabled = false;
                }
                else if (History.HistoryList.Count > 1)     // Otherwise, if this is not the first item, we'll enable back click
                {
                    BS.isEnabled = true;
                }

                switch (await _rootFolder.GetIndexedStateAsync())
                {
                case (IndexedState.FullyIndexed):
                    _options             = new QueryOptions();
                    _options.FolderDepth = FolderDepth.Shallow;
                    if (_pageName.Contains("Generic"))
                    {
                        _options.SetThumbnailPrefetch(ThumbnailMode.ListView, 20, ThumbnailOptions.UseCurrentScale);
                        _options.SetPropertyPrefetch(PropertyPrefetchOptions.BasicProperties, new string[] { "System.DateModified", "System.ContentType", "System.Size", "System.FileExtension" });
                    }
                    else if (_pageName.Contains("Photo"))
                    {
                        _options.SetThumbnailPrefetch(ThumbnailMode.PicturesView, 275, ThumbnailOptions.ResizeThumbnail);
                        _options.SetPropertyPrefetch(PropertyPrefetchOptions.BasicProperties, new string[] { "System.FileExtension" });
                    }
                    _options.IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties;
                    break;

                default:
                    _options             = new QueryOptions();
                    _options.FolderDepth = FolderDepth.Shallow;
                    if (_pageName.Contains("Generic"))
                    {
                        _options.SetThumbnailPrefetch(ThumbnailMode.ListView, 20, ThumbnailOptions.UseCurrentScale);
                        _options.SetPropertyPrefetch(PropertyPrefetchOptions.BasicProperties, new string[] { "System.DateModified", "System.ContentType", "System.ItemPathDisplay", "System.Size", "System.FileExtension" });
                    }
                    else if (_pageName.Contains("Photo"))
                    {
                        _options.SetThumbnailPrefetch(ThumbnailMode.PicturesView, 275, ThumbnailOptions.ResizeThumbnail);
                        _options.SetPropertyPrefetch(PropertyPrefetchOptions.BasicProperties, new string[] { "System.FileExtension" });
                    }
                    _options.IndexerOption = IndexerOption.UseIndexerWhenAvailable;
                    break;
                }

                SortEntry sort = new SortEntry()
                {
                    PropertyName   = "System.FileName",
                    AscendingOrder = true
                };
                _options.SortOrder.Add(sort);
                if (!_rootFolder.AreQueryOptionsSupported(_options))
                {
                    _options.SortOrder.Clear();
                }

                uint index = 0;
                _folderQueryResult = _rootFolder.CreateFolderQueryWithOptions(_options);
                //_folderQueryResult.ContentsChanged += FolderContentsChanged;
                var numFolders = await _folderQueryResult.GetItemCountAsync();

                IReadOnlyList <StorageFolder> storageFolders = await _folderQueryResult.GetFoldersAsync(index, _step);

                while (storageFolders.Count > 0)
                {
                    foreach (StorageFolder folder in storageFolders)
                    {
                        if (tokenSourceCopy.IsCancellationRequested)
                        {
                            return;
                        }
                        await AddFolder(folder, _pageName, tokenSourceCopy.Token);
                    }
                    index         += _step;
                    storageFolders = await _folderQueryResult.GetFoldersAsync(index, _step);
                }

                index            = 0;
                _fileQueryResult = _rootFolder.CreateFileQueryWithOptions(_options);
                _fileQueryResult.ContentsChanged += FileContentsChanged;
                var numFiles = await _fileQueryResult.GetItemCountAsync();

                IReadOnlyList <StorageFile> storageFiles = await _fileQueryResult.GetFilesAsync(index, _step);

                while (storageFiles.Count > 0)
                {
                    foreach (StorageFile file in storageFiles)
                    {
                        if (tokenSourceCopy.IsCancellationRequested)
                        {
                            return;
                        }
                        await AddFile(file, _pageName, tokenSourceCopy.Token);
                    }
                    index       += _step;
                    storageFiles = await _fileQueryResult.GetFilesAsync(index, _step);
                }
                if (numFiles + numFolders == 0)
                {
                    TextState.isVisible = Visibility.Visible;
                }
                stopwatch.Stop();
                Debug.WriteLine("Loading of items in " + Universal.path + " completed in " + stopwatch.Elapsed.Seconds + " seconds.\n");
            }
            catch (UnauthorizedAccessException e)
            {
                if (path.Contains(@"C:\"))
                {
                    DisplayConsentDialog();
                }
                else
                {
                    MessageDialog unsupportedDevice = new MessageDialog("This device may be unsupported. Please file an issue report in Settings - About containing what device we couldn't access. Technical information: " + e, "Unsupported Device");
                    await unsupportedDevice.ShowAsync();

                    return;
                }
            }
            catch (COMException e)
            {
                Frame         rootFrame = Window.Current.Content as Frame;
                MessageDialog driveGone = new MessageDialog(e.Message, "Drive Unplugged");
                await driveGone.ShowAsync();

                rootFrame.Navigate(typeof(MainPage), new SuppressNavigationTransitionInfo());
                return;
            }

            if (!_pageName.Contains("Classic"))
            {
                PVIS.isVisible = Visibility.Collapsed;
            }

            PVIS.isVisible = Visibility.Collapsed;
        }
        public async Task AddFolderToLibraryAsync(StorageFileQueryResult queryResult)
        {
            if (queryResult != null)
            {
                var stop = System.Diagnostics.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 = 100;
                //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 50 files are loaded when we called the above method.
                index += 100;
             
                //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>();
                //'i' is a variable for the index of currently processing file
                double i = 0;
                //'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);
                }
                int failedCount = 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
                    {                        
                        //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 a task that loads the next 100 files. Stepping forward 100 steps without increasing the index.
                        var fileTask = queryResult.GetFilesAsync(index, stepSize).AsTask();

                        //A null Mediafile which we will use afterwards.
                        Mediafile mp3file = null;

                        //A foreach loop to process each StorageFile
                        foreach (StorageFile file in files)
                        {
                            try
                            {
                                //we use 'if' conditional so that we don't add any duplicates
                                if (LibVM.TracksCollection.Elements.All(t => t.Path != file.Path))
                                {

                                    i++; //Notice here that we are increasing the 'i' variable by one for each file.
                                    LibVM.SongCount++; //we also increase the total no. of songs by one.
                                    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, file).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++;
                            }
                        }
                        //after the first 100 files have been added we enable the play button.
                        ShellVM.PlayPauseCommand.IsEnabled = true;
                        //now we add 100 songs directly into our TracksCollection which is an ObservableCollection. This is faster because only one event is invoked.
                        LibVM.TracksCollection.AddRange(tempList, false, true);
                        //now we load 100 songs into database.
                        LibVM.Database.Insert(tempList);
                        //we clear the 'tempList' so it can come with only 100 songs again.
                        tempList.Clear();
                        //here we reinitialize the 'files' variable (outside the while loop) so that it is never 0 and never contains the old files.
                        files = await fileTask.ConfigureAwait(false);
                        //consequently we have to increase the index by 100 so that songs are not repeated.
                        index += 100;
                    }
                    catch(Exception ex)
                    {
                        string message1 = ex.Message + "||" + ex.InnerException;
                        await NotificationManager.ShowAsync(message1);
                    }
                }
                //After all the songs are processed and loaded, we create albums of all those songs and load them using this method.
                await AlbumArtistVM.AddAlbums().ConfigureAwait(false);
                //we stop the stopwatch.
                stop.Stop();
                //and report the user how long it took.
                string message = string.Format("Library successfully loaded! Total Songs: {0} Failed: {1} Loaded: {2} Total Time Taken: {3} seconds", count, failedCount, i, Convert.ToInt32(stop.Elapsed.TotalSeconds).ToString()); 
                await NotificationManager.ShowAsync(message);
            }
        }