summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/ephraim_account.erl12
-rw-r--r--src/core/ephraim_account_event_proxy.erl6
-rw-r--r--src/core/ephraim_accounts.erl2
-rw-r--r--src/core/ephraim_conv.erl69
-rw-r--r--src/core/ephraim_conv_handler.erl25
-rw-r--r--src/core/ephraim_conv_man.erl6
-rw-r--r--src/core/ephraim_event_proxy.erl27
-rw-r--r--src/core/ephraim_roster.erl47
-rw-r--r--src/gui/CoreConnector.vala31
-rw-r--r--src/gui/Ephraim.vala12
11 files changed, 129 insertions, 109 deletions
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<string, Eva.Term> 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<Eva.Ref, Conversation> conversations = new Gee.TreeMap<Eva.Ref, Conversation>();
+ Gee.TreeMap<string, Conversation> conversations = new Gee.TreeMap<string, Conversation>();
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())