Compare commits
6 Commits
feature/ai
...
0.5.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aef8541135 | ||
|
|
018f369ff4 | ||
|
|
9bc1cbc8a1 | ||
|
|
6569ad66d5 | ||
|
|
4f91f5cf67 | ||
|
|
55530de6b6 |
94
README.md
94
README.md
@@ -1,59 +1,22 @@
|
|||||||
profanity-plugins
|
profanity-plugins
|
||||||
=================
|
=================
|
||||||
|
|
||||||
Plugin support for Profanity is currently in development.
|
|
||||||
|
|
||||||
* The `master` branch of Profanity now includes support for C and Python plugins.
|
|
||||||
* The `plugins` branch contains additional support for Ruby and Lua, but is unstable.
|
|
||||||
|
|
||||||
For a list of outstanding issues before releasing 0.5.0, see: https://github.com/boothj5/profanity/milestones/0.5.0
|
|
||||||
|
|
||||||
* [Website documentation](http://www.profanity.im/plugins.html)
|
* [Website documentation](http://www.profanity.im/plugins.html)
|
||||||
|
|
||||||
Building Profanity with plugin support
|
Building Profanity with plugin support
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
Additional dependencies required:
|
Dependencies required:
|
||||||
|
|
||||||
```
|
```
|
||||||
autoconf-archive
|
autoconf-archive
|
||||||
libtool
|
libtool
|
||||||
```
|
```
|
||||||
|
|
||||||
Plus the development packages for supported languages:
|
For Python plugins the following is also required:
|
||||||
|
|
||||||
```
|
```
|
||||||
python-dev
|
python-dev
|
||||||
lua-dev
|
|
||||||
ruby-dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Build with:
|
|
||||||
|
|
||||||
```
|
|
||||||
./bootstrap.sh
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
```
|
|
||||||
|
|
||||||
After building, run `profanity -v` to see which language support is available, example output:
|
|
||||||
|
|
||||||
```
|
|
||||||
Profanity, version 0.5.0dev.plugins-python.63a7316
|
|
||||||
Copyright (C) 2012 - 2016 James Booth <boothj5web@gmail.com>.
|
|
||||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
|
||||||
|
|
||||||
This is free software; you are free to change and redistribute it.
|
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
|
||||||
|
|
||||||
Build information:
|
|
||||||
XMPP library: libmesode
|
|
||||||
Desktop notification support: Enabled
|
|
||||||
OTR support: Enabled
|
|
||||||
PGP support: Enabled
|
|
||||||
C plugins: Enabled
|
|
||||||
Python plugins: Enabled
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Installing plugins
|
Installing plugins
|
||||||
@@ -62,51 +25,17 @@ Installing plugins
|
|||||||
Use the `/plugins install` command, e.g.
|
Use the `/plugins install` command, e.g.
|
||||||
|
|
||||||
```
|
```
|
||||||
/plugins install ~/projects-git/profanity-plugins/say.py
|
/plugins install ~/projects-git/profanity-plugins/stable/say.py
|
||||||
```
|
```
|
||||||
|
|
||||||
See the `/help plugins` command for further plugin management options.
|
See the `/help plugins` command for further plugin management options.
|
||||||
|
|
||||||
More help on plugins
|
Branches
|
||||||
--------------------
|
--------
|
||||||
|
|
||||||
* `/plugins` - Shows a list of loaded plugins.
|
* `0.5.0`: Maintenance branch for plugins compatible with the current Profanity release 0.5.0
|
||||||
* `/help commands plugins` - Shows commands defined by plugins
|
* `0.5.1`: Development for the next Profanity patch release 0.5.1
|
||||||
* `/help <plugin_cmd>` - Show help for a plugin command, e.g. `/help browser`
|
* `master`: Development for the next Profanity major release 0.6.0
|
||||||
|
|
||||||
Plugin themes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The plugins API includes functions to print themed output to the console or a plugins window. The themes need to be added to
|
|
||||||
|
|
||||||
```
|
|
||||||
~/.local/share/profanity/plugin_themes
|
|
||||||
```
|
|
||||||
|
|
||||||
For example ([syscmd.py](https://github.com/boothj5/profanity-plugins/blob/master/syscmd.py) plugin):
|
|
||||||
|
|
||||||
```
|
|
||||||
[system]
|
|
||||||
command=cyan
|
|
||||||
result=green
|
|
||||||
```
|
|
||||||
|
|
||||||
Plugin settings
|
|
||||||
---------------
|
|
||||||
|
|
||||||
The plugins API also includes functions to read and write settings. The settings are stored in:
|
|
||||||
|
|
||||||
```
|
|
||||||
~/.local/share/profanity/plugin_settings
|
|
||||||
```
|
|
||||||
|
|
||||||
For example ([say.py](https://github.com/boothj5/profanity-plugins/blob/master/say.py) plugin):
|
|
||||||
|
|
||||||
```
|
|
||||||
[say]
|
|
||||||
args=-v english -s 120
|
|
||||||
enabled=active
|
|
||||||
```
|
|
||||||
|
|
||||||
Developing plugins
|
Developing plugins
|
||||||
------------------
|
------------------
|
||||||
@@ -117,10 +46,3 @@ API Documentation:
|
|||||||
* [C API](http://www.profanity.im/plugins/c/html/profapi_8h.html)
|
* [C API](http://www.profanity.im/plugins/c/html/profapi_8h.html)
|
||||||
* [C hooks](http://www.profanity.im/plugins/c/html/profhooks_8h.html)
|
* [C hooks](http://www.profanity.im/plugins/c/html/profhooks_8h.html)
|
||||||
|
|
||||||
Example test plugins (Ruby and Lua examples might not be up to date):
|
|
||||||
* [tests/test-c-plugin.c](https://github.com/boothj5/profanity-plugins/blob/master/tests/test-c-plugin/test-c-plugin.c)
|
|
||||||
* [tests/python-test.py](https://github.com/boothj5/profanity-plugins/blob/master/tests/python-test.py)
|
|
||||||
* [tests/RubyTest.rb](https://github.com/boothj5/profanity-plugins/blob/master/tests/RubyTest.rb)
|
|
||||||
* [tests/luatest.lua](https://github.com/boothj5/profanity-plugins/blob/master/tests/luatest.lua)
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
rm -rf ~/.local/share/profanity/plugins/*
|
|
||||||
|
|
||||||
cp ascii.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp syscmd.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp paste.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp browser.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp platform-info.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp say.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp whoami.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp wikipedia-prof.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp clients.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp presence_notify.py ~/.local/share/profanity/plugins/.
|
|
||||||
cp tests/python-test.py ~/.local/share/profanity/plugins/.
|
|
||||||
|
|
||||||
cd pid
|
|
||||||
make clean
|
|
||||||
make
|
|
||||||
cp pid.so ~/.local/share/profanity/plugins/.
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
cd tests/test-c-plugin
|
|
||||||
make clean
|
|
||||||
make
|
|
||||||
cp test-c-plugin.so ~/.local/share/profanity/plugins/.
|
|
||||||
cd ../..
|
|
||||||
|
|
||||||
|
|
||||||
27
paste.py
27
paste.py
@@ -1,27 +0,0 @@
|
|||||||
"""
|
|
||||||
Paste the contents of the clipboard when in a chat or room window.
|
|
||||||
|
|
||||||
Dependencies:
|
|
||||||
pip install future
|
|
||||||
sudo apt-get python-tk (or python3-tk)
|
|
||||||
"""
|
|
||||||
|
|
||||||
import prof
|
|
||||||
import tkinter as tk
|
|
||||||
|
|
||||||
|
|
||||||
def _cmd_paste():
|
|
||||||
root = tk.Tk(baseName="")
|
|
||||||
root.withdraw()
|
|
||||||
result = root.clipboard_get()
|
|
||||||
prof.send_line(u'\u000A' + result)
|
|
||||||
|
|
||||||
|
|
||||||
def prof_init(version, status, account_name, fulljid):
|
|
||||||
synopsis = [
|
|
||||||
"/paste"
|
|
||||||
]
|
|
||||||
description = "Paste contents of clipboard."
|
|
||||||
args = []
|
|
||||||
examples = []
|
|
||||||
prof.register_command("/paste", 0, 0, synopsis, description, args, examples, _cmd_paste)
|
|
||||||
60
stable/paste.py
Normal file
60
stable/paste.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
"""
|
||||||
|
Paste the contents of the clipboard when in a chat or room window.
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
pip install future
|
||||||
|
sudo apt-get python-tk (or python3-tk)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import prof
|
||||||
|
import tkinter as tk
|
||||||
|
|
||||||
|
|
||||||
|
def _cmd_paste(arg1=None, arg2=None):
|
||||||
|
if not arg1:
|
||||||
|
root = tk.Tk(baseName="")
|
||||||
|
root.withdraw()
|
||||||
|
result = root.clipboard_get()
|
||||||
|
newline = prof.settings_boolean_get("paste", "newline", True)
|
||||||
|
if len(result.splitlines()) > 1 and newline:
|
||||||
|
prof.send_line(u'\u000A' + result)
|
||||||
|
else:
|
||||||
|
prof.send_line(result)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if arg1 == "newline":
|
||||||
|
if not arg2:
|
||||||
|
prof.cons_show("")
|
||||||
|
newline = prof.settings_boolean_get("paste", "newline", True)
|
||||||
|
if newline:
|
||||||
|
prof.cons_show("paste.py newline: on")
|
||||||
|
else:
|
||||||
|
prof.cons_show("paste.py newline: off")
|
||||||
|
elif arg2 == "on":
|
||||||
|
prof.settings_boolean_set("paste", "newline", True)
|
||||||
|
prof.cons_show("paste.py newline enabled.")
|
||||||
|
elif arg2 == "off":
|
||||||
|
prof.settings_boolean_set("paste", "newline", False)
|
||||||
|
prof.cons_show("paste.py newline disabled.")
|
||||||
|
else:
|
||||||
|
prof.cons_bad_cmd_usage("/paste")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
prof.cons_bad_cmd_usage("/paste")
|
||||||
|
|
||||||
|
|
||||||
|
def prof_init(version, status, account_name, fulljid):
|
||||||
|
synopsis = [
|
||||||
|
"/paste",
|
||||||
|
"/paste newline on|off"
|
||||||
|
]
|
||||||
|
description = "Paste contents of clipboard."
|
||||||
|
args = [
|
||||||
|
[ "newline on|off", "Send newline before multiline clipboard text, defaults to on" ]
|
||||||
|
]
|
||||||
|
examples = []
|
||||||
|
prof.register_command("/paste", 0, 2, synopsis, description, args, examples, _cmd_paste)
|
||||||
|
prof.completer_add("/paste", [ "newline" ])
|
||||||
|
prof.completer_add("/paste newline", [ "on", "off" ])
|
||||||
129
stable/syscmd.py
Normal file
129
stable/syscmd.py
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
"""
|
||||||
|
Allow running system commands in a plugin window, or send result to recipient
|
||||||
|
|
||||||
|
Theme options in ~/.local/share/profanity/plugin_themes
|
||||||
|
|
||||||
|
[system]
|
||||||
|
command=magenta
|
||||||
|
result=green
|
||||||
|
"""
|
||||||
|
|
||||||
|
import prof
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
system_win = "System"
|
||||||
|
|
||||||
|
|
||||||
|
def _get_result(command):
|
||||||
|
return subprocess.Popen(command, shell=True, stdout=subprocess.PIPE).stdout.read()
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_win_input(win, command):
|
||||||
|
prof.win_show_themed(win, "system", "command", None, command)
|
||||||
|
prof.win_show(win, "")
|
||||||
|
result = _get_result(command)
|
||||||
|
split = result.splitlines()
|
||||||
|
for s in split:
|
||||||
|
prof.win_show_themed(win, "system", "result", None, s)
|
||||||
|
prof.win_show(win, "")
|
||||||
|
|
||||||
|
|
||||||
|
def create_win():
|
||||||
|
if prof.win_exists(system_win) == False:
|
||||||
|
prof.win_create(system_win, _handle_win_input)
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_send(command=None):
|
||||||
|
if command == None:
|
||||||
|
prof.cons_bad_cmd_usage("/system")
|
||||||
|
return
|
||||||
|
|
||||||
|
room = prof.get_current_muc()
|
||||||
|
recipient = prof.get_current_recipient()
|
||||||
|
if room == None and recipient == None:
|
||||||
|
prof.cons_show("You must be in a chat or muc window to send a system command")
|
||||||
|
prof.cons_alert()
|
||||||
|
return
|
||||||
|
|
||||||
|
result = _get_result(command)
|
||||||
|
newline = prof.settings_boolean_get("system", "newline", True)
|
||||||
|
if len(result.splitlines()) > 1 and newline:
|
||||||
|
prof.send_line(u'\u000A' + result)
|
||||||
|
else:
|
||||||
|
prof.send_line(result)
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_exec(command=None):
|
||||||
|
if command == None:
|
||||||
|
prof.cons_bad_cmd_usage("/system")
|
||||||
|
return;
|
||||||
|
|
||||||
|
create_win()
|
||||||
|
prof.win_focus(system_win)
|
||||||
|
_handle_win_input(system_win, command)
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_newline(setting=None):
|
||||||
|
if not setting:
|
||||||
|
prof.cons_show("")
|
||||||
|
newline = prof.settings_boolean_get("system", "newline", True)
|
||||||
|
if newline:
|
||||||
|
prof.cons_show("syscmd.py newline: on")
|
||||||
|
else:
|
||||||
|
prof.cons_show("syscmd.py newline: off")
|
||||||
|
return
|
||||||
|
|
||||||
|
if setting == "on":
|
||||||
|
prof.settings_boolean_set("system", "newline", True)
|
||||||
|
prof.cons_show("syscmd.py newline enabled.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if setting == "off":
|
||||||
|
prof.settings_boolean_set("system", "newline", False)
|
||||||
|
prof.cons_show("syscmd.py newline disabled.")
|
||||||
|
return
|
||||||
|
|
||||||
|
prof.cons_bad_cmd_usage("/paste")
|
||||||
|
|
||||||
|
|
||||||
|
def _cmd_system(arg1=None, arg2=None):
|
||||||
|
if not arg1:
|
||||||
|
create_win()
|
||||||
|
prof.win_focus(system_win)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if arg1 == "newline":
|
||||||
|
_handle_newline(arg2)
|
||||||
|
return
|
||||||
|
|
||||||
|
if arg1 == "send":
|
||||||
|
_handle_send(arg2)
|
||||||
|
return
|
||||||
|
|
||||||
|
if arg1 == "exec":
|
||||||
|
_handle_exec(arg2)
|
||||||
|
return
|
||||||
|
|
||||||
|
prof.cons_bad_cmd_usage("/system")
|
||||||
|
|
||||||
|
|
||||||
|
def prof_init(version, status, account_name, fulljid):
|
||||||
|
synopsis = [
|
||||||
|
"/system",
|
||||||
|
"/system newline on|off",
|
||||||
|
"/system exec <comman>",
|
||||||
|
"/system send <command>"
|
||||||
|
]
|
||||||
|
description = "Run a system command, calling with no arguments will open or focus the system window."
|
||||||
|
args = [
|
||||||
|
[ "newline on|off", "Send newline before multiline command output, defaults to on" ],
|
||||||
|
[ "exec <command>", "Execute a command" ],
|
||||||
|
[ "send <command>", "Send the result of the command to the current recipient or room" ]
|
||||||
|
]
|
||||||
|
examples = [
|
||||||
|
"/system exec ls -l",
|
||||||
|
"/system send uname -a"
|
||||||
|
]
|
||||||
|
prof.register_command("/system", 0, 2, synopsis, description, args, examples, _cmd_system)
|
||||||
|
prof.completer_add("/system", [ "exec", "send", "newline" ])
|
||||||
|
prof.completer_add("/system newline", [ "on", "off" ])
|
||||||
79
syscmd.py
79
syscmd.py
@@ -1,79 +0,0 @@
|
|||||||
"""
|
|
||||||
Allow running system commands in a plugin window, or send result to recipient
|
|
||||||
|
|
||||||
Theme options in ~/.local/share/profanity/plugin_themes
|
|
||||||
|
|
||||||
[system]
|
|
||||||
command=magenta
|
|
||||||
result=green
|
|
||||||
"""
|
|
||||||
|
|
||||||
import prof
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
system_win = "System"
|
|
||||||
|
|
||||||
|
|
||||||
def _get_result(command):
|
|
||||||
return subprocess.Popen(command, shell=True, stdout=subprocess.PIPE).stdout.read()
|
|
||||||
|
|
||||||
|
|
||||||
def _handle_win_input(win, command):
|
|
||||||
prof.win_show_themed(win, "system", "command", None, command)
|
|
||||||
prof.win_show(win, "")
|
|
||||||
result = _get_result(command)
|
|
||||||
split = result.splitlines()
|
|
||||||
for s in split:
|
|
||||||
prof.win_show_themed(win, "system", "result", None, s)
|
|
||||||
prof.win_show(win, "")
|
|
||||||
|
|
||||||
|
|
||||||
def create_win():
|
|
||||||
if prof.win_exists(system_win) == False:
|
|
||||||
prof.win_create(system_win, _handle_win_input)
|
|
||||||
|
|
||||||
|
|
||||||
def _cmd_system(arg1=None, arg2=None):
|
|
||||||
if not arg1:
|
|
||||||
create_win()
|
|
||||||
prof.win_focus(system_win)
|
|
||||||
elif arg1 == "send":
|
|
||||||
if arg2 == None:
|
|
||||||
prof.cons_bad_cmd_usage("/system")
|
|
||||||
else:
|
|
||||||
room = prof.get_current_muc()
|
|
||||||
recipient = prof.get_current_recipient()
|
|
||||||
if room == None and recipient == None:
|
|
||||||
prof.cons_show("You must be in a chat or muc window to send a system command")
|
|
||||||
prof.cons_alert()
|
|
||||||
else:
|
|
||||||
result = _get_result(arg2)
|
|
||||||
prof.send_line(u'\u000A' + result)
|
|
||||||
elif arg1 == "exec":
|
|
||||||
if arg2 == None:
|
|
||||||
prof.cons_bad_cmd_usage("/system")
|
|
||||||
else:
|
|
||||||
create_win()
|
|
||||||
prof.win_focus(system_win)
|
|
||||||
_handle_win_input(system_win, arg2)
|
|
||||||
else:
|
|
||||||
prof.cons_bad_cmd_usage("/system")
|
|
||||||
|
|
||||||
|
|
||||||
def prof_init(version, status, account_name, fulljid):
|
|
||||||
synopsis = [
|
|
||||||
"/system",
|
|
||||||
"/system exec <comman>",
|
|
||||||
"/system send <command>"
|
|
||||||
]
|
|
||||||
description = "Run a system command, calling with no arguments will open or focus the system window."
|
|
||||||
args = [
|
|
||||||
[ "exec <command>", "Execute a command" ],
|
|
||||||
[ "send <command>", "Send the result of the command to the current recipient or room" ]
|
|
||||||
]
|
|
||||||
examples = [
|
|
||||||
"/system exec ls -l",
|
|
||||||
"/system send uname -a"
|
|
||||||
]
|
|
||||||
prof.register_command("/system", 0, 2, synopsis, description, args, examples, _cmd_system)
|
|
||||||
prof.completer_add("/system", [ "exec", "send" ])
|
|
||||||
Reference in New Issue
Block a user