1# Copyright 2017 Virgil Dupras
2
3# This software is licensed under the "BSD" License as described in the "LICENSE" file,
4# which should be included with this package. The terms are also available at
5# http://www.hardcoded.net/licenses/bsd_license
6
7from __future__ import unicode_literals
8
9from ctypes import cdll, byref, Structure, c_char, c_char_p
10from ctypes.util import find_library
11
12from .compat import binary_type
13from .util import preprocess_paths
14
15Foundation = cdll.LoadLibrary(find_library("Foundation"))
16CoreServices = cdll.LoadLibrary(find_library("CoreServices"))
17
18GetMacOSStatusCommentString = Foundation.GetMacOSStatusCommentString
19GetMacOSStatusCommentString.restype = c_char_p
20FSPathMakeRefWithOptions = CoreServices.FSPathMakeRefWithOptions
21FSMoveObjectToTrashSync = CoreServices.FSMoveObjectToTrashSync
22
23kFSPathMakeRefDefaultOptions = 0
24kFSPathMakeRefDoNotFollowLeafSymlink = 0x01
25
26kFSFileOperationDefaultOptions = 0
27kFSFileOperationOverwrite = 0x01
28kFSFileOperationSkipSourcePermissionErrors = 0x02
29kFSFileOperationDoNotMoveAcrossVolumes = 0x04
30kFSFileOperationSkipPreflight = 0x08
31
32
33class FSRef(Structure):
34    _fields_ = [("hidden", c_char * 80)]
35
36
37def check_op_result(op_result):
38    if op_result:
39        msg = GetMacOSStatusCommentString(op_result).decode("utf-8")
40        raise OSError(msg)
41
42
43def send2trash(paths):
44    paths = preprocess_paths(paths)
45    paths = [
46        path.encode("utf-8") if not isinstance(path, binary_type) else path
47        for path in paths
48    ]
49    for path in paths:
50        fp = FSRef()
51        opts = kFSPathMakeRefDoNotFollowLeafSymlink
52        op_result = FSPathMakeRefWithOptions(path, opts, byref(fp), None)
53        check_op_result(op_result)
54        opts = kFSFileOperationDefaultOptions
55        op_result = FSMoveObjectToTrashSync(byref(fp), None, opts)
56        check_op_result(op_result)
57