Skip to content
This repository has been archived by the owner on Jun 10, 2018. It is now read-only.

Commit

Permalink
Refactor Hector::Session
Browse files Browse the repository at this point in the history
  • Loading branch information
sstephenson committed Feb 27, 2010
1 parent 0088526 commit d3b1d76
Show file tree
Hide file tree
Showing 20 changed files with 348 additions and 233 deletions.
18 changes: 17 additions & 1 deletion lib/hector.rb
Expand Up @@ -3,7 +3,23 @@
require "socket"

require "hector/errors"
require "hector/authentication"

require "hector/concerns/authentication"
require "hector/concerns/messaging"
require "hector/concerns/presence"

require "hector/commands/join"
require "hector/commands/names"
require "hector/commands/nick"
require "hector/commands/notice"
require "hector/commands/part"
require "hector/commands/ping"
require "hector/commands/privmsg"
require "hector/commands/quit"
require "hector/commands/topic"
require "hector/commands/who"
require "hector/commands/whois"

require "hector/channel"
require "hector/connection"
require "hector/identity"
Expand Down
38 changes: 0 additions & 38 deletions lib/hector/authentication.rb

This file was deleted.

11 changes: 11 additions & 0 deletions lib/hector/commands/join.rb
@@ -0,0 +1,11 @@
module Hector
module Commands
module Join
def on_join
request.args.first.split(",").each do |channel|
Channel.find_or_create(channel).join(self)
end
end
end
end
end
9 changes: 9 additions & 0 deletions lib/hector/commands/names.rb
@@ -0,0 +1,9 @@
module Hector
module Commands
module Names
def on_names
Channel.find(request.args.first).respond_to_names(self)
end
end
end
end
11 changes: 11 additions & 0 deletions lib/hector/commands/nick.rb
@@ -0,0 +1,11 @@
module Hector
module Commands
module Nick
def on_nick
old_nickname = nickname
rename(request.args.first)
broadcast(:nick, nickname, :source => old_nickname)
end
end
end
end
9 changes: 9 additions & 0 deletions lib/hector/commands/notice.rb
@@ -0,0 +1,9 @@
module Hector
module Commands
module Notice
def on_notice
deliver_message_as(:notice)
end
end
end
end
9 changes: 9 additions & 0 deletions lib/hector/commands/part.rb
@@ -0,0 +1,9 @@
module Hector
module Commands
module Part
def on_part
Channel.find(request.args.first).part(self, request.text)
end
end
end
end
9 changes: 9 additions & 0 deletions lib/hector/commands/ping.rb
@@ -0,0 +1,9 @@
module Hector
module Commands
module Ping
def on_ping
respond_with(:pong, :source => "hector.irc", :text => request.text)
end
end
end
end
9 changes: 9 additions & 0 deletions lib/hector/commands/privmsg.rb
@@ -0,0 +1,9 @@
module Hector
module Commands
module Privmsg
def on_privmsg
deliver_message_as(:privmsg)
end
end
end
end
10 changes: 10 additions & 0 deletions lib/hector/commands/quit.rb
@@ -0,0 +1,10 @@
module Hector
module Commands
module Quit
def on_quit
@quit_message = "Quit: #{request.text}"
connection.close_connection
end
end
end
end
15 changes: 15 additions & 0 deletions lib/hector/commands/topic.rb
@@ -0,0 +1,15 @@
module Hector
module Commands
module Topic
def on_topic
channel = Channel.find(request.args.first)

if request.args.length > 1
channel.change_topic(self, request.text)
else
channel.respond_to_topic(self)
end
end
end
end
end
39 changes: 39 additions & 0 deletions lib/hector/commands/who.rb
@@ -0,0 +1,39 @@
module Hector
module Commands
module Who
def on_who
destination = request.args.first

if channel?(destination)
on_channel_who(destination)
else
on_session_who(destination)
end

respond_with("315", destination, :text => "End of /WHO list.")
end

def on_channel_who(channel_name)
if channel = Channel.find(channel_name)
respond_to_who_for(channel_name, channel.sessions)
end
end

def on_session_who(nickname)
if session = Session.find(nickname)
respond_to_who_for("*", [session])
end
end

def respond_to_who_for(destination, sessions)
sessions.each do |session|
respond_with("352", destination, session.who)
end
end

def who
"#{identity.username} hector.irc hector.irc #{nickname} H :0 #{realname}"
end
end
end
end
27 changes: 27 additions & 0 deletions lib/hector/commands/whois.rb
@@ -0,0 +1,27 @@
module Hector
module Commands
module Whois
def on_whois
nickname = request.args.first
if session = Session.find(nickname)
respond_to_whois_for(self.nickname, session)
else
raise NoSuchNickOrChannel, nickname
end
ensure
respond_with("318", self.nickname, nickname, "End of /WHOIS list.")
end

def respond_to_whois_for(destination, session)
respond_with("311", destination, session.nickname, session.whois)
respond_with("319", destination, session.nickname, :text => channels.map { |channel| channel.name }.join(" ")) unless channels.empty?
respond_with("312", destination, session.nickname, "hector.irc", :text => "Hector")
respond_with("317", destination, session.nickname, session.seconds_idle, session.created_at, :text => "seconds idle, signon time")
end

def whois
"#{nickname} #{identity.username} hector.irc * :#{realname}"
end
end
end
end
40 changes: 40 additions & 0 deletions lib/hector/concerns/authentication.rb
@@ -0,0 +1,40 @@
module Hector
module Concerns
module Authentication
def on_user
@username = request.args.first
@realname = request.text
authenticate
end

def on_pass
@password = request.text
authenticate
end

def on_nick
@nickname = request.text
authenticate
end

protected
def authenticate
set_identity
set_session
end

def set_identity
if @username && @password
@identity = Identity.authenticate(@username, @password)
end
end

def set_session
if @identity && @nickname
@session = Session.create(@nickname, self, @identity, @realname)
@session.commence_presence
end
end
end
end
end
36 changes: 36 additions & 0 deletions lib/hector/concerns/messaging.rb
@@ -0,0 +1,36 @@
module Hector
module Concerns
module Messaging
def deliver_message_as(message_type)
destination, text = request.args.first, request.text
touch_presence

if channel?(destination)
on_channel_message(message_type, destination, text)
else
on_session_message(message_type, destination, text)
end
end

def on_channel_message(message_type, channel_name, text)
if channel = Channel.find(channel_name)
if channel.has_session?(self)
channel.broadcast(message_type, channel.name, :source => source, :text => text, :except => self)
else
raise CannotSendToChannel, channel_name
end
else
raise NoSuchNickOrChannel, channel_name
end
end

def on_session_message(message_type, nickname, text)
if session = Session.find(nickname)
session.respond_with(message_type, nickname, :source => source, :text => text)
else
raise NoSuchNickOrChannel, nickname
end
end
end
end
end
59 changes: 59 additions & 0 deletions lib/hector/concerns/presence.rb
@@ -0,0 +1,59 @@
module Hector
module Concerns
module Presence
def self.included(klass)
klass.class_eval do
attr_reader :created_at, :updated_at
end
end

def channels
Channel.find_all_for_session(self)
end

def commence_presence
@created_at = Time.now
@updated_at = Time.now
deliver_welcome_message
end

def conclude_presence
deliver_quit_message
leave_all_channels
end

def seconds_idle
Time.now - updated_at
end

def peer_sessions
[self, *channels.map { |channel| channel.sessions }.flatten].uniq
end

def touch_presence
@updated_at = Time.now
end

protected
def deliver_welcome_message
respond_with("001", nickname, :text => "Welcome to IRC")
respond_with("422", :text => "MOTD File is missing")
end

def deliver_quit_message
broadcast(:quit, :source => source, :text => quit_message, :except => self)
respond_with(:error, :text => "Closing Link: #{nickname}[hector] (#{quit_message})")
end

def leave_all_channels
channels.each do |channel|
channel.remove(self)
end
end

def quit_message
@quit_message || "Connection closed"
end
end
end
end
6 changes: 2 additions & 4 deletions lib/hector/connection.rb
@@ -1,6 +1,6 @@
module Hector
class Connection < EventMachine::Protocols::LineAndTextProtocol
include Authentication
include Concerns::Authentication

attr_reader :session, :request, :identity

Expand Down Expand Up @@ -34,9 +34,7 @@ def receive_line(line)
end

def unbind
if session
session.destroy
end
session.destroy if session
log(:info, "closing connection")
end

Expand Down

0 comments on commit d3b1d76

Please sign in to comment.