mirror of
https://github.com/arsenetar/send2trash.git
synced 2024-12-21 10:59:03 +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
|
||||
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
|
||||
---
|
||||
---------------------------
|
||||
|
||||
* 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
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
|
||||
==================================================
|
||||
|
||||
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
|
||||
-----
|
||||
|
@ -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
|
||||
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
||||
|
29
setup.py
29
setup.py
@ -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,
|
||||
)
|
Loading…
Reference in New Issue
Block a user