Skip to content
This repository has been archived by the owner on May 30, 2024. It is now read-only.

Commit

Permalink
close #4
Browse files Browse the repository at this point in the history
  • Loading branch information
newbe36524 committed May 3, 2021
1 parent ef1e405 commit f6c03bd
Show file tree
Hide file tree
Showing 28 changed files with 472 additions and 88 deletions.
3 changes: 3 additions & 0 deletions src/Newbe.BookmarkManager/Newbe.BookmarkManager.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<PackageReference Include="Blazor.BrowserExtension" Version="0.1.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
<PackageReference Include="Refit" Version="6.0.38" />
<PackageReference Include="Refit.HttpClientFactory" Version="6.0.38" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="WebExtension.Net" Version="0.2.1" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Capi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Capi_005Cimpl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Ccommon/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Ccommon_005Cimpl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cextensions/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -10,4 +12,6 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Crepository/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Crepository_005Cimpl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cservices/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cservices_005Cimpl/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cservices_005Cimpl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Ctextalias/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Ctextalias_005Cimpl/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
2 changes: 2 additions & 0 deletions src/Newbe.BookmarkManager/Pages/Manager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public partial class Manager
[Inject] public IBkManager BkManager { get; set; }
[Inject] public IBkDataHolder BkDataHolder { get; set; }
[Inject] public ISyncBookmarkJob SyncBookmarkJob { get; set; }
[Inject] public ISyncAliasJob SyncAliasJob { get; set; }

private BkViewItem[] _targetBks = Array.Empty<BkViewItem>();

Expand Down Expand Up @@ -46,6 +47,7 @@ protected override async Task OnInitializedAsync()
await BkDataHolder.InitAsync();
BkDataHolder.OnDataReload += BkDataHolderOnOnDataReload;
await SyncBookmarkJob.StartAsync();
await SyncAliasJob.StartAsync();
_searchSubject
.Throttle(TimeSpan.FromMilliseconds(1000))
.Select(x => x?.Trim())
Expand Down
19 changes: 17 additions & 2 deletions src/Newbe.BookmarkManager/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newbe.BookmarkManager.Services;
using Newbe.BookmarkManager.Services.Configuration;
using Refit;
using WebExtension.Net.Bookmarks;
using WebExtension.Net.Storage;
using WebExtension.Net.Tabs;
Expand All @@ -20,19 +23,31 @@ public static async Task Main(string[] args)

builder.Services.AddScoped(
sp => new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)})
.Configure<BaseUriOptions>(builder.Configuration.GetSection(nameof(BaseUriOptions)))
.Configure<AliasJobOptions>(builder.Configuration.GetSection(nameof(AliasJobOptions)))
;
builder.Services
.AddAntDesign()
.AddBrowserExtensionServices(options => { options.ProjectNamespace = typeof(Program).Namespace; })
.AddTransient<IBookmarksApi, BookmarksApi>()
.AddTransient<ITabsApi, TabsApi>()
.AddTransient<IWindowsApi, WindowsApi>()
.AddTransient<IStorageApi, StorageApi>()
.AddTransient<IClock, SystemClock>()
.AddTransient<IBkManager, BkManager>()
.AddTransient<IBkSearcher, BkSearcher>()
.AddSingleton<IBookmarkDataHolder, BookmarkDataHolder>()
.AddTransient<IClock, SystemClock>()
.AddTransient<IBkRepository, BkRepository>()
.AddSingleton<IBkDataHolder, BkDataHolder>()
.AddSingleton<ISyncBookmarkJob, SyncBookmarkJob>()
.AddTransient<IStorageApi, StorageApi>()
.AddSingleton<ISyncAliasJob, SyncAliasJob>()
.AddTransient<ITextAliasProvider, PinyinTextAliasProvider>();
builder.Services
.AddRefitClient<IPinyinApi>()
.ConfigureHttpClient((sp, client) =>
{
client.BaseAddress = new Uri(sp.GetRequiredService<IOptions<BaseUriOptions>>().Value.PinyinApi);
})
;

await builder.Build().RunAsync();
Expand Down
11 changes: 11 additions & 0 deletions src/Newbe.BookmarkManager/Services/Api/IPinyinApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Refit;

namespace Newbe.BookmarkManager.Services
{
public interface IPinyinApi
{
[Post("/pinyin")]
Task<PinyinOutput> GetPinyinAsync(PinyinInput input);
}
}
15 changes: 15 additions & 0 deletions src/Newbe.BookmarkManager/Services/Api/PinyinOutput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;

namespace Newbe.BookmarkManager.Services
{
public record PinyinOutput
{
public bool IsOk { get; set; }
public Dictionary<string, string> Pinyin { get; set; }
}

public record PinyinInput
{
public string[] Text { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Newbe.BookmarkManager.Services.Configuration
{
public record AliasJobOptions
{
public bool EnablePinyinAlias { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Newbe.BookmarkManager.Services.Configuration
{
public record BaseUriOptions
{
public string PinyinApi { get; set; }
}
}
9 changes: 9 additions & 0 deletions src/Newbe.BookmarkManager/Services/Job/ISyncAliasJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Threading.Tasks;

namespace Newbe.BookmarkManager.Services
{
public interface ISyncAliasJob
{
ValueTask StartAsync();
}
}
1 change: 0 additions & 1 deletion src/Newbe.BookmarkManager/Services/Job/ISyncBookmarkJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ namespace Newbe.BookmarkManager.Services
public interface ISyncBookmarkJob
{
ValueTask StartAsync();
ValueTask LoadNowAsync();
}
}
109 changes: 109 additions & 0 deletions src/Newbe.BookmarkManager/Services/Job/Impl/SyncAliasJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newbe.BookmarkManager.Services.Configuration;

namespace Newbe.BookmarkManager.Services
{
public class SyncAliasJob : ISyncAliasJob
{
private readonly ILogger<SyncAliasJob> _logger;
private readonly IOptions<AliasJobOptions> _options;
private readonly IBkDataHolder _bkDataHolder;
private readonly IClock _clock;
private readonly IEnumerable<ITextAliasProvider> _fillers;
private readonly Subject<long> _jobSubject = new();

// ReSharper disable once NotAccessedField.Local
private IDisposable _loadHandler;

public SyncAliasJob(
ILogger<SyncAliasJob> logger,
IOptions<AliasJobOptions> options,
IBkDataHolder bkDataHolder,
IClock clock,
IEnumerable<ITextAliasProvider> fillers)
{
_logger = logger;
_options = options;
_bkDataHolder = bkDataHolder;
_clock = clock;
_fillers = fillers;
}

public ValueTask StartAsync()
{
if (_options.Value.EnablePinyinAlias)
{
_loadHandler = _jobSubject
.Merge(Observable.Interval(TimeSpan.FromSeconds(60)))
.Select(_ => Observable.FromAsync(async () =>
{
try
{
foreach (var textAliasFiller in _fillers)
{
var bkTags = _bkDataHolder.Collection.Tags.Values
.Where(tag => textAliasFiller.NeedFill(tag))
.ToArray();
if (bkTags.Length > 0)
{
await _bkDataHolder.PushDataChangeActionAsync(async () =>
{
var updateResult = await textAliasFiller.FillAsync(bkTags);
if (updateResult.IsOk)
{
_logger.LogInformation("New alias add for tag");
}
return updateResult.IsOk;
});
}
}
foreach (var textAliasFiller in _fillers)
{
var bks = _bkDataHolder.Collection.Bks.Values
.Where(x => textAliasFiller.NeedFill(x))
.ToArray();
if (bks.Length > 0)
{
_logger.LogInformation("Found {Count} bks need to add alias in {TextAliasType}",
bks.Length,
textAliasFiller.TextAliasType);
const int pageSize = 100;
var pageCount = (int) Math.Ceiling(1.0 * bks.Length / pageSize);
await _bkDataHolder.PushDataChangeActionAsync(async () =>
{
var updated = false;
for (var i = 0; i < pageCount; i++)
{
var items = bks.Skip(i * pageSize).Take(pageSize).ToArray();
var updateResult = await textAliasFiller.FillAsync(items);
updated = updated || updateResult.IsOk;
}
return updated;
});
}
}
}
catch (Exception e)
{
_logger.LogError(e, "Failed to fill alias");
}
}))
.Concat()
.Subscribe(_ => { });
_jobSubject.OnNext(_clock.UtcNow);
}

return ValueTask.CompletedTask;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,5 @@ public async ValueTask StartAsync()
.Concat()
.Subscribe(_ => { });
}

public ValueTask LoadNowAsync()
{
_jobSubject.OnNext(_clock.UtcNow);
return ValueTask.CompletedTask;
}
}
}
3 changes: 2 additions & 1 deletion src/Newbe.BookmarkManager/Services/Models/Bk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ namespace Newbe.BookmarkManager.Services
public record Bk
{
public string Title { get; set; }
public Dictionary<BkAliasType, string> TitleAlias { get; } = new();
public Dictionary<TextAliasType, TextAlias> TitleAlias { get; set; }
public string Url { get; init; }
public string FavIconUrl { get; set; }
public List<string> Tags { get; set; } = new();
public int ClickedCount { get; set; }
public long LastClickTime { get; set; }
public long TitleLastUpdateTime { get; set; }
public long LastCreateTime { get; set; }
}
}
2 changes: 1 addition & 1 deletion src/Newbe.BookmarkManager/Services/Models/BkTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace Newbe.BookmarkManager.Services
public record BkTag
{
public string Tag { get; set; }
public Dictionary<BkAliasType, string> TagAlias { get; set; } = new();
public Dictionary<TextAliasType, TextAlias> TagAlias { get; set; } = new();
}
}
9 changes: 9 additions & 0 deletions src/Newbe.BookmarkManager/Services/Models/TextAlias.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Newbe.BookmarkManager.Services
{
public record TextAlias
{
public TextAliasType TextAliasType { get; set; }
public string Alias { get; set; }
public long LastUpdatedTime { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Newbe.BookmarkManager.Services
{
public enum BkAliasType
public enum TextAliasType
{
Pinyin
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public async ValueTask SaveAsync(BkEntityCollection collection)
{
var local = await _storageApi.GetLocal();
var json = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(collection));
_logger.LogDebug("Data save: {Json}", json);
await local.Set(new Dictionary<string, object>
{
{BookmarkStorageKeyName, json},
Expand Down
23 changes: 22 additions & 1 deletion src/Newbe.BookmarkManager/Services/Services/IBkDataHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,28 @@ public interface IBkDataHolder
ValueTask SaveNowAsync();
ValueTask RestoreAsync();
ValueTask InitAsync();
Task PushDataChangeActionAsync(Func<Task> action);
Task PushDataChangeActionAsync(Func<Task<bool>> action);
event EventHandler<EventArgs> OnDataReload;
}

public static class BkDataHolderExtensions
{
public static Task PushDataChangeActionAsync(this IBkDataHolder holder, Func<Task> action)
{
return holder.PushDataChangeActionAsync(async () =>
{
await action.Invoke();
return true;
});
}

public static Task PushDataChangeActionAsync(this IBkDataHolder holder, Action action)
{
return holder.PushDataChangeActionAsync(() =>
{
action.Invoke();
return Task.FromResult(true);
});
}
}
}
10 changes: 0 additions & 10 deletions src/Newbe.BookmarkManager/Services/Services/ITitleAliasProvider.cs

This file was deleted.

Loading

0 comments on commit f6c03bd

Please sign in to comment.