mirror of
https://github.com/arsenetar/send2trash.git
synced 2025-05-08 09:49:52 +00:00
Merged default branch with py3k. Py3k version of send2trash is now the default one (python 2 version is in the py2k branch).
This commit is contained in:
commit
a8a771c9bd
1
.hgtags
1
.hgtags
@ -1,2 +1,3 @@
|
|||||||
48c2103380f5e7deca49364f44fb31ded9942bb7 1.0.0
|
48c2103380f5e7deca49364f44fb31ded9942bb7 1.0.0
|
||||||
a7e04d8e47e161daaa1f031a7c1e98c52fa269ac 1.0.1
|
a7e04d8e47e161daaa1f031a7c1e98c52fa269ac 1.0.1
|
||||||
|
de5f43fcce5e776eb28306951939afb9946cbd3d 1.1.0
|
||||||
|
14
CHANGES
14
CHANGES
@ -1,14 +1,22 @@
|
|||||||
|
Changes
|
||||||
|
=======
|
||||||
|
|
||||||
|
Version 1.1.0 -- 2010/10/18
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* Converted compiled modules to ctypes so that cross-platform compilation isn't necessary anymore.
|
||||||
|
|
||||||
Version 1.0.2 -- 2010/07/10
|
Version 1.0.2 -- 2010/07/10
|
||||||
---
|
---------------------------
|
||||||
|
|
||||||
* Fixed bugs with external volumes in plat_other.
|
* Fixed bugs with external volumes in plat_other.
|
||||||
|
|
||||||
Version 1.0.1 -- 2010/04/19
|
Version 1.0.1 -- 2010/04/19
|
||||||
---
|
---------------------------
|
||||||
|
|
||||||
* Fixed memory leak in OS X module.
|
* Fixed memory leak in OS X module.
|
||||||
|
|
||||||
Version 1.0.0 -- 2010/04/07
|
Version 1.0.0 -- 2010/04/07
|
||||||
---
|
---------------------------
|
||||||
|
|
||||||
* Initial Release
|
* Initial Release
|
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@ -0,0 +1 @@
|
|||||||
|
include CHANGES
|
12
README
12
README
@ -2,23 +2,19 @@
|
|||||||
Send2Trash -- Send files to trash on all platforms
|
Send2Trash -- Send files to trash on all platforms
|
||||||
==================================================
|
==================================================
|
||||||
|
|
||||||
This is a Python 2 package. The Python 3 package is at http://pypi.python.org/pypi/Send2Trash3k .
|
This is a Python 3 package. The Python 2 package is at http://pypi.python.org/pypi/Send2Trash .
|
||||||
|
|
||||||
Send2Trash is a small package that sends files to the Trash (or Recycle Bin) *natively* and on
|
Send2Trash is a small package that sends files to the Trash (or Recycle Bin) *natively* and on
|
||||||
*all platforms*. On OS X, it uses native ``FSMoveObjectToTrashSync`` Cocoa calls, on Windows, it uses native (and ugly) ``SHFileOperation`` win32 calls. On other platforms, it moves the file to the first folder it finds that looks like a trash (so far, it's known to work on Ubuntu).
|
*all platforms*. On OS X, it uses native ``FSMoveObjectToTrashSync`` Cocoa calls, on Windows, it uses native (and ugly) ``SHFileOperation`` win32 calls. On other platforms, it moves the file to the first folder it finds that looks like a trash (so far, it's known to work on Ubuntu).
|
||||||
|
|
||||||
|
``ctypes`` is used to access native libraries, so no compilation is necessary.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Download the source from http://hg.hardcoded.net/send2trash and install it with::
|
Download the source from http://hg.hardcoded.net/send2trash and install it with::
|
||||||
|
|
||||||
>>> sudo python setup.py install
|
>>> python setup.py install
|
||||||
|
|
||||||
On Windows, you'll need Visual Studio 2008 to compile it. Note that the install you'll get will not be a "universal" package. If you install it on OS X, only the "osx" module will be compiled, and if you install it on Windows, only the "win" module will be compiled.
|
|
||||||
|
|
||||||
To have a cross-platform package you can ship around, you'll have compile the package on both platforms and merge the results so that both compiled modules are in the same package.
|
|
||||||
|
|
||||||
There's no package available on PyPI because packages produced by setuptools/distribute are all crappy (god I hate packaging). That's, I think, because I look at ``sys.platform`` to determine which of the extension module (if any) has to be built. However, when I create a ``sdist``, only the module of the platform I build it on is included in the source package. I don't know how to go around that and configuring that ``setup()`` function is hell. Just download the source from the repo.
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/* Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
|
||||||
#include "Python.h"
|
|
||||||
#include <CoreServices/CoreServices.h>
|
|
||||||
|
|
||||||
static PyObject* send2trash_osx_send(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
UInt8 *utf8_chars;
|
|
||||||
FSRef fp;
|
|
||||||
OSStatus op_result;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "es", "utf-8", &utf8_chars)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSPathMakeRefWithOptions(utf8_chars, kFSPathMakeRefDoNotFollowLeafSymlink, &fp, NULL);
|
|
||||||
op_result = FSMoveObjectToTrashSync(&fp, NULL, kFSFileOperationDefaultOptions);
|
|
||||||
PyMem_Free(utf8_chars);
|
|
||||||
if (op_result != noErr) {
|
|
||||||
PyErr_SetString(PyExc_OSError, GetMacOSStatusCommentString(op_result));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return Py_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyMethodDef TrashMethods[] = {
|
|
||||||
{"send", send2trash_osx_send, METH_VARARGS, ""},
|
|
||||||
{NULL, NULL, 0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
init_send2trash_osx(void)
|
|
||||||
{
|
|
||||||
PyObject *m = Py_InitModule("_send2trash_osx", TrashMethods);
|
|
||||||
if (m == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
|||||||
/* Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
|
||||||
#include "Python.h"
|
|
||||||
|
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
|
||||||
#include "windows.h"
|
|
||||||
#include "shlobj.h"
|
|
||||||
|
|
||||||
/* WARNING: If the filepath is not fully qualified, Windows deletes the file
|
|
||||||
rather than sending it to trash.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static PyObject* send2trash_win_send(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
SHFILEOPSTRUCTW op;
|
|
||||||
PyObject *filepath;
|
|
||||||
Py_ssize_t len;
|
|
||||||
WCHAR filechars[MAX_PATH+1];
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &filepath)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PyUnicode_Check(filepath)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Unicode filename required");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = PyUnicode_GET_SIZE(filepath);
|
|
||||||
memcpy(filechars, PyUnicode_AsUnicode(filepath), sizeof(WCHAR)*len);
|
|
||||||
filechars[len] = '\0';
|
|
||||||
filechars[len+1] = '\0';
|
|
||||||
|
|
||||||
op.hwnd = 0;
|
|
||||||
op.wFunc = FO_DELETE;
|
|
||||||
op.pFrom = (LPCWSTR)&filechars;
|
|
||||||
op.pTo = NULL;
|
|
||||||
op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
|
|
||||||
r = SHFileOperationW(&op);
|
|
||||||
|
|
||||||
if (r != 0) {
|
|
||||||
PyErr_Format(PyExc_OSError, "Couldn't perform operation. Error code: %d", r);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Py_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyMethodDef TrashMethods[] = {
|
|
||||||
{"send", send2trash_win_send, METH_VARARGS, ""},
|
|
||||||
{NULL, NULL, 0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
init_send2trash_win(void)
|
|
||||||
{
|
|
||||||
PyObject *m = Py_InitModule("_send2trash_win", TrashMethods);
|
|
||||||
if (m == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,8 +7,8 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
from plat_osx import send2trash
|
from .plat_osx import send2trash
|
||||||
elif sys.platform == 'win32':
|
elif sys.platform == 'win32':
|
||||||
from plat_win import send2trash
|
from .plat_win import send2trash
|
||||||
else:
|
else:
|
||||||
from plat_other import send2trash
|
from .plat_other import send2trash
|
||||||
|
@ -4,9 +4,41 @@
|
|||||||
# 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
|
||||||
|
|
||||||
import _send2trash_osx
|
from ctypes import cdll, byref, Structure, c_char, c_char_p
|
||||||
|
from ctypes.util import find_library
|
||||||
|
|
||||||
|
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(path):
|
def send2trash(path):
|
||||||
if not isinstance(path, unicode):
|
if not isinstance(path, bytes):
|
||||||
path = unicode(path, 'utf-8')
|
path = path.encode('utf-8')
|
||||||
_send2trash_osx.send(path)
|
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)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# 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
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import os.path as op
|
import os.path as op
|
||||||
@ -61,8 +61,8 @@ def move_without_conflict(src, dst):
|
|||||||
os.rename(src, destpath)
|
os.rename(src, destpath)
|
||||||
|
|
||||||
def send2trash(path):
|
def send2trash(path):
|
||||||
if not isinstance(path, unicode):
|
if not isinstance(path, str):
|
||||||
path = unicode(path, sys.getfilesystemencoding())
|
path = str(path, sys.getfilesystemencoding())
|
||||||
try:
|
try:
|
||||||
move_without_conflict(path, TRASH_PATH)
|
move_without_conflict(path, TRASH_PATH)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -4,12 +4,52 @@
|
|||||||
# 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 ctypes import windll, Structure, byref, c_uint
|
||||||
|
from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL
|
||||||
import os.path as op
|
import os.path as op
|
||||||
import _send2trash_win
|
|
||||||
|
shell32 = windll.shell32
|
||||||
|
SHFileOperationW = shell32.SHFileOperationW
|
||||||
|
|
||||||
|
class SHFILEOPSTRUCTW(Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("hwnd", HWND),
|
||||||
|
("wFunc", UINT),
|
||||||
|
("pFrom", LPCWSTR),
|
||||||
|
("pTo", LPCWSTR),
|
||||||
|
("fFlags", c_uint),
|
||||||
|
("fAnyOperationsAborted", BOOL),
|
||||||
|
("hNameMappings", c_uint),
|
||||||
|
("lpszProgressTitle", LPCWSTR),
|
||||||
|
]
|
||||||
|
|
||||||
|
FO_MOVE = 1
|
||||||
|
FO_COPY = 2
|
||||||
|
FO_DELETE = 3
|
||||||
|
FO_RENAME = 4
|
||||||
|
|
||||||
|
FOF_MULTIDESTFILES = 1
|
||||||
|
FOF_SILENT = 4
|
||||||
|
FOF_NOCONFIRMATION = 16
|
||||||
|
FOF_ALLOWUNDO = 64
|
||||||
|
FOF_NOERRORUI = 1024
|
||||||
|
|
||||||
def send2trash(path):
|
def send2trash(path):
|
||||||
if not isinstance(path, unicode):
|
if not isinstance(path, str):
|
||||||
path = unicode(path, 'mbcs')
|
path = str(path, 'mbcs')
|
||||||
if not op.isabs(path):
|
if not op.isabs(path):
|
||||||
path = op.abspath(path)
|
path = op.abspath(path)
|
||||||
_send2trash_win.send(path)
|
fileop = SHFILEOPSTRUCTW()
|
||||||
|
fileop.hwnd = 0
|
||||||
|
fileop.wFunc = FO_DELETE
|
||||||
|
fileop.pFrom = LPCWSTR(path + '\0')
|
||||||
|
fileop.pTo = None
|
||||||
|
fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT
|
||||||
|
fileop.fAnyOperationsAborted = 0
|
||||||
|
fileop.hNameMappings = 0
|
||||||
|
fileop.lpszProgressTitle = None
|
||||||
|
result = SHFileOperationW(byref(fileop))
|
||||||
|
if result:
|
||||||
|
msg = "Couldn't perform operation. Error code: %d" % result
|
||||||
|
raise OSError(msg)
|
||||||
|
|
||||||
|
29
setup.py
29
setup.py
@ -2,22 +2,6 @@ import sys
|
|||||||
import os.path as op
|
import os.path as op
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
from distutils.extension import Extension
|
|
||||||
|
|
||||||
exts = []
|
|
||||||
|
|
||||||
if sys.platform == 'darwin':
|
|
||||||
exts.append(Extension(
|
|
||||||
'_send2trash_osx',
|
|
||||||
[op.join('modules', 'send2trash_osx.c')],
|
|
||||||
extra_link_args=['-framework', 'CoreServices'],
|
|
||||||
))
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
exts.append(Extension(
|
|
||||||
'_send2trash_win',
|
|
||||||
[op.join('modules', 'send2trash_win.c')],
|
|
||||||
extra_link_args = ['shell32.lib'],
|
|
||||||
))
|
|
||||||
|
|
||||||
CLASSIFIERS = [
|
CLASSIFIERS = [
|
||||||
'Development Status :: 5 - Production/Stable',
|
'Development Status :: 5 - Production/Stable',
|
||||||
@ -26,24 +10,23 @@ CLASSIFIERS = [
|
|||||||
'Operating System :: MacOS :: MacOS X',
|
'Operating System :: MacOS :: MacOS X',
|
||||||
'Operating System :: Microsoft :: Windows',
|
'Operating System :: Microsoft :: Windows',
|
||||||
'Operating System :: POSIX',
|
'Operating System :: POSIX',
|
||||||
'Programming Language :: Python :: 2',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Objective C',
|
|
||||||
'Programming Language :: C',
|
|
||||||
'Topic :: Desktop Environment :: File Managers',
|
'Topic :: Desktop Environment :: File Managers',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
LONG_DESCRIPTION = open('README', 'rt').read() + '\n\n' + open('CHANGES', 'rt').read()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='Send2Trash',
|
name='Send2Trash3k',
|
||||||
version='1.0.2',
|
version='1.1.0',
|
||||||
author='Hardcoded Software',
|
author='Hardcoded Software',
|
||||||
author_email='hsoft@hardcoded.net',
|
author_email='hsoft@hardcoded.net',
|
||||||
packages=['send2trash'],
|
packages=['send2trash'],
|
||||||
scripts=[],
|
scripts=[],
|
||||||
ext_modules = exts,
|
|
||||||
url='http://hg.hardcoded.net/send2trash/',
|
url='http://hg.hardcoded.net/send2trash/',
|
||||||
license='BSD License',
|
license='BSD License',
|
||||||
description='Send file to trash natively under Mac OS X, Windows and Linux.',
|
description='Send file to trash natively under Mac OS X, Windows and Linux.',
|
||||||
long_description=open('README').read(),
|
long_description=LONG_DESCRIPTION,
|
||||||
classifiers=CLASSIFIERS,
|
classifiers=CLASSIFIERS,
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
)
|
)
|
Loading…
x
Reference in New Issue
Block a user