Flow.Launcher/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs

212 lines
8.3 KiB
C#
Raw Permalink Normal View History

using System;
using System.Collections.Generic;
2016-05-07 18:16:13 +00:00
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
2020-04-21 09:12:17 +00:00
using Flow.Launcher.Plugin.SharedCommands;
2020-04-21 09:12:17 +00:00
namespace Flow.Launcher.Plugin.WebSearch
{
2024-11-18 12:07:57 +00:00
public class Main : IAsyncPlugin, ISettingProvider, IPluginI18n, IResultUpdated, IContextMenu
{
internal static PluginInitContext _context;
private Settings _settings;
private SettingsViewModel _viewModel;
internal const string Images = "Images";
internal static string DefaultImagesDirectory;
internal static string CustomImagesDirectory;
private readonly int scoreStandard = 50;
private readonly int scoreSuggestions = 48;
2019-08-02 02:32:02 +00:00
private readonly string SearchSourceGlobalPluginWildCardSign = "*";
2021-01-07 03:09:08 +00:00
public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
{
if (FilesFolders.IsLocationPathString(query.Search))
return new List<Result>();
2019-08-04 11:38:36 +00:00
var searchSourceList = new List<SearchSource>();
var results = new List<Result>();
2021-01-07 13:41:05 +00:00
foreach (SearchSource searchSource in _settings.SearchSources.Where(o => (o.ActionKeyword == query.ActionKeyword ||
o.ActionKeyword == SearchSourceGlobalPluginWildCardSign)
&& o.Enabled))
{
2021-01-07 13:41:05 +00:00
string keyword = string.Empty;
keyword = searchSource.ActionKeyword == SearchSourceGlobalPluginWildCardSign ? query.ToString() : query.Search;
var title = keyword;
string subtitle = _context.API.GetTranslation("flowlauncher_plugin_websearch_search") + " " + searchSource.Title;
// Action Keyword match apear on top
var score = searchSource.ActionKeyword == SearchSourceGlobalPluginWildCardSign ? scoreStandard : scoreStandard + 1;
// This populates the associated action keyword search entry
2021-01-07 13:41:05 +00:00
if (string.IsNullOrEmpty(keyword))
{
var result = new Result
2014-02-28 15:21:01 +00:00
{
2021-01-07 13:41:05 +00:00
Title = subtitle,
SubTitle = string.Empty,
IcoPath = searchSource.IconPath,
Score = score
2021-01-07 13:41:05 +00:00
};
2021-01-07 13:41:05 +00:00
results.Add(result);
}
else
{
var result = new Result
{
2021-01-07 13:41:05 +00:00
Title = title,
SubTitle = subtitle,
IcoPath = searchSource.IconPath,
ActionKeywordAssigned = searchSource.ActionKeyword == SearchSourceGlobalPluginWildCardSign ? string.Empty : searchSource.ActionKeyword,
Score = score,
2021-01-07 13:41:05 +00:00
Action = c =>
{
_context.API.OpenWebUrl(searchSource.Url.Replace("{q}", Uri.EscapeDataString(keyword)), searchSource.IsPrivateMode);
2021-01-07 03:09:08 +00:00
2021-01-07 13:41:05 +00:00
return true;
2024-11-18 12:07:57 +00:00
},
ContextData = searchSource.Url.Replace("{q}", Uri.EscapeDataString(keyword)),
2021-01-07 13:41:05 +00:00
};
2021-01-07 03:09:08 +00:00
2021-01-07 13:41:05 +00:00
results.Add(result);
}
2021-01-07 13:41:05 +00:00
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs
{
Results = results,
Query = query
2021-01-07 13:41:05 +00:00
});
await UpdateResultsFromSuggestionAsync(results, keyword, subtitle, searchSource, query, token).ConfigureAwait(false);
if (token.IsCancellationRequested)
return null;
}
2019-08-04 11:38:36 +00:00
return results;
}
2021-01-07 03:09:08 +00:00
private async Task UpdateResultsFromSuggestionAsync(List<Result> results, string keyword, string subtitle,
SearchSource searchSource, Query query, CancellationToken token)
{
if (_settings.EnableSuggestion)
{
2021-01-07 03:09:08 +00:00
var suggestions = await SuggestionsAsync(keyword, subtitle, searchSource, token).ConfigureAwait(false);
var enumerable = suggestions?.ToList();
if (token.IsCancellationRequested || enumerable is not { Count: > 0 })
2021-01-07 13:41:05 +00:00
return;
results.AddRange(enumerable);
2021-01-07 03:09:08 +00:00
token.ThrowIfCancellationRequested();
}
}
2021-01-07 03:09:08 +00:00
private async Task<IEnumerable<Result>> SuggestionsAsync(string keyword, string subtitle, SearchSource searchSource, CancellationToken token)
{
var source = _settings.SelectedSuggestion;
if (source == null)
{
return new List<Result>();
}
//Suggestions appear below actual result, and appear above global action keyword match if non-global;
var score = searchSource.ActionKeyword == SearchSourceGlobalPluginWildCardSign ? scoreSuggestions : scoreSuggestions + 1;
var suggestions = await source.SuggestionsAsync(keyword, token).ConfigureAwait(false);
2021-01-07 13:41:05 +00:00
token.ThrowIfCancellationRequested();
2021-01-07 13:41:05 +00:00
var resultsFromSuggestion = suggestions?.Take(_settings.MaxSuggestions).Select(o => new Result
{
Title = o,
SubTitle = subtitle,
Score = score,
IcoPath = searchSource.IconPath,
ActionKeywordAssigned = searchSource.ActionKeyword == SearchSourceGlobalPluginWildCardSign ? string.Empty : searchSource.ActionKeyword,
Action = c =>
{
_context.API.OpenWebUrl(searchSource.Url.Replace("{q}", Uri.EscapeDataString(o)), searchSource.IsPrivateMode);
return true;
2024-11-18 12:07:57 +00:00
},
ContextData = searchSource.Url.Replace("{q}", Uri.EscapeDataString(o)),
});
return resultsFromSuggestion;
}
2024-11-18 12:07:57 +00:00
public List<Result> LoadContextMenus(Result selected)
{
2024-11-18 12:43:22 +00:00
if (selected?.ContextData == null || selected.ContextData is not string) return new List<Result>();
2024-11-18 12:07:57 +00:00
return new List<Result>() {
new Result
{
Title = _context.API.GetTranslation("flowlauncher_plugin_websearch_copyurl_title"),
SubTitle = _context.API.GetTranslation("flowlauncher_plugin_websearch_copyurl_subtitle"),
IcoPath = "Images/copylink.png",
Action = c =>
{
_context.API.CopyToClipboard(selected.ContextData as string);
return true;
}
},
};
}
2021-01-07 03:09:08 +00:00
public Task InitAsync(PluginInitContext context)
{
2021-01-07 03:09:08 +00:00
return Task.Run(Init);
void Init()
{
_context = context;
_settings = _context.API.LoadSettingJsonStorage<Settings>();
_viewModel = new SettingsViewModel(_settings);
2021-12-09 03:48:27 +00:00
2021-01-07 03:09:08 +00:00
var pluginDirectory = _context.CurrentPluginMetadata.PluginDirectory;
var bundledImagesDirectory = Path.Combine(pluginDirectory, Images);
// Default images directory is in the WebSearch's application folder
DefaultImagesDirectory = Path.Combine(pluginDirectory, Images);
FilesFolders.ValidateDataDirectory(bundledImagesDirectory, DefaultImagesDirectory);
2021-01-07 03:09:08 +00:00
// Custom images directory is in the WebSearch's data location folder
CustomImagesDirectory = Path.Combine(_context.CurrentPluginMetadata.PluginSettingsDirectoryPath, "CustomIcons");
};
}
2014-03-29 08:13:36 +00:00
#region ISettingProvider Members
public Control CreateSettingPanel()
2014-03-29 08:13:36 +00:00
{
return new SettingsControl(_context, _viewModel);
2014-03-29 08:13:36 +00:00
}
#endregion
2015-01-07 10:45:55 +00:00
2015-02-07 12:17:49 +00:00
public string GetTranslatedPluginTitle()
{
2020-04-21 12:54:41 +00:00
return _context.API.GetTranslation("flowlauncher_plugin_websearch_plugin_name");
2015-02-07 12:17:49 +00:00
}
public string GetTranslatedPluginDescription()
{
2020-04-21 12:54:41 +00:00
return _context.API.GetTranslation("flowlauncher_plugin_websearch_plugin_description");
}
public event ResultUpdatedEventHandler ResultsUpdated;
}
}