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:
Virgil Dupras 2011-02-14 11:00:09 +01:00
commit a8a771c9bd
11 changed files with 109 additions and 161 deletions

View File

@ -1,2 +1,3 @@
48c2103380f5e7deca49364f44fb31ded9942bb7 1.0.0
a7e04d8e47e161daaa1f031a7c1e98c52fa269ac 1.0.1
de5f43fcce5e776eb28306951939afb9946cbd3d 1.1.0

14
CHANGES
View File

@ -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
---
---------------------------
* Fixed bugs with external volumes in plat_other.
Version 1.0.1 -- 2010/04/19
---
---------------------------
* Fixed memory leak in OS X module.
Version 1.0.0 -- 2010/04/07
---
---------------------------
* Initial Release

1
MANIFEST.in Normal file
View File

@ -0,0 +1 @@
include CHANGES

12
README
View File

@ -2,23 +2,19 @@
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
*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
------------
Download the source from http://hg.hardcoded.net/send2trash and install it with::
>>> sudo 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.
>>> python setup.py install
Usage
-----

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -7,8 +7,8 @@
import sys
if sys.platform == 'darwin':
from plat_osx import send2trash
from .plat_osx import send2trash
elif sys.platform == 'win32':
from plat_win import send2trash
from .plat_win import send2trash
else:
from plat_other import send2trash
from .plat_other import send2trash

View File

@ -4,9 +4,41 @@
# which should be included with this package. The terms are also available at
# 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):
if not isinstance(path, unicode):
path = unicode(path, 'utf-8')
_send2trash_osx.send(path)
if not isinstance(path, bytes):
path = path.encode('utf-8')
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)

View File

@ -4,7 +4,7 @@
# 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
import sys
import os
import os.path as op
@ -61,8 +61,8 @@ def move_without_conflict(src, dst):
os.rename(src, destpath)
def send2trash(path):
if not isinstance(path, unicode):
path = unicode(path, sys.getfilesystemencoding())
if not isinstance(path, str):
path = str(path, sys.getfilesystemencoding())
try:
move_without_conflict(path, TRASH_PATH)
except OSError:

View File

@ -4,12 +4,52 @@
# which should be included with this package. The terms are also available at
# 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 _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):
if not isinstance(path, unicode):
path = unicode(path, 'mbcs')
if not isinstance(path, str):
path = str(path, 'mbcs')
if not op.isabs(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)

View File

@ -2,22 +2,6 @@ import sys
import os.path as op
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 = [
'Development Status :: 5 - Production/Stable',
@ -26,24 +10,23 @@ CLASSIFIERS = [
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Programming Language :: Python :: 2',
'Programming Language :: Objective C',
'Programming Language :: C',
'Programming Language :: Python :: 3',
'Topic :: Desktop Environment :: File Managers',
]
LONG_DESCRIPTION = open('README', 'rt').read() + '\n\n' + open('CHANGES', 'rt').read()
setup(
name='Send2Trash',
version='1.0.2',
name='Send2Trash3k',
version='1.1.0',
author='Hardcoded Software',
author_email='hsoft@hardcoded.net',
packages=['send2trash'],
scripts=[],
ext_modules = exts,
url='http://hg.hardcoded.net/send2trash/',
license='BSD License',
description='Send file to trash natively under Mac OS X, Windows and Linux.',
long_description=open('README').read(),
long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS,
zip_safe=False,
)