mad_chatter 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Andrew Havens
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
File without changes
data/bin/mad_chatter ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "thor"
4
+
5
+ module MadChatter
6
+
7
+ class Cli < Thor
8
+ include Thor::Actions
9
+
10
+ def self.source_root
11
+ File.expand_path("../", File.dirname(__FILE__))
12
+ end
13
+
14
+ desc "new", "Creates a scaffold of a new Mad Chatter chatroom"
15
+ def new(name)
16
+ empty_directory "#{name}/extensions"
17
+ copy_file "README", "#{name}/README"
18
+ copy_file "LICENSE", "#{name}/LICENSE"
19
+ copy_file "templates/index.html", "#{name}/web/index.html"
20
+ copy_file "templates/javascript.js", "#{name}/web/javascript.js"
21
+ copy_file "templates/stylesheets/reset.css", "#{name}/web/stylesheets/reset.css"
22
+ copy_file "templates/stylesheets/styles.css", "#{name}/web/stylesheets/styles.css"
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+ MadChatter::Cli.start
@@ -0,0 +1,36 @@
1
+ module MadChatter
2
+
3
+ module Actions
4
+
5
+ class Base
6
+
7
+ def initialize(message, user_token)
8
+ @message = message
9
+ @user_token = user_token
10
+ end
11
+
12
+ def process
13
+ send_message(@message)
14
+ end
15
+
16
+ def username
17
+ MadChatter::Users.username(@user_token)
18
+ end
19
+
20
+ def send_status(message)
21
+ MadChatter::Server.send_status(message)
22
+ end
23
+
24
+ def send_action(message)
25
+ MadChatter::Server.send_action(message)
26
+ end
27
+
28
+ def send_message(message)
29
+ MadChatter::Server.send_message(username, message)
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,26 @@
1
+ module MadChatter
2
+
3
+ module Actions
4
+
5
+ class Join < MadChatter::Actions::Base
6
+
7
+ @@command = '/join'
8
+
9
+ def process
10
+ username = parse_username_from_message
11
+ MadChatter::Users.update(@user_token, username)
12
+ MadChatter::Server.send_users_list
13
+ MadChatter::Server.send_status("#{username} has joined the chatroom")
14
+ end
15
+
16
+ def parse_username_from_message
17
+ # clear the command from the message string
18
+ # the rest will be the new username
19
+ username = @message.sub("#{@@command} ", '')
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,27 @@
1
+ module MadChatter
2
+
3
+ module Actions
4
+
5
+ class Rename < MadChatter::Actions::Base
6
+
7
+ @@command = '/nick'
8
+
9
+ def process
10
+ old_username = username
11
+ username = parse_username_from_message
12
+ MadChatter::Users.update(@user_token, username)
13
+ MadChatter::Server.send_users_list
14
+ MadChatter::Server.send_status("#{old_username} is now known as #{username}")
15
+ end
16
+
17
+ def parse_username_from_message
18
+ # clear the command from the message string
19
+ # the rest will be the new username
20
+ username = @message.sub("#{@@command} ", '')
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,61 @@
1
+ require 'mad_chatter/actions/base'
2
+ require 'mad_chatter/actions/join'
3
+ require 'mad_chatter/actions/rename'
4
+
5
+ module MadChatter
6
+
7
+ module Actions
8
+
9
+ class << self
10
+
11
+ def config(&block)
12
+ @config_block = block
13
+ end
14
+
15
+ def registered_actions
16
+ @registered_actions
17
+ end
18
+
19
+ def init
20
+ load_config_file
21
+ load_default_actions
22
+ load_action_extensions
23
+ end
24
+
25
+ def load_config_file
26
+ if File.exists?('config.rb')
27
+ load 'config.rb' # load up action extensions
28
+ end
29
+ end
30
+
31
+ def load_default_actions
32
+ @registered_actions = {}
33
+ @registered_actions['/join'] = 'MadChatter::Actions::Join'
34
+ @registered_actions['/nick'] = 'MadChatter::Actions::Rename'
35
+ end
36
+
37
+ def load_action_extensions
38
+ config = MadChatter::Actions::Config.new
39
+ @config_block.call(config) if @config_block
40
+ config.actions.each do |command, action_class|
41
+ @registered_actions[command] = action_class
42
+ end
43
+ end
44
+ end
45
+
46
+ class Config
47
+
48
+ attr_accessor :actions
49
+
50
+ def initialize
51
+ @actions = {}
52
+ end
53
+
54
+ def add(command, action_class)
55
+ @actions[command] = action_class
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,22 @@
1
+ require 'mad_chatter/actions'
2
+ require 'mad_chatter/actions/base'
3
+
4
+ module MadChatter
5
+
6
+ class Message < MadChatter::Actions::Base; end
7
+
8
+ class MessageFactory
9
+
10
+ def self.find(message, user_token)
11
+ MadChatter::Actions.registered_actions.each do |command, action_class|
12
+ # puts "looping through registered actions, command: #{command}, action_class: #{action_class}"
13
+ if message =~ /^#{command}/
14
+ return eval(action_class).new(message, user_token)
15
+ end
16
+ end
17
+ # puts 'could not find match for ' + message
18
+ MadChatter::Message.new(message, user_token)
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,116 @@
1
+ require 'digest/sha1'
2
+ require 'mad_chatter/users'
3
+ require 'mad_chatter/message'
4
+
5
+ module MadChatter
6
+
7
+ class Server
8
+
9
+ def initialize(options = {})
10
+ defaults = {
11
+ :host => "0.0.0.0",
12
+ :port => 8100
13
+ }
14
+ @options = defaults.merge!(options)
15
+ end
16
+
17
+ def self.main_channel
18
+ @main_channel ||= EventMachine::Channel.new
19
+ end
20
+
21
+ def start
22
+ EventMachine::WebSocket.start(@options) do |ws|
23
+
24
+ ws.onopen do
25
+
26
+ subscriber_id = MadChatter::Server.main_channel.subscribe { |msg| ws.send(msg) } #main send method, gets called when @main_channel.push gets called
27
+ token = generate_token()
28
+ send_client_token(ws, token)
29
+
30
+ ws.onclose do
31
+ username = MadChatter::Users.username(token)
32
+ if username
33
+ MadChatter::Server.send_status "#{username} has left the chatroom"
34
+ MadChatter::Users.remove(token)
35
+ end
36
+ MadChatter::Server.main_channel.unsubscribe(subscriber_id)
37
+ end
38
+
39
+ ws.onmessage do |msg_json|
40
+ msg = JSON.parse(msg_json)
41
+ if msg['token'].nil?
42
+ send_client_error(ws, 'Token is required')
43
+ else
44
+ message = MadChatter::MessageFactory.find(msg['message'], msg['token'])
45
+ message.process
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+
53
+ def generate_token
54
+ Digest::SHA1.hexdigest Time.now.to_s
55
+ end
56
+
57
+ def send_client_error(client, message)
58
+ data = JSON.generate({
59
+ type: 'error',
60
+ message: message
61
+ })
62
+ send_to_client(client, data)
63
+ end
64
+
65
+ def send_client_token(client, token)
66
+ data = JSON.generate({
67
+ type: 'token',
68
+ message: token
69
+ })
70
+ send_to_client(client, data)
71
+ end
72
+
73
+ def send_to_client(client, data)
74
+ client.send(data)
75
+ end
76
+
77
+ def self.send_users_list
78
+ data = JSON.generate({
79
+ type: 'users',
80
+ message: MadChatter::Users.current
81
+ })
82
+ MadChatter::Server.push_to_all_connections(data)
83
+ end
84
+
85
+ def self.send_status(message)
86
+ data = JSON.generate({
87
+ type: 'status',
88
+ message: message
89
+ })
90
+ MadChatter::Server.push_to_all_connections(data)
91
+ end
92
+
93
+ def self.send_message(username, message)
94
+ data = JSON.generate({
95
+ type: 'message',
96
+ username: username,
97
+ message: message
98
+ })
99
+ MadChatter::Server.push_to_all_connections(data)
100
+ end
101
+
102
+ def self.send_action(message)
103
+ data = JSON.generate({
104
+ type: 'action',
105
+ message: message
106
+ })
107
+ MadChatter::Server.push_to_all_connections(data)
108
+ end
109
+
110
+ def Server.push_to_all_connections(data)
111
+ # puts 'sending to all clients: ' + data
112
+ MadChatter::Server.main_channel.push(data)
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,35 @@
1
+ module MadChatter
2
+
3
+ class Users
4
+
5
+ # Singleton storage for all current users
6
+ class << self
7
+
8
+ def users
9
+ @users ||= {}
10
+ end
11
+
12
+ def update(token, username)
13
+ MadChatter::Users.users[token] = username
14
+ end
15
+
16
+ def remove(token)
17
+ MadChatter::Users.users.delete(token)
18
+ end
19
+
20
+ def username(token)
21
+ MadChatter::Users.users[token]
22
+ end
23
+
24
+ def current
25
+ MadChatter::Users.users.values
26
+ end
27
+
28
+ def token_exists?(token)
29
+ MadChatter::Users.users[token].exists?
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,23 @@
1
+ $:.unshift(File.dirname(__FILE__)) # add this directory to load path
2
+ $:.unshift(Dir.pwd) # add current working directory for loading extensions
3
+
4
+ require 'bundler'
5
+ Bundler.setup
6
+ require 'em-websocket'
7
+ require 'json'
8
+
9
+ require 'mad_chatter/server'
10
+ require 'mad_chatter/actions'
11
+
12
+ EventMachine.run do
13
+
14
+ MadChatter::Actions.init
15
+
16
+ port = ENV['PORT'] || 8100
17
+
18
+ puts "Starting WebSocket server on port #{port}."
19
+
20
+ server = MadChatter::Server.new(:port => port)
21
+ server.start
22
+
23
+ end
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Mad Chatter</title>
5
+ <link rel="stylesheet" href="stylesheets/reset.css">
6
+ <link rel="stylesheet" href="stylesheets/styles.css">
7
+ <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js'></script>
8
+ <script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js'></script>
9
+ <script src='javascript.js'></script>
10
+ <script>
11
+ $(document).ready(function(){
12
+ MadChatter.init('ws://localhost:8100');
13
+ });
14
+ </script>
15
+ </head>
16
+ <body>
17
+
18
+ <div id="login_screen">
19
+ <header>
20
+ <h1>Welcome!</h1>
21
+ </header>
22
+ <div id="pick_a_username">
23
+ <p>What is your name?</p>
24
+ <input id="username" type="text"> <button id="join">Join</button>
25
+ </div>
26
+ </div>
27
+
28
+ <div id="chatroom">
29
+ <div id="sidebar">
30
+ <h2>Members</h2>
31
+ <ul id="members"></ul>
32
+ </div>
33
+ <div id="keyboard">
34
+ <input type="text">
35
+ </div>
36
+ <div id="messages"></div>
37
+ </div>
38
+
39
+ </body>
40
+ </html>
@@ -0,0 +1,128 @@
1
+ function get_current_time(){
2
+ var time = new Date();
3
+ var hours = time.getHours();
4
+ var minutes = time.getMinutes();
5
+ var ampm = 'am';
6
+ if (hours > 11) { ampm = 'pm'; }
7
+ if (minutes < 10) { minutes = "0" + minutes; }
8
+ if (hours == 0) { hours = 12; }
9
+ if (hours > 12) { hours = hours - 12; }
10
+ return hours + ':' + minutes + ampm;
11
+ }
12
+
13
+ var MadChatter = {
14
+
15
+ init: function(ws_host){
16
+ if (typeof WebSocket === 'undefined') {
17
+ alert("Your browser does not support websockets.")
18
+ return false;
19
+ }
20
+ MadChatter.init_websocket(ws_host);
21
+ $('#chatroom').hide();
22
+ MadChatter.wait_for_join();
23
+ MadChatter.wait_for_chat_submit();
24
+ },
25
+
26
+ init_websocket: function(ws_host){
27
+ var ws = new WebSocket(ws_host);
28
+ ws.onopen = function(){};
29
+ ws.onclose = function(){
30
+ MadChatter.display_status('You have been disconnected');
31
+ };
32
+ ws.onmessage = function(evt){
33
+ //console.log(evt.data)
34
+ var data = JSON.parse(evt.data);
35
+ MadChatter.message_received(data.type, data.username, data.message);
36
+ };
37
+ MadChatter.ws = ws;
38
+ },
39
+
40
+ wait_for_join: function(){
41
+ $('#username').keyup(function (event) {
42
+ if (event.keyCode == 13) { // The enter key.
43
+ MadChatter.join_chat();
44
+ }
45
+ });
46
+ $('#join').click(function(){
47
+ MadChatter.join_chat();
48
+ });
49
+ },
50
+
51
+ wait_for_chat_submit: function(){
52
+ var keyboard = $("#keyboard input");
53
+ keyboard.keyup(function (event) {
54
+ if (event.keyCode == 13) { // The enter key.
55
+ MadChatter.send_message(keyboard.val());
56
+ keyboard.val('');
57
+ }
58
+ });
59
+ },
60
+
61
+ join_chat: function(){
62
+ var username = $.trim($('#username').val());
63
+ if (username.length == 0) {
64
+ alert('Please enter your name.');
65
+ return false;
66
+ }
67
+ MadChatter.send_message('/join ' + username);
68
+ $('#login_screen').hide();
69
+ $('#chatroom').show();
70
+ },
71
+
72
+ message_received: function(type, username, message){
73
+ if (type == 'error') {
74
+ console.log('Client error: ' + message)
75
+ return;
76
+ }
77
+ if (type == 'token') {
78
+ MadChatter.client_token = message;
79
+ return;
80
+ }
81
+ if (type == 'users') {
82
+ MadChatter.update_users_list(message);
83
+ return;
84
+ }
85
+ if (type == 'status') {
86
+ MadChatter.display_status(message);
87
+ }
88
+ if (type == 'action') {
89
+ MadChatter.run_action(message);
90
+ }
91
+ if (type == 'message') {
92
+ MadChatter.display_message(username, message);
93
+ }
94
+ MadChatter.scroll_to_bottom_of_chat();
95
+ },
96
+
97
+ update_users_list: function(users){
98
+ $("#members").html('');
99
+ $.each(users, function(index, username) {
100
+ $("#members").append('<li>' + username + '</li>');
101
+ });
102
+ },
103
+
104
+ run_action: function(action){
105
+ eval(action);
106
+ },
107
+
108
+ display_status: function(message){
109
+ $("#messages").append("<p class='status'>" + message + "<time>" + get_current_time() + "</time></p>");
110
+ },
111
+
112
+ display_message: function(username, message){
113
+ $("#messages").append("<p><strong>" + username + ":</strong> " + message + "<time>" + get_current_time() + "</time></p>");
114
+ },
115
+
116
+ scroll_to_bottom_of_chat: function(){
117
+ $("body")[0].scrollTop = $("#messages")[0].scrollHeight;
118
+ },
119
+
120
+ send_message: function(message){
121
+ MadChatter.send_json('message', message);
122
+ },
123
+
124
+ send_json: function(type, msg){
125
+ var json = { type: type, token: MadChatter.client_token, message: msg };
126
+ MadChatter.ws.send(JSON.stringify(json));
127
+ }
128
+ };
@@ -0,0 +1,48 @@
1
+ /* http://meyerweb.com/eric/tools/css/reset/
2
+ v2.0 | 20110126
3
+ License: none (public domain)
4
+ */
5
+
6
+ html, body, div, span, applet, object, iframe,
7
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8
+ a, abbr, acronym, address, big, cite, code,
9
+ del, dfn, em, img, ins, kbd, q, s, samp,
10
+ small, strike, strong, sub, sup, tt, var,
11
+ b, u, i, center,
12
+ dl, dt, dd, ol, ul, li,
13
+ fieldset, form, label, legend,
14
+ table, caption, tbody, tfoot, thead, tr, th, td,
15
+ article, aside, canvas, details, embed,
16
+ figure, figcaption, footer, header, hgroup,
17
+ menu, nav, output, ruby, section, summary,
18
+ time, mark, audio, video {
19
+ margin: 0;
20
+ padding: 0;
21
+ border: 0;
22
+ font-size: 100%;
23
+ font: inherit;
24
+ vertical-align: baseline;
25
+ }
26
+ /* HTML5 display-role reset for older browsers */
27
+ article, aside, details, figcaption, figure,
28
+ footer, header, hgroup, menu, nav, section {
29
+ display: block;
30
+ }
31
+ body {
32
+ line-height: 1;
33
+ }
34
+ ol, ul {
35
+ list-style: none;
36
+ }
37
+ blockquote, q {
38
+ quotes: none;
39
+ }
40
+ blockquote:before, blockquote:after,
41
+ q:before, q:after {
42
+ content: '';
43
+ content: none;
44
+ }
45
+ table {
46
+ border-collapse: collapse;
47
+ border-spacing: 0;
48
+ }
@@ -0,0 +1,121 @@
1
+ #login_screen header {
2
+ padding: 150px 0 20px;
3
+ color: #fff;
4
+ background-color: #000;
5
+ text-align: center;
6
+ font: 25px Verdana, Geneva, Arial, Helvetica, sans-serif;
7
+ }
8
+
9
+ #pick_a_username {
10
+ text-align: center;
11
+ background: #fff;
12
+ padding: 5px 10px 10px;
13
+ font: 18px Verdana, Geneva, Arial, Helvetica, sans-serif;
14
+ }
15
+
16
+ #pick_a_username p {
17
+ margin: 10px;
18
+ }
19
+ #pick_a_username input, #pick_a_username button {
20
+ font: 14px Verdana, Geneva, Arial, Helvetica, sans-serif;
21
+ padding: 5px;
22
+ }
23
+ /*
24
+ #chatroom {
25
+ text-align: left;
26
+ background: #fff;
27
+ padding: 5px 10px 10px;
28
+ }
29
+
30
+ #chatroom #sidebar {
31
+ float: left;
32
+ width: 200px;
33
+ color: #fff;
34
+ background-color: #000;
35
+ height: 100%;
36
+ }
37
+
38
+ #chatroom #body {
39
+ float: right;
40
+ margin-left: 200px;
41
+ width: 580px;
42
+ height: 100%;
43
+ }
44
+ */
45
+
46
+ #chatroom{
47
+ margin:0;
48
+ padding:0 0 100px 200px;
49
+ font: 12px Verdana, Geneva, Arial, Helvetica, sans-serif;
50
+ }
51
+
52
+ #sidebar{
53
+ position:absolute;
54
+ top:0;
55
+ left:0;
56
+ width:200px;
57
+ height:100%;
58
+ color: #fff;
59
+ background-color: #000;
60
+ padding: 20px 5px 0 15px;
61
+ }
62
+
63
+ #sidebar h2 {
64
+ font: 14px Verdana, Geneva, Arial, Helvetica, sans-serif;
65
+ margin-bottom: 10px;
66
+ }
67
+
68
+ #sidebar ul#members li {
69
+ margin-left: 1em;
70
+ }
71
+
72
+ #messages {
73
+ padding: 20px 10px 0px 40px;
74
+ }
75
+
76
+ #messages p {
77
+ padding: 0.25em;
78
+ }
79
+
80
+ #messages time {
81
+ float: right;
82
+ color: #999;
83
+ }
84
+
85
+ #messages .status {
86
+ text-align: center;
87
+ color: #999;
88
+ }
89
+
90
+ #keyboard{
91
+ position:absolute;
92
+ bottom:0;
93
+ left:220px;
94
+ width:400%;
95
+ height:50px;
96
+ background-color: #eee;
97
+ padding: 10px 0 0 20px;
98
+ }
99
+
100
+ #keyboard input {
101
+ width: 15%;
102
+ padding: 5px;
103
+ }
104
+
105
+ @media screen{
106
+ #chatroom>div#sidebar{
107
+ position:fixed;
108
+ }
109
+ #chatroom>div#keyboard{
110
+ position:fixed;
111
+ }
112
+ }
113
+
114
+ * html #chatroom{
115
+ overflow:hidden;
116
+ }
117
+
118
+ * html div#messages{
119
+ height:100%;
120
+ overflow:auto;
121
+ }
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mad_chatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Havens
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-11 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: &2169798480 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.14.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2169798480
25
+ - !ruby/object:Gem::Dependency
26
+ name: em-websocket
27
+ requirement: &2169797840 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.3.5
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2169797840
36
+ description: Mad Chatter is a fun, easy to customize chat server, written in Ruby,
37
+ utilizing HTML 5 Web Sockets
38
+ email: email@andrewhavens.com
39
+ executables:
40
+ - mad_chatter
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - lib/mad_chatter/actions/base.rb
45
+ - lib/mad_chatter/actions/join.rb
46
+ - lib/mad_chatter/actions/rename.rb
47
+ - lib/mad_chatter/actions.rb
48
+ - lib/mad_chatter/message.rb
49
+ - lib/mad_chatter/server.rb
50
+ - lib/mad_chatter/users.rb
51
+ - lib/mad_chatter.rb
52
+ - bin/mad_chatter
53
+ - templates/index.html
54
+ - templates/javascript.js
55
+ - templates/stylesheets/reset.css
56
+ - templates/stylesheets/styles.css
57
+ - LICENSE
58
+ - README
59
+ homepage: http://github.com/andrewhavens/mad_chatter
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 1.8.10
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Mad Chatter is a fun, easy to customize chat server, utilizing HTML 5 Web
83
+ Sockets
84
+ test_files: []