halkion
halkion

Reputation: 123

Copying files with native file manager in python

Okay, so I'm developing an application that will allow users to select file objects in a menu and will allow them to copy said selections to another location. I have so far managed to use the pywin32 module to allow me to copy files using Windows' native file copier.

The code for it:

from win32com.shell import shell, shellcon
srcstr = chr( 0 ).join( [ file[0] for file in files ] )
deststr = chr( 0 ).join( [ file[1] for file in files ] )
shell.SHFileOperation(
    ( 0, shellcon.FO_COPY, srcstr, deststr, shellcon.FOF_MULTIDESTFILES, None, None )
)

This is a fine method for copying under Windows, but I was wondering if there is a way to accomplish the same goal under Mac and/or Linux.

Upvotes: 3

Views: 1076

Answers (5)

SpliFF
SpliFF

Reputation: 38966

I don't envy the task. To achieve this you aren't so much targetting "Linux" but desktop environment X, Y, Z, etc (and the different versions of each). It isn't just KDE vs. Gnome, it's KDE 3/4 vs Gnome 2/3 vs Enlightment vs Xfce4 vs Blackbox vs. TWM and others.

You can get a cross-desktop file picker using a library like GTK or WXwidgets but I don't think either of those has a progress widget for copy operations (you'd have to code that yourself) and they don't look "native" either.

Speaking generally though I don't think a native copy dialog is really something most linux users would care about. We're used to programs looking different and we learn to live with it.

Anyway, I'd recommend GtkProgressBar or wxProgressDialog since either should be reasonably easy to put to this task and both libraries have python bindings.

Upvotes: 0

abarnert
abarnert

Reputation: 365707

On Mac, you'll need to script Finder.

One way to do this is with ScriptingBridge. To start with:

import ScriptingBridge
f = ScriptingBridge.SBApplication.applicationWithBundleIdentifier_("com.apple.Finder")

Then… well, fire up AppleScript Editor, look at Finder's Dictionary, and figure out how to translate that from AppleScript into Python+ScriptingBridge, and if you have any problems, come back and ask again. But here are some hints:

The trick is to get from a path to a Finder reference. And there's no easy way to get there directly. Instead, you have to start with startupDisk, call folders() on it, filter for name == the first component of path, and repeat. See http://developer.apple.com/library/mac/#samplecode/ScriptingBridgeFinder/Listings/Controller_m.html (which is written in Objective C, not Python, but the ScriptingBridge parts are pretty easy to translate).

Upvotes: 0

abarnert
abarnert

Reputation: 365707

The other way to do this on Mac is with NSWorkspace via PyObjC. Like this:

from Cocoa import *
ws = NSWorkspace.sharedWorkspace()
ws.performFileOperation_source_destination_files_tag_(NSWorkspaceCopyOperation,
    '/dirname/of/source', '/dest/directory', ['basenameOfSource'], None)

The problem is that this isn't actually guaranteed to do the same thing as the Finder. For large copies, it usually will, but for smaller copies there may be no feedback at all.

Also, if you want to get any feedback, you have to stash ret[1] and register for the NSWorkspace notification NSWorkspaceDidPerformFileOperationNotification, which means you need a run loop.

Upvotes: 1

michel-slm
michel-slm

Reputation: 9756

The solution will likely be OS/desktop-specific; for instance on GNOME, you'd need to use DBus to communicate with Nautilus.

Someone asked about documentation and apparently there wasn't any: Where to find information about Nautilus D-Bus interface

and this thread indicates that the features you need might exist in the current version of Nautilus: https://askubuntu.com/questions/52093/how-can-i-initiate-nautilus-file-operations-from-the-command-line

but to support OS X, KDE, etc. you might have to do work for each.

Upvotes: 0

andresuribe
andresuribe

Reputation: 117

Have you considered shutil (http://docs.python.org/library/shutil.html)? This module provides that sort of high-level file operations while remaining os-agnostic.

Upvotes: 1

Related Questions