clipboards.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import subprocess
  2. from pandas.compat import PY2, text_type
  3. from .exceptions import PyperclipException
  4. EXCEPT_MSG = """
  5. Pyperclip could not find a copy/paste mechanism for your system.
  6. For more information, please visit https://pyperclip.readthedocs.org """
  7. def init_osx_clipboard():
  8. def copy_osx(text):
  9. p = subprocess.Popen(['pbcopy', 'w'],
  10. stdin=subprocess.PIPE, close_fds=True)
  11. p.communicate(input=text.encode('utf-8'))
  12. def paste_osx():
  13. p = subprocess.Popen(['pbpaste', 'r'],
  14. stdout=subprocess.PIPE, close_fds=True)
  15. stdout, stderr = p.communicate()
  16. return stdout.decode('utf-8')
  17. return copy_osx, paste_osx
  18. def init_gtk_clipboard():
  19. import gtk
  20. def copy_gtk(text):
  21. global cb
  22. cb = gtk.Clipboard()
  23. cb.set_text(text)
  24. cb.store()
  25. def paste_gtk():
  26. clipboardContents = gtk.Clipboard().wait_for_text()
  27. # for python 2, returns None if the clipboard is blank.
  28. if clipboardContents is None:
  29. return ''
  30. else:
  31. return clipboardContents
  32. return copy_gtk, paste_gtk
  33. def init_qt_clipboard():
  34. # $DISPLAY should exist
  35. # Try to import from qtpy, but if that fails try PyQt5 then PyQt4
  36. try:
  37. from qtpy.QtWidgets import QApplication
  38. except ImportError:
  39. try:
  40. from PyQt5.QtWidgets import QApplication
  41. except ImportError:
  42. from PyQt4.QtGui import QApplication
  43. app = QApplication.instance()
  44. if app is None:
  45. app = QApplication([])
  46. def copy_qt(text):
  47. cb = app.clipboard()
  48. cb.setText(text)
  49. def paste_qt():
  50. cb = app.clipboard()
  51. return text_type(cb.text())
  52. return copy_qt, paste_qt
  53. def init_xclip_clipboard():
  54. def copy_xclip(text):
  55. p = subprocess.Popen(['xclip', '-selection', 'c'],
  56. stdin=subprocess.PIPE, close_fds=True)
  57. p.communicate(input=text.encode('utf-8'))
  58. def paste_xclip():
  59. p = subprocess.Popen(['xclip', '-selection', 'c', '-o'],
  60. stdout=subprocess.PIPE, close_fds=True)
  61. stdout, stderr = p.communicate()
  62. return stdout.decode('utf-8')
  63. return copy_xclip, paste_xclip
  64. def init_xsel_clipboard():
  65. def copy_xsel(text):
  66. p = subprocess.Popen(['xsel', '-b', '-i'],
  67. stdin=subprocess.PIPE, close_fds=True)
  68. p.communicate(input=text.encode('utf-8'))
  69. def paste_xsel():
  70. p = subprocess.Popen(['xsel', '-b', '-o'],
  71. stdout=subprocess.PIPE, close_fds=True)
  72. stdout, stderr = p.communicate()
  73. return stdout.decode('utf-8')
  74. return copy_xsel, paste_xsel
  75. def init_klipper_clipboard():
  76. def copy_klipper(text):
  77. p = subprocess.Popen(
  78. ['qdbus', 'org.kde.klipper', '/klipper', 'setClipboardContents',
  79. text.encode('utf-8')],
  80. stdin=subprocess.PIPE, close_fds=True)
  81. p.communicate(input=None)
  82. def paste_klipper():
  83. p = subprocess.Popen(
  84. ['qdbus', 'org.kde.klipper', '/klipper', 'getClipboardContents'],
  85. stdout=subprocess.PIPE, close_fds=True)
  86. stdout, stderr = p.communicate()
  87. # Workaround for https://bugs.kde.org/show_bug.cgi?id=342874
  88. # TODO: https://github.com/asweigart/pyperclip/issues/43
  89. clipboardContents = stdout.decode('utf-8')
  90. # even if blank, Klipper will append a newline at the end
  91. assert len(clipboardContents) > 0
  92. # make sure that newline is there
  93. assert clipboardContents.endswith('\n')
  94. if clipboardContents.endswith('\n'):
  95. clipboardContents = clipboardContents[:-1]
  96. return clipboardContents
  97. return copy_klipper, paste_klipper
  98. def init_no_clipboard():
  99. class ClipboardUnavailable(object):
  100. def __call__(self, *args, **kwargs):
  101. raise PyperclipException(EXCEPT_MSG)
  102. if PY2:
  103. def __nonzero__(self):
  104. return False
  105. else:
  106. def __bool__(self):
  107. return False
  108. return ClipboardUnavailable(), ClipboardUnavailable()