diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 5c7247b..0000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": []
-}
\ No newline at end of file
diff --git a/PhotoRenamer/.vscode/launch.json b/PhotoRenamer/.vscode/launch.json
new file mode 100644
index 0000000..9d886c5
--- /dev/null
+++ b/PhotoRenamer/.vscode/launch.json
@@ -0,0 +1,27 @@
+{
+ // Use IntelliSense to find out which attributes exist for C# debugging
+ // Use hover for the description of the existing attributes
+ // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": ".NET Core Launch (console)",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ // If you have changed target frameworks, make sure to update the program path.
+ "program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/PhotoRenamer.dll",
+ "args": [],
+ "cwd": "${workspaceFolder}",
+ // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
+ "console": "internalConsole",
+ "stopAtEntry": false
+ },
+ {
+ "name": ".NET Core Attach",
+ "type": "coreclr",
+ "request": "attach",
+ "processId": "${command:pickProcess}"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/PhotoRenamer/.vscode/tasks.json
similarity index 83%
rename from .vscode/tasks.json
rename to PhotoRenamer/.vscode/tasks.json
index d04cf29..defd202 100644
--- a/.vscode/tasks.json
+++ b/PhotoRenamer/.vscode/tasks.json
@@ -7,7 +7,7 @@
"type": "process",
"args": [
"build",
- "${workspaceFolder}/PhotoRenamer/PhotoRenamer.csproj",
+ "${workspaceFolder}/PhotoRenamer.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
@@ -19,7 +19,7 @@
"type": "process",
"args": [
"publish",
- "${workspaceFolder}/PhotoRenamer/PhotoRenamer.csproj",
+ "${workspaceFolder}/PhotoRenamer.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
@@ -32,7 +32,7 @@
"args": [
"watch",
"run",
- "${workspaceFolder}/PhotoRenamer/PhotoRenamer.csproj",
+ "${workspaceFolder}/PhotoRenamer.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
diff --git a/PhotoRenamer/PhotoRenamer.csproj b/PhotoRenamer/PhotoRenamer.csproj
index dafa349..4d5e24a 100644
--- a/PhotoRenamer/PhotoRenamer.csproj
+++ b/PhotoRenamer/PhotoRenamer.csproj
@@ -15,6 +15,7 @@
+
diff --git a/PhotoRenamer/Program.cs b/PhotoRenamer/Program.cs
index f6e2e39..fe7d72a 100644
--- a/PhotoRenamer/Program.cs
+++ b/PhotoRenamer/Program.cs
@@ -17,8 +17,8 @@ namespace PhotoRenamer
Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
try
{
- var p = new Renamer(configuration);
- return p.Run();
+ var renamer = new Renamer(configuration);
+ return renamer.Run();
}
catch (Exception e)
{
diff --git a/PhotoRenamer/Renamer.cs b/PhotoRenamer/Renamer.cs
index 510b563..24738cb 100644
--- a/PhotoRenamer/Renamer.cs
+++ b/PhotoRenamer/Renamer.cs
@@ -2,6 +2,9 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
using MetadataExtractor;
using MetadataExtractor.Formats.Exif;
using MetadataExtractor.Formats.QuickTime;
@@ -15,14 +18,22 @@ namespace PhotoRenamer
internal class Renamer
{
private readonly string _sourcePath;
- private readonly string _targetPath;
+ private readonly string _targetPath;
+ private readonly ProgressBarOptions _childOptions;
- public Renamer(IConfiguration configuration)
+ public Renamer(IConfiguration configuration)
{
_sourcePath = Path.GetFullPath(configuration["Source"]);
_targetPath = Path.GetFullPath(configuration["Target"]);
Log.Information($"Source path: {_sourcePath}");
Log.Information($"Target path: {_targetPath}");
+ _childOptions = new ProgressBarOptions
+ {
+ ForegroundColor = ConsoleColor.Yellow,
+ BackgroundColor = ConsoleColor.DarkGreen,
+ ProgressCharacter = '─',
+ CollapseWhenFinished = true
+ };
}
public int Run()
@@ -33,44 +44,58 @@ namespace PhotoRenamer
ForegroundColor = ConsoleColor.Yellow,
ForegroundColorDone = ConsoleColor.DarkGreen,
BackgroundColor = ConsoleColor.DarkGray,
- BackgroundCharacter = '\u2593'
- };
+ BackgroundCharacter = '\u2593'
+ };
+ var i = 0;
using var progressBar = new ProgressBar(files.Length, "Copying files", options);
- foreach (var file in files)
+ var po = new ParallelOptions { MaxDegreeOfParallelism = 4};
+ Parallel.ForEach(files, po, file =>
{
- progressBar.Tick();
try
{
var directories = ImageMetadataReader.ReadMetadata(file);
-
var dateTime = GetDateTimeFromExif(directories) ?? GetDateTimeFromMp4(directories);
- if (dateTime is null) continue;
- var folder = CreateFolder(dateTime.GetValueOrDefault());
- CopyFile(folder, file);
+ if (!(dateTime is null))
+ {
+ var folder = CreateFolder(dateTime.GetValueOrDefault());
+ CopyFile(folder, file, progressBar);
+ }
}
catch (ImageProcessingException)
{
//silently ignore
}
- }
+ finally
+ {
+ System.Threading.Interlocked.Increment(ref i);
+ progressBar.Tick(i);
+ }
+ });
return 0;
}
- private static void CopyFile(string folder, string file)
+ private void CopyFile(string folder, string file, ProgressBarBase progressBar)
{
- var destination = Path.Combine(folder, Path.GetFileName(file));
- if (File.Exists(destination)) return;
- File.Copy(file, destination);
+ var destination = new FileInfo(Path.Combine(folder, Path.GetFileName(file)));
+ var source = new FileInfo(file);
+ if (destination.Exists && destination.Length == source.Length) return;
+
+ using var child = progressBar.Spawn(100, destination.FullName, _childOptions);
+ using var client = new WebClient();
+ client.DownloadProgressChanged += (o, args) => child.Tick(args.ProgressPercentage);
+ client.DownloadFileAsync(new Uri(source.FullName), destination.FullName);
+ while (client.IsBusy)
+ {
+ Thread.Sleep(100);
+ }
+ //source.CopyTo(destination.FullName, true);
+ child.Tick(100);
}
private string CreateFolder(DateTime dateTime)
{
- var folder = Path.Combine(
- _targetPath,
- dateTime.Year.ToString(),
- dateTime.Month.ToString("D2"),
- dateTime.Day.ToString("D2"));
+ var folder = Path.Combine(_targetPath, dateTime.Year.ToString(), dateTime.Month.ToString("D2"));
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
return folder;
}
@@ -81,7 +106,7 @@ namespace PhotoRenamer
.OfType()
.FirstOrDefault()?.GetDateTime(ExifDirectoryBase.TagDateTimeOriginal);
}
-
+
private static DateTime? GetDateTimeFromMp4(IEnumerable directories)
{
return directories
diff --git a/PhotoRenamer/appsettings.json b/PhotoRenamer/appsettings.json
index bc61897..26abaa0 100644
--- a/PhotoRenamer/appsettings.json
+++ b/PhotoRenamer/appsettings.json
@@ -1,4 +1,4 @@
{
- "Source": "C:\\Users\\Holger\\Nextcloud\\DCIM",
- "Target": "C:\\Target"
+ "Source": "\\\\micro\\photo\\Oneplus5",
+ "Target": "\\\\micro\\photo\\Oneplus5"
}
\ No newline at end of file