-
Notifications
You must be signed in to change notification settings - Fork 4
/
pyperclip.py
198 lines (157 loc) · 5.74 KB
/
pyperclip.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
"""
Pyperclip
A cross-platform clipboard module for Python. (only handles plain text for now)
By Al Sweigart [email protected]
BSD License
Usage:
import pyperclip
pyperclip.copy('The text to be copied to the clipboard.')
spam = pyperclip.paste()
On Windows, no additional modules are needed.
On Mac, this module makes use of the pbcopy and pbpaste commands, which should come with the os.
On Linux, this module makes use of the xclip or xsel commands, which should come with the os. Otherwise run "sudo apt-get install xclip" or "sudo apt-get install xsel"
Otherwise on Linux, you will need the gtk or PyQt4 modules installed.
The gtk module is not available for Python 3, and this module does not work with PyGObject yet.
"""
__version__ = '1.5.11'
import platform, os
from subprocess import call, Popen, PIPE
PY2 = '2' == platform.python_version_tuple()[0]
text_type = unicode if PY2 else str
def _pasteWindows():
CF_UNICODETEXT = 13
d = ctypes.windll
d.user32.OpenClipboard(0 if PY2 else None)
handle = d.user32.GetClipboardData(CF_UNICODETEXT)
data = ctypes.c_wchar_p(handle).value
d.user32.CloseClipboard()
return data
def _copyWindows(text):
GMEM_DDESHARE = 0x2000
CF_UNICODETEXT = 13
d = ctypes.windll # cdll expects 4 more bytes in user32.OpenClipboard(0)
if not isinstance(text, text_type):
text = text.decode('mbcs')
d.user32.OpenClipboard(0 if PY2 else None)
d.user32.EmptyClipboard()
hCd = d.kernel32.GlobalAlloc(GMEM_DDESHARE, len(text.encode('utf-16-le')) + 2)
pchData = d.kernel32.GlobalLock(hCd)
ctypes.cdll.msvcrt.wcscpy(ctypes.c_wchar_p(pchData), text)
d.kernel32.GlobalUnlock(hCd)
d.user32.SetClipboardData(CF_UNICODETEXT, hCd)
d.user32.CloseClipboard()
def _pasteCygwin():
CF_UNICODETEXT = 13
d = ctypes.cdll
d.user32.OpenClipboard(0)
handle = d.user32.GetClipboardData(CF_UNICODETEXT)
data = ctypes.c_wchar_p(handle).value
d.user32.CloseClipboard()
return data
def _copyCygwin(text):
GMEM_DDESHARE = 0x2000
CF_UNICODETEXT = 13
d = ctypes.cdll
if not isinstance(text, text_type):
text = text.decode('mbcs')
d.user32.OpenClipboard(0)
d.user32.EmptyClipboard()
hCd = d.kernel32.GlobalAlloc(GMEM_DDESHARE, len(text.encode('utf-16-le')) + 2)
pchData = d.kernel32.GlobalLock(hCd)
ctypes.cdll.msvcrt.wcscpy(ctypes.c_wchar_p(pchData), text)
d.kernel32.GlobalUnlock(hCd)
d.user32.SetClipboardData(CF_UNICODETEXT, hCd)
d.user32.CloseClipboard()
def _copyOSX(text):
p = Popen(['pbcopy', 'w'], stdin=PIPE, close_fds=True)
p.communicate(input=text.encode('utf-8'))
def _pasteOSX():
p = Popen(['pbpaste', 'r'], stdout=PIPE, close_fds=True)
stdout, stderr = p.communicate()
return stdout.decode('utf-8')
def _pasteGtk():
return gtk.Clipboard().wait_for_text()
def _copyGtk(text):
global cb
cb = gtk.Clipboard()
cb.set_text(text)
cb.store()
def _pasteQt():
return str(cb.text())
def _copyQt(text):
cb.setText(text)
def _copyXclip(text):
p = Popen(['xclip', '-selection', 'c'], stdin=PIPE, close_fds=True)
p.communicate(input=text.encode('utf-8'))
def _pasteXclip():
p = Popen(['xclip', '-selection', 'c', '-o'], stdout=PIPE, close_fds=True)
stdout, stderr = p.communicate()
return stdout.decode('utf-8')
def _copyXsel(text):
p = Popen(['xsel', '-b', '-i'], stdin=PIPE, close_fds=True)
p.communicate(input=text.encode('utf-8'))
def _pasteXsel():
p = Popen(['xsel', '-b', '-o'], stdout=PIPE, close_fds=True)
stdout, stderr = p.communicate()
return stdout.decode('utf-8')
# Determine the OS/platform and set the copy() and paste() functions accordingly.
if 'cygwin' in platform.system().lower():
_functions = 'Cygwin' # for debugging
import ctypes
paste = _pasteCygwin
copy = _copyCygwin
elif os.name == 'nt' or platform.system() == 'Windows':
_functions = 'Windows' # for debugging
import ctypes
paste = _pasteWindows
copy = _copyWindows
elif os.name == 'mac' or platform.system() == 'Darwin':
_functions = 'OS X pbcopy/pbpaste' # for debugging
paste = _pasteOSX
copy = _copyOSX
elif os.name == 'posix' or platform.system() == 'Linux':
# Determine which command/module is installed, if any.
xclipExists = call(['which', 'xclip'],
stdout=PIPE, stderr=PIPE) == 0
xselExists = call(['which', 'xsel'],
stdout=PIPE, stderr=PIPE) == 0
gtkInstalled = False
try:
# Check it gtk is installed.
import gtk
gtkInstalled = True
except ImportError:
pass
if not gtkInstalled:
# Check if PyQt4 is installed.
PyQt4Installed = False
try:
import PyQt4.QtCore
import PyQt4.QtGui
PyQt4Installed = True
except ImportError:
pass
# Set one of the copy & paste functions.
if xclipExists:
_functions = 'xclip command' # for debugging
paste = _pasteXclip
copy = _copyXclip
elif gtkInstalled:
_functions = 'gtk module' # for debugging
paste = _pasteGtk
copy = _copyGtk
elif PyQt4Installed:
_functions = 'PyQt4 module' # for debugging
app = PyQt4.QtGui.QApplication([])
cb = PyQt4.QtGui.QApplication.clipboard()
paste = _pasteQt
copy = _copyQt
elif xselExists:
# TODO: xsel doesn't seem to work on Raspberry Pi (my test Linux environment). Putting this as the last method tried.
_functions = 'xsel command' # for debugging
paste = _pasteXsel
copy = _copyXsel
else:
raise Exception('Pyperclip requires the xclip or xsel application, or the gtk or PyQt4 module.')
else:
raise RuntimeError('pyperclip does not support your system.')