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
@@ -0,0 +1,142 @@
|
|
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 IRC
|
6
|
+
module State
|
7
|
+
|
8
|
+
# A state-management class which records the various capabilities of the
|
9
|
+
# IRC daemon.
|
10
|
+
#
|
11
|
+
# @!attribute connected
|
12
|
+
# @return [Boolean] Whether we are connected and registered.
|
13
|
+
#
|
14
|
+
# @!attribute cap
|
15
|
+
# @return [Array<String>] A list of enabled capabilities.
|
16
|
+
#
|
17
|
+
# @!attribute sasl_method
|
18
|
+
# @return [Symbol] Method of SASL authentication (+:plain+ or +:dh_blowfish+).
|
19
|
+
#
|
20
|
+
# @!attribute sasl_id
|
21
|
+
# @return [Array<String>] Identities of SASL-related timers.
|
22
|
+
#
|
23
|
+
# @!attribute server_name
|
24
|
+
# @return [String] Name of the server to which we are connected (e.g. asimov.freenode.net).
|
25
|
+
#
|
26
|
+
# @!attribute nicklen
|
27
|
+
# @return [Integer] The maximum length of a nickname permissible.
|
28
|
+
#
|
29
|
+
# @!attribute prefixes
|
30
|
+
# @return [Hash{Symbol => String}] The list of channel user prefixes supported.
|
31
|
+
#
|
32
|
+
# @!attribute chan_modes
|
33
|
+
# @return [Hash{Symbol => Array<Symbol>}] The list of channel modes supported. The keys
|
34
|
+
# are +:never+, +:list+, +:set+, and +:always+. List: list mode (e.g. +b). Never:
|
35
|
+
# never has a parameter. Set: has a parameter only when set. Always: always has a
|
36
|
+
# parameter.
|
37
|
+
#
|
38
|
+
# @!attribute modelen
|
39
|
+
# @return [Integer] The maximum number of modes permissible in a single /MODE.
|
40
|
+
#
|
41
|
+
# @!attribute topiclen
|
42
|
+
# @return [Integer] The maximum length of a /TOPIC permissible.
|
43
|
+
#
|
44
|
+
# @!attribute chanlen
|
45
|
+
# @return [Integer] The maximum length of a channel's name permissible.
|
46
|
+
class Support
|
47
|
+
|
48
|
+
attr_accessor :cap, :sasl_method, :sasl_id, :server_name, :nicklen, :prefixes,
|
49
|
+
:chan_modes, :modelen, :topiclen, :chanlen, :connected
|
50
|
+
|
51
|
+
def initialize
|
52
|
+
# hashes
|
53
|
+
%w[chan_modes prefixes].each do |hsh|
|
54
|
+
instance_variable_set("@#{hsh}", {})
|
55
|
+
end
|
56
|
+
# arrays
|
57
|
+
%w[cap sasl_id].each do |arr|
|
58
|
+
instance_variable_set("@#{arr}", [])
|
59
|
+
end
|
60
|
+
# strings/symbols/booleans/integers
|
61
|
+
%w[sasl_method server_name nicklen topiclen modelen chanlen
|
62
|
+
connected].each do |str|
|
63
|
+
instance_variable_set("@#{str}", nil)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Process ISUPPORT data.
|
68
|
+
#
|
69
|
+
# @param [Syndi::IRC::Server] irc The IRC connection.
|
70
|
+
# @param [String] data The ISUPPORT data string.
|
71
|
+
def isupport irc, data
|
72
|
+
|
73
|
+
# Nick, channel, topic, and mode length
|
74
|
+
{'@nicklen' => 'NICKLEN',
|
75
|
+
'@chanlen' => 'CHANNELLEN',
|
76
|
+
'@topiclen' => 'TOPICLEN',
|
77
|
+
'@modelen' => 'MODES' }.each_pair do |var, indic|
|
78
|
+
|
79
|
+
if data =~ /#{indic}=(\d+)/
|
80
|
+
instance_variable_set(var, $1.to_i)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
# Parse channel modes.
|
86
|
+
parse_channel_modes data
|
87
|
+
|
88
|
+
# Parse prefixes.
|
89
|
+
parse_prefixes data
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
#######
|
94
|
+
private
|
95
|
+
#######
|
96
|
+
|
97
|
+
# Parse supported channel modes.
|
98
|
+
#
|
99
|
+
# @param [String] data The data string.
|
100
|
+
def parse_channel_modes data
|
101
|
+
if match = %r{\WCHANMODES=(\w+),(\w+),(\w+),(\w+)\W}.match(data)
|
102
|
+
list = match[1].split // || []
|
103
|
+
always = match[2].split // || []
|
104
|
+
set = match[3].split // || []
|
105
|
+
never = match[4].split // || []
|
106
|
+
|
107
|
+
list.map! { |m| m.to_sym }
|
108
|
+
always.map! { |m| m.to_sym }
|
109
|
+
set.map! { |m| m.to_sym }
|
110
|
+
never.map! { |m| m.to_sym }
|
111
|
+
|
112
|
+
{ list: list, always: always, set: set, never: never }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Parse supported prefixes.
|
117
|
+
#
|
118
|
+
# @param [String] data The data string.
|
119
|
+
def parse_prefixes data
|
120
|
+
if match = %r{\WPREFIX=\((\w+)\)(\W+)\s}.match(data)
|
121
|
+
modes = match[1].split //
|
122
|
+
prefixes = match[2].split //
|
123
|
+
|
124
|
+
modes.map! { |m| m.to_sym }
|
125
|
+
|
126
|
+
i = 0
|
127
|
+
modes.each do |m|
|
128
|
+
@prefixes[m] = prefixes[i]
|
129
|
+
i += 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end # class Support
|
135
|
+
|
136
|
+
end # module State
|
137
|
+
|
138
|
+
end # module IRC
|
139
|
+
|
140
|
+
end # module Syndi
|
141
|
+
|
142
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,99 @@
|
|
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
|
+
module IRC
|
7
|
+
|
8
|
+
module Std
|
9
|
+
|
10
|
+
# A module which provides a number of methods for basic IRC commands,
|
11
|
+
# intended for inclusion in {Syndi::IRC::Server}.
|
12
|
+
module Commands
|
13
|
+
|
14
|
+
# Send initial AUTHENTICATE.
|
15
|
+
def authenticate method = :plain
|
16
|
+
if method == :plain
|
17
|
+
snd 'AUTHENTICATE PLAIN'
|
18
|
+
@supp.sasl_method = :plain
|
19
|
+
elsif method == :dh_blowfish
|
20
|
+
snd 'AUTHENTICATE DH-BLOWFISH'
|
21
|
+
@supp.sasl_method = :dh_blowfish
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Send CAP END.
|
26
|
+
def cap_end
|
27
|
+
# Stop any SASL-related timers
|
28
|
+
@supp.sasl_id.each { |t| $m.clock.del t }
|
29
|
+
# Send CAP END
|
30
|
+
snd 'CAP END'
|
31
|
+
end
|
32
|
+
|
33
|
+
# Disconnect from the server.
|
34
|
+
#
|
35
|
+
# @param [String] msg Reason for disconnect.
|
36
|
+
def disconnect msg = 'Closing connection'
|
37
|
+
emit :irc, :disconnect, self, msg
|
38
|
+
snd "QUIT :#{msg}"
|
39
|
+
@socket = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Join a channel on the server.
|
43
|
+
#
|
44
|
+
# @param [String] chan Channel to join.
|
45
|
+
# @param [String] key Key to join, if necessary.
|
46
|
+
def join chan, key = nil
|
47
|
+
snd "JOIN #{chan}#{key.nil? ? '' : key}"
|
48
|
+
emit :irc, :send_join, self, chan, key
|
49
|
+
end
|
50
|
+
|
51
|
+
# Send /NICK to change the bot's nickname on the server.
|
52
|
+
#
|
53
|
+
# @note If the nickname is in use, the bot will append a hyphen and retry,
|
54
|
+
# repeating until success is achieved.
|
55
|
+
#
|
56
|
+
# @param [String] new The new nickname.
|
57
|
+
def nickname= new
|
58
|
+
|
59
|
+
if connected?
|
60
|
+
@newnick = new
|
61
|
+
else
|
62
|
+
@nick = new
|
63
|
+
end
|
64
|
+
|
65
|
+
snd "NICK :#{new}"
|
66
|
+
emit :irc, :send_nick, self, new
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
# Supply server password.
|
71
|
+
#
|
72
|
+
# @param [String] pass
|
73
|
+
def pass password; snd "PASS :#{password}"; end
|
74
|
+
|
75
|
+
# Send /USER.
|
76
|
+
#
|
77
|
+
# @param [String] username The bot's username or ident.
|
78
|
+
# @param [String] hostname The bot's hostname.
|
79
|
+
# @param [String] server Address of the remote server.
|
80
|
+
# @param [String] realname The bot's real name or GECOS.
|
81
|
+
def user username, hostname=Socket.gethostname, server, realname
|
82
|
+
snd "USER #{username} #{hostname} #{server} :#{realname}"
|
83
|
+
end
|
84
|
+
|
85
|
+
# Request a /WHO on ourselves.
|
86
|
+
def who
|
87
|
+
snd "WHO #@nick"
|
88
|
+
emit :irc, :who_self, self
|
89
|
+
end
|
90
|
+
|
91
|
+
end # module Commands
|
92
|
+
|
93
|
+
end # module Std
|
94
|
+
|
95
|
+
end # module IRC
|
96
|
+
|
97
|
+
end # module Syndi
|
98
|
+
|
99
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,216 @@
|
|
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 IRC
|
8
|
+
module IRC
|
9
|
+
|
10
|
+
# namespace Std
|
11
|
+
module Std
|
12
|
+
|
13
|
+
# A module which provides constant representatives of all useful IRC numerics
|
14
|
+
# as specified by the IRC v3.1 protocol.
|
15
|
+
#
|
16
|
+
# @see http://tools.ietf.org/html/rfc1459
|
17
|
+
# @see http://ircv3.atheme.org/
|
18
|
+
module Numerics
|
19
|
+
|
20
|
+
# errors (RFC1459)
|
21
|
+
ERR_NOSUCHNICK = '401'
|
22
|
+
ERR_NOSUCHSERVER = '402'
|
23
|
+
ERR_NOSUCHCHANNEL = '403'
|
24
|
+
ERR_CANNOTSENDTOCHAN = '404'
|
25
|
+
ERR_TOOMANYCHANNELS = '405'
|
26
|
+
ERR_WASNOSUCHNICK = '406'
|
27
|
+
ERR_TOOMANYTARGETS = '407'
|
28
|
+
|
29
|
+
ERR_NOORIGIN = '409'
|
30
|
+
|
31
|
+
ERR_NORECIPIENT = '411'
|
32
|
+
ERR_NOTEXTTOSEND = '412'
|
33
|
+
ERR_NOTOPLEVEL = '413'
|
34
|
+
ERR_WILDTOPLEVEL = '414'
|
35
|
+
|
36
|
+
ERR_UNKNOWNCOMMAND = '421'
|
37
|
+
ERR_NOMOTD = '422'
|
38
|
+
ERR_NOADMININFO = '423'
|
39
|
+
ERR_FILEERROR = '424'
|
40
|
+
|
41
|
+
ERR_NONICKNAMEGIVEN = '431'
|
42
|
+
ERR_ERRONEUSNICKNAME = '432'
|
43
|
+
ERR_NICKNAMEINUSE = '433'
|
44
|
+
ERR_NICKCOLLISION = '436'
|
45
|
+
|
46
|
+
ERR_USERNOTINCHANNEL = '441'
|
47
|
+
ERR_NOTONCHANNEL = '442'
|
48
|
+
ERR_USERONCHANNEL = '443'
|
49
|
+
ERR_NOLOGIN = '444'
|
50
|
+
ERR_SUMMONDISABLED = '445'
|
51
|
+
ERR_USERSDISABLED = '446'
|
52
|
+
|
53
|
+
ERR_NOTREGISTERED = '451'
|
54
|
+
|
55
|
+
ERR_NEEDMOREPARAMS = '461'
|
56
|
+
ERR_ALEADYREGISTERED = '462'
|
57
|
+
ERR_NOPERMFORHOST = '463'
|
58
|
+
ERR_PASSWDMISMATCH = '464'
|
59
|
+
ERR_YOUREBANNEDCREEP = '465'
|
60
|
+
ERR_KEYSET = '467'
|
61
|
+
|
62
|
+
ERR_CHANNELISFULL = '471'
|
63
|
+
ERR_UNKNOWNMODE = '472'
|
64
|
+
ERR_INVITEONLYCHAN = '473'
|
65
|
+
ERR_BANNEDFROMCHAN = '474'
|
66
|
+
ERR_BADCHANNELKEY = '475'
|
67
|
+
|
68
|
+
ERR_NOPRIVILEGES = '481'
|
69
|
+
ERR_CHANOPRIVSNEEDED = '482'
|
70
|
+
ERR_CANTKILLSERVER = '483'
|
71
|
+
|
72
|
+
ERR_NOOPERHOST = '491'
|
73
|
+
|
74
|
+
ERR_UMODEUNKNOWNFLAG = '501'
|
75
|
+
ERR_USERSDONTMATCH = '502'
|
76
|
+
|
77
|
+
# responses (RFC1459)
|
78
|
+
RPL_AWAY = '301'
|
79
|
+
RPL_USERHOST = '302'
|
80
|
+
RPL_ISON = '303'
|
81
|
+
|
82
|
+
RPL_UNAWAY = '305'
|
83
|
+
RPL_NOWAWAY = '306'
|
84
|
+
|
85
|
+
RPL_WHOISUSER = '311'
|
86
|
+
RPL_WHOISSERVER = '312'
|
87
|
+
RPL_WHOISOPERATOR = '313'
|
88
|
+
RPL_WHOWASUSER = '314'
|
89
|
+
RPL_ENDOFWHO = '315'
|
90
|
+
|
91
|
+
RPL_WHOISIDLE = '317'
|
92
|
+
RPL_ENDOFWHOIS = '318'
|
93
|
+
RPL_WHOISCHANNELS = '319'
|
94
|
+
|
95
|
+
RPL_LISTSTART = '321'
|
96
|
+
RPL_LIST = '322'
|
97
|
+
RPL_LISTEND = '323'
|
98
|
+
RPL_CHANNELMODEIS = '324'
|
99
|
+
|
100
|
+
RPL_NOTOPIC = '331'
|
101
|
+
RPL_TOPIC = '332'
|
102
|
+
|
103
|
+
RPL_INVITING = '341'
|
104
|
+
RPL_SUMMONING = '342'
|
105
|
+
|
106
|
+
RPL_VERSION = '351'
|
107
|
+
RPL_WHOREPLY = '352'
|
108
|
+
RPL_NAMREPLY = '353'
|
109
|
+
|
110
|
+
RPL_LINKS = '364'
|
111
|
+
RPL_ENDOFLINKS = '365'
|
112
|
+
RPL_ENDOFNAMES = '366'
|
113
|
+
RPL_BANLIST = '367'
|
114
|
+
RPL_ENDOFBANLIST = '368'
|
115
|
+
RPL_ENDOFWHOWAS = '369'
|
116
|
+
|
117
|
+
RPL_INFO = '371'
|
118
|
+
RPL_MOTD = '372'
|
119
|
+
|
120
|
+
RPL_ENDOFINFO = '374'
|
121
|
+
RPL_MOTDSTART = '375'
|
122
|
+
RPL_ENDOFMOTD = '376'
|
123
|
+
|
124
|
+
RPL_YOUREOPER = '381'
|
125
|
+
RPL_REHASHING = '382'
|
126
|
+
|
127
|
+
RPL_TIME = '391'
|
128
|
+
RPL_USERSSTART = '392'
|
129
|
+
RPL_USERS = '393'
|
130
|
+
RPL_ENDOFUSERS = '394'
|
131
|
+
RPL_NOUSERS = '395'
|
132
|
+
|
133
|
+
# more command responses in the 200-299 range (RFC1459)
|
134
|
+
RPL_TRACELINK = '200'
|
135
|
+
RPL_TRACECONNECTING = '201'
|
136
|
+
RPL_TRACEHANDSHAKE = '202'
|
137
|
+
RPL_TRACEUNKNOWN = '203'
|
138
|
+
RPL_TRACEOPERATOR = '204'
|
139
|
+
RPL_TRACEUSER = '205'
|
140
|
+
RPL_TRACESERVER = '206'
|
141
|
+
|
142
|
+
RPL_TRACENEWTYPE = '208'
|
143
|
+
|
144
|
+
RPL_STATSLINKINFO = '211'
|
145
|
+
RPL_STATSCOMMANDS = '212'
|
146
|
+
RPL_STATSCLINE = '213'
|
147
|
+
RPL_STATSNLINE = '214'
|
148
|
+
RPL_STATSILINE = '215'
|
149
|
+
RPL_STATSKLINE = '216'
|
150
|
+
|
151
|
+
RPL_STATSYLINE = '218'
|
152
|
+
RPL_ENDOFSTATS = '219'
|
153
|
+
|
154
|
+
RPL_UMODEIS = '221'
|
155
|
+
|
156
|
+
RPL_STATSLLINE = '241'
|
157
|
+
RPL_STATSUPTIME = '242'
|
158
|
+
RPL_STATSOLINE = '243'
|
159
|
+
RPL_STATSHLINE = '244'
|
160
|
+
|
161
|
+
RPL_LUSERCLIENT = '251'
|
162
|
+
RPL_LUSEROP = '252'
|
163
|
+
RPL_LUSERUNKNOWN = '253'
|
164
|
+
RPL_LUSERCHANNELS = '254'
|
165
|
+
RPL_LUSERME = '255'
|
166
|
+
RPL_ADMINME = '256'
|
167
|
+
RPL_ADMINLOC1 = '257'
|
168
|
+
RPL_ADMINLOC2 = '258'
|
169
|
+
RPL_ADMINEMAIL = '259'
|
170
|
+
|
171
|
+
RPL_TRACELOG = '261'
|
172
|
+
|
173
|
+
# '900'+ and SASL
|
174
|
+
RPL_LOGGEDIN = '900'
|
175
|
+
RPL_LOGGEDOUT = '901'
|
176
|
+
|
177
|
+
RPL_SASLSUCCESS = '903'
|
178
|
+
|
179
|
+
ERR_SASLFAIL = '904'
|
180
|
+
ERR_SASLTOOLONG = '905'
|
181
|
+
ERR_SASLABORTED = '906'
|
182
|
+
ERR_SASLALREADY = '907'
|
183
|
+
|
184
|
+
# RFC1459 so-called 'reserved' numerics
|
185
|
+
RPL_TRACECLASS = '209'
|
186
|
+
RPL_SERVICEINFO = '231'
|
187
|
+
RPL_SERVICE = '233'
|
188
|
+
RPL_SERVLISTEND = '235'
|
189
|
+
RPL_WHOISCHANOP = '316'
|
190
|
+
RPL_CLOSING = '362'
|
191
|
+
RPL_INFOSTART = '373'
|
192
|
+
RPL_STATSQLINE = '217'
|
193
|
+
RPL_ENDOFSERVICES = '232'
|
194
|
+
RPL_SERVLIST = '234'
|
195
|
+
|
196
|
+
ERR_YOUWILLBEBANNED = '466'
|
197
|
+
ERR_NOSERVICEHOST = '492'
|
198
|
+
ERR_BADCHANMASK = '476'
|
199
|
+
|
200
|
+
# additional RFC2812 numerics
|
201
|
+
RPL_WELCOME = '001'
|
202
|
+
RPL_YOURHOST = '002'
|
203
|
+
RPL_CREATED = '003'
|
204
|
+
RPL_MYINFO = '004'
|
205
|
+
RPL_ISUPPORT = '005' # ISUPPORT favored over BOUNCE
|
206
|
+
RPL_BOUNCE = '010' # here in lieu of 005
|
207
|
+
|
208
|
+
end # module Numerics
|
209
|
+
|
210
|
+
end # module Std
|
211
|
+
|
212
|
+
end # module IRC
|
213
|
+
|
214
|
+
end # module Syndi
|
215
|
+
|
216
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
data/lib/syndi/irc.rb
ADDED
@@ -0,0 +1,121 @@
|
|
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 'syndi'
|
5
|
+
require 'syndi/jewel/util'
|
6
|
+
|
7
|
+
class JewelError < StandardError; end
|
8
|
+
|
9
|
+
module Syndi
|
10
|
+
|
11
|
+
module Jewel
|
12
|
+
include Syndi::Jewel::Util
|
13
|
+
|
14
|
+
# A specification for an Syndi jewel (i.e. plugin, extension, etc.).
|
15
|
+
#
|
16
|
+
# @!attribute name
|
17
|
+
class Specification
|
18
|
+
|
19
|
+
attr_reader :name, :version, :authors, :syndi_version, :our_dir,
|
20
|
+
:bundle, :code_files, :doc_files, :post_message,
|
21
|
+
:install_do
|
22
|
+
|
23
|
+
def omg *args
|
24
|
+
args.each do |unicorn|
|
25
|
+
puts "==> #{unicorn}".magenta
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Construct a new specification.
|
30
|
+
#
|
31
|
+
# @param [String] file The value of +__FILE__+ as accessed from the spec itself.
|
32
|
+
def initialize file
|
33
|
+
@name = nil
|
34
|
+
@version = nil
|
35
|
+
@authors = []
|
36
|
+
@syndi_version = nil
|
37
|
+
@our_dir = File.expand_path('..', file)
|
38
|
+
@bundle = 'Gemfile'
|
39
|
+
@code_files = []
|
40
|
+
@doc_files = []
|
41
|
+
@post_message = nil
|
42
|
+
|
43
|
+
@install_do = proc { nil }
|
44
|
+
|
45
|
+
# Yield to block for configuration.
|
46
|
+
yield self
|
47
|
+
|
48
|
+
# Initiate installation.
|
49
|
+
install
|
50
|
+
end
|
51
|
+
|
52
|
+
# Sets the jewel name.
|
53
|
+
#
|
54
|
+
# @param [String] monkey The name of the jewel.
|
55
|
+
def name= monkey
|
56
|
+
raise JewelError, 'Invalid jewel name!' unless monkey.instance_of? String
|
57
|
+
monkey.downcase!
|
58
|
+
|
59
|
+
@name = monkey
|
60
|
+
omg "Jewel name: #{monkey.green}"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sets the jewel version.
|
64
|
+
#
|
65
|
+
# @param [String] mascara The version of the jewel.
|
66
|
+
def version= mascara
|
67
|
+
mascara.downcase!
|
68
|
+
|
69
|
+
@version = mascara
|
70
|
+
omg "Jewel version: #{mascara.green}"
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sets the jewel author (only one).
|
74
|
+
#
|
75
|
+
# @param [String] its_a_trap The (sole) author of the jewel.
|
76
|
+
def author= its_a_trap
|
77
|
+
raise JewelError, 'Invalid jewel author!' unless its_a_trap.instance_of? String
|
78
|
+
|
79
|
+
@authors.push its_a_trap
|
80
|
+
omg "Jewel written by #{its_a_trap.blue}"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Sets multiple jewel authors.
|
84
|
+
#
|
85
|
+
# @param [Array] chi The authors of the jewel. (splat)
|
86
|
+
def authors= *chi
|
87
|
+
raise JewelError, 'Invalid jewel author list!' unless chi.instance_of? Array
|
88
|
+
raise JewelError, 'Invalid method of author specification!' unless chi.length > 1
|
89
|
+
|
90
|
+
@authors = chi
|
91
|
+
omg "Jewel written by #{chi.join ', '}"
|
92
|
+
end
|
93
|
+
|
94
|
+
# Sets the Syndi version required by the jewel.
|
95
|
+
#
|
96
|
+
# @param [String] essie The minimum Syndi version required.
|
97
|
+
def syndi_version= essie
|
98
|
+
if Gem::Version.new(essie.dup) < Gem::Version.new(Syndi::VERSION.dup)
|
99
|
+
raise JewelError, "This jewel requires Syndi version >= #{essie.red} but current version is #{Syndi::VERSION}!"
|
100
|
+
end
|
101
|
+
|
102
|
+
@syndi_version = essie
|
103
|
+
omg "Jewel is compatible with your version of Syndi (requires: >= #{essie.green})!"
|
104
|
+
end
|
105
|
+
|
106
|
+
# Sets the name of the GemBundler Gemfile. Default is +Gemfile+.
|
107
|
+
#
|
108
|
+
# @param [String] sephora The name of the Gemfile.
|
109
|
+
def bundle= sephora = 'Gemfile'
|
110
|
+
raise JewelError, "Jewel's Gemfile is missing!" unless File.exists? File.join(@our_dir, sephora)
|
111
|
+
|
112
|
+
@bundle = sephora
|
113
|
+
end
|
114
|
+
|
115
|
+
end # class Specification
|
116
|
+
|
117
|
+
end # module Jewel
|
118
|
+
|
119
|
+
end # module Syndi
|
120
|
+
|
121
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,27 @@
|
|
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 'syndi'
|
5
|
+
|
6
|
+
class JewelCutError < StandardError; end
|
7
|
+
|
8
|
+
module Syndi
|
9
|
+
|
10
|
+
module Jewel
|
11
|
+
|
12
|
+
module Util
|
13
|
+
|
14
|
+
# Install the jewel.
|
15
|
+
def install
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
data/lib/syndi/jewel.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# This changes the String class in Ruby's standard library to make life easier
|
2
|
+
# by aliasing String#uc to String#upcase and String#dc to String#downcase
|
3
|
+
class String
|
4
|
+
alias_method :uc, :upcase
|
5
|
+
alias_method :dc, :downcase
|
6
|
+
alias_method :uc!, :upcase!
|
7
|
+
alias_method :dc!, :downcase!
|
8
|
+
end
|
9
|
+
|
10
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,38 @@
|
|
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
|
+
# Standard version string.
|
7
|
+
#
|
8
|
+
# We use semantic versioning: +MAJOR.MINOR.PATCH.PRE.PRENUM+
|
9
|
+
VERSION = '0.1.0'.freeze
|
10
|
+
|
11
|
+
# Standard version plus the codename (assigned to each minor release).
|
12
|
+
#
|
13
|
+
# i.e., +VERSION-CODENAME+
|
14
|
+
FULLVERSION = "#{VERSION}-phoenix".freeze
|
15
|
+
|
16
|
+
# @return [Boolean] Whether this is an alpha-stage copy.
|
17
|
+
def self.alpha?
|
18
|
+
(VERSION =~ /alpha/).nil? ? false : true
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean] Whether this is a beta-stage copy.
|
22
|
+
def self.beta?
|
23
|
+
(VERSION =~ /beta/).nil? ? false : true
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Boolean] Whether this is a release candidate copy.
|
27
|
+
def self.rc?
|
28
|
+
(VERSION =~ /rc/).nil? ? false : true
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Boolean] Whether this is an edge (i.e. testing, development, unstable) copy.
|
32
|
+
def self.edge?
|
33
|
+
alpha? || beta? || rc?
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
# vim: set ts=4 sts=2 sw=2 et:
|