about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2017-02-05 21:09:03 +0000
committerJames Booth <boothj5@gmail.com>2017-02-05 21:09:03 +0000
commit286fecf38d218d10366f025faf7cffcb425e19f4 (patch)
tree331a61f379d7513c8bc9d6db0d852e5fdb0518aa /src
parentc405367dfeb3c23bac192a170501e569be934f26 (diff)
downloadprofani-tty-286fecf38d218d10366f025faf7cffcb425e19f4.tar.gz
Allow installing plugins from directory
Diffstat (limited to 'src')
-rw-r--r--src/command/cmd_funcs.c76
-rw-r--r--src/common.c42
-rw-r--r--src/common.h4
-rw-r--r--src/plugins/plugins.c37
-rw-r--r--src/plugins/plugins.h8
-rw-r--r--src/tools/http_upload.c8
-rw-r--r--src/tools/http_upload.h1
7 files changed, 144 insertions, 32 deletions
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index 7f854249..d26ff43f 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -6214,49 +6214,77 @@ cmd_xa(ProfWin *window, const char *const command, gchar **args)
 gboolean
 cmd_plugins_install(ProfWin *window, const char *const command, gchar **args)
 {
-    char *filename = args[1];
-    if (filename == NULL) {
+    char *path = args[1];
+    if (path == NULL) {
         cons_bad_cmd_usage(command);
         return TRUE;
     }
 
     // expand ~ to $HOME
-    if (filename[0] == '~' && filename[1] == '/') {
-        if (asprintf(&filename, "%s/%s", getenv("HOME"), filename+2) == -1) {
+    if (path[0] == '~' && path[1] == '/') {
+        if (asprintf(&path, "%s/%s", getenv("HOME"), path+2) == -1) {
             return TRUE;
         }
     } else {
-        filename = strdup(filename);
+        path = strdup(path);
     }
 
-    if (access(filename, R_OK) != 0) {
-        cons_show("File not found: %s", filename);
-        free(filename);
+    if (access(path, R_OK) != 0) {
+        cons_show("File not found: %s", path);
+        free(path);
         return TRUE;
     }
 
-    if (!is_regular_file(filename)) {
-        cons_show("Not a file: %s", filename);
-        free(filename);
-        return TRUE;
-    }
+    if (is_regular_file(path)) {
+        if (!g_str_has_suffix(path, ".py") && !g_str_has_suffix(path, ".so")) {
+            cons_show("Plugins must have one of the following extensions: '.py' '.so'");
+            free(path);
+            return TRUE;
+        }
 
-    if (!g_str_has_suffix(filename, ".py") && !g_str_has_suffix(filename, ".so")) {
-        cons_show("Plugins must have one of the following extensions: '.py' '.so'");
-        free(filename);
+        gchar *plugin_name = g_path_get_basename(path);
+        gboolean result = plugins_install(plugin_name, path);
+        if (result) {
+            cons_show("Plugin installed: %s", plugin_name);
+        } else {
+            cons_show("Failed to install plugin: %s", plugin_name);
+        }
+        g_free(plugin_name);
+
+        free(path);
         return TRUE;
     }
 
-    gchar *plugin_name = g_path_get_basename(filename);
-    gboolean result = plugins_install(plugin_name, filename);
-    if (result) {
-        cons_show("Plugin installed: %s", plugin_name);
-    } else {
-        cons_show("Failed to install plugin: %s", plugin_name);
+    if (is_dir(path)) {
+        PluginsInstallResult* result = plugins_install_all(path);
+        if (result->installed || result->failed) {
+            if (result->installed) {
+                cons_show("");
+                cons_show("Installed plugins:");
+                GSList *curr = result->installed;
+                while (curr) {
+                    cons_show("  %s", curr->data);
+                    curr = g_slist_next(curr);
+                }
+            }
+            if (result->failed) {
+                cons_show("");
+                cons_show("Failed installs:");
+                GSList *curr = result->failed;
+                while (curr) {
+                    cons_show("  %s", curr->data);
+                    curr = g_slist_next(curr);
+                }
+            }
+        } else {
+            cons_show("No plugins found in: %s", path);
+        }
+        free(path);
+        plugins_free_install_result(result);
+        return TRUE;
     }
-    g_free(plugin_name);
 
-    free(filename);
+    cons_show("Argument must be a file or directory.");
     return TRUE;
 }
 
diff --git a/src/common.c b/src/common.c
index ef7129cd..898f62fa 100644
--- a/src/common.c
+++ b/src/common.c
@@ -536,3 +536,45 @@ prof_occurrences(const char *const needle, const char *const haystack, int offse
     return *result;
 }
 
+int
+is_regular_file(const char *path)
+{
+    struct stat st;
+    stat(path, &st);
+    return S_ISREG(st.st_mode);
+}
+
+int
+is_dir(const char *path)
+{
+    struct stat st;
+    stat(path, &st);
+    return S_ISDIR(st.st_mode);
+}
+
+void
+get_file_paths_recursive(const char *path, GSList **contents)
+{
+    if (!is_dir(path)) {
+        return;
+    }
+
+    GDir* directory = g_dir_open(path, 0, NULL);
+    const gchar *entry = g_dir_read_name(directory);
+    while (entry) {
+        GString *full = g_string_new(path);
+        if (!g_str_has_suffix(full->str, "/")) {
+            g_string_append(full, "/");
+        }
+        g_string_append(full, entry);
+
+        if (is_dir(full->str)) {
+            get_file_paths_recursive(full->str, contents);
+        } else if (is_regular_file(full->str)) {
+            *contents = g_slist_append(*contents, full->str);
+        }
+
+        g_string_free(full, FALSE);
+        entry = g_dir_read_name(directory);
+    }
+}
diff --git a/src/common.h b/src/common.h
index c2317390..8c42ae52 100644
--- a/src/common.h
+++ b/src/common.h
@@ -123,4 +123,8 @@ gboolean is_notify_enabled(void);
 GSList* prof_occurrences(const char *const needle, const char *const haystack, int offset, gboolean whole_word,
     GSList **result);
 
+int is_regular_file(const char *path);
+int is_dir(const char *path);
+void get_file_paths_recursive(const char *directory, GSList **contents);
+
 #endif
diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c
index 4896fedb..92d605e8 100644
--- a/src/plugins/plugins.c
+++ b/src/plugins/plugins.c
@@ -129,6 +129,43 @@ plugins_init(void)
     return;
 }
 
+void
+plugins_free_install_result(PluginsInstallResult *result)
+{
+    if (!result) {
+        return;
+    }
+    g_slist_free_full(result->installed, free);
+    g_slist_free_full(result->failed, free);
+}
+
+PluginsInstallResult*
+plugins_install_all(const char *const path)
+{
+    PluginsInstallResult *result = malloc(sizeof(PluginsInstallResult));
+    result->installed = NULL;
+    result->failed = NULL;
+    GSList *contents = NULL;
+    get_file_paths_recursive(path, &contents);
+
+    GSList *curr = contents;
+    while (curr) {
+        if (g_str_has_suffix(curr->data, ".py") || g_str_has_suffix(curr->data, ".so")) {
+            gchar *plugin_name = g_path_get_basename(curr->data);
+            if (plugins_install(plugin_name, curr->data)) {
+                result->installed = g_slist_append(result->installed, strdup(curr->data));
+            } else {
+                result->failed = g_slist_append(result->failed, strdup(curr->data));
+            }
+        }
+        curr = g_slist_next(curr);
+    }
+
+    g_slist_free_full(contents, g_free);
+
+    return result;
+}
+
 gboolean
 plugins_install(const char *const plugin_name, const char *const filename)
 {
diff --git a/src/plugins/plugins.h b/src/plugins/plugins.h
index 502af806..af659757 100644
--- a/src/plugins/plugins.h
+++ b/src/plugins/plugins.h
@@ -42,6 +42,11 @@ typedef enum {
     LANG_C
 } lang_t;
 
+typedef struct prof_plugins_install_t {
+    GSList *installed;
+    GSList *failed;
+} PluginsInstallResult;
+
 typedef struct prof_plugin_t {
     char *name;
     lang_t lang;
@@ -107,7 +112,10 @@ char* plugins_autocomplete(const char *const input);
 void plugins_reset_autocomplete(void);
 void plugins_shutdown(void);
 
+void plugins_free_install_result(PluginsInstallResult *result);
+
 gboolean plugins_install(const char *const plugin_name, const char *const filename);
+PluginsInstallResult* plugins_install_all(const char *const path);
 gboolean plugins_load(const char *const name);
 GSList* plugins_load_all(void);
 gboolean plugins_unload(const char *const name);
diff --git a/src/tools/http_upload.c b/src/tools/http_upload.c
index c1ac9fdf..6e5dd27c 100644
--- a/src/tools/http_upload.c
+++ b/src/tools/http_upload.c
@@ -52,6 +52,7 @@
 #include "config/preferences.h"
 #include "ui/ui.h"
 #include "ui/window.h"
+#include "common.h"
 
 #define FALLBACK_MIMETYPE "application/octet-stream"
 #define FALLBACK_CONTENTTYPE_HEADER "Content-Type: application/octet-stream"
@@ -330,10 +331,3 @@ off_t file_size(const char* const filename)
     stat(filename, &st);
     return st.st_size;
 }
-
-int is_regular_file(const char *filename)
-{
-    struct stat st;
-    stat(filename, &st);
-    return S_ISREG(st.st_mode);
-}
diff --git a/src/tools/http_upload.h b/src/tools/http_upload.h
index 15281fa5..ae8f8223 100644
--- a/src/tools/http_upload.h
+++ b/src/tools/http_upload.h
@@ -62,6 +62,5 @@ void* http_file_put(void *userdata);
 
 char* file_mime_type(const char* const file_name);
 off_t file_size(const char* const file_name);
-int is_regular_file(const char *filename);
 
 #endif
7eaca89b84470569e4df3fd'>455fbac6 ^
77d5b5d6 ^
104854ca ^
502d2ea5 ^





e3092e7b ^
f8c0ef3e ^
455fbac6 ^
77d5b5d6 ^
104854ca ^
f8c0ef3e ^
502d2ea5 ^



136412d2 ^
502d2ea5 ^
f8c0ef3e ^


6a0f71b9 ^
455fbac6 ^
77d5b5d6 ^
104854ca ^
6a0f71b9 ^
502d2ea5 ^

6a0f71b9 ^

5e9eff8c ^

455fbac6 ^
77d5b5d6 ^
104854ca ^
5e9eff8c ^
502d2ea5 ^
5e9eff8c ^
bc643692 ^
5e9eff8c ^
104854ca ^
5e9eff8c ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108