Skip to content

Commit c6e1318

Browse files
Update dependency installer to upgrade companion app
1 parent f2a3d3c commit c6e1318

File tree

6 files changed

+109
-54
lines changed

6 files changed

+109
-54
lines changed

MSUScripter/Configs/MsuSongMsuPcmInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public List<string> GetFiles()
9999
return files;
100100
}
101101

102-
[YamlIgnore]
102+
[YamlIgnore, JsonSchemaIgnore]
103103
public bool HasBothSubTracksAndSubChannels
104104
{
105105
get
@@ -110,7 +110,7 @@ public bool HasBothSubTracksAndSubChannels
110110
}
111111
}
112112

113-
[YamlIgnore]
113+
[YamlIgnore, JsonSchemaIgnore]
114114
public bool HasValidSubChannelCount
115115
{
116116
get
@@ -120,7 +120,7 @@ public bool HasValidSubChannelCount
120120
}
121121
}
122122

123-
[YamlIgnore]
123+
[YamlIgnore, JsonSchemaIgnore]
124124
public bool HasValidChildTypes
125125
{
126126
get

MSUScripter/Services/DependencyInstallerService.cs

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,63 +32,73 @@ public async Task<bool> InstallPyApp(Action<string> response, Func<string, strin
3232
{
3333
response.Invoke("Setting up directories");
3434
var destination = Path.Combine(Directories.Dependencies, "python");
35+
36+
var pythonPath = OperatingSystem.IsWindows()
37+
? Path.Combine(destination, "python.exe")
38+
: Path.Combine(destination, "bin", "python3.13");
39+
var doesHavePython = false;
3540

36-
if (Directory.Exists(destination))
41+
if (File.Exists(pythonPath))
3742
{
38-
logger.LogInformation("Deleting prior Python installation");
39-
try
43+
var checkPyVersionResult = await runPyFunc(pythonPath, "--version");
44+
doesHavePython = checkPyVersionResult.Success && checkPyVersionResult.Result.StartsWith("Python 3.13");
45+
}
46+
47+
if (!doesHavePython)
48+
{
49+
if (Directory.Exists(destination))
4050
{
41-
await ITaskService.Run(() =>
51+
logger.LogInformation("Deleting prior Python installation");
52+
try
4253
{
43-
Directory.Delete(destination, true);
44-
});
45-
}
46-
catch (TaskCanceledException)
47-
{
48-
// Do Nothing
54+
await ITaskService.Run(() =>
55+
{
56+
Directory.Delete(destination, true);
57+
});
58+
}
59+
catch (TaskCanceledException)
60+
{
61+
// Do Nothing
62+
}
4963
}
50-
}
51-
52-
EnsureFolders(destination);
5364

54-
var tempFile = Path.Combine(Directories.TempFolder, "python.tar.gz");
55-
var url = OperatingSystem.IsWindows() ? PythonWindowsDownloadUrl : PythonLinuxDownloadUrl;
65+
EnsureFolders(destination);
5666

57-
response.Invoke("Downloading Python");
58-
if (!await DownloadFileAsync(url, tempFile))
59-
{
60-
return false;
61-
}
67+
var tempFile = Path.Combine(Directories.TempFolder, "python.tar.gz");
68+
var url = OperatingSystem.IsWindows() ? PythonWindowsDownloadUrl : PythonLinuxDownloadUrl;
6269

63-
response.Invoke("Extracting Python files");
64-
if (!await ExtractTarGzFile(tempFile, Directories.Dependencies))
65-
{
66-
return false;
67-
}
70+
response.Invoke("Downloading Python");
71+
if (!await DownloadFileAsync(url, tempFile))
72+
{
73+
return false;
74+
}
6875

69-
var pythonPath = OperatingSystem.IsWindows()
70-
? Path.Combine(destination, "python.exe")
71-
: Path.Combine(destination, "bin", "python3.13");
76+
response.Invoke("Extracting Python files");
77+
if (!await ExtractTarGzFile(tempFile, Directories.Dependencies))
78+
{
79+
return false;
80+
}
7281

73-
if (OperatingSystem.IsLinux())
74-
{
75-
File.SetUnixFileMode(pythonPath,
76-
UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
77-
}
82+
if (OperatingSystem.IsLinux())
83+
{
84+
File.SetUnixFileMode(pythonPath,
85+
UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
86+
}
7887

79-
response.Invoke("Verifying Python version");
88+
response.Invoke("Verifying Python version");
8089

81-
var runPyResult = await runPyFunc(pythonPath, "--version");
82-
if (!runPyResult.Success || !runPyResult.Result.StartsWith("Python 3"))
83-
{
84-
logger.LogError("Python version response incorrect: {Response} | {Error}", runPyResult.Result,
85-
runPyResult.Error);
86-
return false;
90+
var verifyPythonInstallResult = await runPyFunc(pythonPath, "--version");
91+
if (!verifyPythonInstallResult.Success || !verifyPythonInstallResult.Result.StartsWith("Python 3.13"))
92+
{
93+
logger.LogError("Python version response incorrect: {Response} | {Error}", verifyPythonInstallResult.Result,
94+
verifyPythonInstallResult.Error);
95+
return false;
96+
}
8797
}
88-
98+
8999
response.Invoke("Installing companion app");
90100

91-
runPyResult = await runPyFunc(pythonPath, "-m pip install py-msu-scripter-app");
101+
var runPyResult = await runPyFunc(pythonPath, "-m pip install --upgrade py-msu-scripter-app");
92102
if (!runPyResult.Success && !runPyResult.Error.StartsWith("[notice]"))
93103
{
94104
logger.LogError("Failed to install Python companion app: {Error}", runPyResult.Error);

MSUScripter/Services/PythonCompanionService.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
using AvaloniaControls.Services;
99
using Microsoft.Extensions.Logging;
1010
using MSUScripter.Models;
11+
using MSUScripter.Tools;
1112

1213
namespace MSUScripter.Services;
1314

1415
public class PythonCompanionService(ILogger<PythonCompanionService> logger, YamlService yamlService, DependencyInstallerService dependencyInstallerService)
1516
{
1617
private const string BaseCommand = "py_msu_scripter_app";
17-
private const string MinVersion = "v0.1.5";
18+
private const string MinVersion = "v0.1.6";
1819
private RunMethod _runMethod = RunMethod.Unknown;
1920
private string? _pythonExecutablePath;
2021
private string? _ffmpegPath;
@@ -34,7 +35,7 @@ public async Task<bool> VerifyInstalledAsync()
3435
_pythonExecutablePath = null;
3536
var response = await RunCommandAsync("--version");
3637

37-
IsValid = response.Success && response.Result.EndsWith(MinVersion) &&
38+
IsValid = response.Success && VerifyVersionNumber(response.Result) &&
3839
!response.Error.Contains("Couldn't find ffmpeg");
3940

4041
if (IsValid)
@@ -49,6 +50,13 @@ public async Task<bool> VerifyInstalledAsync()
4950
return IsValid;
5051
}
5152

53+
private bool VerifyVersionNumber(string versionString)
54+
{
55+
var minVersion = MinVersion.VersionStringToDecimal();
56+
var currentVersion = versionString.Substring(versionString.IndexOf('v')).VersionStringToDecimal();
57+
return currentVersion >= minVersion;
58+
}
59+
5260
public async Task<bool> VerifyFfMpegAsync()
5361
{
5462
var ffmpegFolder = Path.Combine(Directories.Dependencies, "ffmpeg", "bin");
@@ -603,7 +611,7 @@ private async Task<RunPyResult> RunInternalAsync(string command, string argument
603611
await process.WaitForExitAsync(cancellationToken ?? CancellationToken.None);
604612

605613
var resultText = "";
606-
var errorText = "";
614+
string errorText;
607615

608616
if (isPipInstall)
609617
{

MSUScripter/Tools/StringExtensions.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,33 @@ public static int GetUnicodeLength(this string str)
1414
{
1515
return new StringInfo(str.CleanString()).LengthInTextElements;
1616
}
17+
18+
public static decimal? VersionStringToDecimal(this string str)
19+
{
20+
if (!str.Contains('.'))
21+
{
22+
return null;
23+
}
24+
25+
if (str.StartsWith('v'))
26+
{
27+
str = str[1..];
28+
}
29+
30+
var parts = str.Split('.');
31+
if (parts.Length <= 2)
32+
{
33+
return decimal.Parse(str);
34+
}
35+
else if (parts.Length == 3)
36+
{
37+
return decimal.Parse(parts[0]) * 1000 + decimal.Parse(parts[1]) + decimal.Parse(parts[2]) / 1000;
38+
}
39+
else if (parts.Length == 4)
40+
{
41+
return decimal.Parse(parts[0]) * 1000000 + decimal.Parse(parts[1]) * 1000 + decimal.Parse(parts[2]) + decimal.Parse(parts[3]) / 1000;
42+
}
43+
44+
return null;
45+
}
1746
}

Schemas/MsuSongInfo.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@
156156
],
157157
"description": "The file to be used as the input for this track/sub-track/sub-channel"
158158
},
159+
"Dither": {
160+
"type": [
161+
"boolean",
162+
"null"
163+
],
164+
"description": "Whether or not to apply audio dither to the final output."
165+
},
159166
"SubTracks": {
160167
"type": "array",
161168
"description": "Files which will be concatenated together to form the input to the parent track",
@@ -169,9 +176,6 @@
169176
"items": {
170177
"$ref": "#/definitions/MsuSongMsuPcmInfo"
171178
}
172-
},
173-
"HasBothSubTracksAndSubChannels": {
174-
"type": "boolean"
175179
}
176180
}
177181
}

Schemas/MsuSongMsuPcmInfo.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@
9999
],
100100
"description": "The file to be used as the input for this track/sub-track/sub-channel"
101101
},
102+
"Dither": {
103+
"type": [
104+
"boolean",
105+
"null"
106+
],
107+
"description": "Whether or not to apply audio dither to the final output."
108+
},
102109
"SubTracks": {
103110
"type": "array",
104111
"description": "Files which will be concatenated together to form the input to the parent track",
@@ -112,9 +119,6 @@
112119
"items": {
113120
"$ref": "#"
114121
}
115-
},
116-
"HasBothSubTracksAndSubChannels": {
117-
"type": "boolean"
118122
}
119123
}
120124
}

0 commit comments

Comments
 (0)