Created
February 17, 2014 23:55
-
-
Save nicholasf/9061767 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#A simple, one server, multiple channels IRC bridge. | |
defprotocol Speaker do | |
def speak(spoon_response, device) | |
end | |
defmodule Bridge.IRC do | |
use GenServer.Behaviour | |
@moduledoc false | |
defimpl Speaker, for: SpoonResponse do | |
def speak(spoon_response, socket) do | |
IO.puts('ok') | |
IO.puts(spoon_response.msg) | |
IO.inspect(socket) | |
Bridge.IRC.say(socket, spoon_response.msg) | |
end | |
end | |
def run(vocab) do | |
{ :ok, config } = :application.get_env(:spoonbot, :conf) | |
{ server, port, nickname } = Enum.at(config, 0) | |
{ :ok, socket } = :gen_tcp.connect(:erlang.binary_to_list(server), port, [:binary, {:active, false}]) | |
:ok = transmit(socket, "NICK #{nickname}") | |
:ok = transmit(socket, "USER #{nickname} #{server} spoonbot :spoonbot") | |
do_listen(socket, vocab) | |
end | |
def do_listen(socket, vocab) do | |
ping = ~r/\APING/ | |
motd_end = ~r/\/MOTD/ | |
msg = ~r/PRIVMSG spoonbot/ | |
case :gen_tcp.recv(socket, 0) do | |
{ :ok, data } -> | |
IO.puts "#{data}" | |
if Regex.match?(motd_end, data), do: join(socket) | |
if Regex.match?(ping, data), do: pong(socket, data) | |
if Regex.match?(msg, data) do | |
matched_command = Enum.find(vocab, fn(command) -> Regex.match?(command.pattern, data) end) | |
IO.puts "ok .... " | |
Speaker.speak(matched_command.cmd(data), socket) | |
end | |
do_listen(socket, vocab) | |
{ :error, :closed } -> | |
IO.puts "The client closed the connection..." | |
end | |
end | |
def transmit(socket, msg) do | |
IO.puts "sending #{msg}" | |
:gen_tcp.send(socket, "#{msg} \r\n") | |
end | |
#needs to become channel aware | |
def say(socket, data) do | |
pieces = String.split(data, ":") | |
phrase = Enum.drop(pieces, 2) | |
IO.puts("Saying: #{phrase}") | |
transmit(socket, "PRIVMSG #cbt :#{phrase}") | |
end | |
def join(socket) do | |
{ :ok, config} = :application.get_env(:spoonbot, :conf ) | |
channel_list = Enum.at(config, 1) | |
joiner = fn | |
{ channel } -> transmit(socket, "JOIN #{ channel }") | |
{ channel, password } -> transmit(socket, "JOIN #{ channel } #{ password }") | |
end | |
Enum.each(channel_list, joiner) | |
end | |
def pong(socket, data) do | |
server = Enum.at(Regex.split(~r/\s/, data), 1) | |
transmit(socket, "PONG #{ server }") | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment