mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add delete route that allow recursive delete for directories
This commit is contained in:
parent
fccc5b6ad9
commit
9e089b21ed
@ -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>()
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user