Add delete route that allow recursive delete for directories

This commit is contained in:
Zoe Roux 2024-04-29 01:43:35 +02:00
parent fccc5b6ad9
commit 9e089b21ed
No known key found for this signature in database
3 changed files with 51 additions and 21 deletions

View File

@ -84,6 +84,27 @@ public class MiscRepository(
.ToListAsync();
}
public async Task<int> DeletePath(string path, bool recurse)
{
// Make sure to include a path separator to prevents deletions from things like:
// DeletePath("/video/abc", true) -> /video/abdc (should not be deleted)
string dirPath = path.EndsWith("/") ? path : $"{path}/";
int count = await context
.Episodes.Where(x => x.Path == path || (recurse && x.Path.StartsWith(dirPath)))
.ExecuteDeleteAsync();
count += await context
.Movies.Where(x => x.Path == path || (recurse && x.Path.StartsWith(dirPath)))
.ExecuteDeleteAsync();
await context
.Issues.Where(x =>
x.Domain == "scanner"
&& (x.Cause == path || (recurse && x.Cause.StartsWith(dirPath)))
)
.ExecuteDeleteAsync();
return count;
}
public async Task<ICollection<RefreshableItem>> GetRefreshableItems(DateTime end)
{
IQueryable<RefreshableItem> GetItems<T>()

View File

@ -30,7 +30,7 @@ namespace Kyoo.Core.Api;
/// Private APIs only used for other services. Can change at any time without notice.
/// </summary>
[ApiController]
[Permission(nameof(Misc), Kind.Read, Group = Group.Admin)]
[PartialPermission(nameof(Misc), Group = Group.Admin)]
public class Misc(MiscRepository repo) : BaseApi
{
/// <summary>
@ -38,18 +38,40 @@ public class Misc(MiscRepository repo) : BaseApi
/// </summary>
/// <returns>The list of paths known to Kyoo.</returns>
[HttpGet("/paths")]
[PartialPermission(Kind.Read)]
[ProducesResponseType(StatusCodes.Status200OK)]
public Task<ICollection<string>> GetAllPaths()
{
return repo.GetRegisteredPaths();
}
/// <summary>
/// Delete item at path.
/// </summary>
/// <param name="path">The path to delete.</param>
/// <param name="recursive">
/// If true, the path will be considered as a directory and every children will be removed.
/// </param>
/// <returns>Nothing</returns>
[HttpDelete("/paths")]
[PartialPermission(Kind.Delete)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> DeletePath(
[FromQuery] string path,
[FromQuery] bool recursive = false
)
{
await repo.DeletePath(path, recursive);
return NoContent();
}
/// <summary>
/// List items to refresh.
/// </summary>
/// <param name="date">The upper limit for the refresh date.</param>
/// <returns>The items that should be refreshed before the given date</returns>
[HttpGet("/refreshables")]
[PartialPermission(Kind.Read)]
[ProducesResponseType(StatusCodes.Status200OK)]
public Task<ICollection<RefreshableItem>> GetAllPaths([FromQuery] DateTime? date)
{

View File

@ -104,29 +104,16 @@ class KyooClient:
async def delete(
self,
path: str,
type: Literal["episode", "movie"] | None = None,
):
logger.info("Deleting %s", path)
if type is None or type == "movie":
async with self.client.delete(
f'{self._url}/movies?filter=path eq "{quote(path)}"',
headers={"X-API-Key": self._api_key},
) as r:
if not r.ok:
logger.error(f"Request error: {await r.text()}")
r.raise_for_status()
if type is None or type == "episode":
async with self.client.delete(
f'{self._url}/episodes?filter=path eq "{quote(path)}"',
headers={"X-API-Key": self._api_key},
) as r:
if not r.ok:
logger.error(f"Request error: {await r.text()}")
r.raise_for_status()
await self.delete_issue(path)
async with self.client.delete(
f'{self._url}/paths?recursive=true&path={quote(path)}',
headers={"X-API-Key": self._api_key},
) as r:
if not r.ok:
logger.error(f"Request error: {await r.text()}")
r.raise_for_status()
async def get(self, path: str):
async with self.client.get(