%%%---------------------------------------------------------------------- %%% File : mod_discolist.erl %%% Author : Badlop %%% Purpose : Module to list nested links to external services in Discovery %%% Created : %%% Id : 0.1 %%%---------------------------------------------------------------------- %%% ---------------------------------------------------------------------- %%% Example configuration for ejabberd.cfg: %{modules, % [ % ... % {mod_discolist, [{lists, [ % {"servers.localhost", "List of Jabber servers", [ % {"jabber.org", "Jabber.org (USA)"}, % {"amessage.de", "Amessage.de (Germany)"}, % {"jabber.eu.org", "More european servers"} % ]}, % {"chats.localhost", "List of other Chat services", [ % {"conference.jabber.org", "Jabber.org (multilanguage)"}, % {"conference.jabber.ru", "Jabber.ru (russian)"} % ]} % ]} % ]}, % ... % ]}. %%% ---------------------------------------------------------------------- -module(mod_discolist). -author(''). -vsn(''). -behaviour(gen_mod). -export([start/2, init/1, stop/1, process_iq_disco_items/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(PROCNAME, ejabberd_mod_discolist). start(Host, Opts) -> Lists = gen_mod:get_opt(lists, Opts, no_lists), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, init, [Lists])). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc ! stop, {wait, Proc}. init(no_lists) -> ok; init(Lists) -> register_links(Lists), loop(Lists). register_links([{JID,_Name,_}|T]) -> ejabberd_router:register_route(JID), register_links(T); register_links([]) -> ok. unregister_links([{JID,_,_}|T]) -> ejabberd_router:unregister_route(JID), unregister_links(T); unregister_links([]) -> ok. get_name([{"to", Data}|_T]) -> Data; get_name([_|T]) -> get_name(T). get_domain(Name, [{Name, Desc, List}|_T]) -> {Desc, List}; get_domain(Name, [_|T]) -> get_domain(Name, T). do_route(Lists, From, To, Packet) -> {xmlelement, Name, Attrs, _Els} = Packet, case Name of "iq" -> Domain_data = get_domain(get_name(Attrs), Lists), case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], iq_disco_info(Domain_data)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ -> spawn(?MODULE, process_iq_disco_items, [Domain_data, From, To, IQ]); #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)) end end. loop(Lists) -> receive {route, From, To, Packet} -> case catch do_route(Lists, From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, loop(Lists); stop -> unregister_links(Lists), ok; _ -> loop(Lists) end. iq_disco_info({Name, _}) -> [{xmlelement, "identity", [{"category", "services"}, {"type", "jabber"}, {"name", Name}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}]. process_iq_disco_items(Domain_data, From, To, #iq{lang = Lang} = IQ) -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], iq_disco_items(Domain_data, From, Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)). iq_disco_items({_Desc, List}, _From, _Lang) -> lists:map( fun({JID, Name}) -> {xmlelement, "item", [{"jid", JID}, {"name", Name}], []} end, List). iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_discolist"}]}, {xmlelement, "URL", [], [{xmlcdata, "http://ejabberd.jabberstudio.org/"}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "Disco-list module for ejabberd\n" "Copyright (c) 2003-2005 Alexey Shchepin")}]}].