Skip to content

Commit

Permalink
Multithreaded searching
Browse files Browse the repository at this point in the history
  • Loading branch information
Decimation committed Sep 27, 2020
1 parent 065f9da commit fd3d6de
Show file tree
Hide file tree
Showing 15 changed files with 267 additions and 179 deletions.
28 changes: 19 additions & 9 deletions SmartImage/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO.Compression;
using System.Linq;
using System.Media;
using System.Reflection;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -61,23 +63,31 @@ private static void Main(string[] args)
SearchConfig.ReadSearchConfigArguments(args);

if (SearchConfig.Config.NoArguments) {
ConsoleIO.RunMainCommandMenu();
ConsoleMainMenu.RunMainMenu();
Console.Clear();
}

string img = SearchConfig.Config.Image;

var n = Enum.GetValues(typeof(SearchEngines)).Length;

ConsoleOption[] results = new SearchResult[n];
var ok = Search.RunSearch(img, ref results);

if (!ok) {
CliOutput.WriteError("Search failed or aborted");
// Run checks
if (!SearchClient.IsFileValid(img))
{
return;
}

ConsoleIO.HandleConsoleOptions(results);
// var n = Enum.GetValues(typeof(SearchEngines)).Length;
// ConsoleOption[] results = new SearchResult[n];
// var ok = Search.RunSearch(img, ref results);
//
// if (!ok) {
// CliOutput.WriteError("Search failed or aborted");
// return;
// }

using var s = new SearchClient(img);
s.Start();

ConsoleIO.HandleOptions(s.Results);
}
catch (Exception exception) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public sealed class ImgOpsClient : SimpleSearchEngine
public ImgOpsClient() : base("http://imgops.com/") { }

public override string Name => "ImgOps";
public override ConsoleColor Color => ConsoleColor.Magenta;
public override ConsoleColor Color => ConsoleColor.DarkMagenta;

public override SearchEngines Engine => SearchEngines.ImgOps;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public sealed class IqdbClient : SimpleSearchEngine
public IqdbClient() : base("https://iqdb.org/?url=") { }

public override string Name => "IQDB";
public override ConsoleColor Color => ConsoleColor.Magenta;
public override ConsoleColor Color => ConsoleColor.DarkGreen;

public override SearchEngines Engine => SearchEngines.Iqdb;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
#region

#nullable enable
using System;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SimpleCore.Utilities;
using SimpleCore.Win32.Cli;
using SmartImage.Searching.Engines.Imgur;
using SmartImage.Searching.Engines.SauceNao;
Expand All @@ -18,59 +12,31 @@
using SmartImage.Shell;
using SmartImage.Utilities;

// ReSharper disable ReturnTypeCanBeEnumerable.Local

#endregion

// ReSharper disable ReturnTypeCanBeEnumerable.Global

namespace SmartImage.Searching
{
/// <summary>
/// Runs image searches
/// </summary>
public static class Search
public class SearchClient : IDisposable
{
/// <summary>
/// Common image extensions
/// Common image extensions
/// </summary>
private static readonly string[] ImageExtensions =
{
".jpg", ".jpeg", ".png", ".gif", ".tga", ".jfif", ".bmp"
};

private readonly SearchEngines m_engines;

private static ISearchEngine[] GetAllEngines()
{
var engines = new ISearchEngine[]
{
new SauceNaoClient(),
new ImgOpsClient(),
new GoogleImagesClient(),
new TinEyeClient(),
new IqdbClient(),
new BingClient(),
new YandexClient(),
new KarmaDecayClient(),
new TraceMoeClient()
};

return engines;
}
private readonly string m_img;

private readonly string m_imgUrl;

public static bool RunSearch(string img, ref ConsoleOption[] res)
{
/*
* Run
*/
private ConsoleOption[] m_results;

// Run checks
if (!IsFileValid(img)) {
SearchConfig.UpdateFile();
private readonly Thread[] m_threads;

return false;
}
public SearchClient(string img)
{


string auth = SearchConfig.Config.ImgurAuth;
bool useImgur = !String.IsNullOrWhiteSpace(auth);
Expand All @@ -84,76 +50,81 @@ public static bool RunSearch(string img, ref ConsoleOption[] res)
engines = SearchConfig.ENGINES_DEFAULT;
}

m_engines = engines;

// Display config
CliOutput.WriteInfo(SearchConfig.Config);

m_imgUrl = Upload(img, useImgur);

string imgUrl = Upload(img, useImgur);

m_threads = CreateSearchThreads();
}

CliOutput.WriteInfo("Temporary image url: {0}", imgUrl);
public ref ConsoleOption[] Results => ref m_results;

Console.WriteLine();
public void Dispose()
{
foreach (var thread in m_threads) {
thread.Join();
}
}

public void Start()
{
// Display config
CliOutput.WriteInfo(SearchConfig.Config);

// Where the actual searching occurs
CliOutput.WriteInfo("Temporary image url: {0}", m_imgUrl);

//StartSearches(imgUrl, engines, ref res);
var threads = StartSearchesMultithread(imgUrl, engines, ref res);
Console.WriteLine();

foreach (var thread in threads) {
foreach (var thread in m_threads) {
thread.Start();
}

return true;
}



private static Thread[] StartSearchesMultithread(string imgUrl, SearchEngines engines, ref ConsoleOption[] res)
private Thread[] CreateSearchThreads()
{
// todo: improve
// todo: use tasks


var availableEngines = GetAllEngines()
.Where(e => engines.HasFlag(e.Engine))
.Where(e => m_engines.HasFlag(e.Engine))
.ToArray();

int i = 0;

res = new SearchResult[availableEngines.Length + 1];
res[i] = new SearchResult(ConsoleColor.Gray, "(Original image)", imgUrl, null);
m_results = new ConsoleOption[availableEngines.Length + 1];
m_results[i] = new SearchResult(ConsoleColor.Gray, "(Original image)", m_imgUrl);

i++;


var threads = new List<Thread>();

foreach (var currentEngine in availableEngines)
{
var options = res;
foreach (var currentEngine in availableEngines) {

int i1 = i;
var resultsCopy = m_results;
int iCopy = i;

ThreadStart ts = () =>
ThreadStart threadFunction = () =>
{
var result = currentEngine.GetResult(imgUrl);
options[i1] = result;

var result = currentEngine.GetResult(m_imgUrl);
resultsCopy[iCopy] = result;

// If the engine is priority, open its result in the browser
if (SearchConfig.Config.PriorityEngines.HasFlag(currentEngine.Engine))
{
if (SearchConfig.Config.PriorityEngines.HasFlag(currentEngine.Engine)) {
Network.OpenUrl(result.Url);
}

ConsoleIO.Status = ConsoleIO.STATUS_REFRESH;
};


var t = new Thread(threadFunction)
{
Priority = ThreadPriority.Highest
};
var t = new Thread(ts);
t.Priority = ThreadPriority.Highest;
t.Name = string.Format("thread - {0}", currentEngine.Name);

threads.Add(t);

i++;
Expand All @@ -164,9 +135,27 @@ private static Thread[] StartSearchesMultithread(string imgUrl, SearchEngines en

}

private static bool IsFileValid(string img)
private static ISearchEngine[] GetAllEngines()
{
var engines = new ISearchEngine[]
{
new SauceNaoClient(),
new ImgOpsClient(),
new GoogleImagesClient(),
new TinEyeClient(),
new IqdbClient(),
new BingClient(),
new YandexClient(),
new KarmaDecayClient(),
new TraceMoeClient()
};

return engines;
}

internal static bool IsFileValid(string img)
{
if (string.IsNullOrWhiteSpace(img)) {
if (String.IsNullOrWhiteSpace(img)) {
return false;
}

Expand Down
40 changes: 19 additions & 21 deletions SmartImage/Searching/SearchResult.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimpleCore.Utilities;
using SimpleCore.Win32.Cli;
using SmartImage.Searching.Model;
using SmartImage.Shell;
Expand All @@ -12,7 +10,7 @@
namespace SmartImage.Searching
{
/// <summary>
/// Contains search result and information
/// Contains search result and information
/// </summary>
public sealed class SearchResult : ConsoleOption, IExtendedSearchResult
{
Expand All @@ -32,33 +30,18 @@ public SearchResult(ConsoleColor color, string name, string url, float? similari

public override ConsoleColor Color { get; internal set; }


/// <summary>
/// Best match
/// </summary>
public string Url { get; }

// todo: create a specific url field with the original url

public override string? Data => Format();

public override string Name { get; internal set; }

/// <summary>
/// Image similarity
/// </summary>
public float? Similarity { get; set; }

public int? Width { get; set; }
public int? Height { get; set; }
public string? Caption { get; set; }

public bool Success => Url != null;

public List<string> ExtendedInfo { get; }

/// <summary>
/// Direct source matches, other extended results
/// Direct source matches, other extended results
/// </summary>
public List<IExtendedSearchResult> ExtendedResults { get; }

Expand All @@ -77,6 +60,21 @@ public override Func<object?> Function
public override Func<object?>? AltFunction { get; internal set; }


/// <summary>
/// Best match
/// </summary>
public string Url { get; }

/// <summary>
/// Image similarity
/// </summary>
public float? Similarity { get; set; }

public int? Width { get; set; }
public int? Height { get; set; }
public string? Caption { get; set; }


private SearchResult[] FromExtendedResult(IReadOnlyList<IExtendedSearchResult> results)
{

Expand Down Expand Up @@ -113,7 +111,7 @@ public void AddExtendedInfo(IExtendedSearchResult[] bestImages)
var rg = FromExtendedResult(bestImages);


ConsoleIO.HandleConsoleOptions(rg);
ConsoleIO.HandleOptions(rg);

return null;

Expand All @@ -131,7 +129,7 @@ private string Format()
var sb = new StringBuilder();

char success = Success ? CliOutput.RAD_SIGN : CliOutput.MUL_SIGN;
string altStr = AltFunction != null ? ConsoleIO.ALT_DENOTE : string.Empty;
string altStr = AltFunction != null ? ConsoleIO.ALT_DENOTE : String.Empty;

sb.AppendFormat("{0} {1}\n", success, altStr);

Expand Down
Loading

0 comments on commit fd3d6de

Please sign in to comment.