Auto 4.0.0.alpha.1-x86-mingw32

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.
Files changed (65) hide show
  1. data/.yardopts +7 -0
  2. data/Gemfile +19 -0
  3. data/LICENSE.md +31 -0
  4. data/README.md +109 -0
  5. data/Rakefile +41 -0
  6. data/bin/auto +110 -0
  7. data/bin/auto-conf +45 -0
  8. data/conf/example.json +100 -0
  9. data/conf/example.yml +125 -0
  10. data/docs/Contributing.md +77 -0
  11. data/docs/Events.md +103 -0
  12. data/docs/Todo.md +21 -0
  13. data/docs/Upgrade.md +16 -0
  14. data/ext/dsl_base.c +49 -0
  15. data/ext/libauto/auto.h +20 -0
  16. data/ext/libauto/extconf.rb +16 -0
  17. data/ext/libauto/libauto.c +29 -0
  18. data/ext/libauto/libauto.h +28 -0
  19. data/ext/libauto/logger.c +177 -0
  20. data/ext/libauto/logger.h +44 -0
  21. data/lib/auto.rb +43 -0
  22. data/lib/auto/api.rb +7 -0
  23. data/lib/auto/api/events.rb +166 -0
  24. data/lib/auto/api/object.rb +29 -0
  25. data/lib/auto/api/plugin.rb +155 -0
  26. data/lib/auto/api/timers.rb +93 -0
  27. data/lib/auto/bot.rb +338 -0
  28. data/lib/auto/config.rb +181 -0
  29. data/lib/auto/configure.rb +410 -0
  30. data/lib/auto/configure/shell.rb +154 -0
  31. data/lib/auto/dsl/base.rb +74 -0
  32. data/lib/auto/dsl/irc.rb +13 -0
  33. data/lib/auto/irc.rb +8 -0
  34. data/lib/auto/irc/common.rb +63 -0
  35. data/lib/auto/irc/library.rb +89 -0
  36. data/lib/auto/irc/object/channel.rb +21 -0
  37. data/lib/auto/irc/object/entity.rb +90 -0
  38. data/lib/auto/irc/object/message.rb +99 -0
  39. data/lib/auto/irc/object/user.rb +139 -0
  40. data/lib/auto/irc/protocol.rb +164 -0
  41. data/lib/auto/irc/protocol/numerics.rb +60 -0
  42. data/lib/auto/irc/sasl/diffie_hellman.rb +36 -0
  43. data/lib/auto/irc/sasl/mech.rb +15 -0
  44. data/lib/auto/irc/sasl/mech/dh_blowfish.rb +83 -0
  45. data/lib/auto/irc/sasl/mech/plain.rb +39 -0
  46. data/lib/auto/irc/server.rb +301 -0
  47. data/lib/auto/irc/state/channel_manager.rb +6 -0
  48. data/lib/auto/irc/state/support.rb +142 -0
  49. data/lib/auto/irc/state/user_manager.rb +6 -0
  50. data/lib/auto/irc/std/commands.rb +99 -0
  51. data/lib/auto/irc/std/numerics.rb +216 -0
  52. data/lib/auto/rubyext/integer.rb +25 -0
  53. data/lib/auto/rubyext/string.rb +10 -0
  54. data/lib/auto/version.rb +18 -0
  55. data/lib/libauto.so +0 -0
  56. data/spec/api_events_spec.rb +68 -0
  57. data/spec/config_json_spec.rb +116 -0
  58. data/spec/config_other_spec.rb +29 -0
  59. data/spec/config_yaml_spec.rb +136 -0
  60. data/spec/helper.rb +19 -0
  61. data/spec/irc_object_entity_spec.rb +51 -0
  62. data/spec/logger_spec.rb +30 -0
  63. data/spec/plugin_base_spec.rb +35 -0
  64. data/spec/timers_spec.rb +42 -0
  65. metadata +238 -0
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright (c) 2013, Autumn Perrault, et al.
3
+ * All rights reserved.
4
+ * This free software is distributed under the FreeBSD license (LICENSE.md).
5
+ *
6
+ */
7
+
8
+ #ifndef __LIBAUTO_H__
9
+ #define __LIBAUTO_H__
10
+
11
+ /* SYM(x) returns rb_intern(x) */
12
+ #define SYM(str) rb_intern(#str)
13
+
14
+ /* variable for the Auto module */
15
+ VALUE mAuto;
16
+
17
+ /* Init_libauto prototype */
18
+ void Init_libauto();
19
+
20
+ /* Auto's exceptions */
21
+ VALUE eLogError;
22
+ VALUE eConfigError;
23
+ VALUE eDatabaseError;
24
+ VALUE ePluginError;
25
+
26
+ #endif
27
+
28
+ /* vim: set ts=4 sts=4 sw=4 et cindent: */
@@ -0,0 +1,177 @@
1
+ /*
2
+ * Copyright (c) 2013, Autumn Perrault, et al.
3
+ * All rights reserved.
4
+ * This free software is distributed under the FreeBSD license (LICENSE.md).
5
+ *
6
+ */
7
+
8
+ // So that the header will be read correctly.
9
+ #define __LOGGER__
10
+
11
+ #include <errno.h>
12
+ #include <sys/stat.h>
13
+ #include <string.h>
14
+ #include <time.h>
15
+ #include "auto.h"
16
+
17
+ /* @overload initialize()
18
+ * Constructs a new Auto::Logger instance.
19
+ *
20
+ * @return [Auto::Logger]
21
+ */
22
+ VALUE logger_init(VALUE self)
23
+ {
24
+ rb_iv_set(self, "@status", ID2SYM(SYM(good)));
25
+ rb_funcall(self, SYM(log_directory_check), 0);
26
+ return self;
27
+ }
28
+
29
+ /* @overload error(message)
30
+ * This will log +message+ as an error.
31
+ *
32
+ * @param [String] message The error message to be reported.
33
+ * @return [nil]
34
+ */
35
+ VALUE logger_error(VALUE self, VALUE message)
36
+ {
37
+ rb_funcall(self, SYM(log), 2, rb_str_new2("ERROR"), message);
38
+ return Qnil;
39
+ }
40
+
41
+ /* @overload debug(message)
42
+ * This will log +message+ as a debug message.
43
+ *
44
+ * @param [String] message The debug message to be reported.
45
+ * @return [nil]
46
+ */
47
+ VALUE logger_debug(VALUE self, VALUE message)
48
+ {
49
+ rb_funcall(self, SYM(log), 2, rb_str_new2("DEBUG"), message);
50
+ return Qnil;
51
+ }
52
+
53
+ /* @overload warning(message)
54
+ * This will log +message+ as a warning.
55
+ *
56
+ * @param [String] message The admonitory message to be reported.
57
+ * @return [nil]
58
+ */
59
+ VALUE logger_warning(VALUE self, VALUE message)
60
+ {
61
+ rb_funcall(self, SYM(log), 2, rb_str_new2("WARNING"), message);
62
+ return Qnil;
63
+ }
64
+
65
+ /* @overload info(message)
66
+ * This will log +message+ as an informative message.
67
+ *
68
+ * @param [String] message The information to be reported.
69
+ * @return [nil]
70
+ */
71
+ VALUE logger_info(VALUE self, VALUE message)
72
+ {
73
+ rb_funcall(self, SYM(log), 2, rb_str_new2("INFO"), message);
74
+ return Qnil;
75
+ }
76
+
77
+ /* @overload log(type, message)
78
+ * This will foremost call {#log_directory_check} to ensure the log directory
79
+ * exists, and then log the given +message+ as +type+.
80
+ *
81
+ * @param [String] type The type; e.g. WARNING, ERROR, etc.
82
+ * @param [String] message The message to be logged.
83
+ *
84
+ * @return [nil]
85
+ */
86
+ VALUE logger_log(VALUE self, VALUE type, VALUE message)
87
+ {
88
+ // Declaractions and assignments.
89
+ char *log_file_name = ALLOCA_N(char, MAX_TIME_STRING_LENGTH + 1);
90
+ //
91
+ char *log_time = ALLOCA_N(char, LOG_TIME_FORMAT_LENGTH + 1); // Length of our maximum expected string
92
+ FILE *log_file;
93
+
94
+ /* 8 is The number of extra characters i.e " ", "[]", "\n" */
95
+ size_t output_string_size = 8 + RSTRING_LEN(type) + RSTRING_LEN(message) + LOG_TIME_FORMAT_LENGTH;
96
+
97
+ char *formatted_message = ALLOCA_N(char, ++output_string_size);
98
+
99
+ time_t current_time;
100
+
101
+ // Ensure we have the directory we need.
102
+ rb_funcall(self, SYM(log_directory_check), 0);
103
+
104
+ // Get the current time
105
+ time(&current_time);
106
+
107
+ // Create the file name
108
+ strftime(log_file_name, 100, LOG_FILE_FORMAT, localtime(&current_time));
109
+
110
+ // Open the log file for appending.
111
+ log_file = fopen(log_file_name, "a+");
112
+
113
+ // Make sure we can open the file.
114
+ if(log_file == NULL)
115
+ {
116
+ rb_raise(eLogError, "Could not open logfile %s for reading: %d", log_file_name, errno);
117
+ return Qnil;
118
+ }
119
+
120
+ // Create the time to log
121
+ strftime(log_time, 100, "%Y-%M-%d %X %z", localtime(&current_time));
122
+
123
+
124
+ // Create the string to log
125
+ sprintf(formatted_message, "[%s] [%s] %s\n", log_time, RSTRING_PTR(type), RSTRING_PTR(message));
126
+
127
+ // Write sting to log and close.
128
+ fputs(formatted_message, log_file);
129
+ fclose(log_file);
130
+
131
+ return Qnil;
132
+ }
133
+
134
+ /* @overload log_directory_check()
135
+ * @private
136
+ *
137
+ * This will check whether the log directory exists, and attempt to create it
138
+ * in the event that it doesn't.
139
+ *
140
+ * @raise [LogError] If directory creation fails.
141
+ * @return [nil]
142
+ */
143
+ VALUE logger_log_directory_check(VALUE self)
144
+ {
145
+ int result;
146
+
147
+ #ifdef WIN32
148
+ result = _mkdir("logs/");
149
+ #else
150
+ result = mkdir("logs", S_IRWXU);
151
+ #endif
152
+
153
+ // Only raise an error if we fail to create the directory.
154
+ if(result != 0 && errno != EEXIST)
155
+ {
156
+ int error_number = errno;
157
+ rb_iv_set(self, "@status", ID2SYM(SYM(bad)));
158
+ rb_raise(eLogError, "Could not create logs/: %s", strerror(error_number));
159
+ }
160
+
161
+ return Qnil;
162
+ }
163
+
164
+ /* initializes Auto::Logger in Ruby */
165
+ void init_auto_logger()
166
+ {
167
+ cLogger = rb_define_class_under(mAuto, "Logger", rb_cObject);
168
+ rb_define_method(cLogger, "initialize", logger_init, 0);
169
+ rb_define_method(cLogger, "error", logger_error, 1);
170
+ rb_define_method(cLogger, "debug", logger_debug, 1);
171
+ rb_define_method(cLogger, "warning", logger_warning, 1);
172
+ rb_define_method(cLogger, "info", logger_info, 1);
173
+ rb_define_private_method(cLogger, "log_directory_check", logger_log_directory_check, 0);
174
+ rb_define_private_method(cLogger, "log", logger_log, 2);
175
+ }
176
+
177
+ /* vim: set ts=4 sts=4 sw=4 et cindent: */
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Copyright (c) 2013, Autumn Perrault, et al.
3
+ * All rights reserved.
4
+ * This free software is distributed under the FreeBSD license (LICENSE.md).
5
+ *
6
+ */
7
+
8
+ #ifndef __AUTO_LOGGER_H__
9
+ #define __AUTO_LOGGER_H__
10
+
11
+ // Set format based on target OS.
12
+ #ifdef WIN32
13
+ #define LOG_FILE_FORMAT "logs\\%Y%m%d.log"
14
+ #else
15
+ #define LOG_FILE_FORMAT "logs/%Y%m%d.log"
16
+ #endif
17
+
18
+ // This is based on the desired output give or take a few characters.
19
+ #define MAX_TIME_STRING_LENGTH 18
20
+
21
+ // ("YYYY-MM-DD HH:MM:SS +ZZZZ") "YEAR-MONTH-DAY HOUR:MINUTES:SECONDS UTC_OFFSET"
22
+ #define LOG_TIME_FORMAT_LENGTH 25
23
+
24
+ VALUE cLogger;
25
+
26
+ VALUE logger_init(VALUE self);
27
+
28
+ VALUE logger_error(VALUE self, VALUE message);
29
+
30
+ VALUE logger_debug(VALUE self, VALUE message);
31
+
32
+ VALUE logger_warning(VALUE self, VALUE message);
33
+
34
+ VALUE logger_info(VALUE self, VALUE message);
35
+
36
+ VALUE logger_log(VALUE self, VALUE type, VALUE message);
37
+
38
+ VALUE logger_log_directory_check(VALUE self);
39
+
40
+ void init_auto_logger();
41
+
42
+
43
+ #endif
44
+ // __AUTO_LOGGER_H__
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (LICENSE.md).
3
+
4
+ require 'auto/rubyext/string'
5
+ require 'auto/version'
6
+ require 'libauto' # include the native extension
7
+ require 'auto/bot'
8
+
9
+ module Auto
10
+
11
+ # @return [Boolean] Whether we're installed as a gem.
12
+ def self.gem?
13
+ begin
14
+ # If we already checked, just return the result of that.
15
+ return @gem if defined? @gem
16
+
17
+ # Otherwise, check.
18
+ result = Gem.path.each do |gempath|
19
+ break true if __FILE__ =~ /^#{Regexp.escape gempath}/
20
+ end
21
+ @gem = (result == true ? true : false)
22
+ ensure
23
+ @gem ||= false
24
+ end
25
+ end
26
+
27
+ # @return [Boolean] Whether we're running on Microsoft Windows.
28
+ def self.windows?
29
+ begin
30
+ return @windows if defined? @windows
31
+ if ::RbConfig::CONFIG['host_os'] =~ /bccwin|djgpp|mswin|mingw|cygwin|wince/i
32
+ @windows = true
33
+ else
34
+ @windows = false
35
+ end
36
+ ensure
37
+ @windows ||= false
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (LICENSE.md).
3
+
4
+ require 'auto/api/events'
5
+ require 'auto/api/timers'
6
+
7
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,166 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (LICENSE.md).
3
+
4
+ require 'thread'
5
+ require 'auto/api/object'
6
+
7
+ # Entering namespace: Auto
8
+ module Auto
9
+
10
+ # Entering namespace: API
11
+ module API
12
+
13
+ # A class which provides the the fundamental event system, upon which
14
+ # much of the API is based, and which follows a simple model of broadcasting
15
+ # and hooking onto such broadcasts.
16
+ #
17
+ # Plugin writers may be rather interested in {Auto::DSL::Base}, since that
18
+ # provides a simpler interface to Auto's instances of this class.
19
+ #
20
+ # @api Auto
21
+ # @since 4.0.0
22
+ # @author noxgirl
23
+ #
24
+ # @see Auto::DSL::Base
25
+ #
26
+ # @!attribute [r] threads
27
+ # @return [Array] An array of threads used by {#call}.
28
+ class Events < Auto::API::Object
29
+
30
+ attr_reader :events, :threads
31
+
32
+ # Create a new instance of Auto::API::Events.
33
+ def initialize
34
+ @events = {}
35
+ @threads = []
36
+ end
37
+
38
+ # Listen for (hook onto) an event.
39
+ #
40
+ # @param [Symbol] event The name of the event for which to listen.
41
+ # @param [Integer] priority The priority of the event from 1-5, 1 being utmost priority.
42
+ #
43
+ # @yield [...] The arguments that will be yielded to the block vary by event.
44
+ # Please consult with the {file:docs/Events.md events specification} for details by event.
45
+ #
46
+ # @return [Array(Symbol, Integer, String)] Identification data including a unique string. Keep
47
+ # this if you need to destroy the hook later.
48
+ #
49
+ # @example
50
+ # events.on :disconnect do |irc|
51
+ # puts "I'm dying!"
52
+ # end
53
+ #
54
+ # @see Auto::DSL::Base#on
55
+ # @see file:docs/Events.md
56
+ def on(event, priority=3, &cb)
57
+
58
+ # Priority must be in the range of 1-5.
59
+ unless (1..5).include? priority
60
+ return 0
61
+ end
62
+
63
+ # If the event does not exist, create it.
64
+ @events[event] ||= {1 => {}, 2 => {}, 3 => {}, 4 => {}, 5 => {}}
65
+
66
+ # Generate a unique pseudorandom ID for this hook.
67
+ id = ''
68
+ 10.times { id += get_rand_char }
69
+ while @events[event][priority].has_key? id
70
+ id = ''
71
+ 10.times { id += get_rand_char }
72
+ end
73
+
74
+ # Create the hook in memory.
75
+ @events[event][priority][id] = cb
76
+
77
+ [event, priority, id]
78
+
79
+ end
80
+
81
+ # Broadcast an event and associated arguments.
82
+ #
83
+ # The arguments are globbed into an array from the list passed to the
84
+ # method, so be sure to format your call correctly.
85
+ #
86
+ # If a hook returns +false+, all subsequent hook executions will be
87
+ # forestalled from occurring.
88
+ #
89
+ # @param [Symbol] event The event being broadcasted.
90
+ # @param [Array] args A list of arguments which should be passed to
91
+ # the listeners. (splat)
92
+ #
93
+ # @example
94
+ # events.call(:cow_moo, "the cows", "go moo", [1, 3, 5])
95
+ #
96
+ # @see Auto::DSL::Base#emit
97
+ def call(event, *args)
98
+ # Check if any hooks exist for this event.
99
+ if @events.include? event
100
+ $m.debug("A thread is spawning for the sake of a broadcast of event {#{event}}.") if $m.opts.verbose?
101
+ @threads << Thread.new(event) do |evnt|
102
+ status = nil
103
+ begin # catch exceptions
104
+ # Iterate through the hooks.
105
+ @events[evnt].each_key do |priority|
106
+ @events[evnt][priority].each_value do |prc|
107
+ status = prc.call(*args) unless status == false
108
+ end # each hook
109
+ end # each priority
110
+ rescue => e
111
+ $m.error "An exception occurred inside the thread of #{event}: #{e}", false, e.backtrace
112
+ $m.error "Said thread has terminated with a backtrace report."
113
+ end # begin
114
+ end # thread
115
+ end # whether this event exists
116
+ end
117
+
118
+ # Delete a hook or listener.
119
+ #
120
+ # @param [Array(Symbol, Integer, String)] id The identification data of the hook,
121
+ # as provided by #on.
122
+ #
123
+ # @see Auto::DSL::Base#undo_on
124
+ def del(id)
125
+ event, priority, hook = id
126
+
127
+ if @events.has_key? event
128
+ if @events[event][priority].has_key? hook
129
+ @events[event][priority].delete(hook)
130
+ end
131
+ end
132
+
133
+ tidy
134
+ end
135
+
136
+ # Terminate all active threads.
137
+ def die
138
+ @threads.each do |thr|
139
+ thr.kill if thr.active?
140
+ end
141
+ end
142
+
143
+ #######
144
+ private
145
+ #######
146
+
147
+ # Tidy up.
148
+ def tidy
149
+ @events.each do |name, lists|
150
+ empty = true
151
+ empty = lists.each_value { |v| break false if not v.empty? }
152
+ if empty
153
+ # Drop the event.
154
+ @events.delete name
155
+ next
156
+ end
157
+ end
158
+ end
159
+
160
+ end # class Events
161
+
162
+ end # module API
163
+
164
+ end # module Auto
165
+
166
+ # vim: set ts=4 sts=2 sw=2 et: