Initial Commit
Inital Commit of Code base, nothing tested.
This commit is contained in:
commit
0144221712
31 changed files with 1304 additions and 0 deletions
25
.dockerignore
Normal file
25
.dockerignore
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/.idea
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
.idea/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
FreeTubeSync.db
|
||||
21
FreeTubeSync.sln
Normal file
21
FreeTubeSync.sln
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeTubeSync", "FreeTubeSync\FreeTubeSync.csproj", "{E55FECEB-2D88-4FD4-90BF-713EB30D60BB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{47A66AFA-4FD3-40F3-ADE0-27EE0527211B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
compose.yaml = compose.yaml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E55FECEB-2D88-4FD4-90BF-713EB30D60BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E55FECEB-2D88-4FD4-90BF-713EB30D60BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E55FECEB-2D88-4FD4-90BF-713EB30D60BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E55FECEB-2D88-4FD4-90BF-713EB30D60BB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
37
FreeTubeSync/Database/DataContext.cs
Normal file
37
FreeTubeSync/Database/DataContext.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
using FreeTubeSync.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace FreeTubeSync.Database;
|
||||
|
||||
public class DataContext : DbContext
|
||||
{
|
||||
public DataContext(DbContextOptions<DataContext> options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseSqlite("Data Source=FreeTubeSync.db");
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Setting>()
|
||||
.ToTable("Settings")
|
||||
.HasKey(s => s._id);
|
||||
|
||||
modelBuilder.Entity<Setting>()
|
||||
.Property(s => s.ValueJson)
|
||||
.HasColumnName("Value")
|
||||
.IsRequired();
|
||||
}
|
||||
|
||||
public DbSet<History> Histories { get; set; }
|
||||
public DbSet<Playlist> Playlists { get; set; }
|
||||
public DbSet<Profile> Profiles { get; set; }
|
||||
public DbSet<SearchHistory> SearchHistories { get; set; }
|
||||
public DbSet<Setting> Settings { get; set; }
|
||||
public DbSet<Subscription> Subscriptions { get; set; }
|
||||
public DbSet<Video> Videos { get; set; }
|
||||
}
|
||||
23
FreeTubeSync/Dockerfile
Normal file
23
FreeTubeSync/Dockerfile
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||
USER $APP_UID
|
||||
WORKDIR /app
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
COPY ["FreeTubeSync2/FreeTubeSync2.csproj", "FreeTubeSync2/"]
|
||||
RUN dotnet restore "FreeTubeSync2/FreeTubeSync2.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/FreeTubeSync2"
|
||||
RUN dotnet build "./FreeTubeSync2.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
RUN dotnet publish "./FreeTubeSync2.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "FreeTubeSync2.dll"]
|
||||
35
FreeTubeSync/EndPoints/HistoryEndpoint.cs
Normal file
35
FreeTubeSync/EndPoints/HistoryEndpoint.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using FreeTubeSync.Model;
|
||||
|
||||
namespace FreeTubeSync.EndPoints;
|
||||
|
||||
public static class HistoryEndpoint
|
||||
{
|
||||
public static void MapHistoryEndpoints(this WebApplication app)
|
||||
{
|
||||
var group = app.MapGroup("history");
|
||||
|
||||
group.MapGet("/", async (IRepository<History> repository, CancellationToken ct) =>
|
||||
{
|
||||
var results = await repository.GetAllAsync(ct);
|
||||
return Results.Ok(results);
|
||||
});
|
||||
|
||||
group.MapPost("/", async (IRepository<History> repository, CancellationToken ct, History history) =>
|
||||
{
|
||||
var results = await repository.GetByIdAsync(history._id, ct);
|
||||
if (results == null)
|
||||
await repository.AddAsync(history, ct);
|
||||
else
|
||||
await repository.UpdateAsync(history, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
|
||||
group.MapDelete("/{id}", async (IRepository<History> repository, CancellationToken ct, string id) =>
|
||||
{
|
||||
var result = await repository.GetByIdAsync(id, ct);
|
||||
if (result == null) return Results.NotFound();
|
||||
await repository.DeleteAsync(result, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
}
|
||||
}
|
||||
35
FreeTubeSync/EndPoints/PlaylistEndpoint.cs
Normal file
35
FreeTubeSync/EndPoints/PlaylistEndpoint.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using FreeTubeSync.Model;
|
||||
|
||||
namespace FreeTubeSync.EndPoints;
|
||||
|
||||
public static class PlaylistEndpoint
|
||||
{
|
||||
public static void MapPlaylistEndpoints(this WebApplication app)
|
||||
{
|
||||
var group = app.MapGroup("playlists");
|
||||
|
||||
group.MapGet("/", async (IRepository<Playlist> repository, CancellationToken ct) =>
|
||||
{
|
||||
var results = await repository.GetAllAsync(ct);
|
||||
return Results.Ok(results);
|
||||
});
|
||||
|
||||
group.MapPost("/", async (IRepository<Playlist> repository, CancellationToken ct, Playlist playlist) =>
|
||||
{
|
||||
var results = await repository.GetByIdAsync(playlist._id, ct);
|
||||
if (results == null)
|
||||
await repository.AddAsync(playlist, ct);
|
||||
else
|
||||
await repository.UpdateAsync(playlist, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
|
||||
group.MapDelete("/{id}", async (IRepository<Playlist> repository, CancellationToken ct, string id) =>
|
||||
{
|
||||
var result = await repository.GetByIdAsync(id, ct);
|
||||
if (result == null) return Results.NotFound();
|
||||
await repository.DeleteAsync(result, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
}
|
||||
}
|
||||
35
FreeTubeSync/EndPoints/ProfileEndpoint.cs
Normal file
35
FreeTubeSync/EndPoints/ProfileEndpoint.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using FreeTubeSync.Model;
|
||||
|
||||
namespace FreeTubeSync.EndPoints;
|
||||
|
||||
public static class ProfileEndpoint
|
||||
{
|
||||
public static void MapProfileEndpoints(this WebApplication app)
|
||||
{
|
||||
var group = app.MapGroup("profile");
|
||||
|
||||
group.MapGet("/", async (IRepository<Profile> repository, CancellationToken ct) =>
|
||||
{
|
||||
var results = await repository.GetAllAsync(ct);
|
||||
return Results.Ok(results);
|
||||
});
|
||||
|
||||
group.MapPost("/", async (IRepository<Profile> repository, CancellationToken ct, Profile profile) =>
|
||||
{
|
||||
var res = await repository.GetByIdAsync(profile._id, ct);
|
||||
if (res == null)
|
||||
await repository.AddAsync(profile, ct);
|
||||
else
|
||||
await repository.UpdateAsync(profile, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
|
||||
group.MapDelete("/{id}", async (IRepository<Profile> repository, CancellationToken ct, string id) =>
|
||||
{
|
||||
var result = await repository.GetByIdAsync(id, ct);
|
||||
if (result == null) return Results.NotFound();
|
||||
await repository.DeleteAsync(result, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
}
|
||||
}
|
||||
36
FreeTubeSync/EndPoints/SearchHistoryEndpoint.cs
Normal file
36
FreeTubeSync/EndPoints/SearchHistoryEndpoint.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using FreeTubeSync.Model;
|
||||
|
||||
namespace FreeTubeSync.EndPoints;
|
||||
|
||||
public static class SearchHistoryEndpoint
|
||||
{
|
||||
public static void MapSearchHistoryEndpoints(this WebApplication app)
|
||||
{
|
||||
var group = app.MapGroup("searchHistory");
|
||||
|
||||
group.MapGet("/", async (IRepository<History> repository, CancellationToken ct) =>
|
||||
{
|
||||
var result = await repository.GetAllAsync(ct);
|
||||
return Results.Ok(result);
|
||||
});
|
||||
|
||||
group.MapPost("/", async (IRepository<History> repository, CancellationToken ct, History history) =>
|
||||
{
|
||||
var result = await repository.GetByIdAsync(history._id, ct);
|
||||
if (result != null)
|
||||
await repository.UpdateAsync(history, ct);
|
||||
else
|
||||
await repository.AddAsync(history, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
|
||||
group.MapDelete("/{id}", async (IRepository<History> repository, CancellationToken ct, string id) =>
|
||||
{
|
||||
var result = await repository.GetByIdAsync(id, ct);
|
||||
if (result == null) return Results.NotFound();
|
||||
await repository.DeleteAsync(result, ct);
|
||||
return Results.Ok();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
37
FreeTubeSync/EndPoints/SettingEndpoint.cs
Normal file
37
FreeTubeSync/EndPoints/SettingEndpoint.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
using FreeTubeSync.Model;
|
||||
using FreeTubeSync.SpecialResponses;
|
||||
|
||||
namespace FreeTubeSync.EndPoints;
|
||||
|
||||
public static class SettingEndpoint
|
||||
{
|
||||
public static void MapSettingEndpoints(this WebApplication app)
|
||||
{
|
||||
var group = app.MapGroup("settings");
|
||||
|
||||
group.MapGet("/", async (IRepository<Setting> repository, CancellationToken ct) =>
|
||||
{
|
||||
var settings = await repository.GetAllAsync(ct);
|
||||
var response = settings.MapToResponse();
|
||||
return Results.Ok(response);
|
||||
});
|
||||
|
||||
group.MapPost("/", async (IRepository<Setting> repository, CancellationToken ct, Setting setting) =>
|
||||
{
|
||||
var res = await repository.GetByIdAsync(setting._id, ct);
|
||||
if (res == null)
|
||||
await repository.AddAsync(setting, ct);
|
||||
else
|
||||
await repository.UpdateAsync(setting, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
|
||||
group.MapDelete("/{id}", async (IRepository<Setting> repository, CancellationToken ct, string id) =>
|
||||
{
|
||||
var result = await repository.GetByIdAsync(id, ct);
|
||||
if (result == null) return Results.NotFound();
|
||||
await repository.DeleteAsync(result, ct);
|
||||
return Results.Ok();
|
||||
});
|
||||
}
|
||||
}
|
||||
27
FreeTubeSync/FreeTubeSync.csproj
Normal file
27
FreeTubeSync/FreeTubeSync.csproj
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\.dockerignore">
|
||||
<Link>.dockerignore</Link>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.7" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="9.0.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="9.0.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
10
FreeTubeSync/IRepository.cs
Normal file
10
FreeTubeSync/IRepository.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
namespace FreeTubeSync;
|
||||
|
||||
public interface IRepository<TEntity> where TEntity : class
|
||||
{
|
||||
Task AddAsync(TEntity entity, CancellationToken ct);
|
||||
Task UpdateAsync(TEntity entity, CancellationToken ct);
|
||||
Task DeleteAsync(TEntity entity, CancellationToken ct);
|
||||
Task<TEntity?> GetByIdAsync(string id, CancellationToken ct);
|
||||
Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken ct);
|
||||
}
|
||||
248
FreeTubeSync/Migrations/20250719082332_Init.Designer.cs
generated
Normal file
248
FreeTubeSync/Migrations/20250719082332_Init.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
// <auto-generated />
|
||||
|
||||
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("20250719082332_Init")]
|
||||
partial class Init
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.7");
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.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.Playlist", b =>
|
||||
{
|
||||
b.Property<string>("_id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("createdAt")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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.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.SearchHistory", b =>
|
||||
{
|
||||
b.Property<string>("_id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("lastUpdatedAt")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("_id");
|
||||
|
||||
b.ToTable("SearchHistories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Setting", b =>
|
||||
{
|
||||
b.Property<string>("_id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ValueJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("Value");
|
||||
|
||||
b.HasKey("_id");
|
||||
|
||||
b.ToTable("Settings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.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.Video", b =>
|
||||
{
|
||||
b.Property<string>("videoId")
|
||||
.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<string>("playlistItemId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("pubished")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("timeAdded")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("type")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("videoId");
|
||||
|
||||
b.HasIndex("Playlist_id");
|
||||
|
||||
b.ToTable("Videos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Subscription", b =>
|
||||
{
|
||||
b.HasOne("FreeTubeSync.Model.Profile", null)
|
||||
.WithMany("subscriptions")
|
||||
.HasForeignKey("Profile_id");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Video", b =>
|
||||
{
|
||||
b.HasOne("FreeTubeSync.Model.Playlist", null)
|
||||
.WithMany("videos")
|
||||
.HasForeignKey("Playlist_id");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Playlist", b =>
|
||||
{
|
||||
b.Navigation("videos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Profile", b =>
|
||||
{
|
||||
b.Navigation("subscriptions");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
171
FreeTubeSync/Migrations/20250719082332_Init.cs
Normal file
171
FreeTubeSync/Migrations/20250719082332_Init.cs
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace FreeTubeSync.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Init : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Histories",
|
||||
columns: table => new
|
||||
{
|
||||
_id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
videoId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
title = table.Column<string>(type: "TEXT", nullable: false),
|
||||
author = table.Column<string>(type: "TEXT", nullable: false),
|
||||
authorId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
published = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
description = table.Column<string>(type: "TEXT", nullable: false),
|
||||
viewCount = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
lengthSeconds = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
watchProgress = table.Column<float>(type: "REAL", nullable: false),
|
||||
timeWatched = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
isLive = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
type = table.Column<string>(type: "TEXT", nullable: false),
|
||||
lastViewedPlaylistType = table.Column<string>(type: "TEXT", nullable: false),
|
||||
lastViewedPlaylistItemId = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Histories", x => x._id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Playlists",
|
||||
columns: table => new
|
||||
{
|
||||
_id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
playlistName = table.Column<string>(type: "TEXT", nullable: false),
|
||||
@protected = table.Column<bool>(name: "protected", type: "INTEGER", nullable: false),
|
||||
createdAt = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
lastUpdatedAt = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Playlists", x => x._id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Profiles",
|
||||
columns: table => new
|
||||
{
|
||||
_id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
bgColor = table.Column<string>(type: "TEXT", nullable: false),
|
||||
textColor = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Profiles", x => x._id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SearchHistories",
|
||||
columns: table => new
|
||||
{
|
||||
_id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
lastUpdatedAt = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SearchHistories", x => x._id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Settings",
|
||||
columns: table => new
|
||||
{
|
||||
_id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Value = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Settings", x => x._id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Videos",
|
||||
columns: table => new
|
||||
{
|
||||
videoId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
title = table.Column<string>(type: "TEXT", nullable: false),
|
||||
author = table.Column<string>(type: "TEXT", nullable: false),
|
||||
authorId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
lengthSeconds = table.Column<string>(type: "TEXT", nullable: false),
|
||||
pubished = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
timeAdded = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
playlistItemId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
type = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Playlist_id = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Videos", x => x.videoId);
|
||||
table.ForeignKey(
|
||||
name: "FK_Videos_Playlists_Playlist_id",
|
||||
column: x => x.Playlist_id,
|
||||
principalTable: "Playlists",
|
||||
principalColumn: "_id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Subscriptions",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
thumbnail = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Profile_id = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Subscriptions", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Subscriptions_Profiles_Profile_id",
|
||||
column: x => x.Profile_id,
|
||||
principalTable: "Profiles",
|
||||
principalColumn: "_id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Subscriptions_Profile_id",
|
||||
table: "Subscriptions",
|
||||
column: "Profile_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Videos_Playlist_id",
|
||||
table: "Videos",
|
||||
column: "Playlist_id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Histories");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SearchHistories");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Settings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Subscriptions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Videos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Profiles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Playlists");
|
||||
}
|
||||
}
|
||||
}
|
||||
245
FreeTubeSync/Migrations/DataContextModelSnapshot.cs
Normal file
245
FreeTubeSync/Migrations/DataContextModelSnapshot.cs
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
// <auto-generated />
|
||||
|
||||
using FreeTubeSync.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace FreeTubeSync.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
partial class DataContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.7");
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.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.Playlist", b =>
|
||||
{
|
||||
b.Property<string>("_id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("createdAt")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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.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.SearchHistory", b =>
|
||||
{
|
||||
b.Property<string>("_id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("lastUpdatedAt")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("_id");
|
||||
|
||||
b.ToTable("SearchHistories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Setting", b =>
|
||||
{
|
||||
b.Property<string>("_id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ValueJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("Value");
|
||||
|
||||
b.HasKey("_id");
|
||||
|
||||
b.ToTable("Settings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.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.Video", b =>
|
||||
{
|
||||
b.Property<string>("videoId")
|
||||
.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<string>("playlistItemId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("pubished")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("timeAdded")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("type")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("videoId");
|
||||
|
||||
b.HasIndex("Playlist_id");
|
||||
|
||||
b.ToTable("Videos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Subscription", b =>
|
||||
{
|
||||
b.HasOne("FreeTubeSync.Model.Profile", null)
|
||||
.WithMany("subscriptions")
|
||||
.HasForeignKey("Profile_id");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Video", b =>
|
||||
{
|
||||
b.HasOne("FreeTubeSync.Model.Playlist", null)
|
||||
.WithMany("videos")
|
||||
.HasForeignKey("Playlist_id");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Playlist", b =>
|
||||
{
|
||||
b.Navigation("videos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FreeTubeSync.Model.Profile", b =>
|
||||
{
|
||||
b.Navigation("subscriptions");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
43
FreeTubeSync/Model/History.cs
Normal file
43
FreeTubeSync/Model/History.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace FreeTubeSync.Model;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class History
|
||||
{
|
||||
[Key]
|
||||
public string _id { get; set; } = string.Empty;
|
||||
public string videoId { get; set; } = string.Empty;
|
||||
public string title { get; set; } = string.Empty;
|
||||
public string author { get; set; } = string.Empty;
|
||||
public string authorId { get; set; } = string.Empty;
|
||||
public long published { get; set; }
|
||||
public string description { get; set; } = string.Empty;
|
||||
public long viewCount { get; set; }
|
||||
public long lengthSeconds { get; set; }
|
||||
public float watchProgress { get; set; }
|
||||
public long timeWatched { get; set; }
|
||||
public bool isLive { get; set; }
|
||||
public string type { get; set; } = string.Empty;
|
||||
public string lastViewedPlaylistType { get; set; } = string.Empty;
|
||||
public string? lastViewedPlaylistItemId { get; set; }
|
||||
|
||||
public void Update(History other)
|
||||
{
|
||||
if (other.videoId != videoId) videoId = other.videoId;
|
||||
if (other.title != title) title = other.title;
|
||||
if (other.author != author) author = other.author;
|
||||
if (other.authorId != authorId) authorId = other.authorId;
|
||||
if (other.published != published) published = other.published;
|
||||
if (other.description != description) description = other.description;
|
||||
if (other.viewCount != viewCount) viewCount = other.viewCount;
|
||||
if (other.lengthSeconds != lengthSeconds) lengthSeconds = other.lengthSeconds;
|
||||
if (!other.watchProgress.Equals(watchProgress)) watchProgress = other.watchProgress;
|
||||
if (other.timeWatched != timeWatched) timeWatched = other.timeWatched;
|
||||
if (other.isLive != isLive) isLive = other.isLive;
|
||||
if (other.type != type) type = other.type;
|
||||
if (other.lastViewedPlaylistType != lastViewedPlaylistType) lastViewedPlaylistType = other.lastViewedPlaylistType;
|
||||
if (other.lastViewedPlaylistItemId != lastViewedPlaylistItemId) lastViewedPlaylistItemId = other.lastViewedPlaylistItemId;
|
||||
}
|
||||
}
|
||||
25
FreeTubeSync/Model/Playlist.cs
Normal file
25
FreeTubeSync/Model/Playlist.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace FreeTubeSync.Model;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class Playlist
|
||||
{
|
||||
[Key]
|
||||
public string _id { get; set; } = string.Empty;
|
||||
public string playlistName { get; set; } = string.Empty;
|
||||
public bool @protected { get; set; }
|
||||
public List<Video> videos { get; set; } = [];
|
||||
public int createdAt { get; set; }
|
||||
public int lastUpdatedAt { get; set; }
|
||||
|
||||
public void Update(Playlist other)
|
||||
{
|
||||
if (other.playlistName != playlistName) playlistName = other.playlistName;
|
||||
if (other.@protected != @protected) @protected = other.@protected;
|
||||
if (other.videos.Count != videos.Count) videos = other.videos;
|
||||
if (other.createdAt != createdAt) createdAt = other.createdAt;
|
||||
if (other.lastUpdatedAt != lastUpdatedAt) lastUpdatedAt = other.lastUpdatedAt;
|
||||
}
|
||||
}
|
||||
23
FreeTubeSync/Model/Profile.cs
Normal file
23
FreeTubeSync/Model/Profile.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace FreeTubeSync.Model;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class Profile
|
||||
{
|
||||
[Key]
|
||||
public string _id { get; set; } = string.Empty;
|
||||
public string name { get; set; } = string.Empty;
|
||||
public string bgColor { get; set; } = string.Empty;
|
||||
public string textColor { get; set; } = string.Empty;
|
||||
public List<Subscription> subscriptions { get; set; } = [];
|
||||
|
||||
public void Update(Profile other)
|
||||
{
|
||||
if (other.name != name) name = other.name;
|
||||
if (other.bgColor != bgColor) bgColor = other.bgColor;
|
||||
if (other.textColor != textColor) textColor = other.textColor;
|
||||
if (other.subscriptions.Count != subscriptions.Count) subscriptions = other.subscriptions;
|
||||
}
|
||||
}
|
||||
17
FreeTubeSync/Model/SearchHistory.cs
Normal file
17
FreeTubeSync/Model/SearchHistory.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace FreeTubeSync.Model;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class SearchHistory
|
||||
{
|
||||
[Key]
|
||||
public string _id { get; set; } = string.Empty;
|
||||
public int lastUpdatedAt { get; set; }
|
||||
|
||||
public void Update(SearchHistory other)
|
||||
{
|
||||
if (other.lastUpdatedAt != lastUpdatedAt) lastUpdatedAt = other.lastUpdatedAt;
|
||||
}
|
||||
}
|
||||
25
FreeTubeSync/Model/Setting.cs
Normal file
25
FreeTubeSync/Model/Setting.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace FreeTubeSync.Model;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class Setting
|
||||
{
|
||||
[Key]
|
||||
#pragma warning disable CS8618
|
||||
public string _id { get; set; } = string.Empty;
|
||||
public string? ValueJson { get; set; }
|
||||
#pragma warning restore CS8618
|
||||
|
||||
[NotMapped]
|
||||
public object Value
|
||||
{
|
||||
#pragma warning disable CS8603
|
||||
get => string.IsNullOrEmpty(ValueJson) ? null : JsonSerializer.Deserialize<object>(ValueJson);
|
||||
#pragma warning restore CS8603
|
||||
set => ValueJson = JsonSerializer.Serialize(value);
|
||||
}
|
||||
}
|
||||
13
FreeTubeSync/Model/Subscription.cs
Normal file
13
FreeTubeSync/Model/Subscription.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace FreeTubeSync.Model;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class Subscription
|
||||
{
|
||||
[Key]
|
||||
public required string id { get; set; }
|
||||
public required string name { get; set; }
|
||||
public string? thumbnail { get; set; }
|
||||
}
|
||||
18
FreeTubeSync/Model/Video.cs
Normal file
18
FreeTubeSync/Model/Video.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace FreeTubeSync.Model;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class Video
|
||||
{
|
||||
[Key] public string videoId { get; set; } = string.Empty;
|
||||
public string title { get; set; } = string.Empty;
|
||||
public string author { get; set; } = string.Empty;
|
||||
public string authorId { get; set; } = string.Empty;
|
||||
public string lengthSeconds { get; set; } = string.Empty;
|
||||
public int pubished { get; set; }
|
||||
public int timeAdded { get; set; }
|
||||
public string playlistItemId { get; set; } = string.Empty;
|
||||
public string type { get; set; } = string.Empty;
|
||||
}
|
||||
24
FreeTubeSync/Program.cs
Normal file
24
FreeTubeSync/Program.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using FreeTubeSync;
|
||||
using FreeTubeSync.Database;
|
||||
using FreeTubeSync.EndPoints;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
builder.Services.AddDbContext<DataContext>();
|
||||
|
||||
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.MapHistoryEndpoints();
|
||||
app.MapPlaylistEndpoints();
|
||||
app.MapProfileEndpoints();
|
||||
app.MapSearchHistoryEndpoints();
|
||||
app.MapSettingEndpoints();
|
||||
|
||||
app.Run();
|
||||
29
FreeTubeSync/Properties/launchSettings.json
Normal file
29
FreeTubeSync/Properties/launchSettings.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:18186",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "http://localhost:5183",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": false,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
FreeTubeSync/Repository.cs
Normal file
35
FreeTubeSync/Repository.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using FreeTubeSync.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace FreeTubeSync;
|
||||
|
||||
public class Repository<TEntity>(DataContext dbContext) : IRepository<TEntity> where TEntity : class
|
||||
{
|
||||
public async Task AddAsync(TEntity entity, CancellationToken ct)
|
||||
{
|
||||
dbContext.Set<TEntity>().Add(entity);
|
||||
await dbContext.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(TEntity entity, CancellationToken ct)
|
||||
{
|
||||
dbContext.Set<TEntity>().Update(entity);
|
||||
await dbContext.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(TEntity entity, CancellationToken ct)
|
||||
{
|
||||
dbContext.Set<TEntity>().Remove(entity);
|
||||
await dbContext.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
public async Task<TEntity?> GetByIdAsync(string id, CancellationToken ct)
|
||||
{
|
||||
return await dbContext.Set<TEntity>().FindAsync(id, ct);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken ct)
|
||||
{
|
||||
return await dbContext.Set<TEntity>().ToListAsync<TEntity>(ct);
|
||||
}
|
||||
}
|
||||
20
FreeTubeSync/SpecialResponses/Mappings.cs
Normal file
20
FreeTubeSync/SpecialResponses/Mappings.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using FreeTubeSync.Model;
|
||||
|
||||
namespace FreeTubeSync.SpecialResponses;
|
||||
|
||||
public static class Mappings
|
||||
{
|
||||
public static SettingResponse MapToResponse(this Setting setting)
|
||||
{
|
||||
return new SettingResponse
|
||||
{
|
||||
_id = setting._id,
|
||||
value = setting.Value
|
||||
};
|
||||
}
|
||||
|
||||
public static IEnumerable<SettingResponse> MapToResponse(this IEnumerable<Setting> settings)
|
||||
{
|
||||
return settings.Select(MapToResponse);
|
||||
}
|
||||
}
|
||||
9
FreeTubeSync/SpecialResponses/SettingResponse.cs
Normal file
9
FreeTubeSync/SpecialResponses/SettingResponse.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using FreeTubeSync.Model;
|
||||
|
||||
namespace FreeTubeSync.SpecialResponses;
|
||||
|
||||
public class SettingResponse
|
||||
{
|
||||
public string _id { get; set; }
|
||||
public object value { get; set; }
|
||||
}
|
||||
8
FreeTubeSync/appsettings.Development.json
Normal file
8
FreeTubeSync/appsettings.Development.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
FreeTubeSync/appsettings.json
Normal file
9
FreeTubeSync/appsettings.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
7
compose.yaml
Normal file
7
compose.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
services:
|
||||
freetubesync2:
|
||||
image: freetubesync2
|
||||
build:
|
||||
context: .
|
||||
dockerfile: FreeTubeSync2/Dockerfile
|
||||
|
||||
7
global.json
Normal file
7
global.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "8.0.0",
|
||||
"rollForward": "latestMinor",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue