-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathchat.rb
102 lines (79 loc) · 2.84 KB
/
chat.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
require "rubygems"
require "yaml" # ... or where we will store the chat messages ...
require "ftools" # ... or we wanna access the filesystem ...
require "sinatra" # ... or Classy web-development dressed in DSL, http://sinatrarb.com
# Let's configure Sinatra logging in production
# configure :production do
# log = File.new("sinatra.log", "a")
# STDERR.reopen(log)
# STDOUT.reopen(log)
# end
# -----------------------------------------------------------------------------
# = Singleton object to hold the chat 'server'
#
class Chat
@@yaml_file = File.join( File.dirname(__FILE__), 'messages.yml' )
# Initializes the chat
def self.start
puts "Starting chat server..."
load_messages
raise 'YAML file not writable' unless File.writable? @@yaml_file
end
# Load the messages from file and send the new ones in response
def self.listen(from=0)
start unless @@messages
# puts "* | Load messages from time: #{Time.at(from.to_i)}"
# puts " | #{@@messages.inspect}"
@@messages.clone.delete_if { |m| m[:created_at].to_i <= from.to_i if m[:created_at] } # Kick out old messages
end
# Write the message to file
def self.speak(author='', message='Testing the chat...')
# puts ">>> #{author} wants to say #{message}"
tmpfile = File.join( File.dirname(__FILE__), 'messages.tmp' )
File.open(tmpfile, 'w') do |f|
f << ( @@messages << { :author => author, :message => message, :created_at => Time.now.to_i } ).to_yaml
end
File.copy(tmpfile, @@yaml_file) # We have to do an 'atomic write' (Google it :)
File.delete(tmpfile)
end
def self.messages
@@messages
end
private
# Load messages from YAML
def self.load_messages
# puts "Reading messages from YAML file"
@@messages = YAML.load_file( @@yaml_file )
end
end#Chat
# -----------------------------------------------------------------------------
# == Helpers
helpers do
def human_date(t)
Time.at(t).strftime('%m/%d').gsub(/0(\d)/, '\1') +
' ' +
Time.at(t).strftime('%H:%M')
end
end
# == 'Routing' & 'Controllers' of the application
# Main screen
get '/' do
Chat.start
@messages = Chat.messages
@remote_ip = self.request.env['REMOTE_ADDR']
erb :index
end
# Listen for messages in chat
get '/listen' do
out = ""
Chat.listen(params[:from]).each do |m|
out << "<p id=\"#{m[:created_at]}\"><strong>#{m[:author]}</strong> <em>says</em> <span>#{m[:message]}</span><span class='d'> @ #{human_date(m[:created_at])}</span></p>"
end
out
end
# Post messages to chat
post '/speak' do
Chat.speak params[:author], params[:message] unless params[:message] == '' or params[:author] == ''
redirect '/' unless self.request.env['HTTP_X_REQUESTED_WITH'] and
self.request.env['HTTP_X_REQUESTED_WITH'].scan(/XML/) # Don't redirect Ajax request...
end