-
Notifications
You must be signed in to change notification settings - Fork 0
/
file-automation.csx
103 lines (97 loc) · 2.71 KB
/
file-automation.csx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System.IO;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System;
/* Usage:
var pattern = new List<CopyOrder> { ... };
FileProcessor.Start(pattern);
*/
static void Log(string message)
{
Console.WriteLine(String.Concat(DateTime.Now.ToString("hh:mm:ss"), " ", message));
}
class FileProcessor
{
public static void Start(IEnumerable<CopyOrder> orders, bool forceCopy = false)
{
foreach (var order in orders)
{
Log($"Registering {Path.GetFileName(order.Source)}");
var watcher = new FileSystemWatcher(Path.GetDirectoryName(order.Source), Path.GetFileName(order.Source));
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Changed += (async (o, e) =>
{
await order.Act();
});
watcher.EnableRaisingEvents = true;
if (forceCopy)
{
Task.Run(async() =>
{
await order.Act();
});
}
}
}
}
class CopyOrder
{
public string Source;
public string Destination;
public Action OnCompleted;
private CancellationTokenSource _tokenSource;
public CopyOrder(string source, string destination, Action onCompleted = null)
{
Source = source;
Destination = destination;
OnCompleted = onCompleted;
_tokenSource = new CancellationTokenSource();
}
public async Task Act()
{
_tokenSource.Cancel();
_tokenSource = new CancellationTokenSource();
var fileName = Path.GetFileName(Source);
var token = _tokenSource.Token;
await Task.Delay(1000);
if (token.IsCancellationRequested)
{
Log($"Received another event for {fileName}");
return;
}
Log($"Processing {fileName}");
var attempts = 5;
int backoff = 1;
while (attempts-- > 0)
{
try
{
File.Copy(Source, Destination, true);
Log($"Copied {fileName}");
break;
}
catch (IOException)
{
Log($"Still unable to copy {fileName}... Waiting {backoff}s.");
await Task.Delay(backoff*1000);
backoff *= 2;
continue;
}
catch
{
Log($"Error copying {fileName}");
return;
}
}
if (attempts == 0)
{
Log($"Giving up on {fileName}");
}
if (OnCompleted != null)
{
Log("Invoking post-copy action...");
OnCompleted.Invoke();
}
}
}