- Fix Delete button in webdav

- Other bug fixes
This commit is contained in:
Mukhtar Akere
2025-05-16 16:43:01 +01:00
parent b984697fe3
commit 35a74d8dba
6 changed files with 50 additions and 23 deletions

View File

@@ -650,8 +650,7 @@ func (c *Cache) DeleteTorrent(id string) error {
defer c.torrentsRefreshMu.Unlock() defer c.torrentsRefreshMu.Unlock()
if c.deleteTorrent(id, true) { if c.deleteTorrent(id, true) {
c.listingDebouncer.Call(true) go c.RefreshListings(true)
c.logger.Trace().Msgf("Torrent %s deleted successfully", id)
return nil return nil
} }
return nil return nil

View File

@@ -12,6 +12,7 @@ import (
) )
type fileInfo struct { type fileInfo struct {
id string
name string name string
size int64 size int64
mode os.FileMode mode os.FileMode
@@ -24,6 +25,7 @@ func (fi *fileInfo) Size() int64 { return fi.size }
func (fi *fileInfo) Mode() os.FileMode { return fi.mode } func (fi *fileInfo) Mode() os.FileMode { return fi.mode }
func (fi *fileInfo) ModTime() time.Time { return fi.modTime } func (fi *fileInfo) ModTime() time.Time { return fi.modTime }
func (fi *fileInfo) IsDir() bool { return fi.isDir } func (fi *fileInfo) IsDir() bool { return fi.isDir }
func (fi *fileInfo) ID() string { return fi.id }
func (fi *fileInfo) Sys() interface{} { return nil } func (fi *fileInfo) Sys() interface{} { return nil }
func (c *Cache) RefreshListings(refreshRclone bool) { func (c *Cache) RefreshListings(refreshRclone bool) {

View File

@@ -143,7 +143,7 @@ func (tc *torrentCache) refreshListing() {
go func() { go func() {
listing := make([]os.FileInfo, len(all)) listing := make([]os.FileInfo, len(all))
for i, sf := range all { for i, sf := range all {
listing[i] = &fileInfo{sf.name, sf.size, 0755 | os.ModeDir, sf.modTime, true} listing[i] = &fileInfo{sf.id, sf.name, sf.size, 0755 | os.ModeDir, sf.modTime, true}
} }
tc.listing.Store(listing) tc.listing.Store(listing)
}() }()
@@ -156,7 +156,8 @@ func (tc *torrentCache) refreshListing() {
for _, sf := range all { for _, sf := range all {
if sf.bad { if sf.bad {
listing = append(listing, &fileInfo{ listing = append(listing, &fileInfo{
name: fmt.Sprintf("%s(%s)", sf.name, sf.id), id: sf.id,
name: fmt.Sprintf("%s || %s", sf.name, sf.id),
size: sf.size, size: sf.size,
mode: 0755 | os.ModeDir, mode: 0755 | os.ModeDir,
modTime: sf.modTime, modTime: sf.modTime,
@@ -183,6 +184,7 @@ func (tc *torrentCache) refreshListing() {
for _, sf := range all { for _, sf := range all {
if tc.torrentMatchDirectory(filters, sf, now) { if tc.torrentMatchDirectory(filters, sf, now) {
matched = append(matched, &fileInfo{ matched = append(matched, &fileInfo{
id: sf.id,
name: sf.name, size: sf.size, name: sf.name, size: sf.size,
mode: 0755 | os.ModeDir, modTime: sf.modTime, isDir: true, mode: 0755 | os.ModeDir, modTime: sf.modTime, isDir: true,
}) })

View File

@@ -7,6 +7,7 @@ import (
// FileInfo implements os.FileInfo for our WebDAV files // FileInfo implements os.FileInfo for our WebDAV files
type FileInfo struct { type FileInfo struct {
id string
name string name string
size int64 size int64
mode os.FileMode mode os.FileMode
@@ -19,4 +20,5 @@ func (fi *FileInfo) Size() int64 { return fi.size }
func (fi *FileInfo) Mode() os.FileMode { return fi.mode } func (fi *FileInfo) Mode() os.FileMode { return fi.mode }
func (fi *FileInfo) ModTime() time.Time { return fi.modTime } func (fi *FileInfo) ModTime() time.Time { return fi.modTime }
func (fi *FileInfo) IsDir() bool { return fi.isDir } func (fi *FileInfo) IsDir() bool { return fi.isDir }
func (fi *FileInfo) ID() string { return fi.id }
func (fi *FileInfo) Sys() interface{} { return nil } func (fi *FileInfo) Sys() interface{} { return nil }

View File

@@ -258,25 +258,27 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
case "PROPFIND": case "PROPFIND":
h.handlePropfind(w, r) h.handlePropfind(w, r)
return return
case "DELETE":
default: if err := h.handleDelete(w, r); err == nil {
handler := &webdav.Handler{ return
FileSystem: h,
LockSystem: webdav.NewMemLS(),
Logger: func(r *http.Request, err error) {
if err != nil {
h.logger.Trace().
Err(err).
Str("method", r.Method).
Str("path", r.URL.Path).
Msg("WebDAV error")
}
},
} }
handler.ServeHTTP(w, r) // fallthrough to default
return
} }
handler := &webdav.Handler{
FileSystem: h,
LockSystem: webdav.NewMemLS(),
Logger: func(r *http.Request, err error) {
if err != nil {
h.logger.Trace().
Err(err).
Str("method", r.Method).
Str("path", r.URL.Path).
Msg("WebDAV error")
}
},
}
handler.ServeHTTP(w, r)
return
} }
func getContentType(fileName string) string { func getContentType(fileName string) string {
@@ -459,3 +461,22 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) {
w.Header().Set("DAV", "1, 2") w.Header().Set("DAV", "1, 2")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }
// handleDelete deletes a torrent from using id
func (h *Handler) handleDelete(w http.ResponseWriter, r *http.Request) error {
cleanPath := path.Clean(r.URL.Path) // Remove any leading slashes
_, torrentId := path.Split(cleanPath)
if torrentId == "" {
return os.ErrNotExist
}
cachedTorrent := h.cache.GetTorrent(torrentId)
if cachedTorrent == nil {
return os.ErrNotExist
}
h.cache.OnRemove(cachedTorrent.Id)
w.WriteHeader(http.StatusNoContent)
return nil
}

View File

@@ -119,7 +119,8 @@
{{- if and $.CanDelete }} {{- if and $.CanDelete }}
<button <button
class="delete-btn" class="delete-btn"
data-path="{{printf "%s/%s" $.Path $file.Name}}"> data-name="{{$file.Name}}"
data-path="{{printf "%s/%s" $.Path $file.ID}}">
Delete Delete
</button> </button>
{{- end}} {{- end}}
@@ -130,7 +131,7 @@
document.querySelectorAll('.delete-btn').forEach(btn=>{ document.querySelectorAll('.delete-btn').forEach(btn=>{
btn.addEventListener('click', ()=>{ btn.addEventListener('click', ()=>{
let p = btn.getAttribute('data-path'); let p = btn.getAttribute('data-path');
let name = p.split('/').pop(); let name = btn.getAttribute('data-name');
if(!confirm('Delete '+name+'?')) return; if(!confirm('Delete '+name+'?')) return;
fetch(p, { method: 'DELETE' }) fetch(p, { method: 'DELETE' })
.then(_=>location.reload()); .then(_=>location.reload());