Created
June 29, 2016 00:28
-
-
Save matejc/fe3b046809b61d92b89f6245cee3f3cb to your computer and use it in GitHub Desktop.
weechat pushbullet notification
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import re | |
import json | |
import weechat | |
from urllib2 import Request | |
from urllib2 import urlopen | |
SCRIPT_NAME = 'pushnotify' | |
SCRIPT_AUTHOR = 'matejc' | |
SCRIPT_VERSION = '0.1' | |
SCRIPT_LICENSE = 'MIT' | |
SCRIPT_DESC = '''Sends pushbullet notifications upon events, | |
at most one per 1min.''' | |
# ----------------------------------------------------------------------------- | |
# Settings | |
# ----------------------------------------------------------------------------- | |
SETTINGS = { | |
'show_public_message': 'off', | |
'show_private_message': 'on', | |
'show_public_action_message': 'off', | |
'show_private_action_message': 'on', | |
'show_notice_message': 'off', | |
'show_invite_message': 'on', | |
'show_highlighted_message': 'on', | |
'show_server': 'on', | |
'show_channel_topic': 'on', | |
'show_dcc': 'on', | |
'show_upgrade_ended': 'on', | |
'sticky': 'off', | |
'sticky_away': 'on', | |
'pb_api_key': 'changeme!' | |
} | |
# ----------------------------------------------------------------------------- | |
# Globals | |
# ----------------------------------------------------------------------------- | |
TAGGED_MESSAGES = { | |
'public message or action': set(['irc_privmsg', 'notify_message']), | |
'private message or action': set(['irc_privmsg', 'notify_private']), | |
'notice message': set(['irc_notice', 'notify_private']), | |
'invite message': set(['irc_invite', 'notify_highlight']), | |
'channel topic': set(['irc_topic', ]), | |
# 'away status': set(['away_info', ]), | |
} | |
UNTAGGED_MESSAGES = { | |
'away status': | |
re.compile(r'^You ((\w+).){2,3}marked as being away', re.UNICODE), | |
'dcc chat request': | |
re.compile(r'^xfer: incoming chat request from (\w+)', re.UNICODE), | |
'dcc chat closed': | |
re.compile(r'^xfer: chat closed with (\w+)', re.UNICODE), | |
'dcc get request': | |
re.compile( | |
r'^xfer: incoming file from (\w+) [^:]+: ((?:,\w|[^,])+),', | |
re.UNICODE), | |
'dcc get completed': | |
re.compile(r'^xfer: file ([^\s]+) received from \w+: OK', re.UNICODE), | |
'dcc get failed': | |
re.compile( | |
r'^xfer: file ([^\s]+) received from \w+: FAILED', | |
re.UNICODE), | |
'dcc send completed': | |
re.compile(r'^xfer: file ([^\s]+) sent to \w+: OK', re.UNICODE), | |
'dcc send failed': | |
re.compile(r'^xfer: file ([^\s]+) sent to \w+: FAILED', re.UNICODE), | |
} | |
DISPATCH_TABLE = { | |
'away status': 'set_away_status', | |
'public message or action': 'notify_public_message_or_action', | |
'private message or action': 'notify_private_message_or_action', | |
'notice message': 'notify_notice_message', | |
'invite message': 'notify_invite_message', | |
'channel topic': 'notify_channel_topic', | |
'dcc chat request': 'notify_dcc_chat_request', | |
'dcc chat closed': 'notify_dcc_chat_closed', | |
'dcc get request': 'notify_dcc_get_request', | |
'dcc get completed': 'notify_dcc_get_completed', | |
'dcc get failed': 'notify_dcc_get_failed', | |
'dcc send completed': 'notify_dcc_send_completed', | |
'dcc send failed': 'notify_dcc_send_failed', | |
} | |
STATE = { | |
'icon': None, | |
'is_away': False | |
} | |
lines = [] | |
# ----------------------------------------------------------------------------- | |
# Notifiers | |
# ----------------------------------------------------------------------------- | |
def cb_irc_server_connected(data, signal, signal_data): | |
'''Notify when connected to IRC server.''' | |
if weechat.config_get_plugin('show_server') == 'on': | |
a_notify( | |
'Server', | |
'Server Connected', | |
'Connected to network {0}.'.format(signal_data)) | |
return weechat.WEECHAT_RC_OK | |
def cb_irc_server_disconnected(data, signal, signal_data): | |
'''Notify when disconnected to IRC server.''' | |
if weechat.config_get_plugin('show_server') == 'on': | |
a_notify( | |
'Server', | |
'Server Disconnected', | |
'Disconnected from network {0}.'.format(signal_data)) | |
return weechat.WEECHAT_RC_OK | |
def cb_notify_upgrade_ended(data, signal, signal_data): | |
'''Notify on end of WeeChat upgrade.''' | |
if weechat.config_get_plugin('show_upgrade_ended') == 'on': | |
a_notify( | |
'WeeChat', | |
'WeeChat Upgraded', | |
'WeeChat has been upgraded.') | |
return weechat.WEECHAT_RC_OK | |
def notify_highlighted_message(buffername, prefix, message): | |
'''Notify on highlighted message.''' | |
if weechat.config_get_plugin("show_highlighted_message") == "on": | |
a_notify( | |
'Highlight', | |
'Highlighted on {0} by {1}'.format(buffername, prefix), | |
"{0}: {1}".format(prefix, message), | |
) | |
def notify_public_message_or_action(buffername, prefix, message, highlighted): | |
'''Notify on public message or action.''' | |
if prefix == ' *': | |
regex = re.compile(r'^(\w+) (.+)$', re.UNICODE) | |
match = regex.match(message) | |
if match: | |
prefix = match.group(1) | |
message = match.group(2) | |
notify_public_action_message(buffername, prefix, | |
message, highlighted) | |
else: | |
if highlighted: | |
notify_highlighted_message(buffername, prefix, message) | |
elif weechat.config_get_plugin("show_public_message") == "on": | |
a_notify( | |
'Public', | |
'Public Message on {0}'.format(buffername), | |
'{0}: {1}'.format(prefix, message)) | |
def notify_private_message_or_action(buffername, prefix, message, highlighted): | |
'''Notify on private message or action.''' | |
regex = re.compile(r'^CTCP_MESSAGE.+?ACTION (.+)$', re.UNICODE) | |
match = regex.match(message) | |
if match: | |
notify_private_action_message(buffername, prefix, | |
match.group(1), highlighted) | |
else: | |
if prefix == ' *': | |
regex = re.compile(r'^(\w+) (.+)$', re.UNICODE) | |
match = regex.match(message) | |
if match: | |
prefix = match.group(1) | |
message = match.group(2) | |
notify_private_action_message(buffername, prefix, | |
message, highlighted) | |
else: | |
if highlighted: | |
notify_highlighted_message(buffername, prefix, message) | |
elif weechat.config_get_plugin("show_private_message") == "on": | |
a_notify( | |
'Private', | |
'Private Message', | |
'{0}: {1}'.format(prefix, message)) | |
def notify_public_action_message(buffername, prefix, message, highlighted): | |
'''Notify on public action message.''' | |
if highlighted: | |
notify_highlighted_message(buffername, prefix, message) | |
elif weechat.config_get_plugin("show_public_action_message") == "on": | |
a_notify( | |
'Action', | |
'Public Action Message on {0}'.format(buffername), | |
'{0}: {1}'.format(prefix, message), | |
) | |
def notify_private_action_message(buffername, prefix, message, highlighted): | |
'''Notify on private action message.''' | |
if highlighted: | |
notify_highlighted_message(buffername, prefix, message) | |
elif weechat.config_get_plugin("show_private_action_message") == "on": | |
a_notify( | |
'Action', | |
'Private Action Message', | |
'{0}: {1}'.format(prefix, message), | |
) | |
def notify_notice_message(buffername, prefix, message, highlighted): | |
'''Notify on notice message.''' | |
regex = re.compile(r'^([^\s]*) [^:]*: (.+)$', re.UNICODE) | |
match = regex.match(message) | |
if match: | |
prefix = match.group(1) | |
message = match.group(2) | |
if highlighted: | |
notify_highlighted_message(buffername, prefix, message) | |
elif weechat.config_get_plugin("show_notice_message") == "on": | |
a_notify( | |
'Notice', | |
'Notice Message', | |
'{0}: {1}'.format(prefix, message)) | |
def notify_invite_message(buffername, prefix, message, highlighted): | |
'''Notify on channel invitation message.''' | |
if weechat.config_get_plugin("show_invite_message") == "on": | |
regex = re.compile( | |
r'^You have been invited to ([^\s]+) by ([^\s]+)$', re.UNICODE) | |
match = regex.match(message) | |
if match: | |
channel = match.group(1) | |
nick = match.group(2) | |
a_notify( | |
'Invite', | |
'Channel Invitation', | |
'{0} has invited you to join {1}.'.format(nick, channel)) | |
def notify_channel_topic(buffername, prefix, message, highlighted): | |
'''Notify on channel topic change.''' | |
if weechat.config_get_plugin("show_channel_topic") == "on": | |
regex = re.compile( | |
r'^\w+ has (?:changed|unset) topic for ([^\s]+)' + | |
'(?:(?: from "(?:.+)")? to "(.+)")?', | |
re.UNICODE) | |
match = regex.match(message) | |
if match: | |
channel = match.group(1) | |
topic = match.group(2) or '' | |
a_notify( | |
'Channel', | |
'Channel Topic on {0}'.format(buffername), | |
"{0}: {1}".format(channel, topic)) | |
def notify_dcc_chat_request(match): | |
'''Notify on DCC chat request.''' | |
if weechat.config_get_plugin("show_dcc") == "on": | |
nick = match.group(1) | |
a_notify( | |
'DCC', | |
'Direct Chat Request', | |
'{0} wants to chat directly.'.format(nick)) | |
def notify_dcc_chat_closed(match): | |
'''Notify on DCC chat termination.''' | |
if weechat.config_get_plugin("show_dcc") == "on": | |
nick = match.group(1) | |
a_notify( | |
'DCC', | |
'Direct Chat Ended', | |
'Direct chat with {0} has ended.'.format(nick)) | |
def notify_dcc_get_request(match): | |
'Notify on DCC get request.' | |
if weechat.config_get_plugin("show_dcc") == "on": | |
nick = match.group(1) | |
file_name = match.group(2) | |
a_notify( | |
'DCC', | |
'File Transfer Request', | |
'{0} wants to send you {1}.'.format(nick, file_name)) | |
def notify_dcc_get_completed(match): | |
'Notify on DCC get completion.' | |
if weechat.config_get_plugin("show_dcc") == "on": | |
file_name = match.group(1) | |
a_notify('DCC', 'Download Complete', file_name) | |
def notify_dcc_get_failed(match): | |
'Notify on DCC get failure.' | |
if weechat.config_get_plugin("show_dcc") == "on": | |
file_name = match.group(1) | |
a_notify('DCC', 'Download Failed', file_name) | |
def notify_dcc_send_completed(match): | |
'Notify on DCC send completion.' | |
if weechat.config_get_plugin("show_dcc") == "on": | |
file_name = match.group(1) | |
a_notify('DCC', 'Upload Complete', file_name) | |
def notify_dcc_send_failed(match): | |
'Notify on DCC send failure.' | |
if weechat.config_get_plugin("show_dcc") == "on": | |
file_name = match.group(1) | |
a_notify('DCC', 'Upload Failed', file_name) | |
# ----------------------------------------------------------------------------- | |
# Utility | |
# ----------------------------------------------------------------------------- | |
def set_away_status(match): | |
status = match.group(1) | |
if status == 'been ': | |
STATE['is_away'] = True | |
if status == 'longer ': | |
STATE['is_away'] = False | |
def cb_process_message( | |
data, | |
wbuffer, | |
date, | |
tags, | |
displayed, | |
highlight, | |
prefix, | |
message | |
): | |
'''Delegates incoming messages to appropriate handlers.''' | |
if prefix == weechat.buffer_get_string(weechat.current_buffer(), 'localvar_nick'): | |
global lines | |
del lines[:] | |
tags = set(tags.split(',')) | |
functions = globals() | |
is_public_message = tags.issuperset( | |
TAGGED_MESSAGES['public message or action']) | |
buffer_name = weechat.buffer_get_string(wbuffer, 'name') | |
dcc_buffer_regex = re.compile(r'^irc_dcc\.', re.UNICODE) | |
dcc_buffer_match = dcc_buffer_regex.match(buffer_name) | |
highlighted = False | |
if int(highlight): | |
highlighted = True | |
# Private DCC message identifies itself as public. | |
if is_public_message and dcc_buffer_match: | |
notify_private_message_or_action(buffer_name, prefix, | |
message, highlighted) | |
return weechat.WEECHAT_RC_OK | |
# Pass identified, untagged message to its designated function. | |
for key, value in UNTAGGED_MESSAGES.items(): | |
match = value.match(message) | |
if match: | |
functions[DISPATCH_TABLE[key]](match) | |
return weechat.WEECHAT_RC_OK | |
# Pass identified, tagged message to its designated function. | |
for key, value in TAGGED_MESSAGES.items(): | |
if tags.issuperset(value): | |
functions[DISPATCH_TABLE[key]](buffer_name, prefix, | |
message, highlighted) | |
return weechat.WEECHAT_RC_OK | |
return weechat.WEECHAT_RC_OK | |
def _push_now(data, remaining_calls): | |
global lines | |
if len(lines) > 0: | |
body = '\n'.join(lines[-3:]) | |
_notify_pushbullet( | |
weechat.config_get_plugin('pb_api_key'), "weechat", body) | |
del lines[:] | |
return weechat.WEECHAT_RC_OK | |
def notify_push(line=None): | |
global lines | |
if line: | |
lines += [line] | |
def _notify_pushbullet(apikey, title, body): | |
apiurl = "https://api.pushbullet.com/v2/pushes" | |
post = { | |
'type': 'note', | |
'title': title, | |
'body': body | |
} | |
data = json.dumps(post).encode('ascii') | |
data_len = len(data) | |
headers = { | |
'Access-Token': apikey, | |
'Content-Type': 'application/json', | |
'Content-Length': data_len | |
} | |
req = Request( | |
url=apiurl, data=data, headers=headers) | |
f = urlopen(req) | |
f.close() | |
def a_notify(notification, subject, message): | |
# if STATE['is_away'] and weechat.config_get_plugin('sticky_away') == 'off': | |
# return | |
# if not STATE['is_away'] and weechat.config_get_plugin('sticky') == 'off': | |
# return | |
notify_push(message) | |
# ----------------------------------------------------------------------------- | |
# Main | |
# ----------------------------------------------------------------------------- | |
def main(): | |
'''Sets up WeeChat notifications.''' | |
# Initialize options. | |
for option, value in SETTINGS.items(): | |
if not weechat.config_is_set_plugin(option): | |
weechat.config_set_plugin(option, value) | |
# Register hooks. | |
weechat.hook_signal( | |
'irc_server_connected', | |
'cb_irc_server_connected', | |
'') | |
weechat.hook_signal( | |
'irc_server_disconnected', | |
'cb_irc_server_disconnected', | |
'') | |
weechat.hook_signal('upgrade_ended', 'cb_upgrade_ended', '') | |
weechat.hook_print('', '', '', 1, 'cb_process_message', '') | |
# timer called each minute when second is 00 | |
weechat.hook_timer(60 * 1000, 60, 0, "_push_now", "") | |
if __name__ == '__main__' and weechat.register( | |
SCRIPT_NAME, | |
SCRIPT_AUTHOR, | |
SCRIPT_VERSION, | |
SCRIPT_LICENSE, | |
SCRIPT_DESC, | |
'', | |
'' | |
): | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment