-
Notifications
You must be signed in to change notification settings - Fork 10
/
app.rb
125 lines (101 loc) · 2.5 KB
/
app.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require 'slim'
require 'sinatra/base'
require "sinatra/json"
require 'thin'
require 'cgi/cookie'
require 'nokogiri'
require 'em-websocket'
require './lib/uri'
require './lib/uploader'
require 'carrierwave'
COOKIE_KEY = 'rack.session'
COOKIE_SECRET = '*&(^B234312341234'
def _sanitize text
x = Nokogiri::HTML.fragment text
x.css('script,iframe').remove
x.css('a').each{|a| a['target']='_blank'}
x.css('audio,video').each{|m| m.remove_attribute('autoplay')}
x.to_s
end
class Channel < EM::Channel
@@channels = {}
attr_accessor :name, :histroy, :current_sub
def path
self.name=='/' ? '/' : "/channel/#{self.name}"
end
def initialize name
self.name = name
self.histroy = []
super()
end
def other_subs
@subs.reject{|sid| sid== self.current_sub}
end
def send(*item)
item = item.dup
EM.schedule { item.each { |i| other_subs.values.each { |s| s.call i } } }
end
def secure_push title, content
msg = "<dl><dt><span class='badge'>#{title} #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}</span></dt><dd>#{content}</dd></dl>"
msg = _sanitize msg
self.send msg
self.histroy << msg
end
def to_s
"#{name}(#{size}人在线)"
end
def size
@subs.length
end
def gc
@@channels.delete(name) if size==0 && name!='/'
end
class << self
def find_or_init channel
@@channels[channel] ||= new(channel)
end
def find channel
@@channels[channel] || new(channel)
end
def public
@@channels.reject{|key,value| key.start_with? '_'}
end
alias_method :[], :find_or_init
end
end
class App < Sinatra::Base
# register Sinatra::ActiveRecordExtension
# set :database, "sqlite3:///app.sqlite3"
enable :logging
use Rack::Session::Cookie, :key => COOKIE_KEY,
:path => '/',
:expire_after => 2592000, #30 days
:secret => COOKIE_SECRET
get '/' do
channel = '/'
session[:channel] = channel
session[:name] ||= "guest#{rand(10000..99999)}"
@channel=Channel.find channel
slim :index
end
get '/channel/:name' do |name|
channel = name
session[:channel] = channel
@channel=Channel.find channel
slim :index
end
get '/channel' do
slim :channels
end
post '/upload' do
@uploader = MyUploader.new
@uploader.store!(params['file'])
json url: @uploader.url, name: @uploader.filename,
type: @uploader.filename.split('.').last,
indenter: params[:file_indenter]
end
post '/username' do
session[:name] = params[:value]
halt 200
end
end