LINUX.ORG.RU

Как читать историю буфера обмена KDE из питона?

 , ,


0

2

Копирую фрагменты текста со страниц, затем обрабатываю и объединяю их скриптом. Чтобы читать текущее значение буфера, хватает pyperclip. Но мне проще открыть 20 страниц, на каждой нажать Ctrl-Ins, а затем, не отвлекаясь, скормить скрипту всё сразу. А может ли скрипт сам залезть в историю буфера обмена и скопировать последние 20 записей?

Про то, что pyperclip умеет ждать изменения в буфере, знаю, но не пользовался. Если не найдётся более простого решения — попробую так.

Предварительный ответ:

import dbus
dbus.SessionBus().get_object('org.kde.klipper', '/klipper').get_dbus_method('getClipboardHistoryMenu', dbus_interface='org.kde.klipper.klipper')()[:20]

или

import dbus
method = dbus.SessionBus().get_object('org.kde.klipper', '/klipper').get_dbus_method('getClipboardHistoryItem', dbus_interface='org.kde.klipper.klipper')
[str(method(n)) for n in range(20)]

Тему пока не помечаю решённой на случай, если существует легче запоминающееся решение.

★★★★★

Последнее исправление: question4 (всего исправлений: 1)

Ответ на: комментарий от ox55ff

Мне всегда казалось, что историю буфера обмена реализуют сторонние программы.

Да. И как взаимодействовать с этой программой из питона, чтобы она показала историю? Гуглится только устаревшая информация. Даже по названию klipper гуглится что-то несвязанное.

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4

По названию klipper ничего хорошего и не получишь, я подозреваю, что он и сам на питончике написан. Гугли название своей темы.

https://klipper.discourse.group/t/add-python-code-script-to-klipper/9061 С тебя 50 скора.

Irma ★★
()
Последнее исправление: Irma (всего исправлений: 1)
Ответ на: комментарий от question4

Google «KDE klipper history python» -> Copy/paste from command line with Klipper

parser.add_argument("-i", "--item", type=int, nargs="?", const=0,
	help="get the Nth item in clipboard history", metavar="N")
parser.add_argument("-x", "--clear", action="store_true", default=False,
	help="clear the clipboard history")
parser.add_argument("args", nargs="?")

master_0K
()

Вот пример для вызова из консоли:

$ dbus-send --print-reply=literal --dest=org.kde.klipper /klipper org.kde.klipper.klipper.getClipboardHistoryItem int32:"0"
   Some string at index 0...
...
$ dbus-send --print-reply=literal --dest=org.kde.klipper /klipper org.kde.klipper.klipper.getClipboardHistoryItem int32:"19"
   Some string at index 19...

Осталось переписать это на Python.

Ja-Ja-Hey-Ho ★★★★
()
Ответ на: комментарий от frunobulax

Может будет проще сохранить нужные странички в html и обработать парсером в скрипте?

Если веб-страница формируется динамически — нет.

question4 ★★★★★
() автор топика
Ответ на: комментарий от Ja-Ja-Hey-Ho

Вот пример для вызова из консоли:

$ dbus-send --print-reply=literal --dest=org.kde.klipper /klipper org.kde.klipper.klipper.getClipboardHistoryItem int32:"0"
   Some string at index 0...
...
$ dbus-send --print-reply=literal --dest=org.kde.klipper /klipper org.kde.klipper.klipper.getClipboardHistoryItem int32:"19"
   Some string at index 19...

Спасибо.

Какой модуль питона надо импортировать? dbus? Потому что Гугл предлагает кучу других, которые не работают.

И вопрос по терминологии. Правильно ли я понимаю, что

org.kde.klipper — имя шины
/klipper — путь к объекту
org.kde.klipper.klipper — интерфейс
getClipboardHistoryItem — метод
?

Пока получилось примерно следующее:

>>> import dbus
>>> base = dbus.SessionBus()
>>> proxy = base.get_object('org.kde.klipper', '/klipper')
>>> method = proxy.get_dbus_method('getClipboardHistoryItem', dbus_interface='org.kde.klipper.klipper')
>>> [method(n) for n in range(6)]
[dbus.String('org.kde.klipper.klipper'), dbus.String('getClipboardHistoryItem'), dbus.String('proxy.get_dbus_method("Foo", dbus_interface=\'com.example.Bar\')(123)'), dbus.String('get_dbus_method(member, dbus_interface=None) '), dbus.String('org.kde.klipper /klipper org.kde.klipper.klipper.getClipboardHistoryItem'), dbus.String('/klipper')]

В общем, пользоваться в таком виде уже можно. Или можно последнюю строку заменить на [str(method(n)) for n in range(6)]

И ещё есть метод getClipboardHistoryMenu, который сразу вернёт массив со всей историей.

Спасибо, с ним получается так:

>>> proxy.get_dbus_method('getClipboardHistoryMenu', dbus_interface='org.kde.klipper.klipper')()[0:6]
[dbus.String('org.kde.klipper.klipper'), dbus.String('getClipboardHistoryItem'), dbus.String('proxy.get_dbus_method("Foo", dbus_interface=\'com.example.Bar\')(123)'), dbus.String('get_dbus_method(member, dbus_interface=None) '), dbus.String('org.kde.klipper /klipper org.kde.klipper.klipper.getClipboardHistoryItem'), dbus.String('/klipper')]

Не сразу сообразил поставить пустые скобки.

question4 ★★★★★
() автор топика
Ответ на: комментарий от master_0K

https://gist.github.com/aeris/3308963

Спасибо. Не сразу понял, что это была ссылка.

P.S. Какая разница между вызовами get_dbus_method и Interface, в чём преимущества?

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4

Я и сам пытаюсь вникнуть в эту «простую и надёжную» технологию (D-Bus кодинга). Поэтому могу только предложить своё понимание (возможно ложное):

  • get_dbus_method это обращение к функции некоторого объекта

  • Interface этот «объект» содержит в себе объекты и их методы

а разница в удобстве разных абстракций (в зависимости от задачи или личных предпочтений). // это только моё впечатление

master_0K
()
Последнее исправление: master_0K (всего исправлений: 1)

import dbus; pages = dbus.SessionBus().get_object('org.kde.klipper', '/klipper').get_dbus_method('getClipboardHistoryMenu', dbus_interface='org.kde.klipper.klipper')()[:5]; ipsports = [ line.replace('\tSOCKS5\t', '').replace('\t', ':') for page in pages for line in page.split('\n') if line.endswith('\tSOCKS5\t') ]; import pyperclip; pyperclip.copy(','.join(ipsports))

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Да. И как взаимодействовать с этой программой из питона, чтобы она показала историю?

Так этих же программ много - Klipper, ClipIt, Parcellite, CopyQ, Diodon, Clipman, GPaste...

С какой из них ты собрался взаимодействовать? У них всех свое собственное уникальное API, и у некоторых даже не предусматривающее взаимодействие с другими программами.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Так этих же программ много

С какой из них ты собрался взаимодействовать?

С дефолтной в КДЕ. На момент написания темы я не был уверен в её названии.

question4 ★★★★★
() автор топика