123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- """ Utilities for accessing the platform's clipboard.
- """
- import os
- import subprocess
- from IPython.core.error import TryNext
- import IPython.utils.py3compat as py3compat
- class ClipboardEmpty(ValueError):
- pass
- def win32_clipboard_get():
- """ Get the current clipboard's text on Windows.
- Requires Mark Hammond's pywin32 extensions.
- """
- try:
- import win32clipboard
- except ImportError as e:
- raise TryNext("Getting text from the clipboard requires the pywin32 "
- "extensions: http://sourceforge.net/projects/pywin32/") from e
- win32clipboard.OpenClipboard()
- try:
- text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
- except (TypeError, win32clipboard.error):
- try:
- text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
- text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
- except (TypeError, win32clipboard.error) as e:
- raise ClipboardEmpty from e
- finally:
- win32clipboard.CloseClipboard()
- return text
- def osx_clipboard_get() -> str:
- """ Get the clipboard's text on OS X.
- """
- p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'],
- stdout=subprocess.PIPE)
- bytes_, stderr = p.communicate()
- # Text comes in with old Mac \r line endings. Change them to \n.
- bytes_ = bytes_.replace(b'\r', b'\n')
- text = py3compat.decode(bytes_)
- return text
- def tkinter_clipboard_get():
- """ Get the clipboard's text using Tkinter.
- This is the default on systems that are not Windows or OS X. It may
- interfere with other UI toolkits and should be replaced with an
- implementation that uses that toolkit.
- """
- try:
- from tkinter import Tk, TclError
- except ImportError as e:
- raise TryNext("Getting text from the clipboard on this platform requires tkinter.") from e
-
- root = Tk()
- root.withdraw()
- try:
- text = root.clipboard_get()
- except TclError as e:
- raise ClipboardEmpty from e
- finally:
- root.destroy()
- text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
- return text
- def wayland_clipboard_get():
- """Get the clipboard's text under Wayland using wl-paste command.
- This requires Wayland and wl-clipboard installed and running.
- """
- if os.environ.get("XDG_SESSION_TYPE") != "wayland":
- raise TryNext("wayland is not detected")
- try:
- with subprocess.Popen(["wl-paste"], stdout=subprocess.PIPE) as p:
- raw, err = p.communicate()
- if p.wait():
- raise TryNext(err)
- except FileNotFoundError as e:
- raise TryNext(
- "Getting text from the clipboard under Wayland requires the wl-clipboard "
- "extension: https://github.com/bugaevc/wl-clipboard"
- ) from e
- if not raw:
- raise ClipboardEmpty
- try:
- text = py3compat.decode(raw)
- except UnicodeDecodeError as e:
- raise ClipboardEmpty from e
- return text
|