From c6c31702c22e981ed526dea7468efde3ddc34961 Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 11 Jul 2022 01:50:18 +0200 Subject: [PATCH] cheaper file deletion --- contrib/plugins/up2k-hook-ytid.js | 2 ++ copyparty/fsutil.py | 2 +- copyparty/up2k.py | 15 ++++++++++++--- copyparty/util.py | 19 +++++++++++++++++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/contrib/plugins/up2k-hook-ytid.js b/contrib/plugins/up2k-hook-ytid.js index 00961237..38b16ecd 100644 --- a/contrib/plugins/up2k-hook-ytid.js +++ b/contrib/plugins/up2k-hook-ytid.js @@ -1,6 +1,8 @@ // way more specific example -- // assumes all files dropped into the uploader have a youtube-id somewhere in the filename, // locates the youtube-ids and passes them to an API which returns a list of IDS which should be uploaded +// +// assumes copyparty is behind nginx as /ytq is a standalone service which must be rproxied in place function up2k_namefilter(good_files, nil_files, bad_files, hooks) { var filenames = [], diff --git a/copyparty/fsutil.py b/copyparty/fsutil.py index b1d3f3cd..26a7911a 100644 --- a/copyparty/fsutil.py +++ b/copyparty/fsutil.py @@ -2,8 +2,8 @@ from __future__ import print_function, unicode_literals import ctypes -import re import os +import re import time from .__init__ import ANYWIN, MACOS diff --git a/copyparty/up2k.py b/copyparty/up2k.py index 7332397a..fedfa140 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -35,6 +35,7 @@ from .util import ( quotep, ren_open, rmdirs, + rmdirs_up, s2hms, s3dec, s3enc, @@ -1857,11 +1858,12 @@ class Up2k(object): adir, fn = os.path.split(atop) try: st = bos.lstat(atop) + is_dir = stat.S_ISDIR(st.st_mode) except: raise Pebkac(400, "file not found on disk (already deleted?)") scandir = not self.args.no_scandir - if stat.S_ISDIR(st.st_mode): + if is_dir: g = vn.walk("", rem, [], uname, permsets, True, scandir, True) if unpost: raise Pebkac(400, "cannot unpost folders") @@ -1896,8 +1898,14 @@ class Up2k(object): bos.unlink(abspath) - rm = rmdirs(self.log_func, scandir, True, atop, 1) - return n_files, rm[0], rm[1] + ok: list[str] = [] + ng: list[str] = [] + if is_dir: + ok, ng = rmdirs(self.log_func, scandir, True, atop, 1) + + ok2, ng2 = rmdirs_up(os.path.dirname(atop)) + + return n_files, ok + ok2, ng + ng2 def handle_mv(self, uname: str, svp: str, dvp: str) -> str: svn, srem = self.asrv.vfs.get(svp, uname, True, False, True) @@ -1939,6 +1947,7 @@ class Up2k(object): self._mv_file(uname, svpf, dvpf) rmdirs(self.log_func, scandir, True, sabs, 1) + rmdirs_up(os.path.dirname(sabs)) return "k" def _mv_file(self, uname: str, svp: str, dvp: str) -> str: diff --git a/copyparty/util.py b/copyparty/util.py index 2d1b4aba..0d5f964f 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -1422,7 +1422,8 @@ def statdir( def rmdirs( logger: RootLogger, scandir: bool, lstat: bool, top: str, depth: int ) -> tuple[list[str], list[str]]: - if not os.path.exists(fsenc(top)) or not os.path.isdir(fsenc(top)): + """rmdir all descendants, then self""" + if not os.path.isdir(fsenc(top)): top = os.path.dirname(top) depth -= 1 @@ -1446,6 +1447,21 @@ def rmdirs( return ok, ng +def rmdirs_up(top: str) -> tuple[list[str], list[str]]: + """rmdir on self, then all parents""" + try: + os.rmdir(fsenc(top)) + except: + return [], [top] + + par = os.path.dirname(top) + if not par: + return [top], [] + + ok, ng = rmdirs_up(par) + return [top] + ok, ng + + def unescape_cookie(orig: str) -> str: # mw=idk; doot=qwe%2Crty%3Basd+fgh%2Bjkl%25zxc%26vbn # qwe,rty;asd fgh+jkl%zxc&vbn ret = "" @@ -1802,7 +1818,6 @@ def termsize() -> tuple[int, int]: def ioctl_GWINSZ(fd: int) -> Optional[tuple[int, int]]: try: import fcntl - import struct import termios cr = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, b"1234"))