-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bd265b4
Showing
9 changed files
with
744 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.5.33312.197 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BrowserSearch", "BrowserSearch\BrowserSearch.csproj", "{EF807AEB-094D-449A-8FF3-B34E56FB05C6}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|x64 = Debug|x64 | ||
Release|x64 = Release|x64 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{EF807AEB-094D-449A-8FF3-B34E56FB05C6}.Debug|x64.ActiveCfg = Debug|x64 | ||
{EF807AEB-094D-449A-8FF3-B34E56FB05C6}.Debug|x64.Build.0 = Debug|x64 | ||
{EF807AEB-094D-449A-8FF3-B34E56FB05C6}.Release|x64.ActiveCfg = Release|x64 | ||
{EF807AEB-094D-449A-8FF3-B34E56FB05C6}.Release|x64.Build.0 = Release|x64 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {6BD530DB-D589-4E04-A00B-864C0233829A} | ||
EndGlobalSection | ||
EndGlobal |
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,37 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net7.0-windows</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<UseWPF>true</UseWPF> | ||
<AssemblyName>Community.PowerToys.Run.Plugin.$(MSBuildProjectName)</AssemblyName> | ||
<Platforms>AnyCPU;x64</Platforms> | ||
</PropertyGroup> | ||
|
||
<!-- These libraries can be copied from any installation of PowerToys --> | ||
<!-- They are located at <PowerToys Path>\modules\launcher --> | ||
<ItemGroup> | ||
<Reference Include="Wox.Plugin"> | ||
<HintPath>libs\Wox.Plugin.dll</HintPath> | ||
</Reference> | ||
<Reference Include="Wox.Infrastructure"> | ||
<HintPath>libs\Wox.Infrastructure.dll</HintPath> | ||
</Reference> | ||
<Reference Include="Microsoft.Data.Sqlite.Core"> | ||
<HintPath>libs\Microsoft.Data.Sqlite.dll</HintPath> | ||
</Reference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="Images\BrowserSearch.dark.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="Images\BrowserSearch.light.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="plugin.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
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,131 @@ | ||
using Microsoft.Data.Sqlite; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using Wox.Infrastructure; | ||
using Wox.Plugin; | ||
using Wox.Plugin.Logger; | ||
using BrowserInfo = Wox.Plugin.Common.DefaultBrowserInfo; | ||
|
||
namespace BrowserSearch | ||
{ | ||
internal class Chrome : IBrowser | ||
{ | ||
private SqliteConnection? _historyDbConnection, _predictorDbConnection; | ||
|
||
private readonly List<Result> _history = new(); | ||
public string Name { get; } = "Google Chrome"; | ||
public Dictionary<string, string> Predictions { get; } = new(); | ||
|
||
void IBrowser.Init() | ||
{ | ||
CopyDatabases(); | ||
if (_historyDbConnection is null || _predictorDbConnection is null) | ||
{ | ||
throw new ArgumentNullException(nameof(_historyDbConnection)); | ||
} | ||
if (_predictorDbConnection is null) | ||
{ | ||
throw new ArgumentNullException(nameof(_predictorDbConnection)); | ||
} | ||
|
||
PopulatePredictions(); | ||
PopulateHistory(); | ||
|
||
_historyDbConnection.Close(); | ||
_predictorDbConnection.Close(); | ||
} | ||
|
||
private void CopyDatabases() | ||
{ | ||
string historyCopy = Path.GetTempPath() + @"\BrowserSearch_Chrome_History"; | ||
string predictorCopy = Path.GetTempPath() + @"\BrowserSearch_Chrome_ActionPredictor"; | ||
|
||
// We need to copy the databases. If we don't, we won't be able to open them | ||
// while Chrome is running | ||
string localappdata = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); | ||
File.Copy(localappdata + @"\Google\Chrome\User Data\Default\History", historyCopy, true); | ||
File.Copy(localappdata + @"\Google\Chrome\User Data\Default\Network Action Predictor", predictorCopy, true); | ||
|
||
_historyDbConnection = new($"Data Source={historyCopy}"); | ||
_predictorDbConnection = new($"Data Source={predictorCopy}"); | ||
} | ||
|
||
private SqliteDataReader ExecuteCmd(SqliteConnection connection, SqliteCommand cmd) | ||
{ | ||
cmd.Connection = connection; | ||
connection.Open(); | ||
|
||
return cmd.ExecuteReader(); | ||
} | ||
|
||
private void PopulatePredictions() | ||
{ | ||
if (_predictorDbConnection is null) | ||
{ | ||
throw new ArgumentNullException(nameof(_predictorDbConnection)); | ||
} | ||
|
||
Dictionary<string, long> _predictionHits = new(); | ||
|
||
using SqliteCommand cmd = new("SELECT user_text, url, number_of_hits FROM network_action_predictor"); | ||
using SqliteDataReader reader = ExecuteCmd(_predictorDbConnection, cmd); | ||
while (reader.Read()) | ||
{ | ||
string text = (string)reader[0]; // Query | ||
string url = (string)reader[1]; // Predicted URL for that query | ||
long hits = (long)reader[2]; // Amount of times the prediction was correct and the user selected it | ||
|
||
// There can be multiples predictions for the same query | ||
// So lets make sure to only select the one with the most hits | ||
if (_predictionHits.GetValueOrDefault(text, -1) < hits) | ||
{ | ||
_predictionHits[text] = hits; | ||
Predictions[text] = url; | ||
} | ||
} | ||
} | ||
|
||
private void PopulateHistory() | ||
{ | ||
if (_historyDbConnection is null) | ||
{ | ||
throw new ArgumentNullException(nameof(_historyDbConnection)); | ||
} | ||
|
||
using SqliteCommand historyReadCmd = new("SELECT url, title FROM urls ORDER BY visit_count DESC"); | ||
using SqliteDataReader reader = ExecuteCmd(_historyDbConnection, historyReadCmd); | ||
while (reader.Read()) | ||
{ | ||
string url = (string)reader[0]; | ||
string title = (string)reader[1]; | ||
|
||
Result result = new() | ||
{ | ||
QueryTextDisplay = url, | ||
Title = title, | ||
SubTitle = url, | ||
IcoPath = BrowserInfo.IconPath, | ||
Action = action => | ||
{ | ||
// Open URL in default browser | ||
if (!Helper.OpenInShell(url)) | ||
{ | ||
Log.Error($"Couldn't open '{url}'", typeof(Chrome)); | ||
return false; | ||
} | ||
|
||
return true; | ||
}, | ||
}; | ||
|
||
_history.Add(result); | ||
} | ||
} | ||
|
||
List<Result> IBrowser.GetHistory() | ||
{ | ||
return _history ?? new List<Result>(); | ||
} | ||
} | ||
} |
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,14 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Wox.Plugin; | ||
|
||
namespace BrowserSearch | ||
{ | ||
internal interface IBrowser | ||
{ | ||
string Name { get; } | ||
Dictionary<string, string> Predictions { get; } | ||
void Init(); | ||
List<Result> GetHistory(); | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,123 @@ | ||
using BrowserSearch; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Wox.Plugin; | ||
using Wox.Plugin.Logger; | ||
using BrowserInfo = Wox.Plugin.Common.DefaultBrowserInfo; | ||
|
||
namespace Community.Powertoys.Run.Plugin.BrowserSearch | ||
{ | ||
public class Main : IPlugin, IReloadable | ||
{ | ||
private PluginInitContext? _context; | ||
|
||
private readonly List<IBrowser> _supportedBrowsers = new() | ||
{ | ||
new Chrome() | ||
}; | ||
private IBrowser? _defaultBrowser; | ||
|
||
public string Name => "Browser Search"; | ||
public string Description => "Search in your browser's history."; | ||
|
||
public void Init(PluginInitContext context) | ||
{ | ||
_context = context ?? throw new ArgumentNullException(nameof(context)); | ||
|
||
// Retrieve default browser info | ||
BrowserInfo.UpdateIfTimePassed(); | ||
|
||
foreach (IBrowser b in _supportedBrowsers) | ||
{ | ||
if (b.Name == BrowserInfo.Name) | ||
{ | ||
_defaultBrowser = b; | ||
break; | ||
} | ||
} | ||
|
||
if (_defaultBrowser is null) | ||
{ | ||
Log.Error($"Unsupported/unrecognized default browser '{BrowserInfo.Name}'", typeof(Main)); | ||
return; | ||
} | ||
|
||
_defaultBrowser.Init(); | ||
} | ||
|
||
private int CalculateScore(string query, string title, string url, string? predictionUrl) | ||
{ | ||
// Since PT Run's FuzzySearch is too slow, and the history usually has a lot of entries, | ||
// lets calculate the scores manually. | ||
float titleScore = title.Contains(query, StringComparison.InvariantCultureIgnoreCase) | ||
? ((float)query.Length / (float)title.Length * 100f) | ||
: 0; | ||
float urlScore = url.Contains(query, StringComparison.InvariantCultureIgnoreCase) | ||
? ((float)query.Length / (float)url.Length * 100f) | ||
: 0; | ||
|
||
float score = new[] { titleScore, urlScore }.Max(); | ||
|
||
// If the browser has a prediction for this specific query, | ||
// we want to give a higher score to the entry that has | ||
// the prediction's url | ||
if (predictionUrl is not null && predictionUrl == url) | ||
{ | ||
score += 50; | ||
} | ||
|
||
return (int)score; | ||
} | ||
|
||
public List<Result> Query(Query query) | ||
{ | ||
if (query is null) | ||
{ | ||
throw new ArgumentNullException(nameof(query)); | ||
} | ||
if (_defaultBrowser is null) | ||
{ | ||
return new List<Result>(); | ||
} | ||
|
||
List<Result> history = _defaultBrowser.GetHistory(); | ||
|
||
// This happens when the user only typed this plugin's ActionKeyword ("b?") | ||
if (string.IsNullOrEmpty(query.Search)) | ||
{ | ||
return history; | ||
} | ||
|
||
List<Result> results = new(); | ||
// Get the Browser's prediction for this specific query, if it has one | ||
_defaultBrowser.Predictions.TryGetValue(query.Search, out string? prediction); | ||
|
||
for (int i = 0; i < history.Count; i++) | ||
{ | ||
Result r = history[i]; | ||
|
||
int score = CalculateScore(query.Search, r.Title, r.SubTitle, prediction); | ||
if (score <= 0) | ||
{ | ||
continue; | ||
} | ||
|
||
r.Score = score; | ||
results.Add(r); | ||
} | ||
|
||
return results; | ||
} | ||
|
||
public void ReloadData() | ||
{ | ||
if (_context is null) | ||
{ | ||
return; | ||
} | ||
|
||
BrowserInfo.UpdateIfTimePassed(); | ||
} | ||
} | ||
} |
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,13 @@ | ||
{ | ||
"ID": "E5A9FC7A3F7F4320BE612DA95C57C32D", | ||
"ActionKeyword": "b?", | ||
"IsGlobal": true, | ||
"Name": "Browser Search", | ||
"Author": "TBM13", | ||
"Version": "1.0.0", | ||
"Language": "csharp", | ||
"Website": "https://github.com/TBM13/BrowserSearch", | ||
"ExecuteFileName": "Community.PowerToys.Run.Plugin.BrowserSearch.dll", | ||
"IcoPathDark": "Images\\BrowserSearch.dark.png", | ||
"IcoPathLight": "Images\\BrowserSearch.light.png" | ||
} |