Mercurial > dotfiles
diff weechat/perl/pushover.pl @ 259:726728f13152
More Weechat plugins and config.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 21 Jan 2015 16:45:26 -0800 |
parents | |
children | 0a7142b8ab95 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/weechat/perl/pushover.pl Wed Jan 21 16:45:26 2015 -0800 @@ -0,0 +1,302 @@ +# +# Copyright (C) 2013-2014 stfn <stfnmd@gmail.com> +# https://github.com/stfnm/weechat-scripts +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +use strict; +use warnings; + +my %SCRIPT = ( + name => 'pushover', + author => 'stfn <stfnmd@gmail.com>', + version => '1.2', + license => 'GPL3', + desc => 'Send push notifications to your mobile devices using Pushover, NMA or Pushbullet', + opt => 'plugins.var.perl', +); +my %OPTIONS_DEFAULT = ( + 'enabled' => ['on', "Turn script on or off"], + 'service' => ['pushover', 'Notification service to use. Multiple services may be supplied as comma separated list. (supported services: pushover, nma, pushbullet)'], + 'token' => ['ajEX9RWhxs6NgeXFJxSK2jmpY54C9S', 'pushover API token/key (You may feel free to use your own token, so you get your own monthly quota of messages without being affected by other users. See also: https://pushover.net/faq#overview-distribution )'], + 'user' => ['', "pushover user key"], + 'nma_apikey' => ['', "nma API key"], + 'pb_apikey' => ['', "Pushbullet API key"], + 'pb_device_iden' => ['', "Device Iden of pushbullet device"], + 'sound' => ['', "Sound (empty for default)"], + 'priority' => ['', "priority (empty for default)"], + 'show_highlights' => ['on', 'Notify on highlights'], + 'show_priv_msg' => ['on', 'Notify on private messages'], + 'redact_priv_msg' => ['off', 'When receiving private message notifications, hide the actual message text'], + 'only_if_away' => ['off', 'Notify only if away status is active'], + 'only_if_inactive' => ['off', 'Notify only if buffer is not the active (current) buffer'], + 'blacklist' => ['', 'Comma separated list of buffers (full name) to blacklist for notifications (wildcard "*" is allowed, name beginning with "!" is excluded)'], + 'verbose' => ['1', 'Verbosity level (0 = silently ignore any errors, 1 = display brief error, 2 = display full server response)'], +); +my %OPTIONS = (); +my $TIMEOUT = 30 * 1000; + +my $DEBUG = 0; + +# Register script and initialize config +weechat::register($SCRIPT{"name"}, $SCRIPT{"author"}, $SCRIPT{"version"}, $SCRIPT{"license"}, $SCRIPT{"desc"}, "", ""); +init_config(); + +# Setup hooks +weechat::hook_print("", "notify_message,notify_private,notify_highlight", "", 1, "print_cb", ""); +weechat::hook_command($SCRIPT{"name"}, "send custom push notification", + "<text>", + "text: notification text to send", + "", "pushover_cb", ""); + +# +# Handle config stuff +# +sub init_config +{ + weechat::hook_config("$SCRIPT{'opt'}.$SCRIPT{'name'}.*", "config_cb", ""); + my $version = weechat::info_get("version_number", "") || 0; + foreach my $option (keys %OPTIONS_DEFAULT) { + if (!weechat::config_is_set_plugin($option)) { + weechat::config_set_plugin($option, $OPTIONS_DEFAULT{$option}[0]); + $OPTIONS{$option} = $OPTIONS_DEFAULT{$option}[0]; + } else { + $OPTIONS{$option} = weechat::config_get_plugin($option); + } + if ($version >= 0x00030500) { + weechat::config_set_desc_plugin($option, $OPTIONS_DEFAULT{$option}[1]." (default: \"".$OPTIONS_DEFAULT{$option}[0]."\")"); + } + } +} +sub config_cb +{ + my ($pointer, $name, $value) = @_; + $name = substr($name, length("$SCRIPT{opt}.$SCRIPT{name}."), length($name)); + $OPTIONS{$name} = $value; + return weechat::WEECHAT_RC_OK; +} + +# +# Case insensitive search for element in comma separated list +# +sub grep_list($$) +{ + my ($str, $list) = @_; + my @array = split(/,/, $list); + return grep(/^\Q$str\E$/i, @array) ? 1 : 0; +} + +# +# URL escape (percent encoding) +# +sub url_escape($) +{ + my $toencode = $_[0]; + return undef unless (defined($toencode)); + utf8::encode($toencode) if (utf8::is_utf8($toencode)); + $toencode =~ s/([^a-zA-Z0-9_.~-])/uc sprintf("%%%02x",ord($1))/eg; + return $toencode; +} + +# +# Catch printed messages +# +sub print_cb +{ + my ($data, $buffer, $date, $tags, $displayed, $highlight, $prefix, $message) = @_; + + my $buffer_type = weechat::buffer_get_string($buffer, "localvar_type"); + my $buffer_full_name = weechat::buffer_get_string($buffer, "full_name"); + my $away_msg = weechat::buffer_get_string($buffer, "localvar_away"); + my $away = ($away_msg && length($away_msg) > 0) ? 1 : 0; + + if ($OPTIONS{enabled} ne "on" || + $displayed == 0 || + ($OPTIONS{only_if_away} eq "on" && $away == 0) || + ($OPTIONS{only_if_inactive} eq "on" && $buffer eq weechat::current_buffer()) || + weechat::buffer_match_list($buffer, $OPTIONS{blacklist})) { + return weechat::WEECHAT_RC_OK; + } + + my $msg = "[$buffer_full_name] <$prefix> "; + + if ($buffer_type eq "private" && $OPTIONS{redact_priv_msg} eq "on") { + $msg .= "..."; + } else { + $msg .= "$message"; + } + + # Notify! + if ($OPTIONS{show_highlights} eq "on" && $highlight == 1) { + # Message with highlight + notify($msg); + } elsif ($OPTIONS{show_priv_msg} eq "on" && $buffer_type eq "private") { + # Private message + notify($msg); + } + + return weechat::WEECHAT_RC_OK; +} + +# +# /pushover +# +sub pushover_cb +{ + my ($data, $buffer, $args) = @_; + + if (length($args) > 0) { + notify($args); + } + + return weechat::WEECHAT_RC_OK; +} + +# +# Catch API responses +# +sub url_cb +{ + my ($data, $command, $return_code, $out, $err) = @_; + my $msg = "[$SCRIPT{name}] Error: "; + + # Check verbosity level + if ($OPTIONS{verbose} == 0) { + return weechat::WEECHAT_RC_OK; # Don't display anything + } elsif ($OPTIONS{verbose} == 1) { + $msg .= "API call failed. (Most likely the service is having trouble.)"; + + } elsif ($OPTIONS{verbose} == 2) { + $msg .= "@_"; + } + + # Check server response and display error message if NOT successful + if ($command =~ /pushover/ && $return_code == 0 && !($out =~ /\"status\":1/)) { + weechat::print("", $msg); + } elsif ($command =~ /notifymyandroid/ && $return_code == 0 && !($out =~ /success code=\"200\"/)) { + weechat::print("", $msg); + } elsif ($command =~ /pushbullet/ && $return_code == 0 && !($out =~ /\"iden\"/)) { + weechat::print("", $msg); + } + + return weechat::WEECHAT_RC_OK; +} + +# +# Notify wrapper (decides which service to use) +# +sub notify($) +{ + my $message = $_[0]; + + # Notify services + if (grep_list("pushover", $OPTIONS{service})) { + notify_pushover($OPTIONS{token}, $OPTIONS{user}, $message, "weechat", $OPTIONS{priority}, $OPTIONS{sound}); + } + if (grep_list("nma", $OPTIONS{service})) { + notify_nma($OPTIONS{nma_apikey}, "weechat", "$SCRIPT{name}.pl", $message, $OPTIONS{priority}); + } + if (grep_list("pushbullet", $OPTIONS{service})) { + notify_pushbullet($OPTIONS{pb_apikey}, $OPTIONS{pb_device_iden}, "weechat", $message); + } +} + +# +# https://pushover.net/api +# +sub notify_pushover($$$$$$) +{ + my ($token, $user, $message, $title, $priority, $sound) = @_; + + # Required API arguments + my @post = ( + "token=" . url_escape($token), + "user=" . url_escape($user), + "message=" . url_escape($message), + ); + + # Optional API arguments + push(@post, "title=" . url_escape($title)) if ($title && length($title) > 0); + push(@post, "priority=" . url_escape($priority)) if ($priority && length($priority) > 0); + push(@post, "sound=" . url_escape($sound)) if ($sound && length($sound) > 0); + + # Send HTTP POST + my $hash = { "post" => 1, "postfields" => join(";", @post) }; + if ($DEBUG) { + weechat::print("", "[$SCRIPT{name}] Debug: msg -> `$message' HTTP POST -> @post"); + } else { + weechat::hook_process_hashtable("url:https://api.pushover.net/1/messages.json", $hash, $TIMEOUT, "url_cb", ""); + } + + return weechat::WEECHAT_RC_OK; +} + +# +# https://www.notifymyandroid.com/api.jsp +# +sub notify_nma($$$$$) +{ + my ($apikey, $application, $event, $description, $priority) = @_; + + # Required API arguments + my @post = ( + "apikey=" . url_escape($apikey), + "application=" . url_escape($application), + "event=" . url_escape($event), + "description=" . url_escape($description), + ); + + # Optional API arguments + push(@post, "priority=" . url_escape($priority)) if ($priority && length($priority) > 0); + + # Send HTTP POST + my $hash = { "post" => 1, "postfields" => join("&", @post) }; + if ($DEBUG) { + weechat::print("", "[$SCRIPT{name}] Debug: msg -> `$description' HTTP POST -> @post"); + } else { + weechat::hook_process_hashtable("url:https://www.notifymyandroid.com/publicapi/notify", $hash, $TIMEOUT, "url_cb", ""); + } + + return weechat::WEECHAT_RC_OK; +} + +# +# https://docs.pushbullet.com/v2/pushes/ +# +sub notify_pushbullet($$$$) +{ + my ($apikey, $device_iden, $title, $body) = @_; + + # Required API arguments + my $apiurl = "https://$apikey\@api.pushbullet.com/v2/pushes"; + my @post = ( + "type=note", + ); + + # Optional API arguments + push(@post, "device_iden=" . url_escape($device_iden)) if ($device_iden && length($device_iden) > 0); + push(@post, "title=" . url_escape($title)) if ($title && length($title) > 0); + push(@post, "body=" . url_escape($body)) if ($body && length($body) > 0); + + # Send HTTP POST + my $hash = { "post" => 1, "postfields" => join("&", @post) }; + if ($DEBUG) { + weechat::print("", "$apiurl [$SCRIPT{name}] Debug: msg -> `$body' HTTP POST -> @post"); + } else { + weechat::hook_process_hashtable("url:$apiurl", $hash, $TIMEOUT, "url_cb", ""); + } + + return weechat::WEECHAT_RC_OK; +}