diff --git a/weechat/perl/autoload/isgd.pl b/weechat/perl/autoload/isgd.pl new file mode 120000 index 0000000..bc4bbdd --- /dev/null +++ b/weechat/perl/autoload/isgd.pl @@ -0,0 +1 @@ +../isgd.pl \ No newline at end of file diff --git a/weechat/perl/isgd.pl b/weechat/perl/isgd.pl new file mode 100644 index 0000000..cb2f4f9 --- /dev/null +++ b/weechat/perl/isgd.pl @@ -0,0 +1,289 @@ +# +# Copyright (C) 2011-2014 stfn +# 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 . +# + +use strict; +use warnings; +use CGI; + +my %SCRIPT = ( + name => 'isgd', + author => 'stfn ', + version => '0.9', + license => 'GPL3', + desc => 'Shorten URLs with is.gd on demand or automatically', + opt => 'plugins.var.perl', +); +my %OPTIONS_DEFAULT = ( + 'color' => ['white', 'Color used for printing shortened URLs'], + 'auto' => ['off', 'Shorten all incoming URLs automatically'], + 'auto_min_length' => ['1', 'Only shorten incoming URLs automatically which have this minimum length'], +); +my %OPTIONS = (); +my $SHORTENER_URL = "http://is.gd/create.php?format=simple&url="; +my $SHORTENER_BASE = "http://is.gd/"; +my $TIMEOUT = 30 * 1000; +my $CACHE_MAX_SIZE = 128; +my (%LOOKUP, %CACHE); + +weechat::register($SCRIPT{"name"}, $SCRIPT{"author"}, $SCRIPT{"version"}, $SCRIPT{"license"}, $SCRIPT{"desc"}, "", ""); +weechat::hook_print("", "", "", 1, "print_cb", ""); +weechat::hook_command($SCRIPT{"name"}, $SCRIPT{"desc"}, + "[-o] [||]\n", + " -o: send shortened URL to current buffer as input\n" . + " -i: insert shortened URL into input bar of current buffer\n" . + " URL: URL to shorten (multiple URLs may be given)\n" . + " number: shorten up to n last found URLs in current buffer\n" . + "partial expr: shorten last found URL in current buffer which matches the given partial expression\n" . + "\nWithout any URL arguments, the last found URL in the current buffer will be shortened.\n\n" . + "Examples:\n" . + " /isgd\n" . + " /isgd http://google.de\n" . + " /isgd -o http://slashdot.org/\n" . + " /isgd 3\n" . + " /isgd youtube", + "", "command_cb", ""); + +init_config(); + +# +# Catch printed messages +# +sub print_cb +{ + my ($data, $buffer, $date, $tags, $displayed, $highlight, $prefix, $message) = @_; + my @URLs; + my $self_nick = weechat::buffer_get_string($buffer, "localvar_nick"); + + if ($OPTIONS{auto} ne "on" || $tags =~ /\bno_log\b/ || $tags =~ /\birc_332\b/ || $tags =~ /\bnick_\Q$self_nick\E\b/) { + return weechat::WEECHAT_RC_OK; + } + + # Find URLs + @URLs = grep_urls($message, $OPTIONS{auto_min_length}); + + # Process all found URLs + shorten_urls(\@URLs, $buffer, 0); + + return weechat::WEECHAT_RC_OK; +} + +# +# /isgd +# +sub command_cb +{ + my ($data, $buffer, $args) = @_; + my $send = 0; + my @URLs; + + # Check for command switch + if ($args =~ /^-o/) { + $args =~ s/^-o\s*//; + $send = 1; + } elsif ($args =~ /^-i/) { + $args =~ s/^-i\s*//; + $send = 2; + } + + # If URLs were provided in command arguments, shorten them + @URLs = grep_urls($args, 0); + + # Otherwise search backwards in lines of current buffer + if (@URLs == 0) { + # + my $count = 0; + $count = $1 if ($args =~ /^(\d+)$/); + + # + my $match = ""; + $match = $1 if ($count == 0 && $args =~ /^(\S+)$/); + $count = 1 if ($count == 0); + + # Iterate through lines of buffer backwards + my $own_lines = weechat::hdata_pointer(weechat::hdata_get("buffer"), $buffer, "own_lines"); + if ($own_lines) { + my $line = weechat::hdata_pointer(weechat::hdata_get("lines"), $own_lines, "last_line"); + my $hdata_line = weechat::hdata_get("line"); + my $hdata_line_data = weechat::hdata_get("line_data"); + while ($line) { + my $data = weechat::hdata_pointer($hdata_line, $line, "data"); + if ($data) { + my $message = weechat::hdata_string($hdata_line_data, $data, "message"); + my $tags = weechat::hdata_string($hdata_line_data, $data, "tags"); + + foreach (grep_urls($message, 0)) { + my $url = $_; + if ($match eq "" || $url =~ /\Q$match\E/i) { + push(@URLs, $url) unless ($tags =~ /\bno_log\b/); + } + } + last if (@URLs >= $count); + } + $line = weechat::hdata_move($hdata_line, $line, -1); + } + } + + } + + # Now process all found URLs + shorten_urls(\@URLs, $buffer, $send); + + return weechat::WEECHAT_RC_OK; +} + +# +# Shortens a list of URLs +# +sub shorten_urls($$$) +{ + my @URLs = @{$_[0]}; + my $buffer = $_[1]; + my $send = $_[2]; + + foreach (@URLs) { + my $url = $_; + my $cmd = "url:$SHORTENER_URL" . CGI::escape($url); + $LOOKUP{$cmd} = $url; + + if (my $url_short = $CACHE{$cmd}) { + if ($send == 1) { + weechat::command($buffer, $url_short); + } elsif ($send == 2) { + append_to_input($buffer, $url_short); + } else { + print_url($buffer, $url_short, $url); + } + } else { + my $cb; + if ($send == 1) { + $cb = "url_send_cb"; + } elsif ($send == 2) { + $cb = "url_input_cb"; + } else { + $cb = "url_cb"; + } + weechat::hook_process($cmd, $TIMEOUT, $cb, $buffer); + } + } +} + +sub url_cb +{ + my ($data, $command, $return_code, $out, $err) = @_; + my $buffer = $data; + my $url_short = $out; + + if ($return_code == 0 && $url_short) { + cache_url($command, $url_short); + print_url($buffer, $url_short, $LOOKUP{$command}); + } + + return weechat::WEECHAT_RC_OK; +} + +sub url_send_cb +{ + my ($data, $command, $return_code, $out, $err) = @_; + my $buffer = $data; + my $url_short = $out; + + if ($return_code == 0 && $url_short) { + cache_url($command, $url_short); + weechat::command($buffer, $url_short); + } + + return weechat::WEECHAT_RC_OK; +} + +sub url_input_cb +{ + my ($data, $command, $return_code, $out, $err) = @_; + my $buffer = $data; + my $url_short = $out; + + if ($return_code == 0 && $url_short) { + cache_url($command, $url_short); + append_to_input($buffer, $url_short); + } + + return weechat::WEECHAT_RC_OK; +} + +sub grep_urls($$) +{ + my $str = $_[0]; + my $url_min_length = $_[1]; + my @urls; + while ($str =~ m{(https?://.+?)(\s|"|>|$)}gi) { + my $url = $1; + push(@urls, $url) unless ($url =~ /^\Q$SHORTENER_BASE\E/ || length($url) < $url_min_length); + } + return @urls; +} + +sub print_url($$$) +{ + my ($buffer, $url_short, $cmd) = @_; + my $domain = ""; + $domain = $1 if ($cmd =~ m{^https?://([^/]+)}gi); + weechat::print_date_tags($buffer, 0, "no_log", weechat::color($OPTIONS{color}) . "$url_short ($domain)"); +} + +sub cache_url($$) +{ + my ($command, $url_short) = @_; + %CACHE = () if (keys(%CACHE) > $CACHE_MAX_SIZE); + $CACHE{$command} = $url_short; +} + +sub append_to_input($$) +{ + my ($buffer, $url) = @_; + my $input = weechat::buffer_get_string($buffer, "input"); + $input .= " " if (length($input) > 0 && $input =~ /\S$/); # if len>0 and last char is not a whitespace + $input .= $url; + weechat::buffer_set($buffer, "input", $input); +} + +# +# 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; +} diff --git a/weechat/python/autoload/shortenurl.py b/weechat/python/autoload/shortenurl.py deleted file mode 120000 index f88b9aa..0000000 --- a/weechat/python/autoload/shortenurl.py +++ /dev/null @@ -1 +0,0 @@ -../shortenurl.py \ No newline at end of file diff --git a/weechat/python/shortenurl.py b/weechat/python/shortenurl.py deleted file mode 100644 index 818ab1c..0000000 --- a/weechat/python/shortenurl.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2010, 2011, 2012, 2013 by John Anderson -# -# 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 . - -# History -# 2014-5-3, John Anderson -# version 0.5.3: Fixed short_own bug introduced in 0.5, notify the short url -# instead of appending to the message (returning to behavior -# from 0.4) -# 2013-12-25, John Anderson -# version 0.5: Added support for latest weechat (0.4+) -# 2011-10-24, Dmitry Geurkov -# version 0.4.1: added: option "ignore_list" for a blacklist of shorten urls. -# 2011-01-17, nils_2 -# version 0.4: URI will be shorten in /query, too. -# : added: option "short_own". -# 2010-11-08, John Anderson : -# version 0.3: Get python 2.x binary for hook_process (fixes problem -# when python 3.x is default python version, requires -# WeeChat >= 0.3.4) - -import re -import weechat -from urllib import urlencode -from urllib2 import urlopen - -SCRIPT_NAME = "shortenurl" -SCRIPT_AUTHOR = "John Anderson " -SCRIPT_VERSION = "0.5.3" -SCRIPT_LICENSE = "GPL3" -SCRIPT_DESC = "Shorten long incoming and outgoing URLs" - -ISGD = 'http://is.gd/api.php?%s' -TINYURL = 'http://tinyurl.com/api-create.php?%s' - -# script options -# shortener options: -# - isgd -# - tinyurl - -settings = { - "color": "red", - "urllength": "30", - "shortener": "isgd", - "short_own": "off", - "ignore_list": "http://is.gd,http://tinyurl.com", -} - -octet = r'(?:2(?:[0-4]\d|5[0-5])|1\d\d|\d{1,2})' -ipAddr = r'%s(?:\.%s){3}' % (octet, octet) -# Base domain regex off RFC 1034 and 1738 -label = r'[0-9a-z][-0-9a-z]*[0-9a-z]?' -domain = r'%s(?:\.%s)*\.[a-z][-0-9a-z]*[a-z]?' % (label, label) -urlRe = re.compile( - r'(\w+://(?:%s|%s)(?::\d+)?(?:/[^\])>\s]*)?)' % (domain, ipAddr), - re.I -) - - -if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, - SCRIPT_DESC, "", ""): - - for option, default_value in settings.iteritems(): - if weechat.config_get_plugin(option) == "": - weechat.config_set_plugin(option, default_value) - - weechat.hook_print('', 'irc_privmsg', '', 1, 'notify', '') - weechat.hook_modifier('irc_out_privmsg', 'outgoing_hook', '') - - -def notify(data, buf, date, tags, displayed, hilight, prefix, msg): - color = weechat.color(weechat.config_get_plugin('color')) - reset = weechat.color('reset') - - my_nick = weechat.buffer_get_string(buf, 'localvar_nick') - if prefix != my_nick: - urls = find_and_process_urls(msg) - - for url, short_url in urls: - weechat.prnt(buf, '%(color)s[ %(url)s ]%(reset)s' % dict( - color=color, - url=short_url, - reset=reset)) - - return weechat.WEECHAT_RC_OK - - -def outgoing_hook(data, modifier, modifier_data, msg): - short_own = weechat.config_get_plugin('short_own') - if short_own == 'off': - return msg - - urls = find_and_process_urls(msg) - for url, short_url in urls: - msg = msg.replace(url, '%(short_url)s [ %(url)s ]' % dict( - url=url, - short_url=short_url)) - - return msg - - -def find_and_process_urls(new_message): - urls = [] - - for url in urlRe.findall(new_message): - max_url_length = int(weechat.config_get_plugin('urllength')) - - if len(url) > max_url_length and not should_ignore_url(url): - short_url = get_shortened_url(url) - urls.append((url, short_url)) - - return urls - - -def get_shortened_url(url): - shortener = weechat.config_get_plugin('shortener') - if shortener == 'isgd': - url = ISGD % urlencode({'longurl': url}) - if shortener == 'tinyurl': - url = TINYURL % urlencode({'url': url}) - try: - return urlopen(url).read() - except: - return url - - -def should_ignore_url(url): - ignorelist = weechat.config_get_plugin('ignore_list').split(',') - - for ignore in ignorelist: - if len(ignore) > 0 and ignore in url: - return True - - return False