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}"); } }
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"); } }