Skip to content
Closed
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
153 changes: 19 additions & 134 deletions Flow.Launcher.Infrastructure/Alphabet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using hyjiacan.util.p4n;
using hyjiacan.util.p4n.format;
using JetBrains.Annotations;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using ToolGood.Words.Pinyin;
using System.Threading.Tasks;

namespace Flow.Launcher.Infrastructure
{
Expand All @@ -19,160 +19,45 @@ public interface IAlphabet

public class Alphabet : IAlphabet
{
private readonly HanyuPinyinOutputFormat Format = new HanyuPinyinOutputFormat();
private ConcurrentDictionary<string, string[][]> PinyinCache;
private BinaryStorage<Dictionary<string, string[][]>> _pinyinStorage;
private ConcurrentDictionary<string, string> _pinyinCache = new ConcurrentDictionary<string, string>();
private Settings _settings;

public void Initialize([NotNull] Settings settings)
{
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
InitializePinyinHelpers();
}

private void InitializePinyinHelpers()
{
Format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

Stopwatch.Normal("|Flow Launcher.Infrastructure.Alphabet.Initialize|Preload pinyin cache", () =>
{
_pinyinStorage = new BinaryStorage<Dictionary<string, string[][]>>("Pinyin");

lock(_pinyinStorage)
{
var loaded = _pinyinStorage.TryLoad(new Dictionary<string, string[][]>());

PinyinCache = new ConcurrentDictionary<string, string[][]>(loaded);
}

// force pinyin library static constructor initialize
PinyinHelper.toHanyuPinyinStringArray('T', Format);
});
Log.Info($"|Flow Launcher.Infrastructure.Alphabet.Initialize|Number of preload pinyin combination<{PinyinCache.Count}>");
}

public string Translate(string str)
{
return ConvertChineseCharactersToPinyin(str);
}

public string ConvertChineseCharactersToPinyin(string source)
{
if (!_settings.ShouldUsePinyin)
return source;

if (string.IsNullOrEmpty(source))
return source;

if (!ContainsChinese(source))
return source;

var combination = PinyinCombination(source);

var pinyinArray=combination.Select(x => string.Join("", x));
var acronymArray = combination.Select(Acronym).Distinct();

var joinedSingleStringCombination = new StringBuilder();
var all = acronymArray.Concat(pinyinArray);
all.ToList().ForEach(x => joinedSingleStringCombination.Append(x));

return joinedSingleStringCombination.ToString();
}

public void Save()
{
if (!_settings.ShouldUsePinyin)
{
return;
}

lock(_pinyinStorage)
{
_pinyinStorage.Save(PinyinCache.ToDictionary(i => i.Key, i => i.Value));
}
}

private static string[] EmptyStringArray = new string[0];
private static string[][] Empty2DStringArray = new string[0][];

/// <summmary>
/// replace chinese character with pinyin, non chinese character won't be modified
/// Because we don't have words dictionary, so we can only return all possiblie pinyin combination
/// e.g. 音乐 will return yinyue and yinle
/// <param name="characters"> should be word or sentence, instead of single character. e.g. 微软 </param>
/// </summmary>
public string[][] PinyinCombination(string characters)
public string Translate(string content)
{
if (!_settings.ShouldUsePinyin || string.IsNullOrEmpty(characters))
{
return Empty2DStringArray;
}

if (!PinyinCache.ContainsKey(characters))
if (_settings.ShouldUsePinyin)
{
var allPinyins = new List<string[]>();
foreach (var c in characters)
if (_pinyinCache.ContainsKey(content))
{
var pinyins = PinyinHelper.toHanyuPinyinStringArray(c, Format);
if (pinyins != null)
if (WordsHelper.HasChinese(content))
{
var r = pinyins.Distinct().ToArray();
allPinyins.Add(r);
var result = WordsHelper.GetPinyin(content, ";");
result = GetFirstPinyinChar(result) + result.Replace(";", "");
_pinyinCache[content] = result;
return result;
}
else
{
var r = new[] { c.ToString() };
allPinyins.Add(r);
return content;
}
}

var combination = allPinyins.Aggregate(Combination).Select(c => c.Split(';')).ToArray();
PinyinCache[characters] = combination;
return combination;
else
return _pinyinCache[content];
}
else
{
return PinyinCache[characters];
return content;
}
}

public string Acronym(string[] pinyin)
{
var acronym = string.Join("", pinyin.Select(p => p[0]));
return acronym;
}

public bool ContainsChinese(string word)
private string GetFirstPinyinChar(string content)
{
if (!_settings.ShouldUsePinyin)
{
return false;
}

if (word.Length > 40)
{
//Skip strings that are too long string for Pinyin conversion.
return false;
}

var chinese = word.Select(PinyinHelper.toHanyuPinyinStringArray)
.Any(p => p != null);
return chinese;
}

private string[] Combination(string[] array1, string[] array2)
{
if (!_settings.ShouldUsePinyin)
{
return EmptyStringArray;
}

var combination = (
from a1 in array1
from a2 in array2
select $"{a1};{a2}"
).ToArray();
return combination;
return string.Concat(content.Split(';').Select(x => x.First()));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog.Schema" Version="4.7.0-rc1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />
<PackageReference Include="Pinyin4DotNet" Version="2016.4.23.4" />
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
<PackageReference Include="PropertyChanged.Fody" Version="2.5.13" />
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.0.1.4" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 0 additions & 1 deletion Flow.Launcher.Infrastructure/StringMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption

if (_alphabet != null)
{
query = _alphabet.Translate(query);
stringToCompare = _alphabet.Translate(stringToCompare);
}

Expand Down
1 change: 0 additions & 1 deletion Flow.Launcher/PublicAPIInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ public void SaveAppAllSettings()
_settingsVM.Save();
PluginManager.Save();
ImageLoader.Save();
_alphabet.Save();
}

public void ReloadAllPluginData()
Expand Down
17 changes: 9 additions & 8 deletions Plugins/Flow.Launcher.Plugin.Program/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin.Program.Programs;
using Flow.Launcher.Plugin.Program.Views;
using ToolGood.Words.Pinyin;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;

namespace Flow.Launcher.Plugin.Program
Expand Down Expand Up @@ -77,15 +78,15 @@ public List<Result> Query(Query query)
uwps = _uwps;
}

var results1 = win32.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));
var searchText = WordsHelper.HasChinese(query.Search) ? WordsHelper.GetPinyin(query.Search) : query.Search;

var results2 = uwps.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));

var result = results1.Concat(results2).Where(r => r != null && r.Score > 0).ToList();
var result = win32
.Cast<IProgram>()
.Concat(uwps)
.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(searchText, _context.API))
.Where(r=>r?.Score > 0).ToList();
return result;
}

Expand Down
4 changes: 3 additions & 1 deletion Plugins/Flow.Launcher.Plugin.Program/Programs/IProgram.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;

namespace Flow.Launcher.Plugin.Program.Programs
{
Expand All @@ -9,5 +10,6 @@ public interface IProgram
string UniqueIdentifier { get; set; }
string Name { get; }
string Location { get; }
bool Enabled { get; }
}
}