iirc 0.2.1 → 0.2.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 677c6866347be71d8937503af4858234412668648f0e8f331f10aaaa7b5b2e9a
4
- data.tar.gz: 9ebd831386cfd623ba4c8edf76c1c97c447c8321008c3dfacd16e35aa4ca1388
3
+ metadata.gz: 7948a6cd83b37e9d3fa9d8bd5248e330d52ed3881afde4fecdc9d5671cefc3da
4
+ data.tar.gz: 44592080131bb88427003f8e90301402e8211f674e2826d9fac3400fbebae920
5
5
  SHA512:
6
- metadata.gz: de69d9cfe8d0a6c144b0bcd777d1f24fa3315d200fed8bfbd30ccdcf00a480057159924ea0ea3a94f5cfed81537de9f7c93b1b0740653076b1581e11929c5b08
7
- data.tar.gz: b433ad524e9645734d90f53076c2ed7a019262bea73f395d426abcb7ab289ca9f1c897c1ae6376773d6e52b1243104666639c407905b856afc2e611dccb3361d
6
+ metadata.gz: b5f9e7eb864705787c7e7cdb51608f3a0189ca983ce8d95fc16f881a2b7782610b4833122c04ad7fbef82d8a17d1cda1668f46f66a01c23b9b1a363c17874271
7
+ data.tar.gz: e9c9d869cd16d8d2585f0d7399fdb6473a47e7f0012cd038d04f1489550cc90b5af4f09c0d0de8bc25c430e9f134dfd490ff14a492457ec4a193d5595dd7cf50
data/CHANGELOG.md CHANGED
@@ -1,4 +1,37 @@
1
- ## [Unreleased]
1
+ ## [0.2.6] - 2022-03-16
2
+
3
+ - Add ircparser dependency
4
+ - It's technically optional, but it's needed to parse IRCv3 messages
5
+
6
+ ## [0.2.5] - 2022-03-16
7
+
8
+ - Add dial method. Uses SSL by default, with configurable context
9
+ - Add Bot.run method. Dials, yields an instance, then calls #run
10
+ - Add IIRC() method to top-level for DSL shorthand
11
+ - See examples/facts.rb
12
+ - Add examples/ (Facts, Greeter, Wolfram)
13
+
14
+ ## [0.2.4] - 2022-03-15
15
+
16
+ - [Bot::Hooks] Run catch-all hooks before on_#{verb} ones
17
+ - Include Bot::AmbientVerbs in Batteries
18
+ - Lets you write `say "Hello"` in event handlers instead of `say evt.target, "Hello"`
19
+ - Defaults the first arg of say,act,join,part,cycle,mode to the target of the current event
20
+ - Add Bot::PrintIO module
21
+
22
+ ## [0.2.3] - 2022-03-14
23
+
24
+ - Use new configure style for Bot::OperUp
25
+ - Use new configure style for Bot::TrackOwnNick
26
+ - Update own nick from welcome message (001)
27
+
28
+ ## [0.2.2] - 2022-03-13
29
+
30
+ - Use escape sequences in formatting.rb for readability
31
+
32
+ - Fix Event reference in parse()
33
+ - Bot::Event was moved to Event during refactor
34
+ - Missed as my code uses `include IIRC` at the top level
2
35
 
3
36
  ## [0.2.1] - 2022-03-12
4
37
 
data/examples/facts.rb ADDED
@@ -0,0 +1,30 @@
1
+ require "iirc"
2
+
3
+ IIRC {
4
+ include IIRC::Bot::PrintIO
5
+
6
+ def facts
7
+ @facts ||= {}
8
+ end
9
+
10
+ def on_privmsg(evt)
11
+ case evt.message
12
+ when /^=list\b/
13
+ say "I know about #{facts.empty? ? 'nothing' : facts.keys.join(', ')}"
14
+ when /^=tell ([[:alnum:]]+)/
15
+ say facts[$1] ? "#{$1} is #{facts[$1]}" : "I don't know what that is"
16
+ when /^=add ([[:alnum:]]+) (.+)/
17
+ say "Okay, #{$1} is #{$2}"
18
+ facts[$1] = $2
19
+ when /^=del ([[:alnum:]]+)/
20
+ say "Okay, forgetting #{$1}"
21
+ facts.delete $1
22
+ end
23
+ end
24
+
25
+ def autojoin_channels
26
+ ['##facts', '##iirc']
27
+ end
28
+
29
+ run "irc.libera.chat", nick: "FactBot[#{rand(100)}]"
30
+ }
@@ -0,0 +1,16 @@
1
+ require "iirc"
2
+
3
+ class Greeter < IIRC::Bot
4
+ include AutoJoin
5
+ include Verbs
6
+
7
+ def on_join(evt)
8
+ say evt.target, "Hello #{evt.sender.nick}!"
9
+ end
10
+
11
+ def autojoin_channels
12
+ ['##iirc']
13
+ end
14
+ end
15
+
16
+ Greeter.run 'irc.libera.chat', nick: 'GreeterBot' if __FILE__ == $0
@@ -0,0 +1,39 @@
1
+ require "net/https"
2
+ require "iirc"
3
+
4
+ class Wolfram < IIRC::Batteries
5
+ include PrintIO
6
+
7
+ def on_privmsg(evt)
8
+ case evt.message
9
+ when /^!(what .+)/, /^!(define .+)/
10
+ answer($1).then { |answer|
11
+ if answer == "Wolfram|Alpha did not understand your input"
12
+ case rand(3)
13
+ when 0
14
+ say "I have no #{%w(earthly stinkin bloody).sample} idea :)"
15
+ when 1
16
+ say "If only I knew..."
17
+ when 2
18
+ say "#{evt.sender.nick}: If you ever find out, will you tell me?"
19
+ end
20
+ else
21
+ say answer.capitalize
22
+ end
23
+ }
24
+ end
25
+ end
26
+
27
+ def answer(query)
28
+ url = URI.parse("https://api.wolframalpha.com/v1/result")
29
+ url.query = URI.encode_www_form(i: query, appid: ENV['WOLFRAM_APP_ID'])
30
+
31
+ Net::HTTP.get(url)
32
+ end
33
+
34
+ def autojoin_channels
35
+ ['##wolframbot', '##iirc']
36
+ end
37
+ end
38
+
39
+ Wolfram.run 'irc.libera.chat', nick: 'WolframBot'+rand(100).to_s
data/iirc.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ["lib"]
28
28
 
29
29
  # Uncomment to register a new dependency of your gem
30
- # spec.add_dependency "example-gem", "~> 1.0"
30
+ spec.add_dependency "ircparser", "= 1.0.0"
31
31
 
32
32
  # For more information and examples about making a new gem, checkout our
33
33
  # guide at: https://bundler.io/guides/creating_gem.html
@@ -1,11 +1,11 @@
1
1
  module IIRC
2
2
  module Bot::Formatting
3
3
  module_function
4
- def bold s; "#{s}"; end
5
- def italic s; "#{s}"; end
6
- def strike s; "#{s}"; end
7
- def underline s; "#{s}"; end
8
- def strip s; s.gsub /\x03(?:\d{1,2}(?:,\d{1,2})?)?/, ''; end
4
+ def bold(s) "\x02#{s}\x02" end
5
+ def italic(s) "\x1d#{s}\x1d" end
6
+ def strike(s) "\x1e#{s}\x1e" end
7
+ def underline(s) "\x1f#{s}\x1f" end
8
+ def strip(s) s.gsub(/\x03(?:\d{1,2}(?:,\d{1,2})?)?/, '') end
9
9
  alias :strip_formatting :strip
10
10
  end
11
11
  end
@@ -31,10 +31,13 @@ module IIRC
31
31
  end
32
32
 
33
33
  def fire! verb, *args, **kwargs
34
+ for action in hooks[nil]
35
+ call action, *args, **kwargs
36
+ end
34
37
  if respond_to? :"on_#{verb}"
35
38
  send(:"on_#{verb}", *args, **kwargs)
36
39
  end
37
- for action in [*hooks[nil], *hooks[verb]]
40
+ for action in hooks[verb]
38
41
  call action, *args, **kwargs
39
42
  end
40
43
  rescue StopIteration
@@ -1,8 +1,6 @@
1
1
  module IIRC
2
2
  module Bot::IRCv3
3
3
  class Batch < Event
4
- attr_accessor :events
5
-
6
4
  def events
7
5
  @events ||= []
8
6
  end
@@ -6,7 +6,7 @@ module IIRC
6
6
  def parse(line)
7
7
  msg = IRCParser::Message.parse(line.chomp)
8
8
 
9
- Bot::Event.new.tap { |evt|
9
+ Event.new.tap { |evt|
10
10
  evt.sender = IRCParser::RFCWireFormat.__stringify_prefix(msg.prefix) if msg.prefix
11
11
  evt.tags = msg.tags
12
12
  evt.verb = msg.command.downcase.to_sym
@@ -1,15 +1,12 @@
1
1
  module IIRC
2
2
  module Bot::OperUp
3
- def self.configure_actions
4
- [:add_oper_up_hook]
5
- end
6
-
7
- def add_oper_up_hook
8
- on :'001', :oper_up!
9
- end
10
-
11
3
  def oper_up!
12
4
  self << "OPER #{ENV['IRC_OPER']}" if ENV['IRC_OPER']
13
5
  end
6
+
7
+ private
8
+ def configure_oper_up
9
+ on :'001', :oper_up!
10
+ end
14
11
  end
15
12
  end
@@ -1,7 +1,7 @@
1
1
  module IIRC
2
2
  module Bot::Parsing
3
3
  def parse(line)
4
- Bot::Event.new.tap { |evt|
4
+ Event.new.tap { |evt|
5
5
  words = line.chomp.split " "
6
6
 
7
7
  if words[0] and words[0].start_with? ":"
@@ -0,0 +1,12 @@
1
+ module IIRC
2
+ module Bot::PrintIO
3
+ def lines
4
+ super { |line| puts ">> #{line}"; yield line }
5
+ end
6
+
7
+ def <<(line)
8
+ puts "<< #{line}"
9
+ super
10
+ end
11
+ end
12
+ end
@@ -1,9 +1,18 @@
1
1
  module IIRC
2
2
  module Bot::TrackOwnNick
3
- def on_nick evt
4
- if me === evt.sender
5
- self.user.nick = evt.args[0]
3
+ private
4
+
5
+ def configure_own_nick_tracking
6
+ on :'001', :track_own_nick_from_welcome
7
+ on :nick, :track_own_nick_change
8
+ end
9
+
10
+ def track_own_nick_from_welcome evt
11
+ me.nick = evt.args[0]
12
+ end
13
+
14
+ def track_own_nick_change evt
15
+ me.nick = evt.args[0] if me === evt.sender
6
16
  end
7
- end
8
17
  end
9
18
  end
data/lib/iirc/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IIRC
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.6"
5
5
  end
data/lib/iirc.rb CHANGED
@@ -15,6 +15,7 @@ require_relative "iirc/bot/members"
15
15
  require_relative "iirc/bot/oper_up"
16
16
  require_relative "iirc/bot/parsing"
17
17
  require_relative "iirc/bot/pong"
18
+ require_relative "iirc/bot/print_io"
18
19
  require_relative "iirc/bot/reading"
19
20
  require_relative "iirc/bot/redis"
20
21
  require_relative "iirc/bot/regex_hooks"
@@ -36,6 +37,16 @@ module IIRC
36
37
  include Configure
37
38
  include Pong
38
39
  include TrackOwnNick
40
+
41
+ def self.run(host, port=6697, ssl_context: SSL.default_context, **user_params, &blk)
42
+ socket = IIRC.dial(host, port, ssl_context: ssl_context)
43
+
44
+ new(socket, **user_params).tap { |bot|
45
+ bot.register!
46
+ bot.tap(&blk) if blk
47
+ bot.run
48
+ }
49
+ end
39
50
  end
40
51
 
41
52
  class IRCv3Bot < Bot
@@ -46,10 +57,63 @@ module IIRC
46
57
  end
47
58
 
48
59
  class Batteries < IRCv3Bot
49
- include Channels
50
- include Members
51
- include Formatting
52
- include AutoJoin
53
- include Verbs
60
+ include Bot::Channels
61
+ include Bot::Members
62
+ include Bot::Formatting
63
+ include Bot::AutoJoin
64
+ include Bot::Verbs
65
+ include Bot::AmbientVerbs
66
+ end
67
+
68
+ module SSL
69
+ module_function
70
+
71
+ def default_context
72
+ verify_peer_and_hostname
73
+ end
74
+
75
+ def verify_peer_and_hostname
76
+ verify_peer.tap { |context|
77
+ context.verify_hostname = true
78
+ }
79
+ end
80
+
81
+ def verify_peer
82
+ no_verify.tap { |context|
83
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
84
+ context.cert_store = OpenSSL::X509::Store.new.tap(&:set_default_paths)
85
+ }
86
+ end
87
+
88
+ def verify_hostname_only
89
+ no_verify.tap { |context|
90
+ context.verify_hostname = true
91
+ }
92
+ end
93
+
94
+ def no_verify
95
+ require 'openssl'
96
+ OpenSSL::SSL::SSLContext.new
97
+ end
54
98
  end
99
+
100
+ module_function
101
+ def dial(host, port=6697, ssl_context: SSL.default_context)
102
+ require 'socket'
103
+
104
+ Socket.tcp(host, port).then { |socket|
105
+ if ssl_context
106
+ OpenSSL::SSL::SSLSocket.new(socket, ssl_context).tap { |socket|
107
+ socket.hostname = host
108
+ socket.connect
109
+ }
110
+ else
111
+ socket
112
+ end
113
+ }
114
+ end
55
115
  end
116
+
117
+ def IIRC(*args, **kwargs, &blk)
118
+ Class.new(IIRC::Batteries, &blk)
119
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iirc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - mooff
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-12 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2022-03-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ircparser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
13
27
  description: A composable toolkit for IRC bots
14
28
  email:
15
29
  - mooff@awful.cooking
@@ -25,6 +39,9 @@ files:
25
39
  - Rakefile
26
40
  - bin/console
27
41
  - bin/setup
42
+ - examples/facts.rb
43
+ - examples/greeter.rb
44
+ - examples/wolfram.rb
28
45
  - iirc.gemspec
29
46
  - lib/iirc.rb
30
47
  - lib/iirc/bot.rb
@@ -42,6 +59,7 @@ files:
42
59
  - lib/iirc/bot/oper_up.rb
43
60
  - lib/iirc/bot/parsing.rb
44
61
  - lib/iirc/bot/pong.rb
62
+ - lib/iirc/bot/print_io.rb
45
63
  - lib/iirc/bot/reading.rb
46
64
  - lib/iirc/bot/redis.rb
47
65
  - lib/iirc/bot/regex_hooks.rb