mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Handle movies with the same slug but not the same date
This commit is contained in:
parent
8a925b35dd
commit
f59f9a7ba0
@ -17,17 +17,17 @@
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Blurhash.SkiaSharp;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SkiaSharp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Kyoo.Core.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
@ -35,9 +35,8 @@ namespace Kyoo.Core.Controllers
|
||||
/// </summary>
|
||||
public class ThumbnailsManager : IThumbnailsManager
|
||||
{
|
||||
/// <summary>
|
||||
/// A logger to report errors.
|
||||
/// </summary>
|
||||
private static readonly Dictionary<string, TaskCompletionSource<object>> _downloading = new();
|
||||
|
||||
private readonly ILogger<ThumbnailsManager> _logger;
|
||||
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
@ -106,14 +105,50 @@ namespace Kyoo.Core.Controllers
|
||||
public async Task DownloadImages<T>(T item)
|
||||
where T : IThumbnails
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
|
||||
string name = item is IResource res ? res.Slug : "???";
|
||||
|
||||
string posterPath = $"{_GetBaseImagePath(item, "poster")}.{ImageQuality.High.ToString().ToLowerInvariant()}.webp";
|
||||
bool duplicated = false;
|
||||
TaskCompletionSource<object>? sync = null;
|
||||
try
|
||||
{
|
||||
lock (_downloading)
|
||||
{
|
||||
if (File.Exists(posterPath) || _downloading.ContainsKey(posterPath))
|
||||
{
|
||||
duplicated = true;
|
||||
sync = _downloading.GetValueOrDefault(posterPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
sync = new();
|
||||
_downloading.Add(posterPath, sync);
|
||||
}
|
||||
}
|
||||
if (duplicated)
|
||||
{
|
||||
object? dup = sync != null
|
||||
? await sync.Task
|
||||
: null;
|
||||
throw new DuplicatedItemException(dup);
|
||||
}
|
||||
|
||||
await _DownloadImage(item.Poster, _GetBaseImagePath(item, "poster"), $"The poster of {name}");
|
||||
await _DownloadImage(item.Thumbnail, _GetBaseImagePath(item, "thumbnail"), $"The poster of {name}");
|
||||
await _DownloadImage(item.Logo, _GetBaseImagePath(item, "logo"), $"The poster of {name}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!duplicated)
|
||||
{
|
||||
lock (_downloading)
|
||||
{
|
||||
_downloading.Remove(posterPath);
|
||||
sync!.SetResult(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string _GetBaseImagePath<T>(T item, string image)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ import re
|
||||
from aiohttp import ClientSession
|
||||
from pathlib import Path
|
||||
from guessit import guessit
|
||||
from typing import List, Literal
|
||||
from typing import List, Literal, Any
|
||||
from providers.provider import Provider
|
||||
from providers.types.collection import Collection
|
||||
from providers.types.episode import Episode, PartialShow
|
||||
@ -186,7 +186,7 @@ class Scanner:
|
||||
)
|
||||
return await self.post("seasons", data=season.to_kyoo())
|
||||
|
||||
async def post(self, path: str, *, data: object) -> str:
|
||||
async def post(self, path: str, *, data: dict[str, Any]) -> str:
|
||||
logging.debug(
|
||||
"Sending %s: %s",
|
||||
path,
|
||||
@ -206,19 +206,32 @@ class Scanner:
|
||||
logging.error(f"Request error: {await r.text()}")
|
||||
r.raise_for_status()
|
||||
ret = await r.json()
|
||||
|
||||
if r.status == 409 and (
|
||||
(path == "shows" and ret["startAir"][:4] != str(data["start_air"].year))
|
||||
or (
|
||||
path == "movies" and ret["airDate"][:4] != str(data["air_date"].year)
|
||||
)
|
||||
):
|
||||
logging.info(
|
||||
f"Found a {path} with the same slug ({ret['slug']}) and a different date, using the date as part of the slug"
|
||||
)
|
||||
year = (data["start_air"] if path == "movie" else data["air_date"]).year
|
||||
data["slug"] = f"{ret['slug']}-{year}"
|
||||
return await self.post(path, data=data)
|
||||
return ret["id"]
|
||||
|
||||
async def delete(self, path: str):
|
||||
logging.info("Deleting %s", path)
|
||||
async with self._client.delete(
|
||||
f"{self._url}/movies?path={path}", headers={"X-API-Key": self._api_key}
|
||||
f"{self._url}/movies?filter=path eq \"{path}\"", headers={"X-API-Key": self._api_key}
|
||||
) as r:
|
||||
if not r.ok:
|
||||
logging.error(f"Request error: {await r.text()}")
|
||||
r.raise_for_status()
|
||||
|
||||
async with self._client.delete(
|
||||
f"{self._url}/episodes?path={path}", headers={"X-API-Key": self._api_key}
|
||||
f"{self._url}/episodes?filter=path eq \"{path}\"", headers={"X-API-Key": self._api_key}
|
||||
) as r:
|
||||
if not r.ok:
|
||||
logging.error(f"Request error: {await r.text()}")
|
||||
|
Loading…
x
Reference in New Issue
Block a user