1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-25 12:26:40 +02:00

core: add new plugin "script" (scripts manager, replacing scripts weeget.py and script.pl)

This commit is contained in:
Sebastien Helleu
2012-08-14 18:29:32 +02:00
parent 3a245686ca
commit a99d136018
84 changed files with 10881 additions and 1208 deletions
+43
View File
@@ -0,0 +1,43 @@
#
# Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
#
# This file is part of WeeChat, the extensible chat client.
#
# WeeChat 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.
#
# WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
#
ADD_LIBRARY(script MODULE
script.c script.h
script-action.c script-action.h
script-buffer.c script-buffer.h
script-command.c script-command.h
script-completion.c script-completion.h
script-config.c script-config.h
script-info.c script-info.h
script-repo.c script-repo.h)
SET_TARGET_PROPERTIES(script PROPERTIES PREFIX "")
SET (LINK_LIBS)
IF(ZLIB_FOUND)
LIST(APPEND LINK_LIBS ${ZLIB_LIBRARY})
ENDIF(ZLIB_FOUND)
IF(GCRYPT_FOUND)
LIST(APPEND LINK_LIBS gcrypt)
ENDIF(GCRYPT_FOUND)
TARGET_LINK_LIBRARIES(script ${LINK_LIBS})
INSTALL(TARGETS script LIBRARY DESTINATION ${LIBDIR}/plugins)
+46
View File
@@ -0,0 +1,46 @@
#
# Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
#
# This file is part of WeeChat, the extensible chat client.
#
# WeeChat 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.
#
# WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
#
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(ZLIB_CFLAGS) $(GCRYPT_CFLAGS)
libdir = ${weechat_libdir}/plugins
lib_LTLIBRARIES = script.la
script_la_SOURCES = script.c \
script.h \
script-action.c \
script-action.h \
script-buffer.c \
script-buffer.h \
script-command.c \
script-command.h \
script-completion.c \
script-completion.h \
script-config.c \
script-config.h \
script-info.c \
script-info.h \
script-repo.c \
script-repo.h
script_la_LDFLAGS = -module
script_la_LIBADD = $(SCRIPT_LFLAGS) $(ZLIB_LFLAGS) $(GCRYPT_LFLAGS)
EXTRA_DIST = CMakeLists.txt
+710
View File
@@ -0,0 +1,710 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* script-action.c: actions on scripts (load/unload, install/remove, hold, ...)
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <libgen.h>
#include "../weechat-plugin.h"
#include "script.h"
#include "script-action.h"
#include "script-buffer.h"
#include "script-config.h"
#include "script-repo.h"
char *script_actions = NULL;
void script_action_install ();
/*
* script_action_list: list loaded scripts (all languages)
*/
void
script_action_list ()
{
int i, scripts_loaded;
char hdata_name[128];
const char *ptr_name;
struct t_hdata *hdata;
void *ptr_script;
weechat_printf (NULL, "");
weechat_printf (NULL, _("Scripts loaded:"));
scripts_loaded = 0;
for (i = 0; script_language[i]; i++)
{
snprintf (hdata_name, sizeof (hdata_name),
"%s_script", script_language[i]);
hdata = weechat_hdata_get (hdata_name);
ptr_script = weechat_hdata_get_list (hdata, "scripts");
while (ptr_script)
{
ptr_name = weechat_hdata_string (hdata, ptr_script, "name");
weechat_printf (NULL, " %s %s%s%s.%s %s%s %s(%s%s%s)",
script_repo_get_status_for_display (script_repo_search_by_name (ptr_name),
"*?HN", 0),
weechat_color (weechat_config_string (script_config_color_text_name)),
ptr_name,
weechat_color (weechat_config_string (script_config_color_text_extension)),
script_extension[i],
weechat_color (weechat_config_string (script_config_color_text_version)),
weechat_hdata_string (hdata, ptr_script, "version"),
weechat_color ("chat_delimiters"),
weechat_color (weechat_config_string (script_config_color_text_description)),
weechat_hdata_string (hdata, ptr_script, "description"),
weechat_color ("chat_delimiters"));
scripts_loaded++;
ptr_script = weechat_hdata_move (hdata, ptr_script, 1);
}
}
if (scripts_loaded == 0)
{
weechat_printf (NULL, _(" (none)"));
}
}
/*
* script_action_load: load a script
*/
void
script_action_load (const char *name)
{
char *pos, str_command[1024];
int language;
language = -1;
pos = strrchr (name, '.');
if (pos)
language = script_language_search_by_extension (pos + 1);
if (language < 0)
{
weechat_printf (NULL,
_("%s: unknown language for script \"%s\""),
SCRIPT_PLUGIN_NAME, name);
return;
}
/* execute command (for example: "/perl load iset.pl") */
snprintf (str_command, sizeof (str_command),
"/%s load %s",
script_language[language],
name);
weechat_command (NULL, str_command);
}
/*
* script_action_unload: unload a script
*/
void
script_action_unload (const char *name)
{
char *pos, hdata_name[128], *filename, *ptr_base_name, str_command[1024];
const char *ptr_filename, *ptr_registered_name;
int language, found, i;
struct t_hdata *hdata;
void *ptr_script;
language = -1;
pos = strrchr (name, '.');
if (pos)
{
/* unload script by using name + extension (example: "iset.pl") */
language = script_language_search_by_extension (pos + 1);
if (language < 0)
{
weechat_printf (NULL,
_("%s: unknown language for script \"%s\""),
SCRIPT_PLUGIN_NAME, name);
return;
}
/*
* search registered name of script using name with extension,
* for example with "iset.pl" we should find "iset"
*/
snprintf (hdata_name, sizeof (hdata_name),
"%s_script", script_language[language]);
hdata = weechat_hdata_get (hdata_name);
ptr_script = weechat_hdata_get_list (hdata, "scripts");
while (ptr_script)
{
found = 0;
ptr_filename = weechat_hdata_string (hdata, ptr_script, "filename");
if (ptr_filename)
{
filename = strdup (ptr_filename);
if (filename)
{
ptr_base_name = basename (filename);
if (strcmp (ptr_base_name, name) == 0)
found = 1;
free (filename);
}
}
if (found)
{
ptr_registered_name = weechat_hdata_string (hdata, ptr_script,
"name");
if (ptr_registered_name)
{
snprintf (str_command, sizeof (str_command),
"/%s unload %s",
script_language[language],
ptr_registered_name);
weechat_command (NULL, str_command);
}
return;
}
ptr_script = weechat_hdata_move (hdata, ptr_script, 1);
}
}
else
{
/* unload script by using name (example: "iset") */
for (i = 0; script_language[i]; i++)
{
snprintf (hdata_name, sizeof (hdata_name),
"%s_script", script_language[i]);
hdata = weechat_hdata_get (hdata_name);
ptr_script = weechat_hdata_get_list (hdata, "scripts");
while (ptr_script)
{
ptr_registered_name = weechat_hdata_string (hdata, ptr_script,
"name");
if (strcmp (ptr_registered_name, name) == 0)
{
snprintf (str_command, sizeof (str_command),
"/%s unload %s",
script_language[i],
name);
weechat_command (NULL, str_command);
return;
}
ptr_script = weechat_hdata_move (hdata, ptr_script, 1);
}
}
}
}
/*
* script_action_installnext_timer_cb: callback called to install next script
*/
int
script_action_installnext_timer_cb (void *data, int remaining_calls)
{
/* make C compiler happy */
(void) data;
(void) remaining_calls;
script_action_install ();
return WEECHAT_RC_OK;
}
/*
* script_action_install_process_cb: callback called when script is downloaded
*/
int
script_action_install_process_cb (void *data, const char *command,
int return_code, const char *out,
const char *err)
{
char *pos, *filename, str_signal[256];
struct t_repo_script *ptr_script;
/* make C compiler happy */
(void) data;
if (return_code >= 0)
{
pos = strrchr (command, '/');
if ((err && err[0]) || (out && (strncmp (out, "error:", 6) == 0)))
{
weechat_printf (NULL,
_("%s%s: error downloading script \"%s\": %s"),
weechat_prefix ("error"),
SCRIPT_PLUGIN_NAME,
(pos) ? pos + 1 : "?",
(err && err[0]) ? err : out + 6);
return WEECHAT_RC_OK;
}
if (pos)
{
ptr_script = script_repo_search_by_name_ext (pos + 1);
if (ptr_script)
{
filename = script_config_get_script_download_filename (ptr_script);
if (filename)
{
snprintf (str_signal, sizeof (str_signal),
"%s_script_install",
script_language[ptr_script->language]);
weechat_hook_signal_send (str_signal,
WEECHAT_HOOK_SIGNAL_STRING,
filename);
free (filename);
}
/* schedule install of next script */
weechat_hook_timer (10, 0, 1,
&script_action_installnext_timer_cb, NULL);
}
}
}
return WEECHAT_RC_OK;
}
/*
* script_action_install: install script(s) marked for install
*/
void
script_action_install ()
{
struct t_repo_script *ptr_script, *ptr_script_to_install;
char *filename, *url;
int length;
struct t_hashtable *options;
ptr_script_to_install = NULL;
for (ptr_script = repo_scripts; ptr_script;
ptr_script = ptr_script->next_script)
{
if (ptr_script->install_order > 0)
{
if (ptr_script->install_order == 1)
ptr_script_to_install = ptr_script;
ptr_script->install_order--;
}
}
if (ptr_script_to_install)
{
filename = script_config_get_script_download_filename (ptr_script_to_install);
if (filename)
{
options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options)
{
length = 4 + strlen (ptr_script_to_install->url) + 1;
url = malloc (length);
if (url)
{
weechat_printf (NULL,
_("%s: downloading script \"%s\"..."),
SCRIPT_PLUGIN_NAME,
ptr_script_to_install->name_with_extension);
snprintf (url, length, "url:%s",
ptr_script_to_install->url);
weechat_hashtable_set (options, "file_out", filename);
weechat_hook_process_hashtable (url, options, 30000,
&script_action_install_process_cb,
NULL);
free (url);
}
weechat_hashtable_free (options);
}
free (filename);
}
}
}
/*
* script_action_remove: remove a script
*/
void
script_action_remove (const char *name)
{
struct t_repo_script *ptr_script;
char str_signal[256];
ptr_script = script_repo_search_by_name_ext (name);
if (ptr_script)
{
if (!(ptr_script->status & SCRIPT_STATUS_INSTALLED))
{
weechat_printf (NULL,
_("%s: script \"%s\" is not installed"),
SCRIPT_PLUGIN_NAME, name);
}
else if (ptr_script->status & SCRIPT_STATUS_HELD)
{
weechat_printf (NULL,
_("%s: script \"%s\" is held"),
SCRIPT_PLUGIN_NAME, name);
}
else
{
snprintf (str_signal, sizeof (str_signal),
"%s_script_remove",
script_language[ptr_script->language]);
weechat_hook_signal_send (str_signal,
WEECHAT_HOOK_SIGNAL_STRING,
ptr_script->name_with_extension);
}
}
else
{
weechat_printf (NULL,
_("%s: script \"%s\" not found"),
SCRIPT_PLUGIN_NAME, name);
}
}
/*
* script_action_hold: (un)hold a script
* return 1 if ok, 0 if error
*/
int
script_action_hold (const char *name, int quiet)
{
struct t_repo_script *ptr_script;
ptr_script = script_repo_search_by_name_ext (name);
if (ptr_script)
{
if (ptr_script->status & SCRIPT_STATUS_HELD)
{
script_config_unhold (ptr_script->name_with_extension);
if (!quiet)
{
weechat_printf (NULL,
_("%s: script \"%s\" not "
"held any more"),
SCRIPT_PLUGIN_NAME, name);
}
}
else
{
script_config_hold (ptr_script->name_with_extension);
if (!quiet)
{
weechat_printf (NULL,
_("%s: script \"%s\" held"),
SCRIPT_PLUGIN_NAME, name);
}
}
script_repo_update_status (ptr_script);
return 1;
}
else
{
if (!quiet)
{
weechat_printf (NULL,
_("%s: script \"%s\" not found"),
SCRIPT_PLUGIN_NAME, name);
}
}
return 0;
}
/*
* script_action_show: show detailed info on a script
*/
void
script_action_show (const char *name, int quiet)
{
struct t_repo_script *ptr_script;
if (name)
{
ptr_script = script_repo_search_by_name_ext (name);
if (ptr_script)
{
script_buffer_show_detail_script (ptr_script);
}
else
{
if (!quiet)
{
weechat_printf (NULL,
_("%s: script \"%s\" not found"),
SCRIPT_PLUGIN_NAME, name);
}
}
}
else
script_buffer_show_detail_script (NULL);
}
/*
* script_action_run: run planned actions
* return 1 if an action was executed, otherwise 0
*/
int
script_action_run ()
{
char **actions, **argv, **argv_eol, *ptr_action;
int num_actions, argc, i, j, quiet, script_found;
struct t_repo_script *ptr_script;
if (!script_actions)
return 0;
actions = weechat_string_split (script_actions, "\n", 0, 0, &num_actions);
if (actions)
{
for (i = 0; i < num_actions; i++)
{
quiet = 0;
ptr_action = actions[i];
if (ptr_action[0] == '-')
{
/*
* if action starts with options (like "-q"),
* read and skip them
*/
ptr_action++;
while (ptr_action[0] && (ptr_action[0] != ' '))
{
switch (ptr_action[0])
{
case 'q': /* quiet */
quiet = 1;
break;
}
ptr_action++;
}
while (ptr_action[0] == ' ')
{
ptr_action++;
}
}
argv = weechat_string_split (ptr_action, " ", 0, 0, &argc);
argv_eol = weechat_string_split (ptr_action, " ", 1, 0, &argc);
if (argv && argv_eol)
{
if (weechat_strcasecmp (argv[0], "buffer") == 0)
{
/* open buffer with list of scripts */
if (!script_buffer)
{
script_buffer_open ();
script_buffer_refresh (1);
}
weechat_buffer_set (script_buffer, "display", "1");
}
else if (weechat_strcasecmp (argv[0], "list") == 0)
{
script_action_list ();
}
else if (weechat_strcasecmp (argv[0], "load") == 0)
{
for (j = 1; j < argc; j++)
{
script_action_load (argv[j]);
}
}
else if (weechat_strcasecmp (argv[0], "unload") == 0)
{
for (j = 1; j < argc; j++)
{
script_action_unload (argv[j]);
}
}
else if (weechat_strcasecmp (argv[0], "install") == 0)
{
script_found = 0;
for (j = 1; j < argc; j++)
{
ptr_script = script_repo_search_by_name_ext (argv[j]);
if (ptr_script)
{
if (ptr_script->status & SCRIPT_STATUS_HELD)
{
weechat_printf (NULL,
_("%s: script \"%s\" is held"),
SCRIPT_PLUGIN_NAME, argv[j]);
}
else if ((ptr_script->status & SCRIPT_STATUS_INSTALLED)
&& !(ptr_script->status & SCRIPT_STATUS_NEW_VERSION))
{
weechat_printf (NULL,
_("%s: script \"%s\" is already "
"installed and up-to-date"),
SCRIPT_PLUGIN_NAME, argv[j]);
}
else
{
script_found++;
ptr_script->install_order = script_found;
}
}
else
{
weechat_printf (NULL,
_("%s: script \"%s\" not found"),
SCRIPT_PLUGIN_NAME, argv[j]);
}
}
if (script_found)
script_action_install ();
}
else if (weechat_strcasecmp (argv[0], "remove") == 0)
{
for (j = 1; j < argc; j++)
{
script_action_remove (argv[j]);
}
}
else if (weechat_strcasecmp (argv[0], "hold") == 0)
{
script_found = 0;
for (j = 1; j < argc; j++)
{
if (script_action_hold (argv[j], quiet))
script_found = 1;
}
if (script_found)
script_buffer_refresh (0);
}
else if (weechat_strcasecmp (argv[0], "show") == 0)
{
if (!script_buffer)
script_buffer_open ();
script_action_show ((argc >= 2) ? argv[1] : NULL,
quiet);
weechat_buffer_set (script_buffer, "display", "1");
}
else if (weechat_strcasecmp (argv[0], "upgrade") == 0)
{
script_found = 0;
for (ptr_script = repo_scripts; ptr_script;
ptr_script = ptr_script->next_script)
{
/*
* if script is intalled, with new version available,
* and not held, then upgrade it
*/
if ((ptr_script->status & SCRIPT_STATUS_INSTALLED)
&& (ptr_script->status & SCRIPT_STATUS_NEW_VERSION)
&& !(ptr_script->status & SCRIPT_STATUS_HELD))
{
script_found++;
ptr_script->install_order = script_found;
}
}
if (script_found)
script_action_install ();
else
{
weechat_printf (NULL,
_("%s: all scripts are up-to-date"),
SCRIPT_PLUGIN_NAME);
}
}
}
if (argv)
weechat_string_free_split (argv);
if (argv_eol)
weechat_string_free_split (argv_eol);
}
weechat_string_free_split (actions);
}
free (script_actions);
script_actions = NULL;
return 1;
}
/*
* script_action_add: add an action to list of actions
*/
void
script_action_add (const char *action)
{
char *new_actions;
if (!action)
return;
if (script_actions)
{
new_actions = realloc (script_actions,
strlen (script_actions) + 1 + strlen (action) + 1);
if (!new_actions)
return;
script_actions = new_actions;
strcat (script_actions, "\n");
strcat (script_actions, action);
}
else
{
script_actions = strdup (action);
}
}
/*
* script_action_schedule: schedule action
* if "need_repository" is 1, then the action will be
* executed only when the repository file is up-to-date
*/
void
script_action_schedule (const char *action, int need_repository, int quiet)
{
script_action_add (action);
if (need_repository)
{
if (script_repo_file_is_uptodate ())
{
if (!repo_scripts)
script_repo_file_read (quiet);
script_action_run ();
}
else
script_repo_file_update (quiet);
}
else
script_action_run ();
}
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_ACTION_H
#define __WEECHAT_SCRIPT_ACTION_H 1
extern char *script_actions;
extern int script_action_run ();
extern void script_action_schedule (const char *action, int need_repository,
int quiet);
#endif /* __WEECHAT_SCRIPT_ACTION_H */
+797
View File
@@ -0,0 +1,797 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* script-buffer.c: display scripts on script buffer
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "../weechat-plugin.h"
#include "script.h"
#include "script-buffer.h"
#include "script-config.h"
#include "script-repo.h"
struct t_gui_buffer *script_buffer = NULL;
int script_buffer_selected_line = 0;
struct t_repo_script *script_buffer_detail_script = NULL;
/*
* script_buffer_display_line_script: display a line with script
*/
void
script_buffer_display_line_script (int line, struct t_repo_script *script)
{
char str_line[16384], str_item[1024], str_color_name[256], str_color[32];
char str_format[256], str_date[64], str_key[2], utf_char[16], *tags;
const char *columns, *ptr_col;
int char_size, *ptr_max_length, max_length, num_spaces, unknown;
struct tm *tm;
snprintf (str_color_name, sizeof (str_color_name),
"%s,%s",
(line == script_buffer_selected_line) ?
weechat_config_string (script_config_color_text_selected) :
weechat_config_string (script_config_color_text),
(line == script_buffer_selected_line) ?
weechat_config_string (script_config_color_text_bg_selected) :
weechat_config_string (script_config_color_text_bg));
snprintf (str_color, sizeof (str_color),
"%s", weechat_color (str_color_name));
columns = weechat_config_string (script_config_look_columns);
ptr_col = columns;
str_line[0] = '\0';
while (ptr_col[0])
{
unknown = 0;
str_item[0] = '\0';
num_spaces = 0;
char_size = weechat_utf8_char_size (ptr_col);
memcpy (utf_char, ptr_col, char_size);
utf_char[char_size] = '\0';
if (utf_char[0] == '%')
{
ptr_col += char_size;
char_size = weechat_utf8_char_size (ptr_col);
memcpy (utf_char, ptr_col, char_size);
utf_char[char_size] = '\0';
str_key[0] = ptr_col[0];
str_key[1] = '\0';
ptr_max_length = weechat_hashtable_get (script_repo_max_length_field,
str_key);
max_length = (ptr_max_length) ? *ptr_max_length : 0;
num_spaces = max_length;
switch (utf_char[0])
{
case 'a': /* author */
if (script->author)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->author);
snprintf (str_item, sizeof (str_item),
"%s", script->author);
}
break;
case 'd': /* description */
if (script->description)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->description);
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color ((line == script_buffer_selected_line) ? "white" : "249"),
script->description);
}
break;
case 'D': /* date added */
if (script->date_added > 0)
{
tm = localtime (&script->date_added);
strftime (str_date, sizeof (str_date),
"%Y-%m-%d", tm);
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_date_selected :
script_config_color_text_date)),
str_date);
}
else
num_spaces = 10;
break;
case 'e': /* file extension */
if (script->language >= 0)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script_extension[script->language]);
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_extension_selected :
script_config_color_text_extension)),
script_extension[script->language]);
}
break;
case 'l': /* language */
if (script->language >= 0)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script_language[script->language]);
snprintf (str_item, sizeof (str_item),
"%s", script_language[script->language]);
}
break;
case 'L': /* license */
if (script->license)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->license);
snprintf (str_item, sizeof (str_item),
"%s", script->license);
}
break;
case 'n': /* name + extension */
if (script->name_with_extension)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->name_with_extension);
snprintf (str_item, sizeof (str_item),
"%s%s%s.%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_name_selected :
script_config_color_text_name)),
script->name,
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_extension_selected :
script_config_color_text_extension)),
script_extension[script->language]);
}
break;
case 'N': /* name (without extension) */
if (script->name)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->name);
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_name_selected :
script_config_color_text_name)),
script->name);
}
break;
case 'r': /* requirements */
if (script->requirements)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->requirements);
snprintf (str_item, sizeof (str_item),
"%s", script->requirements);
}
break;
case 's': /* status */
snprintf (str_item, sizeof (str_item),
script_repo_get_status_for_display (script,
"*iHrN", 0));
break;
case 't': /* tags */
if (script->tags)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->tags);
tags = weechat_string_replace (script->tags, ",", " ");
if (tags)
{
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_tags_selected :
script_config_color_text_tags)),
tags);
free (tags);
}
}
break;
case 'u': /* date updated */
if (script->date_updated > 0)
{
tm = localtime (&script->date_updated);
strftime (str_date, sizeof (str_date),
"%Y-%m-%d", tm);
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_date_selected :
script_config_color_text_date)),
str_date);
}
else
num_spaces = 10;
break;
case 'v': /* version */
if (script->version)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->version);
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_version_selected :
script_config_color_text_version)),
script->version);
}
break;
case 'V': /* version loaded */
if (script->version_loaded)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->version_loaded);
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (
weechat_config_string (
(line == script_buffer_selected_line) ?
script_config_color_text_version_loaded_selected :
script_config_color_text_version_loaded)),
script->version_loaded);
}
break;
case 'w': /* min_weechat */
if (script->min_weechat)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->min_weechat);
snprintf (str_item, sizeof (str_item),
"%s", script->min_weechat);
}
break;
case 'W': /* max_weechat */
if (script->max_weechat)
{
num_spaces = max_length - weechat_utf8_strlen_screen (script->max_weechat);
snprintf (str_item, sizeof (str_item),
"%s", script->max_weechat);
}
break;
case '%': /* "%%" will display a single "%" */
snprintf (str_item, sizeof (str_item),
"%s%%",
weechat_color (weechat_config_string (script_config_color_text_delimiters)));
break;
default:
unknown = 1;
break;
}
}
else
{
snprintf (str_item, sizeof (str_item),
"%s%s",
weechat_color (weechat_config_string (script_config_color_text_delimiters)),
utf_char);
}
if (!unknown)
{
if (str_item[0])
{
strcat (str_line, str_color);
strcat (str_line, str_item);
}
if (num_spaces > 0)
{
snprintf (str_format, sizeof (str_format),
"%%-%ds",
num_spaces);
snprintf (str_item, sizeof (str_item),
str_format, " ");
strcat (str_line, str_item);
}
}
ptr_col += char_size;
}
weechat_printf_y (script_buffer, line, "%s", str_line);
}
/*
* script_buffer_detail_label: get header of a line for detail of script
* The returned string is aligned on the right
*/
const char *
script_buffer_detail_label (const char *text, int max_length)
{
char str_format[16];
static char result[1024];
int num_spaces;
num_spaces = max_length - weechat_utf8_strlen_screen (text);
snprintf (str_format, sizeof (str_format),
"%%-%ds%%s", num_spaces);
snprintf (result, sizeof (result),
str_format,
(num_spaces > 0) ? " " : "",
text);
return result;
}
/*
* script_buffer_display_detail_script: display detail on a script
*/
void
script_buffer_display_detail_script (struct t_repo_script *script)
{
struct tm *tm;
char str_time[1024];
char *labels[] = { N_("Script"), N_("Version"), N_("Author"),
N_("License"), N_("Description"), N_("Tags"),
N_("Status"), N_("Date added"), N_("Date updated"),
N_("URL"), N_("MD5"), N_("Requires"), N_("Min WeeChat"),
N_("Max WeeChat"), NULL };
int i, length, max_length, line;
max_length = 0;
for (i = 0; labels[i]; i++)
{
length = weechat_utf8_strlen_screen (_(labels[i]));
if (length > max_length)
max_length = length;
}
line = 0;
weechat_printf_y (script_buffer, line + 1,
"%s: %s%s%s.%s",
script_buffer_detail_label (_(labels[line]), max_length),
weechat_color (weechat_config_string (script_config_color_text_name)),
script->name,
weechat_color (weechat_config_string (script_config_color_text_extension)),
script_extension[script->language]);
line++;
weechat_printf_y (script_buffer, line + 1, "%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
script->version);
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s <%s>",
script_buffer_detail_label (_(labels[line]), max_length),
script->author,
script->mail);
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
script->license);
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
script->description);
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
script->tags);
line++;
if ((script->popularity == 0) && (script->status == 0))
{
weechat_printf_y (script_buffer, line + 1,
"%s: -",
script_buffer_detail_label (_(labels[line]), max_length));
}
else
{
weechat_printf_y (script_buffer, line + 1,
"%s: %s%s (%s%s%s%s%s%s%s%s%s%s )",
script_buffer_detail_label (_(labels[line]), max_length),
script_repo_get_status_for_display (script, "*iHrN", 1),
weechat_color ("chat"),
(script->popularity > 0) ? " " : "",
(script->popularity > 0) ? _("popular") : "",
(script->status & SCRIPT_STATUS_INSTALLED) ? " " : "",
(script->status & SCRIPT_STATUS_INSTALLED) ? _("installed") : "",
(script->status & SCRIPT_STATUS_HELD) ? " " : "",
(script->status & SCRIPT_STATUS_HELD) ? _("held") : "",
(script->status & SCRIPT_STATUS_RUNNING) ? " " : "",
(script->status & SCRIPT_STATUS_RUNNING) ? _("running") : "",
(script->status & SCRIPT_STATUS_NEW_VERSION) ? " " : "",
(script->status & SCRIPT_STATUS_NEW_VERSION) ? _("obsolete") : "");
}
line++;
tm = localtime (&script->date_added);
strftime (str_time, sizeof (str_time), "%Y-%m-%d %H:%M:%S", tm);
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
str_time);
line++;
tm = localtime (&script->date_updated);
strftime (str_time, sizeof (str_time), "%Y-%m-%d %H:%M:%S", tm);
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
str_time);
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
script->url);
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
script->md5sum);
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
(script->requirements) ? script->requirements : "-");
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
(script->min_weechat) ? script->min_weechat : "-");
line++;
weechat_printf_y (script_buffer, line + 1,
"%s: %s",
script_buffer_detail_label (_(labels[line]), max_length),
(script->max_weechat) ? script->max_weechat : "-");
}
/*
* script_buffer_refresh: update list of scripts in script buffer
*/
void
script_buffer_refresh (int clear)
{
struct t_repo_script *ptr_script;
int line;
char str_title[1024];
if (!script_buffer)
return;
if (clear)
{
weechat_buffer_clear (script_buffer);
script_buffer_selected_line = (script_repo_count_displayed > 0) ? 0 : -1;
}
if (script_buffer_detail_script)
{
snprintf (str_title, sizeof (str_title),
_("alt+d=back to list"));
}
else
{
snprintf (str_title, sizeof (str_title),
_("%d/%d scripts (filter: %s) | Sort: %s | "
"alt+i=install r=remove l=load u=unload h=(un)hold "
"d=show detail | Input: 'q'=close 'r'=refresh 's:x,y'=sort "
"'words'=filter '*'=reset filter"),
script_repo_count_displayed,
script_repo_count,
(script_repo_filter) ? script_repo_filter : "*",
weechat_config_string (script_config_look_sort));
}
weechat_buffer_set (script_buffer, "title", str_title);
if (script_buffer_detail_script)
{
/* detail on a script */
script_buffer_display_detail_script (script_buffer_detail_script);
}
else
{
/* list of scripts */
line = 0;
for (ptr_script = repo_scripts; ptr_script;
ptr_script = ptr_script->next_script)
{
if (ptr_script->displayed)
{
script_buffer_display_line_script (line, ptr_script);
line++;
}
}
}
}
/*
* script_buffer_set_current_line: set current selected line in script buffer
*/
void
script_buffer_set_current_line (int line)
{
int old_line;
old_line = script_buffer_selected_line;
script_buffer_selected_line = line;
script_buffer_display_line_script (old_line,
script_repo_search_displayed_by_number (old_line));
script_buffer_display_line_script (script_buffer_selected_line,
script_repo_search_displayed_by_number (script_buffer_selected_line));
}
/*
* script_buffer_show_detail_script: show detailed info on a script
*/
void
script_buffer_show_detail_script (struct t_repo_script *script)
{
if (!script_buffer)
return;
if (script_buffer_detail_script == script)
script_buffer_detail_script = NULL;
else
script_buffer_detail_script = script;
weechat_buffer_clear (script_buffer);
script_buffer_refresh (0);
if (!script_buffer_detail_script)
script_buffer_check_line_outside_window ();
}
/*
* script_buffer_get_window_info: get infos about window
*/
void
script_buffer_get_window_info (struct t_gui_window *window,
int *start_line_y, int *chat_height)
{
struct t_hdata *hdata_window, *hdata_window_scroll, *hdata_line;
struct t_hdata *hdata_line_data;
void *window_scroll, *start_line, *line_data;
hdata_window = weechat_hdata_get ("window");
hdata_window_scroll = weechat_hdata_get ("window_scroll");
hdata_line = weechat_hdata_get ("line");
hdata_line_data = weechat_hdata_get ("line_data");
*start_line_y = 0;
window_scroll = weechat_hdata_pointer (hdata_window, window, "scroll");
if (window_scroll)
{
start_line = weechat_hdata_pointer (hdata_window_scroll, window_scroll,
"start_line");
if (start_line)
{
line_data = weechat_hdata_pointer (hdata_line, start_line, "data");
if (line_data)
{
*start_line_y = weechat_hdata_integer (hdata_line_data,
line_data, "y");
}
}
}
*chat_height = weechat_hdata_integer (hdata_window, window,
"win_chat_height");
}
/*
* script_buffer_check_line_outside_window: check if current line is outside
* window
*/
void
script_buffer_check_line_outside_window ()
{
struct t_gui_window *window;
int start_line_y, chat_height;
char str_command[256];
window = weechat_window_search_with_buffer (script_buffer);
if (!window)
return;
script_buffer_get_window_info (window, &start_line_y, &chat_height);
if ((start_line_y > script_buffer_selected_line)
|| (start_line_y <= script_buffer_selected_line - chat_height))
{
snprintf (str_command, sizeof (str_command),
"/window scroll -window %d %s%d",
weechat_window_get_integer (window, "number"),
(start_line_y > script_buffer_selected_line) ? "-" : "+",
(start_line_y > script_buffer_selected_line) ?
start_line_y - script_buffer_selected_line :
script_buffer_selected_line - start_line_y - chat_height + 1);
weechat_command (script_buffer, str_command);
}
}
/*
* script_buffer_window_scrolled_cb: called when signal "window_scrolled" is
* received
*/
int
script_buffer_window_scrolled_cb (void *data, const char *signal,
const char *type_data,
void *signal_data)
{
int start_line_y, chat_height, line;
/* make C compiler happy */
(void) data;
(void) signal;
(void) type_data;
/* scrolled another window/buffer? then just ignore */
if (weechat_window_get_pointer (signal_data, "buffer") != script_buffer)
return WEECHAT_RC_OK;
/* ignore if detail of a script is displayed */
if (script_buffer_detail_script)
return WEECHAT_RC_OK;
script_buffer_get_window_info (signal_data, &start_line_y, &chat_height);
line = script_buffer_selected_line;
while (line < start_line_y)
{
line += chat_height;
}
while (line >= start_line_y + chat_height)
{
line -= chat_height;
}
if (line < start_line_y)
line = start_line_y;
if (line >= script_repo_count_displayed)
line = script_repo_count_displayed - 1;
script_buffer_set_current_line (line);
return WEECHAT_RC_OK;
}
/*
* script_buffer_input_cb: callback called when user send data to script list
* buffer
*/
int
script_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
const char *input_data)
{
/* make C compiler happy */
(void) data;
(void) buffer;
if (strcmp (input_data, "q") == 0)
{
weechat_buffer_close (buffer);
return WEECHAT_RC_OK;
}
if (strncmp (input_data, "s:", 2) == 0)
{
if (input_data[2])
weechat_config_option_set (script_config_look_sort, input_data + 2, 1);
else
weechat_config_option_reset (script_config_look_sort, 1);
return WEECHAT_RC_OK;
}
if (strcmp (input_data, "r") == 0)
{
script_get_loaded_scripts ();
script_repo_remove_all ();
script_repo_file_read (1);
script_buffer_refresh (1);
return WEECHAT_RC_OK;
}
script_repo_filter_scripts (input_data);
return WEECHAT_RC_OK;
}
/*
* script_buffer_close_cb: callback called when script buffer is closed
*/
int
script_buffer_close_cb (void *data, struct t_gui_buffer *buffer)
{
/* make C compiler happy */
(void) data;
(void) buffer;
script_buffer = NULL;
script_buffer_selected_line = 0;
script_buffer_detail_script = NULL;
return WEECHAT_RC_OK;
}
/*
* script_buffer_set_callbacks: restore buffers callbacks (input and close) for
* buffer created by script plugin
*/
void
script_buffer_set_callbacks ()
{
struct t_gui_buffer *ptr_buffer;
ptr_buffer = weechat_buffer_search (SCRIPT_PLUGIN_NAME, SCRIPT_BUFFER_NAME);
if (ptr_buffer)
{
script_buffer = ptr_buffer;
weechat_buffer_set_pointer (script_buffer, "close_callback", &script_buffer_close_cb);
weechat_buffer_set_pointer (script_buffer, "input_callback", &script_buffer_input_cb);
}
}
/*
* script_buffer_open: open script buffer (to display list of scripts)
*/
void
script_buffer_open ()
{
if (!script_buffer)
{
script_buffer = weechat_buffer_new (SCRIPT_BUFFER_NAME,
&script_buffer_input_cb, NULL,
&script_buffer_close_cb, NULL);
/* failed to create buffer ? then exit */
if (!script_buffer)
return;
weechat_buffer_set (script_buffer, "type", "free");
weechat_buffer_set (script_buffer, "title", _("Scripts"));
weechat_buffer_set (script_buffer, "key_bind_meta2-A", "/script up");
weechat_buffer_set (script_buffer, "key_bind_meta2-B", "/script down");
weechat_buffer_set (script_buffer, "key_bind_meta-l", "/script load");
weechat_buffer_set (script_buffer, "key_bind_meta-u", "/script unload");
weechat_buffer_set (script_buffer, "key_bind_meta-i", "/script install");
weechat_buffer_set (script_buffer, "key_bind_meta-r", "/script remove");
weechat_buffer_set (script_buffer, "key_bind_meta-h", "/script hold");
weechat_buffer_set (script_buffer, "key_bind_meta-d", "/script show");
weechat_buffer_set (script_buffer, "localvar_set_type", "script");
script_buffer_selected_line = 0;
script_buffer_detail_script = NULL;
}
}
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_BUFFER_H
#define __WEECHAT_SCRIPT_BUFFER_H 1
#define SCRIPT_BUFFER_NAME "scripts"
struct t_repo_script;
extern struct t_gui_buffer *script_buffer;
extern int script_buffer_selected_line;
extern struct t_repo_script *script_buffer_detail_script;
extern void script_buffer_refresh (int clear);
extern void script_buffer_set_current_line (int line);
extern void script_buffer_show_detail_script (struct t_repo_script *script);
extern void script_buffer_check_line_outside_window ();
extern int script_buffer_window_scrolled_cb (void *data, const char *signal,
const char *type_data,
void *signal_data);
extern int script_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
const char *input_data);
extern int script_buffer_close_cb (void *data, struct t_gui_buffer *buffer);
extern void script_buffer_set_callbacks ();
extern void script_buffer_open ();
#endif /* __WEECHAT_SCRIPT_BUFFER_H */
+270
View File
@@ -0,0 +1,270 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* script-command.c: script commands
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "../weechat-plugin.h"
#include "script.h"
#include "script-command.h"
#include "script-action.h"
#include "script-buffer.h"
#include "script-config.h"
#include "script-repo.h"
/*
* script_command_action: run action
*/
void
script_command_action (struct t_gui_buffer *buffer, const char *action,
const char *action_with_args, int need_repository)
{
struct t_repo_script *ptr_script;
char str_action[4096];
if (action_with_args)
{
/* action with arguments on command line */
script_action_schedule (action_with_args, need_repository, 0);
}
else if (script_buffer && (buffer == script_buffer))
{
/* action on current line of script buffer */
if ((weechat_strcasecmp (action, "show") == 0)
&& script_buffer_detail_script)
{
/* if detail on script is displayed, back to list */
snprintf (str_action, sizeof (str_action),
"-q %s",
action);
script_action_schedule (str_action, need_repository, 1);
}
else
{
/* if list is displayed, execute action on script */
if (!script_buffer_detail_script)
{
ptr_script = script_repo_search_displayed_by_number (script_buffer_selected_line);
if (ptr_script)
{
snprintf (str_action, sizeof (str_action),
"-q %s %s",
action,
ptr_script->name_with_extension);
script_action_schedule (str_action, need_repository, 1);
}
}
}
}
}
/*
* script_command_script: command to manage scripts
*/
int
script_command_script (void *data, struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
char *error;
long value;
int line;
/* make C compiler happy */
(void) data;
if (argc == 1)
{
script_action_schedule ("buffer", 1, 0);
return WEECHAT_RC_OK;
}
if (weechat_strcasecmp (argv[1], "list") == 0)
{
script_action_schedule ("list", 1, 0);
return WEECHAT_RC_OK;
}
if ((weechat_strcasecmp (argv[1], "load") == 0)
|| (weechat_strcasecmp (argv[1], "unload") == 0))
{
script_command_action (buffer,
argv[1],
(argc > 2) ? argv_eol[1] : NULL,
0);
return WEECHAT_RC_OK;
}
if ((weechat_strcasecmp (argv[1], "install") == 0)
|| (weechat_strcasecmp (argv[1], "remove") == 0)
|| (weechat_strcasecmp (argv[1], "hold") == 0)
|| (weechat_strcasecmp (argv[1], "show") == 0))
{
script_command_action (buffer,
argv[1],
(argc > 2) ? argv_eol[1] : NULL,
1);
return WEECHAT_RC_OK;
}
if (weechat_strcasecmp (argv[1], "upgrade") == 0)
{
script_action_schedule ("upgrade", 1, 0);
return WEECHAT_RC_OK;
}
if (weechat_strcasecmp (argv[1], "update") == 0)
{
script_repo_file_update (0);
return WEECHAT_RC_OK;
}
if (!script_buffer)
script_buffer_open ();
if (script_buffer)
{
weechat_buffer_set (script_buffer, "display", "1");
if (argc > 1)
{
if (!script_buffer_detail_script
&& (script_buffer_selected_line >= 0)
&& (script_repo_count_displayed > 0))
{
if (strcmp (argv[1], "up") == 0)
{
value = 1;
if (argc > 2)
{
error = NULL;
value = strtol (argv[2], &error, 10);
if (!error || error[0])
value = 1;
}
line = script_buffer_selected_line - value;
if (line < 0)
line = 0;
if (line != script_buffer_selected_line)
{
script_buffer_set_current_line (line);
script_buffer_check_line_outside_window ();
}
return WEECHAT_RC_OK;
}
else if (strcmp (argv[1], "down") == 0)
{
value = 1;
if (argc > 2)
{
error = NULL;
value = strtol (argv[2], &error, 10);
if (!error || error[0])
value = 1;
}
line = script_buffer_selected_line + value;
if (line >= script_repo_count_displayed)
line = script_repo_count_displayed - 1;
if (line != script_buffer_selected_line)
{
script_buffer_set_current_line (line);
script_buffer_check_line_outside_window ();
}
return WEECHAT_RC_OK;
}
}
}
}
script_buffer_refresh (0);
return WEECHAT_RC_OK;
}
/*
* scrit_command_init: init script commands (create hooks)
*/
void
script_command_init ()
{
weechat_hook_command ("script",
N_("WeeChat scripts manager"),
N_("list || show <script>"
" || load|unload <script> [<script>...]"
" || install|remove|hold <script> [<script>...]"
" || upgrade || update"),
N_(" list: list loaded scripts (all languages)\n"
" show: show detailed info about a script\n"
" load: load script(s)\n"
" unload: unload script(s)\n"
" install: install/upgrade script(s)\n"
" remove: remove script(s)\n"
" hold: hold/unhold script(s) (a script held "
"will not be upgraded any more and cannot be "
"removed)\n"
" upgrade: upgrade all installed scripts which "
"are obsolete (new version available)\n"
" update: update local scripts cache\n\n"
"Without argument, this command opens a buffer "
"with list of scripts.\n\n"
"On script buffer, the possible status for each "
"script are:\n"
" * i H r N\n"
" | | | | |\n"
" | | | | obsolete (new version available)\n"
" | | | running (loaded)\n"
" | | held\n"
" | installed\n"
" popular script\n\n"
"Keys on script buffer:\n"
" alt+i install script\n"
" alt+r remove script\n"
" alt+l load script\n"
" alt+u unload script\n"
" alt+h (un)hold script\n\n"
"Input allowed on script buffer:\n"
" q close buffer\n"
" r refresh buffer\n"
" s:x,y sort buffer using keys x and y (see /help "
"script.look.sort)\n"
" s: reset sort (use default sort)\n"
" word(s) filter scripts: search word(s) in "
"scripts (description, tags, ...)\n"
" * remove filter"),
"list"
" || show %(script_scripts)"
" || load %(script_files)"
" || unload %(python_script)|%(perl_script)|"
"%(ruby_script)|%(tcl_script)|%(lua_script)|"
"%(guile_script)"
" || install %(script_scripts)|%*"
" || remove %(script_scripts_installed)|%*"
" || hold %(script_scripts)"
" || update"
" || upgrade",
&script_command_script, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_COMMAND_H
#define __WEECHAT_SCRIPT_COMMAND_H 1
extern void script_command_init ();
#endif /* __WEECHAT_SCRIPT_COMMAND_H */
+192
View File
@@ -0,0 +1,192 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* script-completion.c: completion for script commands
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include "../weechat-plugin.h"
#include "script.h"
#include "script-repo.h"
/*
* script_completion_scripts_cb: callback for completion with scripts in
* repository
*/
int
script_completion_scripts_cb (void *data, const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_repo_script *ptr_script;
/* make C compiler happy */
(void) data;
(void) completion_item;
(void) buffer;
for (ptr_script = repo_scripts; ptr_script;
ptr_script = ptr_script->next_script)
{
weechat_hook_completion_list_add (completion,
ptr_script->name_with_extension,
0, WEECHAT_LIST_POS_SORT);
}
return WEECHAT_RC_OK;
}
/*
* script_completion_scripts_installed_cb: callback for completion with scripts
* installed
*/
int
script_completion_scripts_installed_cb (void *data, const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_repo_script *ptr_script;
/* make C compiler happy */
(void) data;
(void) completion_item;
(void) buffer;
for (ptr_script = repo_scripts; ptr_script;
ptr_script = ptr_script->next_script)
{
if (ptr_script->status & SCRIPT_STATUS_INSTALLED)
{
weechat_hook_completion_list_add (completion,
ptr_script->name_with_extension,
0, WEECHAT_LIST_POS_SORT);
}
}
return WEECHAT_RC_OK;
}
/*
* script_completion_exec_file_cb: callback called for each file in script
* directories
*/
void
script_completion_exec_file_cb (void *data, const char *filename)
{
struct t_gui_completion *completion;
const char *extension;
char *pos, *filename2, *ptr_base_name;
completion = (struct t_gui_completion *)(((void **)data)[0]);
extension = (const char *)(((void **)data)[1]);
pos = strrchr (filename, '.');
if (!pos)
return;
/* ignore scripts that do not ends with expected extension */
if (strcmp (pos + 1, extension) != 0)
return;
filename2 = strdup (filename);
if (filename2)
{
ptr_base_name = basename (filename2);
weechat_hook_completion_list_add (completion,
ptr_base_name,
0, WEECHAT_LIST_POS_SORT);
free (filename2);
}
}
/*
* script_completion_scripts_files_cb: callback for completion with files in
* script directories
*/
int
script_completion_scripts_files_cb (void *data, const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
const char *weechat_home;
char *directory;
int length, i;
void *pointers[2];
/* make C compiler happy */
(void) data;
(void) completion_item;
(void) buffer;
weechat_home = weechat_info_get ("weechat_dir", NULL);
length = strlen (weechat_home) + 128 + 1;
directory = malloc (length);
if (directory)
{
for (i = 0; script_language[i]; i++)
{
pointers[0] = completion;
pointers[1] = script_extension[i];
/* look for files in "~/.weechat/<language>/" */
snprintf (directory, length,
"%s/%s", weechat_home, script_language[i]);
weechat_exec_on_files (directory, 0,
pointers, &script_completion_exec_file_cb);
/* look for files in "~/.weechat/<language>/autoload/" */
snprintf (directory, length,
"%s/%s/autoload", weechat_home, script_language[i]);
weechat_exec_on_files (directory, 0,
pointers, &script_completion_exec_file_cb);
}
free (directory);
}
return WEECHAT_RC_OK;
}
/*
* script_completion_init: init completion for script plugin
*/
void
script_completion_init ()
{
weechat_hook_completion ("script_scripts",
N_("list of scripts in repository"),
&script_completion_scripts_cb, NULL);
weechat_hook_completion ("script_scripts_installed",
N_("list of scripts installed (from repository)"),
&script_completion_scripts_installed_cb, NULL);
weechat_hook_completion ("script_files",
N_("files in script directories"),
&script_completion_scripts_files_cb, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_COMPLETION_H
#define __WEECHAT_SCRIPT_COMPLETION_H 1
extern void script_completion_init ();
#endif /* __WEECHAT_SCRIPT_COMPLETION_H */
+587
View File
@@ -0,0 +1,587 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* script-config.c: script configuration options (file script.conf)
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../weechat-plugin.h"
#include "script.h"
#include "script-config.h"
#include "script-buffer.h"
#include "script-repo.h"
struct t_config_file *script_config_file = NULL;
struct t_config_section *script_config_section_look = NULL;
struct t_config_section *script_config_section_color = NULL;
struct t_config_section *script_config_section_scripts = NULL;
/* script config, look section */
struct t_config_option *script_config_look_columns;
struct t_config_option *script_config_look_sort;
/* script config, color section */
struct t_config_option *script_config_color_status_popular;
struct t_config_option *script_config_color_status_installed;
struct t_config_option *script_config_color_status_held;
struct t_config_option *script_config_color_status_running;
struct t_config_option *script_config_color_status_obsolete;
struct t_config_option *script_config_color_status_unknown;
struct t_config_option *script_config_color_text;
struct t_config_option *script_config_color_text_date;
struct t_config_option *script_config_color_text_delimiters;
struct t_config_option *script_config_color_text_description;
struct t_config_option *script_config_color_text_extension;
struct t_config_option *script_config_color_text_name;
struct t_config_option *script_config_color_text_tags;
struct t_config_option *script_config_color_text_version;
struct t_config_option *script_config_color_text_version_loaded;
struct t_config_option *script_config_color_text_bg;
struct t_config_option *script_config_color_text_selected;
struct t_config_option *script_config_color_text_date_selected;
struct t_config_option *script_config_color_text_description_selected;
struct t_config_option *script_config_color_text_extension_selected;
struct t_config_option *script_config_color_text_name_selected;
struct t_config_option *script_config_color_text_tags_selected;
struct t_config_option *script_config_color_text_version_selected;
struct t_config_option *script_config_color_text_version_loaded_selected;
struct t_config_option *script_config_color_text_bg_selected;
/* script config, scripts section */
struct t_config_option *script_config_scripts_cache_expire;
struct t_config_option *script_config_scripts_dir;
struct t_config_option *script_config_scripts_hold;
struct t_config_option *script_config_scripts_url;
/*
* script_config_get_dir: get local directory for script
* Note: result must be freed after use
*/
char *
script_config_get_dir ()
{
const char *weechat_home;
char *path, *path2;
weechat_home = weechat_info_get ("weechat_dir", NULL);
path = weechat_string_expand_home (weechat_config_string (script_config_scripts_dir));
path2 = weechat_string_replace ((path) ?
path : weechat_config_string (script_config_scripts_dir),
"%h", weechat_home);
if (path && path2)
{
free (path);
path = NULL;
}
if (path2)
return path2;
if (path)
return path;
return strdup (weechat_config_string (script_config_scripts_dir));
}
/*
* script_config_get_xml_filename: get filename with scripts (by default
* "/home/xxx/.weechat/script/plugins.xml.gz")
* Note: result must be freed after use
*/
char *
script_config_get_xml_filename ()
{
char *path, *filename;
int length;
path = script_config_get_dir ();
length = strlen (path) + 64;
filename = malloc (length);
if (filename)
snprintf (filename, length, "%s/plugins.xml.gz", path);
free (path);
return filename;
}
/*
* script_config_get_script_download_filename: get filename for a script to
* download, for eample:
* "/home/xxx/.weechat/script/iset.pl"
* Note: result must be freed after
* use
*/
char *
script_config_get_script_download_filename (struct t_repo_script *script)
{
char *path, *filename;
int length;
path = script_config_get_dir ();
length = strlen (path) + 1 + strlen (script->name_with_extension) + 1;
filename = malloc (length);
if (filename)
snprintf (filename, length, "%s/%s", path, script->name_with_extension);
free (path);
return filename;
}
/*
* script_config_refresh_cb: callback called when user changes xfer option that
* needs a refresh of script list
*/
void
script_config_refresh_cb (void *data, struct t_config_option *option)
{
/* make C compiler happy */
(void) data;
(void) option;
if (script_buffer)
script_buffer_refresh (0);
}
/*
* script_config_change_sort_cb: callback called when default sort keys are
* changed
*/
void
script_config_change_sort_cb (void *data, struct t_config_option *option)
{
/* make C compiler happy */
(void) data;
(void) option;
if (repo_scripts)
{
script_repo_remove_all ();
script_repo_file_read (1);
script_buffer_refresh (1);
}
}
/*
* script_config_change_hold_cb: callback called when list of scripts to "hold"
* is changed
*/
void
script_config_change_hold_cb (void *data, struct t_config_option *option)
{
/* make C compiler happy */
(void) data;
(void) option;
script_repo_update_status_all ();
if (script_buffer)
script_buffer_refresh (0);
}
/*
* script_config_hold: hold a script
* Note: the option is changed, but the status "held"
* in script is NOT updated by this function
*/
void
script_config_hold (const char *name_with_extension)
{
char **items, *hold;
int num_items, i, length;
length = strlen (weechat_config_string (script_config_scripts_hold)) +
1 + strlen (name_with_extension) + 1;
hold = malloc (length);
if (hold)
{
hold[0] = '\0';
items = weechat_string_split (weechat_config_string (script_config_scripts_hold),
",", 0, 0, &num_items);
if (items)
{
for (i = 0; i < num_items; i++)
{
if (strcmp (items[i], name_with_extension) != 0)
{
if (hold[0])
strcat (hold, ",");
strcat (hold, items[i]);
}
}
weechat_string_free_split (items);
}
if (hold[0])
strcat (hold, ",");
strcat (hold, name_with_extension);
weechat_config_option_set (script_config_scripts_hold, hold, 0);
free (hold);
}
}
/*
* script_config_unhold: unhold a script
* Note: the option is changed, but the status "held"
* in script is NOT updated by this function
*/
void
script_config_unhold (const char *name_with_extension)
{
char **items, *hold;
int num_items, i, length;
length = strlen (weechat_config_string (script_config_scripts_hold)) + 1;
hold = malloc (length);
if (hold)
{
hold[0] = '\0';
items = weechat_string_split (weechat_config_string (script_config_scripts_hold),
",", 0, 0, &num_items);
if (items)
{
for (i = 0; i < num_items; i++)
{
if (strcmp (items[i], name_with_extension) != 0)
{
if (hold[0])
strcat (hold, ",");
strcat (hold, items[i]);
}
}
weechat_string_free_split (items);
}
weechat_config_option_set (script_config_scripts_hold, hold, 0);
free (hold);
}
}
/*
* script_config_reaload: reload script configuration file
*/
int
script_config_reload (void *data, struct t_config_file *config_file)
{
/* make C compiler happy */
(void) data;
return weechat_config_reload (config_file);
}
/*
* script_config_init: init script configuration file
* return: 1 if ok, 0 if error
*/
int
script_config_init ()
{
struct t_config_section *ptr_section;
script_config_file = weechat_config_new (SCRIPT_CONFIG_NAME,
&script_config_reload, NULL);
if (!script_config_file)
return 0;
/* look */
ptr_section = weechat_config_new_section (script_config_file, "look",
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (script_config_file);
return 0;
}
script_config_look_columns = weechat_config_new_option (
script_config_file, ptr_section,
"columns", "string",
N_("format of columns displayed in script buffer: following column "
"identifiers are replaced by their value: %a=author, %d=description, "
"%D=date added, %e=extension, %l=language, %L=license, %n=name with "
"extension, %N=name, %r=requirements, %s=status, %t=tags, "
"%u=date updated, %v=version, %V=version loaded, %w=min_weechat, "
"%W=max_weechat)"),
NULL, 0, 0, "%s %n %V %v %u | %d | %t", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_look_sort = weechat_config_new_option (
script_config_file, ptr_section,
"sort", "string",
N_("default sort keys for scripts: comma-separated list of identifiers: "
"a=author, d=date added, e=extension, i=installed, l=language, "
"n=name, o=obsolete, p=popularity, r=running, u=date updated; char "
"\"-\" can be used before identifier to reverse order; example: "
"\"i,u\": installed scripts first, sorted by update date"),
NULL, 0, 0, "p,n", NULL, 0,
NULL, NULL, &script_config_change_sort_cb, NULL, NULL, NULL);
/* color */
ptr_section = weechat_config_new_section (script_config_file, "color",
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (script_config_file);
return 0;
}
script_config_color_status_popular = weechat_config_new_option (
script_config_file, ptr_section,
"status_popular", "color",
N_("color for status \"popular\" (\"*\")"),
NULL, 0, 0, "yellow", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_status_installed = weechat_config_new_option (
script_config_file, ptr_section,
"status_installed", "color",
N_("color for status \"installed\" (\"i\")"),
NULL, 0, 0, "lightcyan", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_status_held = weechat_config_new_option (
script_config_file, ptr_section,
"status_held", "color",
N_("color for status \"held\" (\"H\")"),
NULL, 0, 0, "white", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_status_running = weechat_config_new_option (
script_config_file, ptr_section,
"status_running", "color",
N_("color for status \"running\" (\"r\")"),
NULL, 0, 0, "lightgreen", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_status_obsolete = weechat_config_new_option (
script_config_file, ptr_section,
"status_obsolete", "color",
N_("color for status \"obsolete\" (\"N\")"),
NULL, 0, 0, "lightmagenta", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_status_unknown = weechat_config_new_option (
script_config_file, ptr_section,
"status_unknown", "color",
N_("color for status \"unknown\" (\"?\")"),
NULL, 0, 0, "lightred", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text = weechat_config_new_option (
script_config_file, ptr_section,
"text", "color",
N_("text color in script buffer"),
NULL, 0, 0, "default", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_date = weechat_config_new_option (
script_config_file, ptr_section,
"text_date", "color",
N_("text color of dates in script buffer"),
NULL, 0, 0, "default", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_delimiters = weechat_config_new_option (
script_config_file, ptr_section,
"text_delimiters", "color",
N_("text color of delimiters in script buffer"),
NULL, 0, 0, "darkgray", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_description = weechat_config_new_option (
script_config_file, ptr_section,
"text_description", "color",
N_("text color of description in script buffer"),
NULL, 0, 0, "default", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_extension = weechat_config_new_option (
script_config_file, ptr_section,
"text_extension", "color",
N_("text color of extension in script buffer"),
NULL, 0, 0, "default", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_name = weechat_config_new_option (
script_config_file, ptr_section,
"text_name", "color",
N_("text color of script name in script buffer"),
NULL, 0, 0, "cyan", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_tags = weechat_config_new_option (
script_config_file, ptr_section,
"text_tags", "color",
N_("text color of tags in script buffer"),
NULL, 0, 0, "brown", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_version = weechat_config_new_option (
script_config_file, ptr_section,
"text_version", "color",
N_("text color of version in script buffer"),
NULL, 0, 0, "magenta", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_version_loaded = weechat_config_new_option (
script_config_file, ptr_section,
"text_version_loaded", "color",
N_("text color of version loaded in script buffer"),
NULL, 0, 0, "default", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_bg = weechat_config_new_option (
script_config_file, ptr_section,
"text_bg", "color",
N_("background color in script buffer"),
NULL, 0, 0, "default", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_selected", "color",
N_("text color for selected line in script buffer"),
NULL, 0, 0, "white", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_date_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_date_selected", "color",
N_("text color of dates for selected line in script buffer"),
NULL, 0, 0, "white", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_description_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_description_selected", "color",
N_("text color of description for selected line in script buffer"),
NULL, 0, 0, "white", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_extension_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_extension_selected", "color",
N_("text color of extension for selected line in script buffer"),
NULL, 0, 0, "white", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_name_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_name_selected", "color",
N_("text color of script name for selected line in script buffer"),
NULL, 0, 0, "lightcyan", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_tags_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_tags_selected", "color",
N_("text color of tags for selected line in script buffer"),
NULL, 0, 0, "yellow", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_version_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_version_selected", "color",
N_("text color of version for selected line in script buffer"),
NULL, 0, 0, "lightmagenta", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_version_loaded_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_version_loaded_selected", "color",
N_("text color of version loaded for selected line in script buffer"),
NULL, 0, 0, "white", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
script_config_color_text_bg_selected = weechat_config_new_option (
script_config_file, ptr_section,
"text_bg_selected", "color",
N_("background color for selected line in script buffer"),
NULL, 0, 0, "red", NULL, 0,
NULL, NULL, &script_config_refresh_cb, NULL, NULL, NULL);
/* scripts */
ptr_section = weechat_config_new_section (script_config_file, "scripts",
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (script_config_file);
return 0;
}
script_config_scripts_cache_expire = weechat_config_new_option (
script_config_file, ptr_section,
"cache_expire", "integer",
N_("local cache expiration time, in minutes (-1 = never expires, "
"0 = always expire)"),
NULL, -1, 525600, "60", NULL, 0, NULL, NULL,
NULL, NULL, NULL, NULL);
script_config_scripts_dir = weechat_config_new_option (
script_config_file, ptr_section,
"dir", "string",
N_("local cache directory for scripts"),
NULL, 0, 0, "%h/script", NULL, 0, NULL, NULL,
NULL, NULL, NULL, NULL);
script_config_scripts_hold = weechat_config_new_option (
script_config_file, ptr_section,
"hold", "string",
N_("scripts to \"hold\": comma-separated list of scripts which will "
"never been upgraded and can not be removed, for example: "
"\"buffers.pl,iset.pl\""),
NULL, 0, 0, "", NULL, 0, NULL, NULL,
&script_config_change_hold_cb, NULL, NULL, NULL);
script_config_scripts_url = weechat_config_new_option (
script_config_file, ptr_section,
"url", "string",
N_("URL for file with list of scripts"),
NULL, 0, 0, "http://www.weechat.org/files/plugins.xml.gz", NULL, 0, NULL, NULL,
NULL, NULL, NULL, NULL);
return 1;
}
/*
* script_config_read: read script configuration file
*/
int
script_config_read ()
{
return weechat_config_read (script_config_file);
}
/*
* script_config_write: write script configuration file
*/
int
script_config_write ()
{
return weechat_config_write (script_config_file);
}
/*
* script_config_free: free script configuration file
*/
void
script_config_free ()
{
weechat_config_free (script_config_file);
}
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_CONFIG_H
#define __WEECHAT_SCRIPT_CONFIG_H 1
#define SCRIPT_CONFIG_NAME "script"
struct t_repo_script;
extern struct t_config_option *script_config_look_columns;
extern struct t_config_option *script_config_look_sort;
extern struct t_config_option *script_config_color_status_popular;
extern struct t_config_option *script_config_color_status_installed;
extern struct t_config_option *script_config_color_status_held;
extern struct t_config_option *script_config_color_status_running;
extern struct t_config_option *script_config_color_status_obsolete;
extern struct t_config_option *script_config_color_status_unknown;
extern struct t_config_option *script_config_color_text;
extern struct t_config_option *script_config_color_text_date;
extern struct t_config_option *script_config_color_text_delimiters;
extern struct t_config_option *script_config_color_text_description;
extern struct t_config_option *script_config_color_text_extension;
extern struct t_config_option *script_config_color_text_name;
extern struct t_config_option *script_config_color_text_tags;
extern struct t_config_option *script_config_color_text_version;
extern struct t_config_option *script_config_color_text_version_loaded;
extern struct t_config_option *script_config_color_text_bg;
extern struct t_config_option *script_config_color_text_selected;
extern struct t_config_option *script_config_color_text_date_selected;
extern struct t_config_option *script_config_color_text_description_selected;
extern struct t_config_option *script_config_color_text_extension_selected;
extern struct t_config_option *script_config_color_text_name_selected;
extern struct t_config_option *script_config_color_text_tags_selected;
extern struct t_config_option *script_config_color_text_version_selected;
extern struct t_config_option *script_config_color_text_version_loaded_selected;
extern struct t_config_option *script_config_color_text_bg_selected;
extern struct t_config_option *script_config_scripts_cache_expire;
extern struct t_config_option *script_config_scripts_dir;
extern struct t_config_option *script_config_scripts_hold;
extern struct t_config_option *script_config_scripts_url;
extern char *script_config_get_dir ();
extern char *script_config_get_xml_filename ();
extern char *script_config_get_script_download_filename (struct t_repo_script *script);
extern void script_config_hold (const char *name_with_extension);
extern void script_config_unhold (const char *name_with_extension);
extern int script_config_init ();
extern int script_config_read ();
extern int script_config_write ();
extern void script_config_free ();
#endif /* __WEECHAT_SCRIPT_CONFIG_H */
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* script-info.c: info, infolist and hdata hooks for script plugin
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../weechat-plugin.h"
#include "script.h"
#include "script-repo.h"
/*
* script_info_get_infolist_cb: callback called when script infolist is asked
*/
struct t_infolist *
script_info_get_infolist_cb (void *data, const char *infolist_name,
void *pointer, const char *arguments)
{
struct t_infolist *ptr_infolist;
struct t_repo_script *ptr_script;
/* make C compiler happy */
(void) data;
if (!infolist_name || !infolist_name[0])
return NULL;
if (weechat_strcasecmp (infolist_name, "script_script") == 0)
{
if (pointer && !script_repo_script_valid (pointer))
return NULL;
ptr_infolist = weechat_infolist_new ();
if (ptr_infolist)
{
if (pointer)
{
/* build list with only one script */
if (!script_repo_add_to_infolist (ptr_infolist, pointer))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
return ptr_infolist;
}
else
{
/* build list with all scripts matching arguments */
for (ptr_script = repo_scripts; ptr_script;
ptr_script = ptr_script->next_script)
{
if (!arguments || !arguments[0]
|| weechat_string_match (ptr_script->name_with_extension,
arguments, 0))
{
if (!script_repo_add_to_infolist (ptr_infolist, ptr_script))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
}
}
return ptr_infolist;
}
}
}
return NULL;
}
/*
* script_info_init: initialize info, infolist and hdata hooks for script plugin
*/
void
script_info_init ()
{
/* infolist hooks */
weechat_hook_infolist ("script_script",
N_("list of scripts"),
N_("script pointer (optional)"),
N_("script name with extension (can start or end with \"*\" as wildcard) (optional)"),
&script_info_get_infolist_cb, NULL);
/* hdata hooks */
weechat_hook_hdata ("script_script", N_("scripts from repository"),
&script_repo_hdata_script_cb, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_INFO_H
#define __WEECHAT_SCRIPT_INFO_H 1
extern void script_info_init ();
#endif /* __WEECHAT_SCRIPT_INFO_H */
File diff suppressed because it is too large Load Diff
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_REPO_H
#define __WEECHAT_SCRIPT_REPO_H 1
/* status for script */
#define SCRIPT_STATUS_INSTALLED 1
#define SCRIPT_STATUS_HELD 2
#define SCRIPT_STATUS_RUNNING 4
#define SCRIPT_STATUS_NEW_VERSION 8
struct t_repo_script
{
char *name; /* script name */
char *name_with_extension; /* script name with extension */
int language; /* language index */
char *author; /* author */
char *mail; /* author's mail */
char *version; /* plugin version */
char *license; /* license */
char *description; /* description */
char *tags; /* comma-separated list of tags */
char *requirements; /* requirements */
char *min_weechat; /* min WeeChat version */
char *max_weechat; /* max WeeChat version */
char *md5sum; /* md5sum of script content */
char *url; /* URL to download script */
int popularity; /* >0 for popular scripts only */
time_t date_added; /* date added */
time_t date_updated; /* date updated */
int status; /* installed/running/new version */
char *version_loaded; /* version of script loaded */
int displayed; /* script displayed? */
int install_order; /* order for install script (if >0)*/
struct t_repo_script *prev_script; /* link to previous script */
struct t_repo_script *next_script; /* link to next script */
};
extern struct t_repo_script *repo_scripts;
extern struct t_repo_script *last_repo_script;
extern int script_repo_count, script_repo_count_displayed;
struct t_hashtable *script_repo_max_length_field;
extern char *script_repo_filter;
extern int script_repo_script_valid (struct t_repo_script *script);
extern struct t_repo_script *script_repo_search_displayed_by_number (int number);
extern struct t_repo_script *script_repo_search_by_name (const char *name);
extern struct t_repo_script *script_repo_search_by_name_ext (const char *name_with_extension);
extern const char *script_repo_get_status_for_display (struct t_repo_script *script,
const char *list,
int collapse);
extern void script_repo_remove_all ();
extern void script_repo_update_status (struct t_repo_script *script);
extern void script_repo_update_status_all ();
extern int script_repo_file_exists ();
extern int script_repo_file_is_uptodate ();
extern int script_repo_file_read (int quiet);
extern void script_repo_file_update (int quiet);
extern void script_repo_filter_scripts (const char *search);
extern struct t_hdata *script_repo_hdata_script_cb (void *data,
const char *hdata_name);
extern int script_repo_add_to_infolist (struct t_infolist *infolist,
struct t_repo_script *script);
extern void script_repo_print_log ();
#endif /* __WEECHAT_SCRIPT_REPO_H */
+292
View File
@@ -0,0 +1,292 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* script.c: scripts manager for WeeChat
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <libgen.h>
#include "../weechat-plugin.h"
#include "script.h"
#include "script-buffer.h"
#include "script-command.h"
#include "script-completion.h"
#include "script-config.h"
#include "script-info.h"
#include "script-repo.h"
WEECHAT_PLUGIN_NAME(SCRIPT_PLUGIN_NAME);
WEECHAT_PLUGIN_DESCRIPTION(N_("Scripts manager"));
WEECHAT_PLUGIN_AUTHOR("Sebastien Helleu <flashcode@flashtux.org>");
WEECHAT_PLUGIN_VERSION(WEECHAT_VERSION);
WEECHAT_PLUGIN_LICENSE(WEECHAT_LICENSE);
struct t_weechat_plugin *weechat_script_plugin = NULL;
char *script_language[] = { "guile", "lua", "perl", "python", "ruby", "tcl", NULL };
char *script_extension[] = { "scm", "lua", "pl", "py", "rb", "tcl", NULL };
struct t_hashtable *script_loaded = NULL;
struct t_hook *script_timer_refresh = NULL;
/*
* script_language_search: search language and return index
* return -1 if not found
*/
int
script_language_search (const char *language)
{
int i;
for (i = 0; script_language[i]; i++)
{
if (strcmp (script_language[i], language) == 0)
return i;
}
/* language not found */
return -1;
}
/*
* script_language_search_by_extension: search language by extension and return
* index
* return -1 if not found
*/
int
script_language_search_by_extension (const char *extension)
{
int i;
for (i = 0; script_extension[i]; i++)
{
if (strcmp (script_extension[i], extension) == 0)
return i;
}
/* extension not found */
return -1;
}
/*
* script_get_loaded_scripts: get loaded scripts (in hashtable)
*/
void
script_get_loaded_scripts ()
{
int i;
char hdata_name[128], *filename, *ptr_base_name;
const char *ptr_filename;
struct t_hdata *hdata;
void *ptr_script;
if (!script_loaded)
{
script_loaded = weechat_hashtable_new (16,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
}
else
weechat_hashtable_remove_all (script_loaded);
for (i = 0; script_language[i]; i++)
{
snprintf (hdata_name, sizeof (hdata_name),
"%s_script", script_language[i]);
hdata = weechat_hdata_get (hdata_name);
ptr_script = weechat_hdata_get_list (hdata, "scripts");
while (ptr_script)
{
ptr_filename = weechat_hdata_string (hdata, ptr_script, "filename");
if (ptr_filename)
{
filename = strdup (ptr_filename);
if (filename)
{
ptr_base_name = basename (filename);
weechat_hashtable_set (script_loaded,
ptr_base_name,
weechat_hdata_string (hdata, ptr_script,
"version"));
free (filename);
}
}
ptr_script = weechat_hdata_move (hdata, ptr_script, 1);
}
}
}
/*
* script_debug_dump_cb: callback for "debug_dump" signal
*/
int
script_debug_dump_cb (void *data, const char *signal, const char *type_data,
void *signal_data)
{
/* make C compiler happy */
(void) data;
(void) signal;
(void) type_data;
if (!signal_data
|| (weechat_strcasecmp ((char *)signal_data, SCRIPT_PLUGIN_NAME) == 0))
{
weechat_log_printf ("");
weechat_log_printf ("***** \"%s\" plugin dump *****",
weechat_plugin->name);
script_repo_print_log ();
weechat_log_printf ("");
weechat_log_printf ("***** End of \"%s\" plugin dump *****",
weechat_plugin->name);
}
return WEECHAT_RC_OK;
}
/*
* script_timer_refresh_cb: callback for timer used to refresh list of scripts
*/
int
script_timer_refresh_cb (void *data, int remaining_calls)
{
/* make C compiler happy */
(void) data;
script_get_loaded_scripts ();
script_repo_update_status_all ();
script_buffer_refresh (0);
if (remaining_calls == 0)
script_timer_refresh = NULL;
return WEECHAT_RC_OK;
}
/*
* script_signal_script_cb: callback for signals "xxx_script_yyy"
* (example: "python_script_loaded")
*/
int
script_signal_script_cb (void *data, const char *signal, const char *type_data,
void *signal_data)
{
/* make C compiler happy */
(void) data;
(void) signal;
(void) type_data;
(void) signal_data;
if (weechat_script_plugin->debug >= 2)
weechat_printf (NULL, "signal: %s, data: %s", signal, (char *)signal_data);
if (!script_timer_refresh)
{
script_timer_refresh = weechat_hook_timer (50, 0, 1,
&script_timer_refresh_cb, NULL);
}
return WEECHAT_RC_OK;
}
/*
* weechat_plugin_init: initialize script plugin
*/
int
weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
{
/* make C compiler happy */
(void) argc;
(void) argv;
weechat_plugin = plugin;
script_buffer_set_callbacks ();
if (!script_config_init ())
return WEECHAT_RC_ERROR;
if (script_config_read () < 0)
return WEECHAT_RC_ERROR;
weechat_mkdir_home (SCRIPT_PLUGIN_NAME, 0755);
script_command_init ();
script_completion_init ();
script_info_init ();
weechat_hook_signal ("debug_dump", &script_debug_dump_cb, NULL);
weechat_hook_signal ("window_scrolled", &script_buffer_window_scrolled_cb, NULL);
weechat_hook_signal ("*_script_*", &script_signal_script_cb, NULL);
if (script_repo_file_exists ())
{
if (!script_repo_file_is_uptodate ())
script_repo_file_update (0);
else
script_repo_file_read (0);
}
if (script_buffer)
script_buffer_refresh (1);
return WEECHAT_RC_OK;
}
/*
* weechat_plugin_end: end script plugin
*/
int
weechat_plugin_end (struct t_weechat_plugin *plugin)
{
/* make C compiler happy */
(void) plugin;
script_config_write ();
script_repo_remove_all ();
if (script_repo_filter)
free (script_repo_filter);
if (script_loaded)
weechat_hashtable_free (script_loaded);
script_config_free ();
return WEECHAT_RC_OK;
}
+37
View File
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_SCRIPT_H
#define __WEECHAT_SCRIPT_H 1
#define weechat_plugin weechat_script_plugin
#define SCRIPT_PLUGIN_NAME "script"
extern struct t_weechat_plugin *weechat_script_plugin;
extern char *script_language[];
extern char *script_extension[];
extern struct t_hashtable *script_loaded;
extern int script_language_search (const char *language);
extern int script_language_search_by_extension (const char *extension);
extern void script_actions_add (const char *action);
extern void script_get_loaded_scripts ();
#endif /* __WEECHAT_SCRIPT_H */