Script: urlbuf.py

A common buffer for URLs.
Author: Jani Kesänen — Version: 0.4 — License: GPL-3.0-or-later
For WeeChat ≥ 0.3.0.
Tags: url, py2, py3
Added: 2011-08-28 — Updated: 2019-07-07

Download GitHub Repository

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# -*- coding: utf-8 -*-
# Copyright (c) 2011-2014 by Jani Kesänen <jani.kesanen@gmail.com>
#
# 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/>.
#

#
# A common buffer for URLs
#
# Collects received URLs from public and private messages into a single
# buffer. This buffer is especially handy if you spend lot's of time afk
# and you don't want to miss any of the cat pictures/videos that were pasted
# while you were doing something meaningful.
#
# This script has been originally developed for WeeChat version 0.3.5. May
# not work properly (or at all) on older versions.
#
# History:
# 2019-07-07, nils_2@freenode.#weechat
#   version 0.4: - fix bug when script unloads.
#                - add search for buffer name and display buffer name
# 2019-07-07, nils_2@freenode.#weechat
#   version 0.3: - make script compatible with Python 3.
# 2014-09-17, Jani Kesänen <jani.kesanen@gmail.com>
#   version 0.2: - added descriptions to settings.
# 2011-06-07, Jani Kesänen <jani.kesanen@gmail.com>
#   version 0.1: - initial release.
#

from __future__ import print_function

SCRIPT_NAME    = "urlbuf"
SCRIPT_AUTHOR  = "Jani Kesänen <jani.kesanen@gmail.com>"
SCRIPT_VERSION = "0.4"
SCRIPT_LICENSE = "GPL3"
SCRIPT_DESC    = "A common buffer for received URLs."

import_ok = True

try:
    import weechat
except ImportError:
    print("This script must be run under WeeChat.")
    import_ok = False

import re

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)

urlbuf_buffer = None

urlbuf_settings = {
    "display_active_buffer" : ("on",  "display URLs from the active buffer"),
    "display_private"       : ("on",  "display URLs from private messages"),
    "display_buffer_number" : ("on",  "display the buffer's number or name (on/name/off)"),
    "display_nick"          : ("off", "display the nick of the user"),
    "skip_duplicates"       : ("on",  "skip the URL that is already in the urlbuf"),
    "skip_buffers"          : ("",    "a comma separated list of buffer numbers or buffer names to skip"),
}


def is_url_listed(buffer, url):
    """ Search for the URL from the buffer lines. """
    infolist = weechat.infolist_get("buffer_lines", buffer, "")

    found = False
    while weechat.infolist_next(infolist):
        message = weechat.infolist_string(infolist, "message").split(' ')[-1]
        if message == url:
            found = True
            break

    weechat.infolist_free(infolist)

    return found


def urlbuf_print_cb(data, buffer, date, tags, displayed, highlight, prefix, message):
    """ Called when a message is printed. """
    global urlbuf_buffer, urlbuf_tags

    # Exit immediately if the buffer does not exist
    if not urlbuf_buffer:
        return weechat.WEECHAT_RC_OK

    # Exit if the wanted tag is not in the message
    tagslist = tags.split(",")
    if not "notify_message" in tagslist:
        if weechat.config_get_plugin("display_private") == "on":
           if not "notify_private" in tagslist:
               return weechat.WEECHAT_RC_OK
        else:
           return weechat.WEECHAT_RC_OK

    # Exit if the message came from a buffer that is on the skip list
    buffer_number = str(weechat.buffer_get_integer(buffer, "number"))
    buffer_name = str(weechat.buffer_get_string(buffer, "name"))
    skips = set(weechat.config_get_plugin("skip_buffers").split(","))
    if buffer_number in skips:
        return weechat.WEECHAT_RC_OK
    if buffer_name in skips:
        return weechat.WEECHAT_RC_OK

    if weechat.config_get_plugin("display_active_buffer") == "off":
        if buffer_number == weechat.buffer_get_integer(weechat.current_buffer(), "number"):
            return weechat.WEECHAT_RC_OK

    # Process all URLs from the message
    for url in urlRe.findall(message):
        output = ""

        if weechat.config_get_plugin("skip_duplicates") == "on":
            if is_url_listed(urlbuf_buffer, url):
                continue

        if weechat.config_get_plugin("display_buffer_number") == "on":
            output += "%s%-2d " % (weechat.color("reset"), weechat.buffer_get_integer(buffer, "number"))
        elif weechat.config_get_plugin("display_buffer_number") == "name":
            output += "%s%s  " % (weechat.color("reset"), weechat.buffer_get_string(buffer, "name"))

        if weechat.config_get_plugin("display_nick") == "on":
            output += "%s " % (prefix)

        # Output the formatted URL into the buffer
        weechat.prnt(urlbuf_buffer, output + url)

    return weechat.WEECHAT_RC_OK


def urlbuf_input_cb(data, buffer, input_data):
    """ A Dummy callback for buffer input. """
    return weechat.WEECHAT_RC_OK


def urlbuf_close_cb(data, buffer):
    """ A callback for buffer closing. """
    global urlbuf_buffer

    urlbuf_buffer = None
    return weechat.WEECHAT_RC_OK

def urlbuf2_close_cb():
    global urlbuf_buffer
    urlbuf_buffer = None
    return weechat.WEECHAT_RC_OK

if __name__ == "__main__" and import_ok:
    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
                        SCRIPT_LICENSE, SCRIPT_DESC, "urlbuf2_close_cb", ""):
        version = weechat.info_get('version_number', '') or 0

        # Set default settings
        for option, default_value in urlbuf_settings.items():
            if not weechat.config_is_set_plugin(option):
                weechat.config_set_plugin(option, default_value[0])
            if int(version) >= 0x00030500:
                weechat.config_set_desc_plugin(option, default_value[1])

        urlbuf_buffer = weechat.buffer_search("python", "urlbuf")

        if not urlbuf_buffer:
            # Create urlbuf. Sets notify to 0 as this buffer does not need to
            # be in hotlist.
            urlbuf_buffer = weechat.buffer_new("urlbuf", "urlbuf_input_cb", \
                                               "", "urlbuf_close_cb", "")
            weechat.buffer_set(urlbuf_buffer, "title", "URL buffer")
            weechat.buffer_set(urlbuf_buffer, "notify", "0")
            weechat.buffer_set(urlbuf_buffer, "nicklist", "0")

        # Hook all public and private messages (some may think this is too limiting)
        weechat.hook_print("", "notify_message", "", 1, "urlbuf_print_cb", "")
        weechat.hook_print("", "notify_private", "", 1, "urlbuf_print_cb", "")