1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-12-04 14:46:46 -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_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_HEADERS([src/config.h])
AM_INIT_AUTOMAKE([foreign subdir-objects]) 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. ### Checks for programs.
AC_PROG_CC AC_PROG_CC
@ -96,6 +94,9 @@ elif test "x$enable_python_plugins" != xno; then
fi fi
fi fi
AS_IF([test "x$PLATFORM" = xosx], [rm -f Python.framework]) 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 else
AM_CONDITIONAL([BUILD_PYTHON_API], [false]) AM_CONDITIONAL([BUILD_PYTHON_API], [false])
fi fi
@ -119,6 +120,9 @@ else
[AC_MSG_ERROR([dl library needed to run C plugins])], [AC_MSG_ERROR([dl library needed to run C plugins])],
[AM_CONDITIONAL([BUILD_C_API], [false])]) [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 else
AM_CONDITIONAL([BUILD_C_API], [false]) AM_CONDITIONAL([BUILD_C_API], [false])
fi fi
@ -360,7 +364,7 @@ AS_IF([test "x$PLATFORM" = xosx],
[AM_CFLAGS="$AM_CFLAGS -Qunused-arguments"]) [AM_CFLAGS="$AM_CFLAGS -Qunused-arguments"])
AM_LDFLAGS="$AM_LDFLAGS -export-dynamic" 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 $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" 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) AC_SUBST(AM_LDFLAGS)
@ -374,14 +378,16 @@ AC_CONFIG_FILES([Makefile])
AC_OUTPUT AC_OUTPUT
echo "" echo ""
echo "PLATFORM : $host_os" echo "PLATFORM : $host_os"
echo "PACKAGE_STATUS : $PACKAGE_STATUS" echo "PACKAGE_STATUS : $PACKAGE_STATUS"
echo "AM_CFLAGS : $AM_CFLAGS" echo "AM_CFLAGS : $AM_CFLAGS"
echo "AM_CPPFLAGS : $AM_CPPFLAGS" echo "AM_CPPFLAGS : $AM_CPPFLAGS"
echo "AM_LDFLAGS : $AM_LDFLAGS" echo "AM_LDFLAGS : $AM_LDFLAGS"
echo "LIBS : $LIBS" echo "LIBS : $LIBS"
echo "Install themes : $THEMES_INSTALL" echo "Install themes : $THEMES_INSTALL"
echo "Themes path : $THEMES_PATH" echo "Themes path : $THEMES_PATH"
echo "Icons path : $ICONS_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 ""
echo "Now you can run \`make' to build profanity" 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 console_msg_ac;
static Autocomplete autoping_ac; static Autocomplete autoping_ac;
static Autocomplete plugins_ac; static Autocomplete plugins_ac;
static Autocomplete plugins_sourcepath_ac;
static Autocomplete plugins_load_ac; static Autocomplete plugins_load_ac;
static Autocomplete plugins_unload_ac; static Autocomplete plugins_unload_ac;
static Autocomplete plugins_reload_ac; static Autocomplete plugins_reload_ac;
@ -940,11 +939,6 @@ cmd_ac_init(void)
autocomplete_add(plugins_ac, "unload"); autocomplete_add(plugins_ac, "unload");
autocomplete_add(plugins_ac, "reload"); autocomplete_add(plugins_ac, "reload");
autocomplete_add(plugins_ac, "python_version"); 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(); filepath_ac = autocomplete_new();
@ -1355,7 +1349,6 @@ cmd_ac_reset(ProfWin* window)
autocomplete_reset(console_msg_ac); autocomplete_reset(console_msg_ac);
autocomplete_reset(autoping_ac); autocomplete_reset(autoping_ac);
autocomplete_reset(plugins_ac); autocomplete_reset(plugins_ac);
autocomplete_reset(plugins_sourcepath_ac);
autocomplete_reset(blocked_ac); autocomplete_reset(blocked_ac);
autocomplete_reset(tray_ac); autocomplete_reset(tray_ac);
autocomplete_reset(presence_ac); autocomplete_reset(presence_ac);
@ -2638,21 +2631,10 @@ _plugins_autocomplete(ProfWin* window, const char* const input, gboolean previou
{ {
char* result = NULL; 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) { if (strncmp(input, "/plugins install ", 17) == 0) {
return cmd_ac_complete_filepath(input, "/plugins install", previous); 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 (strncmp(input, "/plugins load ", 14) == 0) {
if (plugins_load_ac == NULL) { if (plugins_load_ac == NULL) {
plugins_load_ac = autocomplete_new(); plugins_load_ac = autocomplete_new();

View File

@ -2136,7 +2136,6 @@ static struct cmd_t command_defs[] = {
{ "/plugins", { "/plugins",
parse_args, 0, 3, NULL, parse_args, 0, 3, NULL,
CMD_SUBFUNCS( CMD_SUBFUNCS(
{ "sourcepath", cmd_plugins_sourcepath },
{ "install", cmd_plugins_install }, { "install", cmd_plugins_install },
{ "uninstall", cmd_plugins_uninstall }, { "uninstall", cmd_plugins_uninstall },
{ "update", cmd_plugins_update }, { "update", cmd_plugins_update },
@ -2148,8 +2147,6 @@ static struct cmd_t command_defs[] = {
CMD_NOTAGS CMD_NOTAGS
CMD_SYN( CMD_SYN(
"/plugins", "/plugins",
"/plugins sourcepath set <path>",
"/plugins sourcepath clear",
"/plugins install [<path>]", "/plugins install [<path>]",
"/plugins uninstall [<plugin>]", "/plugins uninstall [<plugin>]",
"/plugins update [<path>]", "/plugins update [<path>]",
@ -2158,19 +2155,16 @@ static struct cmd_t command_defs[] = {
"/plugins reload [<plugin>]", "/plugins reload [<plugin>]",
"/plugins python_version") "/plugins python_version")
CMD_DESC( 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( CMD_ARGS(
{ "sourcepath set <path>", "Set the default path to install plugins from, will be used if no arg is passed to /plugins install." }, { "install [<path>]", "Install a plugin, or all plugins found in a directory (recursive). And loads it/them." },
{ "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." },
{ "uninstall [<plugin>]", "Uninstall a plugin." }, { "uninstall [<plugin>]", "Uninstall a plugin." },
{ "update [<path>]", "Updates an installed 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." }, { "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." }, { "reload [<plugin>]", "Reload a plugin, passing no argument will reload all plugins." },
{ "python_version", "Show the Python interpreter version." }) { "python_version", "Show the Python interpreter version." })
CMD_EXAMPLES( CMD_EXAMPLES(
"/plugins sourcepath set /home/meee/projects/profanity-plugins",
"/plugins install", "/plugins install",
"/plugins install /home/steveharris/Downloads/metal.py", "/plugins install /home/steveharris/Downloads/metal.py",
"/plugins update /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; 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 gboolean
cmd_plugins_install(ProfWin* window, const char* const command, gchar** args) cmd_plugins_install(ProfWin* window, const char* const command, gchar** args)
{ {
char* path; char* path = NULL;
if (args[1] == NULL) { if (args[1] == NULL) {
char* sourcepath = prefs_get_string(PREF_PLUGINS_SOURCEPATH); cons_show("Please provide a path to the plugin file or directory, see /help plugins");
if (sourcepath) { return TRUE;
path = strdup(sourcepath); }
g_free(sourcepath);
// 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 { } 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; 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)) { 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); gchar* plugin_name = g_path_get_basename(path);
gboolean result = plugins_install(plugin_name, path, error_message); gboolean result = plugins_install(plugin_name, path, error_message);
if (result) { if (result) {
cons_show("Plugin installed: %s", plugin_name); cons_show("Plugin installed and loaded: %s", plugin_name);
} else { } else {
cons_show("Failed to install plugin: %s. %s", plugin_name, error_message->str); 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 || result->failed) {
if (result->installed) { if (result->installed) {
cons_show(""); cons_show("");
cons_show("Installed plugins:"); cons_show("Installed and loaded plugins:");
GSList* curr = result->installed; GSList* curr = result->installed;
while (curr) { while (curr) {
cons_show(" %s", curr->data); cons_show(" %s", curr->data);
@ -7046,14 +7014,8 @@ cmd_plugins_update(ProfWin* window, const char* const command, gchar** args)
char* path; char* path;
if (args[1] == NULL) { if (args[1] == NULL) {
char* sourcepath = prefs_get_string(PREF_PLUGINS_SOURCEPATH); cons_show("Please provide a path to the plugin file, see /help plugins");
if (sourcepath) { return TRUE;
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;
}
} else { } else {
path = get_expanded_path(args[1]); path = get_expanded_path(args[1]);
} }
@ -7092,13 +7054,8 @@ cmd_plugins_update(ProfWin* window, const char* const command, gchar** args)
return TRUE; return TRUE;
} }
if (is_dir(path)) {
free(path);
return FALSE;
}
free(path); free(path);
cons_show("Argument must be a file or directory."); cons_show("Argument must be a file.");
return TRUE; return TRUE;
} }
@ -7210,6 +7167,42 @@ cmd_plugins_python_version(ProfWin* window, const char* const command, gchar** a
gboolean gboolean
cmd_plugins(ProfWin* window, const char* const command, gchar** args) 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(); GList* plugins = plugins_loaded_list();
if (plugins == NULL) { if (plugins == NULL) {
cons_show("No plugins installed."); 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(); _save_prefs();
boolean_choice_ac = autocomplete_new(); boolean_choice_ac = autocomplete_new();
@ -1928,8 +1933,6 @@ _get_group(preference_t pref)
case PREF_BOOKMARK_INVITE: case PREF_BOOKMARK_INVITE:
case PREF_ROOM_LIST_CACHE: case PREF_ROOM_LIST_CACHE:
return PREF_GROUP_MUC; return PREF_GROUP_MUC;
case PREF_PLUGINS_SOURCEPATH:
return PREF_GROUP_PLUGINS;
case PREF_OMEMO_LOG: case PREF_OMEMO_LOG:
case PREF_OMEMO_POLICY: case PREF_OMEMO_POLICY:
case PREF_OMEMO_TRUST_MODE: case PREF_OMEMO_TRUST_MODE:
@ -2163,8 +2166,6 @@ _get_key(preference_t pref)
return "color.occupants.nick"; return "color.occupants.nick";
case PREF_BOOKMARK_INVITE: case PREF_BOOKMARK_INVITE:
return "bookmark.invite"; return "bookmark.invite";
case PREF_PLUGINS_SOURCEPATH:
return "sourcepath";
case PREF_ROOM_LIST_CACHE: case PREF_ROOM_LIST_CACHE:
return "rooms.cache"; return "rooms.cache";
case PREF_STATUSBAR_SHOW_NAME: case PREF_STATUSBAR_SHOW_NAME:

View File

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