Skip to content

Commit

Permalink
added filtering options and error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Avaray committed Aug 23, 2024
1 parent a859696 commit a3707c8
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 35 deletions.
99 changes: 65 additions & 34 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Text.Json;
using System.Reflection;
using MetadataExtractor;
using System.Text.RegularExpressions;

class Program
{
Expand Down Expand Up @@ -41,6 +42,7 @@ static async Task Main(string[] args)
bool includeSubdirectories = false;
string filePath = args[0];
string? filterString = null;
string? regexPattern = null;

for (int i = 0; i < args.Length; i++)
{
Expand Down Expand Up @@ -85,9 +87,21 @@ static async Task Main(string[] args)
return;
}
}
else if (args[i] == "-s")
{
if (i + 1 < args.Length)
{
regexPattern = args[++i];
}
else
{
Console.WriteLine("Error: -s option requires a search string.");
return;
}
}
else if (i == 0)
{
// If it's not a -d, -o, -r, or -t option and it's the first argument, treat it as the file path
// If option is not provided, assume it is a file path
filePath = args[i];
}
}
Expand All @@ -108,7 +122,7 @@ static async Task Main(string[] args)
.Where(file => IsValidFile(file))
.ToArray();

var tasks = imageFiles.Select(imagePath => Task.Run(() => ExtractMetadata(imagePath, filterString)));
var tasks = imageFiles.Select(imagePath => Task.Run(() => ExtractMetadata(imagePath, filterString, regexPattern)));
var filteredMetadata = await Task.WhenAll(tasks);
allMetadata.AddRange(filteredMetadata.Where(metadata => metadata != null)!);
}
Expand All @@ -122,7 +136,7 @@ static async Task Main(string[] args)

if (IsValidFile(filePath))
{
var metadata = ExtractMetadata(filePath, filterString);
var metadata = ExtractMetadata(filePath, filterString, regexPattern);
if (metadata != null)
{
allMetadata.Add(metadata);
Expand Down Expand Up @@ -163,52 +177,68 @@ private static bool IsValidFile(string filePath)
};
}

private static ImageMetadata? ExtractMetadata(string imagePath, string? filterString = null)
{
var directories = ImageMetadataReader.ReadMetadata(imagePath);
var metadataTags = new List<MetadataTag>();

foreach (var directory in directories)
private static ImageMetadata? ExtractMetadata(string imagePath, string? filterString = null, string? regexPattern = null)
{
foreach (var tag in directory.Tags)
try
{
// Convert filterString and tag.Name to lowercase for case-insensitive matching
if (filterString != null && !tag.Name.ToLowerInvariant().Contains(filterString.ToLowerInvariant()))
continue;
var directories = ImageMetadataReader.ReadMetadata(imagePath);
var metadataTags = new List<MetadataTag>();

metadataTags.Add(new MetadataTag
foreach (var directory in directories)
{
DirectoryName = directory.Name,
TagName = tag.Name,
Description = tag.Description ?? string.Empty
});
}
}
foreach (var tag in directory.Tags)
{
// Filter by TagName
if (filterString != null && !tag.Name.ToLowerInvariant().Contains(filterString.ToLowerInvariant()))
continue;

// Filter by regex in Description
if (regexPattern != null)
{
var regex = new Regex(regexPattern);
if (!regex.IsMatch(tag.Description ?? string.Empty))
continue;
}

metadataTags.Add(new MetadataTag
{
DirectoryName = directory.Name,
TagName = tag.Name,
Description = tag.Description ?? string.Empty
});
}
}

// Only return ImageMetadata if there are tags matching the filter
if (metadataTags.Count == 0)
{
return null; // Return null if no matching tags
}
// Only return ImageMetadata if there are tags matching the filters
if (metadataTags.Count == 0)
{
return null;
}

return new ImageMetadata
{
FilePath = imagePath,
FileName = System.IO.Path.GetFileName(imagePath),
Tags = metadataTags
};
}
return new ImageMetadata
{
FilePath = imagePath,
FileName = System.IO.Path.GetFileName(imagePath),
Tags = metadataTags
};
}
catch (Exception)
{
return null;
}
}

private static void DisplayHelp()
{
Console.WriteLine("Usage: extractor <file-path> [-d <directory-path>] [-o <output-file>] [-r] [-t <filter-string>]");
Console.WriteLine("Usage: extractor <file-path> [-d <directory-path>] [-o <output-file>] [-r]");
Console.WriteLine();
Console.WriteLine("Options:");
Console.WriteLine(" <file-path> Path to a single image file.");
Console.WriteLine(" -d <directory-path> Path to a directory containing image files.");
Console.WriteLine(" -o <output-file> Path to the output file for saving the extracted metadata.");
Console.WriteLine(" -r Include subdirectories when processing a directory.");
Console.WriteLine(" -t <filter-string> Filter metadata by TagName.");
Console.WriteLine(" -s <search-string> Filter metadata by Description using string search.");
Console.WriteLine(" -v, --version Display version.");
Console.WriteLine();
Console.WriteLine("Examples:");
Expand All @@ -217,6 +247,7 @@ private static void DisplayHelp()
Console.WriteLine(" extractor -d images_directory");
Console.WriteLine(" extractor -d images_directory -o output.json");
Console.WriteLine(" extractor -d images_directory -r");
Console.WriteLine(" extractor -d images_directory -t \"Image Height\"");
Console.WriteLine(" extractor -d images_directory -t \"textual tata\"");
Console.WriteLine(" extractor -d images_directory -s \"word\"");
}
}
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,22 @@ extractor -d <directory-path> -r
extractor <file-path> -o <output-file>
```

### Experimental Options

> These options are experimental and might not work as expected. Pretty sure they will be changed or removed in future versions. Combining them together might not work.
- **Filter Tag Name**: Return metadata with specific tag name. Ignore all other tags.

```
extractor -d <directory-path> -t <tag-name>
```

- **Search in Tag Description**: Filter images by searching in tag description. Using [Regex](https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference) is possible, but might not work as expected. Something like `-s '[\d\w]{10}'` should work.

```
extractor -d <directory-path> -s <search-string>
```

## Development

1. **Prerequisites**: Ensure you have the [.NET SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) (version 8.0 or higher) installed on your machine. You can download it from the official [.NET website](https://dotnet.microsoft.com/download). You can check your current version by running the following command:
Expand Down Expand Up @@ -94,4 +110,5 @@ I might add more features in the future. I'm considering following changes:
- [x] Extract recursive metadata extraction `-r` option.
- [x] Add checks for invalid file types. To print message rather than throwing an exception.
- [ ] Lower the required .NET version.
- [ ] Possibility to extract only specific tags. For example `PNG-tEXt`.
- [x] Possibility to filter images by "Tag Name".
- [x] Possibility to filter images with [Regex](https://en.wikipedia.org/wiki/Regular_expression).

0 comments on commit a3707c8

Please sign in to comment.