Restructure project

This commit is contained in:
James Booth
2016-11-13 17:01:39 +00:00
parent 5eea0240ad
commit cdb6cd93b5
20 changed files with 0 additions and 27 deletions

37
stable/ascii.py Normal file
View File

@@ -0,0 +1,37 @@
"""
Print something in ASCII text.
Running from the console will print the text to the console.
Running in a chat or room window will send the ASCII text
Requires 'figlet' which is available on most linux distros e.g.:
sudo apt-get install figlet
"""
import prof
import subprocess
def _cmd_ascii(text):
proc = subprocess.Popen(['figlet', '--', text], stdout=subprocess.PIPE)
ascii_out = proc.communicate()[0].decode('utf-8')
recipient = prof.get_current_recipient()
room = prof.get_current_muc()
if recipient:
prof.send_line(u'\u000A' + ascii_out)
elif room:
prof.send_line(u'\u000A' + ascii_out)
elif prof.current_win_is_console():
prof.cons_show(u'\u000A' + ascii_out)
def prof_init(version, status, account_name, fulljid):
synopsis = [ "/ascii <message>" ]
description = "ASCIIfy a message."
args = [
[ "<message>", "The message to be ASCIIfied" ]
]
examples = [
"/ascii \"Hello there\""
]
prof.register_command("/ascii", 1, 1, synopsis, description, args, examples, _cmd_ascii)

121
stable/browser.py Normal file
View File

@@ -0,0 +1,121 @@
"""
Open the last link received in a chat or room window using the systems default browser
"""
import prof
import os
import webbrowser
import re
_links = {}
_lastlink = {}
def _cmd_browser(url):
global _lastlink
link = None
# use arg if supplied
if (url is not None):
link = url
else:
jid = prof.get_current_recipient()
room = prof.get_current_muc()
# check if in chat window
if (jid is not None):
# check for link from recipient
if jid in _lastlink.keys():
link = _lastlink[jid]
else:
prof.cons_show("No links found from " + jid)
# check if in muc window
elif (room is not None):
if room in _lastlink.keys():
link = _lastlink[room]
else:
prof.cons_show("No links found from " + room)
# not in chat/muc window
else:
prof.cons_show("You must supply a URL to the /browser command")
# open the browser if link found
if (link is not None):
prof.cons_show("Opening " + link + " in browser")
_open_browser(link)
def _open_browser(url):
savout = os.dup(1)
saverr = os.dup(2)
os.close(1)
os.close(2)
os.open(os.devnull, os.O_RDWR)
try:
webbrowser.open(url, new=2)
finally:
os.dup2(savout, 1)
os.dup2(saverr, 2)
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/browser",
"/browser <url>"
]
description = "View a URL in the systems default browser. If no argument is supplied, the last URL in the current chat or room will be used. " \
"Tab autocompletion will go through all previous links in the current chat/room"
args = [
[ "<url>", "URL to open in the browser" ]
]
examples = [
"/browser http://www.profanity.im"
]
prof.register_command("/browser", 0, 1, synopsis, description, args, examples, _cmd_browser)
def prof_on_chat_win_focus(barejid):
prof.completer_clear("/browser")
if barejid in _links:
prof.completer_add("/browser", _links[barejid])
def prof_on_room_win_focus(barejid):
prof.completer_clear("/browser")
if barejid in _links:
prof.completer_add("/browser", _links[barejid])
def _process_message(barejid, current_jid, message):
links = re.findall(r'(https?://\S+)', message)
if (len(links) > 0):
if barejid not in _links:
_links[barejid] = []
# add to list of links for barejid
for link in links:
if link not in _links[barejid]:
_links[barejid].append(link)
# add to autocompleter if message for current window
if current_jid == barejid:
prof.completer_add("/browser", _links[barejid])
# set last link for barejid
_lastlink[barejid] = links[len(links)-1]
def prof_post_chat_message_display(barejid, resource, message):
current_jid = prof.get_current_recipient()
_process_message(barejid, current_jid, message)
def prof_post_room_message_display(barejid, nick, message):
current_jid = prof.get_current_muc()
_process_message(barejid, current_jid, message)
def prof_on_room_history_message(barejid, nick, message, timestamp):
current_jid = prof.get_current_muc()
_process_message(barejid, current_jid, message)

101
stable/clients.py Normal file
View File

@@ -0,0 +1,101 @@
import prof
import xml.etree.ElementTree as ET
clients_win = "Clients"
iq_id_count = 1
def _handle_win_input(win, command):
pass
def _create_win():
if prof.win_exists(clients_win) == False:
prof.win_create(clients_win, _handle_win_input)
def prof_on_iq_stanza_receive(stanza):
iq = ET.fromstring(stanza)
iq_id = iq.get("id")
if not iq_id:
return True
if not iq_id.startswith("clients_"):
return True
iq_type = iq.get("type")
if not iq_type:
return True
if iq_type != "result":
return True
iq_from = iq.get("from")
if not iq_from:
return True
query = iq.find("{jabber:iq:version}query")
if query is None:
return True
name = query.find("{jabber:iq:version}name")
version = query.find("{jabber:iq:version}version")
if name is None and version is None:
return True
message = iq_from.split("/")[1]
if name is not None:
message = message + ", " + name.text
if version is not None:
message = message + ", " + version.text
prof.win_show(clients_win, message)
return False
def _sv_send(muc, occupant):
global iq_id_count
iq = ET.Element("iq", {
"type": "get",
"to": muc + "/" + occupant,
"id": "clients_" + str(iq_id_count)
})
ET.SubElement(iq, "query", {
"xmlns": "jabber:iq:version"
})
iq_id_count = iq_id_count + 1
prof.send_stanza(ET.tostring(iq))
def _cmd_clients():
muc = prof.get_current_muc()
if muc == None:
prof.cons_show("Command only valid in chat rooms.")
return
occupants = prof.get_current_occupants()
if occupants == None or len(occupants) == 0:
prof.cons_show("No occupants for /clients command.")
return
nick = prof.get_current_nick()
_create_win()
prof.win_focus(clients_win)
for occupant in occupants:
if nick != occupant:
_sv_send(muc, occupant)
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/clients"
]
description = "Show client software used by chat room occupants"
args = []
examples = []
prof.register_command("/clients", 0, 0, synopsis, description, args, examples, _cmd_clients)

30
stable/emoticons.py Normal file
View File

@@ -0,0 +1,30 @@
"""
Convert smileys ( :) :( etc) to the Unicode character representation
Dependencies:
pip install future
"""
import prof
from builtins import chr
def _emote(input_str):
result = input_str
result = result.replace(":-)", chr(9786))
result = result.replace(":)", chr(9786))
result = result.replace(":-(", chr(9785))
result = result.replace(":(", chr(9785))
return result
def prof_pre_chat_message_display(barejid, resource, message):
return _emote(message)
def prof_pre_room_message_display(barejid, nick, message):
return _emote(message)
def prof_pre_priv_message_display(barejid, nick, message):
return _emote(message)

62
stable/imgur.py Normal file
View File

@@ -0,0 +1,62 @@
"""
Requires imgur API
pip install imgurpython
Requires scrot installed for screenshot (on linux)
sudo apt-get install scrot
Uses built in screencapture on OSX
"""
import prof
import subprocess
import sys
from os import path
from imgurpython import ImgurClient
from imgurpython.helpers.error import ImgurClientError
client_id = '19c4ba3fc2c26ef'
client_secret = 'dd5b0918a2f5d36391d574bd2061c50b47bade63'
client = ImgurClient(client_id, client_secret)
def _cmd_imgur(arg1):
if arg1 == "screenshot":
file_path = "/tmp/_prof_screenshot.png"
if sys.platform == "darwin":
subprocess.call("screencapture " + file_path, shell=True)
else:
subprocess.call("scrot " + file_path, shell=True)
else:
try:
file_path = path.expanduser(arg1)
except IOError as ioe:
prof.cons_show('Could not find file at ' + file_path)
return
try:
data = client.upload_from_path(file_path, config=None, anon=True)
prof.send_line(data['link'])
except ImgurClientError as e:
prof.log_error('Could not upload to Imgur - ' + e.error_message)
prof.log_error('Imgur status code - ' + e.status_code)
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/imgur <file_path>",
"/imgur screenshot"
]
description = "Upload an image or screenshot to imgur and send the link"
args = [
[ "<file_path>", "full path to image file" ],
[ "screenshot", "upload a full screen capture" ]
]
examples = [
"/imgur ~/images/cats.jpg",
"/imgur screenshot"
]
prof.register_command("/imgur", 1, 1, synopsis, description, args, examples, _cmd_imgur)
prof.completer_add("/imgur", [ "screenshot" ])
prof.filepath_completer_add("/imgur")

60
stable/paste.py Normal file
View 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" ])

18
stable/pid/Makefile Normal file
View File

@@ -0,0 +1,18 @@
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
LINK_FLAGS := -fno-common -flat_namespace -bundle -undefined suppress
else
LINK_FLAGS := -shared -fpic
endif
all: pid.so
%.so:%.o
$(CC) $(LINK_FLAGS) -lprofanity -o $@ $^
%.o:%.c
$(CC) $(INCLUDE) -D_GNU_SOURCE -D_BSD_SOURCE -fpic -g3 -O0 -std=c99 \
-Wextra -pedantic -c -o $@ $<
clean:
$(RM) pid.so

39
stable/pid/pid.c Normal file
View File

@@ -0,0 +1,39 @@
/*
Simple plugin to display the PID of the Profanity process and its parent
Theme example in ~/.local/share/profanity/plugin_themes
[pid]
self=bold_white
parent=white
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <profapi.h>
void
cmd_pid(char **args)
{
pid_t pid = getpid();
pid_t ppid = getppid();
char buf[50];
sprintf(buf, "PID: %d", pid);
prof_cons_show_themed("pid", "self", NULL, buf);
sprintf(buf, "Parent PID: %d", ppid);
prof_cons_show_themed("pid", "parent", NULL, buf);
prof_cons_alert();
}
void
prof_init(const char * const version, const char * const status, const char *const account_name, const char *const fulljid)
{
char *synopsis[] = { "/pid", NULL };
char *description = "Show process ID and parent Process ID in the console window.";
char *args[][2] = { { NULL, NULL } };
char *examples[] = { NULL };
prof_register_command("/pid", 0, 0, synopsis, description, args, examples, cmd_pid);
}

27
stable/platform-info.py Normal file
View File

@@ -0,0 +1,27 @@
"""
Shows platform details in the console
Theme items in ~/.local/share/profanity/plugin_themes
[platform]
line=cyan
"""
import prof
import platform
def _cmd_platform():
result_summary = platform.platform()
prof.cons_show_themed("platform", "line", None, result_summary)
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/platform"
]
description = "Output system information to the console window."
args = []
examples = []
prof.register_command("/platform", 0, 0, synopsis, description, args, examples, _cmd_platform)

164
stable/presence_notify.py Normal file
View File

@@ -0,0 +1,164 @@
import prof
online = set()
def _show_settings():
prof.cons_show("")
prof.cons_show("Presence notify plugin settings:")
mode = prof.settings_string_get("presence_notify", "mode", "all")
prof.cons_show("Mode: {mode}".format(mode=mode))
resource = prof.settings_boolean_get("presence_notify", "resource", False)
if resource:
prof.cons_show("Resource: ON")
else:
prof.cons_show("Resource: OFF")
ignored_list = prof.settings_string_list_get("presence_notify", "ignored")
if ignored_list and len(ignored_list) > 0:
prof.cons_show("Ignored:")
for contact in ignored_list:
prof.cons_show(" {barejid}".format(barejid=contact))
def _cmd_presence_notify(arg1=None, arg2=None, arg3=None):
if arg1 == "all":
prof.settings_string_set("presence_notify", "mode", "all")
prof.cons_show("Notifying on all presence changes")
return
if arg1 == "online":
prof.settings_string_set("presence_notify", "mode", "online")
prof.cons_show("Notifying on online/offline presence changes only")
return
if arg1 == "off":
prof.settings_string_set("presence_notify", "mode", "off")
prof.cons_show("Presence notifications disabled")
return
if arg1 == "ignored":
if arg2 == "clear":
prof.settings_string_list_clear("presence_notify", "ignored")
prof.cons_show("Removed all ignored contacts for presence notifications")
return
if arg2 == "add":
if not arg3:
prof.cons_bad_cmd_usage("/presence_notify")
return
prof.settings_string_list_add("presence_notify", "ignored", arg3)
prof.cons_show("Added {contact} to ignored contacts for presence notifications".format(contact=arg3))
return
if arg2 == "remove":
if not arg3:
prof.cons_bad_cmd_usage("/presence_notify")
return
res = prof.settings_string_list_remove("presence_notify", "ignored", arg3)
if res:
prof.cons_show("Removed {contact} from ignored contacts for presence notifications".format(contact=arg3))
else:
prof.cons_show("{contact} not in ignore list for presence notiications".format(contact=arg3))
return
prof.cons_bad_cmd_usage("/presence_notify")
return
if arg1 == "resource":
if arg2 == "on":
prof.settings_boolean_set("presence_notify", "resource", True)
prof.cons_show("Showing resource in presence notifications")
return;
if arg2 == "off":
prof.settings_boolean_set("presence_notify", "resource", False)
prof.cons_show("Hiding resource in presence notifications")
return;
prof.cons_bad_cmd_usage("/presence_notify")
return
_show_settings()
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/presence_notify all|online|off",
"/presence_notify ignored add|remove|clear [<barejid>]",
"/presence_notify resource on|off"
]
description = "Send a desktop notification on presence updates."
args = [
[ "all", "Enable all presence notifications" ],
[ "online", "Enable only online/offline presence notifications" ],
[ "off", "Disable presence notifications" ],
[ "ignored add|remove <barejid>", "Add or remove a contact from the list excluded from presence notifications"],
[ "ignored clear", "Clear the list of excluded contacts"],
[ "resource on|off", "Enable/disable showing the contacts resource in the notification"]
]
examples = [
"/presence_notify all",
"/presence_notify ignored add bob@server.org"
]
prof.register_command("/presence_notify", 0, 3, synopsis, description, args, examples, _cmd_presence_notify)
prof.completer_add("/presence_notify",
[ "all", "online", "off", "ignored", "resource" ]
)
prof.completer_add("/presence_notify ignored",
[ "add", "remove", "clear" ]
)
prof.completer_add("/presence_notify resource",
[ "on", "off" ]
)
def _do_notify(barejid, presence):
ignored = prof.settings_string_list_get("presence_notify", "ignored")
if ignored and barejid in ignored:
return False
mode = prof.settings_string_get("presence_notify", "mode", "all")
if mode == "all":
return True
elif mode == "online":
if barejid in online:
if presence == "offline":
online.remove(barejid)
return True
else:
return False
else:
if presence != "offline":
online.add(barejid)
return True
else:
return False
else: # off
return False
def prof_on_contact_presence(barejid, resource, presence, status, priority):
if _do_notify(barejid, presence):
jid = barejid
if prof.settings_boolean_get("presence_notify", "resource", False):
jid = jid + "/" + resource
message = "{jid} is {presence}".format(jid=jid, presence=presence)
if status:
message = message + ", \"{status}\"".format(status=status)
prof.notify(message, 5000, "Presence")
return
def prof_on_contact_offline(barejid, resource, status):
if _do_notify(barejid, "offline"):
jid = barejid
if prof.settings_boolean_get("presence_notify", "resource", False):
jid = jid + "/" + resource
message = "{jid} is offline".format(jid=jid)
if status:
message = message + ", \"{status}\"".format(status=status)
prof.notify(message, 5000, "Presence")
return

102
stable/say.py Normal file
View File

@@ -0,0 +1,102 @@
"""
Read message out loud.
On linux requires 'espeak' which is available on most distributions e.g.:
sudo apt-get install espeak
On OSX will use the built in 'say' command.
"""
import prof
import os
from sys import platform
def say(message):
args = prof.settings_string_get("say", "args", "")
if platform == "darwin":
os.system("say " + args + " '" + message + "' 2>/dev/null")
elif platform == "linux" or platform == "linux2":
os.system("echo '" + message + "' | espeak " + args + " 2>/dev/null")
def prof_post_chat_message_display(barejid, resource, message):
enabled = prof.settings_string_get("say", "enabled", "off")
current_recipient = prof.get_current_recipient()
if enabled == "on" or (enabled == "active" and current_recipient == barejid):
say(barejid + " says " + message)
return message
def prof_post_room_message_display(barejid, nick, message):
enabled = prof.settings_string_get("say", "enabled", "off")
current_muc = prof.get_current_muc()
if enabled == "on":
say(nick + " in " + barejid + " says " + message)
elif enabled == "active" and current_muc == barejid:
say(nick + " says " + message)
return message
def prof_post_priv_message_display(barejid, nick, message):
# TODO add get current nick hook for private chats
if enabled:
say(nick + " says " + message)
return message
def _cmd_say(arg1=None, arg2=None):
if arg1 == "on":
prof.settings_string_set("say", "enabled", "on")
prof.cons_show("Say plugin enabled")
elif arg1 == "off":
prof.settings_string_set("say", "enabled", "off")
prof.cons_show("Say plugin disabled")
elif arg1 == "active":
prof.settings_string_set("say", "enabled", "active")
prof.cons_show("Say plugin enabled for active window only")
elif arg1 == "args":
if arg2 == None:
prof.cons_bad_cmd_usage("/say")
else:
prof.settings_string_set("say", "args", arg2)
prof.cons_show("Say plugin arguments set to: " + arg2)
elif arg1 == "clearargs":
prof.settings_string_set("say", "args", "")
prof.cons_show("Say plugin arguments cleared")
elif arg1 == "test":
if arg2 == None:
prof.cons_bad_cmd_usage("/say")
else:
say(arg2)
else:
enabled = prof.settings_string_get("say", "enabled", "off")
args = prof.settings_string_get("say", "args", "")
prof.cons_show("Say plugin settings:")
prof.cons_show("enabled : " + enabled)
if args != "":
prof.cons_show("args : " + args)
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/say on|off|active",
"/say args <args>",
"/say clearargs",
"/say test <message>"
]
description = "Read messages out loud"
args = [
[ "on|off", "Enable/disable say for all windows" ],
[ "active", "Enable say for active window only" ],
[ "args <args>", "Arguments to pass to command" ],
[ "clearargs", "Clear command arguments" ],
[ "test <message>", "Say message" ]
]
examples = []
prof.register_command("/say", 0, 2, synopsis, description, args, examples, _cmd_say)
prof.completer_add("/say", [ "on", "off", "test", "active", "args", "clearargs" ])

208
stable/sounds.py Normal file
View File

@@ -0,0 +1,208 @@
"""
Play sounds on various events.
Requires mpg123 to be installed on the host system:
sudo apt-get install mpg123
brew install mpg123
"""
import subprocess
from os.path import expanduser
import prof
def _play_sound(soundfile):
if soundfile.startswith("~/"):
soundfilenew = soundfile.replace("~", expanduser("~"), 1)
else:
soundfilenew = soundfile
subprocess.Popen(["mpg123", "-q", soundfilenew])
def _cmd_sounds(arg1=None, arg2=None, arg3=None):
if not arg1:
prof.cons_show("")
enabled = prof.settings_boolean_get("sounds", "enabled", False)
chatsound = prof.settings_string_get("sounds", "chat", None)
roomsound = prof.settings_string_get("sounds", "room", None)
privatesound = prof.settings_string_get("sounds", "private", None)
roomlist = prof.settings_string_list_get("sounds", "rooms")
if chatsound or roomsound or privatesound:
if enabled:
prof.cons_show("Sounds: ON")
else:
prof.cons_show("Sounds: OFF")
if chatsound:
prof.cons_show(" Chat : " + chatsound)
if roomsound:
prof.cons_show(" Room : " + roomsound)
if roomlist and len(roomlist) > 0:
for room in roomlist:
prof.cons_show(" " + room)
else:
prof.cons_show(" All rooms")
if privatesound:
prof.cons_show(" Private : " + privatesound)
else:
prof.cons_show("No sounds set.")
return
if arg1 == "on":
prof.settings_boolean_set("sounds", "enabled", True)
prof.cons_show("Sounds enabled")
return
if arg1 == "off":
prof.settings_boolean_set("sounds", "enabled", False)
prof.cons_show("Sounds disabled")
return
if arg1 == "set":
if arg2 == "chat":
prof.settings_string_set("sounds", "chat", arg3)
prof.cons_show("Set chat sound: " + arg3)
elif arg2 == "room":
prof.settings_string_set("sounds", "room", arg3)
prof.cons_show("Set room sound: " + arg3)
elif arg2 == "private":
prof.settings_string_set("sounds", "private", arg3)
prof.cons_show("Set private sound: " + arg3)
else:
prof.cons_bad_cmd_usage("/sounds")
return
if arg1 == "clear":
if arg2 == "chat":
prof.settings_string_set("sounds", "chat", "")
prof.cons_show("Removed chat sound.")
elif arg2 == "room":
prof.settings_string_set("sounds", "room", "")
prof.cons_show("Removed room sound.")
elif arg2 == "private":
prof.settings_string_set("sounds", "private", "")
prof.cons_show("Removed private sound.")
else:
prof.cons_bad_cmd_usage("/sounds")
return
if arg1 == "rooms":
if arg2 == "add":
if not arg3:
prof.cons_bad_cmd_usage("/sounds")
else:
prof.settings_string_list_add("sounds", "rooms", arg3)
prof.cons_show("Sounds enabled for room: " + arg3)
elif arg2 == "remove":
if not arg3:
prof.cons_bad_cmd_usage("/sounds")
else:
prof.settings_string_list_remove("sounds", "rooms", arg3)
roomlist = prof.settings_string_list_get("sounds", "rooms")
if roomlist and len(roomlist) > 0:
prof.cons_show("Sounds disabled for room: " + arg3)
else:
prof.cons_show("Empty room list for sounds, playing in all rooms.")
elif arg2 == "clear":
prof.settings_string_list_clear("sounds", "rooms")
prof.cons_show("Cleared sounds room list, playing in all rooms.")
else:
prof.cons_bad_cmd_usage("/sounds")
return
prof.cons_bad_cmd_usage("/sounds")
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/sounds",
"/sounds on|off",
"/sounds set chat <file>",
"/sounds set room <file>",
"/sounds set private <file>",
"/sounds clear chat",
"/sounds clear room",
"/sounds clear private",
"/sounds rooms add <roomjid>"
]
description = "Play mp3 sounds on various Profanity events. Calling with no args shows current sound files."
args = [
[ "on|off", "Enable or disable playing sounds." ],
[ "set chat <file>", "Path to mp3 file to play on chat messages." ],
[ "set room <file>", "Path to mp3 file to play on room messages." ],
[ "set private <file>", "Path to mp3 file to play on private room messages." ],
[ "clear chat", "Remove the sound for chat messages." ],
[ "clear room", "Remove the sound for room messages." ],
[ "clear private", "Remove the sound for private messages." ],
[ "rooms add <roomjid>", "Add the room to the list that will play the room sound."],
[ "rooms remove <roomjid>", "Remove the room from the list that will play the room sound."],
[ "rooms clear", "Clear the room list, all rooms will play sounds on new messages."]
]
examples = [
"/sounds set chat ~/sounds/woof.mp3",
"/sounds set room ~/sounds/meow.mp3",
"/sounds set private ~/sounds/shhh.mp3",
"/sounds remove private",
"/sounds rooms add myroom@conference.server.org",
"/sounds on"
]
prof.register_command("/sounds", 0, 3, synopsis, description, args, examples, _cmd_sounds)
prof.completer_add("/sounds", [ "set", "clear", "on", "off", "rooms" ])
prof.completer_add("/sounds set", [ "chat", "room", "private" ])
prof.completer_add("/sounds clear", [ "chat", "room", "private" ])
prof.completer_add("/sounds rooms", [ "add", "remove", "clear" ])
prof.filepath_completer_add("/sounds set chat")
prof.filepath_completer_add("/sounds set room")
prof.filepath_completer_add("/sounds set private")
def prof_post_chat_message_display(barejid, resource, message):
enabled = prof.settings_boolean_get("sounds", "enabled", False)
if not enabled:
return
soundfile = prof.settings_string_get("sounds", "chat", None)
if not soundfile:
return
_play_sound(soundfile)
def prof_post_room_message_display(barejid, nick, message):
my_nick = prof.get_room_nick(barejid)
if not my_nick:
return
if my_nick == nick:
return;
enabled = prof.settings_boolean_get("sounds", "enabled", False)
if not enabled:
return
soundfile = prof.settings_string_get("sounds", "room", None)
if not soundfile:
return
roomlist = prof.settings_string_list_get("sounds", "rooms")
if roomlist and (barejid not in roomlist):
return
_play_sound(soundfile)
def prof_post_priv_message_display(barejid, nick, message):
enabled = prof.settings_boolean_get("sounds", "enabled", False)
if not enabled:
return
soundfile = prof.settings_string_get("sounds", "private", None)
if soundfile:
_play_sound(soundfile)

79
stable/syscmd.py Normal file
View File

@@ -0,0 +1,79 @@
"""
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" ])

25
stable/whoami.py Normal file
View File

@@ -0,0 +1,25 @@
"""
Calls the 'whoami' command
Theme in ~/.local/share/profanity/plugin_themes
[whoami]
result=bold_magenta
"""
import prof
import getpass
def _cmd_whoami():
me = getpass.getuser()
prof.cons_show_themed("whoami", "result", None, me)
def prof_init(version, status, account_name, fulljid):
synopsis = [ "/whoami" ]
description = "Calls the system whoami command"
args = []
examples = []
prof.register_command("/whoami", 0, 0, synopsis, description, args, examples, _cmd_whoami)

238
stable/wikipedia-prof.py Normal file
View File

@@ -0,0 +1,238 @@
"""
Requires wikipedia API
pip install wikipedia
Example theme options (~/.local/share/profanity/plugin_themes):
[wikipedia]
error=red
search=bold_green
search.noresult=red
search.results=green
summary.nopage=red
summary.title=bold_green
summary.url=magenta
summary.text=cyan
page.nopage=red
page.title=bold_green
page.text=cyan
images.nopage=red
images=bold_green
images.url=magenta
links.nopage=red
links=bold_green
links.link=green
refs.nopage=red
refs=bold_green
refs.url=magenta
"""
import prof
import wikipedia
import os
import webbrowser
import requests
win = "Wikipedia"
page_ac = []
link_ac = []
def _open_browser(url):
savout = os.dup(1)
saverr = os.dup(2)
os.close(1)
os.close(2)
os.open(os.devnull, os.O_RDWR)
try:
webbrowser.open(url, new=2)
finally:
os.dup2(savout, 1)
os.dup2(saverr, 2)
def _handle_win_input():
pass
def create_win():
if prof.win_exists(win) == False:
prof.win_create(win, _handle_win_input)
def _update_autocomplete():
prof.completer_add("/wikipedia page", page_ac)
prof.completer_add("/wikipedia summary", page_ac)
prof.completer_add("/wikipedia images", page_ac)
prof.completer_add("/wikipedia links", page_ac)
prof.completer_add("/wikipedia refs", page_ac)
def _search(search_terms):
global page_ac
results = wikipedia.search(search_terms)
create_win()
if len(results) > 0:
prof.win_show_themed(win, "wikipedia", "search", None, "Search results for \"" + search_terms + "\":")
for index, result in enumerate(results):
page_ac.append(result)
prof.win_show_themed(win, "wikipedia", "search.results", None, result)
_update_autocomplete()
else:
prof.win_show_themed(win, "wikipedia", "search.noresults", None, "No search results found for \"" + search_terms + "\"")
prof.win_show(win, "")
prof.win_focus(win)
def _summary(page_str):
global link_ac
page = wikipedia.page(page_str)
create_win()
if not page:
prof.win_show_themed(win, "wikipedia", "summary.nopage", None, "No such page: \"" + page_str + "\"")
prof.win_show(win, "")
prof.win_focus(win)
return
link_ac.append(page.url)
prof.completer_add("/wikipedia open", link_ac)
prof.win_show_themed(win, "wikipedia", "summary.title", None, page.title)
prof.win_show_themed(win, "wikipedia", "summary.url", None, page.url)
summary = wikipedia.summary(page_str)
prof.win_show_themed(win, "wikipedia", "summary.text", None, summary)
prof.win_show(win, "")
prof.win_focus(win)
def _page(page_str):
page = wikipedia.page(page_str)
create_win()
if not page:
prof.win_show_themed(win, "wikipedia", "page.nopage", None, "No such page: \"" + page_str + "\"")
prof.win_show(win, "")
prof.win_focus(win)
return
prof.win_show_themed(win, "wikipedia", "page.title", None, page.title)
prof.win_show_themed(win, "wikipedia", "page.text", None, page.content)
prof.win_show(win, "")
prof.win_focus(win)
def _images(page_str):
global link_ac
page = wikipedia.page(page_str)
create_win()
if not page:
prof.win_show_themed(win, "wikipedia", "images.nopage", None, "No such page: \"" + page_str + "\"")
prof.win_show(win, "")
prof.win_focus(win)
return
prof.win_show_themed(win, "wikipedia", "images", None, "Images for " + page_str)
for image in page.images:
prof.win_show_themed(win, "wikipedia", "images.url", None, image)
link_ac.append(image)
prof.completer_add("/wikipedia open", link_ac)
prof.win_show(win, "")
prof.win_focus(win)
def _links(page_str):
global page_ac
page = wikipedia.page(page_str)
create_win()
if not page:
prof.win_show_themed(win, "wikipedia", "links.nopage", None, "No such page: \"" + page_str + "\"")
prof.win_show(win, "")
prof.win_focus(win)
return
prof.win_show_themed(win, "wikipedia", "links", None, "Links for " + page_str)
for link in page.links:
prof.win_show_themed(win, "wikipedia", "links.link", None, link)
page_ac.append(link)
_update_autocomplete()
prof.win_show(win, "")
prof.win_focus(win)
def _refs(page_str):
global link_ac
page = wikipedia.page(page_str)
create_win()
if not page:
prof.win_show_themed(win, "wikipedia", "refs.nopage", None, "No such page: \"" + page_str + "\"")
prof.win_show(win, "")
prof.win_focus(win)
return
prof.win_show_themed(win, "wikipedia", "refs", None, "References for " + page_str)
for ref in page.references:
prof.win_show_themed(win, "wikipedia", "refs.url", None, ref)
link_ac.append(ref)
prof.completer_add("/wikipedia open", link_ac)
prof.win_show(win, "")
prof.win_focus(win)
def cmd_wp(subcmd, arg):
try:
if subcmd == "search": _search(arg)
elif subcmd == "summary": _summary(arg)
elif subcmd == "page": _page(arg)
elif subcmd == "images": _images(arg)
elif subcmd == "links": _links(arg)
elif subcmd == "refs": _refs(arg)
elif subcmd == "open": _open_browser(arg)
except wikipedia.exceptions.WikipediaException as e:
create_win()
prof.win_show_themed(win, "wikipedia", "error", None, str(e))
prof.win_show(win, "")
prof.win_focus(win)
except requests.exceptions.ConnectionError:
create_win()
prof.win_show_themed(win, "wikipedia", "error", None, "Connection Error")
prof.win_show(win, "")
prof.win_focus(win)
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/wikipedia search <text>",
"/wikipedia summary <title>",
"/wikipedia page <title>",
"/wikipedia images <title>",
"/wikipedia links <title>",
"/wikipedia refs <title>",
"/wikipedia open <url>"
]
description = "Interact with wikipedia."
args = [
[ "search <text>", "Search for pages" ],
[ "summary <title>", "Show summary for page" ],
[ "page <title>", "Show the whole page" ],
[ "images <title>", "Show images URLs for page" ],
[ "links <title>", "Show links to other pages from page" ],
[ "refs <title>", "Show external references for page" ],
[ "open <url>", "Open the a URL in the browser" ]
]
examples = [
"/wikipedia search Iron Maiden"
]
prof.register_command("/wikipedia", 2, 2, synopsis, description, args, examples, cmd_wp)
prof.completer_add("/wikipedia",
[ "search", "summary", "page", "images", "links", "refs", "open" ]
)