Skip to content
Browse files

Some refactoring.

  • Loading branch information...
1 parent 4842ae4 commit 689248a7ec0e1fe8da7e66a12536e1776ff57104 @whitequark committed Dec 25, 2012
View
3 Gemfile
@@ -1,6 +1,7 @@
source 'http://rubygems.org'
-gem 'sinatra', '~> 1.0'
+gem 'sinatra', '~> 1.3'
+gem 'sinatra-contrib', '~> 1.3'
gem 'haml'
gem 'sass'
gem 'sequel'
View
13 Gemfile.lock
@@ -1,6 +1,7 @@
GEM
remote: http://rubygems.org/
specs:
+ backports (2.6.5)
cinch (2.0.3)
daemons (1.1.9)
em-hiredis (0.1.1)
@@ -12,13 +13,22 @@ GEM
rack (1.4.1)
rack-protection (1.3.2)
rack
+ rack-test (0.6.2)
+ rack (>= 1.0)
redis (3.0.2)
sass (3.2.4)
sequel (3.42.0)
sinatra (1.3.3)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
+ sinatra-contrib (1.3.2)
+ backports (>= 2.0)
+ eventmachine
+ rack-protection
+ rack-test
+ sinatra (~> 1.3.0)
+ tilt (~> 1.3)
thin (1.5.0)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
@@ -36,5 +46,6 @@ DEPENDENCIES
redis
sass
sequel
- sinatra (~> 1.0)
+ sinatra (~> 1.3)
+ sinatra-contrib (~> 1.3)
thin
View
2 config/thin.yml
@@ -1,7 +1,7 @@
---
environment: production
pid: tmp/viewer.pid
-rackup: config/viewer.ru
+rackup: viewer.ru
log: log/viewer.log
socket: /tmp/irclogger.sock
daemonize: true
View
6 config/viewer.ru
@@ -1,6 +0,0 @@
-require './viewer'
-
-Sinatra::Base.set :run, false
-Sinatra::Base.set :environment, ENV['RACK_ENV']
-
-run Sinatra::Application
View
2 launch-logger.sh
@@ -4,4 +4,4 @@
rvm use 1.9.3
-./logger.rb </dev/null >/dev/null 2>&1 &
+bundle exec ./logger.rb </dev/null >/dev/null 2>&1 &
View
2 launch-viewer.sh
@@ -4,4 +4,4 @@
rvm use 1.9.3
-bundle exec thin -C /var/www/irclog.whitequark.org/config/thin.yml start
+bundle exec thin -C `dirname $0`/config/thin.yml start
View
4 lib/irclogger.rb
@@ -1,7 +1,9 @@
-require 'sequel'
require 'logger'
+require 'yaml'
+require 'sequel'
Config = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'config', 'application.yml'))
DB = Sequel.connect(Config['database'])
require 'irclogger/message'
+require 'irclogger/channel'
View
40 lib/irclogger/channel.rb
@@ -0,0 +1,40 @@
+require 'em-hiredis'
+
+module IrcLogger
+ module Channel
+ @subscribers = Hash.new { |h, k| h[k] = [] }
+
+ def self.subscribe(channel, &block)
+ @subscribers[channel] << block
+
+ block
+ end
+
+ def self.unsubscribe(channel, block)
+ @subscribers[channel].delete block
+
+ nil
+ end
+
+ def self.notify(channel, message_id)
+ message = Message[message_id]
+
+ @subscribers[channel].each do |block|
+ block.call(message)
+ end
+ end
+
+ def self.listen
+ EM::next_tick do
+ pubsub = EM::Hiredis.connect(Config['redis'])
+
+ pubsub.subscribe('message')
+
+ pubsub.on(:message) do |redis_channel, message|
+ channel, message_id = message.split
+ notify(channel, message_id)
+ end
+ end
+ end
+ end
+end
View
148 lib/irclogger/cinch_plugin.rb
@@ -0,0 +1,148 @@
+require 'cinch'
+
+module IrcLogger
+ class CinchPlugin
+ include Cinch::Plugin
+
+ class << self
+ attr_accessor :redis
+ end
+
+ def initialize(*)
+ super
+
+ @user_lists = Hash.new { |h,k| h[k] = Set.new }
+ @user_lists_mutex = Mutex.new
+ end
+
+ def redis
+ self.class.redis
+ end
+ protected :redis
+
+ def post_message(*args)
+ message = Message.create(*args)
+ redis.publish('message', "#{message.channel} #{message.id}")
+ end
+
+ def options(message, other_options={})
+ {
+ channel: message.channel,
+ timestamp: message.time
+ }.merge(other_options)
+ end
+
+ listen_to :channel, method: :on_channel
+ def on_channel(m)
+ unless m.action?
+ post_message(options(m,
+ nick: m.user.nick,
+ line: m.message))
+ end
+ end
+
+ listen_to :action, method: :on_action
+ def on_action(m)
+ post_message(options(m,
+ nick: "* " + m.user.nick,
+ line: m.action_message))
+ end
+
+ listen_to :topic, method: :on_topic
+ def on_topic(m)
+ post_message(options(m,
+ opcode: 'topic',
+ nick: m.user.nick,
+ line: "#{m.user.nick} changed the topic of #{m.channel} to: #{m.message}"))
+ end
+
+ listen_to :join, method: :on_join
+ def on_join(m)
+ post_message(options(m,
+ opcode: 'join',
+ nick: m.user.nick,
+ line: "#{m.user.nick} has joined #{m.channel}"))
+
+ @user_lists_mutex.synchronize do
+ if m.user.nick == bot.nick
+ @user_lists[m.channel.name] = m.channel.users.keys.map(&:nick).to_set
+ end
+
+ @user_lists[m.channel.name].add m.user.nick
+ end
+ end
+
+ listen_to :part, method: :on_part
+ def on_part(m)
+ post_message(options(m,
+ opcode: 'leave',
+ nick: m.user.nick,
+ line: "#{m.user.nick} has left #{m.channel} [#{m.message}]"))
+
+ @user_lists_mutex.synchronize do
+ @user_lists[m.channel.name].delete m.user.nick
+ end
+ end
+
+ listen_to :kick, method: :on_kick
+ def on_kick(m)
+ post_message(options(m,
+ opcode: 'kick',
+ nick: m.params[1],
+ line: "#{m.params[1]} was kicked from #{m.channel} by #{m.user.nick} [#{m.message}]"))
+
+ @user_lists_mutex.synchronize do
+ @user_lists[m.channel.name].delete m.user.nick
+ end
+ end
+
+ listen_to :ban, method: :on_ban do |m, ban|
+ user = m.channel.users.find {|user, _| ban.match(user)}.first
+ actual_nick = user && user.nick
+
+ if actual_nick
+ post_message(options(m,
+ opcode: 'ban',
+ nick: actual_nick,
+ line: "#{actual_nick} was banned on #{m.channel} by #{m.user.nick} [#{m.message}]"))
+ end
+ end
+
+ listen_to :nick, method: :on_nick
+ def on_nick(m)
+ @user_lists_mutex.synchronize do
+ @user_lists.each do |channel, users|
+ if users.include? m.user.last_nick
+ post_message(options(m,
+ channel: channel,
+ opcode: 'nick',
+ nick: m.user.last_nick,
+ line: "#{m.user.last_nick} is now known as #{m.user.nick}"))
+
+ users.delete m.user.last_nick
+ users.add m.user.nick
+ end
+ end
+ end
+ end
+
+ listen_to :quit, method: :on_quit
+ def on_quit(m)
+ @user_lists_mutex.synchronize do
+ @user_lists.each do |channel, users|
+ if users.include? m.user.nick
+ post_message({
+ timestamp: m.time,
+ channel: channel,
+ opcode: 'quit',
+ nick: m.user.nick,
+ line: "#{m.user.nick} has quit [#{m.message}]"
+ })
+
+ users.delete m.user.nick
+ end
+ end
+ end
+ end
+ end
+end
View
110 lib/irclogger/viewer.rb
@@ -0,0 +1,110 @@
+require 'date'
+
+require 'sinatra/base'
+require 'sinatra/reloader'
+require 'haml'
+require 'sass'
+
+require 'irclogger/channel'
+require 'irclogger/viewer_helpers'
+
+module IrcLogger
+ class Viewer < Sinatra::Base
+ set :views, File.expand_path('../../../views', __FILE__)
+ set :public_folder, File.expand_path('../../../public', __FILE__)
+
+ configure :development do
+ register Sinatra::Reloader
+ end
+
+ helpers ViewerHelpers
+
+ before do
+ @channels = DB["select channel from irclog group by channel"].map { |r| r[:channel] }
+ end
+
+ get '/' do
+ haml :index
+ end
+
+ get '/help/search' do
+ haml :'help/search'
+ end
+
+ get '/style.css' do
+ sass :style
+ end
+
+ get '/:channel' do
+ redirect "/#{params[:channel]}/"
+ end
+
+ get '/:channel/search' do
+ @channel = "##{params[:channel].gsub '.', '#'}"
+ @limit = 300
+
+ if params[:q].length >= 3
+ @messages = Message.search_in_channel(@channel, params[:q])
+ @message_count = @messages.count
+
+ @messages = @messages.limit(@limit, ((params[:page] || 1).to_i - 1) * @limit)
+ else
+ @message_count = 0
+ end
+
+ haml :search
+ end
+
+ get '/:channel/stream', provides: 'text/event-stream' do
+ response['X-Accel-Buffering'] = 'no'
+
+ channel = "##{params[:channel].gsub '.', '#'}"
+
+ last_message_id = env['HTTP_LAST_EVENT_ID'] || params['last_id']
+ last_messages = Message.recent_for_channel(channel, last_message_id.to_i)
+
+ render_one = lambda do |stream, message|
+ stream << "id: #{message.id}\n"
+
+ html = haml(:_message, locals: { message: message, dates: false }, layout: false)
+ html.lines.each do |line|
+ stream << "data: #{line}" # \n is already there
+ end
+
+ stream << "\n"
+ end
+
+ stream :keep_open do |out|
+ last_messages.each do |message|
+ render_one.(out, message)
+ end
+
+ subscriber_id = Channel.subscribe(channel) do |message|
+ render_one.(out, message)
+ end
+
+ proc = -> { Channel.unsubscribe(channel, subscriber_id) }
+ out.callback(&proc)
+ out.errback(&proc)
+ end
+ end
+
+ get '/:channel/:date?' do
+ @channel = "##{params[:channel].gsub '.', '#'}"
+ @date = Date.parse(params[:date]) rescue nil
+
+ if @date
+ @is_today = (@date == Time.now.gmtime.to_date)
+
+ dataset = Message.find_by_channel_and_date(@channel, @date)
+ @nicks = Message.nicks(dataset)
+ @messages = Message.track_chains(dataset, @nicks)
+ @topic = Message.most_recent_topic_for(@channel, @date)
+
+ haml :channel
+ else
+ redirect "/#{params[:channel]}/#{Time.now.gmtime.to_date}"
+ end
+ end
+ end
+end
View
96 lib/irclogger/viewer_helpers.rb
@@ -0,0 +1,96 @@
+module IrcLogger
+ module ViewerHelpers
+ include Rack::Utils
+
+ def channel(name)
+ name[1..-1].gsub '#', '.'
+ end
+
+ AUTO_LINK_REGEXP = %r{
+ ( # leading text
+ <\w+.*?>| # leading HTML tag, or
+ [^=!:'"/]| # leading punctuation, or
+ ^ # beginning of line
+ )
+ (
+ https?://| # protocol spec, or
+ www\. # www.*
+ )
+ (
+ [-\w]+ # subdomain or domain
+ (?:\.[-\w]+)* # remaining subdomains or domain
+ (?::\d+)? # port
+ (?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$])))*)* # path
+ (?:\?[\w\+@%&=.;-]+)? # query string
+ (?:\#[\w\-!:/]*)? # trailing anchor
+ )
+ ([[:punct:]]|<|$|) # trailing text
+ }xi
+
+ def format_message(text, nicks=nil)
+ text.gsub('&#x2F;', '/').gsub(AUTO_LINK_REGEXP) do
+ all, a, b, c, d = $&, $1, $2, $3, $4
+ if a =~ /<a\s/i # don't replace URL's that are already linked
+ all
+ else
+ text = b + c
+ %(#{a}<a href="#{text}" class="link" target="_blank">#{text}</a>#{d})
+ end
+ end.
+ # *bold*
+ gsub(/(^|\s)(\*[^\s](?:|.*?[^\s])\*)(\s|$)/, '\1<b>\2</b>\3').
+ # _underlined_
+ gsub(/(^|\s)(_[^\s](?:|.*?[^\s])_)(\s|$)/, '\1<u>\2</u>\3').
+ gsub(Message::NICK_PATTERN) do
+ if nicks && nicks.include?($1)
+ "<span class='chain'>#$1</span>"
+ else
+ $&
+ end
+ end
+ end
+
+ CAL_CACHE = Hash.new do |h, k|
+ h[k] = `cal #{k}`.split("\n")
+ end
+
+ def calendar(channel, date=nil, links=true)
+ origin = date || Date.today
+
+ cal = CAL_CACHE["#{origin.month} #{origin.year}"]
+ cal = "\n<span class='header'>#{cal[1]}</span>\n" + cal[2..-1].join("\n")
+ cal.gsub!("_\b", '')
+
+ if links
+ cal.gsub!(/\b(\d{1,2})\b/) do
+ d = origin.strftime("%Y-%m-#{$1.rjust 2, "0"}")
+ current = "current" if date && date.to_s == d
+
+ if Message.check_by_channel_and_date(channel, Date.parse(d))
+ %Q{<a class="#{current}" href="/#{channel channel}/#{d}">#{$1}</a>}
+ else
+ $1
+ end
+ end
+ end
+
+ next_date = origin >> 1
+ prev_date = origin << 1
+
+ header = "<span class='header'>#{origin.strftime("%B %Y").center(18)}</span>"
+ if links
+ link_if = ->(date, text) do
+ if Message.check_by_channel_and_month(channel, date)
+ %Q{<a href="/#{channel channel}/#{date}">#{text}</a>}
+ else
+ text
+ end
+ end
+
+ link_if.(prev_date, '&lt;') + header + link_if.(next_date, '&gt;') + cal
+ else
+ %Q{&lt;#{header}&gt;#{cal}}
+ end
+ end
+ end
+end
View
130 logger.rb
@@ -1,149 +1,29 @@
#!/usr/bin/env ruby
-require "rubygems"
-require "bundler/setup"
$: << File.join(File.dirname(__FILE__), 'lib')
-require 'set'
require 'irclogger'
-require 'cinch'
+require 'irclogger/cinch_plugin'
require 'redis'
pidfile = File.join(File.dirname(__FILE__), 'tmp', 'logger.pid')
File.open(pidfile, 'w') do |f|
f.write Process.pid
end
-redis = Redis.new(url: Config['redis'])
-
bot = Cinch::Bot.new do
configure do |c|
c.server = Config['server']
c.channels = Config['channels']
c.user = Config['username']
c.nick = Config['nickname']
c.realname = Config['realname']
- end
-
- post_message = lambda do |*args|
- message = Message.create(*args)
- redis.publish('message', "#{message.channel} #{message.id}")
- end
-
- options = lambda do |m, options|
- {
- channel: m.channel,
- timestamp: m.time
- }.merge(options)
- end
-
- user_lists = Hash.new { |h,k| h[k] = Set.new }
- user_lists_mutex = Mutex.new
-
- on :channel do |m|
- unless m.action?
- post_message.(options.(m,
- nick: m.user.nick,
- line: m.message))
- end
- end
-
- on :action do |m|
- post_message.(options.(m,
- nick: "* " + m.user.nick,
- line: m.action_message))
- end
-
- on :topic do |m|
- post_message.(options.(m,
- opcode: 'topic',
- nick: m.user.nick,
- line: "#{m.user.nick} changed the topic of #{m.channel} to: #{m.message}"))
- end
-
- on :join do |m|
- post_message.(options.(m,
- opcode: 'join',
- nick: m.user.nick,
- line: "#{m.user.nick} has joined #{m.channel}"))
- user_lists_mutex.synchronize do
- if m.user.nick == bot.nick
- user_lists[m.channel.name] = m.channel.users.keys.map(&:nick).to_set
- end
-
- user_lists[m.channel.name].add m.user.nick
- end
- end
-
- on :part do |m|
- post_message.(options.(m,
- opcode: 'leave',
- nick: m.user.nick,
- line: "#{m.user.nick} has left #{m.channel} [#{m.message}]"))
-
- user_lists_mutex.synchronize do
- user_lists[m.channel.name].delete m.user.nick
- end
- end
-
- on :kick do |m|
- post_message.(options.(m,
- opcode: 'kick',
- nick: m.params[1],
- line: "#{m.params[1]} was kicked from #{m.channel} by #{m.user.nick} [#{m.message}]"))
-
- user_lists_mutex.synchronize do
- user_lists[m.channel.name].delete m.user.nick
- end
- end
-
- on :ban do |m, ban|
- user = m.channel.users.find {|user, _| ban.match(user)}.first
- actual_nick = user && user.nick
-
- if actual_nick
- post_message.(options.(m,
- opcode: 'ban',
- nick: actual_nick,
- line: "#{actual_nick} was banned on #{m.channel} by #{m.user.nick} [#{m.message}]"))
- end
- end
-
- on :nick do |m|
- user_lists_mutex.synchronize do
- user_lists.each do |channel, users|
- if users.include? m.user.last_nick
- post_message.(options.(m,
- channel: channel,
- opcode: 'nick',
- nick: m.user.last_nick,
- line: "#{m.user.last_nick} is now known as #{m.user.nick}"))
-
- users.delete m.user.last_nick
- users.add m.user.nick
- end
- end
- end
- end
-
- on :quit do |m|
- user_lists_mutex.synchronize do
- user_lists.each do |channel, users|
- if users.include? m.user.nick
- post_message.({
- timestamp: m.time,
- channel: channel,
- opcode: 'quit',
- nick: m.user.nick,
- line: "#{m.user.nick} has quit [#{m.message}]"
- })
-
- users.delete m.user.nick
- end
- end
- end
+ # cinch, oh god why?!
+ c.plugins.plugins = [IrcLogger::CinchPlugin]
end
end
+IrcLogger::CinchPlugin.redis = Redis.new(url: Config['redis'])
+
bot.start
View
226 viewer.rb
@@ -1,226 +0,0 @@
-require "rubygems"
-require "bundler/setup"
-$: << File.join(File.dirname(__FILE__), 'lib')
-
-require 'sinatra'
-require 'haml'
-require 'sass'
-require 'date'
-require 'irclogger'
-require 'em-hiredis'
-
-module Channel
- @subscribers = Hash.new { |h, k| h[k] = [] }
-
- def self.subscribe(channel, &block)
- @subscribers[channel] << block
-
- block
- end
-
- def self.unsubscribe(channel, block)
- @subscribers[channel].delete block
-
- nil
- end
-
- def self.notify(channel, message_id)
- message = Message[message_id]
-
- @subscribers[channel].each do |block|
- block.call(message)
- end
- end
-end
-
-EM::next_tick do
- pubsub = EM::Hiredis.connect(Config['redis'])
- pubsub.subscribe('message')
- pubsub.on(:message) do |redis_channel, message|
- channel, message_id = message.split
- Channel.notify(channel, message_id)
- end
-end
-
-helpers do
- include Rack::Utils
-
- def channel(name)
- name[1..-1].gsub '#', '.'
- end
-
- AUTO_LINK_REGEXP = %r{
- ( # leading text
- <\w+.*?>| # leading HTML tag, or
- [^=!:'"/]| # leading punctuation, or
- ^ # beginning of line
- )
- (
- https?://| # protocol spec, or
- www\. # www.*
- )
- (
- [-\w]+ # subdomain or domain
- (?:\.[-\w]+)* # remaining subdomains or domain
- (?::\d+)? # port
- (?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$])))*)* # path
- (?:\?[\w\+@%&=.;-]+)? # query string
- (?:\#[\w\-!:/]*)? # trailing anchor
- )
- ([[:punct:]]|<|$|) # trailing text
- }xi
-
- def format_message(text, nicks=nil)
- text.gsub('&#x2F;', '/').gsub(AUTO_LINK_REGEXP) do
- all, a, b, c, d = $&, $1, $2, $3, $4
- if a =~ /<a\s/i # don't replace URL's that are already linked
- all
- else
- text = b + c
- %(#{a}<a href="#{text}" class="link" target="_blank">#{text}</a>#{d})
- end
- end.
- # *bold*
- gsub(/(^|\s)(\*[^\s](?:|.*?[^\s])\*)(\s|$)/, '\1<b>\2</b>\3').
- # _underlined_
- gsub(/(^|\s)(_[^\s](?:|.*?[^\s])_)(\s|$)/, '\1<u>\2</u>\3').
- gsub(Message::NICK_PATTERN) do
- if nicks && nicks.include?($1)
- "<span class='chain'>#$1</span>"
- else
- $&
- end
- end
- end
-
- CAL_CACHE = Hash.new do |h, k|
- h[k] = `cal #{k}`.split("\n")
- end
-
- def calendar(channel, date=nil, links=true)
- origin = date || Date.today
-
- cal = CAL_CACHE["#{origin.month} #{origin.year}"]
- cal = "\n<span class='header'>#{cal[1]}</span>\n" + cal[2..-1].join("\n")
- cal.gsub!("_\b", '')
-
- if links
- cal.gsub!(/\b(\d{1,2})\b/) do
- d = origin.strftime("%Y-%m-#{$1.rjust 2, "0"}")
- current = "current" if date && date.to_s == d
-
- if Message.check_by_channel_and_date(channel, Date.parse(d))
- %Q{<a class="#{current}" href="/#{channel channel}/#{d}">#{$1}</a>}
- else
- $1
- end
- end
- end
-
- next_date = origin >> 1
- prev_date = origin << 1
-
- header = "<span class='header'>#{origin.strftime("%B %Y").center(18)}</span>"
- if links
- link_if = ->(date, text) do
- if Message.check_by_channel_and_month(channel, date)
- %Q{<a href="/#{channel channel}/#{date}">#{text}</a>}
- else
- text
- end
- end
-
- link_if.(prev_date, '&lt;') + header + link_if.(next_date, '&gt;') + cal
- else
- %Q{&lt;#{header}&gt;#{cal}}
- end
- end
-end
-
-before do
- @channels = DB["select channel from irclog group by channel"].map { |r| r[:channel] }
-end
-
-get '/' do
- haml :index
-end
-
-get '/help/search' do
- haml :search_help
-end
-
-get '/style.css' do
- sass :style
-end
-
-get '/:channel' do
- redirect "/#{params[:channel]}/"
-end
-
-get '/:channel/search' do
- @channel = "##{params[:channel].gsub '.', '#'}"
- @limit = 300
-
- if params[:q].length >= 3
- @messages = Message.search_in_channel(@channel, params[:q])
- @message_count = @messages.count
-
- @messages = @messages.limit(@limit, ((params[:page] || 1).to_i - 1) * @limit)
- else
- @message_count = 0
- end
-
- haml :search
-end
-
-get '/:channel/stream', provides: 'text/event-stream' do
- response['X-Accel-Buffering'] = 'no'
-
- channel = "##{params[:channel].gsub '.', '#'}"
-
- last_message_id = env['HTTP_LAST_EVENT_ID'] || params['last_id']
- last_messages = Message.recent_for_channel(channel, last_message_id.to_i)
-
- render_one = lambda do |stream, message|
- stream << "id: #{message.id}\n"
-
- html = haml(:_message, locals: { message: message, dates: false }, layout: false)
- html.lines.each do |line|
- stream << "data: #{line}" # \n is already there
- end
-
- stream << "\n"
- end
-
- stream :keep_open do |out|
- last_messages.each do |message|
- render_one.(out, message)
- end
-
- subscriber_id = Channel.subscribe(channel) do |message|
- render_one.(out, message)
- end
-
- proc = -> { Channel.unsubscribe(channel, subscriber_id) }
- out.callback(&proc)
- out.errback(&proc)
- end
-end
-
-get '/:channel/:date?' do
- @channel = "##{params[:channel].gsub '.', '#'}"
-
- if params[:date]
- @date = Date.parse(params[:date])
- @is_today = (@date == Time.now.gmtime.to_date)
-
- dataset = Message.find_by_channel_and_date(@channel, @date)
- @nicks = Message.nicks(dataset)
- @messages = Message.track_chains(dataset, @nicks)
- @topic = Message.most_recent_topic_for(@channel, @date)
-
- haml :channel
- else
- redirect "/#{params[:channel]}/#{Time.now.gmtime.to_date}"
- end
-end
View
8 viewer.ru
@@ -0,0 +1,8 @@
+$: << File.join(File.dirname(__FILE__), 'lib')
+
+require 'irclogger'
+require 'irclogger/viewer'
+
+IrcLogger::Channel.listen
+
+run IrcLogger::Viewer
View
13 views/help/search.haml
@@ -0,0 +1,13 @@
+%section#log
+ %p
+ How to search:
+
+ %ul
+ %li
+ You can use standard <a href='http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html'>MySQL fulltext search</a> operations.
+
+ %li
+ You can fetch a history of kicks and bans of a particular user by searching for "kickban:username".
+
+ %li
+ You can fetch a list of all messages by a particular user by searching for "nick:username".
View
6 views/index.haml
@@ -21,4 +21,8 @@
.talk
%a.timestamp= now
- When there is a yellow arrow to the left of nick, you can click on it to highlight the chain of replies.
+ When there is a yellow arrow to the left of nick, you can click on it to highlight the chain of replies.
+
+ .talk
+ %a.timestamp= now
+ If you want for this logger to be present on a particular <a href="http://freenode.net">freenode.net</a> channel, drop a letter to <a href="mailto:whitequark@whitequark.org">whitequark</a>.
View
12 views/search_help.haml
@@ -1,12 +0,0 @@
-%section#log
- How to search:
-
- %ul
- %li
- You can use standard <a href='http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html'>MySQL fulltext search</a> operations.
-
- %li
- You can fetch a history of kicks and bans of a particular user by searching for "kickban:username".
-
- %li
- You can fetch a list of all messages by a particular user by searching for "nick:username".

0 comments on commit 689248a

Please sign in to comment.
Something went wrong with that request. Please try again.