codebrulee-aide 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,82 @@
1
+ = Aide - What can Jabber do for you?
2
+
3
+ http://github.com/duwanis/aide
4
+
5
+ == DESCRIPTION:
6
+
7
+ Aide is a DSL for defining and running Jabber bots.
8
+ In order to have a good grasp on how to use Aide, you'll want to familiarize
9
+ yourself with two classes: Aide::Dsl (used to actually read the Aide DSL), and
10
+ Aide::ActionContext (blocks defined using the DSL get executed in the scope of
11
+ an ActionContext). More thorough documentation will be coming soon...
12
+
13
+ == FEATURES/PROBLEMS:
14
+
15
+ It doesn't do anything yet. This is the main problem, really.
16
+
17
+ == EXAMPLE:
18
+
19
+ Check out example.aide in the source. If you install the gem
20
+ (see INSTALL below), you should be able to do the following to
21
+ see the results of parsing the file (or any other file matching
22
+ the DSL):
23
+ aide example.aide
24
+
25
+
26
+ == REQUIREMENTS:
27
+
28
+ Patience.
29
+
30
+
31
+ == INSTALL:
32
+
33
+ sudo gem install duwanis-aide --source=http://gems.github.com
34
+
35
+ == ROADMAP:
36
+
37
+ Here's the plan:
38
+ - 0.1 - Functionality in place to create a very simple bot. Can take in any
39
+ number of static commands, but nothing fancy.
40
+ - 0.2 - Help/describe functionality built in by default.
41
+ - 0.3 - Dynamic commands.
42
+ - 0.4 - Ability to subscribe to an XMPP Publisher (XEP-0060)
43
+ - 0.5 - Scheduled tasks (e.g. "execute this code every minute")
44
+ - 0.6 - Ability to act as an XMPP Publisher (XEP-0060)
45
+ - 0.7 - Command-line interface for publishing events (e.g. aide-publish [botname] [event])
46
+ - 0.8 - ?????
47
+ - 0.9 - Profit!
48
+ - 1.0 - Fully functional 1.0 release.
49
+
50
+ == HISTORY:
51
+
52
+ - 0.0.4 - Beginnings of xmpp4r integration.
53
+ - 0.0.2 - Bot class started, DSL is done in a sane way (no more creating kernel
54
+ methods, woo)
55
+ - 0.0.1 - Proof of concept. DSL is somewhat spec'd out, and you
56
+ are now capable of parsing files (albeit crudely).
57
+ - 0.0.0 - A new project is born!
58
+
59
+ == LICENSE:
60
+
61
+ (The MIT License)
62
+
63
+ Copyright (c) 2008 Tommy Morgan
64
+
65
+ Permission is hereby granted, free of charge, to any person obtaining
66
+ a copy of this software and associated documentation files (the
67
+ 'Software'), to deal in the Software without restriction, including
68
+ without limitation the rights to use, copy, modify, merge, publish,
69
+ distribute, sublicense, and/or sell copies of the Software, and to
70
+ permit persons to whom the Software is furnished to do so, subject to
71
+ the following conditions:
72
+
73
+ The above copyright notice and this permission notice shall be
74
+ included in all copies or substantial portions of the Software.
75
+
76
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
77
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
78
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
79
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
80
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
81
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
82
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'aide'
4
+
5
+ filepath = Pathname.new(ARGV[0]).cleanpath.to_s
6
+
7
+ bot = Aide::Bot.new
8
+ dsl = Aide::Dsl.new(bot, filepath)
@@ -0,0 +1,11 @@
1
+ # Just to make our requires at the top of the gem a little easier.
2
+ require 'pathname'
3
+ $:.unshift(Pathname(__FILE__).dirname.expand_path)
4
+
5
+ require 'rubygems'
6
+ require 'xmpp4r'
7
+
8
+ require 'aide/errors'
9
+ require 'aide/bot'
10
+ require 'aide/dsl'
11
+ require 'aide/version'
@@ -0,0 +1,49 @@
1
+ module Aide
2
+ ##
3
+ # This class is used to provide an execution context for processing messages.
4
+ # It houses all the attributes and helper methods that are to be exposed to
5
+ # the blocks that are passed in to Aide via the Aide::Dsl.with method.
6
+ # These contexts are created and destroyed on a per-message basis, so all
7
+ # attribute values refer to the message that is currently being processed.
8
+ #
9
+ class ActionContext
10
+ #String - The Jabber address from which the message was sent.
11
+ attr_accessor :from
12
+ #String - The Jabber address to which the message was sent.
13
+ attr_accessor :to
14
+ #String - The text of the message, minus the portion that was
15
+ #matched by the bot.
16
+ attr_accessor :message
17
+ #String - The full text of the message, including the portion that
18
+ #was matched by the bot.
19
+ attr_accessor :text
20
+ #Symbol - The type of the message (e.g. :chat, :group, etc.)
21
+ attr_accessor :type
22
+ #Aide::Bot - The bot instance that received and is acting on this
23
+ #message.
24
+ attr_accessor :bot
25
+
26
+ ##
27
+ # Sends a message back to the jabber id that sent the original message.
28
+ #=== Parameters:
29
+ # - *text*: String. The text of the message to send.
30
+ #
31
+ def respond(text)
32
+ send(text, from)
33
+ end
34
+
35
+ ##
36
+ # Sends a message to the specified jabber id.
37
+ #=== Parameters:
38
+ # - *text*: String. The text of the message to send.
39
+ # - *to*: String. The jabber id to send the message to.
40
+ #
41
+ def send(text, to)
42
+ response = Message.new(to, text)
43
+ response.type = :chat
44
+
45
+ bot.send(response)
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,176 @@
1
+ module Aide
2
+ ##
3
+ # The Bot class is the workhorse of aide. It is responsible for representing
4
+ # and executing the logic described by the dsl, and interacts with xmpp4r
5
+ # in order to send and receive messages via the jabber protocol.
6
+ #
7
+ class Bot
8
+
9
+ #Hash[String, Block] - the match strings to look for, and the code to execute when found.
10
+ attr_writer :actions
11
+
12
+ #String - the username to sign this bot in with.
13
+ attr_writer :username
14
+ #Password - the password for this bot to use.
15
+ attr_writer :password
16
+ #Array[String] - a list of jabber IDs to allow this bot to interact with. Precludes block_list.
17
+ attr_accessor :allow_list
18
+ #Array[String] - a list of jabber IDs to explicitly block. Ignored if allow_list is set.
19
+ attr_accessor :block_list
20
+
21
+ ##
22
+ #Creates a new Bot instance.
23
+ #
24
+ def initialize
25
+ @actions = {}
26
+ end
27
+
28
+ ##
29
+ #Logs this Bot instance in to the jabber network and starts it listening
30
+ #for messages.
31
+ #=== Preconditions
32
+ #This method assumes that the Bot has already been properly configured;
33
+ #specifically, that at least the username and password properties have
34
+ #been set.
35
+ #=== Postconditions
36
+ #- The Bot will be logged on,
37
+ #- Its presence will be set to 'chat,' and
38
+ #- It will be listening for messages from privileged users in its own thread
39
+ #(see is_user_allowed?)
40
+ #=== Returns
41
+ #+nil+
42
+ #
43
+ def login
44
+ if @password == nil or @username == nil
45
+ raise Aide::Login_Error, "credentials missing"
46
+ end
47
+ @client = Jabber::Client.new(Jabber::JID.new(@username))
48
+ @client.connect
49
+
50
+ #actual authentication with the host
51
+ begin
52
+ @client.auth(@password)
53
+ rescue Jabber::AuthenticationFailure => af
54
+ raise Aide::Login_Error, "Authentication failure: #{af.message}", af.backtrace
55
+ end
56
+
57
+ @client.send(Jabber::Presence.new)
58
+ @thread = Thread.new do
59
+ @client.add_message_callback do |m|
60
+ if m.type == :chat and is_user_allowed? m.from.split('/')[0]
61
+ process_message m
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ ##
69
+ #Sends the given message.
70
+ #=== Parameters
71
+ #- *message*: Jabber::Message. The message to send.
72
+ #
73
+ def send(message)
74
+ @client.send message
75
+ end
76
+
77
+ ##
78
+ #Examines the given message to see if any actions need to be performed
79
+ #on it. If this message matches any actions defined for this Bot, an
80
+ #Aide::ActionContext is created and used to evaluate the block associated
81
+ #with that action.
82
+ #=== Parameters
83
+ #- *message*: Jabber::Message. The message to process.
84
+ #
85
+ def process_message(message)
86
+ results = match(message.body)
87
+ return nil unless results #no need to do anything if there's no match
88
+
89
+ context = Aide::ActionContext.new
90
+ block = @actions[results[:action_name]]
91
+ context.message = results[:message]
92
+ context.from = message.from
93
+ context.to = message.to
94
+ context.bot = self
95
+ context.text = message.body
96
+ context.type = message.type
97
+ context.instance_eval(block.call)
98
+
99
+ nil #no need to complicate things by returning the results of the block
100
+ end
101
+
102
+ ##
103
+ #Log the bot out of jabber and kill the thread that is listening for
104
+ #messages.
105
+ #
106
+ def logout
107
+ @client.close
108
+ @thread.stop
109
+ end
110
+
111
+ ##
112
+ #Given the text of a message, determines if that text matches any of the
113
+ #actions defined for this Bot.
114
+ #=== Parameters
115
+ #- *text*: String. The text of the message to check for matches.
116
+ #=== Returns
117
+ #Hash[:action_name, :message]
118
+ #Where :action_name corresponds to the name of the action this text
119
+ #matches, and :message corresponds to everything in +text+ after the match.
120
+ #Returns +nil+ if no match was found.
121
+ #
122
+ def match(text)
123
+ nil
124
+ # defaulting to no match until this method is implemented
125
+ end
126
+
127
+ ##
128
+ #Checks a given username to see if it is explicitly allowed or blocked.
129
+ #=== Parameters
130
+ #- *username*: String. The username to check privileges for.
131
+ #=== Returns
132
+ #+boolean+ - the value of this boolean depends on the level of privileges
133
+ #set when the Bot was configured. If an allow_list is defined, then that
134
+ #list has highest precedence - +true+ is returned if the user is in that
135
+ #list, and +false+ is returned otherwise. If allow_list is not defined,
136
+ #but block_list is, then the inverse check is performed (+true+ is
137
+ #returned when the user is absent from the block_list, and vice-versa).
138
+ #If neither list is defined then the user is assumed to be authorized.
139
+ #
140
+ def is_user_allowed?(username)
141
+ return @allow_list.member?(username) if @allow_list
142
+ return !@block_list.member?(username) if @block_list
143
+ return true
144
+ end
145
+
146
+ ##
147
+ # Adds an action to the bot.
148
+ #=== Parameters:
149
+ #- *match*: String. The text to match for this action.
150
+ #- *block*: Proc. The code to execute when this action is fired.
151
+ #
152
+ def add_action(match, block)
153
+ @actions[match] = block
154
+ end
155
+
156
+ ##
157
+ # Allows for appending to the allow_list.
158
+ #=== Parameters:
159
+ #- *list*: Array[String]. The list of users to add to the allow_list.
160
+ #
161
+ def add_allow_list(list)
162
+ @allow_list ||= []
163
+ @allow_list += list
164
+ end
165
+
166
+ ##
167
+ # Allows for appending to the block_list.
168
+ #=== Parameters:
169
+ #- *list*: Array[String]. The list of users to add to the block_list.
170
+ #
171
+ def add_block_list(list)
172
+ @block_list ||= []
173
+ @block_list += list
174
+ end
175
+ end # Bot
176
+ end # Aide
@@ -0,0 +1,74 @@
1
+ module Aide
2
+ ##
3
+ #The Dsl class is used for parsing Aide dsl files. All of the functions made
4
+ #available by this class are available to any dsl file.
5
+ #TODO: This class needs better documentation.
6
+ #
7
+ class Dsl
8
+ ##
9
+ # Creates a new Dsl instance.
10
+ #=== Parameters:
11
+ #- *bot*: Aide::Bot. The bot this dsl will modify/set up.
12
+ #- *filename*: String. The file to parse, if any; defaults to nil.
13
+ #=== Yields:
14
+ #Yields self after the file is parsed.
15
+ #
16
+ def initialize(bot, filename = nil)
17
+ @bot = bot
18
+ load_file filename if filename
19
+ yield self if block_given?
20
+ end
21
+
22
+ ##
23
+ # Sets the username for the Bot that is being loaded.
24
+ #
25
+ def bot_username(text)
26
+ @bot.username=text
27
+ end
28
+
29
+ ##
30
+ # Sets the password for the Bot that is being loaded.
31
+ #
32
+ def bot_password(text)
33
+ @bot.password=text
34
+ end
35
+
36
+ ##
37
+ # Adds *people to the allow_list.
38
+ #
39
+ def allow(*people)
40
+ @bot.add_allow_list people
41
+ end
42
+
43
+ ##
44
+ # Adds *people to the block_list.
45
+ #
46
+ def block(*people)
47
+ @bot.add_block_list people
48
+ end
49
+
50
+ ##
51
+ # Defines an action for the bot.
52
+ #===Parameters:
53
+ #- *text*: String. The text to match on.
54
+ #- *&block*: Block. The code to execute when *text* is found (see Aide::ActionContext)
55
+ #
56
+ def with(text,&block)
57
+ @bot.add_action text, block
58
+ end
59
+
60
+ ##
61
+ # Reads in and parses a Dsl file.
62
+ #
63
+ def load_file(filename)
64
+ instance_eval(File.read(filename), filename)
65
+ end
66
+
67
+ ##
68
+ # Parses a block as though it were a Dsl file.
69
+ #
70
+ def load_block(&block)
71
+ instance_eval(&block)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,8 @@
1
+ module Aide
2
+ ##
3
+ #Login_Error represents a problem with the credentials
4
+ #given to an instance of Aide::Bot.
5
+ #
6
+ class Login_Error < StandardError
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Aide #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 4
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: codebrulee-aide
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Tommy Morgan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-09 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: xmpp4r
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.3.0
23
+ version:
24
+ description: Aide provides a DSL for quickly and easily building Jabber (XMPP) bots.
25
+ email: tommy.morgan@gmail.com
26
+ executables:
27
+ - aide
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - README
34
+ - bin/aide
35
+ - lib/aide.rb
36
+ - lib/aide/actioncontext.rb
37
+ - lib/aide/bot.rb
38
+ - lib/aide/dsl.rb
39
+ - lib/aide/errors.rb
40
+ - lib/aide/version.rb
41
+ has_rdoc: true
42
+ homepage: http://github.com/duwanis/aide
43
+ post_install_message:
44
+ rdoc_options:
45
+ - --main
46
+ - README
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.0.1
65
+ signing_key:
66
+ specification_version: 2
67
+ summary: A DSL for defining and running Jabber bots.
68
+ test_files: []
69
+