1
0
mirror of https://github.com/arsenetar/send2trash.git synced 2026-01-25 16:11:39 +00:00

17 Commits
1.0.0 ... 1.1.0

Author SHA1 Message Date
Virgil Dupras
506e48b2e0 v1.1.0
--HG--
branch : py3k
2010-10-18 12:13:37 +02:00
Virgil Dupras
899a3efeb3 Converted the compiled win module to ctypes.
--HG--
branch : py3k
2010-10-17 18:00:56 +01:00
Virgil Dupras
a6907d57a9 Converted the compiled osx module to ctypes.
--HG--
branch : py3k
2010-10-17 18:28:28 +02:00
Virgil Dupras
b5315cb73d Added a setuptools-crappiness notice in the README.
--HG--
branch : py3k
extra : transplant_source : %F8%9A%02%C3%D2%AA%AB%2C%5D%94%EA%13%BD%D6%A0U%3F%D2N%C9
2010-07-13 12:19:19 +02:00
Virgil Dupras
d1fcb13086 v1.0.2
--HG--
branch : py3k
2010-07-10 07:06:01 +02:00
Virgil Dupras
02dc392c45 Fixed a bug in plat_other where conflict handling wouldn't be done correctly in external volume. Thanks to John Benediktsson for the tip.
--HG--
branch : py3k
extra : transplant_source : %C6%11%009sx%B29%CF%EC%CC%D4%88r%BE%D8%BB%9AIa
2010-07-09 21:49:46 -07:00
Virgil Dupras
7546aa606a Fixed an infinite loop in plat_other when using a relative path in a mounted directory.
--HG--
branch : py3k
extra : transplant_source : %B4%A2%DB%EFn%BB%3A%F6%AE%06%F3%29%DB%06%FBE%D0%A2%BEt
2010-07-09 21:46:19 -07:00
Virgil Dupras
2858b5b153 Converted to py3k (haven't tried it on Windows yet, but it should compile and work...)
--HG--
branch : py3k
2010-07-07 16:12:13 +02:00
Virgil Dupras
88b90d859c Updated package metadata. 2010-07-07 11:59:11 +02:00
Virgil Dupras
f5f9c5b352 Fixed the copyright comment which was at a strange place. 2010-04-21 10:30:51 +02:00
Virgil Dupras
06f03e14b4 Fixed spaces/tabs mixup. 2010-04-21 10:14:46 +02:00
Virgil Dupras
8313b0eebb Added tag 1.0.1 for changeset a7e04d8e47e1 2010-04-19 11:25:35 +02:00
Virgil Dupras
e78d1d1bd9 Merged heads. 2010-04-19 11:25:02 +02:00
Virgil Dupras
de898fdcaa v1.0.1: Fixed memory leak. 2010-04-19 11:24:06 +02:00
Virgil Dupras
a3e41602cf Added long_description to setup. 2010-04-08 16:28:23 +02:00
Virgil Dupras
8b00632dd6 Set zip_safe to False, as it causes problems when creating executables for Windows of apps using it. 2010-04-07 16:25:01 +01:00
Virgil Dupras
fa68152b35 Added tag 1.0.0 for changeset 48c2103380f5 2010-04-07 13:16:55 +02:00
11 changed files with 139 additions and 155 deletions

View File

@@ -1,5 +1,7 @@
syntax: glob
*.pyc
*.egg-info
build
dist
.DS_Store

2
.hgtags Normal file
View File

@@ -0,0 +1,2 @@
48c2103380f5e7deca49364f44fb31ded9942bb7 1.0.0
a7e04d8e47e161daaa1f031a7c1e98c52fa269ac 1.0.1

20
CHANGES
View File

@@ -1,4 +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

10
README
View File

@@ -2,19 +2,19 @@
Send2Trash -- Send files to trash on all platforms
==================================================
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.
>>> python setup.py install
Usage
-----

View File

@@ -1,44 +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);
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

@@ -1,13 +1,13 @@
from __future__ import unicode_literals
import sys
import os
import os.path as op
# 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
import sys
import os
import os.path as op
import logging
CANDIDATES = [
@@ -33,8 +33,9 @@ EXTERNAL_CANDIDATES = [
def find_mount_point(path):
# Even if something's wrong, "/" is a mount point, so the loop will exit.
path = op.abspath(path) # Required to avoid infinite loop
while not op.ismount(path):
path = op.join(*op.split(path)[:-1])
path = op.split(path)[0]
return path
def find_ext_volume_trash(volume_root):
@@ -56,12 +57,12 @@ def move_without_conflict(src, dst):
counter += 1
base_name, ext = op.splitext(filename)
new_filename = '{0} {1}{2}'.format(base_name, counter, ext)
destpath = op.join(TRASH_PATH, new_filename)
destpath = op.join(dst, new_filename)
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,32 +2,33 @@ import sys
import os.path as op
from setuptools import setup
from distutils.extension import Extension
exts = []
CLASSIFIERS = [
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Programming Language :: Python :: 3',
'Programming Language :: Objective C',
'Programming Language :: C',
'Topic :: Desktop Environment :: File Managers',
]
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'],
))
LONG_DESCRIPTION = open('README', 'rt').read() + '\n\n' + open('CHANGES', 'rt').read()
setup(
name='Send2Trash',
version='1.0.0',
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='LICENSE',
license='BSD License',
description='Send file to trash natively under Mac OS X, Windows and Linux.',
long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS,
zip_safe=False,
)