|
13 | 13 | import mimetypes
|
14 | 14 | import nbformat
|
15 | 15 |
|
| 16 | +from send2trash import send2trash |
16 | 17 | from tornado import web
|
17 | 18 |
|
18 | 19 | from .filecheckpoints import FileCheckpoints
|
@@ -144,6 +145,11 @@ def _validate_root_dir(self, proposal):
|
144 | 145 | def _checkpoints_class_default(self):
|
145 | 146 | return FileCheckpoints
|
146 | 147 |
|
| 148 | + delete_to_trash = Bool(True, config=True, |
| 149 | + help="""If True (default), deleting files will send them to the |
| 150 | + platform's trash/recycle bin, where they can be recovered. If False, |
| 151 | + deleting files really deletes them.""") |
| 152 | + |
147 | 153 | def is_hidden(self, path):
|
148 | 154 | """Does the API style path correspond to a hidden directory or file?
|
149 | 155 |
|
@@ -464,6 +470,14 @@ def delete_file(self, path):
|
464 | 470 | elif not os.path.isfile(os_path):
|
465 | 471 | raise web.HTTPError(404, u'File does not exist: %s' % os_path)
|
466 | 472 |
|
| 473 | + if self.delete_to_trash: |
| 474 | + self.log.debug("Sending %s to trash", os_path) |
| 475 | + # Looking at the code in send2trash, I don't think the errors it |
| 476 | + # raises let us distinguish permission errors from other errors in |
| 477 | + # code. So for now, just let them all get logged as server errors. |
| 478 | + send2trash(os_path) |
| 479 | + return |
| 480 | + |
467 | 481 | if os.path.isdir(os_path):
|
468 | 482 | self.log.debug("Removing directory %s", os_path)
|
469 | 483 | with self.perm_to_403():
|
|
0 commit comments