syndi 0.0.1 → 0.1.0

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +12 -0
  3. data/CHANGELOG.md +0 -0
  4. data/Gemfile +8 -0
  5. data/INSTALL.md +86 -0
  6. data/LICENSE +28 -0
  7. data/README.md +104 -0
  8. data/Rakefile +26 -0
  9. data/WINDOWS.md +64 -0
  10. data/bin/syndi +102 -0
  11. data/bin/syndi-conf +47 -0
  12. data/conf/example.yml +101 -0
  13. data/docs/Events.md +103 -0
  14. data/docs/Upgrade.md +16 -0
  15. data/ext/csyndi/events.c +50 -0
  16. data/ext/csyndi/extconf.rb +20 -0
  17. data/ext/csyndi/integer.c +53 -0
  18. data/ext/csyndi/libauto.c +37 -0
  19. data/ext/csyndi/logger.c +228 -0
  20. data/include/syndi/csyndi.h +38 -0
  21. data/include/syndi/events.h +19 -0
  22. data/include/syndi/integer.h +17 -0
  23. data/include/syndi/logger.h +57 -0
  24. data/include/syndi.h +22 -0
  25. data/lib/syndi/actress.rb +12 -0
  26. data/lib/syndi/api/events.rb +170 -0
  27. data/lib/syndi/api/object.rb +29 -0
  28. data/lib/syndi/api/plugin.rb +155 -0
  29. data/lib/syndi/api.rb +7 -0
  30. data/lib/syndi/bot.rb +270 -0
  31. data/lib/syndi/config.rb +113 -0
  32. data/lib/syndi/configure/cli.rb +23 -0
  33. data/lib/syndi/configure/generator.rb +410 -0
  34. data/lib/syndi/configure.rb +19 -0
  35. data/lib/syndi/dsl/base.rb +74 -0
  36. data/lib/syndi/dsl/irc.rb +13 -0
  37. data/lib/syndi/events.rb +114 -0
  38. data/lib/syndi/irc/common.rb +63 -0
  39. data/lib/syndi/irc/library.rb +89 -0
  40. data/lib/syndi/irc/object/channel.rb +21 -0
  41. data/lib/syndi/irc/object/entity.rb +90 -0
  42. data/lib/syndi/irc/object/message.rb +99 -0
  43. data/lib/syndi/irc/object/user.rb +139 -0
  44. data/lib/syndi/irc/protocol/numerics.rb +60 -0
  45. data/lib/syndi/irc/protocol.rb +164 -0
  46. data/lib/syndi/irc/sasl/diffie_hellman.rb +36 -0
  47. data/lib/syndi/irc/sasl/mech/dh_blowfish.rb +83 -0
  48. data/lib/syndi/irc/sasl/mech/plain.rb +39 -0
  49. data/lib/syndi/irc/sasl/mech.rb +15 -0
  50. data/lib/syndi/irc/server.rb +301 -0
  51. data/lib/syndi/irc/state/channel_manager.rb +6 -0
  52. data/lib/syndi/irc/state/support.rb +142 -0
  53. data/lib/syndi/irc/state/user_manager.rb +6 -0
  54. data/lib/syndi/irc/std/commands.rb +99 -0
  55. data/lib/syndi/irc/std/numerics.rb +216 -0
  56. data/lib/syndi/irc.rb +8 -0
  57. data/lib/syndi/jewel/specification.rb +121 -0
  58. data/lib/syndi/jewel/util.rb +27 -0
  59. data/lib/syndi/jewel.rb +5 -0
  60. data/lib/syndi/rubyext/string.rb +10 -0
  61. data/lib/syndi/verbosity.rb +10 -0
  62. data/lib/syndi/version.rb +38 -0
  63. data/lib/syndi.rb +129 -0
  64. data/spec/helper.rb +32 -0
  65. data/spec/syndi/events_spec.rb +43 -0
  66. data/tasks/compile.rake +15 -0
  67. data/tasks/install.rake +10 -0
  68. data/tasks/package.rake +13 -0
  69. data/tasks/spec.rake +12 -0
  70. metadata +101 -13
@@ -0,0 +1,113 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ require 'psych'
5
+ require 'syndi/verbosity'
6
+ require 'libsyndi'
7
+
8
+ # Namespace: Syndi
9
+ module Syndi
10
+
11
+ # A class which provides a functional, simple configuration interface. It uses
12
+ # YAML by means of Psych.
13
+ #
14
+ # @api Syndi
15
+ # @since 4.0.0
16
+ # @author noxgirl
17
+ # @author swarley
18
+ #
19
+ # @!attribute conf
20
+ # @return [Hash{}] This is the hash which contains the data parsed from
21
+ # the configuration file.
22
+ # @see #[]
23
+ class Config
24
+
25
+ attr_reader :conf, :type
26
+
27
+ # Produce a new instance, and attempt to parse.
28
+ #
29
+ # @param [String] filepath Path to configuration file.
30
+ def initialize filepath
31
+ $m.verbose("Trying to initialize configuration from '#{filepath}'...", VSIMPLE) do
32
+ @path = filepath
33
+ parse
34
+ end # verbose
35
+ end
36
+
37
+ # Rehash the configuration.
38
+ #
39
+ # If an error occurs, it will revert the configuration to its prior state
40
+ # so that everything can continue to function.
41
+ def rehash!
42
+
43
+ $m.debug("Configuration file is rehashing.")
44
+
45
+ # Keep the old configuration in case of issues.
46
+ oldconf = @conf
47
+ @conf = {}
48
+
49
+ # Rehash
50
+ parse!
51
+
52
+ # Ensure it really succeeded.
53
+ if @conf.empty? or !@conf.instance_of? Hash
54
+ # Nope. Restore old configuration.
55
+ @conf = oldconf
56
+ $m.error 'Failed to rehash the configuration file (parser produced empty config)! Reverting to old configuration.'
57
+ return 0
58
+ end
59
+
60
+ $m.events.call :rehash
61
+
62
+ # This rescue is applicable to anything that happens in here, since if it is reached, there really was an error in general.
63
+ rescue => e
64
+ $m.error 'Failed to rehash configuration file! Reverting to old configuration.', false, e.backtrace
65
+ @conf = oldconf
66
+ return 0
67
+ end
68
+
69
+ # Return value of @conf[key].
70
+ #
71
+ # @return [Object] Value of @conf[key].
72
+ # @see @conf
73
+ def [] key
74
+ @conf[key]
75
+ end
76
+
77
+ #######
78
+ private
79
+ #######
80
+
81
+ # Parse the configuration file, and output the data to {#x}.
82
+ #
83
+ # @raise [ConfigError] If the file does not exist.
84
+ # @raise [ConfigError] If the file cannot be processed.
85
+ def parse
86
+
87
+ # Ensure foremost that the configuration file exists.
88
+ unless File.exists? @path
89
+ raise ConfigError, "Configuration file '#@path' does not exist!"
90
+ end
91
+
92
+ # Get the data from the file.
93
+ f = File.open(@path)
94
+ data = f.read
95
+ f.close
96
+
97
+ conf = {}
98
+ # Process the YAML.
99
+ begin
100
+ conf = Psych.load data
101
+ rescue => e
102
+ raise ConfigError, "Failed to process the YAML in '#@path'", e.backtrace
103
+ end
104
+
105
+ @conf = conf
106
+
107
+ end # def parse
108
+
109
+ end # class Config
110
+
111
+ end # module Syndi
112
+
113
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ require 'thor'
5
+ require 'psych'
6
+
7
+ module Syndi
8
+ module Configure
9
+
10
+ # A command-line interface for making modifications to an existing Syndi
11
+ # configuration file (which is in YAML).
12
+ class CLI < Thor
13
+
14
+
15
+
16
+
17
+ end
18
+
19
+ end
20
+ end
21
+
22
+
23
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,410 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ require 'colored'
5
+ require 'highline'
6
+ require 'yaml'
7
+
8
+ $S = '>>>'.blue
9
+
10
+
11
+ # Check To make sure that we have a decent ruby version. There is no reason to support a
12
+ # version that has reached EOL.
13
+ if RUBY_VERSION < "1.9"
14
+ puts <<-EOM
15
+ The version of ruby that you are using is out dated. Please upgrade to a version of at least
16
+ 1.9.1 to run syndi. The ruby source code is located here http://ruby-lang.org/en/downloads
17
+ EOM
18
+ end
19
+
20
+ # namespace Syndi
21
+ module Syndi
22
+
23
+ # A library for configuration generation. It depends upon the highline gem.
24
+ #
25
+ # @version 1.02
26
+ # @author swarley
27
+ # @author noxgirl
28
+ #
29
+ # @!attribute hl
30
+ # @return [HighLine] HighLine instance.
31
+ #
32
+ # @!attribute conf
33
+ # @return [Hash{}] The configuration hash.
34
+ class Configure
35
+
36
+ syndiload :Shell, 'syndi/configure/shell'
37
+ # Load the shell.
38
+ def shell
39
+ Syndi::Configure::Shell.new(@hl)
40
+ end
41
+
42
+ VERSION = '1.02'.freeze
43
+ SYNDIDIR = File.join(Dir.home, '.config', 'syndibot')
44
+
45
+ attr_accessor :hl, :conf
46
+
47
+ # Produce a new instance of Syndi::Configure.
48
+ def initialize
49
+
50
+ # Produce a new instance of HighLine.
51
+ @hl = HighLine.new
52
+ # Prepare for configuration.
53
+ @conf = Hash.new
54
+
55
+ end
56
+
57
+ # Initiate configuration.
58
+ def generate
59
+
60
+ greeting = <<-EOM
61
+ Greetings! ^.^
62
+
63
+ I am going to assist you in configuring your installation of Syndi. :) I suggest
64
+ that, if you're not already reading it, you consult the installation guide:
65
+ https://github.com/Syndi/Syndi/wiki/Install-Guide
66
+
67
+ When specifying lists, separate elements by commas.
68
+
69
+ Remember, if you need additional help, you're free to use the mailing list at
70
+ https://groups.google.com/group/syndibot-talk, or to join the official IRC
71
+ channel at #syndi on irc.freenode.net. :)
72
+
73
+ Let us begin!
74
+ EOM
75
+ puts greeting.yellow.bold
76
+
77
+ conf_libraries
78
+ conf_database
79
+
80
+ dump
81
+
82
+ end
83
+
84
+ # Configure libraries.
85
+ def conf_libraries
86
+ puts ">>> Currently, the only available library is the IRC library. I will load this automatically.".cyan.bold
87
+ @conf['libraries'] = ['irc']
88
+
89
+ conf_irclib
90
+ end
91
+
92
+ # Configure the IRC library.
93
+ def conf_irclib
94
+
95
+ # Create the configuration hash.
96
+ @conf['irc'] = {}
97
+
98
+ # Add the first server.
99
+ conf_irc_add_server
100
+
101
+ # Add subsequent servers.
102
+ another = @hl.agree("#$S Would you like to add another IRC server? ") { |q| q.default = 'n' }
103
+ while another
104
+ conf_irc_add_server
105
+ another = @hl.agree("#$S Would you like to add another IRC server? ") { |q| q.default = 'n' }
106
+ end
107
+
108
+ end
109
+
110
+ # Add an IRC server.
111
+ def conf_irc_add_server
112
+
113
+ # We need a name.
114
+ name = @hl.ask("#$S What is the name of this IRC server? ")
115
+ while @conf['irc'].include? name
116
+ puts "You've already specified that server. Use a different name.".red.bold
117
+ name = @hl.ask("#$S What is the name of this IRC server?")
118
+ end
119
+
120
+ # We need an address.
121
+ address = @hl.ask("#$S What is the address of <%= color('#{name}', :blue, :bold) %>? ")
122
+
123
+ # And a port.
124
+ port = @hl.ask("#$S What is the port of <%= color('#{name}', :blue, :bold) %>? ", Integer) { |q| q.default = 6667 }
125
+
126
+ # Does it use SSL?
127
+ ssl = @hl.agree("#$S Does <%= color('#{address}:#{port}', :blue, :bold) %> use SSL? ") { |q| q.default = 'n' }
128
+
129
+ # What nickname(s) should we use?
130
+ nicks = @hl.ask("#$S What nicknames should I use on <%= color('#{name}', :blue, :bold) %> (list in descending priority)? ",
131
+ ->(str) { str.split(/,\s*/) }) { |q| q.default = 'syndi' }
132
+ nicksvalid = true
133
+ nicks.each { |n| nicksvalid = false unless n =~ /^[\w\d\[\]\{\}\^\-\_\`]+$/ }
134
+ until nicksvalid
135
+ puts "You entered an invalid nickname. Try again.".red.bold
136
+ nicks = @hl.ask("#$S What nicknames should I use on <%= color('#{name}', :blue, :bold) %> (list in descending priority)? ",
137
+ ->(str) { str.split(/,\s*/) }) { |q| q.default = 'syndi' }
138
+ nicksvalid = true
139
+ nicks.each { |n| nicksvalid = false unless n =~ /^[\w\d\[\]\{\}\^\-\_\`]+$/ }
140
+ end
141
+
142
+ # What username?
143
+ user = @hl.ask("#$S What username should I use on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'syndi' }
144
+
145
+ # What GECOS?
146
+ gecos = @hl.ask("#$S What real name or GECOS should I use on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'Syndi (http://syndi.syndiproj.org)' }
147
+
148
+ # Save the data.
149
+ @conf['irc'][name] = {
150
+ 'address' => address,
151
+ 'port' => port,
152
+ 'useSSL' => ssl,
153
+ 'nickname' => nicks,
154
+ 'username' => user,
155
+ 'realName' => gecos
156
+ }
157
+
158
+ # Should we use SASL?
159
+ sasl = @hl.agree("#$S Should I use SASL to authenticate with services on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'n' }
160
+
161
+ if sasl
162
+
163
+ sasl_user = @hl.ask("#$S What username (i.e. accountname) should I use in SASL authentication? ")
164
+ sasl_pass = @hl.ask("#$S What is the password for <%= color('#{sasl_user}', :blue, :bold) %>? ") { |q| q.echo = false }
165
+ sasl_to = @hl.ask("#$S After how many seconds should SASL authentication time out? ", Integer) { |q| q.default = 15 }
166
+
167
+ @conf['irc'][name]['SASL'] = {
168
+ 'username' => sasl_user,
169
+ 'password' => sasl_pass,
170
+ 'timeout' => sasl_to,
171
+ }
172
+
173
+ else
174
+ # Perhaps NickServ or some other service?
175
+ auth = @hl.agree("#$S OK. Should I identify with a service (e.g. NickServ)? ") { |q| q.default = 'n' }
176
+
177
+ if auth
178
+
179
+ service = @hl.ask("#$S What service should I message? ") { |q| q.default = 'NickServ' }
180
+ command = @hl.ask("#$S What command should I use to identify? ") { |q| q.default = 'IDENTIFY' }
181
+ password = @hl.ask("#$S What password should I use? ") { |q| q.echo = false }
182
+
183
+ @conf['irc'][name]['nickIdentify'] = {
184
+ 'service' => service,
185
+ 'command' => command,
186
+ 'password' => password
187
+ }
188
+
189
+ end
190
+
191
+ end
192
+
193
+ # Setup syndijoin.
194
+ conf_irc_syndijoin name
195
+
196
+ end
197
+
198
+ # Configure syndijoin.
199
+ #
200
+ # @param [String] name Name of IRC server.
201
+ def conf_irc_syndijoin(name)
202
+ another = @hl.agree("#$S Should I automatically join a channel on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'y' }
203
+ @conf['irc'][name]['syndijoin'] = []
204
+
205
+ while another
206
+ @conf['irc'][name]['syndijoin'] << conf_irc_add_channel
207
+ another = @hl.agree("#$S Should I automatically join another channel? ") { |q| q.default = 'n' }
208
+ end
209
+ end
210
+
211
+ # Add an IRC channel.
212
+ #
213
+ # @param [String] server The name of the IRC server.
214
+ def conf_irc_add_channel
215
+
216
+ # What's it called?
217
+ name = @hl.ask("#$S What is the name of the channel? ") { |q| q.default = '#syndi' }
218
+
219
+ # Does it use a key?
220
+ usekey = @hl.agree("#$S Does <%= color('#{name}', :blue, :bold) %> use a key (+k)? ") { |q| q.default = 'n' }
221
+ key = nil
222
+
223
+ if usekey
224
+ key = @hl.ask("#$S What is the key? ")
225
+ end
226
+
227
+ {'name' => name, 'key' => key}
228
+ end
229
+
230
+ # Configure the database.
231
+ def conf_database
232
+ @conf['database'] = Hash.new
233
+
234
+ msg = <<-eom
235
+ >> Syndi supports three database management systems: SQLite 3, MySQL, and Postgres.
236
+ >> If you use SQLite 3, you need the 'sqlite3' gem.
237
+ >> If you use MySQL, you need the 'mysqlplus' gem.
238
+ >> If you use Postgres, you need the 'pg' gem.
239
+ >> See https://github.com/Syndi/Syndi/wiki/Install-Guide for more information.
240
+ eom
241
+ puts msg.cyan
242
+
243
+ type = @hl.ask("#$S What database management system should I use? (sqlite, mysql, or postgres) ") do |q|
244
+ q.default = 'sqlite'
245
+ q.validate = /^(sqlite|mysql|postgres)$/
246
+ end
247
+ @conf['database']['type'] = type
248
+
249
+ if type == 'sqlite'
250
+
251
+ file = @hl.ask("#$S What should be the filename of the database? (relative to <%= color('#{SYNDIDIR}', :blue, :bold) %>) ") do |q|
252
+ q.default = File.join SYNDIDIR, 'syndi.db'
253
+ end
254
+
255
+ unless Dir.exists File.dirname(file)
256
+ puts "Warning: Directory #{File.dirname(file)} does not exist.".red.bold
257
+ end
258
+
259
+ @conf['database']['name'] = file
260
+
261
+ else # mysql and pg
262
+
263
+ address = @hl.ask("#$S What is the host address of the <%= color('#{type}', :blue, :bold) %> server? ") { |q| q.default = 'localhost' }
264
+ name = @hl.ask("#$S What is the database name on the <%= color('#{type}', :blue, :bold) %> server? ") { |q| q.default = 'syndi' }
265
+ username = @hl.ask("#$S What username should I use to connect to <%= color('#{type}', :blue, :bold) %> server? ") { |q| q.default = 'syndi' }
266
+ password = @hl.ask("#$S What is the password for <%= color('#{username}', :blue, :bold) %>? ") { |q| q.echo = false }
267
+
268
+ @conf['database'].merge!({
269
+ 'address' => address,
270
+ 'name' => name,
271
+ 'username' => username,
272
+ 'password' => password
273
+ })
274
+
275
+ end
276
+
277
+ end
278
+
279
+ # Dump configuration.
280
+ def dump
281
+
282
+ # A sanity check.
283
+ if @conf.empty?
284
+ puts "Configuration is inexplicably empty: aborting.".red.bold
285
+ exit 1
286
+ end
287
+
288
+ # Produce file.
289
+ data = <<-EOD
290
+ # Configuration file generated by syndi-conf
291
+ # version #{Syndi::Configure::VERSION}
292
+ # at #{Time.now}
293
+
294
+ #{YAML.dump(@conf)}
295
+ EOD
296
+
297
+ # Produce message.
298
+ final = <<-EOM
299
+ OK! Your configuration file is ready! :D
300
+
301
+ I just need to know one last thing: where to write this fabulous configuration.
302
+
303
+ By default, I will write this to <YOUR_HOME_DIRECTORY>/.config/syndibot/syndi.yml,
304
+ which is perfect for you if you're using the 'syndibot' gem, because this is the
305
+ standard file for which the gem will look when executed.
306
+
307
+ However, if you are running a standalone installation, you probably want to
308
+ write this to your conf/ directory as syndi.yml (if you're running #$0 from the
309
+ main directory, "conf/syndi.yml"), as the standalone Syndi will look for that
310
+ when it is executed.
311
+
312
+ In any event, you are free to write this anywhere you please. Just remember
313
+ that if it is not a default path, you must specify it when running Syndi:
314
+
315
+ $ syndi --config=path/to/config/file.yml
316
+
317
+ Caution: The specified file will be overwritten if it already exists.
318
+ EOM
319
+ puts final.green.bold
320
+
321
+ # Save our directories of interest into easily accessible variables.
322
+ configdir = File.join(Dir.home, '.config')
323
+
324
+ # Ensure that said directories exist regardless of any other conditions.
325
+ unless Dir.exists? configdir
326
+ puts "~ Creating missing directory #{configdir}".magenta
327
+ Dir.mkdir configdir
328
+ end
329
+ unless Dir.exists? SYNDIDIR
330
+ puts "~ Creating missing directory #{SYNDIDIR}".magenta
331
+ Dir.mkdir SYNDIDIR
332
+ end
333
+
334
+ # Ask for a path.
335
+ path = @hl.ask("#$S To where should the configuration be written? ", String) do |q|
336
+
337
+ # Default is ~/.config/syndibot/syndi.yml
338
+ q.default = File.join(syndidir, 'syndi.yml')
339
+
340
+ # A proc to validate the path
341
+ q.validate = proc do |path|
342
+ return false unless path =~ /\.yml$/ # it should end in .yml
343
+ return false unless Dir.exists? File.dirname(path) # the directory should exist
344
+ # We should be able to write to the file:
345
+ begin
346
+ File.open(path, 'w') { |io| io.puts "# Configuration file generated by syndi-conf" }
347
+ rescue => e
348
+ return false
349
+ end
350
+ true
351
+ end
352
+
353
+ # A proc to be called in the event of an invalid path
354
+ q.responses[:not_valid] = proc do
355
+
356
+ # Choose an emergency file in ~/.config/syndibot/ to which to save.
357
+ emerg_file = File.join(syndidir, "syndi.yml.#{Time.now.strftime('%s')}")
358
+ puts "Invalid path! Attempting to write to #{emerg_file}.....".red
359
+ File.open(path, 'w') do |io|
360
+ io.write data
361
+ end
362
+
363
+ end
364
+
365
+ end # ask()
366
+
367
+ File.open(path, 'w') { |io| io.write data } # Dump the data into the file.
368
+
369
+ # We're done.
370
+ puts "I have successfully written your configuration file to #{path}. Thank you for using Syndi.".green.bold
371
+
372
+ end
373
+
374
+ end # class Configure
375
+
376
+ end # module Syndi
377
+
378
+ # This will fix a certain undesirable output.
379
+ #
380
+ # HighLine::Question#append_default appends an ugly manifestation of the
381
+ # default answer.
382
+ #
383
+ # This destroys that provided by HighLine::Question and in lieu uses a prettier
384
+ # one.
385
+ class HighLine
386
+ class Question
387
+ def append_default
388
+ str = ''
389
+ if @default == 'y'
390
+ str = "<%= color('Y', :green) %>/<%= color('n', :red) %>"
391
+ elsif @default == 'n'
392
+ str = "<%= color('y', :green) %>/<%= color('N', :red) %>"
393
+ else
394
+ str = "<%= color('#@default', :bold) %>"
395
+ end
396
+
397
+ if @question =~ /([\t ]+)\Z/
398
+ @question << "[#{str}]#{$1}"
399
+ elsif @question == ""
400
+ @question << "[#{str}] "
401
+ elsif @question[-1, 1] == "\n"
402
+ @question[-2, 0] = " [#{str}]"
403
+ else
404
+ @question << " [#{str}]"
405
+ end
406
+ end
407
+ end
408
+ end
409
+
410
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ module Syndi
5
+
6
+ # A configuration management suite.
7
+ module Configure
8
+
9
+ # syndi-conf version
10
+ VERSION = '2.00'
11
+
12
+ syndiload :CLI, 'syndi/configure/cli'
13
+ syndiload :Generator, 'syndi/configure/generator'
14
+
15
+ end
16
+
17
+ end
18
+
19
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,74 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ # Namespace: Syndi
5
+ module Syndi
6
+
7
+ # Namespace: DSL
8
+ module DSL
9
+
10
+ # A domain-specific language (DSL) wrapper mixin for simple usage of the events
11
+ # system, {Syndi::API::Events}, and the timers system, {Syndi::API::Timers}.
12
+ #
13
+ # @api DSL
14
+ # @author noxgirl
15
+ # @since 4.0.0
16
+ #
17
+ # @see Syndi::API::Events
18
+ # @see Syndi::API::Timers
19
+ module Base
20
+
21
+ # @see Syndi::API::Timers#spawn
22
+ def clock_do(*args); $m.clock.spawn(*args); end
23
+ # @see Syndi::API::Timers#del
24
+ def clock_stop(*args); $m.clock.del(*args); end
25
+
26
+ # Hook onto an event.
27
+ #
28
+ # @param [Symbol] system The events system to access.
29
+ # @param [Symbol] event The event onto which to hook.
30
+ #
31
+ # @see Syndi::API::Events#on
32
+ def on(sys, event, &prc)
33
+ if sys == :syndi # central system
34
+ $m.events.on(event, prc)
35
+ else
36
+ $m.send(sys).events.on(event, prc) if $m.respond_to? sys
37
+ end
38
+ end
39
+
40
+ # Emit an event.
41
+ #
42
+ # @param [Symbol] system The events system to access.
43
+ # @param [Symbol] event The event onto which to hook.
44
+ #
45
+ # @see Syndi::API::Events#call
46
+ def emit(sys, event, *args)
47
+ if sys == :syndi # central system
48
+ $m.events.call(event, *args)
49
+ else
50
+ $m.send(sys).events.call(event, *args) if $m.respond_to? sys
51
+ end
52
+ end
53
+
54
+ # Delete a hook.
55
+ #
56
+ # @param [Symbol] system The events system to access.
57
+ # @param [Array(Symbol, Integer, String)] hook The identification data of the hook.
58
+ #
59
+ # @see Syndi::API::Events#del
60
+ def undo_on(sys, hook)
61
+ if sys == :syndi # central system
62
+ $m.events.del(hook)
63
+ else
64
+ $m.send(sys).events.del(hook) if $m.respond_to? sys
65
+ end
66
+ end
67
+
68
+ end # module Base
69
+
70
+ end # module DSL
71
+
72
+ end # module Syndi
73
+
74
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ module Syndi
5
+ module DSL
6
+ module IRC
7
+ # ok
8
+ end
9
+ end
10
+ end
11
+
12
+
13
+ # vim: set ts=4 sts=2 sw=2 et: