aboutsummaryrefslogtreecommitdiff
path: root/weechat/python
diff options
context:
space:
mode:
Diffstat (limited to 'weechat/python')
l---------weechat/python/autoload/screen_away.py1
l---------weechat/python/autoload/upside_down.py1
-rw-r--r--weechat/python/autoload/weeget.py980
-rw-r--r--weechat/python/screen_away.py151
-rw-r--r--weechat/python/upside_down.py130
5 files changed, 1263 insertions, 0 deletions
diff --git a/weechat/python/autoload/screen_away.py b/weechat/python/autoload/screen_away.py
new file mode 120000
index 0000000..e485b70
--- /dev/null
+++ b/weechat/python/autoload/screen_away.py
@@ -0,0 +1 @@
+../screen_away.py \ No newline at end of file
diff --git a/weechat/python/autoload/upside_down.py b/weechat/python/autoload/upside_down.py
new file mode 120000
index 0000000..fb007ad
--- /dev/null
+++ b/weechat/python/autoload/upside_down.py
@@ -0,0 +1 @@
+../upside_down.py \ No newline at end of file
diff --git a/weechat/python/autoload/weeget.py b/weechat/python/autoload/weeget.py
new file mode 100644
index 0000000..8622ef6
--- /dev/null
+++ b/weechat/python/autoload/weeget.py
@@ -0,0 +1,980 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009-2012 Sebastien Helleu <flashcode@flashtux.org>
+#
+# 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/>.
+#
+
+#
+# WeeChat scripts manager.
+# (this script requires WeeChat >= 0.3.0 and python >= 2.6)
+#
+# History:
+#
+# 2012-03-09, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.8: fix reload of config file
+# 2012-02-27, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.7: add support of scheme scripts
+# 2012-02-05, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.6: use URL transfer from API (for WeeChat >= 0.3.7)
+# 2012-01-03, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.5: make script compatible with Python 3.x
+# 2011-03-25, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.4: add completion with installed scripts for action "remove"
+# 2011-03-10, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.3: add script extension in script name completion and a new
+# completion with tags for actions "list" and "listinstalled"
+# 2011-02-13, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.2: use new help format for command arguments
+# 2010-11-08, Sebastien Helleu <flashcode@flashtux.org>:
+# version 1.1: get python 2.x binary for hook_process (fix problem
+# when python 3.x is default python version, requires
+# WeeChat >= 0.3.4)
+# 2010-02-22, Blake Winton <bwinton@latte.ca>:
+# version 1.0: add action "listinstalled" for command /weeget
+# 2010-01-25, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.9: fix "running" status of scripts with /weeget check
+# 2009-09-30, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.8: fix bugs and add missing info in "/weeget show",
+# display warning if url for plugins.xml.gz is old site
+# 2009-09-07, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.7: update weechat site with new URL
+# 2009-05-02, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.6: sync with last API changes
+# 2009-04-15, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.5: display missing module(s) when import failed
+# 2009-04-11, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.4: use new completion for command arguments
+# 2009-04-07, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.3: fix bug with install/upgrade when weeget is updated with
+# other scripts: ensure that weeget is always the last
+# installed script
+# 2009-04-07, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.2: add author's mail in script description
+# 2009-04-05, Sebastien Helleu <flashcode@flashtux.org>:
+# version 0.1: initial release
+#
+
+SCRIPT_NAME = "weeget"
+SCRIPT_AUTHOR = "Sebastien Helleu <flashcode@flashtux.org>"
+SCRIPT_VERSION = "1.8"
+SCRIPT_LICENSE = "GPL3"
+SCRIPT_DESC = "WeeChat scripts manager"
+
+SCRIPT_COMMAND = "weeget"
+
+import_ok = True
+
+try:
+ import weechat
+except ImportError:
+ print("This script must be run under WeeChat.")
+ print("Get WeeChat now at: http://www.weechat.org/")
+ import_ok = False
+
+try:
+ import sys, os, stat, time, gzip, hashlib, xml.dom.minidom
+except ImportError as message:
+ print("Missing package(s) for %s: %s" % (SCRIPT_NAME, message))
+ import_ok = False
+
+CONFIG_FILE_NAME = "wg"
+
+SCRIPT_EXTENSION = {
+ "perl" : "pl",
+ "python": "py",
+ "ruby" : "rb",
+ "lua" : "lua",
+ "tcl" : "tcl",
+ "guile" : "scm",
+}
+
+# timeout for download of plugins.xml.gz
+TIMEOUT_UPDATE = 60 * 1000
+
+# timeout for download of a script
+TIMEOUT_SCRIPT = 60 * 1000
+
+# config file and options
+wg_config_file = ""
+wg_config_option = {}
+
+# action (install, remove, ..) and arguments
+wg_action = ""
+wg_action_args = ""
+
+# loaded scripts
+wg_loaded_scripts = {}
+
+# hook process and stdout
+wg_hook_process = { "update": "", "script": "" }
+wg_stdout = { "update": "", "script": "" }
+
+# scripts read from plugins.xml.gz
+wg_scripts = {}
+
+# list of script to install, and script currently installing
+wg_scripts_to_install = []
+wg_current_script_install = {}
+
+# =================================[ config ]=================================
+
+def wg_config_init():
+ """
+ Initialization of configuration file.
+ Sections: color, scripts.
+ """
+ global wg_config_file, wg_config_option
+ wg_config_file = weechat.config_new(CONFIG_FILE_NAME,
+ "wg_config_reload_cb", "")
+ if wg_config_file == "":
+ return
+
+ # section "color"
+ section_color = weechat.config_new_section(
+ wg_config_file, "color", 0, 0, "", "", "", "", "", "", "", "", "", "")
+ if section_color == "":
+ weechat.config_free(wg_config_file)
+ return
+ wg_config_option["color_script"] = weechat.config_new_option(
+ wg_config_file, section_color,
+ "script", "color", "Color for script names", "", 0, 0,
+ "cyan", "cyan", 0, "", "", "", "", "", "")
+ wg_config_option["color_installed"] = weechat.config_new_option(
+ wg_config_file, section_color,
+ "installed", "color", "Color for \"installed\" indicator", "", 0, 0,
+ "yellow", "yellow", 0, "", "", "", "", "", "")
+ wg_config_option["color_running"] = weechat.config_new_option(
+ wg_config_file, section_color,
+ "running", "color", "Color for \"running\" indicator", "", 0, 0,
+ "lightgreen", "lightgreen", 0, "", "", "", "", "", "")
+ wg_config_option["color_obsolete"] = weechat.config_new_option(
+ wg_config_file, section_color,
+ "obsolete", "color", "Color for \"obsolete\" indicator", "", 0, 0,
+ "lightmagenta", "lightmagenta", 0, "", "", "", "", "", "")
+ wg_config_option["color_unknown"] = weechat.config_new_option(
+ wg_config_file, section_color,
+ "unknown", "color", "Color for \"unknown status\" indicator", "", 0, 0,
+ "lightred", "lightred", 0, "", "", "", "", "", "")
+ wg_config_option["color_language"] = weechat.config_new_option(
+ wg_config_file, section_color,
+ "language", "color", "Color for language names", "", 0, 0,
+ "lightblue", "lightblue", 0, "", "", "", "", "", "")
+
+ # section "scripts"
+ section_scripts = weechat.config_new_section(
+ wg_config_file, "scripts", 0, 0, "", "", "", "", "", "", "", "", "", "")
+ if section_scripts == "":
+ weechat.config_free(wg_config_file)
+ return
+ wg_config_option["scripts_url"] = weechat.config_new_option(
+ wg_config_file, section_scripts,
+ "url", "string", "URL for file with list of plugins", "", 0, 0,
+ "http://www.weechat.org/files/plugins.xml.gz",
+ "http://www.weechat.org/files/plugins.xml.gz", 0, "", "", "", "", "", "")
+ wg_config_option["scripts_dir"] = weechat.config_new_option(
+ wg_config_file, section_scripts,
+ "dir", "string", "Local cache directory for" + SCRIPT_NAME, "", 0, 0,
+ "%h/" + SCRIPT_NAME, "%h/" + SCRIPT_NAME, 0, "", "", "", "", "", "")
+ wg_config_option["scripts_cache_expire"] = weechat.config_new_option(
+ wg_config_file, section_scripts,
+ "cache_expire", "integer", "Local cache expiration time, in minutes "
+ "(-1 = never expires, 0 = always expires)", "",
+ -1, 60*24*365, "60", "60", 0, "", "", "", "", "", "")
+
+def wg_config_reload_cb(data, config_file):
+ """ Reload configuration file. """
+ return weechat.config_reload(config_file)
+
+def wg_config_read():
+ """ Read configuration file. """
+ global wg_config_file
+ return weechat.config_read(wg_config_file)
+
+def wg_config_write():
+ """ Write configuration file. """
+ global wg_config_file
+ return weechat.config_write(wg_config_file)
+
+def wg_config_color(color):
+ """ Get a color from configuration. """
+ global wg_config_option
+ option = wg_config_option.get("color_" + color, "")
+ if option == "":
+ return ""
+ return weechat.color(weechat.config_string(option))
+
+def wg_config_get_dir():
+ """ Return weeget directory, with expanded WeeChat home dir. """
+ global wg_config_option
+ return weechat.config_string(
+ wg_config_option["scripts_dir"]).replace("%h",
+ weechat.info_get("weechat_dir", ""))
+
+def wg_config_create_dir():
+ """ Create weeget directory. """
+ dir = wg_config_get_dir()
+ if not os.path.isdir(dir):
+ os.makedirs(dir, mode=0o700)
+
+def wg_config_get_cache_filename():
+ """ Get local cache filename, based on URL. """
+ global wg_config_option
+ return wg_config_get_dir() + os.sep + \
+ os.path.basename(weechat.config_string(wg_config_option["scripts_url"]))
+
+# =============================[ download file ]==============================
+
+def wg_download_file(url, filename, timeout, callback, callback_data):
+ """Download a file with an URL. Return hook_process created."""
+ version = weechat.info_get("version_number", "") or 0
+ if int(version) >= 0x00030700:
+ return weechat.hook_process_hashtable("url:%s" % url,
+ { "file_out": filename },
+ timeout,
+ callback, callback_data)
+ else:
+ script = [ "import sys",
+ "try:",
+ " if sys.version_info >= (3,):",
+ " import urllib.request",
+ " response = urllib.request.urlopen('%s')" % url,
+ " else:",
+ " import urllib2",
+ " response = urllib2.urlopen(urllib2.Request('%s'))" % url,
+ " f = open('%s', 'wb')" % filename,
+ " f.write(response.read())",
+ " response.close()",
+ " f.close()",
+ "except Exception as e:",
+ " print('error:' + str(e))" ]
+ return weechat.hook_process("python -c \"%s\"" % "\n".join(script),
+ timeout,
+ callback, callback_data)
+
+# ================================[ scripts ]=================================
+
+def wg_search_script_by_name(name):
+ """
+ Search a script in list by name.
+ Name can be short name ('weeget') or full name ('weeget.py').
+ """
+ global wg_scripts
+ for id, script in wg_scripts.items():
+ if script["name"] == name or script["full_name"] == name:
+ return script
+ return None
+
+def wg_get_loaded_scripts():
+ """
+ Get python dictionary with loaded scripts.
+ Keys are filenames and values are path to script, for example:
+ 'weeget.py': '/home/xxx/.weechat/python/weeget.py'
+ """
+ global wg_loaded_scripts
+ wg_loaded_scripts = {}
+ for language in SCRIPT_EXTENSION.keys():
+ infolist = weechat.infolist_get(language + "_script", "", "")
+ while weechat.infolist_next(infolist):
+ filename = weechat.infolist_string(infolist, "filename")
+ if filename != "":
+ wg_loaded_scripts[os.path.basename(filename)] = filename
+ weechat.infolist_free(infolist)
+
+def wg_is_local_script_loaded(filename):
+ """ Check if a script filename (like 'python/weeget.py') is loaded. """
+ global wg_loaded_scripts
+ filename2 = filename
+ if filename2.startswith("autoload/"):
+ filename2 = filename2[9:]
+ for name, path in wg_loaded_scripts.items():
+ if path.endswith(filename) or path.endswith(filename2):
+ return True
+ return False
+
+def wg_get_local_script_status(script):
+ """
+ Check if a script is installed.
+ 'script' is a dictionary retrieved from scripts xml list.
+ """
+ global wg_loaded_scripts
+ status = { "installed": "", "obsolete": "", "running": "" }
+ local_dir = weechat.info_get("weechat_dir", "") + os.sep + script["language"]
+ local_name = local_dir + os.sep + "autoload" + os.sep + script["full_name"]
+ if not os.path.isfile(local_name):
+ local_name = local_dir + os.sep + script["full_name"]
+ if os.path.isfile(local_name):
+ status["installed"] = "1"
+ f = open(local_name, "rb")
+ md5 = hashlib.md5()
+ md5.update(f.read())
+ f.close()
+ local_md5 = md5.hexdigest()
+ if local_md5 != script["md5sum"]:
+ status["obsolete"] = "1"
+ if script["full_name"] in wg_loaded_scripts.keys():
+ status["running"] = "1"
+ return status
+
+def wg_get_local_scripts():
+ """
+ Get list of all local scripts (in languages and autoload dirs).
+ Return a dictionary with language as key and list of paths as value,
+ with autoloaded scripts at beginning of list, for example:
+ { 'perl': [ 'autoload/buffers.pl',
+ 'autoload/weetris.pl',
+ 'beep.pl',
+ 'launcher.pl' ],
+ 'python': [ 'autoload/weeget.py',
+ 'go.py',
+ 'vdm.py' ]
+ }
+ """
+ files = {}
+ for language in SCRIPT_EXTENSION.keys():
+ files[language] = []
+ autoloaded_files = []
+ rootdir = weechat.info_get("weechat_dir", "") + os.sep + language
+ for root, dirs, listfiles in os.walk(rootdir):
+ if root == rootdir:
+ files[language] = listfiles
+ elif root == rootdir + os.sep + "autoload":
+ autoloaded_files = listfiles
+ for file in autoloaded_files:
+ if file in files[language]:
+ files[language].remove(file)
+ files[language].insert(0, "autoload" + os.sep + file)
+ return files
+
+def wg_get_local_scripts_status():
+ """
+ Return list of all local scripts with status (unknown/obsolete/running).
+ For example:
+ [ 'perl/weetris.pl': { 'unknown': '', 'obsolete': '1', 'running': '' },
+ 'python/weeget.py': { 'unknown': '', 'obsolete': '', 'running': '1' }
+ ]
+ """
+ local_scripts_status = []
+ local_scripts = wg_get_local_scripts()
+ if len(local_scripts) > 0:
+ for language, files in local_scripts.items():
+ for file in files:
+ script_status = { "unknown": "", "obsolete": "", "running": "" }
+ name_with_ext = os.path.basename(file)
+ script = wg_search_script_by_name(os.path.basename(file))
+ if script == None:
+ script_status["unknown"] = "1"
+ else:
+ status = wg_get_local_script_status(script)
+ if status["obsolete"]:
+ script_status["obsolete"] = "1"
+ if wg_is_local_script_loaded(file):
+ script_status["running"] = "1"
+ local_scripts_status.append((language + os.sep + file,
+ script_status))
+ return local_scripts_status
+
+def wg_search_scripts(search):
+ """ Search word in scripts, return list of matching scripts. """
+ global wg_scripts
+ if search == "":
+ return wg_scripts
+ scripts_matching = {}
+ for id, script in wg_scripts.items():
+ if script["name"].lower().find(search) >= 0 \
+ or script["language"].lower().find(search) >= 0 \
+ or script["desc_en"].lower().find(search) >= 0 \
+ or script["desc_fr"].lower().find(search) >= 0 \
+ or script["tags"].lower().find(search) >= 0:
+ scripts_matching[id] = script
+ return scripts_matching
+
+def wg_list_scripts(search, installed=False):
+ """
+ List all scripts (with optional search string).
+ If installed == True, then list only installed scripts.
+ For each script, display status (installed/running/new version available),
+ name of script, language and description.
+ For example:
+ ir buffers pl Sidebar with list of buffers.
+ i N go py Quick jump to buffers.
+ i weetris pl Tetris-like game.
+ """
+ global wg_scripts
+ search = search.strip().lower()
+ scripts_matching = wg_search_scripts(search)
+ if len(scripts_matching) == 0:
+ weechat.prnt("", "%s: no script found" % SCRIPT_NAME)
+ else:
+ weechat.prnt("", "")
+ if search != "":
+ if installed:
+ weechat.prnt("", "Scripts installed matching \"%s\":" % search)
+ else:
+ weechat.prnt("", "Scripts for WeeChat %s matching \"%s\":"
+ % (weechat.info_get("version", ""),
+ search))
+ else:
+ if installed:
+ weechat.prnt("", "Scripts installed:")
+ else:
+ weechat.prnt("", "Scripts for WeeChat %s:"
+ % weechat.info_get("version", ""))
+ sorted_scripts = sorted(scripts_matching.items(),
+ key=lambda s: s[1]["name"])
+ length_max_name = 0
+ for item in sorted_scripts:
+ length = len(item[1]["name"])
+ if length > length_max_name:
+ length_max_name = length
+ str_format = "%%s%%s%%s%%s%%s%%s%%s %%s%%-%ds %%s%%-3s %%s%%s" \
+ % length_max_name
+ for item in sorted_scripts:
+ script = item[1]
+ str_installed = " "
+ str_running = " "
+ str_obsolete = " "
+ status = wg_get_local_script_status(script)
+ if installed and not status["installed"]:
+ continue
+ if status["installed"]:
+ str_installed = "i"
+ if status["running"]:
+ str_running = "r"
+ if status["obsolete"]:
+ str_obsolete = "N"
+ weechat.prnt("", str_format
+ % (wg_config_color("installed"),
+ str_installed,
+ wg_config_color("running"),
+ str_running,
+ wg_config_color("obsolete"),
+ str_obsolete,
+ weechat.color("chat"),
+ wg_config_color("script"),
+ script["name"],
+ wg_config_color("language"),
+ SCRIPT_EXTENSION[script["language"]],
+ weechat.color("chat"),
+ script["desc_en"]))
+
+def wg_show_script(name):
+ """
+ Show detailed info about a script (in repository).
+ For example:
+ Script: weeget.py, version 0.7, license: GPL3
+ Author: Sebastien Helleu <flashcode [at] flashtux [dot] org>
+ Status: installed, running
+ Date: added: 2009-04-05, updated: 2009-09-07
+ URL: http://www.weechat.org/files/scripts/weeget.py
+ MD5: 4b0458dd5cc5c9a09ba8078f89830869
+ Desc: Scripts manager.
+ Tags: scripts
+ Requires: python 2.5
+ Min: 0.3.0
+ """
+ if len(wg_scripts) == 0:
+ return
+ script = wg_search_script_by_name(name)
+ if script == None:
+ weechat.prnt("", "%s: script \"%s%s%s\" not found"
+ % (SCRIPT_NAME,
+ wg_config_color("script"),
+ name,
+ weechat.color("chat")))
+ else:
+ weechat.prnt("", "")
+ weechat.prnt("", " Script: %s%s%s, version %s, license: %s"
+ % (wg_config_color("script"),
+ script["full_name"],
+ weechat.color("chat"),
+ script["version"],
+ script["license"]))
+ weechat.prnt("", " Author: %s <%s>" % (script["author"], script["mail"]))
+ status = wg_get_local_script_status(script)
+ str_status = "not installed"
+ if status["installed"]:
+ str_status = "installed"
+ if status["running"]:
+ str_status += ", running"
+ else:
+ str_status += ", not running"
+ if status["obsolete"]:
+ str_status += " (new version available)"
+ weechat.prnt("", " Status: %s" % str_status)
+ date_added = script.get("added", "")[:10]
+ str_updated = script.get("updated", "")
+ if str_updated != "":
+ date_updated = script["updated"][:10]
+ if date_updated == "0000-00-00" or date_updated == date_added:
+ str_updated = ""
+ if str_updated != "":
+ weechat.prnt("", " Date: added: %s, updated: %s"
+ % (date_added, date_updated))
+ else:
+ weechat.prnt("", " Date: added: %s" % date_added)
+ weechat.prnt("", " URL: %s" % script.get("url", ""))
+ weechat.prnt("", " MD5: %s" % script.get("md5sum", ""))
+ weechat.prnt("", " Desc: %s" % script.get("desc_en", ""))
+ weechat.prnt("", " Tags: %s" % script.get("tags", ""))
+ str_requires = script.get("requirements", "")
+ if str_requires == "":
+ str_requires = "(nothing)"
+ weechat.prnt("", "Requires: %s" % str_requires)
+ vmin = script.get("min_weechat", "")
+ vmax = script.get("max_weechat", "")
+ if vmin != "":
+ weechat.prnt("", " Min: %s" % vmin)
+ if vmax != "":
+ weechat.prnt("", " Max: %s" % vmax)
+
+def wg_install_next_script():
+ """
+ Install first script in list wg_scripts_to_install and remove it from
+ list.
+ """
+ global wg_scripts, wg_scripts_to_install, wg_current_script_install
+ global wg_hook_process
+ if len(wg_scripts) == 0:
+ return
+ # be sure weeget is ALWAYS last script to install/update
+ # otherwise we'll lose end of list when weeget is unloaded by WeeChat
+ if SCRIPT_NAME in wg_scripts_to_install:
+ wg_scripts_to_install.remove(SCRIPT_NAME)
+ wg_scripts_to_install.append(SCRIPT_NAME)
+ # loop until a script is installed, or end if list is empty
+ while len(wg_scripts_to_install) > 0:
+ name = wg_scripts_to_install.pop(0)
+ script = wg_search_script_by_name(name)
+ if script == None:
+ weechat.prnt("", "%s: script \"%s%s%s\" not found"
+ % (SCRIPT_NAME,
+ wg_config_color("script"),
+ name,
+ weechat.color("chat")))
+ else:
+ status = wg_get_local_script_status(script)
+ if status["installed"] and not status["obsolete"]:
+ weechat.prnt("",
+ "%s: script \"%s%s%s\" is already "
+ "installed and up to date"
+ % (SCRIPT_NAME,
+ wg_config_color("script"),
+ script["full_name"],
+ weechat.color("chat")))
+ else:
+ weechat.prnt("", "%s: downloading \"%s%s%s\"..."
+ % (SCRIPT_NAME,
+ wg_config_color("script"),
+ script["full_name"],
+ weechat.color("chat")))
+ if wg_hook_process["script"] != "":
+ weechat.unhook(wg_hook_process["script"])
+ wg_hook_process["script"] = ""
+ wg_current_script_install = script
+ filename = wg_config_get_dir() + os.sep + script["full_name"]
+ wg_hook_process["script"] = wg_download_file(script["url"], filename, TIMEOUT_SCRIPT,
+ "wg_process_script_cb", "")
+ # this function will be called again when script will be
+ # downloaded
+ return
+
+def wg_install_scripts(names):
+ """ Install scripts. """
+ global wg_scripts_to_install
+ for name in names.split(" "):
+ wg_scripts_to_install.append(name)
+ wg_install_next_script()
+
+def wg_process_script_cb(data, command, rc, stdout, stderr):
+ """ Callback when reading a script from website. """
+ global wg_hook_process, wg_stdout, wg_current_script_install, wg_loaded_scripts
+ if stdout != "":
+ wg_stdout["script"] += stdout
+ if stderr != "":
+ wg_stdout["script"] += stderr
+ if int(rc) >= 0:
+ if wg_stdout["script"].startswith("error:"):
+ weechat.prnt("", "%s%s: error downloading script (%s)"
+ % (weechat.prefix("error"), SCRIPT_NAME,
+ wg_stdout["update"][6:].strip()))
+ else:
+ # ask C plugin to install/load script
+ weechat.hook_signal_send(wg_current_script_install["language"] + "_script_install",
+ weechat.WEECHAT_HOOK_SIGNAL_STRING,
+ wg_config_get_dir() + os.sep + wg_current_script_install["full_name"])
+ wg_hook_process["script"] = ""
+ wg_install_next_script()
+ return weechat.WEECHAT_RC_OK
+
+def wg_check_scripts():
+ """
+ Check status of local script(s).
+ For each script found, display status (unknown/running/new version available).
+ For example:
+ r python/autoload/vdm.py
+ ?r python/autoload/dummy.py
+ rN python/shell.py
+ perl/buffers.pl
+ """
+ local_scripts_status = wg_get_local_scripts_status()
+ if len(local_scripts_status) == 0:
+ return
+ weechat.prnt("", "")
+ weechat.prnt("", "Local scripts:")
+ for file, status in local_scripts_status:
+ str_unknown = " "
+ str_running = " "
+ str_obsolete = " "
+ if status["unknown"]:
+ str_unknown = "?"
+ if status["running"]:
+ str_running = "r"
+ if status["obsolete"]:
+ str_obsolete = "N"
+ weechat.prnt("", "%s%s%s%s%s%s%s %s%s%s%s"
+ % (wg_config_color("unknown"), str_unknown,
+ wg_config_color("running"), str_running,
+ wg_config_color("obsolete"), str_obsolete,
+ weechat.color("chat"),
+ os.path.dirname(file),
+ os.sep,
+ wg_config_color("script"),
+ os.path.basename(file)))
+
+def wg_upgrade_scripts():
+ """ Upgrade scripts. """
+ global wg_scripts, wg_scripts_to_install
+ if len(wg_scripts) == 0:
+ return
+ scripts_to_upgrade = []
+ for id, script in wg_scripts.items():
+ status = wg_get_local_script_status(script)
+ if status["installed"] and status["obsolete"]:
+ scripts_to_upgrade.append(script["name"])
+ if len(scripts_to_upgrade) == 0:
+ weechat.prnt("", "%s: all scripts are up to date" % SCRIPT_NAME)
+ else:
+ wg_scripts_to_install.extend(scripts_to_upgrade)
+ wg_install_next_script()
+
+def wg_remove_scripts(names):
+ """ Remove scripts. """
+ if len(wg_scripts) == 0:
+ return
+ list_names = names.split(" ")
+ scripts_to_remove = {}
+ for language in SCRIPT_EXTENSION.keys():
+ scripts_to_remove[language] = []
+ for name in list_names:
+ script = wg_search_script_by_name(name)
+ if script == None:
+ weechat.prnt("", "%s: script \"%s%s%s\" not found"
+ % (SCRIPT_NAME,
+ wg_config_color("script"),
+ name,
+ weechat.color("chat")))
+ else:
+ if script["full_name"] not in scripts_to_remove[script["language"]]:
+ scripts_to_remove[script["language"]].append(script["full_name"])
+ for language in SCRIPT_EXTENSION.keys():
+ if len(scripts_to_remove[language]) > 0:
+ # ask C plugin to remove script file(s)
+ weechat.hook_signal_send(language + "_script_remove",
+ weechat.WEECHAT_HOOK_SIGNAL_STRING,
+ ",".join(scripts_to_remove[language]))
+
+# ==================================[ xml ]===================================
+
+def wg_execute_action():
+ """ Execute action. """
+ global wg_action, wg_action_args, wg_loaded_scripts
+ if wg_action != "":
+ wg_get_loaded_scripts()
+ if wg_action == "list":
+ wg_list_scripts(wg_action_args)
+ elif wg_action == "listinstalled":
+ wg_list_scripts(wg_action_args, installed=True)
+ elif wg_action == "show":
+ wg_show_script(wg_action_args)
+ elif wg_action == "install":
+ wg_install_scripts(wg_action_args)
+ elif wg_action == "check":
+ wg_check_scripts()
+ elif wg_action == "upgrade":
+ wg_upgrade_scripts()
+ elif wg_action == "remove":
+ wg_remove_scripts(wg_action_args)
+ else:
+ weechat.prnt("", "%s%s: unknown action \"%s\""
+ % (weechat.prefix("error"), SCRIPT_NAME, wg_action))
+
+ # reset action
+ wg_action = ""
+ wg_action_args = ""
+ wg_loaded_scripts = {}
+
+def wg_check_version(script):
+ """ Check if a script is designed for current running WeeChat version."""
+ version = weechat.info_get("version", "")
+ version = version.split("-", 1)[0]
+ vmin = script.get("min_weechat", "")
+ vmax = script.get("max_weechat", "")
+ if vmin != "" and version < vmin:
+ return False
+ if vmax != "" and version > vmax:
+ return False
+ return True
+
+def wg_parse_xml():
+ """
+ Parse XML scripts list and return dictionary with list, with key 'id'.
+ Example of item return in dictionary :
+ '119': { 'name' : 'weeget',
+ 'version' : '0.1',
+ 'url' : 'http://www.weechat.org/files/scripts/weeget.py',
+ 'language' : 'python',
+ 'license' : 'GPL3',
+ 'md5sum' : 'd500714fc19b0e10cc4e339e70739e4ad500714fc19b0e10cc4e339e70739e4a',
+ 'tags' : 'scripts',
+ 'desc_en' : 'Scripts manager.',
+ 'desc_fr' : 'Gestionnaire de scripts.',
+ 'requirements': 'python 2.5',
+ 'min_weechat' : '0.3.0',
+ 'max_weechat' : '',
+ 'author' : 'FlashCode',
+ 'mail' : 'flashcode [at] flashtux [dot] org',
+ 'added' : '2009-04-05 22:39:18',
+ 'updated' : '0000-00-00 00:00:00' }
+ """
+ global wg_scripts, wg_action, wg_action_args
+ wg_scripts = {}
+ try:
+ f = gzip.open(wg_config_get_cache_filename(), "rb")
+ string = f.read()
+ f.close()
+ except:
+ weechat.prnt("", "%s%s: unable to read xml file"
+ % (weechat.prefix("error"), SCRIPT_NAME))
+ else:
+ try:
+ dom = xml.dom.minidom.parseString(string)
+ except:
+ weechat.prnt("",
+ "%s%s: unable to parse xml list of scripts"
+ % (weechat.prefix("error"), SCRIPT_NAME))
+ # discard action
+ wg_action = ""
+ wg_action_args = ""
+ else:
+ for scriptNode in dom.getElementsByTagName("plugin"):
+ id = scriptNode.getAttribute("id")
+ script = {}
+ for node in scriptNode.childNodes:
+ if node.nodeType == node.ELEMENT_NODE:
+ if node.firstChild != None:
+ nodename = node.nodeName
+ value = node.firstChild.data
+ if sys.version_info < (3,):
+ # python 2.x: convert unicode to str (in python 3.x, id and text are already strings)
+ nodename = nodename.encode("utf-8")
+ value = value.encode("utf-8")
+ script[nodename] = value
+ if script["language"] in SCRIPT_EXTENSION:
+ script["full_name"] = script["name"] + "." + SCRIPT_EXTENSION[script["language"]]
+ if wg_check_version(script):
+ wg_scripts[id] = script
+ wg_execute_action()
+
+def wg_process_update_cb(data, command, rc, stdout, stderr):
+ """ Callback when reading XML cache file from website. """
+ global wg_hook_process, wg_stdout, wg_scripts
+ if stdout != "":
+ wg_stdout["update"] += stdout
+ if stderr != "":
+ wg_stdout["update"] += stderr
+ if int(rc) >= 0:
+ if wg_stdout["update"].startswith("error:"):
+ weechat.prnt("", "%s%s: error downloading scripts (%s)"
+ % (weechat.prefix("error"), SCRIPT_NAME,
+ wg_stdout["update"][6:].strip()))
+ else:
+ weechat.prnt("", "%s: scripts downloaded" % SCRIPT_NAME)
+ wg_parse_xml()
+ wg_hook_process["update"] = ""
+ return weechat.WEECHAT_RC_OK
+
+def wg_update_cache():
+ """ Download list of scripts and update local cache. """
+ global wg_config_option, wg_hook_process, wg_stdout
+ # get data from website, via hook_process
+ if wg_hook_process["update"] != "":
+ weechat.unhook(wg_hook_process["update"])
+ wg_hook_process["update"] = ""
+ weechat.prnt("", "%s: downloading list of scripts..." % SCRIPT_NAME)
+ wg_stdout["update"] = ""
+ wg_config_create_dir()
+ url = weechat.config_string(wg_config_option["scripts_url"])
+ filename = wg_config_get_cache_filename()
+ wg_hook_process["update"] = wg_download_file(url, filename, TIMEOUT_UPDATE,
+ "wg_process_update_cb", "")
+
+def wg_read_scripts(download_list=True):
+ """ Read scripts list (download list if needed and asked). """
+ global wg_scripts
+ cache_file = wg_config_get_cache_filename()
+ if os.path.isfile(cache_file):
+ # check if local cache file is too old
+ cache_expire = weechat.config_integer(wg_config_option["scripts_cache_expire"]) * 60
+ if cache_expire >= 0:
+ diff_time = time.time() - os.stat(cache_file)[stat.ST_MTIME]
+ if download_list and diff_time >= cache_expire:
+ os.unlink(cache_file)
+ wg_scripts.clear()
+ if len(wg_scripts) > 0:
+ wg_execute_action()
+ else:
+ if os.path.isfile(cache_file):
+ wg_parse_xml()
+ elif download_list:
+ wg_update_cache()
+
+# ================================[ command ]=================================
+
+def wg_cmd(data, buffer, args):
+ """ Callback for /weeget command. """
+ global wg_action, wg_action_args
+ if args == "":
+ weechat.command("", "/help %s" % SCRIPT_COMMAND)
+ return weechat.WEECHAT_RC_OK
+ argv = args.strip().split(" ", 1)
+ if len(argv) == 0:
+ return weechat.WEECHAT_RC_OK
+
+ wg_action = ""
+ wg_action_args = ""
+
+ # check arguments
+ if len(argv) < 2:
+ if argv[0] == "show" or \
+ argv[0] == "install" or \
+ argv[0] == "remove":
+ weechat.prnt("", "%s: too few arguments for action \"%s\""
+ % (SCRIPT_NAME, argv[0]))
+ return weechat.WEECHAT_RC_OK
+
+ # execute asked action
+ if argv[0] == "update":
+ wg_update_cache()
+ else:
+ wg_action = argv[0]
+ wg_action_args = ""
+ if len(argv) > 1:
+ wg_action_args = argv[1]
+ wg_read_scripts()
+
+ return weechat.WEECHAT_RC_OK
+
+def wg_completion_scripts_cb(data, completion_item, buffer, completion):
+ """ Complete with known script names, for command '/weeget'. """
+ global wg_scripts
+ wg_read_scripts(download_list=False)
+ if len(wg_scripts) > 0:
+ for id, script in wg_scripts.items():
+ weechat.hook_completion_list_add(completion, script["full_name"],
+ 0, weechat.WEECHAT_LIST_POS_SORT)
+ return weechat.WEECHAT_RC_OK
+
+def wg_completion_scripts_installed_cb(data, completion_item, buffer, completion):
+ """ Complete with names of scripts installed, for command '/weeget'. """
+ global wg_scripts
+ wg_read_scripts(download_list=False)
+ if len(wg_scripts) > 0:
+ for id, script in wg_scripts.items():
+ status = wg_get_local_script_status(script)
+ if status["installed"]:
+ weechat.hook_completion_list_add(completion, script["full_name"],
+ 0, weechat.WEECHAT_LIST_POS_SORT)
+ return weechat.WEECHAT_RC_OK
+
+def wg_completion_scripts_tags_cb(data, completion_item, buffer, completion):
+ """ Complete with known tags, for command '/weeget'. """
+ global wg_scripts
+ wg_read_scripts(download_list=False)
+ if len(wg_scripts) > 0:
+ for id, script in wg_scripts.items():
+ if script["tags"]:
+ for tag in script["tags"].split(","):
+ weechat.hook_completion_list_add(completion, tag,
+ 0, weechat.WEECHAT_LIST_POS_SORT)
+ return weechat.WEECHAT_RC_OK
+
+# ==================================[ main ]==================================
+
+if __name__ == "__main__" and import_ok:
+ if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
+ SCRIPT_DESC, "wg_unload_script", ""):
+ wg_config_init()
+ wg_config_read()
+ if weechat.config_string(wg_config_option["scripts_url"]).find("weechat.flashtux.org") >= 0:
+ weechat.prnt("", "%sWarning: old site still used in URL for plugins.xml.gz, you should do: /unset wg.scripts.url"
+ % weechat.prefix("error"))
+ str_installed = wg_config_color("installed") + "i" + weechat.color("chat")
+ str_unknown = wg_config_color("unknown") + "?" + weechat.color("chat")
+ str_running = wg_config_color("running") + "r" + weechat.color("chat")
+ str_obsolete = wg_config_color("obsolete") + "N" + weechat.color("chat")
+ weechat.hook_command(SCRIPT_COMMAND,
+ "WeeChat scripts manager",
+ "list|listinstalled [<text>|<tag>] || show <script>"
+ " || install|remove <script> [<script>...] || check|update|upgrade",
+ " list: list scripts (search text if given)\n"
+ "listinstalled: list installed scripts (search text if given)\n"
+ " show: show detailed information about a script (in repository)\n"
+ " install: install/upgrade script(s)\n"
+ " check: check if local scripts needs upgrade\n"
+ " update: update local scripts cache\n"
+ " upgrade: upgrade all local scripts if they are obsolete\n"
+ " remove: remove script(s)\n\n"
+ "Indicators in lists (first column):\n"
+ " " + str_installed + " script is installed\n"
+ " " + str_unknown + " unknown script\n"
+ " " + str_running + " script is running (loaded)\n"
+ " " + str_obsolete + " script is obsolete (new version available)\n\n"
+ "Examples:\n"
+ " /" + SCRIPT_COMMAND + " list => list all scripts\n"
+ " /" + SCRIPT_COMMAND + " list game => list all scripts with text/tag \"game\"\n"
+ " /" + SCRIPT_COMMAND + " install beep.pl => install script beep.pl\n"
+ " /" + SCRIPT_COMMAND + " remove beep.pl => remove script beep.pl",
+ "list %(weeget_scripts_tags)"
+ " || listinstalled %(weeget_scripts_tags)"
+ " || show %(weeget_scripts)"
+ " || install %(weeget_scripts)|%*"
+ " || remove %(weeget_scripts_installed)|%*"
+ " || check"
+ " || update"
+ " || upgrade",
+ "wg_cmd", "")
+ weechat.hook_completion("weeget_scripts", "list of scripts in repository",
+ "wg_completion_scripts_cb", "")
+ weechat.hook_completion("weeget_scripts_installed", "list of scripts installed",
+ "wg_completion_scripts_installed_cb", "")
+ weechat.hook_completion("weeget_scripts_tags", "tags of scripts in repository",
+ "wg_completion_scripts_tags_cb", "")
+
+# ==================================[ end ]===================================
+
+def wg_unload_script():
+ """ Function called when script is unloaded. """
+ wg_config_write()
+ return weechat.WEECHAT_RC_OK
diff --git a/weechat/python/screen_away.py b/weechat/python/screen_away.py
new file mode 100644
index 0000000..744638a
--- /dev/null
+++ b/weechat/python/screen_away.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2009 by xt <xt@bash.no>
+# Copyright (c) 2009 by penryu <penryu@gmail.com>
+# Copyright (c) 2010 by Blake Winton <bwinton@latte.ca>
+# Copyright (c) 2010 by Aron Griffis <agriffis@n01se.net>
+# Copyright (c) 2010 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/>.
+#
+
+#
+# (this script requires WeeChat 0.3.0 or newer)
+#
+# History:
+# 2010-08-07, Filip H.F. "FiXato" Slagter <fixato@gmail.com>
+# version 0.8: add command on attach feature
+# 2010-05-07, Jani Kesänen <jani.kesanen@gmail.com>
+# version 0.7: add command on detach feature
+# 2010-03-07, Aron Griffis <agriffis@n01se.net>
+# version 0.6: move socket check to register,
+# add hook_config for interval,
+# reduce default interval from 60 to 5
+# 2010-02-19, Blake Winton <bwinton@latte.ca>
+# version 0.5: add option to change nick when away
+# 2010-01-18, xt
+# version 0.4: only update servers that are connected
+# 2009-11-30, xt <xt@bash.no>
+# version 0.3: do not touch servers that are manually set away
+# 2009-11-27, xt <xt@bash.no>
+# version 0.2: code for TMUX from penryu
+# 2009-11-27, xt <xt@bash.no>
+# version 0.1: initial release
+
+import weechat as w
+import re
+import os
+
+SCRIPT_NAME = "screen_away"
+SCRIPT_AUTHOR = "xt <xt@bash.no>"
+SCRIPT_VERSION = "0.8"
+SCRIPT_LICENSE = "GPL3"
+SCRIPT_DESC = "Set away status on screen detach"
+
+settings = {
+ 'message': 'Detached from screen',
+ 'interval': '5', # How often in seconds to check screen status
+ 'away_suffix': '', # What to append to your nick when you're away.
+ 'command_on_attach': '', # Command to execute on attach
+ 'command_on_detach': '' # Command to execute on detach
+}
+
+TIMER = None
+SOCK = None
+AWAY = False
+
+def set_timer():
+ '''Update timer hook with new interval'''
+
+ global TIMER
+ if TIMER:
+ w.unhook(TIMER);
+ TIMER = w.hook_timer(int(w.config_get_plugin('interval')) * 1000,
+ 0, 0, "screen_away_timer_cb", '')
+
+def screen_away_config_cb(data, option, value):
+ if option.endswith(".interval"):
+ set_timer()
+ return w.WEECHAT_RC_OK
+
+def get_servers():
+ '''Get the servers that are not away, or were set away by this script'''
+
+ infolist = w.infolist_get('irc_server','','')
+ buffers = []
+ while w.infolist_next(infolist):
+ if not w.infolist_integer(infolist, 'is_connected') == 1:
+ continue
+ if not w.infolist_integer(infolist, 'is_away') or \
+ w.infolist_string(infolist, 'away_message') == \
+ w.config_get_plugin('message'):
+ buffers.append((w.infolist_pointer(infolist, 'buffer'),
+ w.infolist_string(infolist, 'nick')))
+ w.infolist_free(infolist)
+ return buffers
+
+def screen_away_timer_cb(buffer, args):
+ '''Check if screen is attached, update awayness'''
+
+ global AWAY, SOCK
+
+ suffix = w.config_get_plugin('away_suffix')
+ attached = os.access(SOCK, os.X_OK) # X bit indicates attached
+
+ if attached and AWAY:
+ w.prnt('', '%s: Screen attached. Clearing away status' % SCRIPT_NAME)
+ for server, nick in get_servers():
+ w.command(server, "/away")
+ if suffix and nick.endswith(suffix):
+ nick = nick[:-len(suffix)]
+ w.command(server, "/nick %s" % nick)
+ AWAY = False
+ if w.config_get_plugin("command_on_attach"):
+ w.command("", w.config_get_plugin("command_on_attach"))
+
+ elif not attached and not AWAY:
+ w.prnt('', '%s: Screen detached. Setting away status' % SCRIPT_NAME)
+ for server, nick in get_servers():
+ if suffix:
+ w.command(server, "/nick %s%s" % (nick, suffix));
+ w.command(server, "/away %s" % w.config_get_plugin('message'));
+ AWAY = True
+ if w.config_get_plugin("command_on_detach"):
+ w.command("", w.config_get_plugin("command_on_detach"))
+
+ return w.WEECHAT_RC_OK
+
+
+if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
+ SCRIPT_DESC, "", ""):
+ for option, default_value in settings.iteritems():
+ if not w.config_is_set_plugin(option):
+ w.config_set_plugin(option, default_value)
+
+ if 'STY' in os.environ.keys():
+ # We are running under screen
+ cmd_output = os.popen('env LC_ALL=C screen -ls').read()
+ match = re.search(r'Sockets? in (/.+)\.', cmd_output)
+ if match:
+ SOCK = os.path.join(match.group(1), os.environ['STY'])
+
+ if not SOCK and 'TMUX' in os.environ.keys():
+ # We are running under tmux
+ socket_data = os.environ['TMUX']
+ SOCK = socket_data.rsplit(',',2)[0]
+
+ if SOCK:
+ set_timer()
+ w.hook_config("plugins.var.python." + SCRIPT_NAME + ".*",
+ "screen_away_config_cb", "")
diff --git a/weechat/python/upside_down.py b/weechat/python/upside_down.py
new file mode 100644
index 0000000..e07a7bf
--- /dev/null
+++ b/weechat/python/upside_down.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2009 by xt <xt@bash.no>
+#
+# 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/>.
+#
+#
+#
+# USAGE: Bind a key to command /flip . Then write some text at input line
+# press your key to transform it to upside down.
+
+#
+# (this script requires WeeChat 0.3.0 or newer)
+#
+# History:
+# 2010-01-14, xt
+# version 0.3: steal more chars from m4v
+# 2010-01-06, xt <xt@bash.no>
+# version 0.2: fix idiotic programming
+# 2009-11-12, xt <xt@bash.no>
+# version 0.1: initial release
+
+import weechat as w
+import re
+
+SCRIPT_NAME = "upside_down"
+SCRIPT_AUTHOR = "xt <xt@bash.no>"
+SCRIPT_VERSION = "0.3"
+SCRIPT_LICENSE = "GPL3"
+SCRIPT_DESC = "Replaces text you write with upside down text"
+
+settings = {}
+
+replacements = {
+# Upper case
+ u'A' : u'\N{FOR ALL}',
+ u'B' : u'\N{GREEK SMALL LETTER XI}',
+ u'C' : u'\N{ROMAN NUMERAL REVERSED ONE HUNDRED}',
+ u'D' : u'\N{LEFT HALF BLACK CIRCLE}',
+ u'E' : u'\N{LATIN CAPITAL LETTER REVERSED E}',
+ u'F' : u'\N{TURNED CAPITAL F}',
+ u'G' : u'\N{TURNED SANS-SERIF CAPITAL G}',
+ u'J' : u'\N{LATIN SMALL LETTER LONG S}',
+ u'K' : u'\N{RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT}',
+ u'L' : u'\ua780',
+ u'M' : u'W',
+ u'N' : u'\N{LATIN LETTER SMALL CAPITAL REVERSED N}',
+ u'P' : u'\N{CYRILLIC CAPITAL LETTER KOMI DE}',
+ u'Q' : u'\N{GREEK CAPITAL LETTER OMICRON WITH TONOS}',
+ u'R' : u'\N{LATIN LETTER SMALL CAPITAL TURNED R}',
+ u'T' : u'\N{UP TACK}',
+ u'U' : u'\N{INTERSECTION}',
+ u'V' : u'\u0245',
+ u'Y' : u'\N{TURNED SANS-SERIF CAPITAL Y}',
+ 'a' : u"\u0250",
+ 'b' : u'q',
+ 'c' : u"\u0254",
+ 'd' : u'p',
+ 'e' : u"\u01DD",
+ 'f' : u"\u025F",
+ 'g' : u"\u0183",
+ 'h' : u'\u0265',
+ 'i' : u'\u0131',
+ 'j' : u'\u027E',
+ 'k' : u'\u029E',
+ 'm' : u'\u026F',
+ 'n' : u'u',
+ 'r' : u'\u0279',
+ 't' : u'\u0287',
+ 'p' : u'd',
+ 'u' : u'n',
+ 'q' : u'b',
+ 'v' : u'\u028C',
+ 'w' : u'\u028D',
+ 'y' : u'\u028E',
+ '.' : u'\u02D9',
+ '[' : u']',
+ '(' : u')',
+ '{' : u'}',
+ '?' : u'\u00BF',
+ '!' : u'\u00A1',
+ "\'" :u',',
+ '>' : u'<',
+ '<' : u'>',
+ '_' : u'\u203E',
+ ';' : u'\u061B',
+ '\u203F' : u'\u2040',
+ '\u2045' : u'\u2046',
+ '\u2234' : u'\u2235',
+}
+
+
+
+if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
+ SCRIPT_DESC, "", ""):
+ for option, default_value in settings.iteritems():
+ if not w.config_is_set_plugin(option):
+ w.config_set_plugin(option, default_value)
+ w.hook_command("flip",
+ SCRIPT_DESC,
+ "[text]",
+ "text: text to be flipped\n"
+ "",
+ "", "flip_cmd_cb", "")
+
+
+def flip_cmd_cb(data, buffer, args):
+ ''' Command /flip '''
+ translate_input = args
+ if not translate_input:
+ translate_input = w.buffer_get_string(w.current_buffer(), "input")
+ outstring = ''
+ for char in translate_input:
+ if char in replacements:
+ char = replacements[char]
+ outstring += char
+ outstring = outstring.encode('UTF-8')
+ w.buffer_set(w.current_buffer(), 'input', outstring)
+ return w.WEECHAT_RC_OK