Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions generate_dist.bat

This file was deleted.

110 changes: 110 additions & 0 deletions src/DictDownloadManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using Flow.Launcher.Plugin;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Threading.Tasks;

namespace Dictionary
{
public class DictDownloadManager
{
private string dictPath;
private bool downloading = false;
private int downloadPercentage = 0;
private PluginInitContext context;

public DictDownloadManager(string dictPath, PluginInitContext context)
{
this.dictPath = dictPath;
this.context = context;
}

private async Task<bool> CheckForGoogleConnection()
{
try
{
var request = WebRequest.Create("https://google.com/generate_204");
request.Timeout = 2000;
await request.GetResponseAsync();
return true;
}
catch
{
return false;
}
}

private async Task<string> GetDownloadUrl()
{
bool shouldUseMirror = !await CheckForGoogleConnection();
if (shouldUseMirror)
return "https://nullptr_t.coding.net/p/ECDICT-sqlite/d/ECDICT-sqlite/git/raw/master/ecdict-ultimate-sqlite.zip";
else
return "https://github.com/skywind3000/ECDICT-ultimate/releases/download/1.0.0/ecdict-ultimate-sqlite.zip";
}

public async void PerformDownload()
{
downloading = true;

var url = await GetDownloadUrl();
var path = Path.GetDirectoryName(dictPath);
if (!Directory.Exists(path)) Directory.CreateDirectory(path);

var client = new WebClient();

client.DownloadProgressChanged += delegate (object sender, DownloadProgressChangedEventArgs e)
{
downloadPercentage = e.ProgressPercentage;
};

var tmpDictFileLoc = dictPath + ".download";
await client.DownloadFileTaskAsync(new Uri(url), tmpDictFileLoc).ConfigureAwait(false);

await Task.Run(() => ZipFile.ExtractToDirectory(tmpDictFileLoc, Path.GetDirectoryName(dictPath)));

File.Delete(tmpDictFileLoc);

downloading = false;
}

public async Task<List<Result>> HandleQueryAsync(Query query)
{
if (downloading)
{
var progress = "";
if (downloadPercentage != 0) progress = $"{downloadPercentage} %";
return new List<Result> { new Result() {
Title = $"Downloading dictionary database... {progress}",
SubTitle = "Press enter to refresh precentage.",
IcoPath = "Images\\plugin.png",
Action = (e) => {
context.API.ChangeQuery("d downloading" + new string('.',new Random().Next(0,10)));
return false;
}
}};
}
else
{
return new List<Result> { new Result() {
Title = "Dictionary database not found (~1GB Decompressed)",
SubTitle = $"Press enter to download to {dictPath} (~230MB)",
IcoPath = "Images\\plugin.png",
Action = (e) =>
{
if(!downloading) PerformDownload();
context.API.ChangeQuery("d downloading");
return false;
}
}};
}
}

public bool NeedsDownload()
{
return !File.Exists(dictPath);
}
}
}
21 changes: 14 additions & 7 deletions src/Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ public class Main : IAsyncPlugin, ISettingProvider, IResultUpdated
private Iciba iciba;
internal static PluginInitContext Context { get; private set; }
private Settings settings;
private DictDownloadManager dictDownloadManager;
//private SpeechSynthesizer synth;

private string ecdictLocation = Environment.ExpandEnvironmentVariables(@"%LocalAppData%\Flow.Dictionary\ultimate.db");
private string configLocation = Environment.ExpandEnvironmentVariables(@"%AppData%\FlowLauncher\Settings\Plugins\Flow.Dictionary\config.json");

// These two are only for jumping in MakeResultItem
private string ActionWord;
private string QueryWord;
Expand All @@ -41,17 +45,15 @@ public async Task InitAsync(PluginInitContext context)
{
string CurrentPath = context.CurrentPluginMetadata.PluginDirectory;

if (!Directory.Exists(Path.Combine(CurrentPath, "config")))
Directory.CreateDirectory(Path.Combine(CurrentPath, "config"));
Directory.CreateDirectory(Path.GetDirectoryName(configLocation));

string ConfigFile = CurrentPath + "/config/config.json";
if (File.Exists(ConfigFile))
settings = await JsonSerializer.DeserializeAsync<Settings>(File.OpenRead(ConfigFile)).ConfigureAwait(false);
if (File.Exists(configLocation))
settings = await JsonSerializer.DeserializeAsync<Settings>(File.OpenRead(configLocation)).ConfigureAwait(false);
else
settings = new Settings();
settings.ConfigFile = ConfigFile;
settings.ConfigFile = configLocation;

ecdict = new ECDict(CurrentPath + "/dicts/ecdict.db");
dictDownloadManager = new DictDownloadManager(ecdictLocation, context);
wordCorrection = new WordCorrection(CurrentPath + "/dicts/frequency_dictionary_en_82_765.txt", settings.MaxEditDistance);
synonyms = new Synonyms(settings.BighugelabsToken);
iciba = new Iciba(settings.ICIBAToken);
Expand Down Expand Up @@ -327,11 +329,16 @@ private bool IsChinese(string cn)

public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
{
if (dictDownloadManager.NeedsDownload())
return await dictDownloadManager.HandleQueryAsync(query).ConfigureAwait(false);

ActionWord = query.ActionKeyword;
string queryWord = query.Search;
if (queryWord == "") return new List<Result>();
QueryWord = queryWord;

if (ecdict == null) ecdict = new ECDict(ecdictLocation);

if (queryWord.Length < 2)
return await FirstLevelQueryAsync(query, token).ConfigureAwait(false);

Expand Down
22 changes: 11 additions & 11 deletions src/ECDict.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Linq;
using System.Text.RegularExpressions;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -13,12 +12,19 @@ namespace Dictionary
class ECDict
{
readonly SQLiteConnection conn;
Regex stripWord = new Regex("[^a-zA-Z0-9]");

public ECDict(string filename)
{
conn = new SQLiteConnection("Data Source=" + filename + ";Version=3;Read Only=True");
conn.Open();
}

public string StripWord(string word)
{
return stripWord.Replace(word.Trim().ToLower(), "");
}

// This will only return exact match.
// Return null if not found.
public async Task<Word> QueryAsync(string word, CancellationToken token)
Expand Down Expand Up @@ -52,16 +58,15 @@ public async IAsyncEnumerable<Word> QueryRange(IEnumerable<string> words, [Enume

while (await reader.ReadAsync(token).ConfigureAwait(false))
yield return new Word(reader);


}

// This will include exact match and words beginning with it
public async IAsyncEnumerable<Word> QueryBeginningWith(string word, [EnumeratorCancellation] CancellationToken token = default, int limit = 20)
{
word = StripWord(word);
if (word.Length == 0) yield break;

string sql = "select * from stardict where word like '" + word +
string sql = "select * from stardict where sw like '" + word +
"%' order by frq > 0 desc, frq asc limit " + limit;

using SQLiteCommand cmd = new SQLiteCommand(sql, conn);
Expand All @@ -71,10 +76,5 @@ public async IAsyncEnumerable<Word> QueryBeginningWith(string word, [EnumeratorC
yield return new Word(reader);
}
}

internal Task QueryAsync(string queryWord)
{
throw new NotImplementedException();
}
}
}
14 changes: 7 additions & 7 deletions src/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ namespace Dictionary
public class Settings
{
public string ConfigFile;
public string ICIBAToken = "BEBC0A981CB63ED5198597D732BD8956";
public string BighugelabsToken = "";
public int MaxEditDistance = 3;
public bool ShowEnglishDefinition = false;
public string WordWebsite = "";
public string ICIBAToken { get; set; } = "BEBC0A981CB63ED5198597D732BD8956";
public string BighugelabsToken { get; set; } = "";
public int MaxEditDistance { get; set; } = 3;
public bool ShowEnglishDefinition { get; set; } = false;
public string WordWebsite { get; set; } = "";

public async void Save()
public void Save()
{
await JsonSerializer.SerializeAsync(File.OpenWrite(ConfigFile), this);
File.WriteAllText(ConfigFile, JsonSerializer.Serialize(this));
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it back to blocking api because there seems to be some kind of race condition otherwise.

Copy link
Collaborator

@taooceros taooceros Feb 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic should be changed later after ISavable has been migrated to Flow.Launcher.Plugin so that we shall allow the call of Save automatically by Flow. No race situation will exist after that.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds handy! Look forward to that and PluginJsonStorage class you mentioned.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}
}