rflow-components-irc 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/Gemfile +1 -1
- data/Rakefile +2 -6
- data/lib/rflow/components/irc.rb +9 -0
- data/lib/rflow/components/irc/client.rb +84 -3
- data/lib/rflow/components/irc/extensions.rb +3 -0
- data/lib/rflow/components/irc/version.rb +2 -1
- data/rflow-components-irc.gemspec +1 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa57ef5f0c5a9c8a4ccfd2ee5b01f9dc92032538
|
4
|
+
data.tar.gz: da9b89c383e3d7250efa503d54fffb8fce163291
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4dc2b8b1f33c7f545b500d4446da9cf3bd38b5ac189d0c07de9c65327f0ecab8bab93ec8901aa1c2f43b371c28cd15e609f05e1b4627d7f4c017410531c52349
|
7
|
+
data.tar.gz: 6fec0785928ef447592cf1ced7e07c6bfb2457fb02cff455f32e762f8f3009ef36f6f45890e49bb6f9432fcfa943db3d69f808293f8278eff94051b6b39041bc
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.1
|
1
|
+
ruby-2.3.1
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'rspec/core/rake_task'
|
3
|
-
require '
|
3
|
+
require 'yard'
|
4
4
|
Bundler::GemHelper.install_tasks
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
@@ -8,8 +8,4 @@ RSpec::Core::RakeTask.new(:spec) do |t|
|
|
8
8
|
t.rspec_opts = '--tty --color'
|
9
9
|
end
|
10
10
|
|
11
|
-
Rake::
|
12
|
-
rd.main = "README.md"
|
13
|
-
rd.rdoc_files.include("README.md", "lib/**/*.rb")
|
14
|
-
rd.rdoc_dir = File.join('doc', 'html')
|
15
|
-
end
|
11
|
+
YARD::Rake::YardocTask.new
|
data/lib/rflow/components/irc.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
require 'rflow/components/irc/extensions'
|
2
2
|
require 'rflow/components/irc/client'
|
3
3
|
|
4
|
+
# RFlow classes.
|
4
5
|
class RFlow
|
6
|
+
# RFlow component classes.
|
5
7
|
module Components
|
8
|
+
# IRC RFlow component classes.
|
6
9
|
module IRC
|
7
10
|
# Load the schemas
|
11
|
+
# @!visibility private
|
8
12
|
SCHEMA_DIRECTORY = ::File.expand_path(::File.join(::File.dirname(__FILE__), '..', '..', '..', 'schema'))
|
9
13
|
|
14
|
+
# @!visibility private
|
10
15
|
SCHEMA_FILES = {
|
11
16
|
'irc_message.avsc' => 'RFlow::Message::Data::IRC::Message',
|
12
17
|
}
|
@@ -21,9 +26,12 @@ class RFlow
|
|
21
26
|
RFlow::Components::IRC::Extensions::IRCMessageExtension)
|
22
27
|
|
23
28
|
# Some useful IRC parsing methods
|
29
|
+
# @!visibility private
|
24
30
|
IRC_LINE_REGEX = /^(?::(\S+) )?(\S+)(?: (.+))?$/
|
31
|
+
# @!visibility private
|
25
32
|
IRC_PREFIX_REGEX = /^([^!]+)(?:!([^@]+))?(?:@(.*)+)?$/
|
26
33
|
|
34
|
+
# @!visibility private
|
27
35
|
def self.parse_irc_line(line)
|
28
36
|
match = IRC_LINE_REGEX.match(line)
|
29
37
|
unless match
|
@@ -40,6 +48,7 @@ class RFlow
|
|
40
48
|
[prefix, cmd, params]
|
41
49
|
end
|
42
50
|
|
51
|
+
# @!visibility private
|
43
52
|
def self.parse_irc_prefix(prefix)
|
44
53
|
match = IRC_PREFIX_REGEX.match(prefix)
|
45
54
|
unless match
|
@@ -2,20 +2,85 @@ require 'eventmachine'
|
|
2
2
|
require 'rflow'
|
3
3
|
|
4
4
|
class RFlow
|
5
|
+
# @!parse
|
6
|
+
# # Fake classes in this tree to document the actual message types.
|
7
|
+
# class Message
|
8
|
+
# # Fake classes in this tree to document the actual message types.
|
9
|
+
# class Data
|
10
|
+
# # IRC messages.
|
11
|
+
# module IRC
|
12
|
+
# # RFlow format defined for IRC messages which can be emitted by
|
13
|
+
# # {RFlow::Components::IRC::Client}. Of course the real class
|
14
|
+
# # is {RFlow::Message} with type +RFlow::Message::Data::IRC::Message+.
|
15
|
+
# class Message
|
16
|
+
# # @!attribute timestamp
|
17
|
+
# # The timestamp of the message. Accepts a +Time+ or +String+.
|
18
|
+
# # @return [String] in XML schema format
|
19
|
+
# #
|
20
|
+
# # @!attribute prefix
|
21
|
+
# # The message prefix.
|
22
|
+
# # @return [String]
|
23
|
+
# #
|
24
|
+
# # @!attribute command
|
25
|
+
# # The IRC command.
|
26
|
+
# # @return [String]
|
27
|
+
# #
|
28
|
+
# # @!attribute parameters
|
29
|
+
# # IRC parameters.
|
30
|
+
# # @return [String]
|
31
|
+
# #
|
32
|
+
# # Just here to force Yard to create documentation.
|
33
|
+
# # @!visibility private
|
34
|
+
# def initialize; end
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
|
5
40
|
module Components
|
6
41
|
module IRC
|
42
|
+
# Component that subscribes to an IRC channel and issues +RFlow::Message+s
|
43
|
+
# of type {RFlow::Message::Data::IRC::Message} when it receives messages.
|
44
|
+
#
|
7
45
|
# Assumes a single connection, meaning that it can choose to be
|
8
46
|
# 'promiscuous' and not limit its sending to only those messages
|
9
47
|
# derived from one of its own
|
48
|
+
#
|
49
|
+
# Accepts config parameters:
|
50
|
+
# - +server+ - server address
|
51
|
+
# - +port+ - server port
|
52
|
+
# - +server_password+ - server password, not sent if nil
|
53
|
+
# - +nickname+ - IRC nickname
|
54
|
+
# - +username+ - server username
|
55
|
+
# - +oper_user+ - op username, defaults to nickname if nil
|
56
|
+
# - +oper_password+ - op password
|
57
|
+
# - +nickserv_password+ - nickserv password, not sent if nil
|
58
|
+
# - +reconnect_interval+ - reconnect interval in seconds
|
59
|
+
# - +promiscuous+ - true to listen to all messages; false to listen only to those with provenance linking to us
|
10
60
|
class Client < RFlow::Component
|
61
|
+
# @!attribute [r] to_server
|
62
|
+
# Expects +RFlow::Message+s of type {RFlow::Message::Data::IRC::Message}
|
63
|
+
# to be sent along the IRC channel.
|
64
|
+
#
|
65
|
+
# @return [RFlow::Component::InputPort]
|
11
66
|
input_port :to_server
|
67
|
+
# @!attribute [r] from_server
|
68
|
+
# Outputs +RFlow::Message+s of type {RFlow::Message::Data::IRC::Message}
|
69
|
+
# when receiving an IRC message.
|
70
|
+
#
|
71
|
+
# @return [RFlow::Component::OutputPort]
|
12
72
|
output_port :from_server
|
73
|
+
# @!attribute [r] log_port
|
74
|
+
# Outputs +RFlow::Message+s of type {RFlow::Message:Data::Log}
|
75
|
+
# when there are log messages to be emitted, as with reconnection problems.
|
76
|
+
#
|
77
|
+
# @return [RFlow::Component::OutputPort]
|
13
78
|
output_port :log_port
|
14
79
|
|
15
|
-
|
16
|
-
attr_accessor :client_connection
|
17
|
-
attr_accessor :server, :port
|
80
|
+
# @!visibility private
|
81
|
+
attr_accessor :config, :client_connection, :server, :port
|
18
82
|
|
83
|
+
# Default configuration.
|
19
84
|
DEFAULT_CONFIG = {
|
20
85
|
'server' => '127.0.0.1',
|
21
86
|
'port' => 6667,
|
@@ -29,6 +94,8 @@ class RFlow
|
|
29
94
|
'promiscuous' => true,
|
30
95
|
}
|
31
96
|
|
97
|
+
# RFlow-called method at startup.
|
98
|
+
# @return [void]
|
32
99
|
def configure!(config)
|
33
100
|
@config = DEFAULT_CONFIG.merge config
|
34
101
|
|
@@ -40,6 +107,8 @@ class RFlow
|
|
40
107
|
@port = @config['port'].to_i
|
41
108
|
end
|
42
109
|
|
110
|
+
# RFlow-called method at startup.
|
111
|
+
# @return [void]
|
43
112
|
def run!
|
44
113
|
@client_connection = EM.connect(@server, @port, Connection) do |conn|
|
45
114
|
conn.client = self
|
@@ -47,6 +116,8 @@ class RFlow
|
|
47
116
|
end
|
48
117
|
end
|
49
118
|
|
119
|
+
# RFlow-called method at message arrival.
|
120
|
+
# @return [void]
|
50
121
|
def process_message(input_port, input_port_key, connection, message)
|
51
122
|
RFlow.logger.debug { "#{name}: Received a message" }
|
52
123
|
return unless message.data_type_name == 'RFlow::Message::Data::IRC::Message'
|
@@ -70,18 +141,23 @@ class RFlow
|
|
70
141
|
end
|
71
142
|
end
|
72
143
|
|
144
|
+
# @!visibility private
|
73
145
|
class Connection < EventMachine::Connection
|
74
146
|
include EventMachine::Protocols::LineText2
|
75
147
|
|
148
|
+
# @!visibility private
|
76
149
|
attr_accessor :client
|
150
|
+
# @!visibility private
|
77
151
|
attr_reader :client_ip, :client_port, :server_ip, :server_port
|
78
152
|
|
153
|
+
# @!visibility private
|
79
154
|
def post_init
|
80
155
|
@client_port, @client_ip = Socket.unpack_sockaddr_in(get_peername) rescue ["?", "?.?.?.?"]
|
81
156
|
@server_port, @server_ip = Socket.unpack_sockaddr_in(get_sockname) rescue ["?", "?.?.?.?"]
|
82
157
|
super
|
83
158
|
end
|
84
159
|
|
160
|
+
# @!visibility private
|
85
161
|
def connection_completed
|
86
162
|
@reconnecting = false
|
87
163
|
@connected = true
|
@@ -95,6 +171,7 @@ class RFlow
|
|
95
171
|
command "OPER", [client.config['oper_user'] || client.config['nickname'], client.config['oper_password']] unless client.config['oper_password'].nil?
|
96
172
|
end
|
97
173
|
|
174
|
+
# @!visibility private
|
98
175
|
def receive_line(line)
|
99
176
|
RFlow.logger.debug { "#{client.name}: IRCClient#receive_line: #{line}" }
|
100
177
|
prefix, cmd, params = IRC.parse_irc_line(line)
|
@@ -119,6 +196,7 @@ class RFlow
|
|
119
196
|
end
|
120
197
|
end
|
121
198
|
|
199
|
+
# @!visibility private
|
122
200
|
def unbind(reason = nil)
|
123
201
|
if @connected || @reconnecting
|
124
202
|
RFlow.logger.error "#{client.name}: Disconnected from IRC server #{client.config['server']}:#{client.config['port']} due to '#{reason}', reconnecting ..."
|
@@ -140,16 +218,19 @@ class RFlow
|
|
140
218
|
end
|
141
219
|
end
|
142
220
|
|
221
|
+
# @!visibility private
|
143
222
|
def send_irc_message(irc_message)
|
144
223
|
RFlow.logger.debug { "#{client.name}: Sending an IRC message to #{client_ip}:#{client_port}" }
|
145
224
|
command irc_message.data.command, irc_message.data.parameters, irc_message.data.prefix
|
146
225
|
end
|
147
226
|
|
227
|
+
# @!visibility private
|
148
228
|
def send_irc_line(line)
|
149
229
|
RFlow.logger.debug { "#{client.name}: Sending line '#{line}'" }
|
150
230
|
send_data "#{line}\r\n"
|
151
231
|
end
|
152
232
|
|
233
|
+
# @!visibility private
|
153
234
|
def command(cmd, args = [], prefix = nil)
|
154
235
|
RFlow.logger.debug { "#{client.name}: command: '#{cmd}' with args ['#{args.join("', '")}'] and prefix '#{prefix}'" }
|
155
236
|
line = ''
|
@@ -1,8 +1,11 @@
|
|
1
1
|
class RFlow
|
2
2
|
module Components
|
3
3
|
module IRC
|
4
|
+
# @!visibility private
|
4
5
|
module Extensions
|
6
|
+
# @!visibility private
|
5
7
|
module IRCMessageExtension
|
8
|
+
# @!visibility private
|
6
9
|
def self.extended(base_data)
|
7
10
|
base_data.data_object ||= {'timestamp' => Time.now.xmlschema, 'prefix' => nil, 'command' => 'PRIVMSG', 'parameters' => []}
|
8
11
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rflow-components-irc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael L. Artz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rflow
|
@@ -72,6 +72,20 @@ dependencies:
|
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '10.3'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: yard
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0.9'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0.9'
|
75
89
|
description: IRC client and server components for the RFlow FBP framework. Also includes
|
76
90
|
the necessary message types
|
77
91
|
email:
|
@@ -118,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
132
|
version: '0'
|
119
133
|
requirements: []
|
120
134
|
rubyforge_project: rflow-components-irc
|
121
|
-
rubygems_version: 2.
|
135
|
+
rubygems_version: 2.5.1
|
122
136
|
signing_key:
|
123
137
|
specification_version: 4
|
124
138
|
summary: IRC client and server components for the RFlow FBP framework
|