Updated to dotnet 7

This commit is contained in:
Holger Börchers 2022-11-30 15:34:29 +01:00
parent 232846f4d1
commit 4157993abd
7 changed files with 149 additions and 84 deletions

View File

@ -1,20 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
<PackageReference Include="coverlet.collector" Version="1.3.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="coverlet.collector" Version="3.2.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace PhotoRenamer
namespace PhotoRenamer
{
public static class FilesHelper
{

View File

@ -0,0 +1,76 @@
namespace PhotoRenamer
{
public static class HttpClientExtensions
{
public static async Task DownloadAsync(
this HttpClient client,
string requestUri,
Stream destination,
IProgress<float>? progress = null,
CancellationToken cancellationToken = default
)
{
// Get the http headers first to examine the content length
using var response = await client.GetAsync(
requestUri,
HttpCompletionOption.ResponseHeadersRead
);
var contentLength = response.Content.Headers.ContentLength;
using var download = await response.Content.ReadAsStreamAsync(cancellationToken);
// Ignore progress reporting when no progress reporter was
// passed or when the content length is unknown
if (progress == null || !contentLength.HasValue)
{
await download.CopyToAsync(destination, cancellationToken);
return;
}
// Convert absolute progress (bytes downloaded) into relative progress (0% - 100%)
var relativeProgress = new Progress<long>(
totalBytes => progress.Report((float)totalBytes / contentLength.Value)
);
// Use extension method to report progress while downloading
await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken);
progress.Report(1);
}
public static async Task CopyToAsync(
this Stream source,
Stream destination,
int bufferSize,
IProgress<long>? progress = null,
CancellationToken cancellationToken = default
)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (!source.CanRead)
throw new ArgumentException("Has to be readable", nameof(source));
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new ArgumentException("Has to be writable", nameof(destination));
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
var buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
while (
(
bytesRead = await source
.ReadAsync(buffer, 0, buffer.Length, cancellationToken)
.ConfigureAwait(false)
) != 0
)
{
await destination
.WriteAsync(buffer, 0, bytesRead, cancellationToken)
.ConfigureAwait(false);
totalBytesRead += bytesRead;
progress?.Report(totalBytesRead);
}
}
}
}

View File

@ -2,20 +2,20 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MetadataExtractor" Version="2.4.3" />
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="ShellProgressBar" Version="5.0.0" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,6 +1,4 @@
using System;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration;
using Serilog;
namespace PhotoRenamer

View File

@ -4,13 +4,6 @@ using MetadataExtractor.Formats.QuickTime;
using Microsoft.Extensions.Configuration;
using Serilog;
using ShellProgressBar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Directory = System.IO.Directory;
namespace PhotoRenamer
@ -49,27 +42,32 @@ namespace PhotoRenamer
var i = 0;
using var progressBar = new ProgressBar(files.Length, "Copying files", options);
var po = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(files, po, file =>
{
try
Parallel.ForEach(
files,
po,
file =>
{
var directories = ImageMetadataReader.ReadMetadata(file);
var dateTime = GetDateTimeFromExif(directories)
?? GetDateTimeFromMp4(directories)
?? GetDateTimeFromLastWrite(file);
var folder = CreateFolder(dateTime);
CopyFile(folder, file, progressBar);
try
{
var directories = ImageMetadataReader.ReadMetadata(file);
var dateTime =
GetDateTimeFromExif(directories)
?? GetDateTimeFromMp4(directories)
?? GetDateTimeFromLastWrite(file);
var folder = CreateFolder(dateTime);
CopyFile(folder, file, progressBar);
}
catch (ImageProcessingException)
{
//silently ignore
}
finally
{
Interlocked.Increment(ref i);
progressBar.Tick(i);
}
}
catch (ImageProcessingException)
{
//silently ignore
}
finally
{
Interlocked.Increment(ref i);
progressBar.Tick(i);
}
});
);
return 0;
}
@ -80,24 +78,30 @@ namespace PhotoRenamer
return creationTime;
}
private static DateTime? GetDateTimeFromExif(IEnumerable<MetadataExtractor.Directory> directories)
private static DateTime? GetDateTimeFromExif(
IEnumerable<MetadataExtractor.Directory> directories
)
{
DateTime dateTime = default;
return directories
.OfType<ExifIfd0Directory>()
.FirstOrDefault()?
.TryGetDateTime(ExifDirectoryBase.TagDateTime, out dateTime) == true
return
directories
.OfType<ExifIfd0Directory>()
.FirstOrDefault()
?.TryGetDateTime(ExifDirectoryBase.TagDateTime, out dateTime) == true
? (DateTime?)dateTime
: null;
}
private static DateTime? GetDateTimeFromMp4(IEnumerable<MetadataExtractor.Directory> directories)
private static DateTime? GetDateTimeFromMp4(
IEnumerable<MetadataExtractor.Directory> directories
)
{
DateTime dateTime = default;
return directories
.OfType<QuickTimeMovieHeaderDirectory>()
.FirstOrDefault()?
.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out dateTime) == true
return
directories
.OfType<QuickTimeMovieHeaderDirectory>()
.FirstOrDefault()
?.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out dateTime) == true
? (DateTime?)dateTime
: null;
}
@ -110,26 +114,19 @@ namespace PhotoRenamer
destination.CreationTimeUtc = source.CreationTimeUtc;
}
private void CopyFile(string folder, string file, ProgressBarBase progressBar)
private async void CopyFile(string folder, string file, ProgressBarBase progressBar)
{
var destination = new FileInfo(Path.Combine(folder, Path.GetFileName(file)));
var source = new FileInfo(file);
if (destination.Exists && destination.Length == source.Length) return;
if (destination.Exists && destination.Length == source.Length)
return;
using var child = progressBar.Spawn(100, destination.FullName, _childOptions);
using var client = new WebClient();
using var client = new HttpClient();
using var fileStream = File.OpenWrite(destination.FullName);
void OnClientOnDownloadProgressChanged(object o, DownloadProgressChangedEventArgs args) =>
child.Tick(args.ProgressPercentage);
client.DownloadProgressChanged += OnClientOnDownloadProgressChanged;
client.DownloadFileAsync(new Uri(source.FullName), destination.FullName);
while (client.IsBusy)
{
Thread.Sleep(100);
}
client.DownloadProgressChanged -= OnClientOnDownloadProgressChanged;
var progress = new Progress<float>(o => progressBar.Tick((int)o * 100));
await client.DownloadAsync(source.FullName, fileStream, progress);
ResetTimes(destination, source);
child.Tick(100);
@ -137,9 +134,14 @@ namespace PhotoRenamer
private string CreateFolder(DateTime dateTime)
{
var folder = Path.Combine(_targetPath, dateTime.Year.ToString(), dateTime.Month.ToString("D2"));
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
var folder = Path.Combine(
_targetPath,
dateTime.Year.ToString(),
dateTime.Month.ToString("D2")
);
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
return folder;
}
}
}
}

View File

@ -1,6 +1,4 @@
using System;
namespace PhotoRenamer.Types
namespace PhotoRenamer.Types
{
public class MediaFile
{