syndi 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +12 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +8 -0
- data/INSTALL.md +86 -0
- data/LICENSE +28 -0
- data/README.md +104 -0
- data/Rakefile +26 -0
- data/WINDOWS.md +64 -0
- data/bin/syndi +102 -0
- data/bin/syndi-conf +47 -0
- data/conf/example.yml +101 -0
- data/docs/Events.md +103 -0
- data/docs/Upgrade.md +16 -0
- data/ext/csyndi/events.c +50 -0
- data/ext/csyndi/extconf.rb +20 -0
- data/ext/csyndi/integer.c +53 -0
- data/ext/csyndi/libauto.c +37 -0
- data/ext/csyndi/logger.c +228 -0
- data/include/syndi/csyndi.h +38 -0
- data/include/syndi/events.h +19 -0
- data/include/syndi/integer.h +17 -0
- data/include/syndi/logger.h +57 -0
- data/include/syndi.h +22 -0
- data/lib/syndi/actress.rb +12 -0
- data/lib/syndi/api/events.rb +170 -0
- data/lib/syndi/api/object.rb +29 -0
- data/lib/syndi/api/plugin.rb +155 -0
- data/lib/syndi/api.rb +7 -0
- data/lib/syndi/bot.rb +270 -0
- data/lib/syndi/config.rb +113 -0
- data/lib/syndi/configure/cli.rb +23 -0
- data/lib/syndi/configure/generator.rb +410 -0
- data/lib/syndi/configure.rb +19 -0
- data/lib/syndi/dsl/base.rb +74 -0
- data/lib/syndi/dsl/irc.rb +13 -0
- data/lib/syndi/events.rb +114 -0
- data/lib/syndi/irc/common.rb +63 -0
- data/lib/syndi/irc/library.rb +89 -0
- data/lib/syndi/irc/object/channel.rb +21 -0
- data/lib/syndi/irc/object/entity.rb +90 -0
- data/lib/syndi/irc/object/message.rb +99 -0
- data/lib/syndi/irc/object/user.rb +139 -0
- data/lib/syndi/irc/protocol/numerics.rb +60 -0
- data/lib/syndi/irc/protocol.rb +164 -0
- data/lib/syndi/irc/sasl/diffie_hellman.rb +36 -0
- data/lib/syndi/irc/sasl/mech/dh_blowfish.rb +83 -0
- data/lib/syndi/irc/sasl/mech/plain.rb +39 -0
- data/lib/syndi/irc/sasl/mech.rb +15 -0
- data/lib/syndi/irc/server.rb +301 -0
- data/lib/syndi/irc/state/channel_manager.rb +6 -0
- data/lib/syndi/irc/state/support.rb +142 -0
- data/lib/syndi/irc/state/user_manager.rb +6 -0
- data/lib/syndi/irc/std/commands.rb +99 -0
- data/lib/syndi/irc/std/numerics.rb +216 -0
- data/lib/syndi/irc.rb +8 -0
- data/lib/syndi/jewel/specification.rb +121 -0
- data/lib/syndi/jewel/util.rb +27 -0
- data/lib/syndi/jewel.rb +5 -0
- data/lib/syndi/rubyext/string.rb +10 -0
- data/lib/syndi/verbosity.rb +10 -0
- data/lib/syndi/version.rb +38 -0
- data/lib/syndi.rb +129 -0
- data/spec/helper.rb +32 -0
- data/spec/syndi/events_spec.rb +43 -0
- data/tasks/compile.rake +15 -0
- data/tasks/install.rake +10 -0
- data/tasks/package.rake +13 -0
- data/tasks/spec.rake +12 -0
- metadata +101 -13
data/lib/syndi/config.rb
ADDED
@@ -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:
|