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"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.2"> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PrivateAssets>all</PrivateAssets> <PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</PackageReference> <PackageReference Include="coverlet.collector" Version="3.2.0">
<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">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View File

@ -1,8 +1,4 @@
using System; namespace PhotoRenamer
using System.Collections.Generic;
using System.IO;
namespace PhotoRenamer
{ {
public static class FilesHelper 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> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MetadataExtractor" Version="2.4.3" /> <PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" /> <PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog" Version="2.10.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="ShellProgressBar" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

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

View File

@ -4,13 +4,6 @@ using MetadataExtractor.Formats.QuickTime;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Serilog; using Serilog;
using ShellProgressBar; 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; using Directory = System.IO.Directory;
namespace PhotoRenamer namespace PhotoRenamer
@ -49,12 +42,16 @@ namespace PhotoRenamer
var i = 0; var i = 0;
using var progressBar = new ProgressBar(files.Length, "Copying files", options); using var progressBar = new ProgressBar(files.Length, "Copying files", options);
var po = new ParallelOptions { MaxDegreeOfParallelism = 4 }; var po = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(files, po, file => Parallel.ForEach(
files,
po,
file =>
{ {
try try
{ {
var directories = ImageMetadataReader.ReadMetadata(file); var directories = ImageMetadataReader.ReadMetadata(file);
var dateTime = GetDateTimeFromExif(directories) var dateTime =
GetDateTimeFromExif(directories)
?? GetDateTimeFromMp4(directories) ?? GetDateTimeFromMp4(directories)
?? GetDateTimeFromLastWrite(file); ?? GetDateTimeFromLastWrite(file);
var folder = CreateFolder(dateTime); var folder = CreateFolder(dateTime);
@ -69,7 +66,8 @@ namespace PhotoRenamer
Interlocked.Increment(ref i); Interlocked.Increment(ref i);
progressBar.Tick(i); progressBar.Tick(i);
} }
}); }
);
return 0; return 0;
} }
@ -80,24 +78,30 @@ namespace PhotoRenamer
return creationTime; return creationTime;
} }
private static DateTime? GetDateTimeFromExif(IEnumerable<MetadataExtractor.Directory> directories) private static DateTime? GetDateTimeFromExif(
IEnumerable<MetadataExtractor.Directory> directories
)
{ {
DateTime dateTime = default; DateTime dateTime = default;
return directories return
directories
.OfType<ExifIfd0Directory>() .OfType<ExifIfd0Directory>()
.FirstOrDefault()? .FirstOrDefault()
.TryGetDateTime(ExifDirectoryBase.TagDateTime, out dateTime) == true ?.TryGetDateTime(ExifDirectoryBase.TagDateTime, out dateTime) == true
? (DateTime?)dateTime ? (DateTime?)dateTime
: null; : null;
} }
private static DateTime? GetDateTimeFromMp4(IEnumerable<MetadataExtractor.Directory> directories) private static DateTime? GetDateTimeFromMp4(
IEnumerable<MetadataExtractor.Directory> directories
)
{ {
DateTime dateTime = default; DateTime dateTime = default;
return directories return
directories
.OfType<QuickTimeMovieHeaderDirectory>() .OfType<QuickTimeMovieHeaderDirectory>()
.FirstOrDefault()? .FirstOrDefault()
.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out dateTime) == true ?.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out dateTime) == true
? (DateTime?)dateTime ? (DateTime?)dateTime
: null; : null;
} }
@ -110,26 +114,19 @@ namespace PhotoRenamer
destination.CreationTimeUtc = source.CreationTimeUtc; 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 destination = new FileInfo(Path.Combine(folder, Path.GetFileName(file)));
var source = new FileInfo(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 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) => var progress = new Progress<float>(o => progressBar.Tick((int)o * 100));
child.Tick(args.ProgressPercentage); await client.DownloadAsync(source.FullName, fileStream, progress);
client.DownloadProgressChanged += OnClientOnDownloadProgressChanged;
client.DownloadFileAsync(new Uri(source.FullName), destination.FullName);
while (client.IsBusy)
{
Thread.Sleep(100);
}
client.DownloadProgressChanged -= OnClientOnDownloadProgressChanged;
ResetTimes(destination, source); ResetTimes(destination, source);
child.Tick(100); child.Tick(100);
@ -137,8 +134,13 @@ namespace PhotoRenamer
private string CreateFolder(DateTime dateTime) private string CreateFolder(DateTime dateTime)
{ {
var folder = Path.Combine(_targetPath, dateTime.Year.ToString(), dateTime.Month.ToString("D2")); var folder = Path.Combine(
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); _targetPath,
dateTime.Year.ToString(),
dateTime.Month.ToString("D2")
);
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
return folder; return folder;
} }
} }

View File

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