4

I am trying to create a script in Python that will collect data put in the clipboard by the user and preferably save it as a list or in a text file or string/array/variable to work with later on.

This should work on Linux all versions (I would assume Ubuntu), Mac OS all versions and Windows all versions. I am not sure if 32bit and 64bit systems have different ways of accessing the data at the clipboard, if they do I guess it would be safe to make this work for the 32bit versions only so people running the 64bit versions can fall back onto the 32bit version of the OS.

The tricky part, apart from this having to work on the mentioned OS, is that I would like the script to run as long as the user does not stop it and while it runs all the data copied into the clipboard by the user is being copied to a list or in a text file or string/array/variable.

Of course there is a time limit at which the user can input data into the clipboard so I was thinking of having a loop scanning the clipboard every second or every 500 milliseconds, check if the content has changed, and if it has, copy it, otherwise don't copy it.

Is there a unified way or module that does this on all different OS or would it be better to write separate scripts for this task for the various OS?

The thing is, this is part of a bigger project that I would like to make work on Linux, Mac and Windows, so having those three options covered and then use Python code that can be used across the mentioned OS for the rest of the script/project would be ideal. Am I asking too much in general from this script concerning it having to work on Linux, Mac and Windows?

lowtechsun
  • 1,644
  • 3
  • 22
  • 49

5 Answers5

4

The xerox library supports Linux, Mac OS X, and Windows.

Note that it's a very bad idea to perform any action in short (< a minute) intervals, because that makes modern processors wake up regularily. You may want to use the respective operating system's APIs to register a callback once the clipboard changes.

phihag
  • 245,801
  • 63
  • 407
  • 443
  • So xerox.copy(u) will take whatever is in the clipboard on any of the mentioned OS and copy it to a variable I assign? To me, I am just starting to learn Python, it looks like I can use xerox to copy and paste a string I assign in the script rather than taking what actually is in the clipboard and using that as an user input variable in the script. Is this correct? – lowtechsun Oct 24 '11 at 21:11
  • Just FYI: `xerox` requires `xclip` to be installed on linux systems. `xclip` isn't included by default with most distributions. – Joe Kington Oct 24 '11 at 21:36
  • Yes, thank you registering a callback is what I will for sure look into! So this really means splitting the code into the various OS APIs, does it? I thought I could somehow define it in the beginning and then the code can be read by all the OS in one brnach instead of having three branches of the code, each one for the various OS, is my assumption correct here? – lowtechsun Oct 24 '11 at 21:40
  • @JoeKington Thank you, do you also know if it can copy from the clipboard or to it from the code defined in the script? I am looking to copy data from the clipboard on a regular basis and put that into an array or string to be used by the script later on. xerox can copy from the clipboard without putting something in the clipboard beforehand? – lowtechsun Oct 24 '11 at 21:45
  • @lowtechsun Yes, just read `sys.platform` and decide which branch to take based up on that. xerox just reads the current clipboard, no matter who set it. Note that there may be multiple clipboards on Unix systems, especially Linux. – phihag Oct 24 '11 at 21:54
  • But surly the most recent clipboard used on Linux systems can be read by xerox, like you say, the current clipboard. So telling the script to only look for the most recent clipboard used on Linux should work, no? – lowtechsun Oct 24 '11 at 22:24
  • @lowtechsun xerox just uses the X clipboard (which gets updated automatically, by simply selecting anything, and gets pasted with the third mouse button). There is a separate (sometimes synchronized) freedesktop.org clipboard on many Linux systems, with completely different mechanics (Ctrl+C to copy, Ctrl+V to paste). – phihag Oct 24 '11 at 22:29
  • in that case it might be good for starters to focus on the Windows and Mac implementation before going on to Linux. [This post about a shared clipboard across OS](http://www.devx.com/opensource/Article/37233/1954) raises my hope. – lowtechsun Oct 24 '11 at 22:42
  • @lowtechsun That post has a decent set of pointers, but I'd recommend against using Carbon on OS X. Carbon is deprecated, there is no 32-version of it. Which means it won't work on a 64-bit version of Python 2.x – and the default Python on Lion is 64-bit. The Carbon binding was also removed from Python 3.x. Do not use Carbon. – millimoose Oct 24 '11 at 22:53
  • @lowtechsun What you could use on OS X is pyobjc and the pasteboard api, I'll add a code example into my answer. – millimoose Oct 24 '11 at 22:58
4

You're probably better off using a more advanced gui toolkit than Tk, but it's in the standard library, so it's available everywhere.

As a really simple example:

import Tkinter
root = Tkinter.Tk()
root.withdraw() # Hide the main window (optional)
text_in_clipboard = root.clipboard_get()
print text_in_clipboard
Joe Kington
  • 239,485
  • 62
  • 555
  • 446
  • This example works on all the mentioned OS? Since @phihag mentioned there might be multiple clipboards on Linux it might be better to focus on the Windows clipboard at first and then port to Mac and Linux where the user copies and pastes the URL(a) at every new loop of the script. Would love to avoid this situation though and just pick the URLs(a) with a click of a mouse button for example. – lowtechsun Oct 24 '11 at 22:18
  • @lowtechsun For most apps, for a first version, you can safely ignore the "legacy" clipboards on Linux and just use the Ctrl-C/Ctrl-V one that's called "clipboard". I doubt there's a significant overlap between people who care strongly about the "primary" and "secondary" clipboards and people who would use an automated GUI downloader. – millimoose Oct 24 '11 at 22:45
  • @Inerdia Sorry, what are the legacy, primary and secondary clipboards on Linux? Are you saying on Linux have the user browse (with any browser) to the page with the URLs and there for example select them with mouse right-click copy link location is as easy to do as on Mac or Windows and would be appreciated more than having to copy and paste the URL into the script/GUI yourself with hitting the keys? I thought the sometimes synchronized clipboard would perhaps erase the content, is that not what phihag implies? What good forum can I learn about this or make an public project group for this? – lowtechsun Oct 24 '11 at 23:01
  • @lowtechsun By "legacy" clipboards, I meant the "primary" and "secondary" ones, since they're mostly used by older applications. You should probably search SO to see if there's another question that explains the difference between the various Linux clipboards, and ask one if there isn't. I also don't know what your hypothethical user audience would prefer. – millimoose Oct 24 '11 at 23:14
  • @Inerdia yes, thank you, I have come up with [PyGTK](http://www.pygtk.org/) and [PyQt](http://www.riverbankcomputing.co.uk/software/pyqt/intro). Just don't understand what you mean with "I doubt there's a significant overlap between people who care strongly about the "primary" and "secondary" clipboards and people who would use an automated GUI downloader." I am searching now. Really thanks for all the users replies to this question so far. Thanks! – lowtechsun Oct 24 '11 at 23:17
  • @lowtechsun That statement stems from my (quite possibly wrong) opinion that most modern Linux GUI apps use the "clipboard" clipboard exclusively; and if there's an option to make them use the old X11 copy-on-select mechanism, it's not something the kind of Linux user that will install Ubuntu from the live-CD and be happy will turn on. – millimoose Oct 24 '11 at 23:20
2

You could use a GUI toolkit such as Qt to get a portable clipboard API. That said it might be a little overkill to use a whole GUI toolkit just for this. (Unless, of course, you're also going to use it to make a GUI.)

That said, clipboard APIs dealing with plain text should be reasonably simple to make your own abstraction over.

For instance, on OS X you can use PyObjC (which is installed along with OS X) to get plain-text contents of a clipboard:

from AppKit import NSPasteboard
from LaunchServices import 
pb = NSPasteboard.generalPasteboard()
text = pb.stringForType_(kUTTypeUTF8PlainText)

CPU architectures

A 32-bit native app on a 64-bit OS will be accessing the same clipboard as a 64-bit one. If you need to support both architectures of an OS, and aren't writing a driver, for Windows it's okay to ship a 32-bit binary; for Linux you'll likely have to do both versions; for OS X, it should be reasonably safe to ship a 64-bit version, all Macs since mid-2007 have had 64-bit CPUs and the OS support is there since Leopard. A Python script will, on Linux, probably be executed by a Python installation from the distribution package manager, whose bitness will match the system, so you don't necessarily need to worry about that.

millimoose
  • 36,982
  • 8
  • 75
  • 128
  • The book I am learning Python from uses the [Tk-Interface](http://docs.python.org/library/tkinter.html). Could I use that for example? The data on the clipboard will be URLs only. I am writing a downloader. It takes the URL(a) from the user input and changes it given a set pattern. Then it goes to that new created URL(ab), like [this one](http://www.mixcloud.com/api/1/cloudcast/minimalstation/jadele-liveset-11-08-08-mnmlstn.json) for example and copies all that content to the clipboard, extracts the URLs, checks them for 404 errors and displays the good URLs in a list to the user. – lowtechsun Oct 24 '11 at 21:23
  • About the 32/64bit OS: So given this short basic concept I would assume it is only really needed to write a 32 bit version for all the OS, no? I mean for example on a 64bit Linux the 32bit version of the script will run, no? Same on Windows and Mac, if they have a 63bit OS running they can still run 32bit scripts, no? Properly confused now.. About the clipboard: I would like to make it as easy as possible for the user to input the URL(a), so instead of copy and paste to the script just read from the clipboard instead of accessing browser tabs etc, no? – lowtechsun Oct 24 '11 at 21:33
  • @lowtechsun: Tk seems to have some sort of [basic clipboard functionality](http://www.tcl.tk/man/tcl/TkCmd/clipboard.htm). The documentation doesn't mention if it integrates with the native clipboard; one would hope in this day and age it does but native integration isn't historically Tk's strong suit. – millimoose Oct 24 '11 at 21:41
  • @lowtechsun The 32/64 part is only relevant if you were to write your own native code to interface with the clipboard. If you're using Tk or whatever to interface with the OS just let the library worry. Python is a scripting language, you don't need to care about architectures in Python code. – millimoose Oct 24 '11 at 21:43
  • @lowtechsun: If you want to interface with a web browser, you should write a browser extension. You can make it talk to a Python process running in the background by making the Python script expose a web service and calling it from the extension via AJAX. – millimoose Oct 24 '11 at 21:44
  • The script only really gets data from the web when it downloads the URL(ab) content and then later the alive files. The original URL(a) that comes from the user, can be also simply put in by the user instead of being read from the clipboard. Since I am just starting Python, AJAX might be too much to start also, no? I find something that people can use without browser even on all OS more open since it does not make people install FF for example if they run Safari only. Just an example. As open as possible in regards to making it run on all the OS despite of browser. What do you think? – lowtechsun Oct 24 '11 at 22:00
2

Polling is NOT robust/reliable.

You cannot determine if data has changed (on windows anyway) without pasting it into a buffer for inspection. This requires opening the clipboard. If you do this in a loop, you're going to collide with other apps. i.e. the app where the user is copying another item onto the clipboard. This will explode with an "cannot open clipboard" or "out of memory" error. This approach will not work reliably/robustly. You need to use proper clipboard monitoring APIs in the various platforms.

Chris Thornton
  • 15,250
  • 4
  • 34
  • 61
  • Thank you Chris for your informative reply. So let's say I have a loop where I access the clipboard and inspect the content, the if the content changed copy the new content to a variable I assign, and if it is the same, leave it as is, will not work on Windows? The only reason for me wanting to use the clipboard is so that users do not have to copy and paste the URL manually. If there is a more elegant way, let's say with a mouse, to simply copy and paste a URL as a user input into the script please let me know. Had a look at your site and you truly seem to know your thing about clipboards.THX – lowtechsun Oct 25 '11 at 16:38
0

I suspect it's also possible to copy clipboard in platform neutral manner using pythonnet + TextCopy library via following links:

http://pythonnet.github.io/

https://stackoverflow.com/a/51912933/2338477

(See similar problem here: Quick and easy file dialog in Python? )

But haven't tried this by myself, might need also to play around what kind of commands you run and from which console. Let me know if someone will try this, I'll update more details in here.

TarmoPikaro
  • 3,568
  • 1
  • 32
  • 42