delayed-rm 2.9.3__tar.gz → 2.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: delayed_rm
3
- Version: 2.9.3
3
+ Version: 2.11.0
4
4
  Summary: Ever wish you had a few minutes to undo an rm? Now you do!
5
5
  License: GPLv3
6
6
  Project-URL: Homepage, https://github.com/zwimer/delayed_rm
@@ -12,6 +12,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
12
12
  Requires-Python: >=3.10
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
+ Dynamic: license-file
15
16
 
16
17
  # delayed\_rm
17
18
  Ever wish you had a few minutes to undo an rm? Now you do!
@@ -8,11 +8,12 @@ import subprocess
8
8
  import argparse
9
9
  import tempfile
10
10
  import shutil
11
+ import math
11
12
  import time
12
13
  import sys
13
14
 
14
15
 
15
- __version__ = "2.9.3"
16
+ __version__ = "2.11.0"
16
17
 
17
18
 
18
19
  #
@@ -51,6 +52,17 @@ class _Secret:
51
52
  #
52
53
 
53
54
 
55
+ def _size(p: Path) -> str:
56
+ """
57
+ Get file size as a human readable string
58
+ This does follow symlinks
59
+ """
60
+ s = p.stat().st_size
61
+ lg = int(math.log(s, 1000))
62
+ si = " KMGT"[lg].replace(" ", "")
63
+ return f"{round(s/(1000**lg))} {si}B"
64
+
65
+
54
66
  def _eprint(e: str | BaseException) -> None:
55
67
  """
56
68
  Print e to stderr
@@ -88,7 +100,7 @@ def _prep(paths: list[Path], rf: bool) -> list[Path]:
88
100
  except (FileNotFoundError, RuntimeError) as e:
89
101
  raise RMError(e) from e
90
102
  for i in paths:
91
- if not rf and not i.is_symlink() and i.is_dir():
103
+ if not rf and i.is_dir() and not i.is_symlink():
92
104
  raise RMError(f"{i} is a directory. -rf required!")
93
105
  if tmp_d == i:
94
106
  raise RMError(f"Will not delete {tmp_d}")
@@ -107,7 +119,7 @@ def _prep(paths: list[Path], rf: bool) -> list[Path]:
107
119
 
108
120
  def delayed_rm(paths: list[Path], delay: int, rf: bool) -> bool:
109
121
  """
110
- Move paths to a temprary directory, delete them after delay seconds
122
+ Move paths to a temporary directory, delete them after delay seconds
111
123
  Log's this action to the log
112
124
  If rf, acts like rm -rf
113
125
  May raise an RMError if something goes wrong
@@ -147,7 +159,7 @@ def delayed_rm(paths: list[Path], delay: int, rf: bool) -> bool:
147
159
  edited = True
148
160
  except OSError:
149
161
  copyf = lambda src, dst: shutil.copy2(src, dst, follow_symlinks=False)
150
- if p.is_dir():
162
+ if p.is_dir() and not p.is_symlink():
151
163
  shutil.copytree(p, new, copy_function=copyf, symlinks=False)
152
164
  edited = True
153
165
  shutil.rmtree(p)
@@ -213,7 +225,7 @@ def delayed_rm_raw(delay: int, log: bool, r: bool, f: bool, paths: list[Path]) -
213
225
  if r or f or paths:
214
226
  _eprint("--log may not be used with other arguments")
215
227
  return False
216
- print(f"{log_f.read_text()}Log file: {log_f}" if log_f.exists() else "Log is empty")
228
+ print(f"{log_f.read_text()}Log file ({_size(log_f)}): {log_f}" if log_f.exists() else "Log is empty")
217
229
  return True
218
230
  if not paths:
219
231
  _eprint("nothing to remove")
@@ -250,21 +262,28 @@ def cli() -> None:
250
262
  #
251
263
 
252
264
 
253
- def _secret_cli():
265
+ def _secret_cli() -> None:
254
266
  """
255
267
  This CLI is invoked on import and not will do nothing by default
256
268
  This CLI will only activate if argv was intentionally configured to do so
257
269
  This entrypoint is for the spawned process to act
258
270
  """
271
+ if len(sys.argv) > 1 and sys.argv[1] == "--force-cli":
272
+ del sys.argv[1]
273
+ cli()
259
274
  try:
260
- if len(sys.argv) == 4 and sys.argv[1] == _Secret.value:
261
- if environ.get(_Secret.key, None) == _Secret.value:
262
- delay = int(sys.argv[2])
263
- d = Path(sys.argv[3]).resolve()
264
- time.sleep(delay)
265
- shutil.rmtree(d)
266
- with log_f.open("a") as f:
267
- f.write(f"Removing: {d}" + "\n\n")
275
+ if len(sys.argv) != 4 or sys.argv[1] != _Secret.value or environ.get(_Secret.key, None) != _Secret.value:
276
+ print(
277
+ "This script should be run by invoking the cli() function.\n"
278
+ "Pass --force-cli as the first argument to bypass this restriction.",
279
+ file=sys.stderr,
280
+ )
281
+ sys.exit(1)
282
+ d = Path(sys.argv[3]).resolve()
283
+ time.sleep(int(sys.argv[2]))
284
+ shutil.rmtree(d)
285
+ with log_f.open("a") as f:
286
+ f.write(f"Removing: {d}" + "\n\n")
268
287
  except Exception:
269
288
  sys.stderr = log_f.open("a")
270
289
  sys.stdout = sys.stderr
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: delayed_rm
3
- Version: 2.9.3
3
+ Version: 2.11.0
4
4
  Summary: Ever wish you had a few minutes to undo an rm? Now you do!
5
5
  License: GPLv3
6
6
  Project-URL: Homepage, https://github.com/zwimer/delayed_rm
@@ -12,6 +12,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
12
12
  Requires-Python: >=3.10
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
+ Dynamic: license-file
15
16
 
16
17
  # delayed\_rm
17
18
  Ever wish you had a few minutes to undo an rm? Now you do!
File without changes
File without changes
File without changes
File without changes