mad_chatter 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt ADDED
@@ -0,0 +1,9 @@
1
+ Mad Chatter
2
+
3
+ Version 0.1.0
4
+ - Refactored extension architecture. Much nicer syntax now.
5
+ - Moved some of the main configuration to a config.yml file (which is generated when you use the 'new' command)
6
+ - Created skeleton classes for alternative web socket server implementations and moved the default implementation into its own class
7
+
8
+ Versions < 0.1.0
9
+ - Some of the features were implemented, but there were many holes that needed to be filled
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source :rubygems
2
+
3
+ # Gem dependencies
4
+ gem 'thor'
5
+ gem 'eventmachine', '0.12.10'
6
+ gem 'em-websocket'
7
+
8
+ # Development dependencies
9
+ group :development do
10
+ gem "shoulda", ">= 0"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "jeweler", "~> 1.6.4"
13
+ gem "rcov", ">= 0"
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.2.6)
5
+ em-websocket (0.3.5)
6
+ addressable (>= 2.1.1)
7
+ eventmachine (>= 0.12.9)
8
+ eventmachine (0.12.10)
9
+ git (1.2.5)
10
+ jeweler (1.6.4)
11
+ bundler (~> 1.0)
12
+ git (>= 1.2.5)
13
+ rake
14
+ rake (0.9.2.2)
15
+ rcov (0.9.11)
16
+ shoulda (2.11.3)
17
+ thor (0.14.6)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ bundler (~> 1.0.0)
24
+ em-websocket
25
+ eventmachine (= 0.12.10)
26
+ jeweler (~> 1.6.4)
27
+ rcov
28
+ shoulda
29
+ thor
File without changes
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ #Mad Chatter
2
+
3
+ Mad Chatter is a fun, easy to customize chat server. It's written in Ruby and utilizes HTML 5 Web Sockets for fast communication.
4
+
5
+ ##Getting Started
6
+
7
+ To get started, first install the Mad Chatter gem:
8
+
9
+ gem install mad_chatter
10
+
11
+ Then generate the directory where your chat application will live:
12
+
13
+ mad_chatter new mychatroom
14
+
15
+ This command will generate the following structure:
16
+
17
+ mychatroom/
18
+ config.rb
19
+ extensions/
20
+ web/
21
+ index.html
22
+ javascript.js
23
+ stylesheets/
24
+ reset.css
25
+ styles.css
26
+
27
+ To start your chat server, navigate to the directory that was just created and run...
28
+
29
+ mad_chatter start
30
+
31
+ This will start the web socket server on a specific port. You can now open the index.html file in your browser and start playing. All the files necessary to serve to the client are in the web directory. Feel free to copy/move these files if you'd prefer them somewhere else.
32
+
33
+ The start command will launch the web socket server in the background. You can use this command in production to start your server and leave it running. If you need to stop the server, simply run...
34
+
35
+ mad_chatter stop
36
+
37
+
38
+ ##Chat Actions
39
+
40
+ Hopefully, the default chatroom will be relatively intuitive to use. However, there are some extra features that Mad Chatter provides. Every chat message is parsed to see if it is a normal chat message, or if its a special action. These actions are much like IRC commands. For example, if I wanted to change my screen name from Andrew to Andy I could chat this message:
41
+
42
+ /nick andy
43
+
44
+ Mad Chatter will interpret this message as an action and change the user name to andy.
45
+
46
+ If I wanted to embed a YouTube video for all the members of the chatroom to enjoy, I could type:
47
+
48
+ /youtube http://youtu.be/n1NVfDlU6yQ
49
+
50
+ You can even create your own actions to do whatever you want.
51
+
52
+
53
+ ##Customizing
54
+
55
+ The goal of Mad Chatter is to make it easy to create, host, and customize your own chat server. Let's take a look at the different ways you can customize your new chat server.
56
+
57
+ If you want to customize the html/css of your chatroom, you'll find them in the web directory.
58
+
59
+ There is an example config file that shows a few examples of things you can customize.
60
+
61
+ The extensions directory is for you to create your own chat actions. You can add your custom extensions by specifying them in the config file.
62
+
63
+
64
+ ##Contributing
65
+
66
+ Please fork and send pull requests! Or submit issues if you have suggestions on how to improve.
67
+
68
+ ##TODO
69
+
70
+ - Actually implement the server daemonization mentioned above
71
+ - Add support for alternative web socket servers like Juggernaut, Socket.io, or Cramp and web-socket-js for better cross-browser support
72
+ - Add tests!
73
+
74
+ ##Copyright
75
+
76
+ Copyright (c) 2011 Andrew Havens. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ require './lib/mad_chatter/version.rb'
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
18
+ gem.name = "mad_chatter"
19
+ gem.version = MadChatter::VERSION
20
+ gem.homepage = "http://github.com/andrewhavens/mad_chatter"
21
+ gem.license = "MIT"
22
+ gem.summary = %Q{Mad Chatter is a fun, easy to customize chat server, utilizing HTML 5 Web Sockets}
23
+ gem.description = %Q{Mad Chatter is a fun, easy to customize chat server, utilizing HTML 5 Web Sockets}
24
+ gem.email = "email@andrewhavens.com"
25
+ gem.authors = ["Andrew Havens"]
26
+ # dependencies defined in Gemfile
27
+ end
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ require 'rcov/rcovtask'
38
+ Rcov::RcovTask.new do |test|
39
+ test.libs << 'test'
40
+ test.pattern = 'test/**/test_*.rb'
41
+ test.verbose = true
42
+ test.rcov_opts << '--exclude "gems/*"'
43
+ end
44
+
45
+ task :default => :test
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "mad_chatter #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/bin/mad_chatter CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "thor"
3
+ require 'thor'
4
+ require File.expand_path('../../lib/mad_chatter', __FILE__)
4
5
 
5
6
  module MadChatter
6
7
 
@@ -8,21 +9,43 @@ module MadChatter
8
9
  include Thor::Actions
9
10
 
10
11
  def self.source_root
11
- File.expand_path("../", File.dirname(__FILE__))
12
+ File.expand_path('../../', __FILE__)
12
13
  end
13
14
 
14
- desc "new", "Creates a scaffold of a new Mad Chatter chatroom"
15
+ desc "new [name]", "Generates a new Mad Chatter chatroom application"
15
16
  def new(name)
17
+ copy_file "templates/config.yml", "#{name}/config.yml"
18
+ copy_file "templates/extensions.rb", "#{name}/extensions.rb"
16
19
  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"
20
+ copy_file "templates/web/index.html", "#{name}/web/index.html"
21
+ copy_file "templates/web/javascript.js", "#{name}/web/javascript.js"
22
+ copy_file "templates/web/stylesheets/reset.css", "#{name}/web/stylesheets/reset.css"
23
+ copy_file "templates/web/stylesheets/styles.css", "#{name}/web/stylesheets/styles.css"
24
+ end
25
+
26
+ desc 'start', 'Starts the chat server'
27
+ def start
28
+ MadChatter.start
29
+ end
30
+
31
+ desc 'stop', 'Stops the chat server'
32
+ def stop
33
+ # stop the currently running daemon
34
+ # not sure how to best implement this part yet
35
+ end
36
+
37
+ desc 'restart', 'Restarts the chat server'
38
+ def restart
39
+ # restarts the currently running daemon
40
+ # not sure how to best implement this part yet
41
+ end
42
+
43
+ desc 'version', 'Displays the current version number'
44
+ def version
45
+ puts MadChatter::VERSION
23
46
  end
24
47
 
25
48
  end
26
49
  end
27
50
 
28
- MadChatter::Cli.start
51
+ MadChatter::Cli.start(ARGV)
@@ -0,0 +1,34 @@
1
+ module MadChatter
2
+ class Action
3
+
4
+ def self.inherited(extension_class)
5
+ MadChatter.extension_classes << extension_class.new
6
+ end
7
+
8
+ # Helper methods
9
+
10
+ def stop_message_handling
11
+ raise 'Dont call anymore message listeners'
12
+ end
13
+
14
+ def send_json(json)
15
+ MadChatter::Server.send_json(json)
16
+ end
17
+
18
+ def send_message(text)
19
+ message = MadChatter::Message.new('message', text)
20
+ send_json(message.to_s)
21
+ end
22
+
23
+ def send_status_message(text)
24
+ message = MadChatter::Message.new('status', text)
25
+ send_json(message.to_s)
26
+ end
27
+
28
+ def send_users_list
29
+ message = MadChatter::Message.new('users', MadChatter::Users.current)
30
+ send_json(message.to_s)
31
+ end
32
+
33
+ end
34
+ end
@@ -1,26 +1,23 @@
1
1
  module MadChatter
2
-
3
2
  module Actions
4
-
5
- class Join < MadChatter::Actions::Base
3
+ class Join < MadChatter::Action
6
4
 
7
- @@command = '/join'
5
+ @@regex = /\/join (.+)/
8
6
 
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")
7
+ def handle(message)
8
+ if message.text =~ @@regex
9
+ username = parse_username(message.text)
10
+ MadChatter::Users.update(message.token, username)
11
+ send_status_message "#{username} has joined the chatroom"
12
+ send_users_list
13
+ stop_message_handling
14
+ end
14
15
  end
15
16
 
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} ", '')
17
+ def parse_username(text)
18
+ @@regex.match(text).captures[0]
20
19
  end
21
20
 
22
21
  end
23
-
24
22
  end
25
-
26
23
  end
@@ -1,27 +1,24 @@
1
1
  module MadChatter
2
-
3
2
  module Actions
4
-
5
- class Rename < MadChatter::Actions::Base
3
+ class Rename < MadChatter::Action
6
4
 
7
- @@command = '/nick'
5
+ @@regex = /\/nick (.+)/
8
6
 
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}")
7
+ def handle(message)
8
+ if message.text =~ @@regex
9
+ old_username = message.username
10
+ username = parse_username(message.text)
11
+ MadChatter::Users.update(message.token, username)
12
+ send_status_message "#{old_username} is now known as #{username}"
13
+ send_users_list
14
+ stop_message_handling
15
+ end
15
16
  end
16
17
 
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} ", '')
18
+ def parse_username(text)
19
+ @@regex.match(text).captures[0]
21
20
  end
22
21
 
23
22
  end
24
-
25
23
  end
26
-
27
24
  end
@@ -0,0 +1,49 @@
1
+ module MadChatter
2
+
3
+ def self.simple_extensions
4
+ @@simple_extensions ||= []
5
+ end
6
+
7
+ def self.extension_classes
8
+ @@extension_classes ||= []
9
+ end
10
+
11
+ module Config
12
+ class << self
13
+
14
+ def init
15
+ config = MadChatter::Config.initialize_config
16
+ MadChatter::Config.initialize_extensions
17
+ return config
18
+ end
19
+
20
+ def initialize_config
21
+ config_file = File.join(Dir.pwd, 'config.yml')
22
+
23
+ unless File.exist?(config_file)
24
+ raise 'Could not find Mad Chatter config.yml file'
25
+ end
26
+
27
+ config = YAML::load(File.open(config_file))
28
+ defaults = {
29
+ 'websocket_backend' => 'websocket-rack',
30
+ 'websocket_port' => 8100,
31
+ }
32
+ @config = defaults.merge!(config)
33
+ end
34
+
35
+ def initialize_extensions
36
+ simple_extensions_file = File.join(Dir.pwd, 'extensions.rb')
37
+ if File.exist?(simple_extensions_file)
38
+ file_contents = File.read(simple_extensions_file)
39
+ MadChatter::Extensions.load_simple_extensions(file_contents)
40
+ end
41
+
42
+ Dir[Dir.pwd + '/extensions/*.rb'].each do |file|
43
+ require file
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ module MadChatter
2
+ class Extensions
3
+
4
+ def self.load_simple_extensions(extensions)
5
+ instance_eval extensions, __FILE__, __LINE__
6
+ end
7
+
8
+ def self.on_message(regex, &block)
9
+ MadChatter.simple_extensions << { regex: regex, block: block }
10
+ end
11
+
12
+ end
13
+ end
@@ -1,22 +1,22 @@
1
- require 'mad_chatter/actions'
2
- require 'mad_chatter/actions/base'
3
-
4
1
  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
2
+ class Message
3
+
4
+ attr_accessor :type, :text, :token, :username
5
+
6
+ def initialize(type, message_text, token = nil, username = nil)
7
+ @type = type
8
+ @text = message_text
9
+ @token = token
10
+ @username = username
11
+ end
12
+
13
+ def to_s
14
+ JSON.generate({
15
+ type: @type,
16
+ message: @text,
17
+ username: @username,
18
+ })
19
+ end
20
+
20
21
  end
21
-
22
22
  end
@@ -1,116 +1,79 @@
1
- require 'digest/sha1'
2
- require 'mad_chatter/users'
3
- require 'mad_chatter/message'
4
-
5
1
  module MadChatter
6
2
 
7
3
  class Server
8
4
 
9
- def initialize(options = {})
10
- defaults = {
11
- :host => "0.0.0.0",
12
- :port => 8100
13
- }
14
- @options = defaults.merge!(options)
5
+ def initialize(config)
6
+ @config = config
7
+ @server = initialize_server
15
8
  end
16
9
 
17
10
  def self.main_channel
18
11
  @main_channel ||= EventMachine::Channel.new
19
12
  end
13
+
14
+ def initialize_server
15
+ # TODO: Figure out a better (more flexible/dynamic) way to initialize the server class
16
+ if @config['websocket_backend'] && @config['websocket_backend'] == 'MadChatter::Servers::EventMachineWebSocket'
17
+ return MadChatter::Servers::EventMachineWebSocket.new(self, @config['websocket_port'])
18
+ end
19
+
20
+ raise 'You did not specify a valid class name for websocket_backend'
21
+ end
20
22
 
21
23
  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
24
+ EM.run do
25
+ puts "Starting Mad Chatter Web Socket server on port #{@config['websocket_port']}."
26
+ @server.start
50
27
  end
51
28
  end
52
29
 
53
- def generate_token
54
- Digest::SHA1.hexdigest Time.now.to_s
30
+ def register_connection(&send_client_message_block)
31
+ subscriber_id = MadChatter::Server.main_channel.subscribe(send_client_message_block)
32
+ send_client_message_block.call(connection_token)
55
33
  end
56
34
 
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)
35
+ def connection_token
36
+ token = Digest::SHA1.hexdigest Time.now.to_s
37
+ MadChatter::Message.new('token', token).to_s
71
38
  end
72
39
 
73
- def send_to_client(client, data)
74
- client.send(data)
40
+ def connection_closed(id)
41
+ MadChatter::Server.main_channel.unsubscribe(id)
75
42
  end
76
43
 
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
44
+ def message_received(json)
45
+ msg = JSON.parse(json)
46
+ username = MadChatter::Users.find_username_by_token(msg['token'])
47
+ message = MadChatter::Message.new(msg['type'], msg['message'], msg['token'], username)
48
+
49
+ if message.token.nil?
50
+ return # Token is required to send messages
51
+ end
52
+
53
+ begin
54
+ MadChatter.simple_extensions.each do |extension|
55
+ if message.text =~ extension[:regex]
56
+ MadChatter::Action.instance_exec do
57
+ args = extension[:regex].match(message.text).captures
58
+ extension[:block].call(args)
59
+ end
60
+ end
61
+ end
92
62
 
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)
63
+ MadChatter.extension_classes.each do |extension|
64
+ extension.handle(message)
65
+ end
66
+
67
+ MadChatter::Server.send_json(message.to_s)
68
+ rescue RuntimeError
69
+ # dont need to do anything, just prevent any errors from stopping the server
70
+ end
100
71
  end
101
72
 
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)
73
+ def self.send_json(json)
74
+ MadChatter::Server.main_channel.push(json)
108
75
  end
109
76
 
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
77
  end
115
78
 
116
- end
79
+ end
@@ -0,0 +1,38 @@
1
+ require 'em-websocket'
2
+
3
+ module MadChatter
4
+ module Servers
5
+ class EventMachineWebSocket
6
+
7
+ def initialize(main_server, port)
8
+ @main_server = main_server
9
+ @config = {
10
+ :host => '0.0.0.0',
11
+ :port => port
12
+ }
13
+ end
14
+
15
+ def start
16
+ EventMachine::WebSocket.start(@config) do |ws|
17
+
18
+ ws.onopen do
19
+
20
+ connection_id = @main_server.register_connection do |msg|
21
+ ws.send(msg)
22
+ end
23
+
24
+ ws.onclose do
25
+ @main_server.connection_closed(connection_id)
26
+ end
27
+
28
+ ws.onmessage do |msg|
29
+ @main_server.message_received(msg)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,9 @@
1
+ module MadChatter
2
+ module Servers
3
+ class Juggernaut
4
+
5
+ # TODO
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module MadChatter
2
+ module Servers
3
+ class WebSocketRack
4
+
5
+ # TODO
6
+
7
+ end
8
+ end
9
+ end
@@ -1,8 +1,6 @@
1
1
  module MadChatter
2
-
3
2
  class Users
4
3
 
5
- # Singleton storage for all current users
6
4
  class << self
7
5
 
8
6
  def users
@@ -17,7 +15,7 @@ module MadChatter
17
15
  MadChatter::Users.users.delete(token)
18
16
  end
19
17
 
20
- def username(token)
18
+ def find_username_by_token(token)
21
19
  MadChatter::Users.users[token]
22
20
  end
23
21
 
@@ -31,5 +29,4 @@ module MadChatter
31
29
  end
32
30
 
33
31
  end
34
-
35
32
  end
@@ -0,0 +1,5 @@
1
+ module MadChatter
2
+
3
+ VERSION = '0.1.0'
4
+
5
+ end
data/lib/mad_chatter.rb CHANGED
@@ -1,23 +1,29 @@
1
- $:.unshift(File.dirname(__FILE__)) # add this directory to load path
2
- $:.unshift(Dir.pwd) # add current working directory for loading extensions
1
+ lib_dir = File.expand_path('..', __FILE__)
2
+ $:.unshift( lib_dir ) unless $:.include?( lib_dir )
3
3
 
4
- require 'bundler'
5
- Bundler.setup
6
- require 'em-websocket'
4
+ require 'bundler/setup'
5
+ require 'eventmachine'
7
6
  require 'json'
7
+ require 'digest/sha1'
8
8
 
9
+ require 'mad_chatter/action'
10
+ require 'mad_chatter/config'
11
+ require 'mad_chatter/extensions'
12
+ require 'mad_chatter/message'
9
13
  require 'mad_chatter/server'
10
- require 'mad_chatter/actions'
14
+ require 'mad_chatter/users'
11
15
 
12
- EventMachine.run do
16
+ require 'mad_chatter/actions/join'
17
+ require 'mad_chatter/actions/rename'
13
18
 
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
19
+ require 'mad_chatter/servers/em_websocket'
20
+
21
+ module MadChatter
22
+
23
+ def self.start
24
+ config = MadChatter::Config.init
25
+ server = MadChatter::Server.new(config)
26
+ server.start
27
+ end
22
28
 
23
29
  end
@@ -0,0 +1,6 @@
1
+ # ------------------------------------ #
2
+ # Mad Chatter Configuration #
3
+ # ------------------------------------ #
4
+
5
+ websocket_backend: MadChatter::Servers::EventMachineWebSocket
6
+ websocket_port: 8100
@@ -0,0 +1,13 @@
1
+ #
2
+ # Simple Mad Chatter Extensions
3
+ #
4
+ # You can add as many extensions as you want in this file using the
5
+ # simple extension syntax. For more complicated extensions, add your
6
+ # classes to the extensions directory.
7
+ #
8
+ # Example:
9
+ #
10
+ # on_message /hey andrew: (.+)/ do |msg|
11
+ # send_status_message 'Someone sent andrew a chat message'
12
+ # end
13
+ #
File without changes
@@ -110,7 +110,7 @@ var MadChatter = {
110
110
  },
111
111
 
112
112
  display_message: function(username, message){
113
- $("#messages").append("<p><strong>" + username + ":</strong> " + message + "<time>" + get_current_time() + "</time></p>");
113
+ $("#messages").append("<p class='message'><span class='username'>" + username + ":</span> " + message + "<time>" + get_current_time() + "</time></p>");
114
114
  },
115
115
 
116
116
  scroll_to_bottom_of_chat: function(){
@@ -20,28 +20,6 @@
20
20
  font: 14px Verdana, Geneva, Arial, Helvetica, sans-serif;
21
21
  padding: 5px;
22
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
23
 
46
24
  #chatroom{
47
25
  margin:0;
@@ -77,18 +55,22 @@
77
55
  padding: 0.25em;
78
56
  }
79
57
 
80
- #messages time {
58
+ #messages p.message .username {
59
+ font-weight: bold;
60
+ }
61
+
62
+ #messages p.message time, #messages p.status time {
81
63
  float: right;
82
64
  color: #999;
83
65
  }
84
66
 
85
- #messages .status {
67
+ #messages p.status {
86
68
  text-align: center;
87
69
  color: #999;
88
70
  }
89
71
 
90
72
  #keyboard{
91
- position:absolute;
73
+ /* position:absolute;*/
92
74
  bottom:0;
93
75
  left:220px;
94
76
  width:400%;
@@ -103,10 +85,10 @@
103
85
  }
104
86
 
105
87
  @media screen{
106
- #chatroom>div#sidebar{
88
+ #chatroom > div#sidebar{
107
89
  position:fixed;
108
90
  }
109
- #chatroom>div#keyboard{
91
+ #chatroom > div#keyboard{
110
92
  position:fixed;
111
93
  }
112
94
  }
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'mad_chatter'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestMadChatter < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mad_chatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,55 +9,126 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-11 00:00:00.000000000Z
12
+ date: 2011-12-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &2169798480 !ruby/object:Gem::Requirement
16
+ requirement: &2159049300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.14.6
21
+ version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2169798480
24
+ version_requirements: *2159049300
25
+ - !ruby/object:Gem::Dependency
26
+ name: eventmachine
27
+ requirement: &2159048600 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - =
31
+ - !ruby/object:Gem::Version
32
+ version: 0.12.10
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2159048600
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: em-websocket
27
- requirement: &2169797840 !ruby/object:Gem::Requirement
38
+ requirement: &2159031280 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
- - - ~>
41
+ - - ! '>='
31
42
  - !ruby/object:Gem::Version
32
- version: 0.3.5
43
+ version: '0'
33
44
  type: :runtime
34
45
  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
46
+ version_requirements: *2159031280
47
+ - !ruby/object:Gem::Dependency
48
+ name: shoulda
49
+ requirement: &2159030600 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2159030600
58
+ - !ruby/object:Gem::Dependency
59
+ name: bundler
60
+ requirement: &2159029860 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.0.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2159029860
69
+ - !ruby/object:Gem::Dependency
70
+ name: jeweler
71
+ requirement: &2159028900 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.6.4
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2159028900
80
+ - !ruby/object:Gem::Dependency
81
+ name: rcov
82
+ requirement: &2159027800 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *2159027800
91
+ description: Mad Chatter is a fun, easy to customize chat server, utilizing HTML 5
92
+ Web Sockets
38
93
  email: email@andrewhavens.com
39
94
  executables:
40
95
  - mad_chatter
41
96
  extensions: []
42
- extra_rdoc_files: []
97
+ extra_rdoc_files:
98
+ - LICENSE.txt
99
+ - README.md
43
100
  files:
44
- - lib/mad_chatter/actions/base.rb
101
+ - CHANGELOG.txt
102
+ - Gemfile
103
+ - Gemfile.lock
104
+ - LICENSE.txt
105
+ - README.md
106
+ - Rakefile
107
+ - bin/mad_chatter
108
+ - lib/mad_chatter.rb
109
+ - lib/mad_chatter/action.rb
45
110
  - lib/mad_chatter/actions/join.rb
46
111
  - lib/mad_chatter/actions/rename.rb
47
- - lib/mad_chatter/actions.rb
112
+ - lib/mad_chatter/config.rb
113
+ - lib/mad_chatter/extensions.rb
48
114
  - lib/mad_chatter/message.rb
49
115
  - lib/mad_chatter/server.rb
116
+ - lib/mad_chatter/servers/em_websocket.rb
117
+ - lib/mad_chatter/servers/juggernaut.rb
118
+ - lib/mad_chatter/servers/websocket_rack.rb
50
119
  - 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
120
+ - lib/mad_chatter/version.rb
121
+ - templates/config.yml
122
+ - templates/extensions.rb
123
+ - templates/web/index.html
124
+ - templates/web/javascript.js
125
+ - templates/web/stylesheets/reset.css
126
+ - templates/web/stylesheets/styles.css
127
+ - test/helper.rb
128
+ - test/test_mad_chatter.rb
59
129
  homepage: http://github.com/andrewhavens/mad_chatter
60
- licenses: []
130
+ licenses:
131
+ - MIT
61
132
  post_install_message:
62
133
  rdoc_options: []
63
134
  require_paths:
@@ -68,6 +139,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
139
  - - ! '>='
69
140
  - !ruby/object:Gem::Version
70
141
  version: '0'
142
+ segments:
143
+ - 0
144
+ hash: -79813361519807005
71
145
  required_rubygems_version: !ruby/object:Gem::Requirement
72
146
  none: false
73
147
  requirements:
data/README DELETED
File without changes
@@ -1,36 +0,0 @@
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
@@ -1,61 +0,0 @@
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