mirror of
https://github.com/arsenetar/send2trash.git
synced 2025-05-07 09:29:48 +00:00
Add initial pyobjc version for macOS
This is to help with issue #51. Will not help in the case of python 2 or older python 3 version < 3.6.
This commit is contained in:
parent
10c7693d11
commit
530e9b4bc6
@ -4,53 +4,17 @@
|
|||||||
# which should be included with this package. The terms are also available at
|
# which should be included with this package. The terms are also available at
|
||||||
# http://www.hardcoded.net/licenses/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from platform import mac_ver
|
||||||
|
from sys import version_info
|
||||||
|
|
||||||
from ctypes import cdll, byref, Structure, c_char, c_char_p
|
# If macOS is 11.0 or newer try to use the pyobjc version to get around #51
|
||||||
from ctypes.util import find_library
|
# NOTE: pyobjc only supports python >= 3.6
|
||||||
|
if version_info >= (3, 6) and int(mac_ver()[0].split(".", 1)[0]) >= 11:
|
||||||
from .compat import binary_type
|
try:
|
||||||
|
from .plat_osx_pyobjc import send2trash
|
||||||
Foundation = cdll.LoadLibrary(find_library("Foundation"))
|
except ImportError:
|
||||||
CoreServices = cdll.LoadLibrary(find_library("CoreServices"))
|
# Try to fall back to ctypes version, although likely problematic still
|
||||||
|
from .plat_osx_ctypes import send2trash
|
||||||
GetMacOSStatusCommentString = Foundation.GetMacOSStatusCommentString
|
else:
|
||||||
GetMacOSStatusCommentString.restype = c_char_p
|
# Just use the old version otherwise
|
||||||
FSPathMakeRefWithOptions = CoreServices.FSPathMakeRefWithOptions
|
from .plat_osx_ctypes import send2trash # noqa: F401
|
||||||
FSMoveObjectToTrashSync = CoreServices.FSMoveObjectToTrashSync
|
|
||||||
|
|
||||||
kFSPathMakeRefDefaultOptions = 0
|
|
||||||
kFSPathMakeRefDoNotFollowLeafSymlink = 0x01
|
|
||||||
|
|
||||||
kFSFileOperationDefaultOptions = 0
|
|
||||||
kFSFileOperationOverwrite = 0x01
|
|
||||||
kFSFileOperationSkipSourcePermissionErrors = 0x02
|
|
||||||
kFSFileOperationDoNotMoveAcrossVolumes = 0x04
|
|
||||||
kFSFileOperationSkipPreflight = 0x08
|
|
||||||
|
|
||||||
|
|
||||||
class FSRef(Structure):
|
|
||||||
_fields_ = [("hidden", c_char * 80)]
|
|
||||||
|
|
||||||
|
|
||||||
def check_op_result(op_result):
|
|
||||||
if op_result:
|
|
||||||
msg = GetMacOSStatusCommentString(op_result).decode("utf-8")
|
|
||||||
raise OSError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def send2trash(paths):
|
|
||||||
if not isinstance(paths, list):
|
|
||||||
paths = [paths]
|
|
||||||
paths = [
|
|
||||||
path.encode("utf-8") if not isinstance(path, binary_type) else path
|
|
||||||
for path in paths
|
|
||||||
]
|
|
||||||
for path in paths:
|
|
||||||
fp = FSRef()
|
|
||||||
opts = kFSPathMakeRefDoNotFollowLeafSymlink
|
|
||||||
op_result = FSPathMakeRefWithOptions(path, opts, byref(fp), None)
|
|
||||||
check_op_result(op_result)
|
|
||||||
opts = kFSFileOperationDefaultOptions
|
|
||||||
op_result = FSMoveObjectToTrashSync(byref(fp), None, opts)
|
|
||||||
check_op_result(op_result)
|
|
||||||
|
56
send2trash/plat_osx_ctypes.py
Normal file
56
send2trash/plat_osx_ctypes.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Copyright 2017 Virgil Dupras
|
||||||
|
|
||||||
|
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from ctypes import cdll, byref, Structure, c_char, c_char_p
|
||||||
|
from ctypes.util import find_library
|
||||||
|
|
||||||
|
from .compat import binary_type
|
||||||
|
|
||||||
|
Foundation = cdll.LoadLibrary(find_library("Foundation"))
|
||||||
|
CoreServices = cdll.LoadLibrary(find_library("CoreServices"))
|
||||||
|
|
||||||
|
GetMacOSStatusCommentString = Foundation.GetMacOSStatusCommentString
|
||||||
|
GetMacOSStatusCommentString.restype = c_char_p
|
||||||
|
FSPathMakeRefWithOptions = CoreServices.FSPathMakeRefWithOptions
|
||||||
|
FSMoveObjectToTrashSync = CoreServices.FSMoveObjectToTrashSync
|
||||||
|
|
||||||
|
kFSPathMakeRefDefaultOptions = 0
|
||||||
|
kFSPathMakeRefDoNotFollowLeafSymlink = 0x01
|
||||||
|
|
||||||
|
kFSFileOperationDefaultOptions = 0
|
||||||
|
kFSFileOperationOverwrite = 0x01
|
||||||
|
kFSFileOperationSkipSourcePermissionErrors = 0x02
|
||||||
|
kFSFileOperationDoNotMoveAcrossVolumes = 0x04
|
||||||
|
kFSFileOperationSkipPreflight = 0x08
|
||||||
|
|
||||||
|
|
||||||
|
class FSRef(Structure):
|
||||||
|
_fields_ = [("hidden", c_char * 80)]
|
||||||
|
|
||||||
|
|
||||||
|
def check_op_result(op_result):
|
||||||
|
if op_result:
|
||||||
|
msg = GetMacOSStatusCommentString(op_result).decode("utf-8")
|
||||||
|
raise OSError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def send2trash(paths):
|
||||||
|
if not isinstance(paths, list):
|
||||||
|
paths = [paths]
|
||||||
|
paths = [
|
||||||
|
path.encode("utf-8") if not isinstance(path, binary_type) else path
|
||||||
|
for path in paths
|
||||||
|
]
|
||||||
|
for path in paths:
|
||||||
|
fp = FSRef()
|
||||||
|
opts = kFSPathMakeRefDoNotFollowLeafSymlink
|
||||||
|
op_result = FSPathMakeRefWithOptions(path, opts, byref(fp), None)
|
||||||
|
check_op_result(op_result)
|
||||||
|
opts = kFSFileOperationDefaultOptions
|
||||||
|
op_result = FSMoveObjectToTrashSync(byref(fp), None, opts)
|
||||||
|
check_op_result(op_result)
|
29
send2trash/plat_osx_pyobjc.py
Normal file
29
send2trash/plat_osx_pyobjc.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright 2017 Virgil Dupras
|
||||||
|
|
||||||
|
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
|
from Foundation import NSFileManager, NSURL
|
||||||
|
from .compat import text_type
|
||||||
|
|
||||||
|
|
||||||
|
def check_op_result(op_result):
|
||||||
|
# First value will be false on failure
|
||||||
|
if not op_result[0]:
|
||||||
|
# Error is in third value, localized failure reason matchs ctypes version
|
||||||
|
raise OSError(op_result[2].localizedFailureReason())
|
||||||
|
|
||||||
|
|
||||||
|
def send2trash(paths):
|
||||||
|
if not isinstance(paths, list):
|
||||||
|
paths = [paths]
|
||||||
|
paths = [
|
||||||
|
path.decode("utf-8") if not isinstance(path, text_type) else path
|
||||||
|
for path in paths
|
||||||
|
]
|
||||||
|
for path in paths:
|
||||||
|
file_url = NSURL.fileURLWithPath_(path)
|
||||||
|
fm = NSFileManager.defaultManager()
|
||||||
|
op_result = fm.trashItemAtURL_resultingItemURL_error_(file_url, None, None)
|
||||||
|
check_op_result(op_result)
|
Loading…
x
Reference in New Issue
Block a user