Compare commits

...

2 Commits

Author SHA1 Message Date
Andrew Senetar 2aa834be94
Update version & changelog for 1.8.1b0 2021-08-20 22:42:04 -05:00
Andrew Senetar 5e4517aa53
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.
2021-08-20 22:30:51 -05:00
3 changed files with 21 additions and 5 deletions

View File

@ -1,6 +1,10 @@
Changes Changes
======= =======
Version 1.8.1b0 -- 2021/09/20
-----------------------------
* Add fallback to HOMETRASH when cross device errors happen in plat_other (#26, $41, #63)
Version 1.8.0 -- 2021/08/08 Version 1.8.0 -- 2021/08/08
--------------------------- ---------------------------

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

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
name = Send2Trash name = Send2Trash
version = 1.8.0 version = 1.8.1b0
url = https://github.com/arsenetar/send2trash url = https://github.com/arsenetar/send2trash
project_urls = project_urls =
Bug Reports = https://github.com/arsenetar/send2trash/issues Bug Reports = https://github.com/arsenetar/send2trash/issues