Compare commits

...

1 Commits

Author SHA1 Message Date
rlauu
35cbf57f41 Add button to recreate db 2024-11-25 16:05:50 +01:00
3 changed files with 74 additions and 19 deletions

View File

@ -714,6 +714,9 @@
<input type="checkbox" id="eraseModeCacheCheckbox" style="margin-left: 10px" /> <input type="checkbox" id="eraseModeCacheCheckbox" style="margin-left: 10px" />
<label for="eraseModeCacheCheckbox" style="margin-left: 5px">Erase global cached fingerprint files</label> <label for="eraseModeCacheCheckbox" style="margin-left: 5px">Erase global cached fingerprint files</label>
</div> </div>
<div>
<button is="emby-button" class="button-submit emby-button" id="btnRebuildDatabase">Rebuild database</button>
</div>
</div> </div>
<br /> <br />
<br /> <br />
@ -758,6 +761,7 @@
var btnEraseRecapTimestamps = document.querySelector("button#btnEraseRecapTimestamps"); var btnEraseRecapTimestamps = document.querySelector("button#btnEraseRecapTimestamps");
var btnEraseCreditTimestamps = document.querySelector("button#btnEraseCreditTimestamps"); var btnEraseCreditTimestamps = document.querySelector("button#btnEraseCreditTimestamps");
var btnErasePreviewTimestamps = document.querySelector("button#btnErasePreviewTimestamps"); var btnErasePreviewTimestamps = document.querySelector("button#btnErasePreviewTimestamps");
var btnRebuildDatabase = document.querySelector("button#btnRebuildDatabase");
// all plugin configuration fields that can be get or set with .value (i.e. strings or numbers). // all plugin configuration fields that can be get or set with .value (i.e. strings or numbers).
var configurationFields = [ var configurationFields = [
@ -1504,6 +1508,9 @@
eraseTimestamps("Preview"); eraseTimestamps("Preview");
e.preventDefault(); e.preventDefault();
}); });
btnRebuildDatabase.addEventListener("click", () => {
fetchWithAuth("Intros/RebuildDatabase", "POST", null);
});
btnSeasonEraseTimestamps.addEventListener("click", () => { btnSeasonEraseTimestamps.addEventListener("click", () => {
Dashboard.confirm("Are you sure you want to erase all timestamps for this season?", "Confirm timestamp erasure", (result) => { Dashboard.confirm("Are you sure you want to erase all timestamps for this season?", "Confirm timestamp erasure", (result) => {
if (!result) { if (!result) {

View File

@ -251,6 +251,20 @@ public class SkipIntroController(MediaSegmentUpdateManager mediaSegmentUpdateMan
return NoContent(); return NoContent();
} }
/// <summary>
/// Rebuilds the database.
/// </summary>
/// <response code="204">Database rebuilt.</response>
/// <returns>No content.</returns>
[Authorize(Policy = Policies.RequiresElevation)]
[HttpPost("Intros/RebuildDatabase")]
public ActionResult RebuildDatabase()
{
using var db = new IntroSkipperDbContext(Plugin.Instance!.DbPath);
db.RebuildDatabase();
return NoContent();
}
/// <summary> /// <summary>
/// Gets the user interface configuration. /// Gets the user interface configuration.
/// </summary> /// </summary>

View File

@ -109,22 +109,52 @@ public class IntroSkipperDbContext : DbContext
/// </summary> /// </summary>
public void ApplyMigrations() public void ApplyMigrations()
{ {
// If migrations table exists, just apply pending migrations normally // If database doesn't exist or can't connect, create it with migrations
if (Database.GetAppliedMigrations().Any() || !Database.CanConnect()) if (!Database.CanConnect())
{
Database.Migrate();
return;
}
// If migrations table exists, apply pending migrations normally
if (Database.GetAppliedMigrations().Any())
{ {
Database.Migrate(); Database.Migrate();
return; return;
} }
// For databases without migration history // For databases without migration history
try RebuildDatabase();
}
/// <summary>
/// Rebuilds the database while preserving valid segments and season information.
/// </summary>
public void RebuildDatabase()
{ {
// Backup existing data // Backup existing data
List<DbSegment> segments; List<DbSegment> segments = [];
List<DbSeasonInfo> seasonInfos = [];
using (var db = new IntroSkipperDbContext(_dbPath)) using (var db = new IntroSkipperDbContext(_dbPath))
{
try
{ {
segments = [.. db.DbSegment.AsEnumerable().Where(s => s.ToSegment().Valid)]; segments = [.. db.DbSegment.AsEnumerable().Where(s => s.ToSegment().Valid)];
} }
catch (Exception ex)
{
throw new InvalidOperationException("Failed to read DbSegment data", ex);
}
try
{
seasonInfos = [.. db.DbSeasonInfo];
}
catch (Exception ex)
{
throw new InvalidOperationException("Failed to read DbSeasonInfo data", ex);
}
}
// Delete old database // Delete old database
Database.EnsureDeleted(); Database.EnsureDeleted();
@ -134,14 +164,18 @@ public class IntroSkipperDbContext : DbContext
// Restore the data // Restore the data
using (var db = new IntroSkipperDbContext(_dbPath)) using (var db = new IntroSkipperDbContext(_dbPath))
{
if (segments.Count > 0)
{ {
db.DbSegment.AddRange(segments); db.DbSegment.AddRange(segments);
}
if (seasonInfos.Count > 0)
{
db.DbSeasonInfo.AddRange(seasonInfos);
}
db.SaveChanges(); db.SaveChanges();
} }
} }
catch (Exception ex)
{
throw new InvalidOperationException("Failed to apply migrations", ex);
}
}
} }