]> source.dussan.org Git - rspamd.git/commitdiff
* New functionality to lua api:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 1 Sep 2009 16:02:31 +0000 (20:02 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 1 Sep 2009 16:02:31 +0000 (20:02 +0400)
- config class
- metric class
- textpart class
* Add documentation for lua module

src/lua/lua_common.c
src/lua/lua_common.h
src/lua/lua_config.c
src/lua/lua_message.c
src/lua/lua_task.c
src/lua/rspamd.luadoc [new file with mode: 0644]

index eb93dce85668f09a8143302ef054862a5df5bedc..66ae67d5852fc8db1b036c497c2da1d51562db39 100644 (file)
@@ -43,7 +43,7 @@ static const struct luaL_reg loggerlib_m[] = {
     {NULL, NULL}
 };
 
-
+/* Util functions */
 void 
 lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func) 
 {
@@ -66,7 +66,8 @@ lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func)
        lua_pop (L, 1);
 }
 
-void lua_setclass (lua_State *L, const char *classname, int objidx) 
+void 
+lua_setclass (lua_State *L, const char *classname, int objidx) 
 {
        luaL_getmetatable (L, classname);
        if (objidx < 0) {
@@ -75,6 +76,15 @@ void lua_setclass (lua_State *L, const char *classname, int objidx)
        lua_setmetatable (L, objidx);
 }
 
+/* assume that table is at the top */
+void 
+lua_set_table_index (lua_State *L, const char *index, const char *value) 
+{
+
+       lua_pushstring (L, index);
+       lua_pushstring (L, value);
+       lua_settable(L, -3);
+}
 
 
 /*** Logger interface ***/
index b72171e99e675c36099deaf61edc2306de203135..6c915241721e0c5c637e4ff0b24836377c504aa0 100644 (file)
 
 void lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func);
 void lua_setclass (lua_State *L, const char *classname, int objidx);
+void lua_set_table_index (lua_State *L, const char *index, const char *value);
 int luaopen_message (lua_State *L);
 int luaopen_task (lua_State *L);
 int luaopen_config (lua_State *L);
+int luaopen_metric (lua_State *L);
 void init_lua_filters (struct config_file *cfg);
 
 int lua_call_filter (const char *function, struct worker_task *task);
index e88e53daf04dec19b650a9b3ead2bd764281ec73..7eb03f871a9b84a8e5bd4b5343b018c95aa915f2 100644 (file)
@@ -37,6 +37,14 @@ static const struct luaL_reg configlib_m[] = {
     {NULL, NULL}
 };
 
+/* Metric methods */
+LUA_FUNCTION_DEF(metric, register_symbol);
+
+static const struct luaL_reg metriclib_m[] = {
+       LUA_INTERFACE_DEF(metric, register_symbol),
+       {NULL, NULL}
+};
+
 static struct config_file *
 lua_check_config (lua_State *L)
 {
@@ -45,6 +53,13 @@ lua_check_config (lua_State *L)
        return (struct config_file *)ud;
 }
 
+static struct metric *
+lua_check_metric (lua_State *L)
+{
+       void *ud = luaL_checkudata (L, 1, "Rspamd.metric");
+       luaL_argcheck (L, ud != NULL, 1, "'metric' expected");
+       return (struct metric *)ud;
+}
 
 /*** Config functions ***/
 static int
@@ -69,6 +84,38 @@ lua_config_get_module_opt (lua_State *L)
     return 1;
 }
 
+static int
+lua_config_get_all_opt (lua_State *L)
+{
+    struct config_file *cfg = lua_check_config (L);
+    const char *mname;
+       GList *cur_opt;
+       struct module_opt *cur;
+
+    if (cfg) {
+        mname = luaL_checkstring (L, 2);
+
+        if (mname) {   
+                       cur_opt = g_hash_table_lookup (cfg->modules_opts, mname);
+                       if (cur_opt == NULL) {
+                               lua_pushnil (L);
+                               return 1;
+                       }
+       
+                       lua_newtable (L);
+                       while (cur_opt) {
+                               cur = cur_opt->data;
+                               lua_set_table_index (L, cur->param, cur->value);
+                               cur_opt = g_list_next (cur_opt);
+                       }
+                       return 1;
+        }
+    }
+    lua_pushnil (L);
+    return 1;
+}
+
+
 static int
 lua_config_get_metric (lua_State *L)
 {
@@ -83,13 +130,60 @@ lua_config_get_metric (lua_State *L)
             pmetric = lua_newuserdata (L, sizeof (struct metric *));
                    lua_setclass (L, "Rspamd.metric", -1);
                    *pmetric = metric;
+                       return 1;
         }
     }
+
     lua_pushnil (L);
     return 1;
     
 }
 
+/*** Metric functions ***/
+
+struct lua_callback_data {
+       const char *name;
+       lua_State *L;
+};
+
+static void
+lua_metric_symbol_callback (struct worker_task *task, gpointer ud)
+{
+       struct lua_callback_data *cd = ud;
+       struct worker_task **ptask;
+
+       lua_getglobal (cd->L, cd->name);
+       ptask = lua_newuserdata (cd->L, sizeof (struct worker_task *));
+       lua_setclass (cd->L, "Rspamd.task", -1);
+       *ptask = task;
+
+       if (lua_pcall(cd->L, 1, 1, 0) != 0) {
+        msg_warn ("lua_metric_symbol_callback: error running function %s: %s",
+                                       cd->name, lua_tostring(cd->L, -1));
+       }
+}
+
+static int
+lua_metric_register_symbol (lua_State *L)
+{
+       struct metric *metric = lua_check_metric (L);
+       const char *name, *callback;
+       double weight;
+       struct lua_callback_data *cd;
+
+       if (metric) {
+               name = luaL_checkstring (L, 2);
+               weight = luaL_checknumber (L, 3);
+               callback = luaL_checkstring (L, 4);
+               if (name) {
+                       cd = g_malloc (sizeof (struct lua_callback_data));
+                       cd->name = g_strdup (name);
+                       register_symbol (&metric->cache, name, weight, lua_metric_symbol_callback, cd);
+               }
+       }
+       return 1;
+}
+
 int
 luaopen_config (lua_State *L)
 {
@@ -99,3 +193,11 @@ luaopen_config (lua_State *L)
     return 1;
 }
 
+int
+luaopen_metric (lua_State *L)
+{
+    lua_newclass (L, "Rspamd.metric", configlib_m);
+       luaL_openlib (L, "metric", configlib_m, 0);
+
+    return 1;
+}
index 499945ccb7c21d0045c4f250f53f35eb95082f2c..b178da0d437d1702436d45ab1951583af31d063f 100644 (file)
@@ -162,6 +162,7 @@ lua_message_set_header (lua_State *L)
        return 1;
 }
 
+
 int
 luaopen_message (lua_State *L)
 {
@@ -170,3 +171,4 @@ luaopen_message (lua_State *L)
     
        return 1;
 }
+
index 2e299126572bc18a58c7791685c8dcd43c6848d2..e3f1e55d6ac21eeb3acc0febe3229df4453d0907 100644 (file)
 
 
 #include "lua_common.h"
+#include "../message.h"
 
 /* Task methods */
 LUA_FUNCTION_DEF(task, get_message);
 LUA_FUNCTION_DEF(task, insert_result);
 LUA_FUNCTION_DEF(task, get_urls);
+LUA_FUNCTION_DEF(task, get_text_parts);
 
 static const struct luaL_reg tasklib_m[] = {
        LUA_INTERFACE_DEF(task, get_message),
        LUA_INTERFACE_DEF(task, insert_result),
        LUA_INTERFACE_DEF(task, get_urls),
+       LUA_INTERFACE_DEF(task, get_text_parts),
        {NULL, NULL}
 };
 
+/* Textpart methods */
+LUA_FUNCTION_DEF(textpart, get_content);
+LUA_FUNCTION_DEF(textpart, is_empty);
+LUA_FUNCTION_DEF(textpart, is_html);
+LUA_FUNCTION_DEF(textpart, get_fuzzy);
+
+static const struct luaL_reg textpartlib_m[] = {
+       LUA_INTERFACE_DEF(textpart, get_content),
+       LUA_INTERFACE_DEF(textpart, is_empty),
+       LUA_INTERFACE_DEF(textpart, is_html),
+       LUA_INTERFACE_DEF(textpart, get_fuzzy),
+       {NULL, NULL}
+};
+
+/* Utility functions */
 static struct worker_task *
 lua_check_task (lua_State *L) 
 {
@@ -45,6 +63,14 @@ lua_check_task (lua_State *L)
        return (struct worker_task *)ud;
 }
 
+static struct mime_text_part *
+lua_check_textpart (lua_State *L)
+{
+       void *ud = luaL_checkudata (L, 1, "Rspamd.textpart");
+       luaL_argcheck (L, ud != NULL, 1, "'textpart' expected");
+       return (struct mime_text_part *)ud;
+}
+
 /*** Task interface    ***/
 static int
 lua_task_get_message (lua_State *L)
@@ -96,7 +122,90 @@ lua_task_get_urls (lua_State *L)
        return 1;
 }
 
+static int
+lua_task_get_text_parts (lua_State *L)
+{
+
+       struct worker_task *task = lua_check_task (L);
+       GList *cur;
+       struct mime_text_part *part, **ppart;
+
+       if (task != NULL) {
+               cur = task->text_parts;
+               while (cur) {
+                       part = cur->data;
+                       ppart = lua_newuserdata (L, sizeof (struct mime_text_part *));
+                       lua_setclass (L, "Rspamd.textpart", -1);
+                       *ppart = part;
+                       cur = g_list_next (cur);
+               }
+       }
+       lua_pushnil (L);
+       return 1;
+}
+
+/**** Textpart implementation *****/
+
+static int
+lua_textpart_get_content (lua_State *L)
+{
+       struct mime_text_part *part = lua_check_textpart (L);
+
+       if (part == NULL || part->is_empty) {
+               lua_pushnil (L);
+               return 1;
+       }
+       
+       lua_pushlstring (L, part->content->data, part->content->len);
+
+       return 1;
+}
+
+static int
+lua_textpart_is_empty (lua_State *L)
+{
+       struct mime_text_part *part = lua_check_textpart (L);
+
+       if (part == NULL) {
+               lua_pushnil (L);
+               return 1;
+       }
+
+       lua_pushboolean (L, part->is_empty);
+
+       return 1;
+}
+
+static int
+lua_textpart_is_html (lua_State *L)
+{
+       struct mime_text_part *part = lua_check_textpart (L);
+
+       if (part == NULL) {
+               lua_pushnil (L);
+               return 1;
+       }
+
+       lua_pushboolean (L, part->is_html);
+
+       return 1;
+}
+
+static int
+lua_textpart_get_fuzzy (lua_State *L)
+{
+       struct mime_text_part *part = lua_check_textpart (L);
 
+       if (part == NULL || part->is_empty) {
+               lua_pushnil (L);
+               return 1;
+       }
+       
+       lua_pushlstring (L, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe));
+       return 1;
+}
+
+/* Init part */
 int
 luaopen_task (lua_State *L)
 {
@@ -106,3 +215,12 @@ luaopen_task (lua_State *L)
        return 1;
 }
 
+int
+luaopen_textpart (lua_State *L)
+{
+       lua_newclass (L, "Rspamd.textpart", textpartlib_m);
+       luaL_openlib (L, "textpart", textpartlib_m, 0);
+    
+       return 1;
+}
+
diff --git a/src/lua/rspamd.luadoc b/src/lua/rspamd.luadoc
new file mode 100644 (file)
index 0000000..b83832a
--- /dev/null
@@ -0,0 +1,100 @@
+--- Rspamd interaction package
+-- contains several subclasses:
+-- config - for parsing config files
+-- metric - for handling metrics callbacks
+-- task - for interaction with task object
+-- message - gate to GMime functions
+-- textpart - a single textual part of message
+module Rspamd
+
+--- Each lua module MUST have init function that is called after config file was read:
+-- it should be like
+-- function module:module_init(cfg)
+
+------------------------------------- CONFIG -----------------------------------------
+--
+--- Get module option from config
+-- @param mname module name
+-- @param option option
+-- @return string with value
+function config:get_module_opt (mname, option)
+
+--- Get all module options as a table like ['param' => 'value']
+-- @param mname module name
+-- @return table with options
+function config:get_all_opt (mname)
+
+--- Get specified metric
+-- @param name metric name
+-- @return metric object
+function config:get_metric (name)
+
+------------------------------------- METRIC -----------------------------------------
+
+--- Register symbol in metric
+-- @param symbol name of symbol
+-- @param weight weight of symbol
+-- @param callback fucntion that would be called as callback for symbol
+function metric:register_symbol (symbol, weight, callback)
+
+------------------------------------- TASK -------------------------------------------
+
+--- Get message object from task
+-- @return message object
+function task:get_message ()
+
+--- Insert result to specified metric with specified weight (obsoleted)
+-- @param metric metric name
+-- @param symbol symbol name
+-- @param weight weight of symbol
+function task:insert_result (metric, symbol, weight)
+
+--- Get all urls as array
+-- @return array of urls in textual form
+function task:get_urls ()
+
+--- Get all text parts
+-- @return array of textpart objects
+function task:get_text_parts ()
+
+------------------------------------- TEXTPART ---------------------------------------
+
+--- Get part's content
+-- @return string that contains part's content
+function textpart:get_content ()
+
+--- Check if part is empty
+-- @return boolean value
+function textpart:is_empty ()
+
+--- Check if part is html
+-- @return boolean value
+function textpart:is_html ()
+
+--- Get part's fuzzy
+-- @return string that contains part's fuzzy
+function textpart:get_fuzzy ()
+
+------------------------------------- MESSAGE ----------------------------------------
+
+--- Get message subject
+-- @return message subject
+function message:get_subject ()
+
+--- Get message id
+-- @return message id
+function message:get_message_id ()
+
+--- Get sender of message
+-- @return sender's credits
+function message:get_sender ()
+
+--- Get reply-to field
+-- @return value of reply-to header
+function message:get_reply_to ()
+
+--- Get header
+-- @param header_name name of header
+-- @return array of headers with specified name
+function message:get_header (header_name)
+