From 3d451b3dc69d91b04c1153f63436b63940287b13 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 5 Oct 2010 03:34:02 +0200 Subject: Sending work now, too --- src/core/CMakeLists.txt | 1 + src/core/ephraim_account.erl | 12 +++--- src/core/ephraim_account_event_proxy.erl | 6 +-- src/core/ephraim_accounts.erl | 2 +- src/core/ephraim_conv.erl | 69 ++++++++++++-------------------- src/core/ephraim_conv_handler.erl | 25 +++++++++--- src/core/ephraim_conv_man.erl | 6 +-- src/core/ephraim_event_proxy.erl | 27 +++++++++++++ src/core/ephraim_roster.erl | 47 +++++++++++----------- src/gui/CoreConnector.vala | 31 ++++++-------- src/gui/Ephraim.vala | 12 +++--- 11 files changed, 129 insertions(+), 109 deletions(-) create mode 100644 src/core/ephraim_event_proxy.erl diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 97c7d4e..75055bb 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -8,6 +8,7 @@ erl_target(ephraim-core ephraim_conv.erl ephraim_conv_handler.erl ephraim_conv_man.erl + ephraim_event_proxy.erl ephraim_gui.erl ephraim_roster.erl ephraim_roster_handler.erl diff --git a/src/core/ephraim_account.erl b/src/core/ephraim_account.erl index 8024d68..2e95f88 100644 --- a/src/core/ephraim_account.erl +++ b/src/core/ephraim_account.erl @@ -1,18 +1,18 @@ -module(ephraim_account). -behaviour(supervisor). --export([start_link/0]). +-export([start_link/1]). -export([init/1]). -start_link() -> +start_link(Account) -> {ok, Pid} = supervisor:start_link(?MODULE, []), {ok, EventManager} = supervisor:start_child(Pid, {event_man, {gen_event, start_link, []}, permanent, 1000, worker, [gen_event]}), - ephraim_account_event_proxy:start(EventManager), - - {ok, _} = supervisor:start_child(Pid, {conv_man, {ephraim_conv_man, start_link, [EventManager]}, permanent, 1000, supervisor, [ephraim_conv_man]}), + ephraim_event_proxy:start(Account, EventManager), + ephraim_account_event_proxy:start(Account, EventManager), {ok, Connection} = supervisor:start_child(Pid, {connection, {ephraim_conn, start_link, [EventManager]}, permanent, 10000, worker, [ephraim_conn]}), - {ok, _} = supervisor:start_child(Pid, {roster, {ephraim_roster, start_link, [EventManager, Connection]}, permanent, 1000, worker, [ephraim_roster]}), + {ok, Roster} = supervisor:start_child(Pid, {roster, {ephraim_roster, start_link, [EventManager, Connection]}, permanent, 1000, worker, [ephraim_roster]}), + {ok, _} = supervisor:start_child(Pid, {conv_man, {ephraim_conv_man, start_link, [EventManager, Connection, Roster]}, permanent, 1000, supervisor, [ephraim_conv_man]}), {ok, Pid}. init(_Args) -> diff --git a/src/core/ephraim_account_event_proxy.erl b/src/core/ephraim_account_event_proxy.erl index d9cf94e..726b0e0 100644 --- a/src/core/ephraim_account_event_proxy.erl +++ b/src/core/ephraim_account_event_proxy.erl @@ -1,11 +1,11 @@ -module(ephraim_account_event_proxy). -behaviour(gen_event). --export([start/1]). +-export([start/2]). -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). -start(EventManager) -> - gen_event:add_handler(EventManager, ?MODULE, foo_account). +start(Account, EventManager) -> + gen_event:add_handler(EventManager, ?MODULE, Account). init(Account) -> {ok, Account}. diff --git a/src/core/ephraim_accounts.erl b/src/core/ephraim_accounts.erl index a35c486..d3a3694 100644 --- a/src/core/ephraim_accounts.erl +++ b/src/core/ephraim_accounts.erl @@ -8,4 +8,4 @@ start_link() -> init(_Args) -> {ok, {{one_for_one, 1, 60}, - [{account, {ephraim_account, start_link, []}, permanent, infinity, supervisor, [ephraim_account]}]}}. + [{account, {ephraim_account, start_link, [foo_account]}, permanent, infinity, supervisor, [ephraim_account]}]}}. diff --git a/src/core/ephraim_conv.erl b/src/core/ephraim_conv.erl index d9431b2..d6ab742 100644 --- a/src/core/ephraim_conv.erl +++ b/src/core/ephraim_conv.erl @@ -1,39 +1,53 @@ -module(ephraim_conv). -behaviour(gen_server). --export([start_link/2]). +-export([start_link/4]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --export([received_message/4]). +-export([received_message/4, send_message/3]). -record(conv_state, { - conv_ref :: reference(), event_manager :: pid(), + connection :: pid(), + roster :: pid(), my_jid :: binary(), jid :: binary() }). --spec start_link(pid(), binary()) -> ok. -start_link(EventManager, JID) -> - ConvRef = make_ref(), - io:format("Starting conversation ~p with ~p~n", [ConvRef, JID]), - - gen_event:notify(EventManager, {view_update, {conversation, ConvRef, {new, JID}}}), +-spec start_link(pid(), pid(), pid(), binary()) -> ok. +start_link(EventManager, Conn, Roster, JID) -> + gen_event:notify(EventManager, {view_update, {conversation, JID, new}}), {jid,MyJID} = ephraim_config:get(jid), - gen_server:start_link(?MODULE, #conv_state{conv_ref=ConvRef,event_manager=EventManager,my_jid=list_to_binary(MyJID),jid=JID}, []). + gen_server:start_link(?MODULE, #conv_state{event_manager=EventManager,connection=Conn,roster=Roster,my_jid=list_to_binary(MyJID),jid=JID}, []). init(State) -> process_flag(trap_exit, true), + io:format("Starting conversation ~p with ~p~n", [self(), State#conv_state.jid]), + {ok, State}. received_message(Conv, From, Type, Body) -> gen_server:cast(Conv, {received_message, From, Type, Body}). +send_message(Conv, Type, Body) -> + gen_server:cast(Conv, {send_message, Type, Body}). handle_call(_Msg, _From, State) -> {noreply, State}. +update_view(State, From, Type, Body) -> + Alias = ephraim_roster:get_alias(State#conv_state.roster, From), + gen_event:notify(State#conv_state.event_manager, {view_update, {conversation, State#conv_state.jid, {message, Alias, Type, Body}}}). + handle_cast({received_message, From, Type, Body}, State) -> - gen_event:notify(State#conv_state.event_manager, {view_update, {conversation, State#conv_state.conv_ref, {message, From, Type, Body}}}), + update_view(State, From, Type, Body), + {noreply, State}; +handle_cast({send_message, Type, Body}, State) -> + Packet = exmpp_message:normal(Body), + Packet2 = exmpp_message:set_type(Packet, Type), + Packet3 = exmpp_xml:set_attribute(Packet2, to, State#conv_state.jid), + ephraim_conn:send_packet(State#conv_state.connection, Packet3), + + update_view(State, State#conv_state.my_jid, Type, Body), {noreply, State}; handle_cast(_Msg, State) -> {noreply, State}. @@ -41,38 +55,7 @@ handle_cast(_Msg, State) -> handle_info(_Msg, State) -> {ok, State}. terminate(_Reason, State) -> - io:format("Stopping conversation ~p with ~p~n", [State#conv_state.conv_ref, State#conv_state.jid]), + io:format("Stopping conversation ~p with ~p~n", [self(), State#conv_state.jid]), ok. code_change(_OldVersion, State, _Extra) -> {ok, State}. - - --spec loop(#conv_state{}) -> ok. -loop(State) -> - receive - stop -> - ok; - - {receive_message, Packet} -> - Type = exmpp_message:get_type(Packet), - Body = exmpp_message:get_body(Packet), - if - Body =/= undefined -> - ephraim ! {ui_update, {chat_message, State#conv_state.jid, Type, ephraim:get_alias(State#conv_state.jid), Body}}; - true -> - io:format("Received strange message from ~p:~n~p~n", [State#conv_state.jid, Packet]) - end, - loop(State); - - {send_message, Type, Message} -> - Packet = exmpp_message:normal(Message), - Packet2 = exmpp_message:set_type(Packet, Type), - Packet3 = exmpp_xml:set_attribute(Packet2, to, State#conv_state.jid), - ephraim ! {send_packet, Packet3}, - ephraim ! {ui_update, {chat_message, State#conv_state.jid, Type, ephraim:get_alias(State#conv_state.my_jid), Message}}, - loop(State); - - Msg -> - io:format("ephraim_conv (~p): ~p~n", [State#conv_state.jid, Msg]), - loop(State) - end. diff --git a/src/core/ephraim_conv_handler.erl b/src/core/ephraim_conv_handler.erl index e525d99..681e53a 100644 --- a/src/core/ephraim_conv_handler.erl +++ b/src/core/ephraim_conv_handler.erl @@ -1,20 +1,21 @@ -module(ephraim_conv_handler). -include_lib("exmpp/include/exmpp_client.hrl"). -behaviour(gen_event). --export([start/2]). +-export([start/4]). -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). -record(conv_handler_state, { supervisor :: pid(), event_manager :: pid(), + connection :: pid(), + roster :: pid(), convs = dict:new() :: dict() }). -start(Supervisor, EventManager) -> - gen_event:add_handler(EventManager, ?MODULE, {Supervisor, EventManager}). +start(Supervisor, EventManager, Conn, Roster) -> + gen_event:add_handler(EventManager, ?MODULE, #conv_handler_state{supervisor=Supervisor,event_manager=EventManager,connection=Conn,roster=Roster}). -init({Supervisor, EventManager}) -> - State = #conv_handler_state{supervisor=Supervisor,event_manager=EventManager}, +init(State) -> {ok, State}. -spec get_conv(#conv_handler_state{},exmpp_jid:jid()) -> {#conv_handler_state{},pid()|undefined}. @@ -32,12 +33,24 @@ get_conv(State, JID) -> {State, Conv}; error -> {ok, Conv} = supervisor:start_child(State#conv_handler_state.supervisor, - {Key, {ephraim_conv, start_link, [State#conv_handler_state.event_manager, JID]}, transient, 1000, worker, [ephraim_conv]}), + {Key, {ephraim_conv, start_link, [State#conv_handler_state.event_manager, + State#conv_handler_state.connection, State#conv_handler_state.roster, + JID]}, + transient, 1000, worker, [ephraim_conv]}), Dict = dict:store(Key, Conv, State#conv_handler_state.convs), {State#conv_handler_state{convs=Dict}, Conv} end end. +handle_event({view_request, {conversation,JID,new}}, State) -> + {NewState, _} = get_conv(State, JID), + {ok, NewState}; + +handle_event({view_request, {conversation,JID,{send_message,Type,Body}}}, State) -> + {NewState, Conv} = get_conv(State, JID), + ephraim_conv:send_message(Conv, Type, Body), + {ok, NewState}; + handle_event({received_packet, #received_packet{packet_type=message, raw_packet=Packet}}, State) -> From = exmpp_xml:get_attribute(Packet, from, <<"unknown">>), Type = exmpp_message:get_type(Packet), diff --git a/src/core/ephraim_conv_man.erl b/src/core/ephraim_conv_man.erl index 617ccc4..adfa24d 100644 --- a/src/core/ephraim_conv_man.erl +++ b/src/core/ephraim_conv_man.erl @@ -1,11 +1,11 @@ -module(ephraim_conv_man). -behaviour(supervisor). --export([start_link/1]). +-export([start_link/3]). -export([init/1]). -start_link(EventManager) -> +start_link(EventManager, Conn, Roster) -> {ok, Pid} = supervisor:start_link(?MODULE, []), - ephraim_conv_handler:start(Pid, EventManager), + ephraim_conv_handler:start(Pid, EventManager, Conn, Roster), {ok, Pid}. init(_Args) -> diff --git a/src/core/ephraim_event_proxy.erl b/src/core/ephraim_event_proxy.erl new file mode 100644 index 0000000..4b0e35b --- /dev/null +++ b/src/core/ephraim_event_proxy.erl @@ -0,0 +1,27 @@ +-module(ephraim_event_proxy). +-behaviour(gen_event). + +-export([start/2]). +-export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). + +start(Account, EventManager) -> + gen_event:add_handler(ephraim_event_man, ?MODULE, {Account, EventManager}). + +init(State) -> + {ok, State}. + +handle_event({view_request, {account, Account, Event}}, {Account, EventManager}) -> + gen_event:notify(EventManager, {view_request, Event}), + {ok, {Account, EventManager}}; + +handle_event(_Event, State) -> + {ok, State}. + +handle_call(_Msg, State) -> + {noreply, State}. +handle_info(_Msg, State) -> + {ok, State}. +terminate(_Reason, _State) -> + ok. +code_change(_OldVersion, State, _Extra) -> + {ok, State}. diff --git a/src/core/ephraim_roster.erl b/src/core/ephraim_roster.erl index 605d019..6c6a229 100644 --- a/src/core/ephraim_roster.erl +++ b/src/core/ephraim_roster.erl @@ -4,7 +4,7 @@ -export([start_link/2]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --export([presence/2, roster_iq/2, vcard_iq/3]). +-export([presence/2, roster_iq/2, vcard_iq/3, get_alias/2]). -record(roster_state, { event_manager :: pid(), @@ -176,27 +176,9 @@ handleVCardIQs(VCard, [Item|Rest]) -> VCard2 = handleVCardIQ(VCard, Item), handleVCardIQs(VCard2, Rest). --spec get_alias(#roster_state{}, binary()) -> binary(). +-spec get_alias(pid(), binary()) -> binary(). get_alias(Roster, JID) -> - {Node, Domain, _Resource} = exmpp_jid:to_lower(exmpp_jid:parse(JID)), - BareJID = list_to_binary([Node, <<"@">>, Domain]), - - case dict:find(BareJID, Roster#roster_state.entries) of - {ok, Entry} -> - case Entry#roster_entry.name of - undefined -> - case dict:find('NICKNAME', Entry#roster_entry.vcard) of - {ok, Value} -> - Value; - error -> - Node - end; - Name -> - Name - end; - error -> - Node - end. + gen_server:call(Roster, {get_alias,JID}). presence(Roster, Packet) -> gen_server:cast(Roster, {presence, Packet}). @@ -205,8 +187,27 @@ roster_iq(Roster, Payload) -> vcard_iq(Roster, From, Payload) -> gen_server:cast(Roster, {vcard_iq, From, Payload}). -handle_call(_Msg, _From, State) -> - {noreply, State}. +handle_call({get_alias,JID}, _From, State) -> + {Node, Domain, _Resource} = exmpp_jid:to_lower(exmpp_jid:parse(JID)), + BareJID = list_to_binary([Node, <<"@">>, Domain]), + + Result = case dict:find(BareJID, State#roster_state.entries) of + {ok, Entry} -> + case Entry#roster_entry.name of + undefined -> + case dict:find('NICKNAME', Entry#roster_entry.vcard) of + {ok, Value} -> + Value; + error -> + Node + end; + Name -> + Name + end; + error -> + Node + end, + {reply, Result, State}. handle_cast({presence, Packet}, State) -> %io:format("ephraim_roster: Presence: ~p~n", [Packet]), diff --git a/src/gui/CoreConnector.vala b/src/gui/CoreConnector.vala index 46c94f2..9159c49 100644 --- a/src/gui/CoreConnector.vala +++ b/src/gui/CoreConnector.vala @@ -12,16 +12,16 @@ public class CoreConnector { match_roster_update = Eva.parse("{account,Account,{roster_update,JID,Name,Subscription,Groups,Resources,Avatar}}"); match_resource_entry = Eva.parse("{Name,{resource_entry,Priority,Show,Status}}"); match_avatar = Eva.parse("{avatar,Data}"); - match_conversation = Eva.parse("{account,Account,{conversation,Ref,Message}}"); - match_conversation_new = Eva.parse("{new,JID}"); + match_conversation = Eva.parse("{account,Account,{conversation,JID,Message}}"); + match_conversation_new = Eva.parse("new"); match_conversation_message = Eva.parse("{message,From,Type,Body}"); } Eva.PacketHandler con; public signal void update_contact(Contact contact); - public signal void new_conversation(Eva.Ref conv_ref, string jid); - public signal void chat_message(Eva.Ref conv_ref, string from, string type, string message); + public signal void new_conversation(string jid); + public signal void chat_message(string jid, string from, string type, string message); public void start() { con = new Eva.PacketHandler(new UnixInputStream(3, true), new UnixOutputStream(4, true), 4); @@ -178,11 +178,13 @@ public class CoreConnector { update_contact(contact); } else if((match = term.match(match_conversation)) != null) { - Eva.Ref conv_ref = match["Ref"] as Eva.Ref; - if(conv_ref == null) { + Eva.Binary jid_term = match["JID"] as Eva.Binary; + if(jid_term == null) { warn_if_reached(); return; } + string jid = from_utf8(jid_term); + Eva.Term message_term = match["Message"]; if(message_term == null) { warn_if_reached(); @@ -191,14 +193,7 @@ public class CoreConnector { Gee.Map cmatch; if((cmatch = message_term.match(match_conversation_new)) != null) { - Eva.Binary jid_term = cmatch["JID"] as Eva.Binary; - if(jid_term == null) { - warn_if_reached(); - return; - } - - string jid = from_utf8(jid_term); - new_conversation(conv_ref, jid); + new_conversation(jid); } else if((cmatch = message_term.match(match_conversation_message)) != null) { Eva.Binary from_term = cmatch["From"] as Eva.Binary; @@ -221,8 +216,8 @@ public class CoreConnector { return; } string body = from_utf8(body_term); - - chat_message(conv_ref, from, type, body); + + chat_message(jid, from, type, body); } else { stdout.printf("Received unhandled term: %s\n", term.to_string()); @@ -235,12 +230,12 @@ public class CoreConnector { public void start_conversation(string jid) { char[] jid_utf8 = jid.to_utf8(); - con.send(Eva.parse("{start_conversation,~w}", new Eva.Binary(jid_utf8))); + con.send(Eva.parse("{account,foo_account,{conversation,~w,new}}", new Eva.Binary(jid_utf8))); } public void send_message(string jid, string type, string message) { char[] jid_utf8 = jid.to_utf8(); char[] message_utf8 = message.to_utf8(); - con.send(Eva.parse("{send_message,~w,~a,~w}", new Eva.Binary(jid_utf8), type, new Eva.Binary(message_utf8))); + con.send(Eva.parse("{account,foo_account,{conversation,~w,{send_message,~a,~w}}}", new Eva.Binary(jid_utf8), type, new Eva.Binary(message_utf8))); } } diff --git a/src/gui/Ephraim.vala b/src/gui/Ephraim.vala index fb5e77f..5ddcd5e 100644 --- a/src/gui/Ephraim.vala +++ b/src/gui/Ephraim.vala @@ -17,7 +17,7 @@ public class Ephraim { unowned Gtk.TreeView rosterView = builder.get_object("Roster") as Gtk.TreeView; - Gee.TreeMap conversations = new Gee.TreeMap(); + Gee.TreeMap conversations = new Gee.TreeMap(); unowned Gtk.Notebook conversationNotebook = builder.get_object("Conversations") as Gtk.Notebook; ContactList roster = new ContactList(rosterView); @@ -28,22 +28,22 @@ public class Ephraim { coreconn.update_contact.connect(roster.update_contact); - coreconn.new_conversation.connect((conv_ref, jid) => { + coreconn.new_conversation.connect((jid) => { Contact contact = roster.get_contact(jid); Conversation conv = new Conversation(conversationNotebook, jid, contact != null ? contact.display_string : null); - conversations[conv_ref] = conv; + conversations[jid] = conv; conv.send_message.connect((type, message) => coreconn.send_message(jid, type, message)); }); - coreconn.chat_message.connect((conv_ref, from, type, message) => { - if(!(conv_ref in conversations.keys)) { + coreconn.chat_message.connect((jid, from, type, message) => { + if(!(jid in conversations.keys)) { warn_if_reached(); return; } - conversations[conv_ref].chat_message(from, type, message); + conversations[jid].chat_message(from, type, message); }); //if(!coreconn.start()) -- cgit v1.2.3