iirc 0.2.7 → 0.3.0

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: d5f568a48b28bcd4d10bdf613db4baa4451514e26d77acdbf18d9c988fd8792f
4
- data.tar.gz: 2f384b6fd3f8f7e3e43b8b714baad42de702733f0634736abc8a6ede67bb52d9
3
+ metadata.gz: 4c856c393db0b7645fa204d003750816cda3ce860b2be538e523f7d8bcf56b4e
4
+ data.tar.gz: 74252990a51523295d3dc788579b1f7ea456a995939e35d8c6004556742b7117
5
5
  SHA512:
6
- metadata.gz: a6b72bfb5048226f87c4d5c8e3d8471885fea226c970da825c66dd8189642a9908e39fabb050a3867c3ddf794eee25e713006333c875164f04707c3bb42459bf
7
- data.tar.gz: d0876472a0c3f099f0001555191456ee666033377a2180bcaafa74360b7c46f10277be431c4590b557b7a174f4ca409eea0be7b0ad5644bd8aee4203ee8eefc5
6
+ metadata.gz: 1c02d3b4eac6f4bebb0d2cb46e9241594021f07cb4fa2464508203bab3f1402f98901dd138efa1676d2de7fa678ac3117b08256ae819658c02819ff7dc2adeed
7
+ data.tar.gz: bb1fbf17c4f574f099a1b0c47d4e6aa087658c51137c8019facc151ccfd93591125c45b5bd327af6e75a85ae0d3f8ccea434da78b424c5f1c563c8f281413c2e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ## [0.3.0] - 2022-03-26
2
+
3
+ - [Bot] Include ReplyTarget
4
+ - [Hooks] Refactor
5
+ - Add AcceptInvites module
6
+ - Improve Greeter example
7
+
8
+ ## [0.2.9] - 2022-03-24
9
+
10
+ - Add reply target concept (Bot::ReplyTarget)
11
+ - The reply target of an event is the sender's nick when we are its target,
12
+ and equal to the regular target otherwise.
13
+ - The ambient verb methods now target the reply target of the ambient event by default.
14
+ - Should make writing actions more convenient.
15
+
16
+ ## [0.2.8] - 2022-03-22
17
+
18
+ - Add MIT license
19
+
1
20
  ## [0.2.7] - 2022-03-16
2
21
 
3
22
  - Include Bot::RegexHooks in Batteries
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2022 mooff <mooff@awful.cooking>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rake/testtask"
5
+ require "rdoc/task"
5
6
 
6
7
  Rake::TestTask.new(:test) do |t|
7
8
  t.libs << "test"
@@ -9,4 +10,9 @@ Rake::TestTask.new(:test) do |t|
9
10
  t.test_files = FileList["test/**/*_test.rb"]
10
11
  end
11
12
 
13
+ RDoc::Task.new do |rd|
14
+ rd.rdoc_files.include("lib/**/*.rb")
15
+ rd.options = ["--all"]
16
+ end
17
+
12
18
  task default: :test
data/examples/greeter.rb CHANGED
@@ -3,9 +3,10 @@ require "iirc"
3
3
  class Greeter < IIRC::Bot
4
4
  include AutoJoin
5
5
  include Verbs
6
+ include PrintIO
6
7
 
7
8
  def on_join(evt)
8
- say evt.target, "Hello #{evt.sender.nick}!"
9
+ say evt.target, "Hello #{evt.sender.nick}!" unless me === evt.sender
9
10
  end
10
11
 
11
12
  def autojoin_channels
data/iirc.gemspec CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.version = IIRC::VERSION
8
8
  spec.authors = ["mooff"]
9
9
  spec.email = ["mooff@awful.cooking"]
10
+ spec.license = "MIT"
10
11
 
11
12
  spec.summary = "Lean, mean IRC processing machine"
12
13
  spec.description = "A composable toolkit for IRC bots"
@@ -0,0 +1,22 @@
1
+ module IIRC
2
+ module Bot::AcceptInvites
3
+ # Override this to decide whether we should accept a given invite.
4
+ # By default, all invites are accepted.
5
+ # @param [Event]
6
+ # @return [true] if we should join the channel
7
+ def accept_invite?(evt)
8
+ true
9
+ end
10
+
11
+ private
12
+ def configure_accept_invites
13
+ on :invite, :accept_invites
14
+ end
15
+
16
+ def accept_invites(evt)
17
+ if me === evt.target and accept_invite?(evt)
18
+ join evt.args[1]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,3 +1,5 @@
1
+ require_relative "reply_target"
2
+
1
3
  module IIRC
2
4
  module Bot::AmbientEvents
3
5
  private
@@ -27,18 +29,6 @@ module IIRC
27
29
  end
28
30
  end
29
31
 
30
- module Bot::AmbientVerbs
31
- include Bot::AmbientEvents
32
-
33
- def join(channel=ambient_target) super end
34
- def part(channel=ambient_target, reason='') super end
35
- def msg(channel=ambient_target, msg) super end
36
- def act(channel=ambient_target, msg) super end
37
- def cycle(channel=ambient_target, reason='') super end
38
- def mode(channel=ambient_target, mode) super end
39
- alias :say :msg
40
- end
41
-
42
32
  module Bot::AmbientEvents::LabeledRequests
43
33
  def labeled_request(*)
44
34
  initial_evt = ambient_event
@@ -47,4 +37,24 @@ module IIRC
47
37
  end
48
38
  end
49
39
  end
40
+
41
+ module Bot::AmbientEvents::ReplyTarget
42
+ include Bot::ReplyTarget
43
+ def ambient_reply_target
44
+ reply_target(ambient_event)
45
+ end
46
+ end
47
+
48
+ module Bot::AmbientVerbs
49
+ include Bot::AmbientEvents
50
+ include Bot::AmbientEvents::ReplyTarget
51
+
52
+ def join(channel=ambient_reply_target) super end
53
+ def part(channel=ambient_reply_target, reason='') super end
54
+ def msg(channel=ambient_reply_target, msg) super end
55
+ def act(channel=ambient_reply_target, msg) super end
56
+ def cycle(channel=ambient_reply_target, reason='') super end
57
+ def mode(channel=ambient_reply_target, mode) super end
58
+ alias :say :msg
59
+ end
50
60
  end
@@ -4,6 +4,18 @@ module IIRC
4
4
  @hooks ||= Hash.new { |h,v| h[v] = Set.new }
5
5
  end
6
6
 
7
+ def run
8
+ lines { |line|
9
+ begin
10
+ evt = parse(line)
11
+ fire! evt.verb, evt
12
+ rescue Exception => ex
13
+ puts ex.message
14
+ puts ex.backtrace
15
+ end
16
+ }
17
+ end
18
+
7
19
  def on verb=nil, action=nil, &blk
8
20
  if action and blk
9
21
  define_singleton_method(action, blk)
@@ -17,10 +29,6 @@ module IIRC
17
29
  end
18
30
  end
19
31
 
20
- def hook action=nil, &blk
21
- on nil, action, &blk
22
- end
23
-
24
32
  def off verb, action=nil, &blk
25
33
  action ||= blk
26
34
  if action
@@ -30,14 +38,12 @@ module IIRC
30
38
  end
31
39
  end
32
40
 
41
+ def hook action=nil, &blk
42
+ on nil, action, &blk
43
+ end
44
+
33
45
  def fire! verb, *args, **kwargs
34
- for action in hooks[nil]
35
- call action, *args, **kwargs
36
- end
37
- if respond_to? :"on_#{verb}"
38
- send(:"on_#{verb}", *args, **kwargs)
39
- end
40
- for action in hooks[verb]
46
+ for action in hook_seq(verb)
41
47
  call action, *args, **kwargs
42
48
  end
43
49
  rescue StopIteration
@@ -54,16 +60,9 @@ module IIRC
54
60
  end
55
61
  end
56
62
 
57
- def run
58
- lines { |line|
59
- begin
60
- evt = parse(line)
61
- fire! evt.verb, evt
62
- rescue Exception => ex
63
- puts ex.message
64
- puts ex.backtrace
65
- end
66
- }
67
- end
63
+ protected
64
+ def hook_seq(verb)
65
+ [*hooks[nil], (:"on_#{verb}" if respond_to?(:"on_#{verb}")), *hooks[verb]].compact
66
+ end
68
67
  end
69
- end
68
+ end
@@ -4,7 +4,7 @@ module IIRC
4
4
  autoload :IRCParser, 'ircparser'
5
5
 
6
6
  def parse(line)
7
- msg = IRCParser::Message.parse(line.chomp)
7
+ msg = IRCParser::Message.parse(line.tr("\r", '').chomp)
8
8
 
9
9
  Event.new.tap { |evt|
10
10
  evt.sender = IRCParser::RFCWireFormat.__stringify_prefix(msg.prefix) if msg.prefix
@@ -0,0 +1,14 @@
1
+ module IIRC
2
+ module Bot::ReplyTarget
3
+ # The +reply_target+ of an event is the sender's nickname when _we_ are the
4
+ # +target+. Otherwise, it returns the regular +target+.
5
+ #
6
+ # It lets us reply to events without having to repeat the `(me ===
7
+ # target) ? sender.nick : target` logic used to make sure we don't message
8
+ # ourselves when we receive a direct PRIVMSG, NOTICE, etc.
9
+
10
+ def reply_target(evt)
11
+ (me === evt.target) ? evt.sender.nick : evt.target
12
+ end
13
+ end
14
+ end
data/lib/iirc/event.rb CHANGED
@@ -10,8 +10,7 @@ module IIRC
10
10
  end
11
11
 
12
12
  def sender=(v)
13
- v.extend Sender if v
14
- @sender = v
13
+ @sender = IIRC::Sender(v)
15
14
  end
16
15
 
17
16
  def args=(v)
data/lib/iirc/sender.rb CHANGED
@@ -1,7 +1,26 @@
1
1
  module IIRC
2
+ # A mixin which adds IRC hostmask introspection methods to strings.
3
+ #
4
+ # *CoolNick*, *:NickName*, <b>:nick!user@host</b>, *:server.name*, *another.server.name* forms are supported.
5
+ #
6
+ # A leading colon may be present in the string, and will be ignored.
7
+ #
8
+ # @example nick!user@example.com
9
+ # sender = "nick!user@example.com".extend(IIRC::Sender)
10
+ # sender.user? # => true
11
+ # sender.host # => "example.com"
12
+ # @example :irc.server
13
+ # sender = ":irc.server".extend(IIRC::Sender)
14
+ # sender.server? # => true
15
+ # sender.host # => "irc.server"
16
+ # @example JimBob
17
+ # sender = "JimBob".extend(IIRC::Sender)
18
+ # sender.user? # => true
19
+ # sender.nick # => "JimBob"
20
+
2
21
  module Sender
3
22
  def user
4
- @user ||= User.from_sender(self)
23
+ @user ||= User.from_source(self)
5
24
  end
6
25
 
7
26
  def server?
@@ -14,16 +33,37 @@ module IIRC
14
33
 
15
34
  def nick; user&.nick end
16
35
  def username; user&.username end
17
- def host; user&.host end
36
+ def host; server? ? without_leading_colon : user.host end
18
37
 
19
38
  def to_prefix
20
39
  ":#{self}"
21
40
  end
22
41
 
23
- def to_s
42
+ def without_leading_colon
24
43
  delete_prefix(':')
25
44
  end
26
45
 
46
+ alias :to_s :without_leading_colon
27
47
  alias :inspect :to_prefix
28
48
  end
49
+
50
+ module_function
51
+ # Extends and returns a source string with the IIRC::Sender mixin.
52
+ # Duplicates first if the string is frozen. Returns nil if source is nil.
53
+ #
54
+ # @example :nick!user@host
55
+ # v = IIRC.Sender(":JimmyWales!jim@wikipedia.org") # => "JimmyWales!jim@wikipedia.org"
56
+ # v.nick # => "JimmyWales"
57
+ # v.host # => "wikipedia.org"
58
+ # v.user? # => true
59
+ # @example server.name
60
+ # IIRC.Sender("services.libera.chat").server? # => true
61
+
62
+ def Sender(source)
63
+ if source.nil?
64
+ nil
65
+ else
66
+ (source.frozen? ? source.dup : source).extend(Sender)
67
+ end
68
+ end
29
69
  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.7"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/iirc.rb CHANGED
@@ -5,6 +5,7 @@ require_relative "iirc/sender"
5
5
  require_relative "iirc/user"
6
6
 
7
7
  require_relative "iirc/bot"
8
+ require_relative "iirc/bot/accept_invites"
8
9
  require_relative "iirc/bot/ambient"
9
10
  require_relative "iirc/bot/autojoin"
10
11
  require_relative "iirc/bot/channels"
@@ -19,6 +20,7 @@ require_relative "iirc/bot/print_io"
19
20
  require_relative "iirc/bot/reading"
20
21
  require_relative "iirc/bot/redis"
21
22
  require_relative "iirc/bot/regex_hooks"
23
+ require_relative "iirc/bot/reply_target"
22
24
  require_relative "iirc/bot/track_own_nick"
23
25
  require_relative "iirc/bot/verbs"
24
26
 
@@ -37,9 +39,12 @@ module IIRC
37
39
  include Configure
38
40
  include Pong
39
41
  include TrackOwnNick
42
+ include ReplyTarget
40
43
 
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)
44
+ def self.run(host, port=6697, local_host: nil, local_port: nil, ssl_context: SSL.default_context, **user_params, &blk)
45
+ socket = IIRC.dial(host, port,
46
+ local_host: local_host, local_port: local_port,
47
+ ssl_context: ssl_context)
43
48
 
44
49
  new(socket, **user_params).tap { |bot|
45
50
  bot.register!
@@ -99,10 +104,10 @@ module IIRC
99
104
  end
100
105
 
101
106
  module_function
102
- def dial(host, port=6697, ssl_context: SSL.default_context)
107
+ def dial(host, port=6697, local_host: nil, local_port: nil, ssl_context: SSL.default_context)
103
108
  require 'socket'
104
109
 
105
- Socket.tcp(host, port).then { |socket|
110
+ Socket.tcp(host, port, local_host, local_port).then { |socket|
106
111
  if ssl_context
107
112
  OpenSSL::SSL::SSLSocket.new(socket, ssl_context).tap { |socket|
108
113
  socket.hostname = host
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iirc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.0
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-16 00:00:00.000000000 Z
11
+ date: 2022-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ircparser
@@ -35,6 +35,7 @@ files:
35
35
  - ".gitignore"
36
36
  - CHANGELOG.md
37
37
  - Gemfile
38
+ - LICENSE
38
39
  - README.md
39
40
  - Rakefile
40
41
  - bin/console
@@ -45,6 +46,7 @@ files:
45
46
  - iirc.gemspec
46
47
  - lib/iirc.rb
47
48
  - lib/iirc/bot.rb
49
+ - lib/iirc/bot/accept_invites.rb
48
50
  - lib/iirc/bot/ambient.rb
49
51
  - lib/iirc/bot/autojoin.rb
50
52
  - lib/iirc/bot/channels.rb
@@ -63,6 +65,7 @@ files:
63
65
  - lib/iirc/bot/reading.rb
64
66
  - lib/iirc/bot/redis.rb
65
67
  - lib/iirc/bot/regex_hooks.rb
68
+ - lib/iirc/bot/reply_target.rb
66
69
  - lib/iirc/bot/track_own_nick.rb
67
70
  - lib/iirc/bot/verbs.rb
68
71
  - lib/iirc/event.rb
@@ -70,7 +73,8 @@ files:
70
73
  - lib/iirc/user.rb
71
74
  - lib/iirc/version.rb
72
75
  homepage: https://github.com/awfulcooking/iirc
73
- licenses: []
76
+ licenses:
77
+ - MIT
74
78
  metadata:
75
79
  homepage_uri: https://github.com/awfulcooking/iirc
76
80
  source_code_uri: https://github.com/awfulcooking/iirc