diff options
Diffstat (limited to 'weechat/python/autoload/weeget.py')
| -rw-r--r-- | weechat/python/autoload/weeget.py | 980 |
1 files changed, 0 insertions, 980 deletions
diff --git a/weechat/python/autoload/weeget.py b/weechat/python/autoload/weeget.py deleted file mode 100644 index 8622ef6..0000000 --- a/weechat/python/autoload/weeget.py +++ /dev/null @@ -1,980 +0,0 @@ -# -*- 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 |