This repository has been archived by the owner on Jul 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow a list of files to be passed to the program.
- Loading branch information
Showing
7 changed files
with
194 additions
and
92 deletions.
There are no files selected for viewing
87 changes: 5 additions & 82 deletions
87
OffUploader.Core/ParseBarcodesAndUploadDirectoryHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,105 +1,28 @@ | ||
namespace OffUploader.Core | ||
{ | ||
using ImageMagick; | ||
using MediatR; | ||
using OffUploader.Core.Logging; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO.Abstractions; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ZXing; | ||
using ZXing.Magick; | ||
|
||
public class ParseBarcodesAndUploadDirectoryHandler : IRequestHandler<ParseBarcodesAndUploadDirectory> | ||
{ | ||
private static readonly ILog log = LogProvider.GetCurrentClassLogger(); | ||
|
||
private readonly IBarcodeReader barcodeReader; | ||
|
||
private readonly IFileSystem fileSystem; | ||
|
||
private readonly IMagickFactory magickFactory; | ||
|
||
private readonly IMediator mediator; | ||
|
||
public ParseBarcodesAndUploadDirectoryHandler(IBarcodeReader barcodeReader, IFileSystem fileSystem, IMagickFactory magickFactory, IMediator mediator) | ||
public ParseBarcodesAndUploadDirectoryHandler(IFileSystem fileSystem, IMediator mediator) | ||
{ | ||
this.barcodeReader = barcodeReader; | ||
this.fileSystem = fileSystem; | ||
this.magickFactory = magickFactory; | ||
this.mediator = mediator; | ||
} | ||
|
||
public async Task<Unit> Handle(ParseBarcodesAndUploadDirectory request, CancellationToken cancellationToken) | ||
public Task<Unit> Handle(ParseBarcodesAndUploadDirectory request, CancellationToken cancellationToken) | ||
{ | ||
var path = request.Path; | ||
var jpgs = this.fileSystem.Directory.GetJpegs(path); | ||
string? code = null; | ||
log.Info("Reading barcodes from JPEGs in {Path}", path); | ||
var stopwatch = Stopwatch.StartNew(); | ||
foreach (var file in jpgs) | ||
{ | ||
var barcodes = await this.ReadBarcodesAsync(file, cancellationToken).ConfigureAwait(false); | ||
if (barcodes == null) | ||
{ | ||
continue; | ||
} | ||
|
||
if (TryGetFirstCode(barcodes, out code)) | ||
{ | ||
break; | ||
} | ||
} | ||
|
||
stopwatch.Stop(); | ||
|
||
if (code == null) | ||
{ | ||
log.Warn("Barcodes read from JPEGs in {Path} in {Duration}. No good barcode found for any file.", path, stopwatch.Elapsed); | ||
throw new InvalidOperationException("No barcode found in the images."); | ||
} | ||
else | ||
{ | ||
log.Info("Barcodes read from JPEGs in {Path} in {Duration}. Code is {Code}.", path, stopwatch.Elapsed, code); | ||
} | ||
|
||
await this.mediator.Send(new UploadDirectoryRequest(request.Settings, code, path), cancellationToken).ConfigureAwait(false); | ||
return Unit.Value; | ||
} | ||
|
||
private static bool TryGetFirstCode(IEnumerable<Result> barcodes, out string code) | ||
{ | ||
code = string.Empty; | ||
|
||
foreach (var barcode in barcodes) | ||
{ | ||
if (barcode.BarcodeFormat == BarcodeFormat.EAN_13 || | ||
barcode.BarcodeFormat == BarcodeFormat.EAN_8 || | ||
barcode.BarcodeFormat == BarcodeFormat.UPC_A || | ||
barcode.BarcodeFormat == BarcodeFormat.UPC_E) | ||
{ | ||
code = barcode.Text; | ||
log.Info("Found a good barcode for the files: {Barcode}", code); | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
private Task<Result[]> ReadBarcodesAsync(string path, CancellationToken cancellationToken) => Task.Run(() => this.ReadBarcodes(path), cancellationToken); | ||
|
||
private Result[] ReadBarcodes(string path) | ||
{ | ||
log.Trace("Opening image {File} with ImageMagick", path); | ||
using var image = this.magickFactory.CreateImage(path); | ||
log.Trace("Reading barcode of image {File}", path); | ||
var luminanceSource = new MagickImageLuminanceSource((MagickImage)image); | ||
var barcodes = this.barcodeReader.DecodeMultiple(luminanceSource); | ||
log.Debug("Barcodes for {File} are {@Barcodes}", path, barcodes); | ||
return barcodes; | ||
var jpgs = this.fileSystem.Directory.GetJpegs(path).ToList(); | ||
return this.mediator.Send(new ParseBarcodesAndUploadFiles(request.Settings, jpgs), cancellationToken); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace OffUploader.Core | ||
{ | ||
using MediatR; | ||
using System.Collections.Generic; | ||
|
||
public class ParseBarcodesAndUploadFiles : IRequest | ||
{ | ||
public ParseBarcodesAndUploadFiles(ProductOpenerSettings settings, IReadOnlyCollection<string> paths) | ||
{ | ||
this.Settings = settings; | ||
this.Paths = paths; | ||
} | ||
|
||
public IReadOnlyCollection<string> Paths { get; } | ||
|
||
public ProductOpenerSettings Settings { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
namespace OffUploader.Core | ||
{ | ||
using ImageMagick; | ||
using MediatR; | ||
using OffUploader.Core.Logging; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO.Abstractions; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ZXing; | ||
using ZXing.Magick; | ||
|
||
public class ParseBarcodesAndUploadFilesHandler : IRequestHandler<ParseBarcodesAndUploadFiles> | ||
{ | ||
private static readonly ILog log = LogProvider.GetCurrentClassLogger(); | ||
|
||
private readonly IBarcodeReader barcodeReader; | ||
|
||
private readonly IFileSystem fileSystem; | ||
|
||
private readonly IMagickFactory magickFactory; | ||
|
||
private readonly IMediator mediator; | ||
|
||
public ParseBarcodesAndUploadFilesHandler(IBarcodeReader barcodeReader, IFileSystem fileSystem, IMagickFactory magickFactory, IMediator mediator) | ||
{ | ||
this.barcodeReader = barcodeReader; | ||
this.fileSystem = fileSystem; | ||
this.magickFactory = magickFactory; | ||
this.mediator = mediator; | ||
} | ||
|
||
public async Task<Unit> Handle(ParseBarcodesAndUploadFiles request, CancellationToken cancellationToken) | ||
{ | ||
var jpgs = request.Paths; | ||
string? code = null; | ||
log.Info("Reading barcodes from JPEGs: {@Paths}", jpgs); | ||
var stopwatch = Stopwatch.StartNew(); | ||
foreach (var file in jpgs) | ||
{ | ||
var barcodes = await this.ReadBarcodesAsync(file, cancellationToken).ConfigureAwait(false); | ||
if (barcodes == null) | ||
{ | ||
continue; | ||
} | ||
|
||
if (TryGetFirstCode(barcodes, out code)) | ||
{ | ||
break; | ||
} | ||
} | ||
|
||
stopwatch.Stop(); | ||
|
||
if (code == null) | ||
{ | ||
log.Warn("Barcodes read from JPEGs in {@Paths} in {Duration}. No good barcode found for any file.", jpgs, stopwatch.Elapsed); | ||
throw new InvalidOperationException("No barcode found in the images."); | ||
} | ||
else | ||
{ | ||
log.Info("Barcodes read from JPEGs in {@Paths} in {Duration}. Code is {Code}.", jpgs, stopwatch.Elapsed, code); | ||
} | ||
|
||
await this.mediator.Send(new UploadFilesToCodeRequest(request.Settings, code, jpgs), cancellationToken).ConfigureAwait(false); | ||
return Unit.Value; | ||
} | ||
|
||
private static bool TryGetFirstCode(IEnumerable<Result> barcodes, out string code) | ||
{ | ||
code = string.Empty; | ||
|
||
foreach (var barcode in barcodes) | ||
{ | ||
if (barcode.BarcodeFormat == BarcodeFormat.EAN_13 || | ||
barcode.BarcodeFormat == BarcodeFormat.EAN_8 || | ||
barcode.BarcodeFormat == BarcodeFormat.UPC_A || | ||
barcode.BarcodeFormat == BarcodeFormat.UPC_E) | ||
{ | ||
code = barcode.Text; | ||
log.Info("Found a good barcode for the files: {Barcode}", code); | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
private Task<Result[]> ReadBarcodesAsync(string path, CancellationToken cancellationToken) => Task.Run(() => this.ReadBarcodes(path), cancellationToken); | ||
|
||
private Result[] ReadBarcodes(string path) | ||
{ | ||
log.Trace("Opening image {File} with ImageMagick", path); | ||
using var image = this.magickFactory.CreateImage(path); | ||
log.Trace("Reading barcode of image {File}", path); | ||
var luminanceSource = new MagickImageLuminanceSource((MagickImage)image); | ||
var barcodes = this.barcodeReader.DecodeMultiple(luminanceSource); | ||
log.Debug("Barcodes for {File} are {@Barcodes}", path, barcodes); | ||
return barcodes; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace OffUploader.Core | ||
{ | ||
using MediatR; | ||
using System.Collections.Generic; | ||
|
||
public class UploadFilesToCodeRequest : IRequest | ||
{ | ||
public UploadFilesToCodeRequest(ProductOpenerSettings settings, string code, IReadOnlyCollection<string> paths) | ||
{ | ||
this.Settings = settings; | ||
this.Code = code; | ||
this.Paths = paths; | ||
} | ||
|
||
public ProductOpenerSettings Settings { get; } | ||
|
||
public string Code { get; } | ||
|
||
public IReadOnlyCollection<string> Paths { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
namespace OffUploader.Core | ||
{ | ||
using MediatR; | ||
using OffUploader.Core.Logging; | ||
using System.Diagnostics; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
public class UploadFilesToCodeRequestHandler : IRequestHandler<UploadFilesToCodeRequest> | ||
{ | ||
private static readonly ILog log = LogProvider.GetCurrentClassLogger(); | ||
|
||
private readonly IMediator mediator; | ||
|
||
public UploadFilesToCodeRequestHandler(IMediator mediator) | ||
{ | ||
this.mediator = mediator; | ||
} | ||
|
||
public async Task<Unit> Handle(UploadFilesToCodeRequest request, CancellationToken cancellationToken) | ||
{ | ||
var settings = request.Settings; | ||
var code = request.Code; | ||
var jpgs = request.Paths; | ||
log.Info("Uploading {FileCount} JPEGs from to product {Code}", jpgs, code); | ||
var uploaded = 0; | ||
var stopwatch = Stopwatch.StartNew(); | ||
foreach (var jpg in jpgs) | ||
{ | ||
await this.mediator.Send(new UploadFileRequest(settings, code, jpg), cancellationToken).ConfigureAwait(false); | ||
++uploaded; | ||
} | ||
|
||
stopwatch.Stop(); | ||
log.Info("Uploaded {UploadedImagesCount} JPEGs from {@Paths} to product {Code} in {Duration}", uploaded, jpgs, code, stopwatch.Elapsed); | ||
return Unit.Value; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters