Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit e0436d71e617ac5a576b989a863816f92222eb37 Christopher Warren committed Aug 10, 2011
@@ -0,0 +1,5 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
+Chatfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in ceiling_cat.gemspec
+gemspec
@@ -0,0 +1,7 @@
+#!/usr/bin/env ruby
+require 'rubygems'
+require 'ceiling_cat'
+
+load ARGV[0] || './Chatfile'
+
+CeilingCat::Setup.new.connect
@@ -0,0 +1,35 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "ceiling_cat/version"
+
+Gem::Specification.new do |s|
+ s.name = "ceiling_cat"
+ s.version = CeilingCat::VERSION
+ s.authors = ["Chris Warren"]
+ s.email = ["chris@zencoder.com"]
+ s.homepage = "http://zencoder.com"
+ s.summary = %q{Ceiling Cat is watching you chat. A Campfire chat bot.}
+ s.description = %q{Ceiling Cat is watching you chat. A Campfire chat bot!}
+
+ s.rubyforge_project = "ceiling_cat"
+
+ s.add_dependency "tinder"
+
+ s.files = ["lib/ceiling_cat.rb",
+ "lib/ceiling_cat/setup.rb",
+ "lib/ceiling_cat/version.rb",
+ "lib/ceiling_cat/connection.rb",
+ "lib/ceiling_cat/errors.rb",
+ "lib/ceiling_cat/event.rb",
+ "lib/ceiling_cat/user.rb",
+ "lib/ceiling_cat/room.rb",
+ "lib/ceiling_cat/plugin/base.rb",
+ "lib/ceiling_cat/campfire/connection.rb",
+ "lib/ceiling_cat/campfire/event.rb",
+ "lib/ceiling_cat/campfire/room.rb",
+ "lib/ceiling_cat/plugin/calc.rb"
+ ]
+ s.test_files = []
+ s.executables = ["ceiling_cat"]
+ s.require_paths = ["lib"]
+end
@@ -0,0 +1,9 @@
+# General
+%w{version setup connection errors event user room plugin/base}.each do |file|
+ require "ceiling_cat/#{file}"
+end
+
+# Campfire
+%w{connection room event}.each do |file|
+ require "ceiling_cat/campfire/#{file}"
+end
@@ -0,0 +1,16 @@
+require 'tinder'
+
+module CeilingCat
+ module Campfire
+ class Connection < CeilingCat::Connection
+ def initialize(config)
+ @config=config
+ @config.ssl ||= "true"
+ end
+
+ def campfire
+ @campfire = Tinder::Campfire.new(self.config.username, :token => self.config.token, :ssl => self.config.ssl)
+ end
+ end
+ end
+end
@@ -0,0 +1,11 @@
+module CeilingCat
+ module Campfire
+ class Event < CeilingCat::Event
+
+ def handle
+ puts "#{user.short_name} says: #{@body} at #{@time}"
+ end
+
+ end
+ end
+end
@@ -0,0 +1,84 @@
+module CeilingCat
+ module Campfire
+ class Room < CeilingCat::Room
+ def initialize(opts={})
+ super
+ @room = @connection.campfire.find_room_by_name(opts[:room_name])
+ end
+
+ def watch
+ setup_interrupts
+ begin
+ @room.listen do |event|
+ begin
+ @user = CeilingCat::User.new(event[:user][:name], :id => event[:user][:id], :role => event[:user][:type])
+ @body = event[:body]
+ @type = event[:type]
+ unless is_me?(@user) # Otherwise CC will talk to itself
+ super
+ end
+ rescue
+ puts "An error occured with Campfire: #{$!}"
+ end
+ end
+ rescue StandardError => e
+ puts e
+ end
+ end
+
+ def is_me?(user)
+ user.id == me.id
+ end
+
+ def me
+ @me || CeilingCat::User.new(@connection.campfire.me[:id], :id => @connection.campfire.me[:id], :role => @connection.campfire.me[:type])
+ end
+
+ def users_in_room
+ @room.users
+ end
+
+ def registered_users_in_room
+ @registered_users_in_room = useusers_in_roomrs.find_all do |user|
+ if user[:type].to_s.downcase == 'member' && !is_me?(user[:id])
+ CeilingCat::User.new(user[:name], :id => user[:id], :role => user[:type])
+ end
+ end
+ super
+ end
+
+ def unregistered_users_in_room
+ @registered_users_in_room = users_in_room.find_all do |user|
+ if user[:type].to_s.downcase == 'guest'
+ CeilingCat::User.new(user[:name], :id => user[:id], :role => user[:type])
+ end
+ end
+ super
+ end
+
+ def say(something_to_say)
+ something_to_say = [something_to_say] unless something_to_say.is_a?(Array)
+
+ something_to_say.each do |line|
+ @room.speak(line)
+ end
+ end
+
+ def setup_interrupts
+ trap('INT') do
+ puts "Leaving room...."
+ @room.leave if @room
+ exit 1
+ end
+
+ trap('USR1') do
+ # logger.info "Leaving room"
+ @room.leave if @room
+ # logger.info "Reloading config"
+ # config(true)
+ # raise ReloadException.new("Rejoin room please, ceiling cat")
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,14 @@
+module CeilingCat
+ class Connection
+ attr_accessor :config
+
+ def initialize(config)
+ @config=config
+ end
+
+ def plugins
+ self.config.plugins
+ end
+
+ end
+end
@@ -0,0 +1,15 @@
+module CeilingCat
+ class Error < StandardError
+
+ def initialize(message)
+ super message
+ end
+ end
+
+ # Gem Specific Errors
+ class CeilingCatError < StandardError; end
+
+ class UnsupportedChatServiceError < CeilingCatError; end
+
+ class NotImplementedError < CeilingCatError; end
+end
@@ -0,0 +1,26 @@
+module CeilingCat
+ class Event
+ attr_accessor :room, :body, :user, :type, :time
+
+ def initialize(room, body,user,opts={})
+ @room = room
+ @body = body
+ @user = user
+ @type = opts[:type]
+ @time = opts[:time] || Time.now
+ end
+
+ def handle
+ puts "#{user.short_name} says: #{@body} at #{@time}"
+ # @room.say "What up #{user}"
+ @room.plugins.each do |plugin|
+ begin
+ response = plugin.new(self).handle
+ break if response == true
+ rescue => e
+ @room.say("Whoops - there was a problem with a plugin")
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,39 @@
+module CeilingCat
+ module Plugin
+ class Base
+ attr_accessor :room, :body, :user, :type, :time
+
+ def initialize(event)
+ @room = event.room
+ @body = event.body
+ @user = event.user
+ @type = event.type
+ @time = event.time
+ end
+
+ def handle
+ raise NotImplementedError, "Implement in plugin!"
+ end
+
+ def reply(message)
+ @room.say(message)
+ end
+
+ def body_without_command
+ @body.sub(command,"")
+ end
+
+ def talking_to_me?
+ @body =~ /(^|\s)#{@room.me.name}(\s|$)/i
+ end
+
+ def words
+ @body.split
+ end
+
+ def body_without_nick
+ @body.sub(@room.me.name,'')
+ end
+ end
+ end
+end
@@ -0,0 +1,21 @@
+module CeilingCat
+ module Plugin
+ class Calc < CeilingCat::Plugin::Base
+
+ def handle
+ if @body =~ command
+ begin
+ reply("#{body_without_command} = #{eval body_without_command}")
+ rescue
+ reply "I couldn't calculate that. Are you sure it's a math equation?"
+ end
+ end
+ end
+
+ def command
+ /^calculate/i
+ end
+
+ end
+ end
+end
@@ -0,0 +1,33 @@
+module CeilingCat
+ class Room
+ attr_accessor :connection, :room, :body, :user, :type, :registered_users_in_room, :unregistered_users_in_room
+
+ def initialize(opts={})
+ @connection = opts[:connection]
+ end
+
+ def watch
+ CeilingCat::Event.new(self, @body, @user, @type).handle if (@body || @user || @type)
+ end
+
+ def plugins
+ @connection.plugins
+ end
+
+ def registered_users_in_room
+ if @registered_users_in_room
+ @registered_users_in_room
+ else
+ []
+ end
+ end
+
+ def unregistered_users_in_room
+ if @unregistered_users_in_room
+ @unregistered_users_in_room
+ else
+ []
+ end
+ end
+ end
+end
@@ -0,0 +1,47 @@
+require 'ostruct'
+
+module CeilingCat
+ class Setup
+
+ attr_accessor :config
+
+ class << self
+ # Class-level config. This is set by the +configure+ class method,
+ # and is used if no configuration is passed to the +initialize+
+ # method.
+ attr_accessor :config
+ end
+
+ # Configures the connection at the class level. When the +ceiling_cat+ bin
+ # file is loaded, it evals the file referenced by the first
+ # command-line parameter. This file can configure the connection
+ # instance later created by +robut+ by setting parameters in the
+ # CeilingCat::Connection.configure block.
+ def self.configure
+ self.config = OpenStruct.new
+ yield config
+ end
+
+ # Sets the instance config to +config+, converting it into an
+ # OpenStruct if necessary.
+ def config=(config)
+ @config = config.kind_of?(Hash) ? OpenStruct.new(config) : config
+ end
+
+ def initialize(_config = nil)
+ self.config = _config || self.class.config
+ end
+
+ def connect
+ case self.config.service.downcase
+ when 'campfire'
+ connection = CeilingCat::Campfire::Connection.new(self.config)
+ room = CeilingCat::Campfire::Room.new(:connection => connection, :room_name => self.config.room)
+ room.watch
+ else
+ raise CeilingCat::UnsupportedChatServiceError.new("#{self.config.service} is not a supported chat service.")
+ end
+ end
+
+ end
+end
Oops, something went wrong.

0 comments on commit e0436d7

Please sign in to comment.