146 lines
5.8 KiB
C#
146 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace FileInterface.Scheduler
|
|
{
|
|
public sealed class CronJobExecutor
|
|
{
|
|
private readonly ICustomFunctionInvoker _invoker;
|
|
private readonly JobLog _log;
|
|
|
|
public CronJobExecutor(ICustomFunctionInvoker invoker, JobLog log)
|
|
{
|
|
_invoker = invoker;
|
|
_log = log;
|
|
}
|
|
|
|
public void Execute(CronJobConfig job)
|
|
{
|
|
if (job.CallOnceWithoutFile)
|
|
{
|
|
ExecuteSingle(job, null);
|
|
return;
|
|
}
|
|
|
|
if (!Directory.Exists(job.SourceDirectory))
|
|
{
|
|
_log.Error(job, "Source directory does not exist: " + job.SourceDirectory);
|
|
return;
|
|
}
|
|
|
|
SearchOption option = job.IncludeSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
|
string[] files;
|
|
try
|
|
{
|
|
files = Directory.GetFiles(job.SourceDirectory, String.IsNullOrWhiteSpace(job.SearchPattern) ? "*.*" : job.SearchPattern, option)
|
|
.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)
|
|
.ToArray();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Error(job, "Cannot enumerate source files: " + ex.Message);
|
|
return;
|
|
}
|
|
|
|
_log.Info(job, "Found " + files.Length + " file(s).");
|
|
foreach (string file in files)
|
|
{
|
|
try { ExecuteSingle(job, file); }
|
|
catch (Exception ex) { _log.Error(job, "File failed: " + file + " - " + ex.Message); }
|
|
}
|
|
}
|
|
|
|
private void ExecuteSingle(CronJobConfig job, string file)
|
|
{
|
|
string rawContent = "";
|
|
string processedContent = "";
|
|
|
|
if (file != null)
|
|
{
|
|
// Opening with FileShare.ReadWrite prevents common producer/consumer lock issues.
|
|
using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
|
using (var reader = new StreamReader(stream, Encoding.UTF8, true))
|
|
rawContent = reader.ReadToEnd();
|
|
|
|
processedContent = ProcessContent(rawContent, job.RemoveEmptyLines, job.JoinSeparator);
|
|
}
|
|
|
|
string[] inArgs = (job.InArgs ?? new List<string>())
|
|
.Select(arg => Expand(arg, job, file, rawContent, processedContent))
|
|
.ToArray();
|
|
|
|
_log.Info(job, "Calling CustomFunction '" + job.CustomFunction + "' with " + inArgs.Length + " inArg(s)" + (file == null ? "." : " for " + Path.GetFileName(file) + "."));
|
|
CustomFunctionCallResult result = _invoker.Invoke(job.CustomFunction, inArgs);
|
|
if (result == null) result = CustomFunctionCallResult.Fail("Invoker returned null.");
|
|
|
|
if (!result.Success)
|
|
{
|
|
_log.Error(job, "CustomFunction failed: " + result.Message);
|
|
return;
|
|
}
|
|
|
|
_log.Info(job, "CustomFunction succeeded: " + result.Message);
|
|
if (file != null && job.MoveFileAfterSuccess)
|
|
{
|
|
string movedTo = MoveProcessedFile(file, job.MoveTargetDirectory, job.OverwriteTargetFile);
|
|
_log.Info(job, "Moved file to: " + movedTo);
|
|
}
|
|
}
|
|
|
|
private static string ProcessContent(string text, bool removeEmptyLines, string separator)
|
|
{
|
|
if (!removeEmptyLines) return text ?? "";
|
|
string[] lines = (text ?? "").Replace("\r\n", "\n").Replace('\r', '\n').Split('\n');
|
|
return String.Join(separator ?? ";", lines.Where(l => !String.IsNullOrWhiteSpace(l)).Select(l => l.Trim()));
|
|
}
|
|
|
|
private static string Expand(string template, CronJobConfig job, string file, string rawContent, string processedContent)
|
|
{
|
|
string value = template ?? "";
|
|
string fullPath = file ?? "";
|
|
string fileName = file == null ? "" : Path.GetFileName(file);
|
|
string extension = file == null ? "" : Path.GetExtension(file);
|
|
string directory = file == null ? "" : Path.GetDirectoryName(file);
|
|
|
|
return value
|
|
.Replace("{{CONTENT}}", processedContent ?? "")
|
|
.Replace("{{RAW_CONTENT}}", rawContent ?? "")
|
|
.Replace("{{FILE_NAME}}", fileName ?? "")
|
|
.Replace("{{FILE_PATH}}", fullPath)
|
|
.Replace("{{FILE_DIR}}", directory ?? "")
|
|
.Replace("{{FILE_EXT}}", extension ?? "")
|
|
.Replace("{{JOB_NAME}}", job.Name ?? "")
|
|
.Replace("{{NOW}}", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffK"));
|
|
}
|
|
|
|
private static string MoveProcessedFile(string source, string targetDirectory, bool overwrite)
|
|
{
|
|
Directory.CreateDirectory(targetDirectory);
|
|
string target = Path.Combine(targetDirectory, Path.GetFileName(source));
|
|
|
|
if (File.Exists(target))
|
|
{
|
|
if (overwrite) File.Delete(target);
|
|
else
|
|
{
|
|
string name = Path.GetFileNameWithoutExtension(source);
|
|
string ext = Path.GetExtension(source);
|
|
target = Path.Combine(targetDirectory, name + "_" + DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ext);
|
|
int i = 1;
|
|
while (File.Exists(target))
|
|
{
|
|
target = Path.Combine(targetDirectory, name + "_" + DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + "_" + i + ext);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
File.Move(source, target);
|
|
return target;
|
|
}
|
|
}
|
|
}
|