drivel 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in drivel.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Joshua M. Keyes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,79 @@
1
+ # Drivel
2
+
3
+ An alternative DSL utilizing the excellent XMPP library, Blather, for creating interactive XMPP bots.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'drivel'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install drivel
18
+
19
+ ## Usage
20
+
21
+ TBD.
22
+
23
+ ## Example
24
+
25
+ #!/usr/bin/env ruby
26
+
27
+ require 'drivel'
28
+
29
+ configure do
30
+ # Do basic setup/configuration.
31
+ set nickname: 'DrivelBot', jid: 'username@chat.example.com/resource', password: 'secretpassword'
32
+
33
+ # (Optional) conferences to discover and join.
34
+ set :conferences, 'main', 'offtopic'
35
+ end
36
+
37
+ helpers do
38
+ def authorized?(context)
39
+ context.chat? and message.from == 'owner@example.com'
40
+ end
41
+ end
42
+
43
+ connected do
44
+ status :available, 'At your service.'
45
+ end
46
+
47
+ disconnected do
48
+ status :offline, 'Going away now.' and shutdown
49
+ end
50
+
51
+ subscription do |message|
52
+ # Handle subscription messages like Blather would.
53
+ end
54
+
55
+ command 'ping' do |message|
56
+ respond message, 'pong'
57
+ end
58
+
59
+ command 'join :conference' do |message, params|
60
+ respond message, "I'm afraid I can't do that." and halt unless authorized?(message)
61
+ join params[:conference]
62
+ end
63
+
64
+ command 'leave :conference' do |message, params|
65
+ respond message, "I'm afraid I can't do that." and halt unless authorized?(message)
66
+ leave params[:conference]
67
+ end
68
+
69
+ recognize 'What is love?' do |message|
70
+ respond message, "Baby don't hurt me no more."
71
+ end
72
+
73
+ ## Contributing
74
+
75
+ 1. Fork it
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'drivel/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "drivel"
8
+ gem.version = Drivel::VERSION
9
+
10
+ gem.authors = ["Joshua M. Keyes"]
11
+ gem.email = ["joshua.michael.keyes@gmail.com"]
12
+
13
+ gem.description = %q{An alternative DSL utilizing the excellent XMPP library, Blather, for creating interactive XMPP bots.}
14
+ gem.summary = %q{A DSL for building XMPP bots.}
15
+ gem.homepage = "https://github.com/jmkeyes/drivel"
16
+
17
+ gem.files = `git ls-files`.split($/)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ["lib"]
21
+
22
+ gem.add_dependency 'blather', '= 0.8.1'
23
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ require 'drivel/version'
2
+ require 'drivel/base'
3
+ require 'drivel/main'
@@ -0,0 +1,193 @@
1
+ require 'blather/client/client'
2
+
3
+ module Drivel
4
+ module DSL
5
+ def set(key, *values)
6
+ if key.is_a?(Hash) and values.empty?
7
+ key.each { |k, v| set(k, v) }
8
+ else
9
+ create_method("#{key}=") { |value| settings[key] = value }
10
+ create_method("#{key}?") { !!settings[key] }
11
+ create_method("#{key}") { settings[key] }
12
+
13
+ settings[key] = values.first
14
+ end
15
+ end
16
+
17
+ def configure
18
+ yield
19
+ end
20
+
21
+ def helpers(*helpers, &block)
22
+ self.instance_eval(&block) if block_given?
23
+ include(*helpers) unless helpers.empty?
24
+ end
25
+
26
+ def before(handler = nil, *guards, &block)
27
+ filter(:before, handler, *guards, &block)
28
+ end
29
+
30
+ def after(handler = nil, *guards, &block)
31
+ filter(:after, handler, *guards, &block)
32
+ end
33
+
34
+ def connected(&block)
35
+ handle(:ready, &block)
36
+ end
37
+
38
+ def disconnected(&block)
39
+ handle(:disconnected, &block)
40
+ end
41
+
42
+ def subscription(&block)
43
+ handle(:subscription, &block)
44
+ end
45
+
46
+ def command(pattern, *arguments, &block)
47
+ raise InvalidArgumentError unless pattern.is_a?(String) or pattern.is_a?(Regexp)
48
+
49
+ safe_nickname = Regexp.escape(settings[:nickname])
50
+ optional_prefix = /(?:#{safe_nickname}[:,]? |[!$%@])/i
51
+
52
+ pattern.gsub!(/((:\w+)|\*)/) do |key|
53
+ (key == '*' ? "(?<splat>.*?)" : "(?<#{key[1..-1]}>[^\s]+)")
54
+ end if pattern.is_a?(String)
55
+
56
+ recognize(/\A#{optional_prefix}#{pattern}\Z/, &block)
57
+ end
58
+
59
+ def recognize(pattern, *arguments, &block)
60
+ raise InvalidArgumentError unless pattern.is_a?(String) or pattern.is_a?(Regexp)
61
+
62
+ matcher = Regexp.compile(pattern, true)
63
+
64
+ handle(:message, :body => matcher) do |message|
65
+ matches = message.body.match(matcher)
66
+ captures = matches.names.map(&:to_sym).zip(matches.captures)
67
+ yield message, Hash[captures]
68
+ end
69
+ end
70
+
71
+ def ready?
72
+ jid? and password? and nickname?
73
+ end
74
+
75
+ def run!
76
+ client.setup(settings[:jid], settings[:password])
77
+
78
+ # Reopen standard input and direct it at /dev/null.
79
+ $stdin.reopen('/dev/null')
80
+
81
+ # Capture interrupt and terminate and force them to shutdown the connection.
82
+ [:INT, :TERM].each do |signal|
83
+ trap(signal) { shutdown }
84
+ end
85
+
86
+ # Start.
87
+ EM.run { client.run }
88
+ end
89
+
90
+ def status(mode, message)
91
+ mode = nil if mode == :offline
92
+ client.status = mode, message
93
+ end
94
+
95
+ def shutdown
96
+ client.close
97
+ end
98
+
99
+ def respond(message = nil, content = nil)
100
+ response = ::Blather::Stanza::Message.new.tap do |stanza|
101
+ if message and content
102
+ stanza.type, stanza.from = message.type, message.to
103
+
104
+ case message.type
105
+ when :groupchat
106
+ stanza.to = message.from.stripped
107
+ stanza.body = message.from.resource + ': ' + content
108
+ when :chat
109
+ stanza.to = message.from
110
+ stanza.body = content
111
+ else
112
+ raise ArgumentError, 'Cannot respond to messages of type ' + message.type.to_s
113
+ end
114
+ end
115
+
116
+ # Evaluate any given block, passing in this message before delivery.
117
+ yield stanza if block_given?
118
+ end
119
+
120
+ EM.next_tick { client.write(response) }
121
+ end
122
+
123
+ def join(conference, &block)
124
+ room = ::Blather::JID.new(conference)
125
+ request = ::Blather::Stanza::Presence::MUC.new.tap do |stanza|
126
+ target = ::Blather::JID.new(room.node, room.domain, settings[:nickname])
127
+ stanza.to, stanza.type = target, nil
128
+ end
129
+ client.write_with_handler(request)
130
+ end
131
+
132
+ def leave(conference, &block)
133
+ room = ::Blather::JID.new(conference)
134
+ request = ::Blather::Stanza::Presence::MUC.new.tap do |stanza|
135
+ target = ::Blather::JID.new(room.node, room.domain, settings[:nickname])
136
+ stanza.to, stanza.type = target, :unavailable
137
+ end
138
+ client.write_with_handler(request, &block)
139
+ end
140
+
141
+ def pass
142
+ throw :pass
143
+ end
144
+
145
+ def halt
146
+ throw :halt
147
+ end
148
+
149
+ def discover(type, target, node = nil, &block)
150
+ stanza = {
151
+ info: ::Blather::Stanza::DiscoInfo,
152
+ items: ::Blather::Stanza::DiscoItems
153
+ }[type].new
154
+
155
+ stanza.node = node
156
+ stanza.from = client.jid
157
+ stanza.to = target
158
+
159
+ client.write_with_handler(stanza, &block)
160
+ end
161
+
162
+ def schedule(interval, repeat = true, &block)
163
+ EM.next_tick do
164
+ if repeat
165
+ EM.add_periodic_timer(interval, &block)
166
+ else
167
+ EM.add_timer(interval, &block)
168
+ end
169
+ end
170
+ end
171
+
172
+ private
173
+ def settings
174
+ @settings ||= {}
175
+ end
176
+
177
+ def client
178
+ @client ||= ::Blather::Client.new
179
+ end
180
+
181
+ def handle(type, *guards, &block)
182
+ client.register_handler(type, *guards, &block)
183
+ end
184
+
185
+ def filter(type, handler = nil, *guards, &block)
186
+ client.register_filter(type, handler, *guards, &block)
187
+ end
188
+
189
+ def create_method(name, *arguments, &block)
190
+ self.class.send(:define_method, name, *arguments, &block)
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,4 @@
1
+ require 'drivel/base'
2
+
3
+ Object.send(:include, ::Drivel::DSL)
4
+ at_exit { run! if ready? }
@@ -0,0 +1,3 @@
1
+ module Drivel
2
+ VERSION = "0.0.1"
3
+ end
File without changes
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: drivel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joshua M. Keyes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: blather
16
+ requirement: &7989760 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - =
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *7989760
25
+ description: An alternative DSL utilizing the excellent XMPP library, Blather, for
26
+ creating interactive XMPP bots.
27
+ email:
28
+ - joshua.michael.keyes@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - LICENSE.txt
36
+ - README.md
37
+ - Rakefile
38
+ - drivel.gemspec
39
+ - examples/.gitkeep
40
+ - lib/drivel.rb
41
+ - lib/drivel/base.rb
42
+ - lib/drivel/main.rb
43
+ - lib/drivel/version.rb
44
+ - spec/spec_helper.rb
45
+ homepage: https://github.com/jmkeyes/drivel
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.15
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: A DSL for building XMPP bots.
69
+ test_files:
70
+ - spec/spec_helper.rb
71
+ has_rdoc: