Compare commits
No commits in common. "6f920f3f0d5eec35bb8b73dbc9fd2d280761090a" and "fab306c3933ecf61b2eff7bd85ddd704beb789d3" have entirely different histories.
6f920f3f0d
...
fab306c393
8 changed files with 1 additions and 420 deletions
|
|
@ -18,53 +18,6 @@ public class DataContext : DbContext
|
||||||
modelBuilder.Entity<Playlist>()
|
modelBuilder.Entity<Playlist>()
|
||||||
.Navigation(e => e.videos).AutoInclude();
|
.Navigation(e => e.videos).AutoInclude();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int SaveChanges()
|
|
||||||
{
|
|
||||||
TrackChanges();
|
|
||||||
return base.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task<int> SaveChangesAsync(CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
TrackChanges();
|
|
||||||
return await base.SaveChangesAsync(ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TrackChanges()
|
|
||||||
{
|
|
||||||
var changedEntries = ChangeTracker.Entries()
|
|
||||||
.Where(e => e.State == EntityState.Added ||
|
|
||||||
e.State == EntityState.Modified ||
|
|
||||||
e.State == EntityState.Deleted)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
foreach (var entry in changedEntries)
|
|
||||||
{
|
|
||||||
var log = new ChangeLog
|
|
||||||
{
|
|
||||||
TableName = entry.Metadata.GetTableName() ?? entry.Entity.GetType().Name,
|
|
||||||
ChangeType = entry.State.ToString(),
|
|
||||||
ChangeTime = DateTime.UtcNow
|
|
||||||
};
|
|
||||||
|
|
||||||
ChangeLogs.Add(log);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChangeLog? GetLatestChange()
|
|
||||||
{
|
|
||||||
return ChangeLogs
|
|
||||||
.OrderByDescending(cl => cl.ChangeTime)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ChangeLog?> GetLatestChangeAsync(CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
return await ChangeLogs
|
|
||||||
.OrderByDescending(cl => cl.ChangeTime)
|
|
||||||
.FirstOrDefaultAsync(ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbSet<History> Histories { get; set; }
|
public DbSet<History> Histories { get; set; }
|
||||||
public DbSet<Playlist> Playlists { get; set; }
|
public DbSet<Playlist> Playlists { get; set; }
|
||||||
|
|
@ -73,5 +26,4 @@ public class DataContext : DbContext
|
||||||
public DbSet<Setting> Settings { get; set; }
|
public DbSet<Setting> Settings { get; set; }
|
||||||
public DbSet<Subscription> Subscriptions { get; set; }
|
public DbSet<Subscription> Subscriptions { get; set; }
|
||||||
public DbSet<Video> Videos { get; set; }
|
public DbSet<Video> Videos { get; set; }
|
||||||
public DbSet<ChangeLog> ChangeLogs { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
using FreeTubeSync.Database;
|
|
||||||
using FreeTubeSync.Model.Database;
|
|
||||||
|
|
||||||
namespace FreeTubeSync.EndPoints;
|
|
||||||
|
|
||||||
public static class PingEndpoint
|
|
||||||
{
|
|
||||||
public static void MapPingEndpoints(this WebApplication app)
|
|
||||||
{
|
|
||||||
var group = app.MapGroup("ping");
|
|
||||||
group.MapGet("/", async (CancellationToken token) =>
|
|
||||||
{
|
|
||||||
await Task.Delay(10);
|
|
||||||
var dict = new { AppVersion = "0.1.3" };
|
|
||||||
return Results.Ok(dict);
|
|
||||||
});
|
|
||||||
|
|
||||||
group.MapGet("/lastUpdated", async (DataContext dbContext, CancellationToken token) =>
|
|
||||||
{
|
|
||||||
var log = await dbContext.GetLatestChangeAsync(token);
|
|
||||||
|
|
||||||
if (log == null)
|
|
||||||
return Results.NotFound();
|
|
||||||
|
|
||||||
var dict = new { LastUpdated = log.ChangeTime };
|
|
||||||
return Results.Ok(dict);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -51,10 +51,7 @@ public static class ProfileEndpoint
|
||||||
if (f == null)
|
if (f == null)
|
||||||
notFound.Add(subscription);
|
notFound.Add(subscription);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
subscription.MapFrom(f);
|
subscription.MapFrom(f);
|
||||||
await subRepo.UpdateAsync(subscription, ct, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var newSubs = (from subscription in profileJson.subscriptions let f = res.subscriptions.FirstOrDefault(s => s.id == subscription.id) where f == null select subscription).ToList();
|
var newSubs = (from subscription in profileJson.subscriptions let f = res.subscriptions.FirstOrDefault(s => s.id == subscription.id) where f == null select subscription).ToList();
|
||||||
|
|
||||||
|
|
@ -75,7 +72,7 @@ public static class ProfileEndpoint
|
||||||
{
|
{
|
||||||
res.subscriptions.Remove(nfSub);
|
res.subscriptions.Remove(nfSub);
|
||||||
}
|
}
|
||||||
|
|
||||||
await repository.UpdateAsync(res, ct);
|
await repository.UpdateAsync(res, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,269 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using FreeTubeSync.Database;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace FreeTubeSync.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(DataContext))]
|
|
||||||
[Migration("20250731174538_AddChangeLogTracking")]
|
|
||||||
partial class AddChangeLogTracking
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.7");
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.ChangeLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<DateTime>("ChangeTime")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("ChangeType")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("TableName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("ChangeLogs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.History", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("_id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("author")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("authorId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("description")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<bool>("isLive")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("lastViewedPlaylistItemId")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("lastViewedPlaylistType")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<long>("lengthSeconds")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<long>("published")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<long>("timeWatched")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("videoId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<long>("viewCount")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<float>("watchProgress")
|
|
||||||
.HasColumnType("REAL");
|
|
||||||
|
|
||||||
b.HasKey("_id");
|
|
||||||
|
|
||||||
b.ToTable("Histories");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Playlist", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("_id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<long>("createdAt")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<long>("lastUpdatedAt")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("playlistName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<bool>("protected")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.HasKey("_id");
|
|
||||||
|
|
||||||
b.ToTable("Playlists");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Profile", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("_id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("bgColor")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("textColor")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("_id");
|
|
||||||
|
|
||||||
b.ToTable("Profiles");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.SearchHistory", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("_id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<long>("lastUpdatedAt")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.HasKey("_id");
|
|
||||||
|
|
||||||
b.ToTable("SearchHistories");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Setting", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("_id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("value")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("_id");
|
|
||||||
|
|
||||||
b.ToTable("Settings");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Subscription", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("Profile_id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("thumbnail")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("id");
|
|
||||||
|
|
||||||
b.HasIndex("Profile_id");
|
|
||||||
|
|
||||||
b.ToTable("Subscriptions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Video", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("playlistItemId")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("Playlist_id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("author")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("authorId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("lengthSeconds")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<long>("pubished")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<long>("timeAdded")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("title")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("type")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("videoId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("playlistItemId");
|
|
||||||
|
|
||||||
b.HasIndex("Playlist_id");
|
|
||||||
|
|
||||||
b.ToTable("Videos");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Subscription", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("FreeTubeSync.Model.Database.Profile", null)
|
|
||||||
.WithMany("subscriptions")
|
|
||||||
.HasForeignKey("Profile_id");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Video", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("FreeTubeSync.Model.Database.Playlist", null)
|
|
||||||
.WithMany("videos")
|
|
||||||
.HasForeignKey("Playlist_id");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Playlist", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("videos");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.Profile", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("subscriptions");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace FreeTubeSync.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class AddChangeLogTracking : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "ChangeLogs",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
|
||||||
.Annotation("Sqlite:Autoincrement", true),
|
|
||||||
TableName = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
ChangeType = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
ChangeTime = table.Column<DateTime>(type: "TEXT", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_ChangeLogs", x => x.Id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "ChangeLogs");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
using System;
|
|
||||||
using FreeTubeSync.Database;
|
using FreeTubeSync.Database;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
@ -17,28 +16,6 @@ namespace FreeTubeSync.Migrations
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.7");
|
modelBuilder.HasAnnotation("ProductVersion", "9.0.7");
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.ChangeLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<DateTime>("ChangeTime")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("ChangeType")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("TableName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("ChangeLogs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("FreeTubeSync.Model.Database.History", b =>
|
modelBuilder.Entity("FreeTubeSync.Model.Database.History", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("_id")
|
b.Property<string>("_id")
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
namespace FreeTubeSync.Model.Database;
|
|
||||||
|
|
||||||
public class ChangeLog
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string TableName { get; set; } = string.Empty;
|
|
||||||
public string ChangeType { get; set; } = string.Empty;
|
|
||||||
public DateTime ChangeTime { get; set; } = DateTime.MinValue;
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,6 @@ app.MapPlaylistEndpoints();
|
||||||
app.MapProfileEndpoints();
|
app.MapProfileEndpoints();
|
||||||
app.MapSearchHistoryEndpoints();
|
app.MapSearchHistoryEndpoints();
|
||||||
app.MapSettingEndpoints();
|
app.MapSettingEndpoints();
|
||||||
app.MapPingEndpoints();
|
|
||||||
|
|
||||||
await using(var serviceScope = app.Services.CreateAsyncScope())
|
await using(var serviceScope = app.Services.CreateAsyncScope())
|
||||||
await using (var dbContext = serviceScope.ServiceProvider.GetRequiredService<DataContext>())
|
await using (var dbContext = serviceScope.ServiceProvider.GetRequiredService<DataContext>())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue