private async Task <OrganizeSummary> OrganizeAsync(CopyItems items)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            OnProgress(this, PARSE_PROGRESS_FACTOR + 0.1, "Prepare destination");

            try
            {
                OrganizeSummary summary = new OrganizeSummary();

                await Task.Run(() => OrganizationThread(items, summary));

                return(summary);
            }
            catch (Exception)
            {
#if DEBUG
                throw;
#else
                return(null);
#endif
            }
            finally
            {
                OnProgress(this, 1.0, "Organization complete");
            }
        }
        private async Task <object> ParseAsync()
        {
            if (sourcePath.DirectoryAreSame(destinationPath))
            {
                // TODO: implement
                throw new NotSupportedException("TODO");
            }

            OnProgress(this, 0.0, "Parsing source");

            try
            {
                ParseSummary summary = new ParseSummary();
                CopyItems    items   = await ParseItemsAsync(sourcePath, destinationPath, summary);

                dynamic result = new ExpandoObject();
                result.Summary = summary;
                result.Items   = items;
                return(result);
            }
            catch (Exception)
            {
#if DEBUG
                throw;
#else
                return(null);
#endif
            }
            finally
            {
                OnProgress(this, PARSE_PROGRESS_FACTOR, "Parsing complete");
            }
        }
        private void OrganizationThread(CopyItems items, OrganizeSummary summary)
        {
            PrepareDestinationPath(items);

            int itemCount = items.Count;

            for (int i = 0; i < itemCount; i++)
            {
                if (workerAborted)
                {
                    break;
                }

                float progress = (float)(i) / (float)itemCount;
                if ((int)(progress * 10) % 2 == 0)
                {
                    OnProgress(this, PARSE_PROGRESS_FACTOR + 0.1 + (progress * (1.0 - PARSE_PROGRESS_FACTOR - 0.1)), $"Organizing {i + 1} of {itemCount}");
                }

                CopySourceToDestination(items[i], summary);
            }
        }
        private async Task <CopyItems> ParseItemsAsync(string sourcePath, string destinationPath, ParseSummary summary)
        {
            List <string> ignore = new List <string>();

            if (IgnorePaths != null)
            {
                ignore.AddRange(IgnorePaths);
            }
            if (!sourcePath.DirectoryAreSame(destinationPath))
            {
                ignore.Add(destinationPath);
            }

            IEnumerable <MetaData> data;

            try
            {
                MetaParserConfig config = new MetaParserConfig()
                {
                    Recursive = Recursive, IgnorePaths = ignore
                };
                data = await MetaParser.ParseAsync(sourcePath, config);
            }
            catch (MetaParseException ex)
            {
                throw new MediaOrganizerException("Failed to parse meta data", ex);
            }

            PatternPathParser parser = new PatternPathParser(Locale);

            parser.Preload(data);

            CopyItems items = new CopyItems();

            items.sourcePath      = sourcePath;
            items.destinationPath = destinationPath;

            foreach (MetaData meta in data)
            {
                if (workerAborted)
                {
                    break;
                }

                string path = meta.Path;

                switch (meta.Type)
                {
                case MetaType.Directory:
                    summary.totalDirectories.Add(path);
                    continue;

                case MetaType.File:
                    summary.totalFiles.Add(path);
                    summary.ignored.Add(path);
                    continue;

                default:
                    summary.totalFiles.Add(path);
                    break;
                }

                CopyItem item = ParseItem(parser, destinationPath, meta);
                items.Add(item);
                summary.parsed.Add(path);
            }

            return(items);
        }
        private void PrepareDestinationPath(CopyItems items)
        {
            // Setup destination path
            if (!Directory.Exists(items.destinationPath))
            {
                Directory.CreateDirectory(items.destinationPath);
                return;
            }

            switch (CopyPrecondition)
            {
            case CopyPrecondition.None:
                break;

            case CopyPrecondition.RequireEmpty:
                if (Directory.Exists(items.destinationPath))
                {
                    if (Directory.GetFiles(items.destinationPath).Length > 0)
                    {
                        throw new MediaOrganizerException("Path contains files but is required to be empty: {0}", items.destinationPath);
                    }
                    if (Directory.GetDirectories(items.destinationPath).Length > 0)
                    {
                        throw new MediaOrganizerException("Path contains directories but is required to be empty: {0}", items.destinationPath);
                    }
                }
                break;

            case CopyPrecondition.WipeBefore:
                if (items.sourcePath.DirectoryAreSame(items.destinationPath))
                {
                    // TODO: handle exceptions
                    // Move source/destination path to temporary place before copying
                    string tempSourcePath = Path.GetTempFileName();
                    temporaryPaths.Add(tempSourcePath);
                    try
                    {
                        File.Delete(tempSourcePath);
                        Directory.Move(items.sourcePath, tempSourcePath);
                    }
                    catch (Exception ex)
                    {
                        throw new MediaOrganizerException($"Failed to generate temporary directory: {tempSourcePath}", ex);
                    }
                    items.sourcePath = tempSourcePath;
                }
                else
                {
                    try
                    {
                        Directory.Delete(items.destinationPath, true);
                    }
                    catch (Exception ex)
                    {
                        throw new MediaOrganizerException($"Failed to wipe destination path: {items.destinationPath}", ex);
                    }
                }

                if (!Directory.Exists(items.destinationPath))
                {
                    try
                    {
                        Directory.CreateDirectory(items.destinationPath);
                    }
                    catch (Exception ex)
                    {
                        throw new MediaOrganizerException($"Failed to create destination path: {items.destinationPath}", ex);
                    }
                }
                break;

            default:
                throw new NotImplementedException($"CopyPrecondition: {CopyPrecondition}");
            }
        }
Example #6
0
        public async Task<OrganizeSummary> ParseAsync()
        {
            if (sourcePath.DirectoryAreSame(destinationPath))
            {
                // TODO: implement
                throw new NotSupportedException("TODO");
            }

            if (workerRunning)
                throw new InvalidOperationException("Cannot start parsing: worker currently running");
            workerRunning = true;
            workerAborted = false;

            OnProgress(this, 0.0, "Parsing source");

            try
            {
                OrganizeSummary summary = new OrganizeSummary();

                copyItems = new CopyItems();
                copyItems.sourcePath = sourcePath;
                copyItems.destinationPath = destinationPath;
                copyItems.items = await ParseItemsAsync(sourcePath, destinationPath, summary);

                return summary;
            }
            catch (Exception)
            {
#if DEBUG
                throw;
#else
                return null;
#endif
            }
            finally
            {
                workerRunning = false;

                OnProgress(this, PARSE_PROGRESS_FACTOR, "Parsing complete");
            }
        }