Parse images from the scanner

This commit is contained in:
Zoe Roux 2023-08-06 13:17:35 +09:00
parent ca99421624
commit a6c8105d8c
No known key found for this signature in database
11 changed files with 51 additions and 26 deletions

View File

@ -46,7 +46,7 @@
<PropertyGroup Condition="$(CheckCodingStyle) == true"> <PropertyGroup Condition="$(CheckCodingStyle) == true">
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)../Kyoo.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)../Kyoo.ruleset</CodeAnalysisRuleSet>
<NoWarn>1591</NoWarn> <NoWarn>1591;1305</NoWarn>
<!-- <AnalysisMode>All</AnalysisMode> --> <!-- <AnalysisMode>All</AnalysisMode> -->
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -16,7 +16,10 @@
// 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.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Globalization;
namespace Kyoo.Abstractions.Models namespace Kyoo.Abstractions.Models
{ {
@ -42,6 +45,7 @@ namespace Kyoo.Abstractions.Models
public Image? Logo { get; set; } public Image? Logo { get; set; }
} }
[TypeConverter(typeof(ImageConvertor))]
public class Image public class Image
{ {
/// <summary> /// <summary>
@ -54,6 +58,31 @@ namespace Kyoo.Abstractions.Models
/// </summary> /// </summary>
[MaxLength(32)] [MaxLength(32)]
public string Blurhash { get; set; } public string Blurhash { get; set; }
public Image(string source, string? blurhash = null)
{
Source = source;
Blurhash = blurhash ?? "00000000000000";
}
public class ImageConvertor : TypeConverter
{
/// <inheritdoc />
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is not string source)
return base.ConvertFrom(context, culture, value)!;
return new Image(source);
}
}
} }
/// <summary> /// <summary>
@ -64,7 +93,7 @@ namespace Kyoo.Abstractions.Models
/// <summary> /// <summary>
/// Small /// Small
/// </summary> /// </summary>
Small, Low,
/// <summary> /// <summary>
/// Medium /// Medium
@ -74,6 +103,6 @@ namespace Kyoo.Abstractions.Models
/// <summary> /// <summary>
/// Large /// Large
/// </summary> /// </summary>
Large, High,
} }
} }

View File

@ -23,7 +23,6 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using JetBrains.Annotations;
namespace Kyoo.Abstractions.Models.Utils namespace Kyoo.Abstractions.Models.Utils
{ {
@ -43,7 +42,7 @@ namespace Kyoo.Abstractions.Models.Utils
/// <summary> /// <summary>
/// The slug of the resource or null if the id is specified. /// The slug of the resource or null if the id is specified.
/// </summary> /// </summary>
private readonly string _slug; private readonly string? _slug;
/// <summary> /// <summary>
/// Create a new <see cref="Identifier"/> for the given id. /// Create a new <see cref="Identifier"/> for the given id.
@ -183,7 +182,7 @@ namespace Kyoo.Abstractions.Models.Utils
{ {
return _id.HasValue return _id.HasValue
? _id.Value.ToString() ? _id.Value.ToString()
: _slug; : _slug!;
} }
/// <summary> /// <summary>
@ -192,7 +191,7 @@ namespace Kyoo.Abstractions.Models.Utils
public class IdentifierConvertor : TypeConverter public class IdentifierConvertor : TypeConverter
{ {
/// <inheritdoc /> /// <inheritdoc />
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{ {
if (sourceType == typeof(int) || sourceType == typeof(string)) if (sourceType == typeof(int) || sourceType == typeof(string))
return true; return true;
@ -200,12 +199,12 @@ namespace Kyoo.Abstractions.Models.Utils
} }
/// <inheritdoc /> /// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{ {
if (value is int id) if (value is int id)
return new Identifier(id); return new Identifier(id);
if (value is not string slug) if (value is not string slug)
return base.ConvertFrom(context, culture, value); return base.ConvertFrom(context, culture, value)!;
return int.TryParse(slug, out id) return int.TryParse(slug, out id)
? new Identifier(id) ? new Identifier(id)
: new Identifier(slug); : new Identifier(slug);

View File

@ -20,6 +20,7 @@ using System;
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using BlurHashSharp.SkiaSharp;
using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -76,13 +77,13 @@ namespace Kyoo.Core.Controllers
SKBitmap bitmap = SKBitmap.Decode(reader); SKBitmap bitmap = SKBitmap.Decode(reader);
bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.High); bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.High);
await _WriteTo(bitmap, $"{localPath}.{ImageQuality.Large.ToString().ToLowerInvariant()}.jpg"); await _WriteTo(bitmap, $"{localPath}.{ImageQuality.High.ToString().ToLowerInvariant()}.jpg");
bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.Medium); bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.Medium);
await _WriteTo(bitmap, $"{localPath}.{ImageQuality.Medium.ToString().ToLowerInvariant()}.jpg"); await _WriteTo(bitmap, $"{localPath}.{ImageQuality.Medium.ToString().ToLowerInvariant()}.jpg");
bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.Low); bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.Low);
await _WriteTo(bitmap, $"{localPath}.{ImageQuality.Small.ToString().ToLowerInvariant()}.jpg"); await _WriteTo(bitmap, $"{localPath}.{ImageQuality.Low.ToString().ToLowerInvariant()}.jpg");
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -11,6 +11,7 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.9" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SkiaSharp" Version="2.88.3" /> <PackageReference Include="SkiaSharp" Version="2.88.3" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -65,7 +65,7 @@ namespace Kyoo.Core.Api
); );
if (resource == null) if (resource == null)
return NotFound(); return NotFound();
string path = _thumbs.GetImagePath(resource, image, quality ?? ImageQuality.Large); string path = _thumbs.GetImagePath(resource, image, quality ?? ImageQuality.High);
if (path == null || !System.IO.File.Exists(path)) if (path == null || !System.IO.File.Exists(path))
return NotFound(); return NotFound();
return PhysicalFile(Path.GetFullPath(path), "image/jpeg", true); return PhysicalFile(Path.GetFullPath(path), "image/jpeg", true);

View File

@ -40,9 +40,5 @@ class Episode:
return { return {
**asdict(self), **asdict(self),
**asdict(self.translations[default_language]), **asdict(self.translations[default_language]),
# "poster": next(iter(self.translations[default_language].posters), None),
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
# "logo": next(iter(self.translations[default_language].logos), None),
"thumbnail": None,
"show": None, "show": None,
} }

View File

@ -50,9 +50,9 @@ class Movie:
return { return {
**asdict(self), **asdict(self),
**asdict(self.translations[default_language]), **asdict(self.translations[default_language]),
# "poster": next(iter(self.translations[default_language].posters), None), "poster": next(iter(self.translations[default_language].posters), None),
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None), "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
# "logo": next(iter(self.translations[default_language].logos), None), "logo": next(iter(self.translations[default_language].logos), None),
"trailer": next(iter(self.translations[default_language].trailers), None), "trailer": next(iter(self.translations[default_language].trailers), None),
"studio": next((x.to_kyoo() for x in self.studios), None), "studio": next((x.to_kyoo() for x in self.studios), None),
"genres": [x.to_kyoo() for x in self.genres], "genres": [x.to_kyoo() for x in self.genres],

View File

@ -30,7 +30,6 @@ class Season:
return { return {
**asdict(self), **asdict(self),
**asdict(self.translations[default_language]), **asdict(self.translations[default_language]),
# "poster": next(iter(self.translations[default_language].posters), None), "poster": next(iter(self.translations[default_language].posters), None),
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None), "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
# "logo": next(iter(self.translations[default_language].logos), None),
} }

View File

@ -54,9 +54,9 @@ class Show:
**asdict(self.translations[default_language]), **asdict(self.translations[default_language]),
"studio": next((x.to_kyoo() for x in self.studios), None), "studio": next((x.to_kyoo() for x in self.studios), None),
"seasons": None, "seasons": None,
# "poster": next(iter(self.translations[default_language].posters), None), "poster": next(iter(self.translations[default_language].posters), None),
# "thumbnail": next(iter(self.translations[default_language].thumbnails), None), "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
# "logo": next(iter(self.translations[default_language].logos), None), "logo": next(iter(self.translations[default_language].logos), None),
"trailer": next(iter(self.translations[default_language].trailers), None), "trailer": next(iter(self.translations[default_language].trailers), None),
"genres": [x.to_kyoo() for x in self.genres], "genres": [x.to_kyoo() for x in self.genres],
} }

View File

@ -12,5 +12,5 @@ class Studio:
def to_kyoo(self): def to_kyoo(self):
return { return {
**asdict(self), **asdict(self),
# "logo": next(iter(self.logos), None), "logo": next(iter(self.logos), None),
} }