Allow deleting explorer images
Browse files- app.py +15 -0
- explorer.js +24 -0
app.py
CHANGED
|
@@ -1928,6 +1928,21 @@ def image_download(body: DownloadRequest):
|
|
| 1928 |
)
|
| 1929 |
|
| 1930 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1931 |
def login(p):
|
| 1932 |
if not valid_pass(p):
|
| 1933 |
raise gr.Error("Invalid password")
|
|
|
|
| 1928 |
)
|
| 1929 |
|
| 1930 |
|
| 1931 |
+
@api.post(
|
| 1932 |
+
"/api/images/delete",
|
| 1933 |
+
dependencies=[Depends(require_pass)],
|
| 1934 |
+
)
|
| 1935 |
+
def image_delete(body: DownloadRequest):
|
| 1936 |
+
paths = selected_paths(body.items)
|
| 1937 |
+
for path in paths.values():
|
| 1938 |
+
path.unlink()
|
| 1939 |
+
for value in body.items:
|
| 1940 |
+
path = (IMAGE_DIR / value).resolve()
|
| 1941 |
+
if path.is_dir() and not any(path.iterdir()):
|
| 1942 |
+
path.rmdir()
|
| 1943 |
+
return {"deleted": len(paths)}
|
| 1944 |
+
|
| 1945 |
+
|
| 1946 |
def login(p):
|
| 1947 |
if not valid_pass(p):
|
| 1948 |
raise gr.Error("Invalid password")
|
explorer.js
CHANGED
|
@@ -20,6 +20,7 @@ class ImageExplorer extends HTMLElement {
|
|
| 20 |
<button class="all" type="button">Select all</button>
|
| 21 |
<button class="clear" type="button">Clear</button>
|
| 22 |
<button class="download primary" type="button">Download 7z</button>
|
|
|
|
| 23 |
</div>
|
| 24 |
<div class="status">Loading</div>
|
| 25 |
<div class="content"></div>
|
|
@@ -34,6 +35,7 @@ class ImageExplorer extends HTMLElement {
|
|
| 34 |
$(".all", this).addEventListener("click", () => this.select(true))
|
| 35 |
$(".clear", this).addEventListener("click", () => this.select(false))
|
| 36 |
$(".download", this).addEventListener("click", () => this.download())
|
|
|
|
| 37 |
$("input[type=search]", this).addEventListener("input", event => {
|
| 38 |
this.filter(event.target.value)
|
| 39 |
})
|
|
@@ -179,6 +181,28 @@ class ImageExplorer extends HTMLElement {
|
|
| 179 |
this.update()
|
| 180 |
}
|
| 181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
setupLightbox() {
|
| 183 |
const dialog = $(".lightbox", this)
|
| 184 |
const viewer = $(".viewer", dialog)
|
|
|
|
| 20 |
<button class="all" type="button">Select all</button>
|
| 21 |
<button class="clear" type="button">Clear</button>
|
| 22 |
<button class="download primary" type="button">Download 7z</button>
|
| 23 |
+
<button class="delete" type="button">Delete</button>
|
| 24 |
</div>
|
| 25 |
<div class="status">Loading</div>
|
| 26 |
<div class="content"></div>
|
|
|
|
| 35 |
$(".all", this).addEventListener("click", () => this.select(true))
|
| 36 |
$(".clear", this).addEventListener("click", () => this.select(false))
|
| 37 |
$(".download", this).addEventListener("click", () => this.download())
|
| 38 |
+
$(".delete", this).addEventListener("click", () => this.delete())
|
| 39 |
$("input[type=search]", this).addEventListener("input", event => {
|
| 40 |
this.filter(event.target.value)
|
| 41 |
})
|
|
|
|
| 181 |
this.update()
|
| 182 |
}
|
| 183 |
|
| 184 |
+
async delete() {
|
| 185 |
+
const items = $$(".item:checked", this).map(input => input.dataset.path)
|
| 186 |
+
if (!items.length || !confirm(`Delete ${items.length} selected item(s)?`)) return
|
| 187 |
+
const button = $(".delete", this)
|
| 188 |
+
button.disabled = true
|
| 189 |
+
$(".status", this).textContent = "Deleting"
|
| 190 |
+
try {
|
| 191 |
+
const response = await fetch(api("/api/images/delete"), {
|
| 192 |
+
method: "POST",
|
| 193 |
+
headers: { "Content-Type": "application/json" },
|
| 194 |
+
body: JSON.stringify({ items }),
|
| 195 |
+
})
|
| 196 |
+
if (!response.ok) throw new Error("Delete failed")
|
| 197 |
+
this.cache.clear()
|
| 198 |
+
await this.load(this.folder)
|
| 199 |
+
} catch (error) {
|
| 200 |
+
$(".status", this).textContent = error.message
|
| 201 |
+
} finally {
|
| 202 |
+
button.disabled = false
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
setupLightbox() {
|
| 207 |
const dialog = $(".lightbox", this)
|
| 208 |
const viewer = $(".viewer", dialog)
|