ceiling_cat 0.0.2 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
  # General
2
- %w{version setup connection errors event user room plugins/base services/campfire storage/base storage/yaml}.each do |file|
2
+ %w{version setup connection errors event user room plugins/base services/campfire storage/base storage/hash storage/yaml}.each do |file|
3
3
  require "ceiling_cat/#{file}"
4
4
  end
@@ -23,7 +23,7 @@ module CeilingCat
23
23
  end
24
24
 
25
25
  def type # assume that all messages are just text unless the specific room type overrides it.
26
- :chat
26
+ @type || :chat
27
27
  end
28
28
  end
29
29
  end
@@ -53,7 +53,7 @@ module CeilingCat
53
53
  end
54
54
 
55
55
  def self.store
56
- CeilingCat::Setup.config.storage
56
+ CeilingCat::Setup.config ? CeilingCat::Setup.config.storage : CeilingCat::Storage::Hash
57
57
  end
58
58
 
59
59
  def body
@@ -3,11 +3,11 @@ module CeilingCat
3
3
  class CallAndResponse < CeilingCat::Plugin::Base
4
4
  def handle
5
5
  if event.type == :chat
6
- super
7
6
  if match = self.class.list.find{|car| body =~ Regexp.new(Regexp.escape(car[:call]),true) }
8
7
  reply match[:response]
9
8
  return nil
10
9
  end
10
+ super
11
11
  end
12
12
 
13
13
  end
@@ -43,7 +43,7 @@ module CeilingCat
43
43
  end
44
44
 
45
45
  def add
46
- message = body_without_nick_or_command("add call").split
46
+ message = body_without_nick_or_command("add call")
47
47
  call, response = message.split("|")
48
48
  if self.class.add(:call => call.strip,:response => response.strip)
49
49
  reply "Call and Response added."
@@ -67,7 +67,7 @@ module CeilingCat
67
67
  store["call_and_responses"] = (store["call_and_responses"] + [{:call => opts[:call], :response => opts[:response]}]).uniq
68
68
  end
69
69
 
70
- def self.remove(phrase)
70
+ def self.remove(call)
71
71
  store["call_and_responses"] ||= []
72
72
  store["call_and_responses"] = store["call_and_responses"].reject{|car| car[:call].downcase == call.downcase }
73
73
  end
@@ -12,7 +12,9 @@ module CeilingCat
12
12
  if room.connection.config.service.downcase == "campfire" && event.type == :entrance
13
13
  user_count = room.connection.total_user_count
14
14
  max_users = room.connection.config.max_users || 100
15
- room.plugin("notifo").new(@event).deliver("#{user_count} of #{max_users} max connections to Campfire.") if room.plugin_installed?("notifo") && user_count > max_users-2
15
+ if room.plugin_installed?("notifo") && user_count > max_users-2
16
+ room.plugin("notifo").new(@event).deliver("#{user_count} of #{max_users} max connections to Campfire.")
17
+ end
16
18
  end
17
19
  super
18
20
  end
@@ -1,6 +1,6 @@
1
1
  module CeilingCat
2
2
  class NotADateError < CeilingCatError; end
3
-
3
+
4
4
  module Plugin
5
5
  class Days < CeilingCat::Plugin::Base
6
6
  def self.commands
@@ -62,8 +62,7 @@ module CeilingCat
62
62
  end
63
63
  end
64
64
 
65
- store["holidays"] ||= []
66
- store["holidays"] = (store["holidays"] + dates).uniq
65
+ store["holidays"] = (holidays + dates).uniq
67
66
  end
68
67
 
69
68
  def self.remove_from_holidays(days)
@@ -75,13 +74,12 @@ module CeilingCat
75
74
  end
76
75
  end
77
76
 
78
- store["holidays"] ||= []
79
- store["holidays"] = store["holidays"] - dates
77
+ store["holidays"] = holidays - dates
80
78
  end
81
79
 
82
80
  def self.is_a_holiday?(date=Date.today)
83
81
  if is_a_date?(date)
84
- store["holidays"].include? Date.parse(date.to_s)
82
+ holidays.include? Date.parse(date.to_s)
85
83
  else
86
84
  raise NotADateError
87
85
  end
@@ -2,7 +2,7 @@ module CeilingCat
2
2
  module Plugin
3
3
  class Greeter < CeilingCat::Plugin::Base
4
4
  def handle
5
- message = []
5
+ messages = []
6
6
 
7
7
  if event.type == :entrance
8
8
  members = room.users_in_room(:type => "member")
@@ -12,7 +12,7 @@ module CeilingCat
12
12
  elsif user.is_registered?
13
13
  messages << "Nice to see you again #{user.name}"
14
14
  end
15
- reply message unless message.empty?
15
+ reply messages unless messages.empty?
16
16
  elsif event.type == :chat
17
17
  super
18
18
  end
@@ -18,14 +18,19 @@ module CeilingCat
18
18
  :body => { :to => user, :msg => message },
19
19
  :basic_auth => {:username => store["notifo_credentials"][:username], :password => store["notifo_credentials"][:api_secret]})
20
20
  end
21
- else
22
- debugger
23
- puts "here"
24
21
  end
25
22
  end
26
23
 
24
+ def self.active?
25
+ if store["notifo_credentials"] && store["notifo_credentials"][:username].present? && store["notifo_credentials"][:api_secret].present? && Array(store["notifo_users"]).size > 0
26
+ true
27
+ else
28
+ false
29
+ end
30
+ end
31
+
27
32
  def active?
28
- store["notifo_credentials"] && store["notifo_credentials"][:username].present? && store["notifo_credentials"][:api_secret].present? && Array(store["notifo_users"]).size > 0
33
+ self.class.active?
29
34
  end
30
35
 
31
36
  def self.name
@@ -40,6 +45,11 @@ module CeilingCat
40
45
  store["notifo_users"] ||= []
41
46
  store["notifo_users"] = (Array(store["notifo_users"]) + Array(users)).uniq
42
47
  end
48
+
49
+ def self.remove_users(users)
50
+ store["notifo_users"] ||= []
51
+ store["notifo_users"] = (Array(store["notifo_users"]) - Array(users)).uniq
52
+ end
43
53
 
44
54
  def self.set_credentials(username, api_secret)
45
55
  store["notifo_credentials"] = {:username => username, :api_secret => api_secret}
@@ -53,8 +63,7 @@ module CeilingCat
53
63
 
54
64
  def remove_users
55
65
  users = body_without_nick_or_command("remove notifo users").split(" ")
56
- store["notifo_users"] ||= []
57
- store["notifo_users"] = store["notifo_users"] - users
66
+ self.class.remove_users(users)
58
67
  reply "#{users.join(" ")} removed from notifo alerts."
59
68
  end
60
69
 
@@ -43,10 +43,6 @@ module CeilingCat
43
43
  @connection.storage
44
44
  end
45
45
 
46
- def debug_mode?
47
- !store["debug_mode"].nil? && store["debug_mode"] == "true"
48
- end
49
-
50
46
  def plugin_descriptions(show_private=false)
51
47
  messages = []
52
48
  plugins.each do |plugin|
@@ -4,7 +4,7 @@ module CeilingCat
4
4
  module Campfire
5
5
  class Connection < CeilingCat::Connection
6
6
  def initialize(config)
7
- @config=config
7
+ super
8
8
  @config.ssl ||= "true"
9
9
  end
10
10
 
@@ -4,11 +4,11 @@ module CeilingCat
4
4
 
5
5
  def type
6
6
  case @type
7
- when "EnterMessage"
7
+ when "EnterMessage", :entrance
8
8
  :entrance
9
- when "TextMessage"
9
+ when "TextMessage", :chat
10
10
  :chat
11
- when "LeaveMessage", "KickMessage"
11
+ when "LeaveMessage", "KickMessage", :exit
12
12
  :exit
13
13
  end
14
14
  end
@@ -1,24 +1,25 @@
1
1
  module CeilingCat
2
2
  module Campfire
3
3
  class Room < CeilingCat::Room
4
+ attr_accessor :campfire_room
4
5
 
5
6
  def initialize(opts={})
6
7
  super
7
8
  @campfire_room = @connection.campfire.find_room_by_name(opts[:room_name])
8
9
  end
9
-
10
+
10
11
  def watch
11
12
  puts "Watching room..."
12
13
  setup_interrupts
13
14
  begin
14
15
  loop do
15
16
  begin
16
- Timeout::timeout(60) do
17
+ Timeout::timeout(300) do
17
18
  @campfire_room.listen do |event|
18
19
  begin
19
20
  if event[:type] != "TimestampMessage"
20
21
  user = CeilingCat::User.new(event[:user][:name], :id => event[:user][:id], :role => event[:user][:type])
21
-
22
+
22
23
  unless is_me?(user) # Otherwise CC will talk to itself
23
24
  event = CeilingCat::Campfire::Event.new(self,event[:body], user, :type => event[:type])
24
25
  event.handle
@@ -26,19 +27,20 @@ module CeilingCat
26
27
  end
27
28
  end
28
29
  rescue => e
29
- say "An error occurred with Campfire: #{e}" if debug_mode?
30
30
  raise e
31
31
  end
32
32
  end
33
33
  end
34
34
  rescue Timeout::Error
35
- puts "timeout! trying again..."
36
- retry
35
+ retry # Reconnect regularly to keep CC talking with Campfire
37
36
  end
38
37
  end
39
38
  rescue Faraday::Error::ParsingError
40
39
  puts "Error parsing response. Campfire may be down."
41
40
  break
41
+ rescue HTTP::Parser::Error
42
+ puts "Trouble parsing the HTTP response."
43
+ retry
42
44
  rescue ReloadException => e
43
45
  retry
44
46
  rescue NoMethodError => e
@@ -49,22 +51,21 @@ module CeilingCat
49
51
  retry
50
52
  rescue StandardError => e
51
53
  puts e.class
52
- debugger if debug_mode?
53
54
  e.backtrace.each do |line|
54
55
  puts "Backtrace: #{line}"
55
56
  end
56
57
  retry
57
58
  end
58
59
  end
59
-
60
+
60
61
  def is_me?(user)
61
62
  user.id == me.id
62
63
  end
63
-
64
+
64
65
  def me
65
66
  @me ||= CeilingCat::User.new(@connection.campfire.me[:name], :id => @connection.campfire.me[:id], :role => @connection.campfire.me[:type])
66
67
  end
67
-
68
+
68
69
  def users_in_room(opts={})
69
70
  if opts[:reload] || @users_in_room.nil?
70
71
  puts "Requesting user list"
@@ -83,13 +84,13 @@ module CeilingCat
83
84
  end
84
85
  end
85
86
  end
86
-
87
+
87
88
  def say(something_to_say)
88
89
  Array(something_to_say).each do |line|
89
90
  @campfire_room.speak(line)
90
91
  end
91
92
  end
92
-
93
+
93
94
  def setup_interrupts
94
95
  trap('INT') do
95
96
  puts "Leaving room...."
@@ -0,0 +1,29 @@
1
+ module CeilingCat
2
+ module Storage
3
+ class Hash < CeilingCat::Storage::Base
4
+ class << self
5
+
6
+ # Stores +v+ in the hash.
7
+ def []=(k, v)
8
+ internal[k] = v
9
+ end
10
+
11
+ # Returns the value at key +k+.
12
+ def [](k)
13
+ internal[k]
14
+ end
15
+
16
+ private
17
+ # The hash the data is being stored in.
18
+ def internal
19
+ @internal ||= {}
20
+ end
21
+
22
+ def clear
23
+ @internal = nil
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module CeilingCat
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -4,20 +4,25 @@ namespace :plugin do
4
4
  raise "You need to set a name! `rake plugin:create name=[plugin_name]`" unless ENV["name"]
5
5
  name = ENV["name"].downcase
6
6
  file = File.join("plugins", "#{name}.rb")
7
+ test_file = File.join("spec", "plugins", "#{name}_spec.rb")
7
8
 
8
- unless File.exists? file
9
- contents = plugin_base(name)
10
- File.open(file, 'w') {|f| f.write(contents) }
11
- puts "Plugin '#{name}' created at #{file}."
12
- puts "Make sure you require it in your Chatfile and add it to your config.plugins so it runs."
13
- else
14
- puts "A plugin named '#{name}' already exists. Try another name."
9
+ unless File.exists?(file) || File.exists?(test_file)
10
+ contents = plugin_base(name)
11
+ File.open(file, 'w') {|f| f.write(contents) }
12
+
13
+ test_contents = plugin_test_base(name).gsub('\#','#')
14
+ File.open(test_file, 'w') {|f| f.write(test_contents) }
15
+
16
+ puts "Plugin '#{name}' created at #{file}."
17
+ puts "Make sure you require it in your Chatfile and add it to your config.plugins so it runs."
18
+ else
19
+ puts "A plugin named '#{name}' already exists. Try another name."
20
+ end
15
21
  end
16
22
  end
17
- end
18
23
 
19
- def plugin_base(name)
20
- %Q{module CeilingCat
24
+ def plugin_base(name)
25
+ %Q{module CeilingCat
21
26
  module Plugin
22
27
  class #{name.camelize} < CeilingCat::Plugin::Base
23
28
  # See lib/ceiling_cat/plugins/base.rb for the methods available by default.
@@ -56,6 +61,84 @@ def plugin_base(name)
56
61
  end
57
62
  end
58
63
  }
64
+ end
65
+
66
+ def plugin_test_base(name)
67
+ %Q{require 'plugins/#{name}'
68
+
69
+ describe "#{name.camelize}" do
70
+ before(:each) do
71
+ CeilingCat::Storage::Hash.send "clear" # Clear the calls and response each time.
72
+
73
+ user = "user"
74
+ token = "1234abcd"
75
+ plugins = [CeilingCat::Plugin::#{name.camelize}]
76
+
77
+ FakeWeb.register_uri(:get, "https://\#{token}:X@\#{user}.campfirenow.com/rooms.json", :body => fixture('campfire/rooms.json'), :status => ["200"])
78
+ FakeWeb.register_uri(:get, "https://\#{token}:X@\#{user}.campfirenow.com/users/me.json", :body => fixture('campfire/me.json'), :status => ["200"])
79
+
80
+ @connection = CeilingCat::Campfire::Connection.new(OpenStruct.new({:service => 'campfire', :username => user, :token => token, :room => 'Room 1', :plugins => plugins}))
81
+ @room = CeilingCat::Campfire::Room.new(:connection => @connection, :room_name => @connection.config.room)
82
+ end
83
+
84
+ describe "base methods" do
85
+ # Tests for any methods that run outside of a command
86
+ end
87
+
88
+ describe "commands" do
89
+ # Tests for commands
90
+ describe "from a guest user" do
91
+ before(:each) do
92
+ @guest_user = CeilingCat::User.new("Guest", :id => 12345, :role => "guest")
93
+ end
94
+
95
+ describe "calling the 'default' command" do
96
+ it "should not do or say anything" do
97
+ event = CeilingCat::Event.new(@room,"!#{name}", @guest_user)
98
+ @room.should_not_receive(:say)
99
+ CeilingCat::Plugin::#{name.camelize}.new(event).handle
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "from a registered user" do
105
+ before(:each) do
106
+ @registered_user = CeilingCat::User.new("Guest", :id => 12345, :role => "member")
107
+ end
108
+
109
+ describe "calling the 'default' command" do
110
+ it "should call the 'default' method" do
111
+ event = CeilingCat::Event.new(@room,"!#{name}", @registered_user)
112
+ @room.should_receive(:say).with("You've created the '#{name.capitalize}' plugin. Now make it do something awesome!")
113
+ CeilingCat::Plugin::#{name.camelize}.new(event).handle
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ describe 'entrance and exit' do
120
+ # Tests for things to run when a user enters or exits the room
121
+ describe "entering the room" do
122
+ before(:each) do
123
+ @registered_user = CeilingCat::User.new("Guest", :id => 12345, :role => "member", :type => :entrance)
124
+ end
125
+
126
+ it "should do something" do
127
+ end
128
+ end
129
+
130
+ describe "exiting the room" do
131
+ before(:each) do
132
+ @registered_user = CeilingCat::User.new("Guest", :id => 12345, :role => "member", :type => :exit)
133
+ end
134
+
135
+ it "should do something" do
136
+ end
137
+ end
138
+ end
139
+ end
140
+ }
141
+ end
59
142
  end
60
143
 
61
144
  class String
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ceiling_cat
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Chris Warren
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-18 00:00:00 Z
18
+ date: 2011-08-25 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: tinder
@@ -65,6 +65,50 @@ dependencies:
65
65
  version: 0.1.8
66
66
  type: :runtime
67
67
  version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - "="
75
+ - !ruby/object:Gem::Version
76
+ hash: 23
77
+ segments:
78
+ - 2
79
+ - 6
80
+ - 0
81
+ version: 2.6.0
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: ruby-debug
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :development
97
+ version_requirements: *id005
98
+ - !ruby/object:Gem::Dependency
99
+ name: fakeweb
100
+ prerelease: false
101
+ requirement: &id006 !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ type: :development
111
+ version_requirements: *id006
68
112
  description: Ceiling Cat is watching you chat. A Campfire chat bot!
69
113
  email:
70
114
  - chris@zencoder.com
@@ -92,9 +136,9 @@ files:
92
136
  - lib/ceiling_cat/plugins/call_and_response.rb
93
137
  - lib/ceiling_cat/plugins/campfire_account_monitor.rb
94
138
  - lib/ceiling_cat/plugins/days.rb
95
- - lib/ceiling_cat/plugins/general.rb
96
139
  - lib/ceiling_cat/plugins/greeter.rb
97
140
  - lib/ceiling_cat/plugins/notifo.rb
141
+ - lib/ceiling_cat/storage/hash.rb
98
142
  - lib/ceiling_cat/storage/yaml.rb
99
143
  - lib/ceiling_cat/services/campfire.rb
100
144
  - lib/ceiling_cat/services/campfire/connection.rb
@@ -104,7 +148,7 @@ files:
104
148
  homepage: http://zencoder.com
105
149
  licenses: []
106
150
 
107
- post_install_message: " ********************************************************************************\n Run `ceiling_cat setup` to create a Chatfile and a Rakefile - everything you\n need to start watching your chats and making ceiling_cat do your bidding!\n \n Run `rake plugin:create name=plugin_name` to generate a new plugin.\n\n Update your Chatfile with your credentials and you'll be ready to go!\n ********************************************************************************\n"
151
+ post_install_message: " ********************************************************************************\n Run `ceiling_cat setup` to create a Chatfile and a Rakefile - everything you\n need to start watching your chats and making ceiling_cat do your bidding!\n\n Update your Chatfile with your credentials and you'll be ready to go!\n\n Want Ceiling Cat to do something special just for you?\n Run `rake plugin:create name=plugin_name` to generate a new plugin.\n ********************************************************************************\n"
108
152
  rdoc_options: []
109
153
 
110
154
  require_paths:
@@ -1,56 +0,0 @@
1
- module CeilingCat
2
- module Plugin
3
- class General < CeilingCat::Plugin::Base
4
- # See lib/ceiling_cat/plugins/base.rb for the methods available by default.
5
- # Plugins are run in the order they are listed in the Chatfile.
6
- # When a plugin returns anything other than nil the plugin execution chain is halted.
7
- # If you want your plugin to do something but let the remaining plugins execute, return nil at the end of your method.
8
-
9
- # handle manages a plugin's entire interaction with an event.
10
- # If you only want to execute commands - "![command]" - leave handle alone (or remove it and define commands below)
11
- def handle
12
- super
13
- end
14
-
15
- # If you want the plugin to run when certain text is sent use commands instead of handle.
16
- # Ceiling Cat will watch for "![command]" or "[name]: [command" and execute the method for that command.
17
- def self.commands
18
- [{:command => "debugger", :description => "Load the debugger", :method => "run_debug", :public => false},
19
- {:command => "enable debug", :description => "Enable debuggers", :method => "enable_debug", :public => false},
20
- {:command => "disable debug", :description => "Disable debuggers", :method => "disable_debug", :public => false}]
21
- end
22
-
23
- def self.description
24
- "General tasks for development"
25
- end
26
-
27
- def self.name
28
- "General"
29
- end
30
-
31
- def self.public?
32
- false
33
- end
34
-
35
- def run_debug
36
- if room.debug_mode?
37
- reply "Opening debugger in terminal"
38
- debugger
39
- else
40
- reply "Debugging is disabled - !enable debug to activate it."
41
- end
42
- end
43
-
44
- def enable_debug
45
- store["debug_mode"] ||= "true"
46
- reply "debugging enabled"
47
- end
48
-
49
- def disable_debug
50
- store["debug_mode"] ||= "false"
51
- reply "debugging disabled"
52
- end
53
- end
54
- end
55
- end
56
-