diff --git a/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj b/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj
index 342f1e9f..1611da6b 100644
--- a/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj
+++ b/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj
@@ -41,23 +41,11 @@
PreserveNewest
PreserveNewest
-
- PreserveNewest
-
true
PreserveNewest
PreserveNewest
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
diff --git a/AudioCuesheetEditor.End2EndTests/Pages/IndexTest.cs b/AudioCuesheetEditor.End2EndTests/Pages/IndexTest.cs
index 4e1a39be..dd2b7265 100644
--- a/AudioCuesheetEditor.End2EndTests/Pages/IndexTest.cs
+++ b/AudioCuesheetEditor.End2EndTests/Pages/IndexTest.cs
@@ -153,74 +153,5 @@ public async Task RenameAudiofileTestAsync()
await Page.GetByRole(AriaRole.Button, new() { Name = "Ok" }).ClickAsync();
await Expect(Page.Locator("#app")).ToMatchAriaSnapshotAsync("- textbox \"Cuesheet artist\"\n- group \"Cuesheet artist\"\n- text: Cuesheet artist\n- textbox \"Cuesheet title\"\n- group \"Cuesheet title\"\n- text: Cuesheet title\n- group:\n - button \"Choose File\"\n - textbox \"Audiofile\": /Kalimba test \\d+\\.mp3/\n - group \"Audiofile\"\n - text: Audiofile\n - button \"Search\"\n - button\n - button\n- group:\n - button \"Choose File\"\n - textbox \"CD Textfile\": No file selected\n - group \"CD Textfile\"\n - text: CD Textfile\n - button \"Search\"\n - button [disabled]\n - button\n- textbox \"Cataloguenumber\"\n- group \"Cataloguenumber\"\n- text: Cataloguenumber");
}
-
- [TestMethod]
- public async Task ImportUndoRedoTestAsync()
- {
- await Page.GotoAsync("http://localhost:5132/");
- await Page.GetByText("Import view").ClickAsync();
- await Page.GetByRole(AriaRole.Button, new() { Name = "Choose File" }).ClickAsync();
- await Page.GetByRole(AriaRole.Button, new() { Name = "Choose File" }).SetInputFilesAsync(new[] { "Textimport with Cuesheetdata.txt" });
- await Page.GetByRole(AriaRole.Textbox, new() { Name = "Scheme common data" }).FillAsync("Artist - Title - ");
- await Page.GetByRole(AriaRole.Group).Filter(new() { HasText = "Scheme common dataScheme" }).GetByRole(AriaRole.Button).Nth(1).ClickAsync();
- await Page.GetByRole(AriaRole.Paragraph).Filter(new() { HasText = "Cataloguenumber" }).ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Toolbar)).ToMatchAriaSnapshotAsync("- button \"undo\" [disabled]");
- await Expect(Page.GetByRole(AriaRole.Toolbar)).ToMatchAriaSnapshotAsync("- button \"redo\" [disabled]");
- await Page.GetByRole(AriaRole.Button, new() { Name = "Complete" }).ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Button, new() { Name = "undo" })).ToMatchAriaSnapshotAsync("- button \"undo\"");
- await Expect(Page.GetByRole(AriaRole.Toolbar)).ToMatchAriaSnapshotAsync("- button \"redo\" [disabled]");
- await Page.GetByRole(AriaRole.Button, new() { Name = "undo" }).ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Toolbar)).ToMatchAriaSnapshotAsync("- button \"undo\" [disabled]");
- await Expect(Page.GetByRole(AriaRole.Button, new() { Name = "redo" })).ToMatchAriaSnapshotAsync("- button \"redo\"");
- await Page.GetByRole(AriaRole.Button, new() { Name = "redo" }).ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Textbox, new() { Name = "Cuesheet artist" })).ToHaveValueAsync("DJFreezeT");
- await Expect(Page.GetByRole(AriaRole.Textbox, new() { Name = "Cuesheet title" })).ToHaveValueAsync("Rabbit Hole Mix");
- await Expect(Page.GetByRole(AriaRole.Textbox, new() { Name = "Cataloguenumber" })).ToHaveValueAsync("0123456789123");
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Einmusik Clear" })).ToBeVisibleAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Missing Path (Original Mix)" })).ToBeVisibleAsync();
- }
-
- [TestMethod]
- public async Task ImportTestBug54Async()
- {
- await Page.GotoAsync("http://localhost:5132/");
- await Page.GetByText("Import view").ClickAsync();
- await Page.GetByRole(AriaRole.Button, new() { Name = "Choose File" }).ClickAsync();
- await Page.GetByRole(AriaRole.Button, new() { Name = "Choose File" }).SetInputFilesAsync(new[] { "Textimport-Bug-#54.txt" });
- await Page.GetByText("Textfile (common data in").ClickAsync();
- await Page.GetByText("Textfile (just track data)").ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Tabpanel)).ToMatchAriaSnapshotAsync("- table:\n - rowgroup:\n - row \"# Sort Show Column Options Artist Sort Show Column Options Title Sort Show Column Options Begin Sort Show Column Options End Sort Show Column Options Length Sort Show Column Options\":\n - columnheader:\n - checkbox\n - columnheader \"# Sort Show Column Options\":\n - button \"Sort\"\n - button \"Show Column Options\"\n - columnheader \"Artist Sort Show Column Options\":\n - button \"Sort\"\n - button \"Show Column Options\"\n - columnheader \"Title Sort Show Column Options\":\n - button \"Sort\"\n - button \"Show Column Options\"\n - columnheader \"Begin Sort Show Column Options\":\n - button \"Sort\"\n - button \"Show Column Options\"\n - columnheader \"End Sort Show Column Options\":\n - button \"Sort\"\n - button \"Show Column Options\"\n - columnheader \"Length Sort Show Column Options\":\n - button \"Sort\"\n - button \"Show Column Options\"\n - rowgroup:\n - row /Increment Decrement Adriatique Clear X\\. Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"1\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Adriatique Clear\":\n - textbox: Adriatique\n - button \"Clear\"\n - button\n - cell \"X. Clear\":\n - textbox: X.\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Third Harmony Clear Fears And Dreams \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"2\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Third Harmony Clear\":\n - textbox: Third Harmony\n - button \"Clear\"\n - button\n - cell \"Fears And Dreams (Original Mix) Clear\":\n - textbox: Fears And Dreams (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Dele Sosimi Afrobeat Orchestra Clear Too Much Information \\(Laolu Remix; Edit\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"3\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Dele Sosimi Afrobeat Orchestra Clear\":\n - textbox: Dele Sosimi Afrobeat Orchestra\n - button \"Clear\"\n - button\n - cell \"Too Much Information (Laolu Remix; Edit) Clear\":\n - textbox: Too Much Information (Laolu Remix; Edit)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Edem, Govan Clear Ankh \\(Onetwo MX Remix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"4\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Edem, Govan Clear\":\n - textbox: Edem, Govan\n - button \"Clear\"\n - button\n - cell \"Ankh (Onetwo MX Remix) Clear\":\n - textbox: Ankh (Onetwo MX Remix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Jody Wisternoff Clear For All Time \\(feat\\. Hendrik Burkhard\\) \\(Extended Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"5\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Jody Wisternoff Clear\":\n - textbox: Jody Wisternoff\n - button \"Clear\"\n - button\n - cell \"For All Time (feat. Hendrik Burkhard) (Extended Mix) Clear\":\n - textbox: For All Time (feat. Hendrik Burkhard) (Extended Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Einmusik Clear Bead \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"6\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Einmusik Clear\":\n - textbox: Einmusik\n - button \"Clear\"\n - button\n - cell \"Bead (Original Mix) Clear\":\n - textbox: Bead (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Sebastien Leger Clear La Danse du Scorpion Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"7\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Sebastien Leger Clear\":\n - textbox: Sebastien Leger\n - button \"Clear\"\n - button\n - cell \"La Danse du Scorpion Clear\":\n - textbox: La Danse du Scorpion\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Paul Thomas & Solid Stone Clear La Bombo \\(Solid Stone Remix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"8\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Paul Thomas & Solid Stone Clear\":\n - textbox: Paul Thomas & Solid Stone\n - button \"Clear\"\n - button\n - cell \"La Bombo (Solid Stone Remix) Clear\":\n - textbox: La Bombo (Solid Stone Remix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement GusGus Clear Crossfade \\(Maceo Plex Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: \"9\"\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"GusGus Clear\":\n - textbox: GusGus\n - button \"Clear\"\n - button\n - cell \"Crossfade (Maceo Plex Mix) Clear\":\n - textbox: Crossfade (Maceo Plex Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Klangkarussell Clear Time \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Klangkarussell Clear\":\n - textbox: Klangkarussell\n - button \"Clear\"\n - button\n - cell \"Time (Original Mix) Clear\":\n - textbox: Time (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Anysense & Un:said Clear Missing Path \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Anysense & Un:said Clear\":\n - textbox: Anysense & Un:said\n - button \"Clear\"\n - button\n - cell \"Missing Path (Original Mix) Clear\":\n - textbox: Missing Path (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Space Food Clear Bombay Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Space Food Clear\":\n - textbox: Space Food\n - button \"Clear\"\n - button\n - cell \"Bombay Clear\":\n - textbox: Bombay\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement SHDW & Obscure Shape Clear Wächter der Nacht \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"SHDW & Obscure Shape Clear\":\n - textbox: SHDW & Obscure Shape\n - button \"Clear\"\n - button\n - cell \"Wächter der Nacht (Original Mix) Clear\":\n - textbox: Wächter der Nacht (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement HOSH Clear Karma Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"HOSH Clear\":\n - textbox: HOSH\n - button \"Clear\"\n - button\n - cell \"Karma Clear\":\n - textbox: Karma\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Alexey Union Clear Olympia \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Alexey Union Clear\":\n - textbox: Alexey Union\n - button \"Clear\"\n - button\n - cell \"Olympia (Original Mix) Clear\":\n - textbox: Olympia (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Paul Taylor Clear Afterglow Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Paul Taylor Clear\":\n - textbox: Paul Taylor\n - button \"Clear\"\n - button\n - cell \"Afterglow Clear\":\n - textbox: Afterglow\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Philter Clear Stranger Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Philter Clear\":\n - textbox: Philter\n - button \"Clear\"\n - button\n - cell \"Stranger Clear\":\n - textbox: Stranger\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Skizologic Clear Hypersphere \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Skizologic Clear\":\n - textbox: Skizologic\n - button \"Clear\"\n - button\n - cell \"Hypersphere (Original Mix) Clear\":\n - textbox: Hypersphere (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Thomas Schumacher, Caitlin Clear All of You \\(Remix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Thomas Schumacher, Caitlin Clear\":\n - textbox: Thomas Schumacher, Caitlin\n - button \"Clear\"\n - button\n - cell \"All of You (Remix) Clear\":\n - textbox: All of You (Remix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement A\\. Skomoroh Clear White Horse Conquest \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"A. Skomoroh Clear\":\n - textbox: A. Skomoroh\n - button \"Clear\"\n - button\n - cell \"White Horse Conquest (Original Mix) Clear\":\n - textbox: White Horse Conquest (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Patrik Berg Clear Bright \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Patrik Berg Clear\":\n - textbox: Patrik Berg\n - button \"Clear\"\n - button\n - cell \"Bright (Original Mix) Clear\":\n - textbox: Bright (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Hidden Empire Clear Bengal Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Hidden Empire Clear\":\n - textbox: Hidden Empire\n - button \"Clear\"\n - button\n - cell \"Bengal Clear\":\n - textbox: Bengal\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Mario Ochoa Clear Levitate Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Mario Ochoa Clear\":\n - textbox: Mario Ochoa\n - button \"Clear\"\n - button\n - cell \"Levitate Clear\":\n - textbox: Levitate\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Raul Facio Clear Eyes Wide Shut \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Raul Facio Clear\":\n - textbox: Raul Facio\n - button \"Clear\"\n - button\n - cell \"Eyes Wide Shut (Original Mix) Clear\":\n - textbox: Eyes Wide Shut (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Soolver Clear Regular \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Soolver Clear\":\n - textbox: Soolver\n - button \"Clear\"\n - button\n - cell \"Regular (Original Mix) Clear\":\n - textbox: Regular (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Weska Clear EQ64 \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Weska Clear\":\n - textbox: Weska\n - button \"Clear\"\n - button\n - cell \"EQ64 (Original Mix) Clear\":\n - textbox: EQ64 (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Tempo Giusto Clear The Fall \\(Extended Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Tempo Giusto Clear\":\n - textbox: Tempo Giusto\n - button \"Clear\"\n - button\n - cell \"The Fall (Extended Mix) Clear\":\n - textbox: The Fall (Extended Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Vlind & Asteroid & Gary Leroy Clear Trinity \\(Extended Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Vlind & Asteroid & Gary Leroy Clear\":\n - textbox: Vlind & Asteroid & Gary Leroy\n - button \"Clear\"\n - button\n - cell \"Trinity (Extended Mix) Clear\":\n - textbox: Trinity (Extended Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Astral Legacy Clear Vaveyla \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Astral Legacy Clear\":\n - textbox: Astral Legacy\n - button \"Clear\"\n - button\n - cell \"Vaveyla (Original Mix) Clear\":\n - textbox: Vaveyla (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Gerrox Clear Chakra \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Gerrox Clear\":\n - textbox: Gerrox\n - button \"Clear\"\n - button\n - cell \"Chakra (Original Mix) Clear\":\n - textbox: Chakra (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Charlotte De Witte Clear Pattern Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Charlotte De Witte Clear\":\n - textbox: Charlotte De Witte\n - button \"Clear\"\n - button\n - cell \"Pattern Clear\":\n - textbox: Pattern\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Space Food Clear Amabey Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Space Food Clear\":\n - textbox: Space Food\n - button \"Clear\"\n - button\n - cell \"Amabey Clear\":\n - textbox: Amabey\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement ARTBAT Clear Papilion \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"ARTBAT Clear\":\n - textbox: ARTBAT\n - button \"Clear\"\n - button\n - cell \"Papilion (Original Mix) Clear\":\n - textbox: Papilion (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement PETER PAHN Clear Enjoy Infinity \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"PETER PAHN Clear\":\n - textbox: PETER PAHN\n - button \"Clear\"\n - button\n - cell \"Enjoy Infinity (Original Mix) Clear\":\n - textbox: Enjoy Infinity (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Solitek Clear Instinct \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Solitek Clear\":\n - textbox: Solitek\n - button \"Clear\"\n - button\n - cell \"Instinct (Original Mix) Clear\":\n - textbox: Instinct (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Veerus Clear Heavy Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Veerus Clear\":\n - textbox: Veerus\n - button \"Clear\"\n - button\n - cell \"Heavy Clear\":\n - textbox: Heavy\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Secret Cinema & Reinier Zonneveld Clear Pain Thing \\(Original Mix\\) Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Secret Cinema & Reinier Zonneveld Clear\":\n - textbox: Secret Cinema & Reinier Zonneveld\n - button \"Clear\"\n - button\n - cell \"Pain Thing (Original Mix) Clear\":\n - textbox: Pain Thing (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Amelie Lens Clear Hypnotized Clear \\d+:\\d+:\\d+ \\d+:\\d+:\\d+ \\d+:\\d+:\\d+/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Amelie Lens Clear\":\n - textbox: Amelie Lens\n - button \"Clear\"\n - button\n - cell \"Hypnotized Clear\":\n - textbox: Hypnotized\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - row /Increment Decrement Nikolay Kirov Clear Chasing the Sun \\(Original Mix\\) Clear \\d+:\\d+:\\d+ End has no value! Length has no value!/:\n - cell:\n - checkbox\n - cell \"Increment Decrement\":\n - spinbutton: /\\d+/\n - button \"Increment\"\n - button \"Decrement\"\n - cell \"Nikolay Kirov Clear\":\n - textbox: Nikolay Kirov\n - button \"Clear\"\n - button\n - cell \"Chasing the Sun (Original Mix) Clear\":\n - textbox: Chasing the Sun (Original Mix)\n - button \"Clear\"\n - button\n - cell /\\d+:\\d+:\\d+/:\n - textbox: /\\d+:\\d+:\\d+/\n - cell \"End has no value!\":\n - textbox\n - cell \"Length has no value!\":\n - textbox\n - rowgroup:\n - row");
- }
-
- [TestMethod]
- public async Task ImportTestSampleInputfile2Async()
- {
- await Page.GotoAsync("http://localhost:5132/");
- await Page.GetByText("Import view").ClickAsync();
- await Page.GetByRole(AriaRole.Button, new() { Name = "Choose File" }).SetInputFilesAsync(new[] { "Sample_Inputfile2.txt" });
- await Page.GetByRole(AriaRole.Group).Filter(new() { HasText = "Scheme common dataScheme" }).GetByLabel("Clear").ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Textbox, new() { Name = "Cuesheet artist" })).ToBeEmptyAsync();
- await Expect(Page.GetByRole(AriaRole.Textbox, new() { Name = "Cuesheet title" })).ToBeEmptyAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Sample Title 1 Clear" })).ToBeVisibleAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = ":09:23" }).Nth(1)).ToBeVisibleAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "01:15:" })).ToBeVisibleAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Sample Artist 8 Clear" })).ToBeVisibleAsync();
- }
-
- [TestMethod]
- public async Task ImportTestTraktorAsync()
- {
- await Page.GotoAsync("http://localhost:5132/");
- await Page.GetByText("Import view").ClickAsync();
- await Page.GetByRole(AriaRole.Button, new() { Name = "Choose File" }).SetInputFilesAsync(new[] { "Traktor Export.html" });
- await Page.GetByText("Textfile (common data in").ClickAsync();
- await Page.GetByText("Traktor history").ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Arba Han Clear" })).ToBeVisibleAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = ":48:53" }).Nth(1)).ToBeVisibleAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Acid Rain Clear" })).ToBeVisibleAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = ":48:40" }).Nth(1)).ToBeVisibleAsync();
- await Page.GetByRole(AriaRole.Button, new() { Name = "Complete" }).ClickAsync();
- await Expect(Page.GetByRole(AriaRole.Cell, new() { Name = "Space Yoda (Snyl Remix) Clear" })).ToBeVisibleAsync();
- }
}
}
diff --git a/AudioCuesheetEditor.End2EndTests/Textimport with Cuesheetdata.txt b/AudioCuesheetEditor.End2EndTests/Textimport with Cuesheetdata.txt
deleted file mode 100644
index f476fd54..00000000
--- a/AudioCuesheetEditor.End2EndTests/Textimport with Cuesheetdata.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-DJFreezeT - Rabbit Hole Mix - 0123456789123
-Adriatique - X. 00:05:24.250
-Third Harmony - Fears And Dreams (Original Mix) 00:10:39
-Dele Sosimi Afrobeat Orchestra - Too Much Information (Laolu Remix; Edit) 00:17:06
-Edem, Govan - Ankh (Onetwo MX Remix) 00:23:21
-Jody Wisternoff - For All Time (feat. Hendrik Burkhard) (Extended Mix) 00:29:02
-Einmusik - Bead (Original Mix) 00:34:27
-Sebastien Leger - La Danse du Scorpion 00:40:59
-Paul Thomas & Solid Stone - La Bombo (Solid Stone Remix) 00:46:19
-GusGus - Crossfade (Maceo Plex Mix) 00:52:20
-Klangkarussell - Time (Original Mix) 00:56:19
-Anysense & Un:said - Missing Path (Original Mix) 01:01:41
-Space Food - Bombay 01:06:33
-SHDW & Obscure Shape - Wächter der Nacht (Original Mix) 01:11:04
-HOSH - Karma 01:15:28
-Alexey Union - Olympia (Original Mix) 01:21:08
-Paul Taylor - Afterglow 01:25:38
-Philter - Stranger 01:31:52
-Skizologic - Hypersphere (Original Mix) 01:36:40
-Thomas Schumacher, Caitlin - All of You (Remix) 01:42:16
-A. Skomoroh - White Horse Conquest (Original Mix) 01:47:04
-Patrik Berg - Bright (Original Mix) 01:52:37
-Hidden Empire - Bengal 01:58:05
-Mario Ochoa - Levitate 02:03:00
-Raul Facio - Eyes Wide Shut (Original Mix) 02:08:21
-Soolver - Regular (Original Mix) 02:14:31
-Weska - EQ64 (Original Mix) 02:18:35
-Tempo Giusto - The Fall (Extended Mix) 02:24:12
-Vlind & Asteroid & Gary Leroy - Trinity (Extended Mix) 02:29:38
-Astral Legacy - Vaveyla (Original Mix) 02:32:52
-Gerrox - Chakra (Original Mix) 02:37:00
-Charlotte De Witte - Pattern 02:41:55
-Space Food - Amabey 02:46:55
-ARTBAT - Papilion (Original Mix) 02:51:13
-PETER PAHN - Enjoy Infinity (Original Mix) 02:56:08
-Solitek - Instinct (Original Mix) 03:00:57
-Veerus - Heavy 03:05:19
-Secret Cinema & Reinier Zonneveld - Pain Thing (Original Mix) 03:09:38
-Amelie Lens - Hypnotized 03:13:13
-Nikolay Kirov - Chasing the Sun (Original Mix)
diff --git a/AudioCuesheetEditor.End2EndTests/Textimport-Bug-#54.txt b/AudioCuesheetEditor.End2EndTests/Textimport-Bug-#54.txt
deleted file mode 100644
index 9cda0a9e..00000000
--- a/AudioCuesheetEditor.End2EndTests/Textimport-Bug-#54.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-
-Adriatique - X. 00:05:24
-Third Harmony - Fears And Dreams (Original Mix) 00:10:39
-Dele Sosimi Afrobeat Orchestra - Too Much Information (Laolu Remix; Edit) 00:17:06
-Edem, Govan - Ankh (Onetwo MX Remix) 00:23:21
-Jody Wisternoff - For All Time (feat. Hendrik Burkhard) (Extended Mix) 00:29:02
-Einmusik - Bead (Original Mix) 00:34:27
-Sebastien Leger - La Danse du Scorpion 00:40:59
-Paul Thomas & Solid Stone - La Bombo (Solid Stone Remix) 00:46:19
-GusGus - Crossfade (Maceo Plex Mix) 00:52:20
-Klangkarussell - Time (Original Mix) 00:56:19
-Anysense & Un:said - Missing Path (Original Mix) 01:01:41
-Space Food - Bombay 01:06:33
-SHDW & Obscure Shape - Wächter der Nacht (Original Mix) 01:11:04
-HOSH - Karma 01:15:28
-Alexey Union - Olympia (Original Mix) 01:21:08
-Paul Taylor - Afterglow 01:25:38
-Philter - Stranger 01:31:52
-Skizologic - Hypersphere (Original Mix) 01:36:40
-Thomas Schumacher, Caitlin - All of You (Remix) 01:42:16
-A. Skomoroh - White Horse Conquest (Original Mix) 01:47:04
-Patrik Berg - Bright (Original Mix) 01:52:37
-Hidden Empire - Bengal 01:58:05
-Mario Ochoa - Levitate 02:03:00
-Raul Facio - Eyes Wide Shut (Original Mix) 02:08:21
-Soolver - Regular (Original Mix) 02:14:31
-Weska - EQ64 (Original Mix) 02:18:35
-Tempo Giusto - The Fall (Extended Mix) 02:24:12
-Vlind & Asteroid & Gary Leroy - Trinity (Extended Mix) 02:29:38
-Astral Legacy - Vaveyla (Original Mix) 02:32:52
-Gerrox - Chakra (Original Mix) 02:37:00
-Charlotte De Witte - Pattern 02:41:55
-Space Food - Amabey 02:46:55
-ARTBAT - Papilion (Original Mix) 02:51:13
-PETER PAHN - Enjoy Infinity (Original Mix) 02:56:08
-Solitek - Instinct (Original Mix) 03:00:57
-Veerus - Heavy 03:05:19
-Secret Cinema & Reinier Zonneveld - Pain Thing (Original Mix) 03:09:38
-Amelie Lens - Hypnotized 03:13:13
-Nikolay Kirov - Chasing the Sun (Original Mix)
diff --git a/AudioCuesheetEditor.End2EndTests/Traktor Export.html b/AudioCuesheetEditor.End2EndTests/Traktor Export.html
deleted file mode 100644
index bdc497c7..00000000
--- a/AudioCuesheetEditor.End2EndTests/Traktor Export.html
+++ /dev/null
@@ -1,306 +0,0 @@
-
-
-
-
-
-
-
- Track List HISTORY
-
-
-
-
- Track List: HISTORY
-
-
- | Num. |
- Artist |
- Title |
- Start Time |
-
-
- | 1 |
- Nachap |
- Glass |
- 2025/1/29 18:52:10 |
-
-
- | 2 |
- |
- Progressive + Melodic DECK |
- 2025/1/29 19:04:06 |
-
-
- | 3 |
- Nomer 21 |
- Depersonalization |
- 2025/1/29 19:05:41 |
-
-
- | 4 |
- SevenEver, Nopopstar, 2JOHN'S & Eugene Jay |
- Showing Off |
- 2025/1/29 19:11:24 |
-
-
- | 5 |
- Carlo Whale |
- Unconscious |
- 2025/1/29 19:16:12 |
-
-
- | 6 |
- Arba Han |
- Timelaps |
- 2025/1/29 19:21:47 |
-
-
- | 7 |
- Savill |
- Energy Surrounds |
- 2025/1/29 19:25:23 |
-
-
- | 8 |
- Teklix |
- The Tribal Code |
- 2025/1/29 19:32:40 |
-
-
- | 9 |
- Neuralis |
- I'm Looking for Answers |
- 2025/1/29 19:41:03 |
-
-
- | 10 |
- Nopopstar & Arsia |
- Dirty Moves |
- 2025/1/29 19:46:44 |
-
-
- | 11 |
- SevenEver, Nopopstar, 2JOHN'S & Eugene Jay |
- Lost (Maze 28 Remix) |
- 2025/1/29 19:52:34 |
-
-
- | 12 |
- SevenEver, Nopopstar, 2JOHN'S & Eugene Jay |
- Lost (Redspace Remix) |
- 2025/1/29 19:57:27 |
-
-
- | 13 |
- Gadoz |
- 5d |
- 2025/1/29 20:00:32 |
-
-
- | 14 |
- DJ Danzik |
- Out of Space |
- 2025/1/29 20:08:44 |
-
-
- | 15 |
- Enis Çoban |
- Internet |
- 2025/1/29 20:11:32 |
-
-
- | 16 |
- Cold Mind & Alex Yikker |
- Rage |
- 2025/1/29 20:17:24 |
-
-
- | 17 |
- Maze 28 |
- Sol (JAHAYA Remix) |
- 2025/1/29 20:23:43 |
-
-
- | 18 |
- Alex Grafton |
- Hi Baby |
- 2025/1/29 20:25:01 |
-
-
- | 19 |
- Che&Mos & Halo Far |
- Daddy |
- 2025/1/29 20:34:23 |
-
-
- | 20 |
- K KARDEN |
- Acid Rain |
- 2025/1/29 20:37:32 |
-
-
- | 21 |
- Dobrov & Gar1sson |
- Analogic (Redspace Remix) |
- 2025/1/29 20:40:50 |
-
-
- | 22 |
- Gazfluz |
- Vargan |
- 2025/1/29 20:48:50 |
-
-
- | 23 |
- SHKAPOV |
- Control |
- 2025/1/29 20:52:49 |
-
-
- | 24 |
- QazaQ |
- On the Line |
- 2025/1/29 20:58:57 |
-
-
- | 25 |
- Alex Schaufel |
- Elizabeth (Larsun Hesh Remix) |
- 2025/1/29 21:01:19 |
-
-
- | 26 |
- Oiro |
- Just Business |
- 2025/1/29 21:06:28 |
-
-
- | 27 |
- Molex |
- Mind Split (Redspace Remix) |
- 2025/1/29 21:11:32 |
-
-
- | 28 |
- SOLI |
- Give Me Your Mind |
- 2025/1/29 21:19:58 |
-
-
- | 29 |
- MANDU |
- Jacky |
- 2025/1/29 21:25:58 |
-
-
- | 30 |
- SOLI |
- Spacetoon |
- 2025/1/29 21:31:15 |
-
-
- | 31 |
- Sasha Fashion |
- Moqton |
- 2025/1/29 21:33:41 |
-
-
- | 32 |
- NAASA |
- Poison |
- 2025/1/29 21:42:28 |
-
-
- | 33 |
- Nopopstar, 2JOHN'S & Eugene Jay |
- Nightlong |
- 2025/1/29 21:48:55 |
-
-
- | 34 |
- Skillz jay |
- Choir |
- 2025/1/29 21:51:24 |
-
-
- | 35 |
- Kovax |
- Controller |
- 2025/1/29 21:57:59 |
-
-
- | 36 |
- Mumboi |
- Just a Beat |
- 2025/1/29 22:00:41 |
-
-
- | 37 |
- Eclept |
- Sprut |
- 2025/1/29 22:07:28 |
-
-
- | 38 |
- Rudensky |
- Dark Escort |
- 2025/1/29 22:12:45 |
-
-
- | 39 |
- Alexey Union, Kinky Sound & KOCHETOV |
- Connected |
- 2025/1/29 22:17:12 |
-
-
- | 40 |
- ANMA (MD) |
- Space Yoda (Snyl Remix) |
- 2025/1/29 22:24:40 |
-
-
- | 41 |
- Inache |
- Andale (MONTA (TN) Remix) |
- 2025/1/29 22:30:03 |
-
-
-
-
-
diff --git a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj
index ce6c191f..4ebd0bab 100644
--- a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj
+++ b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj
@@ -36,4 +36,13 @@
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
diff --git a/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs b/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs
index 1849ce87..7b6f0454 100644
--- a/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs
+++ b/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs
@@ -71,6 +71,90 @@ public void EmptyCuesheetTracksValidationTest()
Assert.AreEqual(ValidationStatus.Success, validationErrorTracks.Status);
}
+ [TestMethod()]
+ public void ImportTest()
+ {
+ // Arrange
+ var fileContent = new List
+ {
+ "CuesheetArtist - CuesheetTitle c:\\tmp\\Testfile.mp3",
+ "Sample Artist 1 - Sample Title 1 00:05:00",
+ "Sample Artist 2 - Sample Title 2 00:09:23",
+ "Sample Artist 3 - Sample Title 3 00:15:54",
+ "Sample Artist 4 - Sample Title 4 00:20:13",
+ "Sample Artist 5 - Sample Title 5 00:24:54",
+ "Sample Artist 6 - Sample Title 6 00:31:54",
+ "Sample Artist 7 - Sample Title 7 00:45:54",
+ "Sample Artist 8 - Sample Title 8 01:15:54"
+ };
+
+ var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
+ var sessionStateContainer = new SessionStateContainer(traceChangeManager);
+ var localStorageOptionsProviderMock = new Mock();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = TextImportScheme.DefaultSchemeCuesheet,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
+ };
+ var timeSpanFormat = new TimeSpanFormat();
+ var options = new ApplicationOptions();
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
+ var testHelper = new TestHelper();
+ // Act
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
+
+ // Assert
+ Assert.IsNull(sessionStateContainer.ImportCuesheet?.CDTextfile);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(0).Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(1).Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(2).Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(3).Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(4).Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(5).Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(6).Validate().Status);
+ Assert.AreEqual(ValidationStatus.Success, sessionStateContainer.ImportCuesheet?.Tracks.ElementAt(7).Validate().Status);
+ }
+
+ [TestMethod()]
+ public void ImportTestCalculateEndCorrectly()
+ {
+ // Arrange
+ var textImportMemoryStream = new MemoryStream(Resources.Textimport_Bug_54);
+ using var reader = new StreamReader(textImportMemoryStream);
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
+ var testHelper = new TestHelper();
+ var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
+ var sessionStateContainer = new SessionStateContainer(traceChangeManager);
+ var localStorageOptionsProviderMock = new Mock();
+ var options = new ApplicationOptions();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = null,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
+ };
+ options.ImportScheme = textImportScheme;
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
+ var timeSpanFormat = new TimeSpanFormat();
+ // Act
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
+ // Assert
+ Assert.IsNull(sessionStateContainer.Importfile?.AnalyseException);
+ Assert.IsNotNull(sessionStateContainer.ImportCuesheet);
+ Assert.AreEqual(39, sessionStateContainer.ImportCuesheet.Tracks.Count);
+ Assert.AreEqual(new TimeSpan(0, 5, 24), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(0).End);
+ Assert.AreEqual(new TimeSpan(3, 13, 13), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(38).Begin);
+ }
+
[TestMethod()]
public void RecordTest()
{
@@ -342,6 +426,68 @@ public void TrackLengthChangedWithIsLinkedToPreivousTest()
Assert.AreEqual(track1.End, track2.Begin);
Assert.AreEqual(editedTrack.End, track2.Begin);
}
+ [TestMethod()]
+ public void ImportSamplesTest()
+ {
+ // Arrange
+ var fileContent = File.ReadAllLines("Sample_Inputfile.txt");
+ var testHelper = new TestHelper();
+ var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
+ var sessionStateContainer = new SessionStateContainer(traceChangeManager);
+ var localStorageOptionsProviderMock = new Mock();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = TextImportScheme.DefaultSchemeCuesheet,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
+ };
+ var timeSpanFormat = new TimeSpanFormat();
+ var options = new ApplicationOptions();
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
+ // Act
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
+ // Assert
+ Assert.IsNull(sessionStateContainer.Importfile?.AnalyseException);
+ Assert.IsNotNull(sessionStateContainer.ImportCuesheet);
+ Assert.AreEqual("CuesheetArtist", sessionStateContainer.ImportCuesheet.Artist);
+ Assert.AreEqual("CuesheetTitle", sessionStateContainer.ImportCuesheet.Title);
+ Assert.AreEqual(8, sessionStateContainer.ImportCuesheet.Tracks.Count);
+ Assert.AreEqual(new TimeSpan(1, 15, 54), sessionStateContainer.ImportCuesheet.Tracks.Last().End);
+ }
+
+ [TestMethod()]
+ public void ImportSamples2Test()
+ {
+ // Arrange
+ var fileContent = File.ReadAllLines("Sample_Inputfile2.txt");
+ var testHelper = new TestHelper();
+ var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
+ var sessionStateContainer = new SessionStateContainer(traceChangeManager);
+ var localStorageOptionsProviderMock = new Mock();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = null,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
+ };
+ var timeSpanFormat = new TimeSpanFormat();
+ var options = new ApplicationOptions
+ {
+ ImportScheme = textImportScheme
+ };
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
+ // Act
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
+ // Assert
+ Assert.IsNull(sessionStateContainer.Importfile?.AnalyseException);
+ Assert.IsNotNull(sessionStateContainer.ImportCuesheet);
+ Assert.IsNull(sessionStateContainer.ImportCuesheet.Artist);
+ Assert.IsNull(sessionStateContainer.ImportCuesheet.Title);
+ Assert.AreEqual(8, sessionStateContainer.ImportCuesheet.Tracks.Count);
+ Assert.AreEqual(new TimeSpan(1, 15, 54), sessionStateContainer.ImportCuesheet.Tracks.Last().End);
+ }
[TestMethod()]
public void ValidateTest()
diff --git a/AudioCuesheetEditor.Tests/Model/IO/Import/ImportprofileTests.cs b/AudioCuesheetEditor.Tests/Model/IO/Import/ImportprofileTests.cs
deleted file mode 100644
index b25e9756..00000000
--- a/AudioCuesheetEditor.Tests/Model/IO/Import/ImportprofileTests.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-//This file is part of AudioCuesheetEditor.
-
-//AudioCuesheetEditor is free software: you can redistribute it and/or modify
-//it under the terms of the GNU General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//AudioCuesheetEditor is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU General Public License for more details.
-
-//You should have received a copy of the GNU General Public License
-//along with Foobar. If not, see
-//.
-
-using AudioCuesheetEditor.Model.Entity;
-using AudioCuesheetEditor.Model.IO.Import;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Linq;
-
-namespace AudioCuesheetEditor.Tests.Model.IO.Import
-{
- [TestClass()]
- public class ImportprofileTests
- {
- [TestMethod()]
- public void Validate_WithoutPlaceholder_ReturnsInvalid()
- {
- // Arrange
- var importprofile = new Importprofile()
- {
- SchemeCuesheet = "Test 1",
- SchemeTracks = "Here comes next track"
- };
- // Act
- var result = importprofile.Validate();
- // Assert
- Assert.AreEqual(ValidationStatus.Error, result.Status);
- Assert.AreEqual(2, result.ValidationMessages.Count);
- Assert.AreEqual("{0} contains no placeholder!", result.ValidationMessages.First().Message);
- Assert.AreEqual(nameof(Importprofile.SchemeCuesheet), result.ValidationMessages.First().Parameter?.First().ToString());
- Assert.AreEqual("{0} contains no placeholder!", result.ValidationMessages.Last().Message);
- Assert.AreEqual(nameof(Importprofile.SchemeTracks), result.ValidationMessages.Last().Parameter?.First().ToString());
- }
- }
-}
\ No newline at end of file
diff --git a/AudioCuesheetEditor.Tests/Model/IO/Import/TextImportSchemeTests.cs b/AudioCuesheetEditor.Tests/Model/IO/Import/TextImportSchemeTests.cs
new file mode 100644
index 00000000..17be72f0
--- /dev/null
+++ b/AudioCuesheetEditor.Tests/Model/IO/Import/TextImportSchemeTests.cs
@@ -0,0 +1,168 @@
+//This file is part of AudioCuesheetEditor.
+
+//AudioCuesheetEditor is free software: you can redistribute it and/or modify
+//it under the terms of the GNU General Public License as published by
+//the Free Software Foundation, either version 3 of the License, or
+//(at your option) any later version.
+
+//AudioCuesheetEditor is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//GNU General Public License for more details.
+
+//You should have received a copy of the GNU General Public License
+//along with Foobar. If not, see
+//.
+using AudioCuesheetEditor.Model.Entity;
+using AudioCuesheetEditor.Model.IO.Import;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Linq;
+
+namespace AudioCuesheetEditor.Tests.Model.IO.Import
+{
+ [TestClass()]
+ public class TextImportSchemeTests
+ {
+ [TestMethod]
+ public void Validate_SchemeCuesheet_WithValidPlaceholders_ShouldReturnSuccess()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeCuesheet = "(?'Artist'.+) - (?'Title'.+)\\t+(?'Audiofile'.+)"
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeCuesheet));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Success, result.Status);
+ Assert.AreEqual(0, result.ValidationMessages.Count);
+ }
+
+ [TestMethod]
+ public void Validate_SchemeCuesheet_WithSimplePlaceholders_ShouldReturnSuccess()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeCuesheet = "Artist - Title"
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeCuesheet));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Success, result.Status);
+ Assert.AreEqual(0, result.ValidationMessages.Count);
+ }
+
+ [TestMethod]
+ public void Validate_SchemeCuesheet_WithoutPlaceholders_ShouldReturnError()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeCuesheet = "InvalidPattern"
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeCuesheet));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Error, result.Status);
+ Assert.AreEqual(1, result.ValidationMessages.Count);
+ var message = result.ValidationMessages.Single();
+ Assert.AreEqual("{0} contains no placeholder!", message.Message);
+ Assert.AreEqual(nameof(TextImportScheme.SchemeCuesheet), message.Parameter?.FirstOrDefault());
+ }
+
+ [TestMethod]
+ public void Validate_SchemeTracks_WithValidPlaceholders_ShouldReturnSuccess()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeTracks = "(?'Artist'.+) - (?'Title'.+)(?:...\\t)(?'End'.+)"
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeTracks));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Success, result.Status);
+ Assert.AreEqual(0, result.ValidationMessages.Count);
+ }
+
+ [TestMethod]
+ public void Validate_SchemeTracks_WithSimplePlaceholders_ShouldReturnSuccess()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeTracks = "Artist - Title\tEnd"
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeTracks));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Success, result.Status);
+ Assert.AreEqual(0, result.ValidationMessages.Count);
+ }
+
+ [TestMethod]
+ public void Validate_SchemeTracks_WithoutPlaceholders_ShouldReturnError()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeTracks = "InvalidPattern"
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeTracks));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Error, result.Status);
+ Assert.AreEqual(1, result.ValidationMessages.Count);
+ var message = result.ValidationMessages.Single();
+ Assert.AreEqual("{0} contains no placeholder!", message.Message);
+ Assert.AreEqual(nameof(TextImportScheme.SchemeTracks), message.Parameter?.FirstOrDefault());
+ }
+
+ [TestMethod]
+ public void Validate_SchemeCuesheetEmpty_ShouldReturnSuccess()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeCuesheet = string.Empty
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeCuesheet));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Success, result.Status);
+ Assert.AreEqual(0, result.ValidationMessages.Count);
+ }
+
+ [TestMethod]
+ public void Validate_SchemeTrackstEmpty_ShouldReturnSuccess()
+ {
+ // Arrange
+ var scheme = new TextImportScheme
+ {
+ SchemeTracks = string.Empty
+ };
+
+ // Act
+ var result = scheme.Validate(nameof(TextImportScheme.SchemeTracks));
+
+ // Assert
+ Assert.AreEqual(ValidationStatus.Success, result.Status);
+ Assert.AreEqual(0, result.ValidationMessages.Count);
+ }
+ }
+}
diff --git a/AudioCuesheetEditor.Tests/Properties/Resources.Designer.cs b/AudioCuesheetEditor.Tests/Properties/Resources.Designer.cs
index c8637f77..20d2a794 100644
--- a/AudioCuesheetEditor.Tests/Properties/Resources.Designer.cs
+++ b/AudioCuesheetEditor.Tests/Properties/Resources.Designer.cs
@@ -90,16 +90,6 @@ internal static byte[] Playlist_Bug_57 {
}
}
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
- ///
- internal static byte[] Sample_Inputfile {
- get {
- object obj = ResourceManager.GetObject("Sample_Inputfile", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
///
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
///
@@ -135,17 +125,7 @@ internal static byte[] Textimport_Bug_54 {
///
internal static byte[] Textimport_with_Cuesheetdata {
get {
- object obj = ResourceManager.GetObject("Textimport with Cuesheetdata", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
- ///
- internal static byte[] Traktor_Export {
- get {
- object obj = ResourceManager.GetObject("Traktor Export", resourceCulture);
+ object obj = ResourceManager.GetObject("Textimport_with_Cuesheetdata", resourceCulture);
return ((byte[])(obj));
}
}
diff --git a/AudioCuesheetEditor.Tests/Properties/Resources.resx b/AudioCuesheetEditor.Tests/Properties/Resources.resx
index 0370cfee..243026f0 100644
--- a/AudioCuesheetEditor.Tests/Properties/Resources.resx
+++ b/AudioCuesheetEditor.Tests/Properties/Resources.resx
@@ -136,13 +136,7 @@
..\Resources\Textimport_Bug_#233.txt;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- ..\Resources\Traktor Export.html;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
+
..\Resources\Textimport with Cuesheetdata.txt;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- ..\Resources\Sample_Inputfile.txt;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
\ No newline at end of file
diff --git a/AudioCuesheetEditor.Tests/Resources/Textimport with Cuesheetdata.txt b/AudioCuesheetEditor.Tests/Resources/Textimport with Cuesheetdata.txt
index f476fd54..754820c5 100644
--- a/AudioCuesheetEditor.Tests/Resources/Textimport with Cuesheetdata.txt
+++ b/AudioCuesheetEditor.Tests/Resources/Textimport with Cuesheetdata.txt
@@ -37,4 +37,4 @@ Solitek - Instinct (Original Mix) 03:00:57
Veerus - Heavy 03:05:19
Secret Cinema & Reinier Zonneveld - Pain Thing (Original Mix) 03:09:38
Amelie Lens - Hypnotized 03:13:13
-Nikolay Kirov - Chasing the Sun (Original Mix)
+Nikolay Kirov - Chasing the Sun (Original Mix)
diff --git a/AudioCuesheetEditor.Tests/Resources/Traktor Export.html b/AudioCuesheetEditor.Tests/Resources/Traktor Export.html
deleted file mode 100644
index bdc497c7..00000000
--- a/AudioCuesheetEditor.Tests/Resources/Traktor Export.html
+++ /dev/null
@@ -1,306 +0,0 @@
-
-
-
-
-
-
-
- Track List HISTORY
-
-
-
-
- Track List: HISTORY
-
-
- | Num. |
- Artist |
- Title |
- Start Time |
-
-
- | 1 |
- Nachap |
- Glass |
- 2025/1/29 18:52:10 |
-
-
- | 2 |
- |
- Progressive + Melodic DECK |
- 2025/1/29 19:04:06 |
-
-
- | 3 |
- Nomer 21 |
- Depersonalization |
- 2025/1/29 19:05:41 |
-
-
- | 4 |
- SevenEver, Nopopstar, 2JOHN'S & Eugene Jay |
- Showing Off |
- 2025/1/29 19:11:24 |
-
-
- | 5 |
- Carlo Whale |
- Unconscious |
- 2025/1/29 19:16:12 |
-
-
- | 6 |
- Arba Han |
- Timelaps |
- 2025/1/29 19:21:47 |
-
-
- | 7 |
- Savill |
- Energy Surrounds |
- 2025/1/29 19:25:23 |
-
-
- | 8 |
- Teklix |
- The Tribal Code |
- 2025/1/29 19:32:40 |
-
-
- | 9 |
- Neuralis |
- I'm Looking for Answers |
- 2025/1/29 19:41:03 |
-
-
- | 10 |
- Nopopstar & Arsia |
- Dirty Moves |
- 2025/1/29 19:46:44 |
-
-
- | 11 |
- SevenEver, Nopopstar, 2JOHN'S & Eugene Jay |
- Lost (Maze 28 Remix) |
- 2025/1/29 19:52:34 |
-
-
- | 12 |
- SevenEver, Nopopstar, 2JOHN'S & Eugene Jay |
- Lost (Redspace Remix) |
- 2025/1/29 19:57:27 |
-
-
- | 13 |
- Gadoz |
- 5d |
- 2025/1/29 20:00:32 |
-
-
- | 14 |
- DJ Danzik |
- Out of Space |
- 2025/1/29 20:08:44 |
-
-
- | 15 |
- Enis Çoban |
- Internet |
- 2025/1/29 20:11:32 |
-
-
- | 16 |
- Cold Mind & Alex Yikker |
- Rage |
- 2025/1/29 20:17:24 |
-
-
- | 17 |
- Maze 28 |
- Sol (JAHAYA Remix) |
- 2025/1/29 20:23:43 |
-
-
- | 18 |
- Alex Grafton |
- Hi Baby |
- 2025/1/29 20:25:01 |
-
-
- | 19 |
- Che&Mos & Halo Far |
- Daddy |
- 2025/1/29 20:34:23 |
-
-
- | 20 |
- K KARDEN |
- Acid Rain |
- 2025/1/29 20:37:32 |
-
-
- | 21 |
- Dobrov & Gar1sson |
- Analogic (Redspace Remix) |
- 2025/1/29 20:40:50 |
-
-
- | 22 |
- Gazfluz |
- Vargan |
- 2025/1/29 20:48:50 |
-
-
- | 23 |
- SHKAPOV |
- Control |
- 2025/1/29 20:52:49 |
-
-
- | 24 |
- QazaQ |
- On the Line |
- 2025/1/29 20:58:57 |
-
-
- | 25 |
- Alex Schaufel |
- Elizabeth (Larsun Hesh Remix) |
- 2025/1/29 21:01:19 |
-
-
- | 26 |
- Oiro |
- Just Business |
- 2025/1/29 21:06:28 |
-
-
- | 27 |
- Molex |
- Mind Split (Redspace Remix) |
- 2025/1/29 21:11:32 |
-
-
- | 28 |
- SOLI |
- Give Me Your Mind |
- 2025/1/29 21:19:58 |
-
-
- | 29 |
- MANDU |
- Jacky |
- 2025/1/29 21:25:58 |
-
-
- | 30 |
- SOLI |
- Spacetoon |
- 2025/1/29 21:31:15 |
-
-
- | 31 |
- Sasha Fashion |
- Moqton |
- 2025/1/29 21:33:41 |
-
-
- | 32 |
- NAASA |
- Poison |
- 2025/1/29 21:42:28 |
-
-
- | 33 |
- Nopopstar, 2JOHN'S & Eugene Jay |
- Nightlong |
- 2025/1/29 21:48:55 |
-
-
- | 34 |
- Skillz jay |
- Choir |
- 2025/1/29 21:51:24 |
-
-
- | 35 |
- Kovax |
- Controller |
- 2025/1/29 21:57:59 |
-
-
- | 36 |
- Mumboi |
- Just a Beat |
- 2025/1/29 22:00:41 |
-
-
- | 37 |
- Eclept |
- Sprut |
- 2025/1/29 22:07:28 |
-
-
- | 38 |
- Rudensky |
- Dark Escort |
- 2025/1/29 22:12:45 |
-
-
- | 39 |
- Alexey Union, Kinky Sound & KOCHETOV |
- Connected |
- 2025/1/29 22:17:12 |
-
-
- | 40 |
- ANMA (MD) |
- Space Yoda (Snyl Remix) |
- 2025/1/29 22:24:40 |
-
-
- | 41 |
- Inache |
- Andale (MONTA (TN) Remix) |
- 2025/1/29 22:30:03 |
-
-
-
-
-
diff --git a/AudioCuesheetEditor.Tests/Resources/Sample_Inputfile.txt b/AudioCuesheetEditor.Tests/Sample_Inputfile.txt
similarity index 100%
rename from AudioCuesheetEditor.Tests/Resources/Sample_Inputfile.txt
rename to AudioCuesheetEditor.Tests/Sample_Inputfile.txt
diff --git a/AudioCuesheetEditor.End2EndTests/Sample_Inputfile2.txt b/AudioCuesheetEditor.Tests/Sample_Inputfile2.txt
similarity index 100%
rename from AudioCuesheetEditor.End2EndTests/Sample_Inputfile2.txt
rename to AudioCuesheetEditor.Tests/Sample_Inputfile2.txt
diff --git a/AudioCuesheetEditor.Tests/Services/IO/CuesheetImportServiceTests.cs b/AudioCuesheetEditor.Tests/Services/IO/CuesheetImportServiceTests.cs
index 03f2ae32..2b373da0 100644
--- a/AudioCuesheetEditor.Tests/Services/IO/CuesheetImportServiceTests.cs
+++ b/AudioCuesheetEditor.Tests/Services/IO/CuesheetImportServiceTests.cs
@@ -18,6 +18,7 @@
using AudioCuesheetEditor.Tests.Properties;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -30,43 +31,46 @@ public class CuesheetImportServiceTests
public void Analyse_WithSampleCuesheet_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"PERFORMER ""Sample CD Artist""
-TITLE ""Sample CD Title""
-FILE ""AC DC - TNT.mp3"" MP3
-CDTEXTFILE ""Testfile.cdt""
-CATALOG 0123456789012
-TRACK 01 AUDIO
- PERFORMER ""Sample Artist 1""
- TITLE ""Sample Title 1""
- INDEX 01 00:00:00
-TRACK 02 AUDIO
- PERFORMER ""Sample Artist 2""
- TITLE ""Sample Title 2""
- INDEX 01 05:00:00
-TRACK 03 AUDIO
- PERFORMER ""Sample Artist 3""
- TITLE ""Sample Title 3""
- INDEX 01 09:23:00
-TRACK 04 AUDIO
- PERFORMER ""Sample Artist 4""
- TITLE ""Sample Title 4""
- INDEX 01 15:54:00
-TRACK 05 AUDIO
- PERFORMER ""Sample Artist 5""
- TITLE ""Sample Title 5""
- INDEX 01 20:13:00
-TRACK 06 AUDIO
- PERFORMER ""Sample Artist 6""
- TITLE ""Sample Title 6""
- INDEX 01 24:54:00
-TRACK 07 AUDIO
- PERFORMER ""Sample Artist 7""
- TITLE ""Sample Title 7""
- INDEX 01 31:54:00
-TRACK 08 AUDIO
- PERFORMER ""Sample Artist 8""
- TITLE ""Sample Title 8""
- INDEX 01 45:51:00";
+ var fileContent = new List
+ {
+ "PERFORMER \"Sample CD Artist\"",
+ "TITLE \"Sample CD Title\"",
+ "FILE \"AC DC - TNT.mp3\" MP3",
+ "CDTEXTFILE \"Testfile.cdt\"",
+ "CATALOG 0123456789012",
+ "TRACK 01 AUDIO",
+ " PERFORMER \"Sample Artist 1\"",
+ " TITLE \"Sample Title 1\"",
+ " INDEX 01 00:00:00",
+ "TRACK 02 AUDIO",
+ " PERFORMER \"Sample Artist 2\"",
+ " TITLE \"Sample Title 2\"",
+ " INDEX 01 05:00:00",
+ "TRACK 03 AUDIO",
+ " PERFORMER \"Sample Artist 3\"",
+ " TITLE \"Sample Title 3\"",
+ " INDEX 01 09:23:00",
+ "TRACK 04 AUDIO",
+ " PERFORMER \"Sample Artist 4\"",
+ " TITLE \"Sample Title 4\"",
+ " INDEX 01 15:54:00",
+ "TRACK 05 AUDIO",
+ " PERFORMER \"Sample Artist 5\"",
+ " TITLE \"Sample Title 5\"",
+ " INDEX 01 20:13:00",
+ "TRACK 06 AUDIO",
+ " PERFORMER \"Sample Artist 6\"",
+ " TITLE \"Sample Title 6\"",
+ " INDEX 01 24:54:00",
+ "TRACK 07 AUDIO",
+ " PERFORMER \"Sample Artist 7\"",
+ " TITLE \"Sample Title 7\"",
+ " INDEX 01 31:54:00",
+ "TRACK 08 AUDIO",
+ " PERFORMER \"Sample Artist 8\"",
+ " TITLE \"Sample Title 8\"",
+ " INDEX 01 45:51:00"
+ };
// Act
var importFile = CuesheetImportService.Analyse(fileContent);
// Assert
@@ -74,17 +78,15 @@ TRACK 08 AUDIO
Assert.IsNull(importFile.AnalyseException);
Assert.IsNotNull(importFile.AnalysedCuesheet);
Assert.AreEqual(8, importFile.AnalysedCuesheet.Tracks.Count);
- Assert.IsNotNull(importFile.FileContentRecognized);
- var lines = importFile.FileContentRecognized.Split(Environment.NewLine);
- Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "PERFORMER \"Sample CD Artist\""), lines.ElementAt(0));
- Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "TITLE \"Sample CD Title\""), lines.ElementAt(1));
- Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "FILE \"AC DC - TNT.mp3\" MP3"), lines.ElementAt(2));
- Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "CDTEXTFILE \"Testfile.cdt\""), lines.ElementAt(3));
- Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "CATALOG 0123456789012"), lines.ElementAt(4));
- Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "TRACK 01 AUDIO"), lines.ElementAt(5));
- Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "PERFORMER \"Sample Artist 1\"")), lines.ElementAt(6));
- Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "TITLE \"Sample Title 1\"")), lines.ElementAt(7));
- Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "INDEX 01 00:00:00")), lines.ElementAt(8));
+ Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "PERFORMER \"Sample CD Artist\""), importFile.FileContentRecognized?.ElementAt(0));
+ Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "TITLE \"Sample CD Title\""), importFile.FileContentRecognized?.ElementAt(1));
+ Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "FILE \"AC DC - TNT.mp3\" MP3"), importFile.FileContentRecognized?.ElementAt(2));
+ Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "CDTEXTFILE \"Testfile.cdt\""), importFile.FileContentRecognized?.ElementAt(3));
+ Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "CATALOG 0123456789012"), importFile.FileContentRecognized?.ElementAt(4));
+ Assert.AreEqual(string.Format(CuesheetConstants.RecognizedMarkHTML, "TRACK 01 AUDIO"), importFile.FileContentRecognized?.ElementAt(5));
+ Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "PERFORMER \"Sample Artist 1\"")), importFile.FileContentRecognized?.ElementAt(6));
+ Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "TITLE \"Sample Title 1\"")), importFile.FileContentRecognized?.ElementAt(7));
+ Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "INDEX 01 00:00:00")), importFile.FileContentRecognized?.ElementAt(8));
}
[TestMethod()]
@@ -93,7 +95,12 @@ public void Analyse_WithCuesheetBug30_CreatesValidCuesheet()
//Arrange
var textImportMemoryStream = new MemoryStream(Resources.Playlist_Bug_30);
using var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
//Act
var importFile = CuesheetImportService.Analyse(fileContent);
//Assert
@@ -107,7 +114,12 @@ public void Analyse_WithCuesheetBug57_CreatesValidCuesheet()
//Arrange
var textImportMemoryStream = new MemoryStream(Resources.Playlist_Bug_57);
using var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
//Act
var importFile = CuesheetImportService.Analyse(fileContent);
//Assert
@@ -123,7 +135,12 @@ public void Analyse_WithCuesheetBug36_CreatesValidCuesheet()
//Arrange
var textImportMemoryStream = new MemoryStream(Resources.Playlist__36_Frames);
using var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
//Act
var importFile = CuesheetImportService.Analyse(fileContent);
//Assert
@@ -137,56 +154,57 @@ public void Analyse_WithCuesheetBug36_CreatesValidCuesheet()
public void Analyse_WithCDTextFileCatalogueNumberAndPreAndPostGap_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"PERFORMER ""Sample CD Artist""
-TITLE ""Sample CD Title""
-FILE ""AC DC - TNT.mp3"" MP3
-CDTEXTFILE ""Testfile.cdt""
-CATALOG 0123456789012
-TRACK 01 AUDIO
- PERFORMER ""Sample Artist 1""
- TITLE ""Sample Title 1""
- FLAGS 4CH DCP PRE SCMS
- INDEX 01 00:00:00
-TRACK 02 AUDIO
- PERFORMER ""Sample Artist 2""
- TITLE ""Sample Title 2""
- FLAGS DCP PRE
- INDEX 01 05:00:00
-TRACK 03 AUDIO
- PERFORMER ""Sample Artist 3""
- TITLE ""Sample Title 3""
- INDEX 01 09:23:00
-TRACK 04 AUDIO
- PERFORMER ""Sample Artist 4""
- TITLE ""Sample Title 4""
- INDEX 01 15:54:00
-TRACK 05 AUDIO
- PERFORMER ""Sample Artist 5""
- TITLE ""Sample Title 5""
- INDEX 01 20:13:00
- POSTGAP 00:02:00
-TRACK 06 AUDIO
- PERFORMER ""Sample Artist 6""
- TITLE ""Sample Title 6""
- INDEX 01 24:54:00
-TRACK 07 AUDIO
- PERFORMER ""Sample Artist 7""
- TITLE ""Sample Title 7""
- PREGAP 00:04:00
- INDEX 01 31:54:00
-TRACK 08 AUDIO
- PERFORMER ""Sample Artist 8""
- TITLE ""Sample Title 8""
- INDEX 01 45:51:00";
+ var fileContent = new List
+ {
+ "PERFORMER \"Sample CD Artist\"",
+ "TITLE \"Sample CD Title\"",
+ "FILE \"AC DC - TNT.mp3\" MP3",
+ "CDTEXTFILE \"Testfile.cdt\"",
+ "CATALOG 0123456789012",
+ "TRACK 01 AUDIO",
+ " PERFORMER \"Sample Artist 1\"",
+ " TITLE \"Sample Title 1\"",
+ " FLAGS 4CH DCP PRE SCMS",
+ " INDEX 01 00:00:00",
+ "TRACK 02 AUDIO",
+ " PERFORMER \"Sample Artist 2\"",
+ " TITLE \"Sample Title 2\"",
+ " FLAGS DCP PRE",
+ " INDEX 01 05:00:00",
+ "TRACK 03 AUDIO",
+ " PERFORMER \"Sample Artist 3\"",
+ " TITLE \"Sample Title 3\"",
+ " INDEX 01 09:23:00",
+ "TRACK 04 AUDIO",
+ " PERFORMER \"Sample Artist 4\"",
+ " TITLE \"Sample Title 4\"",
+ " INDEX 01 15:54:00",
+ "TRACK 05 AUDIO",
+ " PERFORMER \"Sample Artist 5\"",
+ " TITLE \"Sample Title 5\"",
+ " INDEX 01 20:13:00",
+ " POSTGAP 00:02:00",
+ "TRACK 06 AUDIO",
+ " PERFORMER \"Sample Artist 6\"",
+ " TITLE \"Sample Title 6\"",
+ " INDEX 01 24:54:00",
+ "TRACK 07 AUDIO",
+ " PERFORMER \"Sample Artist 7\"",
+ " TITLE \"Sample Title 7\"",
+ " PREGAP 00:04:00",
+ " INDEX 01 31:54:00",
+ "TRACK 08 AUDIO",
+ " PERFORMER \"Sample Artist 8\"",
+ " TITLE \"Sample Title 8\"",
+ " INDEX 01 45:51:00"
+ };
// Act
var importFile = CuesheetImportService.Analyse(fileContent);
// Assert
Assert.IsNull(importFile.AnalyseException);
Assert.IsNotNull(importFile.AnalysedCuesheet);
- Assert.IsNotNull(importFile.FileContentRecognized);
- var lines = importFile.FileContentRecognized.Split(Environment.NewLine);
- Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "FLAGS 4CH DCP PRE SCMS")), lines.ElementAt(8));
- Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "PREGAP 00:04:00")), lines.ElementAt(35));
+ Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "FLAGS 4CH DCP PRE SCMS")), importFile.FileContentRecognized?.ElementAt(8));
+ Assert.AreEqual(string.Format(" {0}", string.Format(CuesheetConstants.RecognizedMarkHTML, "PREGAP 00:04:00")), importFile.FileContentRecognized?.ElementAt(35));
Assert.AreEqual(8, importFile.AnalysedCuesheet.Tracks.Count);
Assert.IsNotNull(importFile.AnalysedCuesheet.CDTextfile);
Assert.AreEqual(4, importFile.AnalysedCuesheet.Tracks.ElementAt(0).Flags.Count());
diff --git a/AudioCuesheetEditor.Tests/Services/IO/FileInputManagerTests.cs b/AudioCuesheetEditor.Tests/Services/IO/FileInputManagerTests.cs
index f78b881c..2b293be9 100644
--- a/AudioCuesheetEditor.Tests/Services/IO/FileInputManagerTests.cs
+++ b/AudioCuesheetEditor.Tests/Services/IO/FileInputManagerTests.cs
@@ -13,7 +13,6 @@
//You should have received a copy of the GNU General Public License
//along with Foobar. If not, see
//.
-using AudioCuesheetEditor.Model.IO.Audio;
using AudioCuesheetEditor.Services.IO;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.Extensions.Logging;
@@ -38,7 +37,7 @@ public void CheckFileMimeType_ReturnsTrue_WhenContentTypeDoesNotMatchButExtensio
var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
// Act
- var result = manager.CheckFileMimeType(file, "audio/mpeg", [".mp3"]);
+ var result = manager.CheckFileMimeType(file, "audio/mpeg", ".mp3");
// Assert
Assert.IsTrue(result);
@@ -55,7 +54,7 @@ public void CheckFileMimeType_ReturnsTrue_WhenContentTypeDoesMatchButNotExtensio
var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
// Act
- var result = manager.CheckFileMimeType(file, "audio/mpeg", [".mp3", ".txt"]);
+ var result = manager.CheckFileMimeType(file, "audio/mpeg", ".mp3");
// Assert
Assert.IsTrue(result);
@@ -72,7 +71,7 @@ public void CheckFileMimeType_ReturnsFalse_WhenExtensionDoesNotMatchAndContentTy
var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
// Act
- var result = manager.CheckFileMimeType(file, "audio/flac", [".mp3"]);
+ var result = manager.CheckFileMimeType(file, "audio/flac", ".mp3");
// Assert
Assert.IsFalse(result);
@@ -89,150 +88,12 @@ public void CheckFileMimeType_ReturnsTrue_WhenContentTypeAndExtensionMatch()
var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
// Act
- var result = manager.CheckFileMimeType(file, "audio/wave", [".wav"]);
+ var result = manager.CheckFileMimeType(file, "audio/wave", ".wav");
// Assert
Assert.IsTrue(result);
}
- [TestMethod()]
- public void CheckFileMimeType_ReturnsTrue_WhenContentMainTypeMatch()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("history.txt", "text/plain");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.CheckFileMimeType(file, "text/*", [".txt", ".text"]);
-
- // Assert
- Assert.IsTrue(result);
- }
-
- [TestMethod()]
- public void IsValidAudiofile_ReturnsTrue_WithValidAudiocodec()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("test.wav", "audio/wav");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.IsValidAudiofile(file);
-
- // Assert
- Assert.IsTrue(result);
- }
-
- [TestMethod()]
- public void IsValidAudiofile_ReturnsFalse_WithInvalidAudiocodecAndExtension()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("test.mock", "just a fantasy");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.IsValidAudiofile(file);
-
- // Assert
- Assert.IsFalse(result);
- }
-
- [TestMethod()]
- public void GetAudioCodec_ReturnsAudiocodec_WhenContentTypeMatches()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("test.wbem", "audio/webm");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.GetAudioCodec(file);
-
- // Assert
- Assert.IsNotNull(result);
- Assert.AreEqual(Audiofile.AudioCodecWEBM, result);
- }
-
- [TestMethod()]
- public void GetAudioCodec_ReturnsAudiocodec_WhenContentTypeAndFileExtensionMatches()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("test.webm", "audio/webm");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.GetAudioCodec(file);
-
- // Assert
- Assert.IsNotNull(result);
- Assert.AreEqual(Audiofile.AudioCodecWEBM, result);
- }
-
- [TestMethod()]
- public void GetAudioCodec_ReturnsNull_WhenContentTypeAndFileExtensionNotMatch()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("test.acx", "fantasy stuff");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.GetAudioCodec(file);
-
- // Assert
- Assert.IsNull(result);
- }
-
- [TestMethod()]
- public void IsValidForImportView_ReturnsTrue_WhenFileIsHtml()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("test.html", "text/html");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.IsValidForImportView(file);
-
- // Assert
- Assert.IsTrue(result);
- }
-
- [TestMethod()]
- public void IsValidForImportView_ReturnsFalse_WhenFileIsBinary()
- {
- // Arrange
- var jsRuntimeMock = new Mock();
- var httpClientMock = new Mock();
- var loggerMock = new Mock>();
- var file = CreateBrowserFile("test.dat", "application/octet-stream");
- var manager = new FileInputManager(jsRuntimeMock.Object, httpClientMock.Object, loggerMock.Object);
-
- // Act
- var result = manager.IsValidForImportView(file);
-
- // Assert
- Assert.IsFalse(result);
- }
-
private static IBrowserFile CreateBrowserFile(string name, string contentType)
{
var fileMock = new Mock();
diff --git a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs
index 1dcf6fb8..08b24803 100644
--- a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs
+++ b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs
@@ -14,17 +14,18 @@
//along with Foobar. If not, see
//.
-using AudioCuesheetEditor.Model.AudioCuesheet;
-using AudioCuesheetEditor.Model.AudioCuesheet.Import;
+using AudioCuesheetEditor.Data.Options;
using AudioCuesheetEditor.Model.IO.Import;
+using AudioCuesheetEditor.Model.Options;
+using AudioCuesheetEditor.Model.Utility;
using AudioCuesheetEditor.Services.IO;
using AudioCuesheetEditor.Services.UI;
using AudioCuesheetEditor.Tests.Utility;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
+using System.Collections.Generic;
using System.Linq;
-using System.Threading.Tasks;
namespace AudioCuesheetEditor.Tests.Services.IO
{
@@ -32,86 +33,78 @@ namespace AudioCuesheetEditor.Tests.Services.IO
public class ImportManagerTests
{
[TestMethod()]
- public async Task ImportTextAsync_WithAnalysedCuesheet_SetsImportCuesheet()
+ public void ImportTextAsync_TextfileWithStartDateTime_CreatesValidCuesheet()
{
// Arrange
- var fileContent = "This is just a test";
- var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
- var sessionStateContainer = new SessionStateContainer(traceChangeManager);
- var fileInputManagerMock = new Mock();
- var textImportServiceMock = new Mock();
- var importCuesheet = new ImportCuesheet()
+ var fileContent = new List
{
- Artist = "Test Cuesheet Artist",
- Title = "Test Cuesheet Title",
- Audiofile = "Test Cuesheet Audiofile",
- Cataloguenumber = "Test Cuesheet Cataloguenumber",
- CDTextfile = "Test Cuesheet CDTextfile"
+ "Innellea~The Golden Fort~02.08.2024 20:10:48",
+ "Nora En Pure~Diving with Whales (Daniel Portman Remix)~02.08.2024 20:15:21",
+ "WhoMadeWho & Adriatique~Miracle (RÜFÜS DU SOL Remix)~02.08.2024 20:20:42",
+ "Ella Wild~Poison D'araignee (Original Mix)~02.08.2024 20:28:03",
+ "Stil & Bense~On The Edge (Original Mix)~02.08.2024 20:32:42",
+ "Nebula~Clairvoyant Dreams~02.08.2024 20:39:01",
+ "Valentina Black~I'm a Tree (Extended Mix)~02.08.2024 20:47:08",
+ "Nebula~Clairvoyant Dreams~02.08.2024 20:53:20",
+ "Kiko & Dave Davis feat. Phoebe~Living in Space (Dub Mix)~02.08.2024 20:58:11",
+ "Lilly Palmer~Before Acid~02.08.2024 21:03:53",
+ "Sofi Tukker~Drinkee (Vintage Culture & John Summit Extended Mix)~02.08.2024 21:09:52",
+ "CID & Truth x Lies~Caroline (Extended Mix)~02.08.2024 21:14:09",
+ "Moby~Why Does My Heart Feel So Bad? (Oxia Remix)~02.08.2024 21:17:15",
+ "Ammo Avenue~Little Gurl (Extended Mix)~02.08.2024 21:22:46",
+ "James Hurr & Smokin Jo & Stealth~Beggin' For Change~02.08.2024 21:28:37",
+ "Kristine Blond~Love Shy (Sam Divine & CASSIMM Extended Remix)~02.08.2024 21:30:47",
+ "Vanilla Ace~Work On You (Original Mix)~02.08.2024 21:36:28",
+ "Truth X Lies~Like This~02.08.2024 21:42:05",
+ "Terri-Anne~Round Round~02.08.2024 21:44:07",
+ "Joanna Magik~Maneater~02.08.2024 21:46:32",
+ "Jen Payne & Kevin McKay~Feed Your Soul~02.08.2024 21:48:45",
+ "Kevin McKay & Eppers & Notelle~On My Own~02.08.2024 21:51:37",
+ "Nader Razdar & Kevin McKay~Get Ur Freak On (Kevin McKay Extended Mix)~02.08.2024 21:53:49",
+ "Philip Z~Yala (Extended Mix)~02.08.2024 21:59:40",
+ "Kyle Kinch & Kevin McKay~Hella~02.08.2024 22:05:53",
+ "Roze Wild~B-O-D-Y~02.08.2024 22:08:26",
+ "Jey Kurmis~Snoop~02.08.2024 22:11:09",
+ "Bootie Brown & Tame Impala & Gorillaz~New Gold (Dom Dolla Remix Extended)~02.08.2024 22:16:23",
+ "Eli Brown & Love Regenerator~Don't You Want Me (Original Mix)~02.08.2024 22:21:23",
+ "Local Singles~Voices~02.08.2024 22:25:59"
};
- importCuesheet.Tracks.Add(new()
- {
- Artist = "Test Track Artist 1",
- Title = "Test Track Title 1",
- Begin = new TimeSpan(0, 3, 20),
- End = new TimeSpan(0, 7, 43),
- Flags = [Flag.DCP],
- Position = 1,
- PreGap = new TimeSpan(0, 0, 2),
- PostGap = new TimeSpan(0, 0, 4)
- });
- var importfile = new Importfile()
- {
- FileContent = fileContent,
- FileType = ImportFileType.Textfile,
- AnalysedCuesheet = importCuesheet
- };
- textImportServiceMock.Setup(x => x.AnalyseAsync(fileContent)).ReturnsAsync(importfile);
- var importManager = new ImportManager(sessionStateContainer, traceChangeManager, fileInputManagerMock.Object, textImportServiceMock.Object);
- var testHelper = new TestHelper();
- // Act
- await importManager.ImportTextAsync(fileContent);
- // Assert
- Assert.AreEqual(importfile, sessionStateContainer.Importfile);
- Assert.IsNotNull(sessionStateContainer.ImportCuesheet);
- Assert.AreEqual(importCuesheet.Artist, sessionStateContainer.ImportCuesheet.Artist);
- Assert.AreEqual(importCuesheet.Title, sessionStateContainer.ImportCuesheet.Title);
- Assert.IsNotNull(sessionStateContainer.ImportCuesheet.Audiofile);
- Assert.AreEqual(importCuesheet.Audiofile, sessionStateContainer.ImportCuesheet.Audiofile.Name);
- Assert.AreEqual(importCuesheet.Cataloguenumber, sessionStateContainer.ImportCuesheet.Cataloguenumber);
- Assert.IsNotNull(sessionStateContainer.ImportCuesheet.CDTextfile);
- Assert.AreEqual(importCuesheet.CDTextfile, sessionStateContainer.ImportCuesheet.CDTextfile.Name);
- Assert.AreEqual(importCuesheet.Tracks.First().Artist, sessionStateContainer.ImportCuesheet.Tracks.First().Artist);
- Assert.AreEqual(importCuesheet.Tracks.First().Title, sessionStateContainer.ImportCuesheet.Tracks.First().Title);
- Assert.AreEqual(importCuesheet.Tracks.First().Begin, sessionStateContainer.ImportCuesheet.Tracks.First().Begin);
- Assert.AreEqual(importCuesheet.Tracks.First().End, sessionStateContainer.ImportCuesheet.Tracks.First().End);
- CollectionAssert.AreEquivalent(importCuesheet.Tracks.First().Flags.ToList(), sessionStateContainer.ImportCuesheet.Tracks.First().Flags.ToList());
- Assert.AreEqual(importCuesheet.Tracks.First().Position, sessionStateContainer.ImportCuesheet.Tracks.First().Position);
- Assert.AreEqual(importCuesheet.Tracks.First().PreGap, sessionStateContainer.ImportCuesheet.Tracks.First().PreGap);
- Assert.AreEqual(importCuesheet.Tracks.First().PostGap, sessionStateContainer.ImportCuesheet.Tracks.First().PostGap);
- }
- [TestMethod()]
- public async Task ImportTextAsync_WithoutAnalysedCuesheet_DoesNothing()
- {
- // Arrange
- var fileContent = "This is just a test";
var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
var sessionStateContainer = new SessionStateContainer(traceChangeManager);
- var fileInputManagerMock = new Mock();
- var textImportServiceMock = new Mock();
- var importfile = new Importfile()
+ var localStorageOptionsProviderMock = new Mock();
+ var textImportScheme = new TextImportScheme()
{
- FileContent = fileContent,
- FileType = ImportFileType.Textfile,
+ SchemeCuesheet = null,
+ SchemeTracks = @"(?'Artist'[a-zA-Z0-9_ .();äöü&:,'*-?:]{1,})~(?'Title'[a-zA-Z0-9_ .();äöü&'*-?:Ü]{1,})~(?'StartDateTime'.{1,})"
};
- textImportServiceMock.Setup(x => x.AnalyseAsync(fileContent)).ReturnsAsync(importfile);
- var importManager = new ImportManager(sessionStateContainer, traceChangeManager, fileInputManagerMock.Object, textImportServiceMock.Object);
+ var timeSpanFormat = new TimeSpanFormat();
+ var options = new ApplicationOptions();
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
var testHelper = new TestHelper();
// Act
- await importManager.ImportTextAsync(fileContent);
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
// Assert
- Assert.AreEqual(importfile, sessionStateContainer.Importfile);
- Assert.IsNull(sessionStateContainer.ImportCuesheet);
+ Assert.IsNull(sessionStateContainer.Importfile?.AnalyseException);
+ Assert.IsNotNull(sessionStateContainer.ImportCuesheet);
+ Assert.AreEqual(30, sessionStateContainer.ImportCuesheet.Tracks.Count);
+ Assert.AreEqual("Innellea", sessionStateContainer.ImportCuesheet.Tracks.ElementAt(0).Artist);
+ Assert.AreEqual("The Golden Fort", sessionStateContainer.ImportCuesheet.Tracks.ElementAt(0).Title);
+ Assert.AreEqual(TimeSpan.Zero, sessionStateContainer.ImportCuesheet.Tracks.ElementAt(0).Begin);
+ Assert.AreEqual(new TimeSpan(0, 4, 33), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(0).End);
+ Assert.AreEqual(new TimeSpan(0, 4, 33), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(0).Length);
+ Assert.AreEqual("Nora En Pure", sessionStateContainer.ImportCuesheet.Tracks.ElementAt(1).Artist);
+ Assert.AreEqual("Diving with Whales (Daniel Portman Remix)", sessionStateContainer.ImportCuesheet.Tracks.ElementAt(1).Title);
+ Assert.AreEqual(new TimeSpan(0, 4, 33), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(1).Begin);
+ Assert.AreEqual(new TimeSpan(0, 9, 54), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(1).End);
+ Assert.AreEqual(new TimeSpan(0, 5, 21), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(1).Length);
+ Assert.AreEqual("Local Singles", sessionStateContainer.ImportCuesheet.Tracks.ElementAt(29).Artist);
+ Assert.AreEqual("Voices", sessionStateContainer.ImportCuesheet.Tracks.ElementAt(29).Title);
+ Assert.AreEqual(new TimeSpan(2, 15, 11), sessionStateContainer.ImportCuesheet.Tracks.ElementAt(29).Begin);
+ Assert.IsNull(sessionStateContainer.ImportCuesheet.Tracks.ElementAt(29).End);
+ Assert.IsNull(sessionStateContainer.ImportCuesheet.Tracks.ElementAt(29).Length);
}
}
}
\ No newline at end of file
diff --git a/AudioCuesheetEditor.Tests/Services/IO/TextImportServiceTests.cs b/AudioCuesheetEditor.Tests/Services/IO/TextImportServiceTests.cs
index 19557500..e95cfd6c 100644
--- a/AudioCuesheetEditor.Tests/Services/IO/TextImportServiceTests.cs
+++ b/AudioCuesheetEditor.Tests/Services/IO/TextImportServiceTests.cs
@@ -13,49 +13,45 @@
//You should have received a copy of the GNU General Public License
//along with Foobar. If not, see
//.
-using AudioCuesheetEditor.Data.Options;
using AudioCuesheetEditor.Model.AudioCuesheet;
-using AudioCuesheetEditor.Model.AudioCuesheet.Import;
using AudioCuesheetEditor.Model.IO.Import;
-using AudioCuesheetEditor.Model.Options;
using AudioCuesheetEditor.Model.Utility;
using AudioCuesheetEditor.Services.IO;
using AudioCuesheetEditor.Tests.Properties;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Moq;
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
namespace AudioCuesheetEditor.Tests.Services.IO
{
[TestClass()]
public class TextImportServiceTests
{
-
[TestMethod()]
- public async Task AnalyseAsync_SampleCuesheet_CreatesValidCuesheetAsync()
+ public void Analyse_SampleCuesheet_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"CuesheetArtist - CuesheetTitle c:\tmp\Testfile.mp3
-Sample Artist 1 - Sample Title 1 00:05:00
-Sample Artist 2 - Sample Title 2 00:09:23
-Sample Artist 3 - Sample Title 3 00:15:54
-Sample Artist 4 - Sample Title 4 00:20:13
-Sample Artist 5 - Sample Title 5 00:24:54
-Sample Artist 6 - Sample Title 6 00:31:54
-Sample Artist 7 - Sample Title 7 00:45:54
-Sample Artist 8 - Sample Title 8 01:15:54";
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var fileContent = new List
{
- SelectedImportProfile = ApplicationOptions.DefaultSelectedImportprofile
+ "CuesheetArtist - CuesheetTitle c:\\tmp\\Testfile.mp3",
+ "Sample Artist 1 - Sample Title 1 00:05:00",
+ "Sample Artist 2 - Sample Title 2 00:09:23",
+ "Sample Artist 3 - Sample Title 3 00:15:54",
+ "Sample Artist 4 - Sample Title 4 00:20:13",
+ "Sample Artist 5 - Sample Title 5 00:24:54",
+ "Sample Artist 6 - Sample Title 6 00:31:54",
+ "Sample Artist 7 - Sample Title 7 00:45:54",
+ "Sample Artist 8 - Sample Title 8 01:15:54"
+ };
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = TextImportScheme.DefaultSchemeCuesheet,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -69,65 +65,55 @@ public async Task AnalyseAsync_SampleCuesheet_CreatesValidCuesheetAsync()
}
[TestMethod()]
- public async Task AnalyseAsync_InvalidSchemeTracks_CreatesAnalyseExceptionAsync()
+ public void Analyse_InvalidSchemeTracks_CreatesAnalyseException()
{
// Arrange
- var fileContent = @"CuesheetArtist|CuesheetTitle c:\tmp\TestTextFile.cdt
-1|Sample Artist 1 - Sample Title 1 00:05:00
-2|Sample Artist 2 - Sample Title 2 00:09:23
-3|Sample Artist 3 - Sample Title 3 00:15:54
-4|Sample Artist 4 - Sample Title 4 00:20:13
-5|Sample Artist 5 - Sample Title 5 00:24:54
-6|Sample Artist 6 - Sample Title 6 00:31:54
-7|Sample Artist 7 - Sample Title 7 00:45:54
-8|Sample Artist 8 - Sample Title 8 01:15:54";
- var profile = new Importprofile()
+ var fileContent = new List
{
- UseRegularExpression = true,
- SchemeCuesheet = @"(?'Cuesheet.Artist'\A.*)[|](?'Cuesheet.Title'\w{1,})\t{1,}(?'Cuesheet.CDTextfile'.{1,})",
- SchemeTracks = @"(?'Track.Position'.{1,})|(?'Track.Artist'.{1,}) - (?'Track.Title'[a-zA-Z0-9_ ]{1,})\t{1,}(?'Track.End'.{1,})"
+ "CuesheetArtist|CuesheetTitle c:\\tmp\\TestTextFile.cdt",
+ "1|Sample Artist 1 - Sample Title 1 00:05:00",
+ "2|Sample Artist 2 - Sample Title 2 00:09:23",
+ "3|Sample Artist 3 - Sample Title 3 00:15:54",
+ "4|Sample Artist 4 - Sample Title 4 00:20:13",
+ "5|Sample Artist 5 - Sample Title 5 00:24:54",
+ "6|Sample Artist 6 - Sample Title 6 00:31:54",
+ "7|Sample Artist 7 - Sample Title 7 00:45:54",
+ "8|Sample Artist 8 - Sample Title 8 01:15:54"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = @"(?'Cuesheet.Artist'\A.*)[|](?'Cuesheet.Title'\w{1,})\t{1,}(?'Cuesheet.CDTextfile'.{1,})",
+ SchemeTracks = @"(?'Track.Position'.{1,})|(?'Track.Artist'.{1,}) - (?'Track.Title'[a-zA-Z0-9_ ]{1,})\t{1,}(?'Track.End'.{1,})"
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNotNull(importfile.AnalyseException);
}
[TestMethod()]
- public async Task AnalyseAsync_InputfileWithExtraSeperator_CreatesValidCuesheetAsync()
+ public void Analyse_InputfileWithExtraSeperator_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"CuesheetArtist|CuesheetTitle c:\tmp\TestTextFile.cdt
-1|Sample Artist 1 - Sample Title 1 00:05:00
-2|Sample Artist 2 - Sample Title 2 00:09:23
-3|Sample Artist 3 - Sample Title 3 00:15:54
-4|Sample Artist 4 - Sample Title 4 00:20:13
-5|Sample Artist 5 - Sample Title 5 00:24:54
-6|Sample Artist 6 - Sample Title 6 00:31:54
-7|Sample Artist 7 - Sample Title 7 00:45:54
-8|Sample Artist 8 - Sample Title 8 01:15:54";
- var profile = new Importprofile()
+ var fileContent = new List
{
- UseRegularExpression = true,
- SchemeCuesheet = @"(?'Artist'\A.*)[|](?'Title'\w{1,})\t{1,}(?'CDTextfile'[^\r\n]+)",
- SchemeTracks = @"(?'Position'\d{1,})[|](?'Artist'.{1,}) - (?'Title'[a-zA-Z0-9_ ]{1,})\t{1,}(?'End'.{1,})"
+ "CuesheetArtist|CuesheetTitle c:\\tmp\\TestTextFile.cdt",
+ "1|Sample Artist 1 - Sample Title 1 00:05:00",
+ "2|Sample Artist 2 - Sample Title 2 00:09:23",
+ "3|Sample Artist 3 - Sample Title 3 00:15:54",
+ "4|Sample Artist 4 - Sample Title 4 00:20:13",
+ "5|Sample Artist 5 - Sample Title 5 00:24:54",
+ "6|Sample Artist 6 - Sample Title 6 00:31:54",
+ "7|Sample Artist 7 - Sample Title 7 00:45:54",
+ "8|Sample Artist 8 - Sample Title 8 01:15:54"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = @"(?'Artist'\A.*)[|](?'Title'\w{1,})\t{1,}(?'CDTextfile'.{1,})",
+ SchemeTracks = @"(?'Position'\d{1,})[|](?'Artist'.{1,}) - (?'Title'[a-zA-Z0-9_ ]{1,})\t{1,}(?'End'.{1,})"
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -140,34 +126,30 @@ public async Task AnalyseAsync_InputfileWithExtraSeperator_CreatesValidCuesheetA
Assert.AreEqual("Sample Title 1", importfile.AnalysedCuesheet.Tracks.ElementAt(0).Title);
Assert.AreEqual(new TimeSpan(0, 5, 0), importfile.AnalysedCuesheet.Tracks.ElementAt(0).End);
}
-
+
[TestMethod()]
- public async Task AnalyseAsync_InputfileWithSimplifiedScheme_CreatesValidCuesheetAsync()
+ public void Analyse_InputfileWithSimplifiedScheme_CreatesValidCuesheet()
{
- var fileContent = @"CuesheetArtist|CuesheetTitle c:\tmp\TestTextFile.cdt
-1|Sample Artist 1 - Sample Title 1 00:05:00
-2|Sample Artist 2 - Sample Title 2 00:09:23
-3|Sample Artist 3 - Sample Title 3 00:15:54
-4|Sample Artist 4 - Sample Title 4 00:20:13
-5|Sample Artist 5 - Sample Title 5 00:24:54
-6|Sample Artist 6 - Sample Title 6 00:31:54
-7|Sample Artist 7 - Sample Title 7 00:45:54
-8|Sample Artist 8 - Sample Title 8 01:15:54";
- var profile = new Importprofile()
+ // Arrange
+ var fileContent = new List
{
- UseRegularExpression = false,
- SchemeCuesheet = @"Artist|Title CDTextfile",
- SchemeTracks = @"Position|Artist - Title End"
+ "CuesheetArtist|CuesheetTitle c:\\tmp\\TestTextFile.cdt",
+ "1|Sample Artist 1 - Sample Title 1 00:05:00",
+ "2|Sample Artist 2 - Sample Title 2 00:09:23",
+ "3|Sample Artist 3 - Sample Title 3 00:15:54",
+ "4|Sample Artist 4 - Sample Title 4 00:20:13",
+ "5|Sample Artist 5 - Sample Title 5 00:24:54",
+ "6|Sample Artist 6 - Sample Title 6 00:31:54",
+ "7|Sample Artist 7 - Sample Title 7 00:45:54",
+ "8|Sample Artist 8 - Sample Title 8 01:15:54"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = @"Artist|Title CDTextfile",
+ SchemeTracks = @"Position|Artist - Title End"
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -182,83 +164,71 @@ public async Task AnalyseAsync_InputfileWithSimplifiedScheme_CreatesValidCueshee
}
[TestMethod()]
- public async Task AnalyseAsync_InvalidScheme_CreatesAnalyseExceptionAsync()
+ public void Analyse_InvalidScheme_CreatesAnalyseException()
{
// Arrange
- var fileContent = @"CuesheetArtist|CuesheetTitle c:\tmp\TestTextFile.cdt A83412346734
-1|Sample Artist 1 - Sample Title 1 00:05:00
-2|Sample Artist 2 - Sample Title 2 00:09:23
-3|Sample Artist 3 - Sample Title 3 00:15:54
-4|Sample Artist 4 - Sample Title 4 00:20:13
-5|Sample Artist 5 - Sample Title 5 00:24:54
-6|Sample Artist 6 - Sample Title 6 00:31:54
-7|Sample Artist 7 - Sample Title 7 00:45:54
-8|Sample Artist 8 - Sample Title 8 01:15:54
-
-
-
-
-
-
-
-
-";
- var profile = new Importprofile()
+ var fileContent = new List
+ {
+ "CuesheetArtist|CuesheetTitle c:\\tmp\\TestTextFile.cdt A83412346734",
+ "1|Sample Artist 1 - Sample Title 1 00:05:00",
+ "2|Sample Artist 2 - Sample Title 2 00:09:23",
+ "3|Sample Artist 3 - Sample Title 3 00:15:54",
+ "4|Sample Artist 4 - Sample Title 4 00:20:13",
+ "5|Sample Artist 5 - Sample Title 5 00:24:54",
+ "6|Sample Artist 6 - Sample Title 6 00:31:54",
+ "7|Sample Artist 7 - Sample Title 7 00:45:54",
+ "8|Sample Artist 8 - Sample Title 8 01:15:54",
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty
+ };
+ var textImportScheme = new TextImportScheme()
{
- UseRegularExpression = true,
SchemeCuesheet = @"(?'Cuesheet.Artist'\A.*)[|](?'Cuesheet.Title'\w{1,})\t{1,}(?'Cuesheet.CDTextfile'[a-zA-Z0-9_ .();äöü&:,\\]{1,})\t{1,}(?'Cuesheet.Cataloguenumber'.{1,})",
SchemeTracks = @"(?'Track.Position'.{1,})|(?'Track.Artist'.{1,}) - (?'Track.Title'[a-zA-Z0-9_ ]{1,})\t{1,}(?'Track.End'.{1,})"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
- {
- SelectedImportProfile = profile
- };
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNotNull(importfile.AnalyseException);
}
[TestMethod()]
- public async Task AnalyseAsync_CuesheetWithTextfileAndCatalogueNumber_CreatesValidCuesheetAsync()
+ public void Analyse_CuesheetWithTextfileAndCatalogueNumber_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"CuesheetArtist|CuesheetTitle c:\tmp\TestTextFile.cdt A83412346734
-1|Sample Artist 1 - Sample Title 1 00:05:00
-2|Sample Artist 2 - Sample Title 2 00:09:23
-3|Sample Artist 3 - Sample Title 3 00:15:54
-4|Sample Artist 4 - Sample Title 4 00:20:13
-5|Sample Artist 5 - Sample Title 5 00:24:54
-6|Sample Artist 6 - Sample Title 6 00:31:54
-7|Sample Artist 7 - Sample Title 7 00:45:54
-8|Sample Artist 8 - Sample Title 8 01:15:54
-
-
-
-
-
-
-
-
-";
- var profile = new Importprofile()
- {
- UseRegularExpression = true,
- SchemeCuesheet = @"(?'Artist'\A.*)[|](?'Title'\w{1,})\t{1,}(?'CDTextfile'[a-zA-Z0-9_ .();äöü&:,\\]{1,})\t{1,}(?'Cataloguenumber'[^\r\n]+)",
+ var fileContent = new List
+ {
+ "CuesheetArtist|CuesheetTitle c:\\tmp\\TestTextFile.cdt A83412346734",
+ "1|Sample Artist 1 - Sample Title 1 00:05:00",
+ "2|Sample Artist 2 - Sample Title 2 00:09:23",
+ "3|Sample Artist 3 - Sample Title 3 00:15:54",
+ "4|Sample Artist 4 - Sample Title 4 00:20:13",
+ "5|Sample Artist 5 - Sample Title 5 00:24:54",
+ "6|Sample Artist 6 - Sample Title 6 00:31:54",
+ "7|Sample Artist 7 - Sample Title 7 00:45:54",
+ "8|Sample Artist 8 - Sample Title 8 01:15:54",
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty,
+ string.Empty
+ };
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = @"(?'Artist'\A.*)[|](?'Title'\w{1,})\t{1,}(?'CDTextfile'[a-zA-Z0-9_ .();äöü&:,\\]{1,})\t{1,}(?'Cataloguenumber'.{1,})",
SchemeTracks = @"(?'Position'.{1,})[|](?'Artist'.{1,}) - (?'Title'[a-zA-Z0-9_ ]{1,})\t{1,}(?'End'.{1,})"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
- {
- SelectedImportProfile = profile
- };
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -274,31 +244,28 @@ public async Task AnalyseAsync_CuesheetWithTextfileAndCatalogueNumber_CreatesVal
}
[TestMethod()]
- public async Task AnalyseAsync_CuesheeTracksOnly_CreatesValidCuesheetAsync()
+ public void Analyse_CuesheeTracksOnly_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"Sample Artist 1 - Sample Title 1 00:05:00
-Sample Artist 2 - Sample Title 2 00:09:23
-Sample Artist 3 - Sample Title 3 00:15:54
-Sample Artist 4 - Sample Title 4 00:20:13
-Sample Artist 5 - Sample Title 5 00:24:54
-Sample Artist 6 - Sample Title 6 00:31:54
-Sample Artist 7 - Sample Title 7 00:45:54
-Sample Artist 8 - Sample Title 8 01:15:54
-Sample Artist 9 - Sample Title 9 ";
- var profile = new Importprofile()
+ var fileContent = new List
{
- SchemeTracks = $"{nameof(ImportTrack.Artist)} - {nameof(ImportTrack.Title)}\t{nameof(ImportTrack.End)}"
+ "Sample Artist 1 - Sample Title 1 00:05:00",
+ "Sample Artist 2 - Sample Title 2 00:09:23",
+ "Sample Artist 3 - Sample Title 3 00:15:54",
+ "Sample Artist 4 - Sample Title 4 00:20:13",
+ "Sample Artist 5 - Sample Title 5 00:24:54",
+ "Sample Artist 6 - Sample Title 6 00:31:54",
+ "Sample Artist 7 - Sample Title 7 00:45:54",
+ "Sample Artist 8 - Sample Title 8 01:15:54",
+ "Sample Artist 9 - Sample Title 9"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = null,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -309,26 +276,25 @@ public async Task AnalyseAsync_CuesheeTracksOnly_CreatesValidCuesheetAsync()
}
[TestMethod()]
- public async Task AnalyseAsync_CuesheetBug213_CreatesValidCuesheetAsync()
+ public void Analyse_CuesheetBug213_CreatesValidCuesheet()
{
// Arrange
var textImportMemoryStream = new MemoryStream(Resources.Textimport_Bug_213);
using var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
- var profile = new Importprofile()
+ List lines = [];
+ while (reader.EndOfStream == false)
{
- SchemeTracks = $"{nameof(ImportTrack.Artist)} - {nameof(ImportTrack.Title)}\t{nameof(ImportTrack.End)}",
- TimeSpanFormat = new() { Scheme = $"{nameof(TimeSpanFormat.Minutes)}:{nameof(TimeSpanFormat.Seconds)}" }
- };
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
+ var timeSpanFormat = new TimeSpanFormat() { Scheme = "Minutes:Seconds" };
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = null,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent, timeSpanFormat);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -337,31 +303,27 @@ public async Task AnalyseAsync_CuesheetBug213_CreatesValidCuesheetAsync()
}
[TestMethod()]
- public async Task AnalyseAsync_CuesheetWithFlags_CreatesValidCuesheetAsync()
+ public void Analyse_CuesheetWithFlags_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"Sample Artist 1 - Sample Title 1 00:05:00 DCP
-Sample Artist 2 - Sample Title 2 00:09:23
-Sample Artist 3 - Sample Title 3 00:15:54 PRE, DCP
-Sample Artist 4 - Sample Title 4 00:20:13 4CH
-Sample Artist 5 - Sample Title 5 00:24:54
-Sample Artist 6 - Sample Title 6 00:31:54 PRE DCP 4CH
-Sample Artist 7 - Sample Title 7 00:45:54
-Sample Artist 8 - Sample Title 8 01:15:54 PRE DCP 4CH SCMS";
- var profile = new Importprofile()
+ var fileContent = new List
{
- UseRegularExpression = true,
- SchemeTracks = "(?'Artist'[a-zA-Z0-9_ .();äöü&:,]+) - (?'Title'[a-zA-Z0-9_ .();äöü]+)[\t ]+(?'End'[0-9]{2}:[0-9]{2}:[0-9]{2})(?:[\t ]+(?'Flags'[A-Za-z0-9 ,]+))?(?=[\t ]*(?:\r?\n|$))"
+ "Sample Artist 1 - Sample Title 1 00:05:00 DCP",
+ "Sample Artist 2 - Sample Title 2 00:09:23",
+ "Sample Artist 3 - Sample Title 3 00:15:54 PRE, DCP",
+ "Sample Artist 4 - Sample Title 4 00:20:13 4CH",
+ "Sample Artist 5 - Sample Title 5 00:24:54",
+ "Sample Artist 6 - Sample Title 6 00:31:54 PRE DCP 4CH",
+ "Sample Artist 7 - Sample Title 7 00:45:54",
+ "Sample Artist 8 - Sample Title 8 01:15:54 PRE DCP 4CH SCMS"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = null,
+ SchemeTracks = "(?'Artist'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Title'[a-zA-Z0-9_ .();äöü]{1,})\t{1,}(?'End'[0-9]{2}[:][0-9]{2}[:][0-9]{2})\t{1,}(?'Flags'[a-zA-Z 0-9,]{1,})"
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -380,31 +342,27 @@ public async Task AnalyseAsync_CuesheetWithFlags_CreatesValidCuesheetAsync()
}
[TestMethod()]
- public async Task AnalyseAsync_CuesheetWithPreGapAndPostGap_CreatesValidCuesheetAsync()
+ public void Analyse_CuesheetWithPreGapAndPostGap_CreatesValidCuesheet()
{
// Arrange
- var fileContent = @"Sample Artist 1 - Sample Title 1 00:00:02 00:05:00 00:00:00
-Sample Artist 2 - Sample Title 2 00:00:04 00:09:23 00:00:00
-Sample Artist 3 - Sample Title 3 00:00:00 00:15:54 00:00:02
-Sample Artist 4 - Sample Title 4 00:00:00 00:20:13 00:00:03
-Sample Artist 5 - Sample Title 5 00:00:00 00:24:54 00:00:04
-Sample Artist 6 - Sample Title 6 00:00:00 00:31:54 00:00:01
-Sample Artist 7 - Sample Title 7 00:00:00 00:45:54 00:00:00
-Sample Artist 8 - Sample Title 8 00:00:02 01:15:54 00:00:00";
- var profile = new Importprofile()
+ var fileContent = new List
{
- UseRegularExpression = true,
- SchemeTracks = "(?'Artist'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Title'[a-zA-Z0-9_ .();äöü]{1,})\t{1,}(?'PreGap'[0-9]{2}[:][0-9]{2}[:][0-9]{2})\t{1,}(?'End'[0-9]{2}[:][0-9]{2}[:][0-9]{2})\t{1,}(?'PostGap'[0-9]{2}[:][0-9]{2}[:][0-9]{2})"
+ "Sample Artist 1 - Sample Title 1 00:00:02 00:05:00 00:00:00",
+ "Sample Artist 2 - Sample Title 2 00:00:04 00:09:23 00:00:00",
+ "Sample Artist 3 - Sample Title 3 00:00:00 00:15:54 00:00:02",
+ "Sample Artist 4 - Sample Title 4 00:00:00 00:20:13 00:00:03",
+ "Sample Artist 5 - Sample Title 5 00:00:00 00:24:54 00:00:04",
+ "Sample Artist 6 - Sample Title 6 00:00:00 00:31:54 00:00:01",
+ "Sample Artist 7 - Sample Title 7 00:00:00 00:45:54 00:00:00",
+ "Sample Artist 8 - Sample Title 8 00:00:02 01:15:54 00:00:00"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = null,
+ SchemeTracks = "(?'Artist'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Title'[a-zA-Z0-9_ .();äöü]{1,})\t{1,}(?'PreGap'[0-9]{2}[:][0-9]{2}[:][0-9]{2})\t{1,}(?'End'[0-9]{2}[:][0-9]{2}[:][0-9]{2})\t{1,}(?'PostGap'[0-9]{2}[:][0-9]{2}[:][0-9]{2})"
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -428,76 +386,73 @@ public async Task AnalyseAsync_CuesheetWithPreGapAndPostGap_CreatesValidCuesheet
}
[TestMethod()]
- public async Task AnalyseAsync_SchemeCuesheetOnly_CreatesFileContentRecognizedOnlyForCuesheetAsync()
+ public void Analyse_SchemeCuesheetOnly_CreatesFileContentRecognizedOnlyForCuesheet()
{
// Arrange
- var fileContent = @"CuesheetArtist - CuesheetTitle c:\tmp\Testfile.mp3
-Sample Artist 1 - Sample Title 1 00:05:00
-Sample Artist 2 - Sample Title 2 00:09:23
-Sample Artist 3 - Sample Title 3 00:15:54
-Sample Artist 4 - Sample Title 4 00:20:13
-Sample Artist 5 - Sample Title 5 00:24:54
-Sample Artist 6 - Sample Title 6 00:31:54
-Sample Artist 7 - Sample Title 7 00:45:54
-Sample Artist 8 - Sample Title 8 01:15:54";
- var profile = new Importprofile()
+ var fileContent = new List
{
- SchemeCuesheet = $"{nameof(ImportCuesheet.Artist)} - {nameof(ImportCuesheet.Title)}\t{nameof(ImportCuesheet.Audiofile)}"
+ "CuesheetArtist - CuesheetTitle c:\\tmp\\Testfile.mp3",
+ "Sample Artist 1 - Sample Title 1 00:05:00",
+ "Sample Artist 2 - Sample Title 2 00:09:23",
+ "Sample Artist 3 - Sample Title 3 00:15:54",
+ "Sample Artist 4 - Sample Title 4 00:20:13",
+ "Sample Artist 5 - Sample Title 5 00:24:54",
+ "Sample Artist 6 - Sample Title 6 00:31:54",
+ "Sample Artist 7 - Sample Title 7 00:45:54",
+ "Sample Artist 8 - Sample Title 8 01:15:54"
};
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = profile
+ SchemeCuesheet = TextImportScheme.DefaultSchemeCuesheet,
+ SchemeTracks = null
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
Assert.IsNotNull(importfile.FileContentRecognized);
- var lines = importfile.FileContentRecognized.Split(Environment.NewLine);
Assert.AreEqual(string.Format("{0} - {1} {2}",
string.Format(CuesheetConstants.RecognizedMarkHTML, "CuesheetArtist"),
string.Format(CuesheetConstants.RecognizedMarkHTML, "CuesheetTitle"),
- string.Format(CuesheetConstants.RecognizedMarkHTML, "c:\\tmp\\Testfile.mp3")), lines.First());
+ string.Format(CuesheetConstants.RecognizedMarkHTML, "c:\\tmp\\Testfile.mp3")), importfile.FileContentRecognized.First());
Assert.AreEqual("CuesheetArtist", importfile.AnalysedCuesheet.Artist);
Assert.AreEqual("CuesheetTitle", importfile.AnalysedCuesheet.Title);
Assert.AreEqual("c:\\tmp\\Testfile.mp3", importfile.AnalysedCuesheet.Audiofile);
Assert.AreEqual(0, importfile.AnalysedCuesheet.Tracks.Count);
- Assert.AreEqual("Sample Artist 1 - Sample Title 1 00:05:00", lines.ElementAt(1));
- Assert.AreEqual("Sample Artist 2 - Sample Title 2 00:09:23", lines.ElementAt(2));
- Assert.AreEqual("Sample Artist 3 - Sample Title 3 00:15:54", lines.ElementAt(3));
- Assert.AreEqual("Sample Artist 4 - Sample Title 4 00:20:13", lines.ElementAt(4));
- Assert.AreEqual("Sample Artist 5 - Sample Title 5 00:24:54", lines.ElementAt(5));
- Assert.AreEqual("Sample Artist 6 - Sample Title 6 00:31:54", lines.ElementAt(6));
- Assert.AreEqual("Sample Artist 7 - Sample Title 7 00:45:54", lines.ElementAt(7));
- Assert.AreEqual("Sample Artist 8 - Sample Title 8 01:15:54", lines.ElementAt(8));
+ Assert.AreEqual("Sample Artist 1 - Sample Title 1 00:05:00", importfile.FileContentRecognized.ElementAt(1));
+ Assert.AreEqual("Sample Artist 2 - Sample Title 2 00:09:23", importfile.FileContentRecognized.ElementAt(2));
+ Assert.AreEqual("Sample Artist 3 - Sample Title 3 00:15:54", importfile.FileContentRecognized.ElementAt(3));
+ Assert.AreEqual("Sample Artist 4 - Sample Title 4 00:20:13", importfile.FileContentRecognized.ElementAt(4));
+ Assert.AreEqual("Sample Artist 5 - Sample Title 5 00:24:54", importfile.FileContentRecognized.ElementAt(5));
+ Assert.AreEqual("Sample Artist 6 - Sample Title 6 00:31:54", importfile.FileContentRecognized.ElementAt(6));
+ Assert.AreEqual("Sample Artist 7 - Sample Title 7 00:45:54", importfile.FileContentRecognized.ElementAt(7));
+ Assert.AreEqual("Sample Artist 8 - Sample Title 8 01:15:54", importfile.FileContentRecognized.ElementAt(8));
}
[TestMethod()]
- public async Task AnalyseAsync_CuesheetWithoutTracks_CreatesValidFileContentRecognizedAsync()
+ public void Analyse_CuesheetWithoutTracks_CreatesValidFileContentRecognized()
{
// Arrange
- var fileContent = @"CuesheetArtist - CuesheetTitle c:\tmp\Testfile.mp3
-Sample Artist 1 - Sample Title 1 00:05:00
-Sample Artist 2 - Sample Title 2 00:09:23
-Sample Artist 3 - Sample Title 3 00:15:54
-Sample Artist 4 - Sample Title 4 00:20:13
-Sample Artist 5 - Sample Title 5 00:24:54
-Sample Artist 6 - Sample Title 6 00:31:54
-Sample Artist 7 - Sample Title 7 00:45:54
-Sample Artist 8 - Sample Title 8 01:15:54";
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ var fileContent = new List
+ {
+ "CuesheetArtist - CuesheetTitle c:\\tmp\\Testfile.mp3",
+ "Sample Artist 1 - Sample Title 1 00:05:00",
+ "Sample Artist 2 - Sample Title 2 00:09:23",
+ "Sample Artist 3 - Sample Title 3 00:15:54",
+ "Sample Artist 4 - Sample Title 4 00:20:13",
+ "Sample Artist 5 - Sample Title 5 00:24:54",
+ "Sample Artist 6 - Sample Title 6 00:31:54",
+ "Sample Artist 7 - Sample Title 7 00:45:54",
+ "Sample Artist 8 - Sample Title 8 01:15:54"
+ };
+ var textImportScheme = new TextImportScheme()
{
- SelectedImportProfile = ApplicationOptions.DefaultSelectedImportprofile
+ SchemeCuesheet = TextImportScheme.DefaultSchemeCuesheet,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
@@ -506,225 +461,39 @@ public async Task AnalyseAsync_CuesheetWithoutTracks_CreatesValidFileContentReco
Assert.AreEqual("Sample Artist 1", importfile.AnalysedCuesheet.Tracks.ElementAt(0).Artist);
Assert.AreEqual("Sample Title 1", importfile.AnalysedCuesheet.Tracks.ElementAt(0).Title);
Assert.AreEqual(new TimeSpan(0, 5, 0), importfile.AnalysedCuesheet.Tracks.ElementAt(0).End);
- var lines = importfile.FileContentRecognized.Split(Environment.NewLine);
Assert.AreEqual(string.Format("{0} - {1} {2}",
string.Format(CuesheetConstants.RecognizedMarkHTML, "Sample Artist 8"),
string.Format(CuesheetConstants.RecognizedMarkHTML, "Sample Title 8"),
- string.Format(CuesheetConstants.RecognizedMarkHTML, "01:15:54")), lines.Last());
+ string.Format(CuesheetConstants.RecognizedMarkHTML, "01:15:54")), importfile.FileContentRecognized.Last());
}
[TestMethod()]
- public async Task AnalyseAsync_TextfileBug233_CreatesValidFileContentRecognizedAsync()
+ public void Analyse_TextfileBug233_CreatesValidFileContentRecognized()
{
// Arrange
- var profile = new Importprofile()
- {
- SchemeTracks = $"{nameof(ImportTrack.Artist)} - {nameof(ImportTrack.Title)}\t{nameof(ImportTrack.End)}"
- };
var textImportMemoryStream = new MemoryStream(Resources.Textimport_Bug__233);
- using var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
+ using var reader = new StreamReader(textImportMemoryStream);
+ List lines = [];
+ while (reader.EndOfStream == false)
{
- SelectedImportProfile = profile
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = null,
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
};
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
// Act
- var importfile = await service.AnalyseAsync(fileContent);
+ var importfile = TextImportService.Analyse(textImportScheme, fileContent);
// Assert
Assert.IsNull(importfile.AnalyseException);
Assert.IsNotNull(importfile.AnalysedCuesheet);
Assert.IsNotNull(importfile.FileContentRecognized);
- var lines = importfile.FileContentRecognized.Split(Environment.NewLine);
Assert.AreEqual(string.Format("{0} - {1}\t\t\t\t\t\t\t\t{2}",
string.Format(CuesheetConstants.RecognizedMarkHTML, "Age Of Love"),
string.Format(CuesheetConstants.RecognizedMarkHTML, "The Age Of Love (Charlotte De Witte & Enrico Sangiuliano Remix)"),
- string.Format(CuesheetConstants.RecognizedMarkHTML, "04:29:28")), lines.ElementAt(53));
- }
-
- [TestMethod()]
- public async Task AnalyseAsync_WithRegularExpression_ReturnsCuesheetAsync()
- {
- // Arrange
- var profile = new Importprofile()
- {
- UseRegularExpression = true,
- SchemeTracks = "\\s*| \\d+ | \\s*(?.*?) | \\s*(?.*?) | \\s*(?.*?) | \\s*
"
- };
- var textImportMemoryStream = new MemoryStream(Resources.Traktor_Export);
- var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
- {
- SelectedImportProfile = profile
- };
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
- // Act
- var importfile = await service.AnalyseAsync(fileContent);
- // Assert
- Assert.AreEqual(fileContent, importfile.FileContent);
- Assert.IsNull(importfile.AnalyseException);
- Assert.IsNotNull(importfile.AnalysedCuesheet);
- Assert.IsNull(importfile.AnalysedCuesheet.Artist);
- Assert.IsNull(importfile.AnalysedCuesheet.Title);
- Assert.AreEqual(41, importfile.AnalysedCuesheet.Tracks.Count);
- Assert.AreEqual("Nachap", importfile.AnalysedCuesheet.Tracks.First().Artist);
- Assert.AreEqual("Glass", importfile.AnalysedCuesheet.Tracks.First().Title);
- Assert.AreEqual(new DateTime(2025, 1, 29, 18, 52, 10), importfile.AnalysedCuesheet.Tracks.First().StartDateTime);
- Assert.AreEqual("Inache", importfile.AnalysedCuesheet.Tracks.Last().Artist);
- Assert.AreEqual("Andale (MONTA (TN) Remix)", importfile.AnalysedCuesheet.Tracks.Last().Title);
- Assert.AreEqual(new DateTime(2025, 1, 29, 22, 30, 3), importfile.AnalysedCuesheet.Tracks.Last().StartDateTime);
- Assert.IsNotNull(importfile.FileContentRecognized);
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "Sasha Fashion")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "2025/1/29 21:48:55")));
- }
-
- [TestMethod()]
- public async Task AnalyseAsync_WithoutRegularExpression_ReturnsCuesheetAsync()
- {
- // Arrange
- var profile = new Importprofile()
- {
- UseRegularExpression = false,
- SchemeCuesheet = "Artist - Title - Cataloguenumber",
- SchemeTracks = "Artist - Title\tBegin"
- };
- var textImportMemoryStream = new MemoryStream(Resources.Textimport_with_Cuesheetdata);
- var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
- {
- SelectedImportProfile = profile
- };
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
- // Act
- var importfile = await service.AnalyseAsync(fileContent);
- // Assert
- Assert.IsNull(importfile.AnalyseException);
- Assert.IsNotNull(importfile.AnalysedCuesheet);
- Assert.AreEqual("DJFreezeT", importfile.AnalysedCuesheet.Artist);
- Assert.AreEqual("Rabbit Hole Mix", importfile.AnalysedCuesheet.Title);
- Assert.AreEqual("0123456789123", importfile.AnalysedCuesheet.Cataloguenumber);
- Assert.AreEqual("Adriatique", importfile.AnalysedCuesheet.Tracks.First().Artist);
- Assert.AreEqual("X.", importfile.AnalysedCuesheet.Tracks.First().Title);
- Assert.AreEqual(new TimeSpan(0, 0, 5, 24, 250), importfile.AnalysedCuesheet.Tracks.First().Begin);
- Assert.AreEqual("Nikolay Kirov", importfile.AnalysedCuesheet.Tracks.Last().Artist);
- Assert.AreEqual("Chasing the Sun (Original Mix)", importfile.AnalysedCuesheet.Tracks.Last().Title);
- Assert.IsNull(importfile.AnalysedCuesheet.Tracks.Last().Begin);
- Assert.IsNotNull(importfile.FileContentRecognized);
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "DJFreezeT")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "Rabbit Hole Mix")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "0123456789123")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "Nikolay Kirov")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "Chasing the Sun (Original Mix)")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "SHDW & Obscure Shape")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "Wächter der Nacht (Original Mix)")));
- }
-
- [TestMethod()]
- public async Task AnalyseAsync_TextfileWithStartDateTime_CreatesValidCuesheetAsync()
- {
- // Arrange
- var fileContent = $@"Innellea~The Golden Fort~{new DateTime(2024, 8, 14, 20, 10, 48)}
-Nora En Pure~Diving with Whales (Daniel Portman Remix)~{new DateTime(2024, 8, 14, 20, 15, 21)}
-WhoMadeWho & Adriatique~Miracle (RÜFÜS DU SOL Remix)~{new DateTime(2024, 8, 14, 20, 20, 42)}
-Ella Wild~Poison D'araignee (Original Mix)~{new DateTime(2024, 8, 14, 20, 28, 03)}
-Stil & Bense~On The Edge (Original Mix)~{new DateTime(2024, 8, 14, 20, 32, 42)}
-Nebula~Clairvoyant Dreams~{new DateTime(2024, 8, 14, 20, 39, 1)}
-Valentina Black~I'm a Tree (Extended Mix)~{new DateTime(2024, 8, 14, 20, 47, 08)}
-Nebula~Clairvoyant Dreams~{new DateTime(2024, 8, 14, 20, 53, 20)}
-Kiko & Dave Davis feat. Phoebe~Living in Space (Dub Mix)~{new DateTime(2024, 8, 14, 20, 58, 11)}
-Lilly Palmer~Before Acid~{new DateTime(2024, 8, 14, 21, 03, 53)}
-Sofi Tukker~Drinkee (Vintage Culture & John Summit Extended Mix)~{new DateTime(2024, 8, 14, 21, 09, 52)}
-CID & Truth x Lies~Caroline (Extended Mix)~{new DateTime(2024, 8, 14, 21, 14, 09)}
-Moby~Why Does My Heart Feel So Bad? (Oxia Remix)~{new DateTime(2024, 8, 14, 21, 17, 15)}
-Ammo Avenue~Little Gurl (Extended Mix)~{new DateTime(2024, 8, 14, 21, 22, 46)}
-James Hurr & Smokin Jo & Stealth~Beggin' For Change~{new DateTime(2024, 8, 14, 21, 28, 37)}
-Kristine Blond~Love Shy (Sam Divine & CASSIMM Extended Remix)~{new DateTime(2024, 8, 14, 21, 30, 47)}
-Vanilla Ace~Work On You (Original Mix)~{new DateTime(2024, 8, 14, 21, 36, 28)}
-Truth X Lies~Like This~{new DateTime(2024, 8, 14, 21, 42, 05)}
-Terri-Anne~Round Round~{new DateTime(2024, 8, 14, 21, 44, 07)}
-Joanna Magik~Maneater~{new DateTime(2024, 8, 14, 21, 46, 32)}
-Jen Payne & Kevin McKay~Feed Your Soul~1{new DateTime(2024, 8, 14, 21, 48, 45)}
-Kevin McKay & Eppers & Notelle~On My Own~{new DateTime(2024, 8, 14, 21, 51, 37)}
-Nader Razdar & Kevin McKay~Get Ur Freak On (Kevin McKay Extended Mix)~{new DateTime(2024, 8, 14, 21, 53, 49)}
-Philip Z~Yala (Extended Mix)~{new DateTime(2024, 8, 14, 21, 59, 40)}
-Kyle Kinch & Kevin McKay~Hella~{new DateTime(2024, 8, 14, 22, 05, 53)}
-Roze Wild~B-O-D-Y~{new DateTime(2024, 8, 14, 22, 08, 26)}
-Jey Kurmis~Snoop~{new DateTime(2024, 8, 14, 22, 11, 09)}
-Bootie Brown & Tame Impala & Gorillaz~New Gold (Dom Dolla Remix Extended)~{new DateTime(2024, 8, 14, 22, 16, 23)}
-Eli Brown & Love Regenerator~Don't You Want Me (Original Mix)~{new DateTime(2024, 8, 14, 22, 21, 23)}
-Local Singles~Voices~{new DateTime(2024, 8, 14, 22, 25, 59)}";
-
- var profile = new Importprofile()
- {
- UseRegularExpression = false,
- SchemeTracks = $"{nameof(ImportTrack.Artist)}~{nameof(ImportTrack.Title)}~{nameof(ImportTrack.StartDateTime)}"
- };
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
- {
- SelectedImportProfile = profile
- };
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
- // Act
- var importfile = await service.AnalyseAsync(fileContent);
- // Assert
- Assert.IsNull(importfile.AnalyseException);
- Assert.IsNotNull(importfile.AnalysedCuesheet);
- Assert.AreEqual(30, importfile.AnalysedCuesheet.Tracks.Count);
- Assert.AreEqual("Innellea", importfile.AnalysedCuesheet.Tracks.ElementAt(0).Artist);
- Assert.AreEqual("The Golden Fort", importfile.AnalysedCuesheet.Tracks.ElementAt(0).Title);
- Assert.AreEqual(new DateTime(2024, 8, 14, 20, 10, 48), importfile.AnalysedCuesheet.Tracks.ElementAt(0).StartDateTime);
- Assert.AreEqual("Nora En Pure", importfile.AnalysedCuesheet.Tracks.ElementAt(1).Artist);
- Assert.AreEqual("Diving with Whales (Daniel Portman Remix)", importfile.AnalysedCuesheet.Tracks.ElementAt(1).Title);
- Assert.AreEqual(new DateTime(2024, 8, 14, 20, 15, 21), importfile.AnalysedCuesheet.Tracks.ElementAt(1).StartDateTime);
- Assert.AreEqual("Local Singles", importfile.AnalysedCuesheet.Tracks.ElementAt(29).Artist);
- Assert.AreEqual("Voices", importfile.AnalysedCuesheet.Tracks.ElementAt(29).Title);
- Assert.AreEqual(new DateTime(2024, 8, 14, 22, 25, 59), importfile.AnalysedCuesheet.Tracks.ElementAt(29).StartDateTime);
- }
-
- [TestMethod()]
- public async Task AnalyseAsync_WithCommonDataMatchingMultipleLines_SetsCommonDataOnceAsync()
- {
- // Arrange
- var profile = new Importprofile()
- {
- UseRegularExpression = false,
- SchemeCuesheet = "Artist - Title\tAudiofile",
- SchemeTracks = "Artist - Title\tBegin"
- };
- var textImportMemoryStream = new MemoryStream(Resources.Sample_Inputfile);
- var reader = new StreamReader(textImportMemoryStream);
- var fileContent = reader.ReadToEnd();
- var localStorageOptionsProviderMock = new Mock();
- var options = new ApplicationOptions
- {
- SelectedImportProfile = profile
- };
- localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
- var service = new TextImportService(localStorageOptionsProviderMock.Object);
- // Act
- var importfile = await service.AnalyseAsync(fileContent);
- // Assert
- Assert.IsNull(importfile.AnalyseException);
- Assert.IsNotNull(importfile.AnalysedCuesheet);
- Assert.AreEqual("CuesheetArtist", importfile.AnalysedCuesheet.Artist);
- Assert.AreEqual("CuesheetTitle", importfile.AnalysedCuesheet.Title);
- Assert.AreEqual("c:\\AudioFile.mp3", importfile.AnalysedCuesheet.Audiofile);
- Assert.AreEqual(8, importfile.AnalysedCuesheet.Tracks.Count);
- Assert.IsNotNull(importfile.FileContentRecognized);
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "CuesheetArtist")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "CuesheetTitle")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "c:\\AudioFile.mp3")));
- Assert.IsTrue(importfile.FileContentRecognized.Contains(String.Format(CuesheetConstants.RecognizedMarkHTML, "Sample Artist 8")));
+ string.Format(CuesheetConstants.RecognizedMarkHTML, "04:29:28")), importfile.FileContentRecognized.ElementAt(53));
}
}
}
\ No newline at end of file
diff --git a/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs b/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs
index 155ed70c..76c4e24b 100644
--- a/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs
+++ b/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs
@@ -13,13 +13,21 @@
//You should have received a copy of the GNU General Public License
//along with Foobar. If not, see
//.
+using AudioCuesheetEditor.Data.Options;
using AudioCuesheetEditor.Model.AudioCuesheet;
using AudioCuesheetEditor.Model.Entity;
+using AudioCuesheetEditor.Model.IO.Import;
+using AudioCuesheetEditor.Model.Options;
+using AudioCuesheetEditor.Model.Utility;
+using AudioCuesheetEditor.Services.IO;
using AudioCuesheetEditor.Services.UI;
+using AudioCuesheetEditor.Tests.Properties;
using AudioCuesheetEditor.Tests.Utility;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
namespace AudioCuesheetEditor.Tests.Services.UI
@@ -156,6 +164,115 @@ public void TrackListTest()
Assert.IsFalse(manager.CanRedo);
}
+ [TestMethod()]
+ public void Import_ValidTextfile_IsUndoable()
+ {
+ // Arrange
+ var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
+ var sessionStateContainer = new SessionStateContainer(traceChangeManager);
+ var textImportMemoryStream = new MemoryStream(Resources.Textimport_with_Cuesheetdata);
+ using var reader = new StreamReader(textImportMemoryStream);
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
+ var localStorageOptionsProviderMock = new Mock();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = "(?'Artist'\\A.*) - (?'Title'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Cataloguenumber'.{1,})",
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
+ };
+ var timeSpanFormat = new TimeSpanFormat();
+ var options = new ApplicationOptions();
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
+ // Act
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
+ // Assert
+ Assert.IsFalse(traceChangeManager.CanUndo);
+ Assert.IsFalse(traceChangeManager.CanRedo);
+ Assert.IsNotNull(sessionStateContainer.ImportCuesheet);
+ Assert.AreEqual("DJFreezeT", sessionStateContainer.ImportCuesheet.Artist);
+ Assert.AreEqual("0123456789123", sessionStateContainer.ImportCuesheet.Cataloguenumber);
+ Assert.AreNotEqual(0, sessionStateContainer.ImportCuesheet.Tracks.Count);
+ }
+
+ [TestMethod()]
+ public void UndoImport_ValidTextfile_ResetsToEmptyCuesheet()
+ {
+ // Arrange
+ var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
+ var sessionStateContainer = new SessionStateContainer(traceChangeManager);
+ var textImportMemoryStream = new MemoryStream(Resources.Textimport_with_Cuesheetdata);
+ using var reader = new StreamReader(textImportMemoryStream);
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
+ var localStorageOptionsProviderMock = new Mock();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = "(?'Artist'\\A.*) - (?'Title'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Cataloguenumber'.{1,})",
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
+ };
+ var timeSpanFormat = new TimeSpanFormat();
+ var options = new ApplicationOptions();
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
+ importManager.ImportCuesheet();
+ // Act
+ traceChangeManager.Undo();
+ // Assert
+ Assert.AreEqual(0, sessionStateContainer.Cuesheet.Tracks.Count);
+ Assert.IsTrue(string.IsNullOrEmpty(sessionStateContainer.Cuesheet.Artist));
+ Assert.IsTrue(string.IsNullOrEmpty(sessionStateContainer.Cuesheet.Cataloguenumber));
+ Assert.IsFalse(traceChangeManager.CanUndo);
+ Assert.IsTrue(traceChangeManager.CanRedo);
+ }
+
+ [TestMethod()]
+ public void UndoAndRedoImport_ValidTextfile_ResetsTextfileValues()
+ {
+ // Arrange
+ var testhelper = new TestHelper();
+ var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger());
+ var sessionStateContainer = new SessionStateContainer(traceChangeManager);
+ var textImportMemoryStream = new MemoryStream(Resources.Textimport_with_Cuesheetdata);
+ using var reader = new StreamReader(textImportMemoryStream);
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var fileContent = lines.AsReadOnly();
+ var localStorageOptionsProviderMock = new Mock();
+ var textImportScheme = new TextImportScheme()
+ {
+ SchemeCuesheet = "(?'Artist'\\A.*) - (?'Title'[a-zA-Z0-9_ .();äöü&:,]{1,}) - (?'Cataloguenumber'.{1,})",
+ SchemeTracks = TextImportScheme.DefaultSchemeTracks
+ };
+ var timeSpanFormat = new TimeSpanFormat();
+ var options = new ApplicationOptions();
+ localStorageOptionsProviderMock.Setup(x => x.GetOptionsAsync()).ReturnsAsync(options);
+ var fileInputManagerMock = new Mock();
+ var importManager = new ImportManager(sessionStateContainer, localStorageOptionsProviderMock.Object, traceChangeManager, fileInputManagerMock.Object);
+ importManager.ImportText(fileContent, textImportScheme, timeSpanFormat);
+ traceChangeManager.Undo();
+ // Act
+ traceChangeManager.Redo();
+ // Assert
+ Assert.AreEqual("DJFreezeT", sessionStateContainer.ImportCuesheet?.Artist);
+ Assert.AreEqual("0123456789123", sessionStateContainer.ImportCuesheet?.Cataloguenumber);
+ Assert.AreEqual(39, sessionStateContainer.ImportCuesheet?.Tracks.Count);
+ }
+
[TestMethod()]
public void RemoveTracksTest()
{
diff --git a/AudioCuesheetEditor/AudioCuesheetEditor.csproj b/AudioCuesheetEditor/AudioCuesheetEditor.csproj
index 0b8da88c..826022e8 100644
--- a/AudioCuesheetEditor/AudioCuesheetEditor.csproj
+++ b/AudioCuesheetEditor/AudioCuesheetEditor.csproj
@@ -20,7 +20,6 @@
-
diff --git a/AudioCuesheetEditor/Model/AudioCuesheet/CuesheetConstants.cs b/AudioCuesheetEditor/Model/AudioCuesheet/CuesheetConstants.cs
index f0121747..2994ab3d 100644
--- a/AudioCuesheetEditor/Model/AudioCuesheet/CuesheetConstants.cs
+++ b/AudioCuesheetEditor/Model/AudioCuesheet/CuesheetConstants.cs
@@ -31,7 +31,6 @@ public class CuesheetConstants
public static readonly String Tab = "\t";
public static readonly String CuesheetCDTextfile = "CDTEXTFILE";
public static readonly String CuesheetCatalogueNumber = "CATALOG";
- public static readonly String MarkHTMLStart = "";
- public static readonly String RecognizedMarkHTML = MarkHTMLStart + "{0}" + "";
+ public static readonly String RecognizedMarkHTML = "{0}";
}
}
diff --git a/AudioCuesheetEditor/Model/IO/FileExtensions.cs b/AudioCuesheetEditor/Model/IO/FileExtensions.cs
index 980f574d..439bf6df 100644
--- a/AudioCuesheetEditor/Model/IO/FileExtensions.cs
+++ b/AudioCuesheetEditor/Model/IO/FileExtensions.cs
@@ -21,6 +21,5 @@ public class FileExtensions
public const string Projectfile = ".ace";
public const string Cuesheet = ".cue";
public const string CDTextfile = ".cdt";
- public const string HTML = ".html";
}
}
diff --git a/AudioCuesheetEditor/Model/IO/FileMimeTypes.cs b/AudioCuesheetEditor/Model/IO/FileMimeTypes.cs
index 37483831..1dc3c20d 100644
--- a/AudioCuesheetEditor/Model/IO/FileMimeTypes.cs
+++ b/AudioCuesheetEditor/Model/IO/FileMimeTypes.cs
@@ -17,9 +17,9 @@ namespace AudioCuesheetEditor.Model.IO
{
public static class FileMimeTypes
{
- public const string TextPlain = "text/plain";
+ public const string Text = "text/plain";
public const string Projectfile = "application/x-ace";
public const string Cuesheet = "application/x-cue";
- public const string Text = "text/*";
+ public const string CDTextfile = "text/*";
}
}
diff --git a/AudioCuesheetEditor/Model/IO/Import/IImportfile.cs b/AudioCuesheetEditor/Model/IO/Import/IImportfile.cs
index a10f1d99..b99d07b0 100644
--- a/AudioCuesheetEditor/Model/IO/Import/IImportfile.cs
+++ b/AudioCuesheetEditor/Model/IO/Import/IImportfile.cs
@@ -21,15 +21,15 @@ namespace AudioCuesheetEditor.Model.IO.Import
public interface IImportfile
{
///
- /// File content
+ /// File content (each element is a file line)
///
- String? FileContent { get; set; }
+ IEnumerable? FileContent { get; set; }
///
/// File content with marking which passages has been reconized by scheme
///
- String? FileContentRecognized { get; set; }
+ IEnumerable? FileContentRecognized { get; set; }
///
- /// Exception that has been thrown while reading out the file
+ /// Exception that has been thrown while readinng out the file
///
Exception? AnalyseException { get; set; }
///
diff --git a/AudioCuesheetEditor/Model/IO/Import/Importfile.cs b/AudioCuesheetEditor/Model/IO/Import/Importfile.cs
index c0726e8e..033e1989 100644
--- a/AudioCuesheetEditor/Model/IO/Import/Importfile.cs
+++ b/AudioCuesheetEditor/Model/IO/Import/Importfile.cs
@@ -20,14 +20,14 @@ namespace AudioCuesheetEditor.Model.IO.Import
{
public class Importfile : IImportfile
{
+ ///
+ public IEnumerable? FileContent { get; set; }
+ ///
+ public IEnumerable? FileContentRecognized { get; set; }
///
public Exception? AnalyseException { get; set; }
///
public ImportCuesheet? AnalysedCuesheet { get; set; }
public ImportFileType FileType { get; set; }
- ///
- public string? FileContentRecognized { get; set; }
- ///
- public string? FileContent { get; set; }
}
}
diff --git a/AudioCuesheetEditor/Model/IO/Import/Importprofile.cs b/AudioCuesheetEditor/Model/IO/Import/TextImportScheme.cs
similarity index 76%
rename from AudioCuesheetEditor/Model/IO/Import/Importprofile.cs
rename to AudioCuesheetEditor/Model/IO/Import/TextImportScheme.cs
index b1f824c4..e63c3fce 100644
--- a/AudioCuesheetEditor/Model/IO/Import/Importprofile.cs
+++ b/AudioCuesheetEditor/Model/IO/Import/TextImportScheme.cs
@@ -16,26 +16,55 @@
using AudioCuesheetEditor.Model.AudioCuesheet;
using AudioCuesheetEditor.Model.AudioCuesheet.Import;
using AudioCuesheetEditor.Model.Entity;
-using AudioCuesheetEditor.Model.Utility;
namespace AudioCuesheetEditor.Model.IO.Import
{
- public class Importprofile : Validateable
+ public class TextImportScheme : Validateable
{
public static readonly IEnumerable AvailableSchemeCuesheet;
public static readonly IEnumerable AvailableSchemesTrack;
- static Importprofile()
+ static TextImportScheme()
{
AvailableSchemeCuesheet = [nameof(Cuesheet.Artist), nameof(Cuesheet.Title), nameof(Cuesheet.Audiofile), nameof(Cuesheet.CDTextfile), nameof(Cuesheet.Cataloguenumber)];
AvailableSchemesTrack = [nameof(Track.Artist), nameof(Track.Title), nameof(Track.Begin), nameof(Track.End), nameof(Track.Length), nameof(Track.Position), nameof(Track.Flags), nameof(Track.PreGap), nameof(Track.PostGap), nameof(ImportTrack.StartDateTime)];
}
- public Guid Id { get; init; } = Guid.NewGuid();
- public String? Name { get; set; }
- public Boolean UseRegularExpression { get; set; }
- public String? SchemeCuesheet { get; set; }
- public String? SchemeTracks { get; set; }
- public TimeSpanFormat? TimeSpanFormat { get; set; }
+
+ public static readonly String DefaultSchemeCuesheet = @"(?'Artist'\w*) - (?'Title'\w*)\t{1,}(?'Audiofile'.*)";
+ public static readonly String DefaultSchemeTracks = @"(?'Artist'.+?) - (?'Title'.+?)\s*\t+(?'End'.+)";
+
+ public static readonly TextImportScheme DefaultTextImportScheme = new()
+ {
+ SchemeCuesheet = DefaultSchemeCuesheet,
+ SchemeTracks = DefaultSchemeTracks
+ };
+
+ private string? schemeTracks;
+ private string? schemeCuesheet;
+
+ public event EventHandler? SchemeChanged;
+
+ public String? SchemeTracks
+ {
+ get { return schemeTracks; }
+ set
+ {
+ schemeTracks = value;
+ SchemeChanged?.Invoke(this, nameof(SchemeTracks));
+ OnValidateablePropertyChanged();
+ }
+ }
+
+ public String? SchemeCuesheet
+ {
+ get { return schemeCuesheet; }
+ set
+ {
+ schemeCuesheet = value;
+ SchemeChanged?.Invoke(this, nameof(SchemeCuesheet));
+ OnValidateablePropertyChanged();
+ }
+ }
public override ValidationResult Validate(string property)
{
ValidationStatus validationStatus = ValidationStatus.NoValidation;
diff --git a/AudioCuesheetEditor/Model/Options/ApplicationOptions.cs b/AudioCuesheetEditor/Model/Options/ApplicationOptions.cs
index db2d3fb3..97af692a 100644
--- a/AudioCuesheetEditor/Model/Options/ApplicationOptions.cs
+++ b/AudioCuesheetEditor/Model/Options/ApplicationOptions.cs
@@ -13,7 +13,6 @@
//You should have received a copy of the GNU General Public License
//along with Foobar. If not, see
//.
-using AudioCuesheetEditor.Model.AudioCuesheet.Import;
using AudioCuesheetEditor.Model.Entity;
using AudioCuesheetEditor.Model.IO;
using AudioCuesheetEditor.Model.IO.Export;
@@ -34,35 +33,6 @@ public enum ViewMode
public class ApplicationOptions : Validateable, IOptions
{
public const LogLevel DefaultLogLevel = LogLevel.Information;
- public static readonly Importprofile DefaultSelectedImportprofile = new()
- {
- Name = "Textfile (common data in first line)",
- UseRegularExpression = false,
- SchemeCuesheet = $"{nameof(ImportCuesheet.Artist)} - {nameof(ImportCuesheet.Title)}\t{nameof(ImportCuesheet.Audiofile)}",
- SchemeTracks = $"{nameof(ImportTrack.Artist)} - {nameof(ImportTrack.Title)}\t{nameof(ImportTrack.End)}"
- };
- public static readonly ICollection DefaultImportprofiles =
- [
- DefaultSelectedImportprofile,
- new()
- {
- Name = "Textfile (just track data)",
- UseRegularExpression = false,
- SchemeTracks = $"{nameof(ImportTrack.Artist)} - {nameof(ImportTrack.Title)}\t{nameof(ImportTrack.End)}"
- },
- new()
- {
- Name = "Textfile (track data seperated by ~)",
- UseRegularExpression = false,
- SchemeTracks = $"{nameof(ImportTrack.Artist)}~{nameof(ImportTrack.Title)}~{nameof(ImportTrack.StartDateTime)}"
- },
- new()
- {
- Name = "Traktor history",
- UseRegularExpression = true,
- SchemeTracks = @$"\s*| (?<{nameof(ImportTrack.Position)}>\d+) | \s*(?<{nameof(ImportTrack.Artist)}>.*?) | \s*(?<{nameof(ImportTrack.Title)}>.*?) | \s*(?<{nameof(ImportTrack.StartDateTime)}>.*?) | \s*
"
- }
- ];
private string? projectFilename = Projectfile.DefaultFilename;
private string? cuesheetFilename = Exportfile.DefaultCuesheetFilename;
public String? CuesheetFilename
@@ -132,29 +102,12 @@ public String? ProjectFilename
}
public TimeSpanFormat? TimeSpanFormat { get; set; }
public Boolean LinkTracks { get; set; } = true;
+ public TextImportScheme ImportScheme { get; set; } = TextImportScheme.DefaultTextImportScheme;
+ public TimeSpanFormat ImportTimeSpanFormat { get; set; } = new();
public uint RecordCountdownTimer { get; set; } = 5;
public Boolean FixedTracksTableHeader { get; set; } = false;
public String? DisplayTimeSpanFormat { get; set; }
public LogLevel MinimumLogLevel { get; set; } = DefaultLogLevel;
- [JsonInclude]
- public Guid? SelectedImportProfileId { get; private set; } = DefaultSelectedImportprofile.Id;
- public ICollection ImportProfiles { get; set; } = DefaultImportprofiles;
- [JsonIgnore]
- public Importprofile? SelectedImportProfile
- {
- get => SelectedImportProfileId.HasValue ? ImportProfiles.FirstOrDefault(x => x.Id == SelectedImportProfileId) : null;
- set
- {
- if (ImportProfiles.Any(x => x.Id == value?.Id) == false)
- {
- if (value != null)
- {
- ImportProfiles.Add(value);
- }
- }
- SelectedImportProfileId = value?.Id;
- }
- }
public override ValidationResult Validate(string property)
{
diff --git a/AudioCuesheetEditor/Model/Options/ExportOptions.cs b/AudioCuesheetEditor/Model/Options/ExportOptions.cs
index dfa267a2..eb36939b 100644
--- a/AudioCuesheetEditor/Model/Options/ExportOptions.cs
+++ b/AudioCuesheetEditor/Model/Options/ExportOptions.cs
@@ -67,17 +67,7 @@ public ExportOptions(ICollection exportProfiles, Guid? selectedPr
public Exportprofile? SelectedExportProfile
{
get => SelectedProfileId.HasValue ? ExportProfiles.FirstOrDefault(x => x.Id == SelectedProfileId) : null;
- set
- {
- if (ExportProfiles.Any(x => x.Id == value?.Id) == false)
- {
- if (value != null)
- {
- ExportProfiles.Add(value);
- }
- }
- SelectedProfileId = value?.Id;
- }
+ set => SelectedProfileId = value?.Id;
}
public Guid? SelectedProfileId { get; private set; }
}
diff --git a/AudioCuesheetEditor/Program.cs b/AudioCuesheetEditor/Program.cs
index 785f743c..a6a022fe 100644
--- a/AudioCuesheetEditor/Program.cs
+++ b/AudioCuesheetEditor/Program.cs
@@ -27,8 +27,10 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services;
+using System.ComponentModel.Design;
using System.Globalization;
using System.Reflection;
+using System.Reflection.Emit;
using Toolbelt.Blazor.Extensions.DependencyInjection;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
@@ -50,7 +52,7 @@
builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
-builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
diff --git a/AudioCuesheetEditor/Services/IO/CuesheetImportService.cs b/AudioCuesheetEditor/Services/IO/CuesheetImportService.cs
index 9f6af21d..47ad4494 100644
--- a/AudioCuesheetEditor/Services/IO/CuesheetImportService.cs
+++ b/AudioCuesheetEditor/Services/IO/CuesheetImportService.cs
@@ -16,18 +16,16 @@
using AudioCuesheetEditor.Model.AudioCuesheet;
using AudioCuesheetEditor.Model.AudioCuesheet.Import;
using AudioCuesheetEditor.Model.IO.Import;
-using System.Text;
using System.Text.RegularExpressions;
namespace AudioCuesheetEditor.Services.IO
{
public class CuesheetImportService
{
- public static IImportfile Analyse(string fileContent)
+ public static IImportfile Analyse(IEnumerable fileContent)
{
Importfile importfile = new()
{
- FileContent = fileContent,
FileType = ImportFileType.Cuesheet
};
try
@@ -57,9 +55,11 @@ public static IImportfile Analyse(string fileContent)
var regexCDTextfile = new Regex("^" + CuesheetConstants.CuesheetCDTextfile + " \"(?'" + cuesheetCDTextfileGroupName + "'.{0,})\"");
var regexCatalogueNumber = new Regex("^" + CuesheetConstants.CuesheetCatalogueNumber + " (?'" + cuesheetCatalogueNumberGroupName + "'.{0,})");
ImportTrack? track = null;
- StringBuilder recognizedContent = new();
- foreach (var line in fileContent.Split(Environment.NewLine))
+ List lines = [];
+ List? recognizedLines = [];
+ foreach (var line in fileContent)
{
+ lines.Add(line);
String? recognizedLine = line;
if (String.IsNullOrEmpty(line) == false)
{
@@ -277,9 +277,10 @@ public static IImportfile Analyse(string fileContent)
}
}
}
- recognizedContent.AppendLine(recognizedLine);
+ recognizedLines.Add(recognizedLine);
}
- importfile.FileContentRecognized = recognizedContent.ToString().TrimEnd(Environment.NewLine.ToCharArray());
+ importfile.FileContent = lines.AsReadOnly();
+ importfile.FileContentRecognized = recognizedLines.AsReadOnly();
}
catch (Exception ex)
{
diff --git a/AudioCuesheetEditor/Services/IO/FileInputManager.cs b/AudioCuesheetEditor/Services/IO/FileInputManager.cs
index 96129e13..d3ef5d12 100644
--- a/AudioCuesheetEditor/Services/IO/FileInputManager.cs
+++ b/AudioCuesheetEditor/Services/IO/FileInputManager.cs
@@ -27,7 +27,7 @@ public class FileInputManager(IJSRuntime jsRuntime, HttpClient httpClient, ILogg
private readonly HttpClient _httpClient = httpClient;
private readonly ILogger _logger = logger;
- public AudioCodec? GetAudioCodec(IBrowserFile browserFile)
+ public static AudioCodec? GetAudioCodec(IBrowserFile browserFile)
{
AudioCodec? foundAudioCodec = null;
var extension = Path.GetExtension(browserFile.Name);
@@ -37,7 +37,7 @@ public class FileInputManager(IJSRuntime jsRuntime, HttpClient httpClient, ILogg
{
foundAudioCodec = audioCodecsFound.FirstOrDefault();
}
- if (foundAudioCodec == null)
+ else
{
// Second search with mime type or file extension
audioCodecsFound = Audiofile.AudioCodecs.Where(x => x.MimeType.Equals(browserFile.ContentType, StringComparison.OrdinalIgnoreCase) || x.FileExtension.Equals(extension, StringComparison.OrdinalIgnoreCase));
@@ -46,35 +46,21 @@ public class FileInputManager(IJSRuntime jsRuntime, HttpClient httpClient, ILogg
return foundAudioCodec;
}
- public bool IsValidAudiofile(IBrowserFile browserFile)
+ public Boolean CheckFileMimeType(IBrowserFile file, String mimeType, String fileExtension)
{
- var codec = GetAudioCodec(browserFile);
- return codec != null;
- }
-
- public Boolean CheckFileMimeType(IBrowserFile file, String mimeType, IEnumerable fileExtensions)
- {
- _logger.LogDebug("CheckFileMimeType called with file: file.Name: '{FileName}', file.ContentType: '{ContentType}', mimeType: '{MimeType}', fileExtensions: '{fileExtensions}'", file.Name, file.ContentType, mimeType, fileExtensions);
+ _logger.LogDebug("CheckFileMimeType called with file: file.Name: '{FileName}', file.ContentType: '{ContentType}', mimeType: '{MimeType}', fileExtension: '{FileExtension}'", file.Name, file.ContentType, mimeType, fileExtension);
Boolean fileMimeTypeMatches = false;
- if ((file != null) && (String.IsNullOrEmpty(mimeType) == false))
+ if ((file != null) && (String.IsNullOrEmpty(mimeType) == false) && (String.IsNullOrEmpty(fileExtension) == false))
{
if (String.IsNullOrEmpty(file.ContentType) == false)
{
- if (mimeType.EndsWith("/*"))
- {
- var mainType = mimeType.Substring(0, mimeType.Length - 1);
- fileMimeTypeMatches = file.ContentType.StartsWith(mainType, StringComparison.CurrentCultureIgnoreCase);
- }
- else
- {
- fileMimeTypeMatches = file.ContentType.Equals(mimeType, StringComparison.CurrentCultureIgnoreCase);
- }
+ fileMimeTypeMatches = file.ContentType.Equals(mimeType, StringComparison.CurrentCultureIgnoreCase);
}
- if ((fileMimeTypeMatches == false) && (fileExtensions.Any()))
+ if (fileMimeTypeMatches == false)
{
//Try to find by file extension
var extension = Path.GetExtension(file.Name);
- fileMimeTypeMatches = fileExtensions.Any(x => x.Equals(extension, StringComparison.CurrentCultureIgnoreCase));
+ fileMimeTypeMatches = extension.Equals(fileExtension, StringComparison.CurrentCultureIgnoreCase);
}
}
return fileMimeTypeMatches;
@@ -115,7 +101,7 @@ public Boolean CheckFileMimeType(IBrowserFile file, String mimeType, IEnumerable
CDTextfile? cdTextfile = null;
if (browserFile != null)
{
- if (CheckFileMimeType(browserFile, FileMimeTypes.Text, [FileExtensions.CDTextfile]))
+ if (CheckFileMimeType(browserFile, FileMimeTypes.CDTextfile, FileExtensions.CDTextfile))
{
cdTextfile = new CDTextfile(browserFile.Name);
}
@@ -126,11 +112,5 @@ public Boolean CheckFileMimeType(IBrowserFile file, String mimeType, IEnumerable
}
return cdTextfile;
}
-
- ///
- public bool IsValidForImportView(IBrowserFile browserFile)
- {
- return CheckFileMimeType(browserFile, FileMimeTypes.Text, [FileExtensions.Text, FileExtensions.HTML]);
- }
}
}
diff --git a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs
index 6bf15fef..7a7326c8 100644
--- a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs
+++ b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs
@@ -22,16 +22,8 @@ namespace AudioCuesheetEditor.Services.IO
{
public interface IFileInputManager
{
- bool IsValidAudiofile(IBrowserFile browserFile);
- AudioCodec? GetAudioCodec(IBrowserFile browserFile);
- bool CheckFileMimeType(IBrowserFile file, string mimeType, IEnumerable fileExtensions);
+ bool CheckFileMimeType(IBrowserFile file, string mimeType, string fileExtension);
Task CreateAudiofileAsync(string? fileInputId, IBrowserFile? browserFile, Action>? afterContentStreamLoaded = null);
CDTextfile? CreateCDTextfile(IBrowserFile? browserFile);
- ///
- /// Checks if the file can be used for the import view
- ///
- ///
- ///
- bool IsValidForImportView(IBrowserFile browserFile);
}
}
\ No newline at end of file
diff --git a/AudioCuesheetEditor/Services/IO/ITextImportService.cs b/AudioCuesheetEditor/Services/IO/ITextImportService.cs
deleted file mode 100644
index 3f4f31a6..00000000
--- a/AudioCuesheetEditor/Services/IO/ITextImportService.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-//This file is part of AudioCuesheetEditor.
-
-//AudioCuesheetEditor is free software: you can redistribute it and/or modify
-//it under the terms of the GNU General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//AudioCuesheetEditor is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU General Public License for more details.
-
-//You should have received a copy of the GNU General Public License
-//along with Foobar. If not, see
-//.
-
-using AudioCuesheetEditor.Model.IO.Import;
-
-namespace AudioCuesheetEditor.Services.IO
-{
- public interface ITextImportService
- {
- Task AnalyseAsync(string fileContent);
- }
-}
\ No newline at end of file
diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs
index 729392cf..eef38039 100644
--- a/AudioCuesheetEditor/Services/IO/ImportManager.cs
+++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs
@@ -13,10 +13,14 @@
//You should have received a copy of the GNU General Public License
//along with Foobar. If not, see
//.
+using AudioCuesheetEditor.Data.Options;
using AudioCuesheetEditor.Model.AudioCuesheet;
using AudioCuesheetEditor.Model.AudioCuesheet.Import;
using AudioCuesheetEditor.Model.IO;
using AudioCuesheetEditor.Model.IO.Audio;
+using AudioCuesheetEditor.Model.IO.Import;
+using AudioCuesheetEditor.Model.Options;
+using AudioCuesheetEditor.Model.Utility;
using AudioCuesheetEditor.Services.UI;
using Microsoft.AspNetCore.Components.Forms;
@@ -30,20 +34,21 @@ public enum ImportFileType
Textfile,
Audiofile
}
- public class ImportManager(ISessionStateContainer sessionStateContainer, ITraceChangeManager traceChangeManager, IFileInputManager fileInputManager, ITextImportService textImportService)
+ public class ImportManager(ISessionStateContainer sessionStateContainer, ILocalStorageOptionsProvider localStorageOptionsProvider, ITraceChangeManager traceChangeManager, IFileInputManager fileInputManager)
{
private readonly ISessionStateContainer _sessionStateContainer = sessionStateContainer;
+ private readonly ILocalStorageOptionsProvider _localStorageOptionsProvider = localStorageOptionsProvider;
private readonly ITraceChangeManager _traceChangeManager = traceChangeManager;
private readonly IFileInputManager _fileInputManager = fileInputManager;
- private readonly ITextImportService _textImportService = textImportService;
public async Task> ImportFilesAsync(IEnumerable files)
{
Dictionary importFileTypes = [];
foreach (var file in files)
{
- if (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Projectfile, [FileExtensions.Projectfile]))
+ if (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Projectfile, FileExtensions.Projectfile))
{
+ //TODO: can not be undone
var fileContent = await ReadFileContentAsync(file);
var cuesheet = Projectfile.ImportFile(fileContent.ToArray());
if (cuesheet != null)
@@ -52,31 +57,40 @@ public async Task> ImportFilesAsync(IEn
}
importFileTypes.Add(file, ImportFileType.ProjectFile);
}
- if (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Cuesheet, [FileExtensions.Cuesheet]))
+ if (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Cuesheet, FileExtensions.Cuesheet))
{
var fileContent = await ReadFileContentAsync(file);
fileContent.Position = 0;
using var reader = new StreamReader(fileContent);
- var stringFileContent = reader.ReadToEnd();
- ImportCuesheet(stringFileContent);
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ ImportCuesheet(lines);
importFileTypes.Add(file, ImportFileType.Cuesheet);
}
- if (_fileInputManager.IsValidForImportView(file))
+ if (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Text, FileExtensions.Text))
{
var fileContent = await ReadFileContentAsync(file);
fileContent.Position = 0;
using var reader = new StreamReader(fileContent);
- var stringFileContent = reader.ReadToEnd();
- await ImportTextAsync(stringFileContent);
+ List lines = [];
+ while (reader.EndOfStream == false)
+ {
+ lines.Add(reader.ReadLine());
+ }
+ var options = await _localStorageOptionsProvider.GetOptionsAsync();
+ ImportText([.. lines], options.ImportScheme, options.ImportTimeSpanFormat);
importFileTypes.Add(file, ImportFileType.Textfile);
}
}
return importFileTypes;
}
- public async Task ImportTextAsync(string fileContent)
+ public void ImportText(IEnumerable fileContent, TextImportScheme textImportScheme, TimeSpanFormat timeSpanFormat)
{
- _sessionStateContainer.Importfile = await _textImportService.AnalyseAsync(fileContent);
+ _sessionStateContainer.Importfile = TextImportService.Analyse(textImportScheme, fileContent, timeSpanFormat);
if (_sessionStateContainer.Importfile.AnalysedCuesheet != null)
{
var importCuesheet = new Cuesheet();
@@ -96,7 +110,7 @@ public void ImportCuesheet()
_sessionStateContainer.ResetImport();
}
- private void ImportCuesheet(String fileContent)
+ private void ImportCuesheet(IEnumerable fileContent)
{
_sessionStateContainer.Importfile = CuesheetImportService.Analyse(fileContent);
if (_sessionStateContainer.Importfile.AnalysedCuesheet != null)
diff --git a/AudioCuesheetEditor/Services/IO/TextImportService.cs b/AudioCuesheetEditor/Services/IO/TextImportService.cs
index 92946a85..5d46e3c4 100644
--- a/AudioCuesheetEditor/Services/IO/TextImportService.cs
+++ b/AudioCuesheetEditor/Services/IO/TextImportService.cs
@@ -14,184 +14,120 @@
//along with Foobar. If not, see
//.
-using AudioCuesheetEditor.Data.Options;
using AudioCuesheetEditor.Model.AudioCuesheet;
using AudioCuesheetEditor.Model.AudioCuesheet.Import;
using AudioCuesheetEditor.Model.IO.Audio;
using AudioCuesheetEditor.Model.IO.Import;
-using AudioCuesheetEditor.Model.Options;
using AudioCuesheetEditor.Model.Utility;
using System.Reflection;
-using System.Text;
using System.Text.RegularExpressions;
namespace AudioCuesheetEditor.Services.IO
{
- public class TextImportService(ILocalStorageOptionsProvider localStorageOptionsProvider) : ITextImportService
+ public class TextImportService
{
- private readonly ILocalStorageOptionsProvider _localStorageOptionsProvider = localStorageOptionsProvider;
-
- public async Task AnalyseAsync(string fileContent)
+ public static IImportfile Analyse(TextImportScheme textImportScheme, IEnumerable fileContent, TimeSpanFormat? timeSpanFormat = null)
{
Importfile importfile = new()
{
- FileContent = fileContent,
- FileContentRecognized = fileContent,
- AnalysedCuesheet = new ImportCuesheet(),
FileType = ImportFileType.Textfile
};
try
{
- var options = await _localStorageOptionsProvider.GetOptionsAsync();
- var importprofile = options.SelectedImportProfile ?? throw new InvalidOperationException("Selected import profiles is not set!");
- SearchForCuesheetData(ref importfile, fileContent, importprofile);
- SearchForTrackData(ref importfile, fileContent, importprofile);
- }
- catch (Exception ex)
- {
- importfile.FileContentRecognized = fileContent;
- importfile.AnalyseException = ex;
- importfile.AnalysedCuesheet = null;
- }
- return importfile;
- }
-
- private static string ApplyRegexAndMarkGroups(object entity, Regex regex, string input, TimeSpanFormat? timeSpanFormat)
- {
- return regex.Replace(input, match =>
- {
- string result = match.Value;
- var groupInfos = new List<(int RelIndex, int Length, string Value, string Key)>();
- for (int matchCounter = 1; matchCounter < match.Groups.Count; matchCounter++)
- {
- var group = match.Groups[matchCounter];
- var key = regex.GroupNameFromNumber(matchCounter);
- if (!string.IsNullOrEmpty(key) && key != matchCounter.ToString())
- {
- var property = entity.GetType().GetProperty(key, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
- if (property != null)
- {
- SetValue(entity, property, group.Value, timeSpanFormat);
- }
- int relIndex = group.Index - match.Index;
- groupInfos.Add((relIndex, group.Length, group.Value, key));
- }
- }
- if (groupInfos.Count == 0)
- {
- return result;
- }
- groupInfos.Sort((a, b) => b.RelIndex.CompareTo(a.RelIndex));
- var sb = new StringBuilder(result);
- foreach (var (RelIndex, Length, Value, Key) in groupInfos)
- {
- sb.Remove(RelIndex, Length);
- sb.Insert(RelIndex, string.Format(CuesheetConstants.RecognizedMarkHTML, Value));
- }
- return sb.ToString();
- });
- }
-
- private static void SearchForCuesheetData(ref Importfile importfile, string fileContent, Importprofile importprofile)
- {
- if (string.IsNullOrWhiteSpace(importprofile.SchemeCuesheet) == false)
- {
- var cuesheet = importfile.AnalysedCuesheet;
- Regex regex;
- if (importprofile.UseRegularExpression == true)
+ importfile.FileContent = fileContent;
+ importfile.AnalysedCuesheet = new ImportCuesheet();
+ Boolean cuesheetRecognized = false;
+ List recognizedFileContent = [];
+ Regex? regExCuesheet = null, regExTracks = null;
+ if (String.IsNullOrEmpty(textImportScheme.SchemeCuesheet) == false)
{
- regex = new Regex(importprofile.SchemeCuesheet, RegexOptions.Multiline);
+ regExCuesheet = CreateCuesheetRegexPattern(textImportScheme.SchemeCuesheet);
}
- else
+ if (String.IsNullOrEmpty(textImportScheme.SchemeTracks) == false)
{
- regex = CreateCuesheetRegexPattern(importprofile.SchemeCuesheet);
+ regExTracks = CreateTrackRegexPattern(textImportScheme.SchemeTracks);
}
-
- if (importprofile.UseRegularExpression)
+ foreach (var line in fileContent)
{
- importfile.FileContentRecognized = ApplyRegexAndMarkGroups(cuesheet!, regex, fileContent, importprofile.TimeSpanFormat);
- }
- else
- {
- var sb = new StringBuilder();
- using (var reader = new StringReader(fileContent))
+ var recognizedLine = line;
+ if (String.IsNullOrEmpty(line) == false)
{
- string? line;
- while ((line = reader.ReadLine()) != null)
+ Boolean recognized = false;
+ if ((recognized == false) && (cuesheetRecognized == false) && (regExCuesheet != null))
{
- var markedLine = ApplyRegexAndMarkGroups(cuesheet!, regex, line, importprofile.TimeSpanFormat);
- sb.AppendLine(markedLine);
- if (!string.Equals(markedLine, line))
- {
- //We found the first occurence, break the loop
- //Attach the rest of the file to FileContentRecognized
- sb.Append(reader.ReadToEnd());
- break;
- }
+ recognizedLine = AnalyseLine(line, importfile.AnalysedCuesheet, regExCuesheet, timeSpanFormat);
+ recognized = recognizedLine != null;
+ cuesheetRecognized = recognizedLine != null;
+ }
+ if ((recognized == false) && (regExTracks != null))
+ {
+ var track = new ImportTrack();
+ recognizedLine = AnalyseLine(line, track, regExTracks, timeSpanFormat);
+ recognized = recognizedLine != null;
+ importfile.AnalysedCuesheet.Tracks.Add(track);
}
}
- importfile.FileContentRecognized = sb.ToString();
+ recognizedFileContent.Add(recognizedLine);
+ }
+ if (recognizedFileContent.Count > 0)
+ {
+ importfile.FileContentRecognized = recognizedFileContent.AsReadOnly();
}
}
+ catch (Exception ex)
+ {
+ importfile.FileContent = fileContent;
+ importfile.FileContentRecognized = fileContent;
+ importfile.AnalyseException = ex;
+ importfile.AnalysedCuesheet = null;
+ }
+ return importfile;
}
- private static void SearchForTrackData(ref Importfile importfile, string fileContent, Importprofile importprofile)
+ private static String? AnalyseLine(String line, object entity, Regex regex, TimeSpanFormat? timeSpanFormat)
{
- if (string.IsNullOrWhiteSpace(importprofile.SchemeTracks) == false)
+ String? recognized = null;
+ string? recognizedLine = line;
+ if (String.IsNullOrEmpty(line) == false)
{
- Regex regex;
- if (importprofile.UseRegularExpression == true)
- {
- regex = new Regex(importprofile.SchemeTracks, RegexOptions.Multiline);
- }
- else
- {
- regex = CreateTrackRegexPattern(importprofile.SchemeTracks);
- }
-
- var cuesheet = importfile.AnalysedCuesheet;
- importfile.FileContentRecognized ??= fileContent;
- if (importprofile.UseRegularExpression)
- {
-
- importfile.FileContentRecognized = regex.Replace(importfile.FileContentRecognized,
- match =>
- {
- var track = new ImportTrack();
- string marked = ApplyRegexAndMarkGroups(track, regex, match.Value, importprofile.TimeSpanFormat);
- cuesheet!.Tracks.Add(track);
- return marked;
- }
- );
- }
- else
+ var match = regex.Match(line);
+ if (match.Success)
{
- var sb = new StringBuilder();
- using (var reader = new StringReader(importfile.FileContentRecognized))
+ for (int groupCounter = 1; groupCounter < match.Groups.Count; groupCounter++)
{
- string? line;
- while ((line = reader.ReadLine()) != null)
+ var key = match.Groups.Keys.ElementAt(groupCounter);
+ var group = match.Groups.GetValueOrDefault(key);
+ if ((group != null) && (group.Success))
{
- // Check if this line is already analyzed
- if (line.Contains(CuesheetConstants.MarkHTMLStart) == false)
+ var property = entity.GetType().GetProperty(key, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ if (property != null)
{
- var track = new ImportTrack();
- var markedLine = ApplyRegexAndMarkGroups(track, regex, line, importprofile.TimeSpanFormat);
- if (!string.Equals(markedLine, line))
- {
- cuesheet!.Tracks.Add(track);
- }
- sb.AppendLine(markedLine);
+ SetValue(entity, property, group.Value, timeSpanFormat);
+ recognizedLine = string.Concat(recognizedLine.AsSpan(0, group.Index + (13 * (groupCounter - 1)))
+ , String.Format(CuesheetConstants.RecognizedMarkHTML, group.Value)
+ , recognizedLine.AsSpan(group.Index + (13 * (groupCounter - 1)) + group.Length));
}
else
{
- sb.AppendLine(line);
+ throw new NullReferenceException(String.Format("Property '{0}' was not found for line content {1}", key, line));
}
}
+ else
+ {
+ throw new NullReferenceException(String.Format("Group '{0}' could not be found!", key));
+ }
+ }
+ if (recognizedLine.Contains(CuesheetConstants.RecognizedMarkHTML.Substring(0, CuesheetConstants.RecognizedMarkHTML.IndexOf("{0}"))))
+ {
+ recognized = recognizedLine;
}
- importfile.FileContentRecognized = sb.ToString().TrimEnd(Environment.NewLine.ToCharArray());
+ }
+ else
+ {
+ recognized = line;
}
}
+ return recognized;
}
private static void SetValue(object entity, PropertyInfo property, string value, TimeSpanFormat? timeSpanFormat)
@@ -227,135 +163,57 @@ private static void SetValue(object entity, PropertyInfo property, string value,
private static Regex CreateCuesheetRegexPattern(string scheme)
{
- string[] fieldNames =
- [
- nameof(ImportCuesheet.Artist),
- nameof(ImportCuesheet.Title),
- nameof(ImportCuesheet.Audiofile),
- nameof(ImportCuesheet.CDTextfile),
- nameof(ImportCuesheet.Cataloguenumber)
- ];
- var parts = new List();
- int idx = 0;
- while (idx < scheme.Length)
+ var regex = new Regex(scheme);
+ var groupNames = regex.GetGroupNames();
+ //GroupNames always has a group "0", so we count for more than one group
+ if (groupNames.Any(x => x != "0"))
{
- var field = fieldNames.FirstOrDefault(fn => scheme.IndexOf(fn, idx, StringComparison.Ordinal) == idx);
- if (field != null)
- {
- parts.Add(field);
- idx += field.Length;
- }
- else
- {
- int nextFieldIdx = scheme.Length;
- foreach (var fn in fieldNames)
- {
- int pos = scheme.IndexOf(fn, idx, StringComparison.Ordinal);
- if (pos >= 0 && pos < nextFieldIdx)
- {
- nextFieldIdx = pos;
- }
- }
- string separator = scheme.Substring(idx, nextFieldIdx - idx);
- parts.Add(separator);
- idx = nextFieldIdx;
- }
+ return regex;
}
-
- var regexBuilder = new StringBuilder("^");
- for (int i = 0; i < parts.Count; i++)
+ else
{
- var part = parts[i];
- if (fieldNames.Contains(part))
- {
- bool isLast = i == parts.Count - 1 || parts.Skip(i + 1).All(p => !fieldNames.Contains(p));
- if (isLast)
- {
- regexBuilder.Append($@"(?<{part}>.+)");
- }
- else
- {
- regexBuilder.Append($@"(?<{part}>.+?)");
- }
- }
- else
- {
- string sep = Regex.Escape(part).Replace("\\t", @"\t{1,}");
- regexBuilder.Append(sep);
- }
- }
- regexBuilder.Append('$');
+ var regexString = Regex.Escape(scheme);
- return new Regex(regexBuilder.ToString());
+ regexString = regexString.Replace(nameof(Cuesheet.Artist), $"(?<{nameof(Cuesheet.Artist)}>.+)");
+ regexString = regexString.Replace(nameof(Cuesheet.Title), $"(?<{nameof(Cuesheet.Title)}>.+)");
+ regexString = regexString.Replace(nameof(Cuesheet.Audiofile), $"(?<{nameof(Cuesheet.Audiofile)}>.+)");
+ regexString = regexString.Replace(nameof(Cuesheet.CDTextfile), $"(?<{nameof(Cuesheet.CDTextfile)}>.+)");
+ regexString = regexString.Replace(nameof(Cuesheet.Cataloguenumber), $"(?<{nameof(Cuesheet.Cataloguenumber)}>.+)");
+ //Replace tab with non matching group
+ regexString = regexString.Replace("\\t", "(?:...\\t)");
+
+ return new Regex(regexString);
+ }
}
private static Regex CreateTrackRegexPattern(string scheme)
{
- string[] fieldNames =
- [
- nameof(ImportTrack.Artist),
- nameof(ImportTrack.Title),
- nameof(ImportTrack.Begin),
- nameof(ImportTrack.End),
- nameof(ImportTrack.Length),
- nameof(ImportTrack.Position),
- nameof(ImportTrack.Flags),
- nameof(ImportTrack.PreGap),
- nameof(ImportTrack.PostGap),
- nameof(ImportTrack.StartDateTime)
- ];
- var parts = new List();
- int idx = 0;
- while (idx < scheme.Length)
+ var regex = new Regex(scheme);
+ var groupNames = regex.GetGroupNames();
+ //GroupNames always has a group "0", so we count for more than one group
+ if (groupNames.Any(x => x != "0"))
{
- var field = fieldNames.FirstOrDefault(fn => scheme.IndexOf(fn, idx, StringComparison.Ordinal) == idx);
- if (field != null)
- {
- parts.Add(field);
- idx += field.Length;
- }
- else
- {
- int nextFieldIdx = scheme.Length;
- foreach (var fn in fieldNames)
- {
- int pos = scheme.IndexOf(fn, idx, StringComparison.Ordinal);
- if (pos >= 0 && pos < nextFieldIdx)
- {
- nextFieldIdx = pos;
- }
- }
- string separator = scheme.Substring(idx, nextFieldIdx - idx);
- parts.Add(separator);
- idx = nextFieldIdx;
- }
+ return regex;
}
-
- var regexBuilder = new StringBuilder("^");
- for (int i = 0; i < parts.Count; i++)
- {
- var part = parts[i];
- if (fieldNames.Contains(part))
- {
- bool isLast = i == parts.Count - 1 || parts.Skip(i + 1).All(p => !fieldNames.Contains(p));
- if (isLast)
- {
- regexBuilder.Append($@"(?<{part}>.+)");
- }
- else
- {
- regexBuilder.Append($@"(?<{part}>.+?)");
- }
- }
- else
- {
- string sep = Regex.Escape(part).Replace("\\t", @"\t{1,}");
- regexBuilder.Append(sep);
- }
+ else
+ {
+ var regexString = Regex.Escape(scheme);
+
+ regexString = regexString.Replace(nameof(ImportTrack.Artist), $"(?<{nameof(ImportTrack.Artist)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.Title), $"(?<{nameof(ImportTrack.Title)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.Begin), $"(?<{nameof(ImportTrack.Begin)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.End), $"(?<{nameof(ImportTrack.End)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.Length), $"(?<{nameof(ImportTrack.Length)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.Position), $"(?<{nameof(ImportTrack.Position)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.Flags), $"(?<{nameof(ImportTrack.Flags)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.PreGap), $"(?<{nameof(ImportTrack.PreGap)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.PostGap), $"(?<{nameof(ImportTrack.PostGap)}>.+)");
+ regexString = regexString.Replace(nameof(ImportTrack.StartDateTime), $"(?<{nameof(ImportTrack.StartDateTime)}>.+)");
+ //Replace tab with non matching group
+ regexString = regexString.Replace("\\t", "(?:...\\t)");
+
+ return new Regex(regexString);
}
- regexBuilder.Append('$');
-
- return new Regex(regexBuilder.ToString());
}
}
}
diff --git a/AudioCuesheetEditor/Shared/AppBar.razor b/AudioCuesheetEditor/Shared/AppBar.razor
index 522e2cf8..c4413df8 100644
--- a/AudioCuesheetEditor/Shared/AppBar.razor
+++ b/AudioCuesheetEditor/Shared/AppBar.razor
@@ -35,10 +35,10 @@ along with Foobar. If not, see
{
-
+
-
+
}
diff --git a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor b/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor
index 7f5d21f4..412434c1 100644
--- a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor
+++ b/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor
@@ -21,7 +21,6 @@ along with Foobar. If not, see
@inject ApplicationOptionsTimeSpanParser _applicationOptionsTimeSpanParser
@inject ValidationService _validationService
@inject IDialogService _dialogService
-@inject IFileInputManager _fileInputManager
@@ -129,9 +128,13 @@ along with Foobar. If not, see
void AudiofileSelected(CuesheetSection section, IBrowserFile? browserFile)
{
- if ((browserFile != null) && (_fileInputManager.IsValidAudiofile(browserFile) == true))
+ if (browserFile != null)
{
- section.AudiofileName = browserFile?.Name;
+ var codec = FileInputManager.GetAudioCodec(browserFile);
+ if (codec != null)
+ {
+ section.AudiofileName = browserFile?.Name;
+ }
}
else
{
diff --git a/AudioCuesheetEditor/Shared/Dialogs/SelectFileDialog.razor b/AudioCuesheetEditor/Shared/Dialogs/SelectFileDialog.razor
index 8198bb4f..68e64b89 100644
--- a/AudioCuesheetEditor/Shared/Dialogs/SelectFileDialog.razor
+++ b/AudioCuesheetEditor/Shared/Dialogs/SelectFileDialog.razor
@@ -51,8 +51,8 @@ along with Foobar. If not, see
invalidDropFileNames.Clear();
foreach (var file in files)
{
- if ((_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Projectfile, [FileExtensions.Projectfile]) == false)
- && (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Cuesheet, [FileExtensions.Cuesheet]) == false))
+ if ((_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Projectfile, FileExtensions.Projectfile) == false)
+ && (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Cuesheet, FileExtensions.Cuesheet) == false))
{
invalidDropFileNames.Add(file.Name);
}
diff --git a/AudioCuesheetEditor/Shared/Import/ImportFileContent.razor b/AudioCuesheetEditor/Shared/Import/ImportFileContent.razor
index c8c5c83a..d90881ca 100644
--- a/AudioCuesheetEditor/Shared/Import/ImportFileContent.razor
+++ b/AudioCuesheetEditor/Shared/Import/ImportFileContent.razor
@@ -21,34 +21,43 @@ along with Foobar. If not, see
@inject ISessionStateContainer _sessionStateContainer
-
-
-
- @if (FileContentRecognized != null)
- {
- @((MarkupString)SanitizeHTML(FileContentRecognized))
- }
-
-
-
-
-
-
+ @if (FileContentRecognized != null)
+ {
+
+
+
+ @foreach (var line in FileContentRecognized)
+ {
+ @((MarkupString)String.Format("{0}
", line))
+ }
+
+
+
+
+
+
+ }
@code {
[Parameter]
public EventCallback FileContentChanged { get; set; }
- public String? FileContentRecognized => _sessionStateContainer.Importfile?.FileContentRecognized;
-
- async Task FileContent_TextChangedAsync(string newFileContent)
+ public IEnumerable? FileContentRecognized => _sessionStateContainer.Importfile?.FileContentRecognized;
+ public String FileContent
{
- await FileContentChanged.InvokeAsync(newFileContent);
+ get
+ {
+ String fileContent = String.Empty;
+ if (_sessionStateContainer.Importfile?.FileContent != null)
+ {
+ fileContent = String.Join(Environment.NewLine, _sessionStateContainer.Importfile.FileContent);
+ }
+ return fileContent;
+ }
}
- string SanitizeHTML(string input)
+ async Task FileContent_TextChangedAsync(string newFileContent)
{
- var sanitizer = new HtmlSanitizer();
- return sanitizer.Sanitize(input);
+ await FileContentChanged.InvokeAsync(newFileContent);
}
}
diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.de.resx b/AudioCuesheetEditor/Shared/Import/ImportSchemes.de.resx
similarity index 82%
rename from AudioCuesheetEditor/Shared/Import/Importprofiles.de.resx
rename to AudioCuesheetEditor/Shared/Import/ImportSchemes.de.resx
index a7736980..1262de70 100644
--- a/AudioCuesheetEditor/Shared/Import/Importprofiles.de.resx
+++ b/AudioCuesheetEditor/Shared/Import/ImportSchemes.de.resx
@@ -117,8 +117,11 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- Möchten Sie wirklich die Importprofile auf Werkseinstellungen zurücksetzen?
+
+ Platzhalter hinzufügen
+
+
+ Möchten Sie wirklich die Importschemata auf Werkseinstellungen zurücksetzen?
Künstler
@@ -127,7 +130,7 @@
Audiodatei
- Beginn
+ Start
Katalognummer
@@ -144,26 +147,14 @@
Ende
-
- Geben Sie hier das Allgemeine Informationen Schema für das Profil an
-
-
- Geben Sie hier den Namen für das Profil an
-
-
- Geben Sie hier das Zeitformat für das Profil an
-
-
- Geben Sie hier das Titel Schema für das Profil an
-
Markierungen
Stunden
-
- Import Profil
+
+ Importschemata
Länge
@@ -174,12 +165,6 @@
Minuten
-
- Name
-
-
- Neues Importprofil
-
Position
@@ -189,24 +174,18 @@
Vorlücke
-
- Profil Name
-
-
- Schema Allgemeine Informationen
-
-
- Schema Titel
-
-
- Suche mit regulären Ausdrücken
-
Sekunden
Startzeitpunkt
+
+ Textimportschema Cuesheet
+
+
+ Textimportschema Titel
+
Zeitformat für den Import
diff --git a/AudioCuesheetEditor/Shared/Import/ImportSchemes.razor b/AudioCuesheetEditor/Shared/Import/ImportSchemes.razor
new file mode 100644
index 00000000..29de29ff
--- /dev/null
+++ b/AudioCuesheetEditor/Shared/Import/ImportSchemes.razor
@@ -0,0 +1,133 @@
+@using System.Linq.Expressions
+
+@inherits BaseLocalizedComponent
+
+@inject IStringLocalizer _localizer
+@inject ValidationService _validationService
+@inject IDialogService _dialogService
+
+
+ @_localizer["Import schemes"]
+
+
+
+
+
+ @foreach (var scheme in TextImportScheme.AvailableSchemeCuesheet)
+ {
+ @_localizer[scheme]
+ }
+
+
+
+
+
+ @foreach (var scheme in TextImportScheme.AvailableSchemesTrack)
+ {
+ @_localizer[scheme]
+ }
+
+
+
+
+
+ @foreach (var scheme in TimeSpanFormat.AvailableTimespanScheme)
+ {
+ @_localizer[scheme]
+ }
+
+
+
+@code {
+ [Parameter]
+ public EventCallback ImportSchemeCuesheetChanged { get; set; }
+
+ [Parameter]
+ public EventCallback ImportSchemeTracksChanged { get; set; }
+
+ [Parameter]
+ public EventCallback ImportTimeInputFormatChanged { get; set; }
+
+ MudTextField? importSchemeCuesheetTextField, importSchemeTracksTextField, importTimeInputFormatTextField;
+
+ void AppendPlaceholderToTextField(MudTextField? mudTextField, string placeholder)
+ {
+ mudTextField?.SetText($"{mudTextField.Text}{placeholder}");
+ }
+
+ async Task ImportSchemeCuesheetTextChangedAsync(string newScheme)
+ {
+ await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ImportScheme.SchemeCuesheet, newScheme);
+ await ImportSchemeCuesheetChanged.InvokeAsync(newScheme);
+ }
+
+ async Task ImportSchemeTracksTextChangedAsync(string newScheme)
+ {
+ await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ImportScheme.SchemeTracks, newScheme);
+ await ImportSchemeTracksChanged.InvokeAsync(newScheme);
+ }
+
+ async Task ImportTimeInputFormatChangedAsync(string newScheme)
+ {
+ await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ImportTimeSpanFormat.Scheme, newScheme);
+ await ImportTimeInputFormatChanged.InvokeAsync(newScheme);
+ }
+
+ String? GetValidationErrorMessage(object? model, string propertyName)
+ {
+ String? validationErrorMessage = null;
+ if (model != null)
+ {
+ var validationMessages = _validationService.Validate(model, propertyName);
+ if (validationMessages.Count() > 0)
+ {
+ validationErrorMessage = String.Join(Environment.NewLine, validationMessages);
+ }
+ }
+ return validationErrorMessage;
+ }
+
+ async Task ResetSchemes()
+ {
+ if (ApplicationOptions != null)
+ {
+ var parameters = new DialogParameters
+ {
+ { x => x.ConfirmText, _localizer["Are you sure you want to reset the import schemes to factory default?"] },
+ };
+ var dialog = await _dialogService.ShowAsync(_localizer["Confirm"], parameters);
+ var result = await dialog.Result;
+ if (result?.Canceled == false)
+ {
+ ApplicationOptions.ImportScheme = TextImportScheme.DefaultTextImportScheme;
+ ApplicationOptions.ImportTimeSpanFormat = new();
+ await LocalStorageOptionsProvider.SaveOptionsAsync(ApplicationOptions);
+ await ImportSchemeCuesheetChanged.InvokeAsync(ApplicationOptions.ImportScheme.SchemeCuesheet);
+ await ImportSchemeTracksChanged.InvokeAsync(ApplicationOptions.ImportScheme.SchemeTracks);
+ await ImportTimeInputFormatChanged.InvokeAsync(ApplicationOptions.ImportTimeSpanFormat.Scheme);
+ }
+ }
+ }
+}
diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.resx b/AudioCuesheetEditor/Shared/Import/ImportSchemes.resx
similarity index 83%
rename from AudioCuesheetEditor/Shared/Import/Importprofiles.resx
rename to AudioCuesheetEditor/Shared/Import/ImportSchemes.resx
index 5bd62cc2..e6597bc9 100644
--- a/AudioCuesheetEditor/Shared/Import/Importprofiles.resx
+++ b/AudioCuesheetEditor/Shared/Import/ImportSchemes.resx
@@ -117,8 +117,11 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- Are you sure you want to reset the import profiles to factory default?
+
+ Add placeholder
+
+
+ Are you sure you want to reset the import schemes to factory default?
Artist
@@ -144,26 +147,14 @@
End
-
- Enter the common data scheme for this profile here
-
-
- Enter the name for this profile here
-
-
- Enter the time format for this profile here
-
-
- Enter the track scheme for this profile here
-
Flags
Hours
-
- Import profile
+
+ Import schemes
Length
@@ -174,12 +165,6 @@
Minutes
-
- Name
-
-
- New import profile
-
Position
@@ -189,24 +174,18 @@
PreGap
-
- Profile name
-
-
- Scheme common data
-
-
- Scheme tracks
-
-
- Search using regular expressions
-
Seconds
StartDateTime
+
+ Textimport scheme cuesheet
+
+
+ Textimport scheme tracks
+
Time input format for import
diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor
deleted file mode 100644
index 9925e1c2..00000000
--- a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor
+++ /dev/null
@@ -1,200 +0,0 @@
-@using System.Linq.Expressions
-
-@inherits BaseLocalizedComponent
-
-@inject IStringLocalizer _localizer
-@inject ValidationService _validationService
-@inject IDialogService _dialogService
-
-@if (ApplicationOptions != null)
-{
-
-
- @foreach (var profile in ApplicationOptions.ImportProfiles)
- {
- @profile.Name
- }
-
-
-
-
-
-
-
-
-
-
-
-
- @foreach (var scheme in Importprofile.AvailableSchemeCuesheet)
- {
- @_localizer[scheme]
- }
-
-
-
-
-
- @foreach (var scheme in Importprofile.AvailableSchemesTrack)
- {
- @_localizer[scheme]
- }
-
-
-
-
-
- @foreach (var scheme in TimeSpanFormat.AvailableTimespanScheme)
- {
- @_localizer[scheme]
- }
-
-
-}
-
-@code {
- [Parameter]
- public EventCallback ImportprofileChanged { get; set; }
-
- MudTextField? schemeCuesheetTextField, schemeTracksTextField, timeSpanFormatTextField;
-
- void AppendPlaceholderToTextField(MudTextField? mudTextField, string placeholder)
- {
- mudTextField?.SetText($"{mudTextField.Text}{placeholder}");
- }
-
- async Task SelectedImportProfileChangedAsync(Importprofile? newSelectedProfile)
- {
- await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.SelectedImportProfile, newSelectedProfile);
- await ImportprofileChanged.InvokeAsync();
- }
-
- async Task UseRegularExpressionChangedAsync(Boolean? newValue)
- {
- await LocalStorageOptionsProvider.SaveNestedOptionValueAsync(x => x.SelectedImportProfile, x => x!.UseRegularExpression, newValue!.Value);
- await ImportprofileChanged.InvokeAsync();
- }
-
- async Task SchemeCuesheetChangedAsync(string newScheme)
- {
- await LocalStorageOptionsProvider.SaveNestedOptionValueAsync(x => x.SelectedImportProfile, x => x!.SchemeCuesheet, newScheme);
- await ImportprofileChanged.InvokeAsync();
- }
-
- async Task SchemeTracksChangedAsync(string newScheme)
- {
- await LocalStorageOptionsProvider.SaveNestedOptionValueAsync(x => x.SelectedImportProfile, x => x!.SchemeTracks, newScheme);
- await ImportprofileChanged.InvokeAsync();
- }
-
- async Task ImportTimeInputFormatChangedAsync(string newScheme)
- {
- var profile = ApplicationOptions?.SelectedImportProfile;
- if (profile != null)
- {
- TimeSpanFormat? format = null;
- if (string.IsNullOrEmpty(newScheme))
- {
- format = null;
- }
- else
- {
- format = new() { Scheme = newScheme };
- }
- await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.SelectedImportProfile!.TimeSpanFormat, format);
- await ImportprofileChanged.InvokeAsync();
- }
- }
-
- String? GetValidationErrorMessage(object? model, string propertyName)
- {
- String? validationErrorMessage = null;
- if (model != null)
- {
- var validationMessages = _validationService.Validate(model, propertyName);
- if (validationMessages.Count() > 0)
- {
- validationErrorMessage = String.Join(Environment.NewLine, validationMessages);
- }
- }
- return validationErrorMessage;
- }
-
- async Task ResetSchemes()
- {
- var parameters = new DialogParameters
- {
- { x => x.ConfirmText, _localizer["Are you sure you want to reset the import profiles to factory default?"] },
- };
- var dialog = await _dialogService.ShowAsync(_localizer["Confirm"], parameters);
- var result = await dialog.Result;
- if (result?.Canceled == false)
- {
- ApplicationOptions!.ImportProfiles = ApplicationOptions.DefaultImportprofiles;
- ApplicationOptions!.SelectedImportProfile = ApplicationOptions.DefaultSelectedImportprofile;
- await LocalStorageOptionsProvider.SaveOptionsAsync(ApplicationOptions);
- await ImportprofileChanged.InvokeAsync();
- }
- }
-
- async Task AddImportprofileClick()
- {
- var newProfilesNames = ApplicationOptions!.ImportProfiles.Where(x => x.Name?.StartsWith(_localizer["New import profile"]) == true).Select(x => x.Name);
- var regex = new System.Text.RegularExpressions.Regex(@"(\d+)$");
- int maxNumber = newProfilesNames
- .Select(name =>
- {
- var match = regex.Match(name ?? "");
- return match.Success ? int.Parse(match.Value) : 0;
- })
- .DefaultIfEmpty(0)
- .Max();
- var profile = new Importprofile()
- {
- Name = $"{_localizer["New import profile"]} {maxNumber + 1}"
- };
- ApplicationOptions!.SelectedImportProfile = profile;
- await LocalStorageOptionsProvider.SaveOptionsAsync(ApplicationOptions);
- await ImportprofileChanged.InvokeAsync();
- }
-
- async Task DeleteImportprofileClick()
- {
- var selectedProfile = ApplicationOptions?.SelectedImportProfile;
- if (selectedProfile != null)
- {
- ApplicationOptions!.ImportProfiles.Remove(selectedProfile);
- var lastProfile = ApplicationOptions.ImportProfiles.LastOrDefault();
- if (lastProfile != null)
- {
- ApplicationOptions!.SelectedImportProfile = lastProfile;
- }
- await LocalStorageOptionsProvider.SaveOptionsAsync(ApplicationOptions);
- }
- }
-}
diff --git a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor b/AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor
index 94f9b212..590b8275 100644
--- a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor
+++ b/AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor
@@ -29,7 +29,7 @@ along with Foobar. If not, see
-
+
@foreach (var invalidFileName in invalidDropFileNames)
{
@@ -54,7 +54,8 @@ along with Foobar. If not, see
invalidDropFileNames.Clear();
foreach (var file in files)
{
- if (_fileInputManager.IsValidForImportView(file) == false)
+ if ((_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Text, FileExtensions.Text) == false)
+ && (FileInputManager.GetAudioCodec(file) == null))
{
invalidDropFileNames.Add(file.Name);
}
@@ -76,7 +77,7 @@ along with Foobar. If not, see
// Audio file is handled seperatly
foreach (var file in files)
{
- var codec = _fileInputManager.GetAudioCodec(file);
+ var codec = FileInputManager.GetAudioCodec(file);
if (codec != null)
{
var audiofile = await _fileInputManager.CreateAudiofileAsync(dropFileInputId, file);
diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor
index 4404698a..470d5c84 100644
--- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor
+++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor
@@ -33,7 +33,7 @@ along with Foobar. If not, see
-
+
@if (_sessionStateContainer.Importfile?.AnalyseException != null)
{
@@ -68,17 +68,18 @@ along with Foobar. If not, see
Boolean fileContentExpanded = false, cuesheetDataExpanded = false, cuesheetTracksExpanded = false;
Boolean selectFilesStepCompleted = false, selectFilesStepError = false;
- async Task ImportFileContent_FileContentChanged(string newFileContent)
+ void ImportFileContent_FileContentChanged(string newFileContent)
{
- await _importManager.ImportTextAsync(newFileContent);
+ var textToAnalyse = newFileContent.Split(Environment.NewLine);
+ _importManager.ImportText(textToAnalyse, ApplicationOptions!.ImportScheme, ApplicationOptions!.ImportTimeSpanFormat);
}
- async Task ReanalyseImportfile()
+ void ReanalyseImportfile()
{
var fileContent = _sessionStateContainer.Importfile?.FileContent;
if (fileContent != null)
{
- await _importManager.ImportTextAsync(fileContent);
+ _importManager.ImportText(fileContent, ApplicationOptions!.ImportScheme, ApplicationOptions.ImportTimeSpanFormat);
}
}
diff --git a/AudioCuesheetEditor/_Imports.razor b/AudioCuesheetEditor/_Imports.razor
index 4dd0e275..4cd9df9e 100644
--- a/AudioCuesheetEditor/_Imports.razor
+++ b/AudioCuesheetEditor/_Imports.razor
@@ -43,5 +43,4 @@
@using Howler.Blazor.Components
@using Markdig
@using Toolbelt.Blazor.HotKeys2
-@using MudBlazor
-@using Ganss.Xss
\ No newline at end of file
+@using MudBlazor
\ No newline at end of file