irconnect 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dceeaa4921ecd73f225a56d9d117012c87a3d21d
4
+ data.tar.gz: 973ba8dd099a6004a67712c85ffc225186a32876
5
+ SHA512:
6
+ metadata.gz: 7526d562c12c5be0dafa89a712b06c5d7822c936d418f1e842e2e75398f269c0e54f1471ce61c9ccf0aa63cb51062aebf3f5cc6de89a1f222d9517e53e59b7d1
7
+ data.tar.gz: 70326593920dcb75fe539d10cdfca50b30586c4d06a5b67dc3ee427640978812ba74a0d965e4348422ae38fc4dbb5601495f56a01ae3b0f7fc2d62f8f4281e4e
@@ -0,0 +1,41 @@
1
+
2
+ module IRConnect
3
+ # represents an IRC Command received from the server
4
+ class Command
5
+ attr_reader :prefix, :command, :params, :last_param
6
+
7
+ # IRC message format:
8
+ # :<prefix> <command> <params> :<trailing>
9
+ # info on parsing commands:
10
+ # http://goo.gl/N3YGLq
11
+ def initialize(command_string)
12
+ fail 'Bad IRC command format' unless command_string =~ /
13
+ \A (?::([^\040]+)\040)? # prefix
14
+ ([A-Za-z]+|\d{3}) # command
15
+ ((?:\040[^:][^\040]+)*) # all but the last param
16
+ (?:\040:?(.*))? # last param
17
+ \Z
18
+ /x
19
+ @prefix, @command = Regexp.last_match(1), Regexp.last_match(2)
20
+ parse_params(Regexp.last_match(3), Regexp.last_match(4))
21
+ end
22
+
23
+ def ==(other)
24
+ prefix == other.prefix &&
25
+ command == other.command &&
26
+ params == other.params
27
+ end
28
+
29
+ private
30
+
31
+ def parse_params(param, param_last)
32
+ if param.empty?
33
+ @params = []
34
+ else
35
+ @params = param.split
36
+ @params << param_last unless param_last.nil?
37
+ end
38
+ @last_param = params.last
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,123 @@
1
+ require 'socket'
2
+ require './lib/command'
3
+
4
+ module IRConnect
5
+ # Simple wrapper around common IRC commands
6
+ class Connection
7
+ DEFAULT_OPTIONS = { port: 6667, socket_class: TCPSocket }
8
+
9
+ attr_reader :socket, :port, :connected, :nick, :server, :command_buffer
10
+
11
+ LOGIN_COMMANDS = {
12
+ '001' => 'RPL_WELCOME',
13
+ '431' => 'ERR_NONICKNAMEGIVEN',
14
+ '432' => 'ERR_ERRONEUSNICKNAME',
15
+ '433' => 'ERR_NICKNAMEINUSE',
16
+ '436' => 'ERR_NICKCOLLISION',
17
+ '461' => 'ERR_NEEDMOREPARAMS',
18
+ '462' => 'ERR_ALREADYREGISTERED'
19
+ }
20
+
21
+ JOIN_COMMANDS = {
22
+ '461' => 'ERR_NEEDMOREPARAMS',
23
+ '471' => 'ERR_CHANNELISFULL',
24
+ '473' => 'ERR_INVITEONLYCHAN',
25
+ '474' => 'ERR_BANNEDFROMCHAN',
26
+ '475' => 'ERR_BADCHANNELKEY',
27
+ '476' => 'ERR_BADCHANMASK',
28
+ '403' => 'ERR_NOSUCHCHANNEL',
29
+ '405' => 'ERR_TOOMANYCHANNELS',
30
+ '332' => 'RPL_TOPIC',
31
+ '353' => 'RPL_NAMREPLY'
32
+ }
33
+
34
+ def initialize(server, options = {})
35
+ options = DEFAULT_OPTIONS.merge(options)
36
+ @server = server
37
+ @port = options[:port]
38
+ @nick = options[:nick]
39
+ @socket = options[:socket_class].new(@server, @port)
40
+ @command_buffer = []
41
+ end
42
+
43
+ def nick(name)
44
+ unless name =~ /\A[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]+\z/i
45
+ fail 'Invalid NICK'
46
+ end
47
+ send("NICK #{name}")
48
+ end
49
+
50
+ # host and server are typically ignored by servers
51
+ # for security reasons
52
+ def user(nickname, hostname, servername, fullname)
53
+ send("USER #{nickname} #{hostname} #{servername} :#{fullname}")
54
+ end
55
+
56
+ def login(nickname, hostname, servername, fullname)
57
+ nick(nickname)
58
+ user(nickname, hostname, servername, fullname)
59
+ reply = receive_until { |c| LOGIN_COMMANDS.include?(c.command) }
60
+
61
+ fail 'Login error, no response from server' if reply.nil?
62
+ if reply.command != '001'
63
+ fail "Login error: #{reply.last_param}\n" \
64
+ "Received: #{reply.command} -> #{LOGIN_COMMANDS[reply.command]}"
65
+ end
66
+ end
67
+
68
+ def join_channel(chan)
69
+ send("JOIN #{chan}")
70
+ reply = receive_until { |c| JOIN_COMMANDS.include?(c.command) }
71
+
72
+ fail 'Unable to join channel, unknown error' if reply.nil?
73
+ unless reply.command == '332' || reply.command == '353'
74
+ fail "Error joining #{chan}: #{reply.last_param} \n" \
75
+ "Received: #{reply.command} -> #{JOIN_COMMANDS[reply.command]}"
76
+ end
77
+ end
78
+
79
+ def privmsg(target, message)
80
+ send("PRIVMSG #{target} :#{message}")
81
+ end
82
+
83
+ def receive
84
+ return command_buffer.shift unless command_buffer.empty?
85
+
86
+ command = receive_command
87
+ command.nil? ? nil : IRConnect::Command.new(command)
88
+ end
89
+
90
+ def receive_until
91
+ skip_commands = []
92
+
93
+ while (command = receive)
94
+ if yield(command)
95
+ command_buffer.unshift(*skip_commands)
96
+ return command
97
+ else
98
+ skip_commands << command
99
+ end
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def receive_command
106
+ command = socket.gets
107
+ return nil if command.nil?
108
+
109
+ if command =~ /\APING (.*?)\r\n\Z/
110
+ send("PONG #{Regexp.last_match(1)}")
111
+ receive_command
112
+ else
113
+ command.sub(/\r\n\Z/, '')
114
+ end
115
+ end
116
+
117
+ def send(cmd)
118
+ socket.print("#{cmd}\r\n")
119
+ rescue IOError
120
+ raise
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,3 @@
1
+ require './lib/command.rb'
2
+ require './lib/connection.rb'
3
+
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: irconnect
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Justin Speers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Wrapper around basic IRC Client functionality
14
+ email: speersj@fastmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/command.rb
20
+ - lib/connection.rb
21
+ - lib/irconnect.rb
22
+ homepage: https://github.com/jaspeers/irconnect
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.4.5
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: irconnect
46
+ test_files: []