cinch-memo 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in cinch-memo.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ Cinch-Memo
2
+ ===========
3
+
4
+ The Cinch Memo Plugin. Store messages for users while they are away.
5
+
6
+ Installation
7
+ ---------------------
8
+
9
+ if you haven't already...
10
+
11
+ $ gem install cinch
12
+
13
+ then install this gem.
14
+
15
+ $ gem install cinch-memo
16
+
17
+ Installation and Setup
18
+ ----------
19
+
20
+ #### Configuration ####
21
+
22
+ To setup the plugin to work with your cinch bot, we'll need to provide some info like so:
23
+
24
+ Cinch::Plugins::Memo::Base.configure do |c|
25
+ c.store = :redis # data store
26
+ c.host = 'localhost' # your host
27
+ c.port = '6709' # your port
28
+ end
29
+
30
+ Currently, only Redis is available as a backend store.
31
+
32
+ #### Commands ####
33
+
34
+ * !memo [nick] [message] - stores the message for the user
35
+ * !memo? - returns memo's for your nick
36
+
37
+ ## Integration with Cinch ##
38
+
39
+ It's simple. follow the guide on cinch or do something like:
40
+
41
+ # mybot.rb
42
+ require 'cinch'
43
+ require 'cinch-memo'
44
+
45
+ Cinch::Plugins::Memo::Base.configure do |c|
46
+ c.store = :redis # data store
47
+ c.host = 'localhost' # your host
48
+ c.port = '6709' # your port
49
+ end
50
+
51
+ bot = Cinch::Bot.new do
52
+ configure do |c|
53
+ c.server = "irc.freenode.net"
54
+ c.nick = "cinch"
55
+ c.channels = ["#padrino"]
56
+ c.plugins.plugins = [Cinch::Plugins::Memo::Base]
57
+ end
58
+
59
+ end
60
+
61
+ bot.start
62
+
63
+ Finally, run your bot.
64
+
65
+ ruby -rubygems mybot.rb
66
+
67
+ And there you go!
68
+
69
+
70
+ TODO
71
+ -----
72
+
73
+ * add auto deliver message functionality when you sign on.
74
+ * add rate limiting ability
75
+ * add additional backend stores.
76
+ * add some kind of auth mech
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "cinch-memo/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "cinch-memo"
7
+ s.version = Cinch::Plugins::Memo::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Arthur Chiu"]
10
+ s.email = ["mr.arthur.chiu@gmail.com"]
11
+ s.homepage = "http://rubygems.org/gems/cinch-memo"
12
+ s.summary = %q{Memo Plugin for Cinch}
13
+ s.description = %q{Give your Cinch bot memo functionality!}
14
+
15
+ s.rubyforge_project = "cinch-memo"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'cinch'
23
+ s.add_dependency 'json'
24
+ s.add_dependency 'redis'
25
+ s.add_development_dependency 'riot', '~>0.12.0'
26
+ s.add_development_dependency 'mocha'
27
+ s.add_development_dependency 'timecop'
28
+ end
@@ -0,0 +1,53 @@
1
+ module Cinch
2
+ module Plugins
3
+ module Memo
4
+ class Base
5
+ include Cinch::Plugin
6
+ attr_accessor :backend
7
+
8
+ class << self
9
+ attr_accessor :store, :host, :port
10
+
11
+ def configure(&block)
12
+ yield self
13
+ end
14
+ end
15
+
16
+ def initialize(*args)
17
+ super
18
+ @backend =
19
+ case self.class.store
20
+ when :redis then Cinch::Plugins::Memo::Redis.new(self.class.host, self.class.port)
21
+ else
22
+ self.class.store
23
+ end
24
+ end
25
+
26
+ match %r{memo (\S*) (.*)}, :method => :store_message
27
+ match %r{memo\?}, :method => :get_message
28
+
29
+ # Stores message to designated user.
30
+ def store_message(m, nick, message)
31
+ if nick == @bot.nick
32
+ m.reply "You can't store a message for me."
33
+ else
34
+ @backend.store(nick,m.user.nick, message)
35
+ m.reply "Message saved!"
36
+ end
37
+ end
38
+
39
+ # Gets messages for the designated user
40
+ def get_message(m)
41
+ messages = @backend.retrieve(m.user.nick)
42
+ unless messages.nil? || messages.empty?
43
+ messages.each { |msg| m.reply msg }
44
+ else
45
+ m.reply "There are no messages for you."
46
+ end
47
+ end
48
+
49
+ end # Base
50
+
51
+ end # Memo
52
+ end # Plugins
53
+ end #Cinch
@@ -0,0 +1,25 @@
1
+ require 'redis'
2
+ require 'json'
3
+ module Cinch
4
+ module Plugins
5
+ module Memo
6
+ class Redis
7
+
8
+ def initialize(host, port)
9
+ @backend = ::Redis.new(:host => host, :port => port)
10
+ end
11
+
12
+ def store(recipient, sender, message)
13
+ @backend.sadd recipient, [sender, message, Time.now.to_s].to_json
14
+ end
15
+
16
+ def retrieve(recipient)
17
+ messages = @backend.smembers recipient
18
+ @backend.del(recipient)
19
+ messages
20
+ end
21
+
22
+ end # Redis
23
+ end # Memo
24
+ end # Plugins
25
+ end # Cinch
@@ -0,0 +1,7 @@
1
+ module Cinch
2
+ module Plugins
3
+ module Memo
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
data/lib/cinch-memo.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'cinch'
2
+
3
+ module Cinch
4
+ module Plugins
5
+ module Memo
6
+ autoload :Base, 'cinch-memo/base'
7
+ autoload :Redis, 'cinch-memo/store/redis'
8
+ end
9
+ end
10
+ end
data/test/base_test.rb ADDED
@@ -0,0 +1,78 @@
1
+ require File.expand_path('../teststrap',__FILE__)
2
+
3
+ context "Base" do
4
+ dont_register!
5
+ setup { @bot = mock() }
6
+
7
+ helper :base do |store|
8
+ Cinch::Plugins::Memo::Base.configure do |c|
9
+ c.store = store
10
+ end
11
+ Cinch::Plugins::Memo::Base
12
+ end
13
+
14
+
15
+ context "#configure" do
16
+ setup { base(:redis) }
17
+ asserts(:store).equals :redis
18
+ end
19
+
20
+ context "#initialize" do
21
+ setup { base(:redis).new(@bot) }
22
+ asserts_topic.assigns :backend
23
+ end
24
+
25
+ context "#store_message" do
26
+ setup do
27
+ @bot.expects(:nick).returns('bob')
28
+ @base = base(:redis).new(@bot)
29
+ @message = mock()
30
+ end
31
+
32
+ context "with bot nick" do
33
+ setup { @message.expects(:reply).with("You can't store a message for me.").returns(true) }
34
+ asserts("that it doesn't save message for bot") { @base.store_message(@message,'bob','hey') }
35
+ end
36
+
37
+ context "with non-bot nick" do
38
+ setup do
39
+ @replier = mock() ; @replier.expects(:nick).returns("chris")
40
+ @message.expects(:user).returns(@replier)
41
+ @message.expects(:reply).with("Message saved!").returns(true)
42
+ @backend = mock()
43
+ @backend.expects(:store).with('john','chris','hey')
44
+ @base.backend = @backend
45
+ end
46
+ asserts("that it does save message") { @base.store_message(@message, 'john', 'hey') }
47
+ end
48
+ end
49
+
50
+ context "#deliver_message" do
51
+ setup do
52
+ @replier = mock() ; @replier.expects(:nick).returns('chris')
53
+ @message = mock() ; @message.expects(:user).returns(@replier)
54
+ @backend = mock()
55
+ @base = base(:redis).new(@bot)
56
+ end
57
+
58
+ context "with message" do
59
+ setup do
60
+ @backend.expects(:retrieve).with('chris').returns(["john: hey there!", "john: bye!"])
61
+ @base.backend = @backend
62
+ @message.expects(:reply).with("john: hey there!")
63
+ @message.expects(:reply).with("john: bye!")
64
+ end
65
+ asserts("that it returns message") { @base.get_message(@message) }
66
+ end
67
+
68
+ context "without message" do
69
+ setup do
70
+ @backend.expects(:retrieve).with('chris').returns([])
71
+ @base.backend = @backend
72
+ @message.expects(:reply).with("There are no messages for you.").returns(true)
73
+ end
74
+ asserts("that it says there aren't messages") { @base.get_message(@message) }
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../../teststrap',__FILE__)
2
+ require 'redis'
3
+ context "Redis" do
4
+ dont_register!
5
+ setup { @bot = mock() }
6
+
7
+ helper :base do
8
+ Cinch::Plugins::Memo::Base.configure do |c|
9
+ c.store = :redis
10
+ c.host = 'localhost'
11
+ c.port = '6709'
12
+ end
13
+ Cinch::Plugins::Memo::Base
14
+ end
15
+
16
+ context "#initialize" do
17
+ setup { ::Redis.expects(:new).with(:host => 'localhost', :port => '6709') }
18
+ setup { base.new(@bot) }
19
+ asserts_topic.assigns :backend
20
+ end
21
+
22
+ context "#store" do
23
+ setup do
24
+ Timecop.freeze(Time.now)
25
+ backend = mock() ; backend.expects(:sadd).with('bob', ['chris','yo yo', Time.now].to_json).returns(true)
26
+ ::Redis.expects(:new).with(:host => 'localhost', :port => '6709').returns(backend)
27
+ Cinch::Plugins::Memo::Redis.new('localhost','6709')
28
+ end
29
+ asserts("that it stores message") { topic.store('bob', 'chris','yo yo') }
30
+ end
31
+
32
+ context "#retrieve" do
33
+ setup do
34
+ Timecop.freeze(Time.now)
35
+ backend = mock() ; backend.expects(:smembers).with("bob").returns("\[\"a\",\"b\",\"c\"\]")
36
+ backend.expects(:del).with('bob').returns(true)
37
+ ::Redis.expects(:new).with(:host => 'localhost', :port => '6709').returns(backend)
38
+ Cinch::Plugins::Memo::Redis.new('localhost','6709')
39
+ end
40
+ asserts("that it retrieves message") { topic.retrieve('bob') }
41
+ end
42
+ end
data/test/teststrap.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+ require 'riot'
4
+ require 'mocha'
5
+ require 'timecop'
6
+ require File.expand_path('../../lib/cinch-memo',__FILE__)
7
+
8
+ class Riot::Situation
9
+ include Mocha::API
10
+ end
11
+
12
+ class Riot::Context
13
+ # Turn off bot register hook
14
+ def dont_register!
15
+ setup { Cinch::Plugins::Memo::Base.stubs(:__register_with_bot).with(any_parameters).returns(true) }
16
+ end
17
+ end
18
+
19
+ class Object
20
+ def capture(stream)
21
+ begin
22
+ stream = stream.to_s
23
+ eval "$#{stream} = StringIO.new"
24
+ yield
25
+ result = eval("$#{stream}").string
26
+ ensure
27
+ eval("$#{stream} = #{stream.upcase}")
28
+ end
29
+ result
30
+ end
31
+ end
data/test.watchr ADDED
@@ -0,0 +1,70 @@
1
+ ENV["WATCHR"] = "1"
2
+ system 'clear'
3
+
4
+ def growl(message)
5
+ growlnotify = `which growlnotify`.chomp
6
+ title = "Watchr Test Results"
7
+ image = message.include?('0 failures, 0 errors') ? "~/.watchr_images/passed.png" : "~/.watchr_images/failed.png"
8
+ options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'"
9
+ system %(#{growlnotify} #{options} &)
10
+ end
11
+
12
+ def run(cmd)
13
+ puts(cmd)
14
+ `#{cmd}`
15
+ end
16
+
17
+ def run_test_file(file)
18
+ system('clear')
19
+ result = run(%Q(ruby -I"lib:test" -rubygems #{file}))
20
+ growl result.split("\n").last rescue nil
21
+ puts result
22
+ end
23
+
24
+ def run_all_tests
25
+ system('clear')
26
+ result = run "rake test"
27
+ growl result.split("\n").last rescue nil
28
+ puts result
29
+ end
30
+
31
+ def run_all_features
32
+ system('clear')
33
+ run "cucumber"
34
+ end
35
+
36
+ def related_test_files(path)
37
+ Dir['test/**/*.rb'].select { |file| file =~ /#{File.basename(path).split(".").first}_test.rb/ }
38
+ end
39
+
40
+ def run_suite
41
+ run_all_tests
42
+ # run_all_features
43
+ end
44
+
45
+ watch('test/teststrap\.rb') { run_all_tests }
46
+ watch('test/(.*).*_test\.rb') { |m| run_test_file(m[0]) }
47
+ watch('lib/.*/.*\.rb') { |m| related_test_files(m[0]).map {|tf| run_test_file(tf) } }
48
+ # watch('features/.*/.*\.feature') { run_all_features }
49
+
50
+ # Ctrl-\
51
+ Signal.trap 'QUIT' do
52
+ puts " --- Running all tests ---\n\n"
53
+ run_all_tests
54
+ end
55
+
56
+ @interrupted = false
57
+
58
+ # Ctrl-C
59
+ Signal.trap 'INT' do
60
+ if @interrupted then
61
+ @wants_to_quit = true
62
+ abort("\n")
63
+ else
64
+ puts "Interrupt a second time to quit"
65
+ @interrupted = true
66
+ Kernel.sleep 1.5
67
+ # raise Interrupt, nil # let the run loop catch it
68
+ run_suite
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cinch-memo
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Arthur Chiu
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-07 01:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: cinch
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: json
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: redis
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :runtime
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: riot
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ - 12
70
+ - 0
71
+ version: 0.12.0
72
+ type: :development
73
+ version_requirements: *id004
74
+ - !ruby/object:Gem::Dependency
75
+ name: mocha
76
+ prerelease: false
77
+ requirement: &id005 !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ type: :development
86
+ version_requirements: *id005
87
+ - !ruby/object:Gem::Dependency
88
+ name: timecop
89
+ prerelease: false
90
+ requirement: &id006 !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ type: :development
99
+ version_requirements: *id006
100
+ description: Give your Cinch bot memo functionality!
101
+ email:
102
+ - mr.arthur.chiu@gmail.com
103
+ executables: []
104
+
105
+ extensions: []
106
+
107
+ extra_rdoc_files: []
108
+
109
+ files:
110
+ - .gitignore
111
+ - Gemfile
112
+ - README.md
113
+ - Rakefile
114
+ - cinch-memo.gemspec
115
+ - lib/cinch-memo.rb
116
+ - lib/cinch-memo/base.rb
117
+ - lib/cinch-memo/store/redis.rb
118
+ - lib/cinch-memo/version.rb
119
+ - test.watchr
120
+ - test/base_test.rb
121
+ - test/store/redis_test.rb
122
+ - test/teststrap.rb
123
+ has_rdoc: true
124
+ homepage: http://rubygems.org/gems/cinch-memo
125
+ licenses: []
126
+
127
+ post_install_message:
128
+ rdoc_options: []
129
+
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ segments:
138
+ - 0
139
+ version: "0"
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ requirements: []
149
+
150
+ rubyforge_project: cinch-memo
151
+ rubygems_version: 1.3.7
152
+ signing_key:
153
+ specification_version: 3
154
+ summary: Memo Plugin for Cinch
155
+ test_files:
156
+ - test/base_test.rb
157
+ - test/store/redis_test.rb
158
+ - test/teststrap.rb