mirror of
https://github.com/cyanfish/naps2.git
synced 2024-11-11 02:45:19 +03:00
Remove FileNamePlaceholders as a dependency (use as a param instead)
This commit is contained in:
parent
646edc205a
commit
a8d91b8907
@ -31,7 +31,6 @@ namespace NAPS2.Automation
|
||||
private readonly IErrorOutput errorOutput;
|
||||
private readonly IScannedImageImporter scannedImageImporter;
|
||||
private readonly PdfSettingsContainer pdfSettingsContainer;
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
private readonly ImageSettingsContainer imageSettingsContainer;
|
||||
private readonly IOperationFactory operationFactory;
|
||||
private readonly OcrManager ocrManager;
|
||||
@ -42,11 +41,11 @@ namespace NAPS2.Automation
|
||||
private List<List<ScannedImage>> scanList;
|
||||
private int pagesScanned;
|
||||
private int totalPagesScanned;
|
||||
private DateTime startTime;
|
||||
private Placeholders placeholders;
|
||||
private List<string> actualOutputPaths;
|
||||
private OcrParams ocrParams;
|
||||
|
||||
public AutomatedScanning(AutomatedScanningOptions options, IProfileManager profileManager, IScanPerformer scanPerformer, IErrorOutput errorOutput, IEmailProviderFactory emailProviderFactory, IScannedImageImporter scannedImageImporter, PdfSettingsContainer pdfSettingsContainer, FileNamePlaceholders fileNamePlaceholders, ImageSettingsContainer imageSettingsContainer, IOperationFactory operationFactory, OcrManager ocrManager, IFormFactory formFactory, GhostscriptManager ghostscriptManager)
|
||||
public AutomatedScanning(AutomatedScanningOptions options, IProfileManager profileManager, IScanPerformer scanPerformer, IErrorOutput errorOutput, IEmailProviderFactory emailProviderFactory, IScannedImageImporter scannedImageImporter, PdfSettingsContainer pdfSettingsContainer, ImageSettingsContainer imageSettingsContainer, IOperationFactory operationFactory, OcrManager ocrManager, IFormFactory formFactory, GhostscriptManager ghostscriptManager)
|
||||
{
|
||||
this.options = options;
|
||||
this.profileManager = profileManager;
|
||||
@ -55,7 +54,6 @@ namespace NAPS2.Automation
|
||||
this.emailProviderFactory = emailProviderFactory;
|
||||
this.scannedImageImporter = scannedImageImporter;
|
||||
this.pdfSettingsContainer = pdfSettingsContainer;
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
this.imageSettingsContainer = imageSettingsContainer;
|
||||
this.operationFactory = operationFactory;
|
||||
this.ocrManager = ocrManager;
|
||||
@ -82,7 +80,7 @@ namespace NAPS2.Automation
|
||||
return;
|
||||
}
|
||||
|
||||
startTime = DateTime.Now;
|
||||
placeholders = Placeholders.All.WithDate(DateTime.Now);
|
||||
ConsoleOverwritePrompt.ForceOverwrite = options.ForceOverwrite;
|
||||
|
||||
if (options.Install != null)
|
||||
@ -246,7 +244,7 @@ namespace NAPS2.Automation
|
||||
// Email, so no check needed
|
||||
return true;
|
||||
}
|
||||
var subPath = fileNamePlaceholders.SubstitutePlaceholders(options.OutputPath, startTime);
|
||||
var subPath = placeholders.Substitute(options.OutputPath);
|
||||
if (IsPdfFile(subPath)
|
||||
&& File.Exists(subPath)
|
||||
&& !options.ForceOverwrite)
|
||||
@ -302,8 +300,8 @@ namespace NAPS2.Automation
|
||||
|
||||
var message = new EmailMessage
|
||||
{
|
||||
Subject = fileNamePlaceholders.SubstitutePlaceholders(options.EmailSubject, startTime, false) ?? "",
|
||||
BodyText = fileNamePlaceholders.SubstitutePlaceholders(options.EmailBody, startTime, false),
|
||||
Subject = placeholders.Substitute(options.EmailSubject, false) ?? "",
|
||||
BodyText = placeholders.Substitute(options.EmailBody, false),
|
||||
AutoSend = options.EmailAutoSend,
|
||||
SilentSend = options.EmailSilentSend
|
||||
};
|
||||
@ -327,7 +325,7 @@ namespace NAPS2.Automation
|
||||
int i = 0;
|
||||
foreach (var path in actualOutputPaths)
|
||||
{
|
||||
string attachmentName = fileNamePlaceholders.SubstitutePlaceholders(options.EmailFileName, startTime, false, i++, scanList.Count > 1 ? digits : 0);
|
||||
string attachmentName = placeholders.Substitute(options.EmailFileName, false, i++, scanList.Count > 1 ? digits : 0);
|
||||
message.Attachments.Add(new EmailAttachment
|
||||
{
|
||||
FilePath = path,
|
||||
@ -434,7 +432,7 @@ namespace NAPS2.Automation
|
||||
|
||||
private async Task ExportToImageFiles()
|
||||
{
|
||||
var path = fileNamePlaceholders.SubstitutePlaceholders(options.OutputPath, startTime);
|
||||
var path = placeholders.Substitute(options.OutputPath);
|
||||
await DoExportToImageFiles(options.OutputPath);
|
||||
OutputVerbose(ConsoleResources.FinishedSavingImages, Path.GetFullPath(path));
|
||||
}
|
||||
@ -460,7 +458,7 @@ namespace NAPS2.Automation
|
||||
i = op.Status.CurrentProgress;
|
||||
}
|
||||
};
|
||||
op.Start(outputPath, startTime, scan);
|
||||
op.Start(outputPath, placeholders, scan);
|
||||
await op.Success;
|
||||
}
|
||||
}
|
||||
@ -548,8 +546,8 @@ namespace NAPS2.Automation
|
||||
}
|
||||
};
|
||||
int digits = (int)Math.Floor(Math.Log10(scanList.Count)) + 1;
|
||||
string actualPath = fileNamePlaceholders.SubstitutePlaceholders(path, startTime, true, scanIndex++, scanList.Count > 1 ? digits : 0);
|
||||
op.Start(actualPath, startTime, fileContents, pdfSettings, ocrParams, email, null);
|
||||
string actualPath = placeholders.Substitute(path, true, scanIndex++, scanList.Count > 1 ? digits : 0);
|
||||
op.Start(actualPath, placeholders, fileContents, pdfSettings, ocrParams, email, null);
|
||||
if (!await op.Success)
|
||||
{
|
||||
return false;
|
||||
|
@ -23,17 +23,15 @@ namespace NAPS2.ImportExport
|
||||
private readonly PdfSettingsContainer pdfSettingsContainer;
|
||||
private readonly OcrManager ocrManager;
|
||||
private readonly IErrorOutput errorOutput;
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
private readonly DialogHelper dialogHelper;
|
||||
private readonly IOperationProgress operationProgress;
|
||||
|
||||
public AutoSave(IOperationFactory operationFactory, PdfSettingsContainer pdfSettingsContainer, OcrManager ocrManager, IErrorOutput errorOutput, FileNamePlaceholders fileNamePlaceholders, DialogHelper dialogHelper, IOperationProgress operationProgress)
|
||||
public AutoSave(IOperationFactory operationFactory, PdfSettingsContainer pdfSettingsContainer, OcrManager ocrManager, IErrorOutput errorOutput, DialogHelper dialogHelper, IOperationProgress operationProgress)
|
||||
{
|
||||
this.operationFactory = operationFactory;
|
||||
this.pdfSettingsContainer = pdfSettingsContainer;
|
||||
this.ocrManager = ocrManager;
|
||||
this.errorOutput = errorOutput;
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
this.dialogHelper = dialogHelper;
|
||||
this.operationProgress = operationProgress;
|
||||
}
|
||||
@ -47,13 +45,13 @@ namespace NAPS2.ImportExport
|
||||
try
|
||||
{
|
||||
bool ok = true;
|
||||
DateTime now = DateTime.Now;
|
||||
var placeholders = Placeholders.All.WithDate(DateTime.Now);
|
||||
int i = 0;
|
||||
string firstFileSaved = null;
|
||||
var scans = SaveSeparatorHelper.SeparateScans(new[] { images }, settings.Separator).ToList();
|
||||
foreach (var imageList in scans)
|
||||
{
|
||||
(bool success, string filePath) = await SaveOneFile(settings, now, i++, imageList, scans.Count == 1 ? notify : null);
|
||||
(bool success, string filePath) = await SaveOneFile(settings, placeholders, i++, imageList, scans.Count == 1 ? notify : null);
|
||||
if (!success)
|
||||
{
|
||||
ok = false;
|
||||
@ -80,18 +78,18 @@ namespace NAPS2.ImportExport
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<(bool, string)> SaveOneFile(AutoSaveSettings settings, DateTime now, int i, List<ScannedImage> images, ISaveNotify notify)
|
||||
private async Task<(bool, string)> SaveOneFile(AutoSaveSettings settings, Placeholders placeholders, int i, List<ScannedImage> images, ISaveNotify notify)
|
||||
{
|
||||
if (images.Count == 0)
|
||||
{
|
||||
return (true, null);
|
||||
}
|
||||
string subPath = fileNamePlaceholders.SubstitutePlaceholders(settings.FilePath, now, true, i);
|
||||
string subPath = placeholders.Substitute(settings.FilePath, true, i);
|
||||
if (settings.PromptForFilePath)
|
||||
{
|
||||
if (dialogHelper.PromptToSavePdfOrImage(subPath, out string newPath))
|
||||
{
|
||||
subPath = fileNamePlaceholders.SubstitutePlaceholders(newPath, now, true, i);
|
||||
subPath = placeholders.Substitute(newPath, true, i);
|
||||
}
|
||||
}
|
||||
var extension = Path.GetExtension(subPath);
|
||||
@ -99,10 +97,10 @@ namespace NAPS2.ImportExport
|
||||
{
|
||||
if (File.Exists(subPath))
|
||||
{
|
||||
subPath = fileNamePlaceholders.SubstitutePlaceholders(subPath, now, true, 0, 1);
|
||||
subPath = placeholders.Substitute(subPath, true, 0, 1);
|
||||
}
|
||||
var op = operationFactory.Create<SavePdfOperation>();
|
||||
if (op.Start(subPath, now, images, pdfSettingsContainer.PdfSettings, ocrManager.DefaultParams, false, null))
|
||||
if (op.Start(subPath, placeholders, images, pdfSettingsContainer.PdfSettings, ocrManager.DefaultParams, false, null))
|
||||
{
|
||||
operationProgress.ShowProgress(op);
|
||||
}
|
||||
@ -116,7 +114,7 @@ namespace NAPS2.ImportExport
|
||||
else
|
||||
{
|
||||
var op = operationFactory.Create<SaveImagesOperation>();
|
||||
if (op.Start(subPath, now, images))
|
||||
if (op.Start(subPath, placeholders, images))
|
||||
{
|
||||
operationProgress.ShowProgress(op);
|
||||
}
|
||||
|
@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NAPS2.ImportExport
|
||||
{
|
||||
public class FileNamePlaceholders
|
||||
{
|
||||
public const string YEAR_4_DIGITS = "$(YYYY)";
|
||||
public const string YEAR_2_DIGITS = "$(YY)";
|
||||
public const string MONTH_2_DIGITS = "$(MM)";
|
||||
public const string DAY_2_DIGITS = "$(DD)";
|
||||
public const string HOUR_24_CLOCK = "$(hh)";
|
||||
public const string MINUTE_2_DIGITS = "$(mm)";
|
||||
public const string SECOND_2_DIGITS = "$(ss)";
|
||||
public const string NUMBER_4_DIGITS = "$(nnnn)";
|
||||
public const string NUMBER_3_DIGITS = "$(nnn)";
|
||||
public const string NUMBER_2_DIGITS = "$(nn)";
|
||||
public const string NUMBER_1_DIGIT = "$(n)";
|
||||
|
||||
private static readonly Dictionary<string, Func<DateTime, string>> Placeholders = new Dictionary<string, Func<DateTime, string>>
|
||||
{
|
||||
{ YEAR_4_DIGITS, dateTime => dateTime.ToString("yyyy") },
|
||||
{ YEAR_2_DIGITS, dateTime => dateTime.ToString("yy") },
|
||||
{ MONTH_2_DIGITS, dateTime => dateTime.ToString("MM") },
|
||||
{ DAY_2_DIGITS, dateTime => dateTime.ToString("dd") },
|
||||
{ HOUR_24_CLOCK, dateTime => dateTime.ToString("HH") },
|
||||
{ MINUTE_2_DIGITS, dateTime => dateTime.ToString("mm") },
|
||||
{ SECOND_2_DIGITS, dateTime => dateTime.ToString("ss") },
|
||||
};
|
||||
|
||||
private static readonly Regex NumberPlaceholderPattern = new Regex(@"\$\(n+\)");
|
||||
|
||||
public string SubstitutePlaceholders(string fileNameWithPath, DateTime dateTime, bool incrementIfExists = true, int numberSkip = 0, int autoNumberDigits = 0)
|
||||
{
|
||||
if (fileNameWithPath == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Start with environment variables
|
||||
string result = Environment.ExpandEnvironmentVariables(fileNameWithPath);
|
||||
// Most placeholders don't need a special case
|
||||
result = Placeholders.Aggregate(result, (current, ph) => current.Replace(ph.Key, ph.Value(dateTime)));
|
||||
// One does, however
|
||||
var match = NumberPlaceholderPattern.Match(result);
|
||||
if (match.Success)
|
||||
{
|
||||
result = NumberPlaceholderPattern.Replace(result, "");
|
||||
result = SubstituteNumber(result, match.Index, match.Length - 3, numberSkip, true);
|
||||
}
|
||||
else if (autoNumberDigits > 0)
|
||||
{
|
||||
result = result.Insert(result.Length - Path.GetExtension(result).Length, ".");
|
||||
result = SubstituteNumber(result, result.Length - Path.GetExtension(result).Length, autoNumberDigits, numberSkip, incrementIfExists);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private string SubstituteNumber(string path, int insertionIndex, int minDigits, int skip, bool incrementIfExists)
|
||||
{
|
||||
string result;
|
||||
int i = skip;
|
||||
do
|
||||
{
|
||||
++i;
|
||||
result = path.Insert(insertionIndex, i.ToString("D" + minDigits));
|
||||
} while (incrementIfExists && File.Exists(result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -18,15 +18,13 @@ namespace NAPS2.ImportExport.Images
|
||||
{
|
||||
public class SaveImagesOperation : OperationBase
|
||||
{
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
private readonly ImageSettingsContainer imageSettingsContainer;
|
||||
private readonly IOverwritePrompt overwritePrompt;
|
||||
private readonly ScannedImageRenderer scannedImageRenderer;
|
||||
private readonly TiffHelper tiffHelper;
|
||||
|
||||
public SaveImagesOperation(FileNamePlaceholders fileNamePlaceholders, ImageSettingsContainer imageSettingsContainer, IOverwritePrompt overwritePrompt, ScannedImageRenderer scannedImageRenderer, TiffHelper tiffHelper)
|
||||
public SaveImagesOperation(ImageSettingsContainer imageSettingsContainer, IOverwritePrompt overwritePrompt, ScannedImageRenderer scannedImageRenderer, TiffHelper tiffHelper)
|
||||
{
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
this.imageSettingsContainer = imageSettingsContainer;
|
||||
this.overwritePrompt = overwritePrompt;
|
||||
this.scannedImageRenderer = scannedImageRenderer;
|
||||
@ -44,10 +42,10 @@ namespace NAPS2.ImportExport.Images
|
||||
/// If multiple images are provided, they will be saved to files with numeric identifiers, e.g. img1.jpg, img2.jpg, etc..
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to save. For multiple images, this is modified by appending a number before the extension.</param>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="placeholders"></param>
|
||||
/// <param name="images">The collection of images to save.</param>
|
||||
/// <param name="batch"></param>
|
||||
public bool Start(string fileName, DateTime dateTime, List<ScannedImage> images, bool batch = false)
|
||||
public bool Start(string fileName, Placeholders placeholders, List<ScannedImage> images, bool batch = false)
|
||||
{
|
||||
Status = new OperationStatus
|
||||
{
|
||||
@ -59,12 +57,12 @@ namespace NAPS2.ImportExport.Images
|
||||
{
|
||||
try
|
||||
{
|
||||
var subFileName = fileNamePlaceholders.SubstitutePlaceholders(fileName, dateTime, batch);
|
||||
var subFileName = placeholders.Substitute(fileName, batch);
|
||||
if (Directory.Exists(subFileName))
|
||||
{
|
||||
// Not supposed to be a directory, but ok...
|
||||
fileName = Path.Combine(subFileName, "$(n).jpg");
|
||||
subFileName = fileNamePlaceholders.SubstitutePlaceholders(fileName, dateTime, batch);
|
||||
subFileName = placeholders.Substitute(fileName, batch);
|
||||
}
|
||||
ImageFormat format = GetImageFormat(subFileName);
|
||||
|
||||
@ -114,7 +112,7 @@ namespace NAPS2.ImportExport.Images
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileNameN = fileNamePlaceholders.SubstitutePlaceholders(fileName, dateTime, true, i,
|
||||
var fileNameN = placeholders.Substitute(fileName, true, i,
|
||||
digits);
|
||||
Status.StatusText = string.Format(MiscResources.SavingFormat, Path.GetFileName(fileNameN));
|
||||
InvokeStatusChanged();
|
||||
|
@ -16,14 +16,12 @@ namespace NAPS2.ImportExport.Pdf
|
||||
{
|
||||
public class SavePdfOperation : OperationBase
|
||||
{
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
private readonly IPdfExporter pdfExporter;
|
||||
private readonly IOverwritePrompt overwritePrompt;
|
||||
private readonly IEmailProviderFactory emailProviderFactory;
|
||||
|
||||
public SavePdfOperation(FileNamePlaceholders fileNamePlaceholders, IPdfExporter pdfExporter, IOverwritePrompt overwritePrompt, IEmailProviderFactory emailProviderFactory)
|
||||
public SavePdfOperation(IPdfExporter pdfExporter, IOverwritePrompt overwritePrompt, IEmailProviderFactory emailProviderFactory)
|
||||
{
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
this.pdfExporter = pdfExporter;
|
||||
this.overwritePrompt = overwritePrompt;
|
||||
this.emailProviderFactory = emailProviderFactory;
|
||||
@ -32,10 +30,10 @@ namespace NAPS2.ImportExport.Pdf
|
||||
AllowBackground = true;
|
||||
}
|
||||
|
||||
public bool Start(string fileName, DateTime dateTime, ICollection<ScannedImage> images, PdfSettings pdfSettings, OcrParams ocrParams, bool email, EmailMessage emailMessage)
|
||||
public bool Start(string fileName, Placeholders placeholders, ICollection<ScannedImage> images, PdfSettings pdfSettings, OcrParams ocrParams, bool email, EmailMessage emailMessage)
|
||||
{
|
||||
ProgressTitle = email ? MiscResources.EmailPdfProgress : MiscResources.SavePdfProgress;
|
||||
var subFileName = fileNamePlaceholders.SubstitutePlaceholders(fileName, dateTime);
|
||||
var subFileName = placeholders.Substitute(fileName);
|
||||
Status = new OperationStatus
|
||||
{
|
||||
StatusText = string.Format(MiscResources.SavingFormat, Path.GetFileName(subFileName)),
|
||||
@ -45,7 +43,7 @@ namespace NAPS2.ImportExport.Pdf
|
||||
if (Directory.Exists(subFileName))
|
||||
{
|
||||
// Not supposed to be a directory, but ok...
|
||||
subFileName = fileNamePlaceholders.SubstitutePlaceholders(Path.Combine(subFileName, "$(n).pdf"), dateTime);
|
||||
subFileName = placeholders.Substitute(Path.Combine(subFileName, "$(n).pdf"));
|
||||
}
|
||||
if (File.Exists(subFileName))
|
||||
{
|
||||
|
107
NAPS2.Sdk/ImportExport/Placeholders.cs
Normal file
107
NAPS2.Sdk/ImportExport/Placeholders.cs
Normal file
@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NAPS2.ImportExport
|
||||
{
|
||||
public abstract class Placeholders
|
||||
{
|
||||
public const string YEAR_4_DIGITS = "$(YYYY)";
|
||||
public const string YEAR_2_DIGITS = "$(YY)";
|
||||
public const string MONTH_2_DIGITS = "$(MM)";
|
||||
public const string DAY_2_DIGITS = "$(DD)";
|
||||
public const string HOUR_24_CLOCK = "$(hh)";
|
||||
public const string MINUTE_2_DIGITS = "$(mm)";
|
||||
public const string SECOND_2_DIGITS = "$(ss)";
|
||||
public const string NUMBER_4_DIGITS = "$(nnnn)";
|
||||
public const string NUMBER_3_DIGITS = "$(nnn)";
|
||||
public const string NUMBER_2_DIGITS = "$(nn)";
|
||||
public const string NUMBER_1_DIGIT = "$(n)";
|
||||
|
||||
public static DefaultPlaceholders All => new DefaultPlaceholders();
|
||||
|
||||
public static EnvironmentPlaceholders Env => new EnvironmentPlaceholders();
|
||||
|
||||
public static StubPlaceholders None => new StubPlaceholders();
|
||||
|
||||
public abstract string Substitute(string filePath, bool incrementIfExists = true, int numberSkip = 0, int autoNumberDigits = 0);
|
||||
|
||||
public class StubPlaceholders : Placeholders
|
||||
{
|
||||
public override string Substitute(string filePath, bool incrementIfExists = true, int numberSkip = 0, int autoNumberDigits = 0) => filePath;
|
||||
}
|
||||
|
||||
public class EnvironmentPlaceholders : Placeholders
|
||||
{
|
||||
public override string Substitute(string filePath, bool incrementIfExists = true, int numberSkip = 0, int autoNumberDigits = 0) => Environment.ExpandEnvironmentVariables(filePath);
|
||||
}
|
||||
|
||||
public class DefaultPlaceholders : Placeholders
|
||||
{
|
||||
private static readonly Dictionary<string, Func<DateTime, string>> Replacements = new Dictionary<string, Func<DateTime, string>>
|
||||
{
|
||||
{YEAR_4_DIGITS, dateTime => dateTime.ToString("yyyy")},
|
||||
{YEAR_2_DIGITS, dateTime => dateTime.ToString("yy")},
|
||||
{MONTH_2_DIGITS, dateTime => dateTime.ToString("MM")},
|
||||
{DAY_2_DIGITS, dateTime => dateTime.ToString("dd")},
|
||||
{HOUR_24_CLOCK, dateTime => dateTime.ToString("HH")},
|
||||
{MINUTE_2_DIGITS, dateTime => dateTime.ToString("mm")},
|
||||
{SECOND_2_DIGITS, dateTime => dateTime.ToString("ss")},
|
||||
};
|
||||
|
||||
private static readonly Regex NumberPlaceholderPattern = new Regex(@"\$\(n+\)");
|
||||
|
||||
private readonly DateTime? dateTimeOverride;
|
||||
|
||||
public DefaultPlaceholders(DateTime? dateTimeOverride = null)
|
||||
{
|
||||
this.dateTimeOverride = dateTimeOverride;
|
||||
}
|
||||
|
||||
public DefaultPlaceholders WithDate(DateTime dateTime) => new DefaultPlaceholders(dateTime);
|
||||
|
||||
public override string Substitute(string filePath, bool incrementIfExists = true, int numberSkip = 0, int autoNumberDigits = 0)
|
||||
{
|
||||
if (filePath == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var dateTime = dateTimeOverride ?? DateTime.Now;
|
||||
// Start with environment variables
|
||||
string result = Environment.ExpandEnvironmentVariables(filePath);
|
||||
// Most placeholders don't need a special case
|
||||
result = Replacements.Aggregate(result, (current, ph) => current.Replace(ph.Key, ph.Value(dateTime)));
|
||||
// One does, however
|
||||
var match = NumberPlaceholderPattern.Match(result);
|
||||
if (match.Success)
|
||||
{
|
||||
result = NumberPlaceholderPattern.Replace(result, "");
|
||||
result = SubstituteNumber(result, match.Index, match.Length - 3, numberSkip, true);
|
||||
}
|
||||
else if (autoNumberDigits > 0)
|
||||
{
|
||||
result = result.Insert(result.Length - Path.GetExtension(result).Length, ".");
|
||||
result = SubstituteNumber(result, result.Length - Path.GetExtension(result).Length, autoNumberDigits, numberSkip, incrementIfExists);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string SubstituteNumber(string path, int insertionIndex, int minDigits, int skip, bool incrementIfExists)
|
||||
{
|
||||
string result;
|
||||
int i = skip;
|
||||
do
|
||||
{
|
||||
++i;
|
||||
result = path.Insert(insertionIndex, i.ToString("D" + minDigits));
|
||||
} while (incrementIfExists && File.Exists(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -360,7 +360,7 @@
|
||||
<Compile Include="Config\IConfigManager.cs" />
|
||||
<Compile Include="Config\ProfileManager.cs" />
|
||||
<Compile Include="Config\UserConfig.cs" />
|
||||
<Compile Include="ImportExport\FileNamePlaceholders.cs" />
|
||||
<Compile Include="ImportExport\Placeholders.cs" />
|
||||
<Compile Include="ImportExport\Email\EmailSettings.cs" />
|
||||
<Compile Include="ImportExport\Email\EmailSettingsContainer.cs" />
|
||||
<Compile Include="ImportExport\Images\ImageSettings.cs" />
|
||||
|
@ -23,18 +23,16 @@ namespace NAPS2.Scan.Batch
|
||||
{
|
||||
private readonly IScanPerformer scanPerformer;
|
||||
private readonly IProfileManager profileManager;
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
private readonly IPdfExporter pdfExporter;
|
||||
private readonly IOperationFactory operationFactory;
|
||||
private readonly PdfSettingsContainer pdfSettingsContainer;
|
||||
private readonly OcrManager ocrManager;
|
||||
private readonly IFormFactory formFactory;
|
||||
|
||||
public BatchScanPerformer(IScanPerformer scanPerformer, IProfileManager profileManager, FileNamePlaceholders fileNamePlaceholders, IPdfExporter pdfExporter, IOperationFactory operationFactory, PdfSettingsContainer pdfSettingsContainer, OcrManager ocrManager, IFormFactory formFactory)
|
||||
public BatchScanPerformer(IScanPerformer scanPerformer, IProfileManager profileManager, IPdfExporter pdfExporter, IOperationFactory operationFactory, PdfSettingsContainer pdfSettingsContainer, OcrManager ocrManager, IFormFactory formFactory)
|
||||
{
|
||||
this.scanPerformer = scanPerformer;
|
||||
this.profileManager = profileManager;
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
this.pdfExporter = pdfExporter;
|
||||
this.operationFactory = operationFactory;
|
||||
this.pdfSettingsContainer = pdfSettingsContainer;
|
||||
@ -44,7 +42,7 @@ namespace NAPS2.Scan.Batch
|
||||
|
||||
public async Task PerformBatchScan(BatchSettings settings, FormBase batchForm, Action<ScannedImage> imageCallback, Action<string> progressCallback, CancellationToken cancelToken)
|
||||
{
|
||||
var state = new BatchState(scanPerformer, profileManager, fileNamePlaceholders, pdfExporter, operationFactory, pdfSettingsContainer, ocrManager, formFactory)
|
||||
var state = new BatchState(scanPerformer, profileManager, pdfExporter, operationFactory, pdfSettingsContainer, ocrManager, formFactory)
|
||||
{
|
||||
Settings = settings,
|
||||
ProgressCallback = progressCallback,
|
||||
@ -59,7 +57,6 @@ namespace NAPS2.Scan.Batch
|
||||
{
|
||||
private readonly IScanPerformer scanPerformer;
|
||||
private readonly IProfileManager profileManager;
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
private readonly IPdfExporter pdfExporter;
|
||||
private readonly IOperationFactory operationFactory;
|
||||
private readonly PdfSettingsContainer pdfSettingsContainer;
|
||||
@ -70,11 +67,10 @@ namespace NAPS2.Scan.Batch
|
||||
private ScanParams scanParams;
|
||||
private List<List<ScannedImage>> scans;
|
||||
|
||||
public BatchState(IScanPerformer scanPerformer, IProfileManager profileManager, FileNamePlaceholders fileNamePlaceholders, IPdfExporter pdfExporter, IOperationFactory operationFactory, PdfSettingsContainer pdfSettingsContainer, OcrManager ocrManager, IFormFactory formFactory)
|
||||
public BatchState(IScanPerformer scanPerformer, IProfileManager profileManager, IPdfExporter pdfExporter, IOperationFactory operationFactory, PdfSettingsContainer pdfSettingsContainer, OcrManager ocrManager, IFormFactory formFactory)
|
||||
{
|
||||
this.scanPerformer = scanPerformer;
|
||||
this.profileManager = profileManager;
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
this.pdfExporter = pdfExporter;
|
||||
this.operationFactory = operationFactory;
|
||||
this.pdfSettingsContainer = pdfSettingsContainer;
|
||||
@ -228,7 +224,7 @@ namespace NAPS2.Scan.Batch
|
||||
{
|
||||
ProgressCallback(MiscResources.BatchStatusSaving);
|
||||
|
||||
var now = DateTime.Now;
|
||||
var placeholders = Placeholders.All.WithDate(DateTime.Now);
|
||||
var allImages = scans.SelectMany(x => x).ToList();
|
||||
|
||||
if (Settings.OutputType == BatchOutputType.Load)
|
||||
@ -240,7 +236,7 @@ namespace NAPS2.Scan.Batch
|
||||
}
|
||||
else if (Settings.OutputType == BatchOutputType.SingleFile)
|
||||
{
|
||||
await Save(now, 0, allImages);
|
||||
await Save(placeholders, 0, allImages);
|
||||
foreach (var img in allImages)
|
||||
{
|
||||
img.Dispose();
|
||||
@ -251,7 +247,7 @@ namespace NAPS2.Scan.Batch
|
||||
int i = 0;
|
||||
foreach (var imageList in SaveSeparatorHelper.SeparateScans(scans, Settings.SaveSeparator))
|
||||
{
|
||||
await Save(now, i++, imageList);
|
||||
await Save(placeholders, i++, imageList);
|
||||
foreach (var img in imageList)
|
||||
{
|
||||
img.Dispose();
|
||||
@ -260,18 +256,18 @@ namespace NAPS2.Scan.Batch
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Save(DateTime now, int i, List<ScannedImage> images)
|
||||
private async Task Save(Placeholders placeholders, int i, List<ScannedImage> images)
|
||||
{
|
||||
if (images.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var subPath = fileNamePlaceholders.SubstitutePlaceholders(Settings.SavePath, now, true, i);
|
||||
var subPath = placeholders.Substitute(Settings.SavePath, true, i);
|
||||
if (GetSavePathExtension().ToLower() == ".pdf")
|
||||
{
|
||||
if (File.Exists(subPath))
|
||||
{
|
||||
subPath = fileNamePlaceholders.SubstitutePlaceholders(subPath, now, true, 0, 1);
|
||||
subPath = placeholders.Substitute(subPath, true, 0, 1);
|
||||
}
|
||||
var snapshots = images.Select(x => x.Preserve()).ToList();
|
||||
try
|
||||
@ -286,7 +282,7 @@ namespace NAPS2.Scan.Batch
|
||||
else
|
||||
{
|
||||
var op = operationFactory.Create<SaveImagesOperation>();
|
||||
op.Start(subPath, now, images, true);
|
||||
op.Start(subPath, placeholders, images, true);
|
||||
await op.Success;
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,8 @@ namespace NAPS2.WinForms
|
||||
{
|
||||
public partial class FPlaceholders : FormBase
|
||||
{
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
|
||||
public FPlaceholders(FileNamePlaceholders fileNamePlaceholders)
|
||||
public FPlaceholders()
|
||||
{
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
AcceptButton = btnOK;
|
||||
@ -29,19 +26,19 @@ namespace NAPS2.WinForms
|
||||
// Annoying, but oh well.
|
||||
var placeholders = new[]
|
||||
{
|
||||
FileNamePlaceholders.YEAR_4_DIGITS,
|
||||
FileNamePlaceholders.YEAR_2_DIGITS,
|
||||
FileNamePlaceholders.MONTH_2_DIGITS,
|
||||
FileNamePlaceholders.DAY_2_DIGITS,
|
||||
FileNamePlaceholders.HOUR_24_CLOCK,
|
||||
FileNamePlaceholders.MINUTE_2_DIGITS,
|
||||
FileNamePlaceholders.SECOND_2_DIGITS,
|
||||
FileNamePlaceholders.NUMBER_4_DIGITS,
|
||||
FileNamePlaceholders.NUMBER_3_DIGITS,
|
||||
FileNamePlaceholders.NUMBER_2_DIGITS,
|
||||
FileNamePlaceholders.NUMBER_1_DIGIT,
|
||||
$"{FileNamePlaceholders.YEAR_4_DIGITS}-{FileNamePlaceholders.MONTH_2_DIGITS}-{FileNamePlaceholders.DAY_2_DIGITS}",
|
||||
$"{FileNamePlaceholders.HOUR_24_CLOCK}_{FileNamePlaceholders.MINUTE_2_DIGITS}_{FileNamePlaceholders.SECOND_2_DIGITS}",
|
||||
Placeholders.YEAR_4_DIGITS,
|
||||
Placeholders.YEAR_2_DIGITS,
|
||||
Placeholders.MONTH_2_DIGITS,
|
||||
Placeholders.DAY_2_DIGITS,
|
||||
Placeholders.HOUR_24_CLOCK,
|
||||
Placeholders.MINUTE_2_DIGITS,
|
||||
Placeholders.SECOND_2_DIGITS,
|
||||
Placeholders.NUMBER_4_DIGITS,
|
||||
Placeholders.NUMBER_3_DIGITS,
|
||||
Placeholders.NUMBER_2_DIGITS,
|
||||
Placeholders.NUMBER_1_DIGIT,
|
||||
$"{Placeholders.YEAR_4_DIGITS}-{Placeholders.MONTH_2_DIGITS}-{Placeholders.DAY_2_DIGITS}",
|
||||
$"{Placeholders.HOUR_24_CLOCK}_{Placeholders.MINUTE_2_DIGITS}_{Placeholders.SECOND_2_DIGITS}",
|
||||
};
|
||||
var buttons = gboxPlaceholders.Controls.OfType<Button>().OrderBy(x => x.Top).ThenBy(x => x.Left).ToArray();
|
||||
for (int i = 0; i < Math.Min(placeholders.Length, buttons.Length); i++)
|
||||
@ -74,7 +71,7 @@ namespace NAPS2.WinForms
|
||||
|
||||
private void txtFileName_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
lblPreview.Text = fileNamePlaceholders.SubstitutePlaceholders(txtFileName.Text, DateTime.Now, false);
|
||||
lblPreview.Text = Placeholders.All.Substitute(txtFileName.Text, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,20 +23,18 @@ namespace NAPS2.WinForms
|
||||
private readonly ImageSettingsContainer imageSettingsContainer;
|
||||
private readonly EmailSettingsContainer emailSettingsContainer;
|
||||
private readonly DialogHelper dialogHelper;
|
||||
private readonly FileNamePlaceholders fileNamePlaceholders;
|
||||
private readonly ChangeTracker changeTracker;
|
||||
private readonly IOperationFactory operationFactory;
|
||||
private readonly IFormFactory formFactory;
|
||||
private readonly OcrManager ocrManager;
|
||||
private readonly IOperationProgress operationProgress;
|
||||
|
||||
public WinFormsExportHelper(PdfSettingsContainer pdfSettingsContainer, ImageSettingsContainer imageSettingsContainer, EmailSettingsContainer emailSettingsContainer, DialogHelper dialogHelper, FileNamePlaceholders fileNamePlaceholders, ChangeTracker changeTracker, IOperationFactory operationFactory, IFormFactory formFactory, OcrManager ocrManager, IOperationProgress operationProgress)
|
||||
public WinFormsExportHelper(PdfSettingsContainer pdfSettingsContainer, ImageSettingsContainer imageSettingsContainer, EmailSettingsContainer emailSettingsContainer, DialogHelper dialogHelper, ChangeTracker changeTracker, IOperationFactory operationFactory, IFormFactory formFactory, OcrManager ocrManager, IOperationProgress operationProgress)
|
||||
{
|
||||
this.pdfSettingsContainer = pdfSettingsContainer;
|
||||
this.imageSettingsContainer = imageSettingsContainer;
|
||||
this.emailSettingsContainer = emailSettingsContainer;
|
||||
this.dialogHelper = dialogHelper;
|
||||
this.fileNamePlaceholders = fileNamePlaceholders;
|
||||
this.changeTracker = changeTracker;
|
||||
this.operationFactory = operationFactory;
|
||||
this.formFactory = formFactory;
|
||||
@ -63,7 +61,7 @@ namespace NAPS2.WinForms
|
||||
}
|
||||
}
|
||||
|
||||
var subSavePath = fileNamePlaceholders.SubstitutePlaceholders(savePath, DateTime.Now);
|
||||
var subSavePath = Placeholders.All.Substitute(savePath);
|
||||
var changeToken = changeTracker.State;
|
||||
if (await ExportPDF(subSavePath, images, false, null))
|
||||
{
|
||||
@ -81,7 +79,7 @@ namespace NAPS2.WinForms
|
||||
|
||||
var pdfSettings = pdfSettingsContainer.PdfSettings;
|
||||
pdfSettings.Metadata.Creator = MiscResources.NAPS2;
|
||||
if (op.Start(filename, DateTime.Now, images, pdfSettings, ocrManager.DefaultParams, email, emailMessage))
|
||||
if (op.Start(filename, Placeholders.All.WithDate(DateTime.Now), images, pdfSettings, ocrManager.DefaultParams, email, emailMessage))
|
||||
{
|
||||
operationProgress.ShowProgress(op);
|
||||
}
|
||||
@ -109,7 +107,7 @@ namespace NAPS2.WinForms
|
||||
|
||||
var op = operationFactory.Create<SaveImagesOperation>();
|
||||
var changeToken = changeTracker.State;
|
||||
if (op.Start(savePath, DateTime.Now, images))
|
||||
if (op.Start(savePath, Placeholders.All.WithDate(DateTime.Now), images))
|
||||
{
|
||||
operationProgress.ShowProgress(op);
|
||||
}
|
||||
@ -151,7 +149,7 @@ namespace NAPS2.WinForms
|
||||
{
|
||||
attachmentName += ".pdf";
|
||||
}
|
||||
attachmentName = fileNamePlaceholders.SubstitutePlaceholders(attachmentName, DateTime.Now, false);
|
||||
attachmentName = Placeholders.All.Substitute(attachmentName, false);
|
||||
|
||||
var tempFolder = new DirectoryInfo(Path.Combine(Paths.Temp, Path.GetRandomFileName()));
|
||||
tempFolder.Create();
|
||||
|
Loading…
Reference in New Issue
Block a user