Skip to content

Commit e98a6d1

Browse files
authored
Merge pull request #17 from SubZeroPL/iso-handling
Iso handling
2 parents 86d35a7 + 1bd3c24 commit e98a6d1

File tree

11 files changed

+149
-97
lines changed

11 files changed

+149
-97
lines changed

AssM.csproj

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,30 @@
55
<Nullable>enable</Nullable>
66
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
77
<ApplicationManifest>app.manifest</ApplicationManifest>
8-
<Version>1.6.1</Version>
8+
<Version>1.7.0</Version>
99
<Authors>SubZeroPL</Authors>
10-
<PackageProjectUrl>https://github.com/SubZeroPL/AssM/</PackageProjectUrl>
11-
<AssemblyVersion>1.6.1</AssemblyVersion>
12-
<FileVersion>1.6.1</FileVersion>
10+
<PackageProjectUrl>https://github.com/SubZeroPL/AssM</PackageProjectUrl>
11+
<AssemblyVersion>1.7.0</AssemblyVersion>
12+
<FileVersion>1.7.0</FileVersion>
1313
<Title>AssM</Title>
14+
<PackageLicenseUrl>https://github.com/SubZeroPL/AssM/blob/master/LICENSE</PackageLicenseUrl>
15+
<RepositoryUrl>https://github.com/SubZeroPL/AssM/</RepositoryUrl>
16+
<ApplicationIcon>Assets\assm.ico</ApplicationIcon>
1417
</PropertyGroup>
1518

1619
<ItemGroup>
17-
<PackageReference Include="Avalonia" Version="11.3.0" />
18-
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.0" />
19-
<PackageReference Include="Avalonia.Desktop" Version="11.3.0" />
20-
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.0" />
21-
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.0" />
20+
<PackageReference Include="Avalonia" Version="11.3.9" />
21+
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.9" />
22+
<PackageReference Include="Avalonia.Desktop" Version="11.3.9" />
23+
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.9" />
24+
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.9" />
2225
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
23-
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.3.0" />
24-
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />
26+
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.3.9" />
27+
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />
2528
<PackageReference Include="Markdown.Avalonia" Version="11.0.3-a1"/>
26-
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
27-
<PackageReference Include="NLog" Version="5.4.0" />
29+
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
30+
<PackageReference Include="NLog" Version="6.0.6" />
31+
<PackageReference Include="Octokit" Version="14.0.0" />
2832
</ItemGroup>
2933

3034
<ItemGroup>
@@ -40,6 +44,7 @@
4044

4145
<ItemGroup>
4246
<AvaloniaResource Include="Assets\**"/>
47+
<AvaloniaResource Remove="Updater\**" />
4348
</ItemGroup>
4449

4550
<ItemGroup>
@@ -53,25 +58,30 @@
5358
</Compile>
5459
<Compile Remove="Avalonia.Labs\**"/>
5560
<Compile Remove="DiscTools\**"/>
61+
<Compile Remove="Updater\**" />
5662
</ItemGroup>
5763

5864
<ItemGroup>
5965
<AvaloniaXaml Remove="Avalonia.Labs\**"/>
6066
<AvaloniaXaml Remove="DiscTools\**"/>
67+
<AvaloniaXaml Remove="Updater\**" />
6168
</ItemGroup>
6269

6370
<ItemGroup>
6471
<EmbeddedResource Remove="Avalonia.Labs\**"/>
6572
<EmbeddedResource Remove="DiscTools\**"/>
73+
<EmbeddedResource Remove="Updater\**" />
6674
</ItemGroup>
6775

6876
<ItemGroup>
6977
<AdditionalFiles Remove="Avalonia.Labs\**"/>
7078
<AdditionalFiles Remove="DiscTools\**"/>
79+
<AdditionalFiles Remove="Updater\**" />
7180
</ItemGroup>
7281

7382
<ItemGroup>
7483
<None Remove="Avalonia.Labs\**"/>
7584
<None Remove="DiscTools\**"/>
85+
<None Remove="Updater\**" />
7686
</ItemGroup>
7787
</Project>

Assets/assm.ico

1.33 MB
Binary file not shown.

Classes/Constants.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ private static bool IsWindows() =>
2929
[GeneratedRegex(BinFile)]
3030
public static partial Regex BinFileRegex();
3131

32-
private const string BinHash = @"BIN \(TRACK (\d{2})\) MD5\: (.+)";
32+
private const string BinHash = @"TRACK (\d{2}) MD5\: (.+)";
3333
[GeneratedRegex(BinHash)]
3434
public static partial Regex BinHashRegex();
3535
public const string ReadmeGameTitle = "#gameTitle#";
@@ -53,4 +53,12 @@ private static bool IsWindows() =>
5353
"Generating README",
5454
"Process JSON"
5555
];
56+
57+
public static readonly string[] AddFolderSteps =
58+
[
59+
"",
60+
"Aggregating image files (folder {0} of {1})",
61+
"Adding to the list",
62+
"Loading existing data"
63+
];
5664
}

Classes/Functions.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static class Functions
1919

2020
public static string GetChdName(Game game, Configuration configuration) => configuration.GameIdAsChdName
2121
? $"{game.Id.ToUpper()}.chd"
22-
: Path.GetFileName(Path.ChangeExtension(game.CuePath, "chd"));
22+
: Path.GetFileName(Path.ChangeExtension(game.ImagePath, "chd"));
2323

2424
public static void LoadChdManInfo(string chdPath, Game game)
2525
{
@@ -174,7 +174,7 @@ private static void LoadTrackInfoFromReadme(string readmePath, Game game)
174174
}
175175

176176
var endIndex = Array.FindIndex(lines, line => line.Contains("**Description:**")) - 1;
177-
var hashes = lines.Skip(startIndex).Take(endIndex - startIndex).Where(item => item.StartsWith("BIN"));
177+
var hashes = lines.Skip(startIndex).Take(endIndex - startIndex).Where(item => item.StartsWith("TRACK"));
178178
foreach (var hashLine in hashes)
179179
{
180180
var matches = Constants.BinHashRegex().Matches(hashLine);
@@ -199,11 +199,12 @@ private static void LoadTrackInfoFromReadme(string readmePath, Game game)
199199
}
200200
}
201201

202-
public static List<string> GetCueFilesInDirectory(string directory)
202+
public static List<string> GetCueIsoFilesInDirectory(string directory)
203203
{
204-
Logger.Debug($"Getting cue files from {directory}");
205-
var result = Directory.GetFiles(directory).Where(d => Path.GetExtension(d) == ".cue").ToList();
206-
Directory.GetDirectories(directory).ToList().ForEach(d => result.AddRange(GetCueFilesInDirectory(d)));
204+
Logger.Debug($"Getting cue/iso files from {directory}");
205+
var result = Directory.GetFiles(directory)
206+
.Where(d => Path.GetExtension(d) == ".cue" || Path.GetExtension(d) == ".iso").ToList();
207+
Directory.GetDirectories(directory).ToList().ForEach(d => result.AddRange(GetCueIsoFilesInDirectory(d)));
207208
return result;
208209
}
209210

@@ -216,29 +217,30 @@ public static List<string> GetReadmeFilesInDirectory(string directory)
216217
return result;
217218
}
218219

219-
public static Game? AddGameToList(string cuePath, Configuration configuration, ObservableCollection<Game> gameList)
220+
public static Game? AddGameToList(string imagePath, Configuration configuration, ObservableCollection<Game> gameList)
220221
{
221-
Logger.Debug($"Adding game to list from {cuePath}");
222-
var di = DiscInspector.ScanDisc(cuePath);
222+
Logger.Debug($"Adding game to list from {imagePath}");
223+
var di = DiscInspector.ScanDisc(imagePath);
223224
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - apparently there are games that have no Id in image (like SLPS-00018)
224225
if (di.Data.SerialNumber == null)
225226
{
226-
Logger.Error($"Failed to add game to list from {cuePath}{Environment.NewLine}Id not present in image");
227+
Logger.Error($"Failed to add game to list from {imagePath}{Environment.NewLine}Id not present in image");
227228
return null;
228229
}
229-
var title = configuration.GetTitleFromCue ? Path.GetFileNameWithoutExtension(cuePath) : di.Data.GameTitle;
230+
231+
var title = configuration.GetTitleFromCue ? Path.GetFileNameWithoutExtension(imagePath) : di.Data.GameTitle;
230232
var game = new Game
231233
{
232234
Title = title, Id = di.Data.SerialNumber, Platform = di.DetectedDiscType,
233-
CuePath = cuePath
235+
ImagePath = imagePath
234236
};
235237
var existingGame = gameList.FirstOrDefault(g => g.Id == game.Id);
236238
if (existingGame != null)
237239
{
238240
Logger.Debug($"Game already exists: {existingGame.Title}, updating");
239241
existingGame.Title = game.Title;
240242
existingGame.Platform = game.Platform;
241-
existingGame.CuePath = game.CuePath;
243+
existingGame.ImagePath = game.ImagePath;
242244
existingGame.Id = game.Id;
243245
}
244246
else
@@ -273,4 +275,6 @@ public static void ProcessJson(Configuration configuration, Game game, Action<do
273275
Logger.Debug($"Json processing cancelled: {e}");
274276
}
275277
}
278+
279+
public static bool IsIso(Game game) => game.ImagePath.EndsWith(".iso", StringComparison.OrdinalIgnoreCase);
276280
}

Data/Game.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class Game
99
{
1010
public string Title { get; set; } = string.Empty;
1111
public string Id { get; set; } = string.Empty;
12-
public string CuePath { get; set; } = string.Empty;
12+
public string ImagePath { get; set; } = string.Empty;
1313
public DetectedDiscType Platform { get; set; } = DetectedDiscType.UnknownFormat;
1414
public bool ReadmeCreated { get; set; }
1515
public bool ChdCreated { get; set; }
@@ -29,6 +29,6 @@ public class ChdData
2929
public string GetTrackInfo()
3030
{
3131
return string.Join(Environment.NewLine,
32-
TrackInfo.Select(ti => $"BIN (TRACK {ti.TrackNo,2:D2}) MD5: {ti.TrackMD5}{Environment.NewLine}")).Trim();
32+
TrackInfo.Select(ti => $"TRACK {ti.TrackNo,2:D2} MD5: {ti.TrackMD5}{Environment.NewLine}")).Trim();
3333
}
3434
}

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
It is a piece of software that assists in creating entries for [Arkadyzja savestates repository](https://github.com/ActionPL/duckstation_openbios_savestates). It allows creating and editing README files for games that will have savestates uploaded to the repository. Those savestates will then be available for [Arkadyzja](https://arkadyzja.honmaru.pl/).
44

55
## ⚠️ Requirements
6-
For the application to work [.NET framework 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) is required.
6+
For the application to work, [.NET Framework 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) is required.
77

8-
Application is developed and tested on Windows 11 OS. In theory should also work on Linux/Mac hovewer it was not tested on those platforms (only a bit on Linux and not at all on Mac) and currently only Win and Linux builds are released (see below).
8+
Application is developed and tested on Windows 11 OS. It should also work on Linux/Mac hovewer it was not tested (extensively) on those platforms (only a bit on Linux and not at all on Mac) and currently only Win and Linux builds are released (see below).
99

1010
## 📦 Releases
1111
Each release starting with 1.4.0 has four variants:
@@ -23,12 +23,12 @@ Clicking it will open default browser on the latest release page.
2323

2424
## 🪧 Usage
2525
[![Last Release](https://img.shields.io/github/v/release/SubZeroPL/AssM?logo=github&label=latest)](https://github.com/SubZeroPL/AssM/releases)
26-
- get latest version of the application from [Releases](https://github.com/SubZeroPL/AssM/releases) page
26+
- get the latest version of the application from the [Releases](https://github.com/SubZeroPL/AssM/releases) page
2727
- unpack to some empty directory
2828
- run the `AssM.exe` file (or `AssM` for Linux)
2929

3030
![Application main window](.github/assets/app.png "Application main window")
31-
First you should select Output directory, where the created README files will be stored. The files are created in a specific directory structure:
31+
First, you should select the Output directory, where the created README files will be stored. The files are created in a specific directory structure:
3232
`OutputPath\Platform\GameID`.\
3333
The output directory is saved between sessions, so when you start the application next time it will be automatically read and existing entries inserted into the table.\
3434
**You should not modify existing directory structure if you plan to use the output directory again later!**
@@ -40,8 +40,8 @@ When you click `Start processing` the application will go through the list and p
4040

4141
## ⚙️ Configuration
4242
![Configuration options](.github/assets/config.png "Configuration options")
43-
- Get game title from CUE file name - by default game name is extracted from cue/bin image, this option uses CUE file name instead
44-
- Use Game ID as name for CHD file - by default game title (as set by previous option) is used for CHD file name, this option uses Game ID instead
43+
- Get game title from CUE file name - by default, game name is extracted from cue/bin image; this option uses CUE file name instead
44+
- Use Game ID as the name for CHD file by default, game title (as set by a previous option) is used for CHD file name; this option uses Game ID instead
4545

4646
Other configuration options should be self-explanatory.
4747

Windows/AddFolderProgressWindow.axaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:gif="clr-namespace:Avalonia.Labs.Gif;assembly=Avalonia.Labs.Gif"
6-
mc:Ignorable="d" d:DesignWidth="300"
6+
mc:Ignorable="d" d:DesignWidth="400"
77
x:Class="AssM.Windows.AddFolderProgressWindow"
88
Closing="Window_OnClosing"
9-
Width="300" WindowStartupLocation="CenterOwner" SizeToContent="Height" ShowInTaskbar="False" CanResize="False"
9+
Width="400" WindowStartupLocation="CenterOwner" SizeToContent="Height" ShowInTaskbar="False" CanResize="False"
1010
Title="Adding folder contents">
1111
<StackPanel>
1212
<StackPanel Orientation="Horizontal">
13-
<Label>Processing folder:</Label>
14-
<Label Name="LabelFolderName"></Label>
13+
<Label Name="LabelStep">Processing folder (0 of 0):</Label>
1514
</StackPanel>
15+
<Label Name="LabelFolderName">folder name</Label>
1616
<Panel HorizontalAlignment="Center">
1717
<gif:GifImage Source="avares://AssM/Assets/loading.gif" />
1818
</Panel>

Windows/AddFolderProgressWindow.axaml.cs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99

1010
namespace AssM.Windows;
1111

12+
internal class AddFolderProgressUpdateObject
13+
{
14+
public string? Dir { get; init; }
15+
public int? Count { get; init; }
16+
public int? Index { get; init; }
17+
public int Step { get; init; }
18+
}
19+
1220
public partial class AddFolderProgressWindow : Window
1321
{
1422
private readonly BackgroundWorker _worker;
@@ -24,43 +32,64 @@ public AddFolderProgressWindow()
2432

2533
private void WorkerOnProgressChanged(object? sender, ProgressChangedEventArgs e)
2634
{
27-
if (e.UserState is string dir)
28-
LabelFolderName.Content = dir;
35+
if (e.UserState is not AddFolderProgressUpdateObject updateObject) return;
36+
LabelStep.Content = Constants.AddFolderSteps[updateObject.Step];
37+
if (updateObject.Step == 1)
38+
{
39+
LabelStep.Content = string.Format(Constants.AddFolderSteps[updateObject.Step], updateObject.Index,
40+
updateObject.Count);
41+
LabelFolderName.Content = updateObject.Dir;
42+
}
2943
}
3044

31-
public void Process(List<string> dirs, ObservableCollection<Game> gameList, Configuration configuration, Action<List<string>> finishedCallback)
45+
public void Process(List<string> dirs, ObservableCollection<Game> gameList, Configuration configuration,
46+
Action<List<string>> finishedCallback)
3247
{
3348
var cueFiles = new List<string>();
3449
var errors = new List<string>();
3550
_worker.DoWork += (_, _) =>
3651
{
52+
var index = 0;
3753
foreach (var dir in dirs)
3854
{
3955
if (_worker.CancellationPending) return;
40-
_worker.ReportProgress(0, dir);
41-
cueFiles.AddRange(Functions.GetCueFilesInDirectory(dir));
56+
var progress = index / dirs.Count * 100;
57+
_worker.ReportProgress(progress,
58+
new AddFolderProgressUpdateObject { Dir = dir, Index = index++, Count = dirs.Count, Step = 1 });
59+
cueFiles.AddRange(Functions.GetCueIsoFilesInDirectory(dir));
4260
}
4361

62+
index = 0;
4463
foreach (var cueFile in cueFiles)
4564
{
4665
if (_worker.CancellationPending) return;
66+
var progress = index / cueFiles.Count * 100;
67+
_worker.ReportProgress(progress,
68+
new AddFolderProgressUpdateObject
69+
{ Dir = cueFile, Index = index++, Count = cueFiles.Count, Step = 2 });
4770
var game = Functions.AddGameToList(cueFile, configuration, gameList);
4871
if (game == null)
4972
{
50-
errors.Add($"Failed to add game to list from {cueFile}{Environment.NewLine}Id not present in image");
73+
errors.Add(
74+
$"Failed to add game to list from {cueFile}{Environment.NewLine}Id not present in image");
5175
}
5276
}
5377

78+
index = 0;
5479
if (string.IsNullOrWhiteSpace(configuration.OutputDirectory)) return;
5580
foreach (var game in gameList)
5681
{
5782
if (_worker.CancellationPending) return;
83+
var progress = index / gameList.Count * 100;
84+
_worker.ReportProgress(progress,
85+
new AddFolderProgressUpdateObject
86+
{ Dir = game.Title, Index = index++, Count = gameList.Count, Step = 3 });
5887
Functions.LoadExistingData(game, configuration);
5988
}
6089
};
61-
90+
6291
_worker.RunWorkerCompleted += (_, _) => finishedCallback.Invoke(errors);
63-
92+
6493
_worker.RunWorkerAsync();
6594
}
6695

Windows/MainWindow.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
</MenuItem>
4040
<CheckBox Name="CheckBoxProcessModified" IsThreeState="False" Click="CheckBox_OnClick">Process only modified enties</CheckBox>
4141
<CheckBox Name="CheckBoxOverwriteReadme" IsThreeState="False" Click="CheckBox_OnClick">Overwrite existing READMEs</CheckBox>
42-
<CheckBox Name="CheckBoxGetTitleFromCue" IsThreeState="False" Click="CheckBox_OnClick">Get game title from CUE file name</CheckBox>
42+
<CheckBox Name="CheckBoxGetTitleFromCue" IsThreeState="False" Click="CheckBox_OnClick">Get game title from file name</CheckBox>
4343
<CheckBox Name="CheckBoxGameIdAsChdName" IsThreeState="False" Click="CheckBox_OnClick">Use Game ID as name for CHD file</CheckBox>
4444
</MenuFlyout>
4545
</Button.Flyout>

0 commit comments

Comments
 (0)