Add fallback to HOMETRASH on plat_other

In the case where os.path.ismount() does not detect a mount and os.rename errors
fallback to HOMETRASH.  This covers several situations where continuing with
the identified trash location is incorrect due to complex mounts.

Close #26, #41, #63.
This commit is contained in:
Andrew Senetar 2021-08-20 22:30:51 -05:00
parent 62849fba0b
commit 5e4517aa53
Signed by: arsenetar
GPG Key ID: C63300DCE48AB2F1
1 changed files with 16 additions and 4 deletions

View File

@ -19,6 +19,7 @@ from __future__ import unicode_literals
import errno import errno
import sys import sys
import os import os
import shutil
import os.path as op import os.path as op
from datetime import datetime from datetime import datetime
import stat import stat
@ -95,7 +96,7 @@ def check_create(dir):
os.makedirs(dir, 0o700) os.makedirs(dir, 0o700)
def trash_move(src, dst, topdir=None): def trash_move(src, dst, topdir=None, cross_dev=False):
filename = op.basename(src) filename = op.basename(src)
filespath = op.join(dst, FILES_DIR) filespath = op.join(dst, FILES_DIR)
infopath = op.join(dst, INFO_DIR) infopath = op.join(dst, INFO_DIR)
@ -112,14 +113,18 @@ def trash_move(src, dst, topdir=None):
with open(op.join(infopath, destname + INFO_SUFFIX), "w") as f: with open(op.join(infopath, destname + INFO_SUFFIX), "w") as f:
f.write(info_for(src, topdir)) f.write(info_for(src, topdir))
os.rename(src, op.join(filespath, destname)) destpath = op.join(filespath, destname)
if cross_dev:
shutil.move(src, destpath)
else:
os.rename(src, destpath)
def find_mount_point(path): def find_mount_point(path):
# Even if something's wrong, "/" is a mount point, so the loop will exit. # Even if something's wrong, "/" is a mount point, so the loop will exit.
# Use realpath in case it's a symlink # Use realpath in case it's a symlink
path = op.realpath(path) # Required to avoid infinite loop path = op.realpath(path) # Required to avoid infinite loop
while not op.ismount(path): while not op.ismount(path): # Note ismount() does not always detect mounts
path = op.split(path)[0] path = op.split(path)[0]
return path return path
@ -206,4 +211,11 @@ def send2trash(paths):
if trash_dev != path_dev: if trash_dev != path_dev:
raise OSError("Couldn't find mount point for %s" % path) raise OSError("Couldn't find mount point for %s" % path)
dest_trash = find_ext_volume_trash(topdir) dest_trash = find_ext_volume_trash(topdir)
trash_move(path_b, dest_trash, topdir) try:
trash_move(path_b, dest_trash, topdir)
except OSError as error:
# Cross link errors default back to HOMETRASH
if error.errno == errno.EXDEV:
trash_move(path_b, HOMETRASH_B, XDG_DATA_HOME, cross_dev=True)
else:
raise