Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#41 S3へのアップロードを実装 #48

Merged
merged 21 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
59a2420
#41 S3へのアップロードを実装
miyaji255 May 2, 2024
8b2008b
#49 style bert vit2周りの細かい修正
aiueo-1234 May 2, 2024
2a6c2fd
#49 フォーマット
aiueo-1234 May 2, 2024
372cf8c
Merge pull request #50 from OUCC/feat/#49
aiueo-1234 May 2, 2024
53ca423
#41 State更新の条件を追加
miyaji255 May 2, 2024
cbbbb66
#51 音声合成にかける文字数を制限する&wavからmp3へ変換
TakenPt May 2, 2024
acccb50
#51 生成ファイルの再利用
TakenPt May 2, 2024
0b333f2
#51 カバーファイルのパス代入忘れの修正
aiueo-1234 May 2, 2024
a984402
#51 coverfilepathの削除
aiueo-1234 May 3, 2024
cab481f
#41 生成後のファイルを出力するように変更
miyaji255 May 3, 2024
8a6b5d3
#51 ストリーム周りの修正
aiueo-1234 May 3, 2024
5c96b1e
#51 テストの修正
aiueo-1234 May 3, 2024
dd4a5d2
Merge pull request #52 from OUCC/feat/#51
miyaji255 May 3, 2024
2c95e98
CIの対象にreleaseブランチを追加
miyaji255 May 3, 2024
274fc3d
Merge pull request #53 from OUCC/feat/add-ci-target
miyaji255 May 3, 2024
3377342
Merge branch 'main' into feat/#41
miyaji255 May 3, 2024
8c993e4
fmt
miyaji255 May 3, 2024
749863e
#54 mp3とwavでtotaltimeが変わることへの対処
aiueo-1234 May 3, 2024
04f04ec
#54 Claudeが生成するプロンプトへの対処を追加
aiueo-1234 May 3, 2024
fb35843
Merge pull request #55 from OUCC/feat/#54
aiueo-1234 May 3, 2024
d9130ba
Merge branch 'main' into feat/#41
miyaji255 May 3, 2024
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
6 changes: 6 additions & 0 deletions KoeBook.Core/Contracts/Services/IS3UploadService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace KoeBook.Core.Contracts.Services;

public interface IS3UploadService
{
ValueTask<string> UploadFileAsync(string filePath, CancellationToken cancellationToken);
}
3 changes: 3 additions & 0 deletions KoeBook.Core/EbookException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,7 @@ public enum ExceptionType

[EnumMember(Value = "表紙の画像の生成に失敗しました")]
CreateCoverFileFailed,

[EnumMember(Value = "ファイルのアップロードに失敗しました")]
S3UploadFailed,
}
2 changes: 2 additions & 0 deletions KoeBook.Core/KoeBook.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.7.300" />
<PackageReference Include="AWSSDK.S3" Version="3.7.307.25" />
<PackageReference Include="Betalgo.OpenAI" Version="8.1.1" />
<PackageReference Include="Claudia" Version="1.2.0" />
<PackageReference Include="FastEnum" Version="1.8.0" />
Expand Down
29 changes: 29 additions & 0 deletions KoeBook.Core/Services/S3UploadService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Amazon.S3;
using Amazon.S3.Transfer;
using KoeBook.Core.Contracts.Services;

namespace KoeBook.Core.Services;

public class S3UploadService(IAmazonS3 s3Client) : IS3UploadService
{
private readonly IAmazonS3 _s3Client = s3Client;

public async ValueTask<string> UploadFileAsync(string filePath, CancellationToken cancellationToken)
{
try
{
// 設定に移すのが面倒なので固定値
const string S3BucketName = "koebook-gakusai-storage";
var guid = Guid.NewGuid();
var fileName = Path.GetFileName(filePath);
var fileTransferUtility = new TransferUtility(_s3Client);
await fileTransferUtility.UploadAsync(filePath, S3BucketName, $"{guid}/{fileName}", cancellationToken);

return $"http://storage.koebook.oucc.org/{guid}/{Uri.EscapeDataString(fileName)}";
}
catch (AmazonS3Exception e)
{
throw new EbookException(ExceptionType.S3UploadFailed, innerException: e);
}
}
}
12 changes: 10 additions & 2 deletions KoeBook/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FastEnumUtility;
using Amazon.S3;
using FastEnumUtility;
using KoeBook.Activation;
using KoeBook.Components.Dialog;
using KoeBook.Contracts.Services;
Expand All @@ -15,6 +16,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.UI.Xaml;
using QRCoder;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
Expand Down Expand Up @@ -80,6 +82,8 @@ public App()
services.AddSingleton<IDisplayStateChangeService, DisplayStateChangeService>();
services.AddSingleton<ICreateCoverFileService, CreateCoverFileService>();

services.AddSingleton<QRCodeGenerator>();

// Views and ViewModels
services.AddTransient<SettingsViewModel>();
services.AddTransient<SettingsPage>();
Expand All @@ -96,6 +100,10 @@ public App()
// Configuration
services.Configure<LocalSettingsOptions>(context.Configuration.GetSection(nameof(LocalSettingsOptions)));

// AWS
services.AddDefaultAWSOptions(context.Configuration.GetAWSOptions());
services.AddAWSService<IAmazonS3>();

// Core Services Mock
var mockOptions = context.Configuration.GetSection(nameof(MockOptions)).Get<MockOptions>()!;
if (mockOptions.IAnalyzerService.HasValue && mockOptions.IAnalyzerService.Value)
Expand All @@ -111,7 +119,7 @@ public App()
})
.Build();

App.GetService<IAppNotificationService>().Initialize();
GetService<IAppNotificationService>().Initialize();

UnhandledException += App_UnhandledException;
}
Expand Down
4 changes: 2 additions & 2 deletions KoeBook/Components/Dialog/DialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public Task<ContentDialogResult> ShowAsync(
string title,
object content,
string primaryText,
string closeText,
string? closeText,
ContentDialogButton defaultButton,
CancellationToken cancellationToken)
{
Expand All @@ -36,7 +36,7 @@ public Task<ContentDialogResult> ShowAsync(
string title,
string content,
string primaryText,
string closeText,
string? closeText,
ContentDialogButton defaultButton,
CancellationToken cancellationToken)
{
Expand Down
3 changes: 2 additions & 1 deletion KoeBook/Components/Dialog/SharedContentDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ public SharedContentDialog(string title, string primaryText, string? closeText,
{
Title = title;
PrimaryButtonText = primaryText;
CloseButtonText = closeText;
if (closeText is not null)
CloseButtonText = closeText;
DefaultButton = defaultButton;
InitializeComponent();
}
Expand Down
4 changes: 2 additions & 2 deletions KoeBook/Contracts/Services/IDialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ Task<ContentDialogResult> ShowAsync(
string title,
object content,
string primaryText,
string closeText,
string? closeText,
ContentDialogButton defaultButton,
CancellationToken cancellationToken);

Task<ContentDialogResult> ShowAsync(
string title,
string content,
string primaryText,
string closeText,
string? closeText,
ContentDialogButton defaultButton,
CancellationToken cancellationToken);

Expand Down
7 changes: 6 additions & 1 deletion KoeBook/KoeBook.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.7.300" />
<PackageReference Include="AWSSDK.S3" Version="3.7.307.25" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.0.240109" />
<PackageReference Include="FastEnum" Version="1.8.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231008000" />
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
<PackageReference Include="QRCoder" Version="1.5.1" />
<PackageReference Include="ReactiveProperty" Version="9.4.1" />
<PackageReference Include="WinUIEx" Version="2.3.2" />
</ItemGroup>
Expand Down Expand Up @@ -77,4 +80,6 @@
<ItemGroup>
<Resource Remove="Views\CreateStoryPage.xaml" />
</ItemGroup>

<ProjectExtensions><VisualStudio><UserProperties appsettings_1local_1json__JsonSchema="https://json.schemastore.org/appsettings.json" /></VisualStudio></ProjectExtensions>
</Project>
12 changes: 10 additions & 2 deletions KoeBook/Models/GenerationTask.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using CommunityToolkit.Mvvm.ComponentModel;
using FastEnumUtility;
using KoeBook.Core.Models;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media.Imaging;

namespace KoeBook.Models;

Expand Down Expand Up @@ -39,7 +41,7 @@ public BookProperties ToBookProperties()

public CancellationToken CancellationToken => CancellationTokenSource.Token;

public string Source => _rawSource is string uri ? uri : "AI生成";
public string Source => _rawSource is string uri ? uri : "Claudeによって生成されました。";

private readonly object _rawSource;

Expand All @@ -49,7 +51,7 @@ public BookProperties ToBookProperties()
{
SourceType.Url => "URL",
SourceType.FilePath => "ファイルパス",
SourceType.AiStory => "AI生成",
SourceType.AiStory => "生成方法",
_ => string.Empty,
};

Expand Down Expand Up @@ -93,6 +95,12 @@ public bool SkipEdit

public bool Editable => State == GenerationState.Editting;

[ObservableProperty]
[NotifyPropertyChangedFor(nameof(QrcodeVisibility))]
BitmapImage? _qrcode;

public Visibility QrcodeVisibility => Qrcode is null ? Visibility.Collapsed : Visibility.Visible;

[ObservableProperty]
private BookScripts? _bookScripts;

Expand Down
9 changes: 6 additions & 3 deletions KoeBook/Services/DisplayStateChangeService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using KoeBook.Contracts.Services;
using KoeBook.Core.Contracts.Services;
using KoeBook.Core.Models;
using Microsoft.UI.Dispatching;

namespace KoeBook.Services;

Expand All @@ -11,7 +12,7 @@ internal class DisplayStateChangeService(IGenerationTaskService taskService) : I
public void UpdateProgress(BookProperties bookProperties, int progress, int maximum)
{
var taskService = _taskService; // thisをキャプチャしないようにする
_ = App.MainWindow.DispatcherQueue.TryEnqueue(() =>
_ = App.MainWindow.DispatcherQueue.TryEnqueue(DispatcherQueuePriority.High, () =>
{
var task = taskService.GetProcessingTask(bookProperties.Id);
task.MaximumProgress = maximum;
Expand All @@ -22,9 +23,11 @@ public void UpdateProgress(BookProperties bookProperties, int progress, int maxi
public void UpdateState(BookProperties bookProperties, GenerationState state)
{
var taskService = _taskService; // thisをキャプチャしないようにする
_ = App.MainWindow.DispatcherQueue.TryEnqueue(() =>
_ = App.MainWindow.DispatcherQueue.TryEnqueue(DispatcherQueuePriority.High, () =>
{
taskService.GetProcessingTask(bookProperties.Id).State = state;
var task = taskService.GetProcessingTask(bookProperties.Id);
if(task.State < state)
task.State = state;
});
}

Expand Down
39 changes: 32 additions & 7 deletions KoeBook/Services/GenerationTaskRunnerService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using FastEnumUtility;
using System.Diagnostics;
using FastEnumUtility;
using KoeBook.Contracts.Services;
using KoeBook.Core;
using KoeBook.Core.Contracts.Services;
using KoeBook.Core.Models;
using KoeBook.Models;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using QRCoder;
using Windows.Storage;
using Windows.Storage.Streams;

namespace KoeBook.Services;

Expand All @@ -13,19 +18,25 @@ public class GenerationTaskRunnerService
private readonly IGenerationTaskService _taskService;
private readonly IAnalyzerService _analyzerService;
private readonly IEpubGenerateService _epubGenService;
private readonly IS3UploadService _uploadService;
private readonly QRCodeGenerator _qrCodeGenerator;
private readonly IDialogService _dialogService;
private readonly string _tempFolder = ApplicationData.Current.TemporaryFolder.Path;

public GenerationTaskRunnerService(
IGenerationTaskService taskService,
IAnalyzerService analyzerService,
IEpubGenerateService epubGenService,
IS3UploadService uploadService,
QRCodeGenerator qrCodeGenerator,
IDialogService dialogService)
{
_taskService = taskService;
_taskService.OnTasksChanged += TasksChanged;
_analyzerService = analyzerService;
_epubGenService = epubGenService;
_uploadService = uploadService;
_qrCodeGenerator = qrCodeGenerator;
_dialogService = dialogService;
}

Expand Down Expand Up @@ -83,14 +94,28 @@ private async ValueTask RunAsyncCore(GenerationTask task, bool firstStep)
task.State = GenerationState.Completed;
task.Progress = 1;
task.MaximumProgress = 1;
var fileName = Path.GetFileName(resultPath);
var resultDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "KoeBook");
if (!Directory.Exists(resultDirectory))
Directory.CreateDirectory(resultDirectory);
File.Move(resultPath, Path.Combine(resultDirectory, fileName), true);

var resultUrl = await _uploadService.UploadFileAsync(resultPath, task.CancellationToken);
aiueo-1234 marked this conversation as resolved.
Show resolved Hide resolved
var qrCodeData = _qrCodeGenerator.CreateQrCode(resultUrl, QRCodeGenerator.ECCLevel.M);
var qrCode = new PngByteQRCode(qrCodeData).GetGraphic(20);
using (var ims = new InMemoryRandomAccessStream())
{
using (var writer = new DataWriter(ims.GetOutputStreamAt(0)))
{
writer.WriteBytes(qrCode);
await writer.StoreAsync().AsTask(task.CancellationToken);
}
task.Qrcode = new BitmapImage();
await task.Qrcode.SetSourceAsync(ims).AsTask(task.CancellationToken);
}

await _dialogService.ShowAsync("title", new Image()
{
Source = task.Qrcode,
}, "OK", null, ContentDialogButton.Primary, task.CancellationToken);
}
else
throw new InvalidOperationException();
throw new UnreachableException();
}
catch (OperationCanceledException)
{
Expand Down
1 change: 1 addition & 0 deletions KoeBook/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public static IHostBuilder UseCoreStartup(this IHostBuilder builder)
.AddSingleton<IScrapingService, ScrapingAozoraService>()
.AddSingleton<IScrapingService, ScrapingNaroService>()
.AddSingleton<AiStoryAnalyzerService>()
.AddSingleton<IS3UploadService, S3UploadService>()
.AddSingleton<IStoryCreatorService, ClaudeStoryGeneratorService>();
services.AddSingleton<IEpubCreateService, EpubCreateService>();
services.AddSingleton<ISplitBraceService, SplitBraceService>();
Expand Down
20 changes: 20 additions & 0 deletions KoeBook/Views/EditDetailsTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,26 @@
Text="編集はできなくなります" />
</StackPanel>

<TextBlock
Visibility="{x:Bind ViewModel.Task.QrcodeVisibility, Mode=OneWay}"
Style="{StaticResource SubtitleTextBlockStyle}"
Margin="{StaticResource MediumTopMargin}"
Text="出力結果" />
<StackPanel
Visibility="{x:Bind ViewModel.Task.QrcodeVisibility, Mode=OneWay}"
Background="{ThemeResource CardBackgroundFillColorDefault}"
BorderBrush="{ThemeResource CardStrokeColorDefault}"
BorderThickness="1"
Padding="12"
Width="280"
CornerRadius="12"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}">
<Image
MaxWidth="256"
Source="{x:Bind ViewModel.Task.Qrcode, Mode=OneWay}"/>
</StackPanel>

<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Margin="{StaticResource MediumTopMargin}"
Expand Down
4 changes: 4 additions & 0 deletions KoeBook/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@
"ISoundGenerationSelectorService": false,
"ISoundGenerationService": false,
"IStoryCreaterService": false
},
"AWS": {
"Profile": "KoeBook",
"Region": "ap-northeast-1"
}
}