This version will wok more properly
This commit is contained in:
parent
e62c996c6e
commit
29c8fe06c6
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@ -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": []
|
|
||||||
}
|
|
27
PhotoRenamer/.vscode/launch.json
vendored
Normal file
27
PhotoRenamer/.vscode/launch.json
vendored
Normal file
@ -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}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -7,7 +7,7 @@
|
|||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"${workspaceFolder}/PhotoRenamer/PhotoRenamer.csproj",
|
"${workspaceFolder}/PhotoRenamer.csproj",
|
||||||
"/property:GenerateFullPaths=true",
|
"/property:GenerateFullPaths=true",
|
||||||
"/consoleloggerparameters:NoSummary"
|
"/consoleloggerparameters:NoSummary"
|
||||||
],
|
],
|
||||||
@ -19,7 +19,7 @@
|
|||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
"publish",
|
"publish",
|
||||||
"${workspaceFolder}/PhotoRenamer/PhotoRenamer.csproj",
|
"${workspaceFolder}/PhotoRenamer.csproj",
|
||||||
"/property:GenerateFullPaths=true",
|
"/property:GenerateFullPaths=true",
|
||||||
"/consoleloggerparameters:NoSummary"
|
"/consoleloggerparameters:NoSummary"
|
||||||
],
|
],
|
||||||
@ -32,7 +32,7 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"watch",
|
"watch",
|
||||||
"run",
|
"run",
|
||||||
"${workspaceFolder}/PhotoRenamer/PhotoRenamer.csproj",
|
"${workspaceFolder}/PhotoRenamer.csproj",
|
||||||
"/property:GenerateFullPaths=true",
|
"/property:GenerateFullPaths=true",
|
||||||
"/consoleloggerparameters:NoSummary"
|
"/consoleloggerparameters:NoSummary"
|
||||||
],
|
],
|
@ -15,6 +15,7 @@
|
|||||||
<PackageReference Include="Serilog" Version="2.9.0" />
|
<PackageReference Include="Serilog" Version="2.9.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||||
<PackageReference Include="ShellProgressBar" Version="5.0.0" />
|
<PackageReference Include="ShellProgressBar" Version="5.0.0" />
|
||||||
|
<PackageReference Include="QuickIO.NET" Version="2.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -17,8 +17,8 @@ namespace PhotoRenamer
|
|||||||
Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
|
Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var p = new Renamer(configuration);
|
var renamer = new Renamer(configuration);
|
||||||
return p.Run();
|
return renamer.Run();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using MetadataExtractor;
|
using MetadataExtractor;
|
||||||
using MetadataExtractor.Formats.Exif;
|
using MetadataExtractor.Formats.Exif;
|
||||||
using MetadataExtractor.Formats.QuickTime;
|
using MetadataExtractor.Formats.QuickTime;
|
||||||
@ -15,14 +18,22 @@ namespace PhotoRenamer
|
|||||||
internal class Renamer
|
internal class Renamer
|
||||||
{
|
{
|
||||||
private readonly string _sourcePath;
|
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"]);
|
_sourcePath = Path.GetFullPath(configuration["Source"]);
|
||||||
_targetPath = Path.GetFullPath(configuration["Target"]);
|
_targetPath = Path.GetFullPath(configuration["Target"]);
|
||||||
Log.Information($"Source path: {_sourcePath}");
|
Log.Information($"Source path: {_sourcePath}");
|
||||||
Log.Information($"Target path: {_targetPath}");
|
Log.Information($"Target path: {_targetPath}");
|
||||||
|
_childOptions = new ProgressBarOptions
|
||||||
|
{
|
||||||
|
ForegroundColor = ConsoleColor.Yellow,
|
||||||
|
BackgroundColor = ConsoleColor.DarkGreen,
|
||||||
|
ProgressCharacter = '─',
|
||||||
|
CollapseWhenFinished = true
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Run()
|
public int Run()
|
||||||
@ -33,44 +44,58 @@ namespace PhotoRenamer
|
|||||||
ForegroundColor = ConsoleColor.Yellow,
|
ForegroundColor = ConsoleColor.Yellow,
|
||||||
ForegroundColorDone = ConsoleColor.DarkGreen,
|
ForegroundColorDone = ConsoleColor.DarkGreen,
|
||||||
BackgroundColor = ConsoleColor.DarkGray,
|
BackgroundColor = ConsoleColor.DarkGray,
|
||||||
BackgroundCharacter = '\u2593'
|
BackgroundCharacter = '\u2593'
|
||||||
};
|
};
|
||||||
|
var i = 0;
|
||||||
using var progressBar = new ProgressBar(files.Length, "Copying files", options);
|
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
|
try
|
||||||
{
|
{
|
||||||
var directories = ImageMetadataReader.ReadMetadata(file);
|
var directories = ImageMetadataReader.ReadMetadata(file);
|
||||||
|
|
||||||
var dateTime = GetDateTimeFromExif(directories) ?? GetDateTimeFromMp4(directories);
|
var dateTime = GetDateTimeFromExif(directories) ?? GetDateTimeFromMp4(directories);
|
||||||
if (dateTime is null) continue;
|
if (!(dateTime is null))
|
||||||
var folder = CreateFolder(dateTime.GetValueOrDefault());
|
{
|
||||||
CopyFile(folder, file);
|
var folder = CreateFolder(dateTime.GetValueOrDefault());
|
||||||
|
CopyFile(folder, file, progressBar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ImageProcessingException)
|
catch (ImageProcessingException)
|
||||||
{
|
{
|
||||||
//silently ignore
|
//silently ignore
|
||||||
}
|
}
|
||||||
}
|
finally
|
||||||
|
{
|
||||||
|
System.Threading.Interlocked.Increment(ref i);
|
||||||
|
progressBar.Tick(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return 0;
|
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));
|
var destination = new FileInfo(Path.Combine(folder, Path.GetFileName(file)));
|
||||||
if (File.Exists(destination)) return;
|
var source = new FileInfo(file);
|
||||||
File.Copy(file, destination);
|
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)
|
private string CreateFolder(DateTime dateTime)
|
||||||
{
|
{
|
||||||
var folder = Path.Combine(
|
var folder = Path.Combine(_targetPath, dateTime.Year.ToString(), dateTime.Month.ToString("D2"));
|
||||||
_targetPath,
|
|
||||||
dateTime.Year.ToString(),
|
|
||||||
dateTime.Month.ToString("D2"),
|
|
||||||
dateTime.Day.ToString("D2"));
|
|
||||||
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
|
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"Source": "C:\\Users\\Holger\\Nextcloud\\DCIM",
|
"Source": "\\\\micro\\photo\\Oneplus5",
|
||||||
"Target": "C:\\Target"
|
"Target": "\\\\micro\\photo\\Oneplus5"
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user