Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit daea635
Showing
11 changed files
with
2,074 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
source :rubygems | ||
|
||
gem 'cramp' | ||
gem 'rainbows' | ||
|
||
# Rack based routing | ||
gem 'http_router' | ||
|
||
# Collection of async-proof rack middlewares - https://github.com/rkh/async-rack.git | ||
gem 'async-rack' | ||
gem 'yajl-ruby' |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
GEM | ||
remote: http://rubygems.org/ | ||
specs: | ||
activesupport (3.0.10) | ||
async-rack (0.5.1) | ||
rack (~> 1.1) | ||
cramp (0.15.1) | ||
activesupport (~> 3.0.9) | ||
eventmachine (~> 1.0.0.beta.3) | ||
rack (~> 1.3.2) | ||
thor (~> 0.14.6) | ||
eventmachine (1.0.0.beta.3) | ||
http_router (0.10.2) | ||
rack (>= 1.0.0) | ||
url_mount (~> 0.2.1) | ||
kgio (2.6.0) | ||
rack (1.3.2) | ||
rainbows (4.2.0) | ||
kgio (~> 2.5) | ||
rack (~> 1.1) | ||
unicorn (~> 4.0) | ||
raindrops (0.7.0) | ||
thor (0.14.6) | ||
unicorn (4.0.1) | ||
kgio (~> 2.4) | ||
rack | ||
raindrops (~> 0.6) | ||
url_mount (0.2.1) | ||
rack | ||
yajl-ruby (0.8.2) | ||
|
||
PLATFORMS | ||
ruby | ||
|
||
DEPENDENCIES | ||
async-rack | ||
cramp | ||
http_router | ||
rainbows | ||
yajl-ruby |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
class ChatAction < Cramp::Websocket | ||
on_finish :handle_leave | ||
on_data :received_data | ||
|
||
def received_data(data) | ||
message = parse_json(data) | ||
case message[:action] | ||
when 'join' | ||
handle_join(message) | ||
when 'message' | ||
handle_message(message) | ||
end | ||
end | ||
|
||
def handle_join(message) | ||
@user = message[:user] | ||
|
||
config = { | ||
:server => "irc.freenode.net", | ||
:port => 6667, | ||
:nickname => @user, | ||
:realname => @user, | ||
:username => @user, | ||
:channels => ["#cramp"] | ||
} | ||
|
||
message_handler = Proc.new {|event| render encode_json(:message => event.message, :user => event.from, :action => 'message') } | ||
config[:handlers] = {'privmsg' => message_handler} | ||
|
||
@irc = EM.connect(config[:server], config[:port], IRC::Connection, :config => config) | ||
end | ||
|
||
def handle_leave | ||
return unless @irc | ||
|
||
@irc.quit('Goodbye!') | ||
@irc.close_connection | ||
end | ||
|
||
def handle_message(message) | ||
return unless @irc | ||
|
||
@irc.send_message(@irc.channels[0], message[:message]) | ||
render encode_json(:message => message[:message], :user => @user, :action => 'message') | ||
end | ||
|
||
protected | ||
|
||
def encode_json(payload) | ||
Yajl::Encoder.encode(payload) | ||
end | ||
|
||
def parse_json(payload) | ||
Yajl::Parser.parse(payload, :symbolize_keys => true) | ||
end | ||
|
||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
class HomeAction < Cramp::Action | ||
@@template = ERB.new(File.read(Snoop::Application.root('app/views/index.erb'))) | ||
|
||
def start | ||
render @@template.result(binding) | ||
finish | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
<html> | ||
<head> | ||
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script> | ||
<script src='http://jquery-json.googlecode.com/files/jquery.json-2.2.min.js'></script> | ||
<script src='http://datejs.googlecode.com/svn/trunk/build/date.js'></script> | ||
<script> | ||
$(document).ready(function(){ | ||
if (typeof(WebSocket) != 'undefined' || typeof(MozWebSocket)) { | ||
$('#ask').show(); | ||
} else { | ||
$('#error').show(); | ||
} | ||
|
||
// join on enter | ||
$('#ask input').keydown(function(event) { | ||
if (event.keyCode == 13) { | ||
$('#ask a').click(); | ||
} | ||
}) | ||
|
||
// join on click | ||
$('#ask a').click(function() { | ||
join($('#ask input').val()); | ||
$('#ask').hide(); | ||
$('#channel').show(); | ||
$('input#message').focus(); | ||
}); | ||
|
||
function join(name) { | ||
var host = window.location.host.split(':')[0]; | ||
|
||
var SocketKlass = "MozWebSocket" in window ? MozWebSocket : WebSocket; | ||
var ws = new SocketKlass('ws://<%= request.host_with_port %>/websocket'); | ||
|
||
var container = $('div#msgs'); | ||
ws.onmessage = function(evt) { | ||
var obj = $.evalJSON(evt.data); | ||
if (typeof obj != 'object') return; | ||
|
||
var action = obj['action']; | ||
var struct = container.find('li.' + action + ':first'); | ||
if (struct.length < 1) { | ||
console.log("Could not handle: " + evt.data); | ||
return; | ||
} | ||
|
||
var msg = struct.clone(); | ||
msg.find('.time').text((new Date()).toString("HH:mm:ss")); | ||
|
||
if (action == 'message') { | ||
var matches; | ||
if (matches = obj['message'].match(/^\s*[\/\\]me\s(.*)/)) { | ||
msg.find('.user').text(obj['user'] + ' ' + matches[1]); | ||
msg.find('.user').css('font-weight', 'bold'); | ||
} else { | ||
msg.find('.user').text(obj['user']); | ||
msg.find('.message').text(': ' + obj['message']); | ||
} | ||
} else if (action == 'control') { | ||
msg.find('.user').text(obj['user']); | ||
msg.find('.message').text(obj['message']); | ||
msg.addClass('control'); | ||
} | ||
|
||
if (obj['user'] == name) msg.find('.user').addClass('self'); | ||
container.find('ul').append(msg.show()); | ||
container.scrollTop(container.find('ul').innerHeight()); | ||
} | ||
|
||
$('#channel form').submit(function(event) { | ||
event.preventDefault(); | ||
var input = $(this).find(':input'); | ||
var msg = input.val(); | ||
ws.send($.toJSON({ action: 'message', message: msg })); | ||
input.val(''); | ||
}); | ||
|
||
// send name when joining | ||
ws.onopen = function() { | ||
ws.send($.toJSON({ action: 'join', user: name })); | ||
} | ||
} | ||
}); | ||
</script> | ||
<style type="text/css" media="screen"> | ||
* { | ||
font-family: Georgia; | ||
} | ||
a { | ||
color: #000; | ||
text-decoration: none; | ||
} | ||
a:hover { | ||
text-decoration: underline; | ||
} | ||
div.bordered { | ||
margin: 0 auto; | ||
margin-top: 100px; | ||
width: 600px; | ||
padding: 20px; | ||
text-align: center; | ||
border: 10px solid #ddd; | ||
-webkit-border-radius: 20px; | ||
} | ||
#error { | ||
background-color: #BA0000; | ||
color: #fff; | ||
font-weight: bold; | ||
} | ||
#ask { | ||
font-size: 20pt; | ||
} | ||
#ask input { | ||
font-size: 20pt; | ||
padding: 10px; | ||
margin: 0 10px; | ||
} | ||
#ask span.join { | ||
padding: 10px; | ||
background-color: #ddd; | ||
-webkit-border-radius: 10px; | ||
} | ||
#channel { | ||
margin-top: 100px; | ||
height: 480px; | ||
position: relative; | ||
} | ||
#channel div#descr { | ||
position: absolute; | ||
left: -10px; | ||
top: -190px; | ||
font-size: 13px; | ||
text-align: left; | ||
line-height: 20px; | ||
padding: 5px; | ||
width: 630px; | ||
} | ||
div#msgs { | ||
overflow-y: scroll; | ||
height: 400px; | ||
} | ||
div#msgs ul { | ||
list-style: none; | ||
padding: 0; | ||
margin: 0; | ||
text-align: left; | ||
} | ||
div#msgs li { | ||
line-height: 20px; | ||
} | ||
div#msgs li span.user { | ||
color: #ff9900; | ||
} | ||
div#msgs li span.user.self { | ||
color: #aa2211; | ||
} | ||
div#msgs li span.time { | ||
float: right; | ||
margin-right: 5px; | ||
color: #aaa; | ||
font-family: "Courier New"; | ||
font-size: 12px; | ||
} | ||
div#msgs li.control { | ||
text-align: center; | ||
} | ||
div#msgs li.control span.message { | ||
color: #aaa; | ||
} | ||
div#input { | ||
text-align: left; | ||
margin-top: 20px; | ||
} | ||
div#input #message { | ||
width: 600px; | ||
border: 5px solid #bbb; | ||
-webkit-border-radius: 3px; | ||
font-size: 30pt; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="error" class="bordered" style="display: none;"> | ||
This browser has no native WebSocket support.<br/> | ||
Use a WebKit nightly or Google Chrome. | ||
</div> | ||
<div id="ask" class="bordered" style="display: none;"> | ||
Name: <input type="text" id="name" /> <a href="#"><span class="join">Join!</span></a> | ||
</div> | ||
<div id="channel" class="bordered" style="display: none;"> | ||
<div id="descr" class="bordered"> | ||
#fauna @ irc.freenode.net | ||
</div> | ||
<div id="msgs"> | ||
<ul> | ||
<li class="message" style="display: none"> | ||
<span class="user"></span><span class="message"></span> | ||
<span class="time"></span> | ||
</li> | ||
<li class="control" style="display: none"> | ||
<span class="user"></span> <span class="message"></span> | ||
<span class="time"></span> | ||
</li> | ||
</ul> | ||
</div> | ||
<div id="input"> | ||
<form><input type="text" id="message" /></form> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
require "rubygems" | ||
require "bundler" | ||
|
||
module Snoop | ||
class Application | ||
|
||
def self.root(path = nil) | ||
@_root ||= File.expand_path(File.dirname(__FILE__)) | ||
path ? File.join(@_root, path.to_s) : @_root | ||
end | ||
|
||
def self.env | ||
@_env ||= ENV['RACK_ENV'] || 'development' | ||
end | ||
|
||
def self.routes | ||
@_routes ||= eval(File.read('./config/routes.rb')) | ||
end | ||
|
||
# Initialize the application | ||
def self.initialize! | ||
Cramp::Websocket.backend = :rainbows | ||
end | ||
|
||
end | ||
end | ||
|
||
Bundler.require(:default, Snoop::Application.env) | ||
|
||
require 'erb' | ||
require 'yaml' | ||
require 'stringio' | ||
require 'yajl' | ||
|
||
$: << Snoop::Application.root('lib/ruby-em-irc2/lib') | ||
require 'em-ruby-irc' | ||
|
||
# Preload application classes | ||
Dir['./app/**/*.rb'].each {|f| require f} | ||
|
Oops, something went wrong.