Skip to content

Commit b0be1e3

Browse files
committed
Implement DuckDuckGo web search suggestions
1 parent 8d311c4 commit b0be1e3

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ public Settings()
197197
public SuggestionSource[] Suggestions { get; set; } = {
198198
new Google(),
199199
new Baidu(),
200-
new Bing()
200+
new Bing(),
201+
new DuckDuckGo()
201202
};
202203

203204
[JsonIgnore]
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Flow.Launcher.Infrastructure.Http;
6+
using Flow.Launcher.Infrastructure.Logger;
7+
using System.Net.Http;
8+
using System.Threading;
9+
using System.Text.Json;
10+
11+
namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
12+
{
13+
public class DuckDuckGo : SuggestionSource
14+
{
15+
public override async Task<List<string>> SuggestionsAsync(string query, CancellationToken token)
16+
{
17+
// When the search query is empty, DuckDuckGo returns `[]`. When it's not empty, it returns data
18+
// in the following format: `["query", ["suggestion1", "suggestion2", ...]]`.
19+
if (string.IsNullOrEmpty(query))
20+
{
21+
return new List<string>();
22+
}
23+
24+
try
25+
{
26+
const string api = "https://duckduckgo.com/ac/?type=list&q=";
27+
28+
await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);
29+
30+
using var json = await JsonDocument.ParseAsync(resultStream, cancellationToken: token);
31+
32+
var results = json.RootElement.EnumerateArray().ElementAt(1);
33+
34+
return results.EnumerateArray().Select(o => o.GetString()).ToList();
35+
36+
}
37+
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
38+
{
39+
Log.Exception("|DuckDuckGo.Suggestions|Can't get suggestion from DuckDuckGo", e);
40+
return null;
41+
}
42+
catch (JsonException e)
43+
{
44+
Log.Exception("|DuckDuckGo.Suggestions|can't parse suggestions", e);
45+
return new List<string>();
46+
}
47+
}
48+
49+
public override string ToString()
50+
{
51+
return "DuckDuckGo";
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)