|
14 | 14 | import mimetypes
|
15 | 15 | import nbformat
|
16 | 16 |
|
| 17 | +from send2trash import send2trash |
17 | 18 | from tornado import web
|
18 | 19 |
|
19 | 20 | from .filecheckpoints import FileCheckpoints
|
@@ -149,6 +150,11 @@ def _validate_root_dir(self, proposal):
|
149 | 150 | def _checkpoints_class_default(self):
|
150 | 151 | return FileCheckpoints
|
151 | 152 |
|
| 153 | + delete_to_trash = Bool(True, config=True, |
| 154 | + help="""If True (default), deleting files will send them to the |
| 155 | + platform's trash/recycle bin, where they can be recovered. If False, |
| 156 | + deleting files really deletes them.""") |
| 157 | + |
152 | 158 | @default('files_handler_class')
|
153 | 159 | def _files_handler_class_default(self):
|
154 | 160 | return AuthenticatedFileHandler
|
@@ -493,6 +499,14 @@ def delete_file(self, path):
|
493 | 499 | elif not os.path.isfile(os_path):
|
494 | 500 | raise web.HTTPError(404, u'File does not exist: %s' % os_path)
|
495 | 501 |
|
| 502 | + if self.delete_to_trash: |
| 503 | + self.log.debug("Sending %s to trash", os_path) |
| 504 | + # Looking at the code in send2trash, I don't think the errors it |
| 505 | + # raises let us distinguish permission errors from other errors in |
| 506 | + # code. So for now, just let them all get logged as server errors. |
| 507 | + send2trash(os_path) |
| 508 | + return |
| 509 | + |
496 | 510 | if os.path.isdir(os_path):
|
497 | 511 | self.log.debug("Removing directory %s", os_path)
|
498 | 512 | with self.perm_to_403():
|
|
0 commit comments