mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Fix enum mapping bugs (#360)
This commit is contained in:
commit
f7603db588
@ -4,8 +4,23 @@ WORKDIR /kyoo
|
|||||||
|
|
||||||
COPY .config/dotnet-tools.json .config/dotnet-tools.json
|
COPY .config/dotnet-tools.json .config/dotnet-tools.json
|
||||||
RUN dotnet tool restore
|
RUN dotnet tool restore
|
||||||
|
|
||||||
|
COPY Kyoo.sln ./Kyoo.sln
|
||||||
|
COPY nuget.config ./nuget.config
|
||||||
|
COPY src/Directory.Build.props src/Directory.Build.props
|
||||||
|
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
||||||
|
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||||
|
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
||||||
|
COPY src/Kyoo.Host/Kyoo.Host.csproj src/Kyoo.Host/Kyoo.Host.csproj
|
||||||
|
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||||
|
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||||
|
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
||||||
|
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
||||||
|
RUN dotnet restore -a $TARGETARCH
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet ef migrations bundle --self-contained -f -o /app/migrate -p src/Kyoo.Postgresql --verbose
|
RUN dotnet build
|
||||||
|
RUN dotnet ef migrations bundle --no-build --self-contained -f -o /app/migrate -p src/Kyoo.Postgresql --verbose
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0
|
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0
|
||||||
COPY --from=builder /app/migrate /app/migrate
|
COPY --from=builder /app/migrate /app/migrate
|
||||||
|
@ -79,12 +79,12 @@ public class Movie
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of tags that match this movie.
|
/// A list of tags that match this movie.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string[] Tags { get; set; } = Array.Empty<string>();
|
public string[] Tags { get; set; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of genres (themes) this show has.
|
/// The list of genres (themes) this show has.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Genre[] Genres { get; set; } = Array.Empty<Genre>();
|
public List<Genre> Genres { get; set; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is this show airing, not aired yet or finished?
|
/// Is this show airing, not aired yet or finished?
|
||||||
|
@ -17,9 +17,15 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Dapper;
|
||||||
using EFCore.NamingConventions.Internal;
|
using EFCore.NamingConventions.Internal;
|
||||||
|
using InterpolatedSql.SqlBuilders;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
|
using Kyoo.Postgresql.Utils;
|
||||||
|
using Kyoo.Utils;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
|
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
|
||||||
@ -42,15 +48,6 @@ public class PostgresContext : DatabaseContext
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly bool _skipConfigure;
|
private readonly bool _skipConfigure;
|
||||||
|
|
||||||
// TODO: This needs ot be updated but ef-core still does not offer a way to use this.
|
|
||||||
[Obsolete]
|
|
||||||
static PostgresContext()
|
|
||||||
{
|
|
||||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
|
|
||||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<Genre>();
|
|
||||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<WatchStatus>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Design time constructor (dotnet ef migrations add). Do not use
|
/// Design time constructor (dotnet ef migrations add). Do not use
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -102,11 +99,45 @@ public class PostgresContext : DatabaseContext
|
|||||||
"md5",
|
"md5",
|
||||||
args,
|
args,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
argumentsPropagateNullability: new[] { false },
|
argumentsPropagateNullability: [false],
|
||||||
type: args[0].Type,
|
type: args[0].Type,
|
||||||
typeMapping: args[0].TypeMapping
|
typeMapping: args[0].TypeMapping
|
||||||
));
|
));
|
||||||
|
|
||||||
|
SqlMapper.TypeMapProvider = (type) =>
|
||||||
|
{
|
||||||
|
return new CustomPropertyTypeMap(
|
||||||
|
type,
|
||||||
|
(type, name) =>
|
||||||
|
{
|
||||||
|
string newName = Regex.Replace(
|
||||||
|
name,
|
||||||
|
"(^|_)([a-z])",
|
||||||
|
(match) => match.Groups[2].Value.ToUpperInvariant()
|
||||||
|
);
|
||||||
|
// TODO: Add images handling here (name: poster_source, newName: PosterSource) should set Poster.Source
|
||||||
|
return type.GetProperty(newName)!;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
SqlMapper.AddTypeHandler(
|
||||||
|
typeof(Dictionary<string, MetadataId>),
|
||||||
|
new JsonTypeHandler<Dictionary<string, MetadataId>>()
|
||||||
|
);
|
||||||
|
SqlMapper.AddTypeHandler(
|
||||||
|
typeof(Dictionary<string, string>),
|
||||||
|
new JsonTypeHandler<Dictionary<string, string>>()
|
||||||
|
);
|
||||||
|
SqlMapper.AddTypeHandler(
|
||||||
|
typeof(Dictionary<string, ExternalToken>),
|
||||||
|
new JsonTypeHandler<Dictionary<string, ExternalToken>>()
|
||||||
|
);
|
||||||
|
SqlMapper.AddTypeHandler(typeof(List<string>), new ListTypeHandler<string>());
|
||||||
|
SqlMapper.AddTypeHandler(typeof(List<Genre>), new ListTypeHandler<Genre>());
|
||||||
|
SqlMapper.AddTypeHandler(typeof(Wrapper), new Wrapper.Handler());
|
||||||
|
InterpolatedSqlBuilderOptions.DefaultOptions.ReuseIdenticalParameters = true;
|
||||||
|
InterpolatedSqlBuilderOptions.DefaultOptions.AutoFixSingleQuotes = false;
|
||||||
|
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,16 +16,9 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Dapper;
|
|
||||||
using InterpolatedSql.SqlBuilders;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Postgresql.Utils;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -43,43 +36,6 @@ public class PostgresModule(IConfiguration configuration, IWebHostEnvironment en
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Name => "Postgresql";
|
public string Name => "Postgresql";
|
||||||
|
|
||||||
static PostgresModule()
|
|
||||||
{
|
|
||||||
SqlMapper.TypeMapProvider = (type) =>
|
|
||||||
{
|
|
||||||
return new CustomPropertyTypeMap(
|
|
||||||
type,
|
|
||||||
(type, name) =>
|
|
||||||
{
|
|
||||||
string newName = Regex.Replace(
|
|
||||||
name,
|
|
||||||
"(^|_)([a-z])",
|
|
||||||
(match) => match.Groups[2].Value.ToUpperInvariant()
|
|
||||||
);
|
|
||||||
// TODO: Add images handling here (name: poster_source, newName: PosterSource) should set Poster.Source
|
|
||||||
return type.GetProperty(newName)!;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
SqlMapper.AddTypeHandler(
|
|
||||||
typeof(Dictionary<string, MetadataId>),
|
|
||||||
new JsonTypeHandler<Dictionary<string, MetadataId>>()
|
|
||||||
);
|
|
||||||
SqlMapper.AddTypeHandler(
|
|
||||||
typeof(Dictionary<string, string>),
|
|
||||||
new JsonTypeHandler<Dictionary<string, string>>()
|
|
||||||
);
|
|
||||||
SqlMapper.AddTypeHandler(
|
|
||||||
typeof(Dictionary<string, ExternalToken>),
|
|
||||||
new JsonTypeHandler<Dictionary<string, ExternalToken>>()
|
|
||||||
);
|
|
||||||
SqlMapper.AddTypeHandler(typeof(List<string>), new ListTypeHandler<string>());
|
|
||||||
SqlMapper.AddTypeHandler(typeof(List<Genre>), new ListTypeHandler<Genre>());
|
|
||||||
SqlMapper.AddTypeHandler(typeof(Wrapper), new Wrapper.Handler());
|
|
||||||
InterpolatedSqlBuilderOptions.DefaultOptions.ReuseIdenticalParameters = true;
|
|
||||||
InterpolatedSqlBuilderOptions.DefaultOptions.AutoFixSingleQuotes = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Configure(IServiceCollection services)
|
public void Configure(IServiceCollection services)
|
||||||
{
|
{
|
||||||
@ -96,16 +52,24 @@ public class PostgresModule(IConfiguration configuration, IWebHostEnvironment en
|
|||||||
["TIMEOUT"] = "30"
|
["TIMEOUT"] = "30"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NpgsqlDataSourceBuilder dsBuilder = new(builder.ConnectionString);
|
||||||
|
dsBuilder.MapEnum<Status>();
|
||||||
|
dsBuilder.MapEnum<Genre>();
|
||||||
|
dsBuilder.MapEnum<WatchStatus>();
|
||||||
|
NpgsqlDataSource dataSource = dsBuilder.Build();
|
||||||
|
|
||||||
services.AddDbContext<DatabaseContext, PostgresContext>(
|
services.AddDbContext<DatabaseContext, PostgresContext>(
|
||||||
x =>
|
x =>
|
||||||
{
|
{
|
||||||
x.UseNpgsql(builder.ConnectionString).UseProjectables();
|
x.UseNpgsql(dataSource).UseProjectables();
|
||||||
if (environment.IsDevelopment())
|
if (environment.IsDevelopment())
|
||||||
x.EnableDetailedErrors().EnableSensitiveDataLogging();
|
x.EnableDetailedErrors().EnableSensitiveDataLogging();
|
||||||
},
|
},
|
||||||
ServiceLifetime.Transient
|
ServiceLifetime.Transient
|
||||||
);
|
);
|
||||||
services.AddTransient<DbConnection>((_) => new NpgsqlConnection(builder.ConnectionString));
|
services.AddTransient(
|
||||||
|
(services) => services.GetRequiredService<DatabaseContext>().Database.GetDbConnection()
|
||||||
|
);
|
||||||
|
|
||||||
services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
|
services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class ListTypeHandler<T> : SqlMapper.TypeHandler<List<T>>
|
|||||||
public override List<T> Parse(object value)
|
public override List<T> Parse(object value)
|
||||||
{
|
{
|
||||||
T[] typedValue = (T[])value; // looks like Dapper did not indicate the property type to Npgsql, so it defaults to string[] (default CLR type for text[] PostgreSQL type)
|
T[] typedValue = (T[])value; // looks like Dapper did not indicate the property type to Npgsql, so it defaults to string[] (default CLR type for text[] PostgreSQL type)
|
||||||
return typedValue?.ToList() ?? new();
|
return typedValue?.ToList() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetValue(IDbDataParameter parameter, List<T>? value)
|
public override void SetValue(IDbDataParameter parameter, List<T>? value)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
x-transcoder: &transcoder-base
|
x-transcoder: &transcoder-base
|
||||||
image: zoriya/kyoo_transcoder:edge
|
image: zoriya/kyoo_transcoder:latest
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
aliases:
|
aliases:
|
||||||
@ -14,7 +14,7 @@ x-transcoder: &transcoder-base
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
back:
|
back:
|
||||||
image: zoriya/kyoo_back:edge
|
image: zoriya/kyoo_back:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cpus: 1.5
|
cpus: 1.5
|
||||||
env_file:
|
env_file:
|
||||||
@ -32,7 +32,7 @@ services:
|
|||||||
- kyoo:/kyoo
|
- kyoo:/kyoo
|
||||||
|
|
||||||
migrations:
|
migrations:
|
||||||
image: zoriya/kyoo_migrations:edge
|
image: zoriya/kyoo_migrations:latest
|
||||||
restart: "no"
|
restart: "no"
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
@ -41,13 +41,13 @@ services:
|
|||||||
- ./.env
|
- ./.env
|
||||||
|
|
||||||
front:
|
front:
|
||||||
image: zoriya/kyoo_front:edge
|
image: zoriya/kyoo_front:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- KYOO_URL=${KYOO_URL:-http://back:5000}
|
- KYOO_URL=${KYOO_URL:-http://back:5000}
|
||||||
|
|
||||||
scanner:
|
scanner:
|
||||||
image: zoriya/kyoo_scanner:edge
|
image: zoriya/kyoo_scanner:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
back:
|
back:
|
||||||
|
@ -52,14 +52,15 @@ export const ConnectionError = () => {
|
|||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (account.isVerified) return <ErrorView error={error} noBubble />;
|
if (!account.isVerified) {
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
{...css({ flexGrow: 1, flexShrink: 1, justifyContent: "center", alignItems: "center" })}
|
{...css({ flexGrow: 1, flexShrink: 1, justifyContent: "center", alignItems: "center" })}
|
||||||
>
|
>
|
||||||
<P>{t("errors.needVerification")}</P>
|
<P>{t("errors.needVerification")}</P>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<View {...css({ padding: ts(2) })}>
|
<View {...css({ padding: ts(2) })}>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user