Full jid accessor
authorMyhailo Danylenko <isbear@ukrpost.net>
Fri, 27 Feb 2009 00:19:33 +0200
changeset 10 73f4c12b6ffb
parent 9 c2517f8bf647
child 11 f74fff438888
Full jid accessor * full_jid * current_buddy sets * fix memleak in buddy_info
TODO
examples/mcabberrc.lua
examples/xep0030.lua
examples/xep0047.lua
examples/xep0077.lua
examples/xep0146.lua
main.c
--- a/TODO	Thu Feb 26 01:05:02 2009 +0200
+++ b/TODO	Fri Feb 27 00:19:33 2009 +0200
@@ -6,4 +6,6 @@
 mcabber_config_file uses option to set dir?
 do uninitialization of commands and features with objects?
 help system accessors (needs major rewrite and planning)
+object access to roster and buddies
+there are many places with code, that really works only in utf
 
--- a/examples/mcabberrc.lua	Thu Feb 26 01:05:02 2009 +0200
+++ b/examples/mcabberrc.lua	Fri Feb 27 00:19:33 2009 +0200
@@ -115,28 +115,6 @@
 	end
 end
 
--- XXX to C?
-function full_current_jid ()
-	local jid = main.current_buddy ()
-	if jid then
-		local info = main.buddy_info ( jid )
-		local prio, resource = 0
-		for res, par in pairs ( info.resources ) do
-			if prio <= par.priority then
-				resource = res
-				prio = par.priority
-			end
-		end
-		if resource then
-			return jid .. '/' .. resource
-		else
-			return jid
-		end
-	else
-		return nil
-	end
-end
-
 function online ( jid )
 	local info = main.buddy_info ( jid )
 	if not info then
--- a/examples/xep0030.lua	Thu Feb 26 01:05:02 2009 +0200
+++ b/examples/xep0030.lua	Fri Feb 27 00:19:33 2009 +0200
@@ -61,7 +61,7 @@
 			who = args.t
 			args.t = nil
 		else
-			who = full_current_jid ()
+			who = main.full_jid ()
 		end
 		if args[1] == 'items' then
 			local node = nil
--- a/examples/xep0047.lua	Thu Feb 26 01:05:02 2009 +0200
+++ b/examples/xep0047.lua	Fri Feb 27 00:19:33 2009 +0200
@@ -90,8 +90,12 @@
 		return true
 	end )
 
--- You must specify a full jid with resource!
 function send_file ( to, name )
+	if not to then
+		to = main.full_jid ()
+	elseif not to:match ( "/" ) then
+		to = main.full_jid ( to )
+	end
 	local sid = gen_unique_sid ()
 	local conn = lm.connection.bless ( main.connection () )
 	conn:send (
@@ -170,7 +174,7 @@
 				who = args.t
 				args.t = nil
 			else
-				who = full_current_jid ()
+				who = main.full_jid ()
 			end
 			args[1] = nil
 			send_file ( who, rebuild_args_string ( args ) )
--- a/examples/xep0077.lua	Thu Feb 26 01:05:02 2009 +0200
+++ b/examples/xep0077.lua	Fri Feb 27 00:19:33 2009 +0200
@@ -148,7 +148,7 @@
 		if args and args ~= '' then
 			who = args
 		else
-			who = full_current_jid ()
+			who = main.full_jid ()
 		end
 		register_to ( who )
 	end, 'jid' )
@@ -159,7 +159,7 @@
 		if args and args ~= '' then
 			who = args
 		else
-			who = full_current_jid ()
+			who = main.full_jid ()
 		end
 		unregister_from ( who )
 	end, 'jid' )
--- a/examples/xep0146.lua	Thu Feb 26 01:05:02 2009 +0200
+++ b/examples/xep0146.lua	Fri Feb 27 00:19:33 2009 +0200
@@ -46,7 +46,7 @@
 			who = args.t
 			args.t = nil
 		else
-			who = full_current_jid ()
+			who = main.full_jid ()
 		end
 		if args[1] == 'list' or not args[1] then
 			disco_items (
--- a/main.c	Thu Feb 26 01:05:02 2009 +0200
+++ b/main.c	Fri Feb 27 00:19:33 2009 +0200
@@ -220,11 +220,47 @@
 }
 
 /// main.current_buddy
-/// Returns jid of current selected buddy.
-/// R: string
+/// Returns jid of current selected buddy or sets current buddy to buddy with specified jid.
+/// A: string (optional)
+/// R: string (optional)
 static int lua_main_current_buddy (lua_State *L)
 {
-	lua_pushstring (L, buddy_getjid (BUDDATA (current_buddy)));
+	if (lua_gettop (L) > 0) { // Set
+		char *jid = jidtodisp (luaL_checkstring (L, 1));
+		scr_RosterSearch (jid);
+		g_free (jid);
+		return 0;
+	} else { // Get
+		lua_pushstring (L, buddy_getjid (BUDDATA (current_buddy)));
+		return 1;
+	}
+}
+
+/// main.full_jid
+/// Returns full jid (with current resource) of specified buddy (or current, if not specified).
+/// Note, that if there are no resources online, it will return just what it got.
+/// A: string (jid, optional)
+/// R: string (jid)
+static int lua_main_full_jid (lua_State *L)
+{
+	GList *buddy;
+	GSList *resources;
+	GSList *resource;
+	if (lua_gettop (L) > 0)
+		buddy = buddy_search_jid (luaL_checkstring (L, 1));
+	else
+		buddy = current_buddy;
+	if (!buddy)
+		return 0;
+	resources = buddy_getresources (BUDDATA (buddy));
+	if (!resources) {
+		lua_pushstring (L, buddy_getjid (BUDDATA (buddy)));
+		return 1;
+	}
+	lua_pushfstring (L, "%s%c%s", buddy_getjid (BUDDATA (buddy)), JID_RESOURCE_SEPARATOR, g_slist_last(resources)->data);
+	for (resource = resources; resource; resource = g_slist_next (resource))
+		g_free (resource->data);
+	g_slist_free (resources);
 	return 1;
 }
 
@@ -248,6 +284,7 @@
 	lua_pushstring (d->L, buddy_getstatusmsg (d->buddy, resource));
 	lua_settable   (d->L, -3);
 	lua_settable (d->L, -3);
+	g_free (resource);
 }
 
 /// main.buddy_info
@@ -262,6 +299,7 @@
 {
 	char                  *jid   = jidtodisp (luaL_checkstring (L, 1));
 	GSList                *buddy = roster_find (jid, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_AGENT|ROSTER_TYPE_ROOM);
+	GSList                *resources;
 	lua_state_and_buddy_t  snb;
 	g_free (jid);
 
@@ -284,8 +322,10 @@
 	lua_createtable (L, 0, 0);
 	snb.L     = L;
 	snb.buddy = BUDDATA (buddy);
+	resources = buddy_getresources (BUDDATA (buddy));
 	g_slist_foreach (buddy_getresources (BUDDATA (buddy)), (GFunc) lua_buddy_resources_callback, &snb);
-	lua_settable    (L, -3);
+	g_slist_free (resources);
+	lua_settable (L, -3);
 	
 	return 1;
 }
@@ -599,6 +639,27 @@
 	return 0;
 }
 
+// BUDDY
+
+#if 0
+static int lua_buddy_name (lua_State *L)
+{
+	lua_buddy_t *buddy = luaL_checkbuddy (L, 1);
+	if (lua_gettop (L) > 1) { // Set
+		const char *name = luaL_checkstring (L, 2);
+		buddy_setname (buddy->obj, name);
+		return 0;
+	} else { // Get
+		const char *name = buddy_getname (buddy->obj);
+		if (name)
+			lua_pushstring (L, name);
+		else
+			lua_pushnil (L);
+		return 1;
+	}
+}
+#endif
+
 // MAIN INITIALIZATION CODE
 
 #ifdef LLM_LOG_HANDLER
@@ -658,27 +719,71 @@
 		return g_realloc (ptr, nsize);
 }
 
+#define reg(NAME)                   \
+	{ #NAME, lua_main_##NAME },
 static const luaL_Reg lua_reg_main[] = {
-	{ "config_file",   lua_main_config_file   },
-	{ "connection",    lua_main_connection    },
-	{ "log",           lua_main_log           },
-	{ "option",        lua_main_option        },
-	{ "add_feature",   lua_main_add_feature   },
-	{ "del_feature",   lua_main_del_feature   },
-	{ "add_completion",lua_main_add_completion},
-	{ "del_completion",lua_main_del_completion},
-	{ "command",       lua_main_command       },
-	{ "print_info",    lua_main_print_info    },
-	{ "beep",          lua_main_beep          },
-	{ "run",           lua_main_run           },
-	{ "status",        lua_main_status        },
-	{ "roster",        lua_main_roster        },
-	{ "current_buddy", lua_main_current_buddy },
-	{ "buddy_info",    lua_main_buddy_info    },
-	{ "timer",         lua_main_timer         },
-	{ "bgread",        lua_main_bgread        },
-	{ NULL,            NULL                   },
+	reg ( config_file )
+	reg ( connection )
+	reg ( log )
+	reg ( option )
+	reg ( add_feature )
+	reg ( del_feature )
+	reg ( add_completion )
+	reg ( del_completion )
+	reg ( command )
+	reg ( print_info )
+	reg ( beep )
+	reg ( run )
+	reg ( status )
+	reg ( roster )
+	reg ( current_buddy )
+	reg ( full_jid )
+	reg ( buddy_info )
+	reg ( timer )
+	reg ( bgread )
+	{ NULL, NULL },
 };
+#undef reg
+
+#if 0
+#define reg(name)                    \
+	{ #NAME, lua_buddy_##NAME },
+static const luaL_Reg lua_reg_buddy[] = {
+	reg ( jid )
+	reg ( group )
+	reg ( name )
+	reg ( nick )
+	reg ( in_room )
+	reg ( topic )
+	reg ( printstatus )
+	reg ( autowhois )
+	reg ( type )
+	reg ( subscription )
+	reg ( status )
+	reg ( message )
+	reg ( time )
+	reg ( priority )
+	reg ( events )
+	reg ( caps )
+	reg ( role )
+	reg ( realjid )
+	reg ( flags )
+	reg ( onserver )
+	reg ( resources )
+	{ "__gc", lua_buddy_gc },
+	{ NULL,   NULL         },
+};
+#undef reg
+#endif
+
+#if 0
+static const luaL_Reg lua_reg_roster[] = {
+	{ "__index",    lua_roster_index    },
+	{ "__newindex", lua_roster_newindex },
+	{ "__len",      lua_roster_len      },
+	{ NULL,         NULL                },
+};
+#endif
 
 const gchar *g_module_check_init (GModule *module)
 {
@@ -695,6 +800,18 @@
 	lua_register (lua, "dopath", lua_global_dopath);
 	lua_register (lua, "print",  lua_global_print );
 
+#if 0
+	lua_newtable (lua);
+	luaL_newmetatable (lua, "mcabber.roster");
+	luaL_register (lua, NULL, lua_reg_roster);
+	lua_setmetatable (lua, -2);
+	lua_setglobal (lua, "roster");
+
+	lua_newuserdata (lua,1);
+	luaL_newmetatable (lua, "mcabber.buddy");
+	luaL_register (lua, NULL, lua_reg_buddy);
+#endif
+
 	cmd_add ("lua", "", 0, 0, (void (*) (char *p)) do_lua, lua);
 
 #ifdef LLM_LOG_HANDLER