Skip to content

Commit

Permalink
One can now PART a channel using existing API :P Also added functiona…
Browse files Browse the repository at this point in the history
…lity to track topics in a channel
  • Loading branch information
mazenharake committed Apr 14, 2010
1 parent a50ab75 commit 75aa9f2
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 12 deletions.
3 changes: 3 additions & 0 deletions include/eirc.hrl
Expand Up @@ -45,6 +45,7 @@
-define(PRIVMSG(Nick, Msg), ?CMD(["PRIVMSG ",Nick," :",Msg])).
-define(NOTICE(Nick, Msg), ?CMD(["NOTICE ",Nick," :",Msg])).
-define(JOIN(Chan, Key), ?CMD(["JOIN ",Chan," ",Key])).
-define(PART(Chan), ?CMD(["PART ",Chan])).
-define(QUIT(Msg), ?CMD(["QUIT :",Msg])).

%% CTCP Responses
Expand All @@ -62,6 +63,8 @@
-define(RPL_ISUPPORT, "005"). %% Defacto standard for server support
-define(RPL_BOUNCE, "010"). %% Defacto replacement of "005" in RFC2812

-define(RPL_TOPIC, "332").

-define(ERR_NONICKNAMEGIVEN, "431").
-define(ERR_ERRONEUSNICKNAME, "432").
-define(ERR_NICKNAMEINUSE, "433").
Expand Down
10 changes: 8 additions & 2 deletions src/eirc.erl
Expand Up @@ -68,6 +68,9 @@ join(Client, Channel) ->
join(Client, Channel, Key) ->
eirc_cl:join(Client, Channel, Key).

part(Client, Channel) ->
eirc_cl:part(Client, Channel).

quit(Client, QuitMsg) ->
eirc_cl:quit(Client, QuitMsg).

Expand All @@ -77,8 +80,11 @@ is_logged_on(Client) ->
channels(Client) ->
eirc_cl:channels(Client).

chan_users(Client, ChanName) ->
eirc_cl:chan_users(Client, ChanName).
chan_users(Client, Channel) ->
eirc_cl:chan_users(Client, Channel).

chan_topic(Client, Channel) ->
eirc_cl:chan_topic(Client, Channel).

%% =============================================================================
%% Internal Functions
Expand Down
18 changes: 12 additions & 6 deletions src/eirc_chan.erl
Expand Up @@ -62,7 +62,6 @@ set_topic(Struct, ChanName, Topic) ->
Channel = gb_trees:get(Name, Struct),
gb_trees:enter(Name, Channel#chan{ topic = Topic }, Struct).


%% =============================================================================
%% Users JOIN/PART/AKAs(namechange)
%% =============================================================================
Expand Down Expand Up @@ -109,14 +108,21 @@ channels(Struct) ->
[ ChanName || {ChanName, _Chan} <- gb_trees:to_list(Struct) ].

chan_users(Struct, ChanName) ->
Name = normalize(ChanName),
case gb_trees:lookup(Name, Struct) of
{value, Channel} -> Channel#chan.users;
none -> {error, no_such_channel}
end.
get_attr(Struct, ChanName, fun(#chan{ users = Users }) -> Users end).

chan_topic(Struct, ChanName) ->
get_attr(Struct, ChanName, fun(#chan{ topic = Topic }) -> Topic end).


%% =============================================================================
%% Internal functions
%% =============================================================================
normalize(ChanName) -> string:to_lower(ChanName).

get_attr(Struct, ChanName, Fun) ->
Name = normalize(ChanName),
case gb_trees:lookup(Name, Struct) of
{value, Channel} -> Fun(Channel);
none -> {error, no_such_channel}
end.

39 changes: 35 additions & 4 deletions src/eirc_cl.erl
Expand Up @@ -54,6 +54,9 @@ cmd(Client, RawCmd) ->
join(Client, Channel, Key) ->
gen_server:call(Client, {join, Channel, Key}, infinity).

part(Client, Channel) ->
gen_server:call(Client, {part, Channel}, infinity).

quit(Client, QuitMsg) ->
gen_server:call(Client, {quit, QuitMsg}, infinity).

Expand All @@ -63,8 +66,11 @@ is_logged_on(Client) ->
channels(Client) ->
gen_server:call(Client, channels).

chan_users(Client, ChanName) ->
gen_server:call(Client, {chan_users, ChanName}).
chan_users(Client, Channel) ->
gen_server:call(Client, {chan_users, Channel}).

chan_topic(Client, Channel) ->
gen_server:call(Client, {chan_topic, Channel}).

%% =============================================================================
%% Behaviour callback API
Expand Down Expand Up @@ -112,6 +118,10 @@ handle_call({join, Channel, Key}, _From, State) ->
gen_tcp:send(State#state.socket, ?JOIN(Channel, Key)),
{reply, ok, State};

handle_call({part, Channel}, _From, State) ->
gen_tcp:send(State#state.socket, ?PART(Channel)),
{reply, ok, State};

handle_call({cmd, RawCmd}, _From, State) ->
gen_tcp:send(State#state.socket, ?CMD(RawCmd)),
{reply, ok, State};
Expand All @@ -122,8 +132,11 @@ handle_call(is_logged_on, _From, State) ->
handle_call(channels, _From, State) ->
{reply, eirc_chan:channels(State#state.channels), State};

handle_call({chan_users, ChanName}, _From, State) ->
{reply, eirc_chan:chan_users(State#state.channels, ChanName), State};
handle_call({chan_users, Channel}, _From, State) ->
{reply, eirc_chan:chan_users(State#state.channels, Channel), State};

handle_call({chan_topic, Channel}, _From, State) ->
{reply, eirc_chan:chan_topic(State#state.channels, Channel), State};

handle_call(_, _, State) ->
{reply, ok, State}.
Expand Down Expand Up @@ -184,6 +197,24 @@ handle_data(#ircmsg{ nick = Nick, cmd = "JOIN" } = Msg,
Channels = eirc_chan:join(State#state.channels, hd(Msg#ircmsg.args)),
{noreply, State#state{ channels = Channels }};

%% Topic message on join
handle_data(#ircmsg{ cmd = ?RPL_TOPIC } = Msg, State) ->
case Msg#ircmsg.args of
[_MyNick, Channel, Topic] ->
%% Not RFC compliant but _very_ common
ok;
[Channel, Topic] ->
%% RFC expected response
ok
end,
Channels = eirc_chan:set_topic(State#state.channels, Channel, Topic),
{noreply, State#state{ channels = Channels }};

%% Topic message while in channel
handle_data(#ircmsg{ cmd = "TOPIC", args = [Channel, Topic] }, State) ->
Channels = eirc_chan:set_topic(State#state.channels, Channel, Topic),
{noreply, State#state{ channels = Channels }};

%% We left a channel
handle_data(#ircmsg{ nick = Nick, cmd = "PART" } = Msg,
#state{ nick = Nick } = State) ->
Expand Down

0 comments on commit 75aa9f2

Please sign in to comment.