-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathFolderMonitorManager.cs
More file actions
152 lines (130 loc) · 5.38 KB
/
Copy pathFolderMonitorManager.cs
File metadata and controls
152 lines (130 loc) · 5.38 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using Playnite.SDK;
using System;
using System.IO;
using System.Threading;
namespace SharpMemories
{
public class FolderMonitorManager
{
private static readonly ILogger logger = LogManager.GetLogger();
private readonly SharpMemoriesSettingsViewModel settings;
private FileSystemWatcher fileWatcher;
private string currentGameTitle = null;
public FolderMonitorManager(SharpMemoriesSettingsViewModel settings)
{
this.settings = settings;
}
public void StartMonitoring(string gameTitle)
{
var monitorFolder = settings?.Settings?.MonitorFolder;
if (string.IsNullOrWhiteSpace(monitorFolder))
{
logger.Debug("Monitor folder is not configured, skipping folder monitoring");
return;
}
logger.Info($"Starting folder monitor for: {monitorFolder}");
if (fileWatcher != null)
{
logger.Debug("Disposing existing file watcher before creating new one");
fileWatcher.Dispose();
}
currentGameTitle = gameTitle;
fileWatcher = new FileSystemWatcher(monitorFolder)
{
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime,
Filter = "*.*", // Monitor all files
EnableRaisingEvents = true
};
fileWatcher.Created += OnNewScreenshot;
logger.Debug("File watcher created and event handler attached");
}
public void StopMonitoring()
{
if (fileWatcher != null)
{
logger.Info("Stopping folder monitor");
fileWatcher.EnableRaisingEvents = false;
fileWatcher.Dispose();
fileWatcher = null;
logger.Debug("File watcher disposed");
}
else
{
logger.Debug("No active file watcher to stop");
}
currentGameTitle = null;
}
private void OnNewScreenshot(object sender, FileSystemEventArgs e)
{
try
{
logger.Debug($"New file detected in monitor folder: {e.FullPath}");
if (string.IsNullOrWhiteSpace(currentGameTitle))
{
logger.Warn("No game is currently open. Ignoring new file.");
return;
}
var outFolder = settings?.Settings?.OutputFolder;
if (string.IsNullOrWhiteSpace(outFolder))
{
outFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Playnite", "Plugins", "SharpMemories", "Screenshots");
logger.Debug($"Using default output folder: {outFolder}");
}
var safeTitle = FileHelpers.MakeSafeFilename(currentGameTitle);
var gameFolder = Path.Combine(outFolder, safeTitle);
try { Directory.CreateDirectory(gameFolder); } catch (Exception ex) { logger.Error(ex, "Failed to create game folder"); }
var destinationPath = Path.Combine(gameFolder, Path.GetFileName(e.FullPath));
// Wait for file to become available before attempting to move it
if (!WaitForFileAccess(e.FullPath, maxWaitSeconds: 10))
{
logger.Error($"Timeout waiting for file access: {e.FullPath}");
return;
}
File.Move(e.FullPath, destinationPath);
logger.Info($"Moved file '{e.FullPath}' to '{destinationPath}'");
}
catch (Exception ex)
{
logger.Error(ex, $"Error handling new file: {e.FullPath}");
}
}
private bool WaitForFileAccess(string filePath, int maxWaitSeconds = 10)
{
var maxAttempts = maxWaitSeconds * 10; // Check every 100ms
for (int i = 0; i < maxAttempts; i++)
{
try
{
// Try to open the file exclusively to check if it's accessible
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
logger.Debug($"File is now accessible: {filePath} (after {i * 100}ms)");
return true;
}
}
catch (FileNotFoundException)
{
logger.Warn($"File no longer exists: {filePath}");
return false;
}
catch (IOException)
{
// File is still locked, wait and retry
if (i == 0)
{
logger.Debug($"File is locked, waiting for access: {filePath}");
}
Thread.Sleep(100);
}
catch (UnauthorizedAccessException)
{
// Permission issue
logger.Error($"Access denied to file: {filePath}");
return false;
}
}
logger.Warn($"Timeout waiting for file access after {maxWaitSeconds} seconds: {filePath}");
return false;
}
}
}