Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aef8541135 | ||
|
|
018f369ff4 | ||
|
|
9bc1cbc8a1 | ||
|
|
6569ad66d5 | ||
|
|
4f91f5cf67 | ||
|
|
55530de6b6 |
94
README.md
94
README.md
@@ -1,59 +1,22 @@
|
||||
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)
|
||||
|
||||
Building Profanity with plugin support
|
||||
--------------------------------------
|
||||
|
||||
Additional dependencies required:
|
||||
Dependencies required:
|
||||
|
||||
```
|
||||
autoconf-archive
|
||||
libtool
|
||||
```
|
||||
|
||||
Plus the development packages for supported languages:
|
||||
For Python plugins the following is also required:
|
||||
|
||||
```
|
||||
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
|
||||
@@ -62,51 +25,17 @@ Installing plugins
|
||||
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.
|
||||
|
||||
More help on plugins
|
||||
--------------------
|
||||
Branches
|
||||
--------
|
||||
|
||||
* `/plugins` - Shows a list of loaded plugins.
|
||||
* `/help commands plugins` - Shows commands defined by plugins
|
||||
* `/help <plugin_cmd>` - Show help for a plugin command, e.g. `/help browser`
|
||||
|
||||
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
|
||||
```
|
||||
* `0.5.0`: Maintenance branch for plugins compatible with the current Profanity release 0.5.0
|
||||
* `0.5.1`: Development for the next Profanity patch release 0.5.1
|
||||
* `master`: Development for the next Profanity major release 0.6.0
|
||||
|
||||
Developing plugins
|
||||
------------------
|
||||
@@ -117,10 +46,3 @@ API Documentation:
|
||||
* [C API](http://www.profanity.im/plugins/c/html/profapi_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