1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-11-03 19:37:16 -05:00

Merge pull request #1598 from profanity-im/feature/global-plugins

Improve plugins user experience
This commit is contained in:
Michael Vetter 2021-09-29 19:29:47 +02:00 committed by GitHub
commit b72801a0e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 112 deletions

View File

@ -7,8 +7,6 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([src/config.h])
AM_INIT_AUTOMAKE([foreign subdir-objects])
# TODO Introduce with Ruby plugins, see https://github.com/profanity-im/profanity/issues/779
#AX_PREFIX_CONFIG_H([src/prof_config.h], [PROF], [src/config.h])
### Checks for programs.
AC_PROG_CC
@ -96,6 +94,9 @@ elif test "x$enable_python_plugins" != xno; then
fi
fi
AS_IF([test "x$PLATFORM" = xosx], [rm -f Python.framework])
# set path to look for global python plugins
GLOBAL_PYTHON_PLUGINS_PATH='${pkgdatadir}/plugins'
AC_SUBST(GLOBAL_PYTHON_PLUGINS_PATH)
else
AM_CONDITIONAL([BUILD_PYTHON_API], [false])
fi
@ -119,6 +120,9 @@ else
[AC_MSG_ERROR([dl library needed to run C plugins])],
[AM_CONDITIONAL([BUILD_C_API], [false])])
])])
# set path to look for global c plugins
GLOBAL_C_PLUGINS_PATH='${pkglibdir}/plugins'
AC_SUBST(GLOBAL_C_PLUGINS_PATH)
else
AM_CONDITIONAL([BUILD_C_API], [false])
fi
@ -360,7 +364,7 @@ AS_IF([test "x$PLATFORM" = xosx],
[AM_CFLAGS="$AM_CFLAGS -Qunused-arguments"])
AM_LDFLAGS="$AM_LDFLAGS -export-dynamic"
AM_CPPFLAGS="$AM_CPPFLAGS $glib_CFLAGS $gio_CFLAGS $curl_CFLAGS $libnotify_CFLAGS $PYTHON_CPPFLAGS ${GTK_CFLAGS} ${SQLITE_CFLAGS}"
AM_CPPFLAGS="$AM_CPPFLAGS -DTHEMES_PATH=\"\\\"$THEMES_PATH\\\"\" -DICONS_PATH=\"\\\"$ICONS_PATH\\\"\""
AM_CPPFLAGS="$AM_CPPFLAGS -DTHEMES_PATH=\"\\\"$THEMES_PATH\\\"\" -DICONS_PATH=\"\\\"$ICONS_PATH\\\"\" -DGLOBAL_PYTHON_PLUGINS_PATH=\"\\\"$GLOBAL_PYTHON_PLUGINS_PATH\\\"\" -DGLOBAL_C_PLUGINS_PATH=\"\\\"$GLOBAL_C_PLUGINS_PATH\\\"\""
LIBS="$glib_LIBS $gio_LIBS $curl_LIBS $libnotify_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_LDFLAGS ${GTK_LIBS} ${SQLITE_LIBS} $LIBS"
AC_SUBST(AM_LDFLAGS)
@ -374,14 +378,16 @@ AC_CONFIG_FILES([Makefile])
AC_OUTPUT
echo ""
echo "PLATFORM : $host_os"
echo "PACKAGE_STATUS : $PACKAGE_STATUS"
echo "AM_CFLAGS : $AM_CFLAGS"
echo "AM_CPPFLAGS : $AM_CPPFLAGS"
echo "AM_LDFLAGS : $AM_LDFLAGS"
echo "LIBS : $LIBS"
echo "Install themes : $THEMES_INSTALL"
echo "Themes path : $THEMES_PATH"
echo "Icons path : $ICONS_PATH"
echo "PLATFORM : $host_os"
echo "PACKAGE_STATUS : $PACKAGE_STATUS"
echo "AM_CFLAGS : $AM_CFLAGS"
echo "AM_CPPFLAGS : $AM_CPPFLAGS"
echo "AM_LDFLAGS : $AM_LDFLAGS"
echo "LIBS : $LIBS"
echo "Install themes : $THEMES_INSTALL"
echo "Themes path : $THEMES_PATH"
echo "Icons path : $ICONS_PATH"
echo "Global Python plugins path : $GLOBAL_PYTHON_PLUGINS_PATH"
echo "Global C plugins path : $GLOBAL_C_PLUGINS_PATH"
echo ""
echo "Now you can run \`make' to build profanity"

View File

@ -242,7 +242,6 @@ static Autocomplete console_ac;
static Autocomplete console_msg_ac;
static Autocomplete autoping_ac;
static Autocomplete plugins_ac;
static Autocomplete plugins_sourcepath_ac;
static Autocomplete plugins_load_ac;
static Autocomplete plugins_unload_ac;
static Autocomplete plugins_reload_ac;
@ -940,11 +939,6 @@ cmd_ac_init(void)
autocomplete_add(plugins_ac, "unload");
autocomplete_add(plugins_ac, "reload");
autocomplete_add(plugins_ac, "python_version");
autocomplete_add(plugins_ac, "sourcepath");
plugins_sourcepath_ac = autocomplete_new();
autocomplete_add(plugins_sourcepath_ac, "set");
autocomplete_add(plugins_sourcepath_ac, "clear");
filepath_ac = autocomplete_new();
@ -1355,7 +1349,6 @@ cmd_ac_reset(ProfWin* window)
autocomplete_reset(console_msg_ac);
autocomplete_reset(autoping_ac);
autocomplete_reset(plugins_ac);
autocomplete_reset(plugins_sourcepath_ac);
autocomplete_reset(blocked_ac);
autocomplete_reset(tray_ac);
autocomplete_reset(presence_ac);
@ -2638,21 +2631,10 @@ _plugins_autocomplete(ProfWin* window, const char* const input, gboolean previou
{
char* result = NULL;
if (strncmp(input, "/plugins sourcepath set ", 24) == 0) {
return cmd_ac_complete_filepath(input, "/plugins sourcepath set", previous);
}
if (strncmp(input, "/plugins install ", 17) == 0) {
return cmd_ac_complete_filepath(input, "/plugins install", previous);
}
if (strncmp(input, "/plugins sourcepath ", 20) == 0) {
result = autocomplete_param_with_ac(input, "/plugins sourcepath", plugins_sourcepath_ac, TRUE, previous);
if (result) {
return result;
}
}
if (strncmp(input, "/plugins load ", 14) == 0) {
if (plugins_load_ac == NULL) {
plugins_load_ac = autocomplete_new();

View File

@ -2136,7 +2136,6 @@ static struct cmd_t command_defs[] = {
{ "/plugins",
parse_args, 0, 3, NULL,
CMD_SUBFUNCS(
{ "sourcepath", cmd_plugins_sourcepath },
{ "install", cmd_plugins_install },
{ "uninstall", cmd_plugins_uninstall },
{ "update", cmd_plugins_update },
@ -2148,8 +2147,6 @@ static struct cmd_t command_defs[] = {
CMD_NOTAGS
CMD_SYN(
"/plugins",
"/plugins sourcepath set <path>",
"/plugins sourcepath clear",
"/plugins install [<path>]",
"/plugins uninstall [<plugin>]",
"/plugins update [<path>]",
@ -2158,19 +2155,16 @@ static struct cmd_t command_defs[] = {
"/plugins reload [<plugin>]",
"/plugins python_version")
CMD_DESC(
"Manage plugins. Passing no arguments lists currently loaded plugins.")
"Manage plugins. Passing no arguments lists currently loaded plugins and global plugins which are available for local installation. Global directory for Python plugins is " GLOBAL_PYTHON_PLUGINS_PATH " and for C Plugins is " GLOBAL_C_PLUGINS_PATH ".")
CMD_ARGS(
{ "sourcepath set <path>", "Set the default path to install plugins from, will be used if no arg is passed to /plugins install." },
{ "sourcepath clear", "Clear the default plugins source path." },
{ "install [<path>]", "Install a plugin, or all plugins found in a directory (recursive). Passing no argument will use the sourcepath if one is set." },
{ "install [<path>]", "Install a plugin, or all plugins found in a directory (recursive). And loads it/them." },
{ "uninstall [<plugin>]", "Uninstall a plugin." },
{ "update [<path>]", "Updates an installed plugin" },
{ "load [<plugin>]", "Load a plugin that already exists in the plugin directory, passing no argument loads all found plugins." },
{ "load [<plugin>]", "Load a plugin that already exists in the plugin directory, passing no argument loads all found plugins. It will be loaded upon next start too unless unloaded." },
{ "unload [<plugin>]", "Unload a loaded plugin, passing no argument will unload all plugins." },
{ "reload [<plugin>]", "Reload a plugin, passing no argument will reload all plugins." },
{ "python_version", "Show the Python interpreter version." })
CMD_EXAMPLES(
"/plugins sourcepath set /home/meee/projects/profanity-plugins",
"/plugins install",
"/plugins install /home/steveharris/Downloads/metal.py",
"/plugins update /home/steveharris/Downloads/metal.py",

View File

@ -6924,66 +6924,34 @@ cmd_receipts(ProfWin* window, const char* const command, gchar** args)
return TRUE;
}
gboolean
cmd_plugins_sourcepath(ProfWin* window, const char* const command, gchar** args)
{
if (args[1] == NULL) {
char* sourcepath = prefs_get_string(PREF_PLUGINS_SOURCEPATH);
if (sourcepath) {
cons_show("Current plugins sourcepath: %s", sourcepath);
g_free(sourcepath);
} else {
cons_show("Plugins sourcepath not currently set.");
}
return TRUE;
}
if (g_strcmp0(args[1], "clear") == 0) {
prefs_set_string(PREF_PLUGINS_SOURCEPATH, NULL);
cons_show("Plugins sourcepath cleared.");
return TRUE;
}
if (g_strcmp0(args[1], "set") == 0) {
if (args[2] == NULL) {
cons_bad_cmd_usage(command);
return TRUE;
}
char* path = get_expanded_path(args[2]);
if (!is_dir(path)) {
cons_show("Plugins sourcepath must be a directory.");
free(path);
return TRUE;
}
cons_show("Setting plugins sourcepath: %s", path);
prefs_set_string(PREF_PLUGINS_SOURCEPATH, path);
free(path);
return TRUE;
}
cons_bad_cmd_usage(command);
return TRUE;
}
gboolean
cmd_plugins_install(ProfWin* window, const char* const command, gchar** args)
{
char* path;
char* path = NULL;
if (args[1] == NULL) {
char* sourcepath = prefs_get_string(PREF_PLUGINS_SOURCEPATH);
if (sourcepath) {
path = strdup(sourcepath);
g_free(sourcepath);
cons_show("Please provide a path to the plugin file or directory, see /help plugins");
return TRUE;
}
// take whole path or build it in case it's just the plugin name
if (strchr(args[1], '/')) {
path = get_expanded_path(args[1]);
} else {
if (g_str_has_suffix(args[1], ".py")) {
path = g_strdup_printf("%s/%s", GLOBAL_PYTHON_PLUGINS_PATH, args[1]);
} else if (g_str_has_suffix(args[1], ".so")) {
path = g_strdup_printf("%s/%s", GLOBAL_C_PLUGINS_PATH, args[1]);
} else {
cons_show("Either a path must be provided or the sourcepath property must be set, see /help plugins");
cons_show("Plugins must have one of the following extensions: '.py' '.so'");
return TRUE;
}
} else {
path = get_expanded_path(args[1]);
}
if (access(path, R_OK) != 0) {
cons_show("Cannot access: %s", path);
free(path);
return TRUE;
}
if (is_regular_file(path)) {
@ -6997,7 +6965,7 @@ cmd_plugins_install(ProfWin* window, const char* const command, gchar** args)
gchar* plugin_name = g_path_get_basename(path);
gboolean result = plugins_install(plugin_name, path, error_message);
if (result) {
cons_show("Plugin installed: %s", plugin_name);
cons_show("Plugin installed and loaded: %s", plugin_name);
} else {
cons_show("Failed to install plugin: %s. %s", plugin_name, error_message->str);
}
@ -7010,7 +6978,7 @@ cmd_plugins_install(ProfWin* window, const char* const command, gchar** args)
if (result->installed || result->failed) {
if (result->installed) {
cons_show("");
cons_show("Installed plugins:");
cons_show("Installed and loaded plugins:");
GSList* curr = result->installed;
while (curr) {
cons_show(" %s", curr->data);
@ -7046,14 +7014,8 @@ cmd_plugins_update(ProfWin* window, const char* const command, gchar** args)
char* path;
if (args[1] == NULL) {
char* sourcepath = prefs_get_string(PREF_PLUGINS_SOURCEPATH);
if (sourcepath) {
path = strdup(sourcepath);
g_free(sourcepath);
} else {
cons_show("Either a path must be provided or the sourcepath property must be set, see /help plugins");
return TRUE;
}
cons_show("Please provide a path to the plugin file, see /help plugins");
return TRUE;
} else {
path = get_expanded_path(args[1]);
}
@ -7092,13 +7054,8 @@ cmd_plugins_update(ProfWin* window, const char* const command, gchar** args)
return TRUE;
}
if (is_dir(path)) {
free(path);
return FALSE;
}
free(path);
cons_show("Argument must be a file or directory.");
cons_show("Argument must be a file.");
return TRUE;
}
@ -7210,6 +7167,42 @@ cmd_plugins_python_version(ProfWin* window, const char* const command, gchar** a
gboolean
cmd_plugins(ProfWin* window, const char* const command, gchar** args)
{
GDir* global_pyp_dir = NULL;
GDir* global_cp_dir = NULL;
if (access(GLOBAL_PYTHON_PLUGINS_PATH, R_OK) == 0) {
GError* error = NULL;
global_pyp_dir = g_dir_open(GLOBAL_PYTHON_PLUGINS_PATH, 0, &error);
if (error) {
log_warning("Error when trying to open global plugins path: %s", GLOBAL_PYTHON_PLUGINS_PATH);
g_error_free(error);
return TRUE;
}
}
if (access(GLOBAL_C_PLUGINS_PATH, R_OK) == 0) {
GError* error = NULL;
global_cp_dir = g_dir_open(GLOBAL_C_PLUGINS_PATH, 0, &error);
if (error) {
log_warning("Error when trying to open global plugins path: %s", GLOBAL_C_PLUGINS_PATH);
g_error_free(error);
return TRUE;
}
}
if (global_pyp_dir) {
const gchar *filename;
cons_show("The following Python plugins are available globally and can be installed:");
while ((filename = g_dir_read_name(global_pyp_dir))) {
cons_show(" %s", filename);
}
}
if (global_cp_dir) {
const gchar *filename;
cons_show("The following C plugins are available globally and can be installed:");
while ((filename = g_dir_read_name(global_cp_dir))) {
cons_show(" %s", filename);
}
}
GList* plugins = plugins_loaded_list();
if (plugins == NULL) {
cons_show("No plugins installed.");

View File

@ -214,6 +214,11 @@ _prefs_load(void)
}
}
// 0.12 started to remove `sourcepath`
if (g_key_file_has_key(prefs, PREF_GROUP_PLUGINS, "sourcepath", NULL)) {
g_key_file_remove_key(prefs, PREF_GROUP_PLUGINS, "sourcepath", NULL);
}
_save_prefs();
boolean_choice_ac = autocomplete_new();
@ -1928,8 +1933,6 @@ _get_group(preference_t pref)
case PREF_BOOKMARK_INVITE:
case PREF_ROOM_LIST_CACHE:
return PREF_GROUP_MUC;
case PREF_PLUGINS_SOURCEPATH:
return PREF_GROUP_PLUGINS;
case PREF_OMEMO_LOG:
case PREF_OMEMO_POLICY:
case PREF_OMEMO_TRUST_MODE:
@ -2163,8 +2166,6 @@ _get_key(preference_t pref)
return "color.occupants.nick";
case PREF_BOOKMARK_INVITE:
return "bookmark.invite";
case PREF_PLUGINS_SOURCEPATH:
return "sourcepath";
case PREF_ROOM_LIST_CACHE:
return "rooms.cache";
case PREF_STATUSBAR_SHOW_NAME:

View File

@ -157,7 +157,6 @@ typedef enum {
PREF_ROSTER_COLOR_NICK,
PREF_OCCUPANTS_COLOR_NICK,
PREF_BOOKMARK_INVITE,
PREF_PLUGINS_SOURCEPATH,
PREF_ROOM_LIST_CACHE,
PREF_STATUSBAR_SHOW_NAME,
PREF_STATUSBAR_SHOW_NUMBER,