-
Notifications
You must be signed in to change notification settings - Fork 288
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1047 from oxygen-dioxide/publish
Add a singer publish tool to pack a singer into a zip file
- Loading branch information
Showing
10 changed files
with
236 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using Ignore; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.IO.Compression; | ||
using System.Linq; | ||
|
||
using OpenUtau.Core.Ustx; | ||
|
||
namespace OpenUtau.Classic { | ||
public class VoicebankPublisher { | ||
private readonly Action<double, string> progress; | ||
private readonly Ignore.Ignore? ignore; | ||
|
||
public VoicebankPublisher(Action<double, string> progress, string? gitIgnore) { | ||
this.progress = progress; | ||
if(gitIgnore != null) { | ||
ignore = new Ignore.Ignore(); | ||
ignore.Add(gitIgnore.Split("\n")); | ||
} | ||
} | ||
|
||
private static void ModifyConfig(USinger singer, Action<VoicebankConfig> modify) { | ||
var yamlFile = Path.Combine(singer.Location, "character.yaml"); | ||
VoicebankConfig? config = null; | ||
if (File.Exists(yamlFile)) { | ||
using (var stream = File.OpenRead(yamlFile)) { | ||
config = VoicebankConfig.Load(stream); | ||
} | ||
} | ||
if (config == null) { | ||
config = new VoicebankConfig(); | ||
} | ||
modify(config); | ||
using (var stream = File.Open(yamlFile, FileMode.Create)) { | ||
config.Save(stream); | ||
} | ||
} | ||
|
||
private bool IsIgnored(string relativePath){ | ||
return ignore?.IsIgnored(relativePath.Replace('\\', '/')) ?? false; | ||
} | ||
|
||
private List<string> GetFilesToPack(string singerPath) | ||
{ | ||
List<string> fileList = Directory.EnumerateFiles(singerPath, "*.*", SearchOption.AllDirectories).ToList(); | ||
List<string> packList = fileList.FindAll(x => !IsIgnored(System.IO.Path.GetRelativePath(singerPath, x))); | ||
return packList; | ||
} | ||
|
||
///<summary> | ||
///Compress a voicebank into an optimized zip archive for distribution. | ||
///This function only supports voicebanks that follow the classic packaging model, | ||
///including utau, enunu and diffsinger. | ||
///Vogen voicebanks aren't supported. | ||
///</summary> | ||
public void Publish(USinger singer, string outputFile){ | ||
var location = singer.Location; | ||
if(!Directory.Exists(location)){ | ||
return; | ||
} | ||
progress.Invoke(0, $"Publishing {singer.Name}"); | ||
//Write singer type into character.yaml | ||
try { | ||
ModifyConfig(singer, config => config.SingerType = singer.SingerType.ToString().ToLower()); | ||
} catch (Exception e) { } | ||
var packList = GetFilesToPack(location); | ||
int index = 0; | ||
int fileCount = packList.Count(); | ||
using(ZipArchive archive = new ZipArchive(File.Create(outputFile), ZipArchiveMode.Create)) | ||
{ | ||
foreach (var absFilePath in packList) | ||
{ | ||
index++; | ||
progress.Invoke(100.0 * index / fileCount, $"Compressing {absFilePath}"); | ||
string reFilePath = Path.GetRelativePath(location, absFilePath); | ||
archive.CreateEntryFromFile(absFilePath, reFilePath); | ||
} | ||
} | ||
progress.Invoke(0, $"Published {singer.Name} to {outputFile}"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using OpenUtau.Classic; | ||
using OpenUtau.Core; | ||
using OpenUtau.Core.Util; | ||
using OpenUtau.Core.Ustx; | ||
using ReactiveUI.Fody.Helpers; | ||
|
||
namespace OpenUtau.App.ViewModels { | ||
public class SingerPublishViewModel : ViewModelBase { | ||
public USinger singer; | ||
[Reactive] public bool UseIgnore { get; set; } | ||
[Reactive] public string IgnoreTypes { get; set; } | ||
|
||
public SingerPublishViewModel(USinger singer) { | ||
this.singer = singer; | ||
UseIgnore = Preferences.Default.VoicebankPublishUseIgnore; | ||
IgnoreTypes = Preferences.Default.VoicebankPublishIgnores; | ||
} | ||
|
||
public Task Publish(string outputFile){ | ||
return Task.Run(() => { | ||
try { | ||
Preferences.Default.VoicebankPublishUseIgnore = UseIgnore; | ||
if(UseIgnore){ | ||
Preferences.Default.VoicebankPublishIgnores = IgnoreTypes; | ||
} | ||
Preferences.Save(); | ||
if(Directory.Exists(singer.Location)){ | ||
var publisher = new VoicebankPublisher((progress, info) => { | ||
DocManager.Inst.ExecuteCmd(new ProgressBarNotification(progress, info)); | ||
}, UseIgnore ? IgnoreTypes : null); | ||
publisher.Publish(singer, outputFile); | ||
} | ||
else if(File.Exists(singer.Location)){ | ||
File.Copy(singer.Location, outputFile); | ||
} | ||
} finally { | ||
new Task(() => { | ||
DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, "")); | ||
}).Start(DocManager.Inst.MainScheduler); | ||
} | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<Window xmlns="https://github.com/avaloniaui" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:vm="using:OpenUtau.App.ViewModels" | ||
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="600" | ||
x:Class="OpenUtau.App.Views.SingerPublishDialog" | ||
Icon="/Assets/open-utau.ico" | ||
WindowStartupLocation="CenterScreen" | ||
MinWidth="500" MinHeight="500" Width="500" Height="500" | ||
ExtendClientAreaToDecorationsHint="False" | ||
Title="{DynamicResource singers.publish}"> | ||
<Grid Margin="{Binding $parent.WindowDecorationMargin}"> | ||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Visible"> | ||
<StackPanel Margin="5"> | ||
<TextBlock Text="{DynamicResource singers.publish.description}"/> | ||
<Grid ColumnDefinitions="Auto,Auto" RowDefinitions="25" VerticalAlignment="Center" Margin="4"> | ||
<CheckBox IsChecked="{Binding UseIgnore}" VerticalAlignment="Center" Content="Use file type ignoring"/> | ||
<TextBlock Text="{DynamicResource singers.publish.useignore}" Grid.Column="1" VerticalAlignment="Center"/> | ||
</Grid> | ||
<TextBlock Text="{DynamicResource singers.publish.ignoretypes}"/> | ||
<TextBox Text="{Binding IgnoreTypes}" Height="300" VerticalAlignment="Center" IsEnabled="{Binding UseIgnore}" AcceptsReturn="True"/> | ||
<Button Content="{DynamicResource singers.publish.publish}" Click="PublishClicked" VerticalAlignment="Center" Margin="0,10,0,0"/> | ||
</StackPanel> | ||
</ScrollViewer> | ||
</Grid> | ||
</Window> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using System.IO; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Avalonia.Controls; | ||
using Avalonia.Interactivity; | ||
using Avalonia.Platform.Storage; | ||
using Serilog; | ||
using OpenUtau.App.ViewModels; | ||
|
||
namespace OpenUtau.App.Views { | ||
public partial class SingerPublishDialog : Window { | ||
public SingerPublishDialog() { | ||
InitializeComponent(); | ||
} | ||
|
||
async void PublishClicked(object sender, RoutedEventArgs arg){ | ||
var viewModel = DataContext as SingerPublishViewModel; | ||
if (viewModel == null) { | ||
return; | ||
} | ||
var singer = viewModel.singer; | ||
if(singer == null){ | ||
return; | ||
} | ||
var types = FilePicker.ZIP; | ||
if(File.Exists(singer.Location)){ | ||
var suffix = Path.GetExtension(singer.Location); | ||
types = new FilePickerFileType(suffix.ToUpper()) { | ||
Patterns = new[] { "*" + suffix }, | ||
}; | ||
} | ||
var outputFile = await FilePicker.SaveFile( | ||
this, "singers.publish", types); | ||
if (outputFile == null) { | ||
return; | ||
} | ||
Publish(outputFile); | ||
} | ||
|
||
void Publish(string outputFile){ | ||
var viewModel = DataContext as SingerPublishViewModel; | ||
if (viewModel == null) { | ||
return; | ||
} | ||
var scheduler = TaskScheduler.FromCurrentSynchronizationContext(); | ||
viewModel.Publish(outputFile).ContinueWith((task) => { | ||
if (task.IsFaulted) { | ||
Log.Error(task.Exception, "Failed to publish singer"); | ||
if (Parent is Window window) { | ||
MessageBox.ShowError(window, task.Exception); | ||
} | ||
} | ||
}, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler); | ||
Close(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters