mod_spox 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. data/CHANGELOG +31 -1
  2. data/LICENSE +674 -0
  3. data/README.rdoc +73 -0
  4. data/bin/mod_spox +28 -28
  5. data/data/mod_spox/extras/AOLSpeak.rb +2 -3
  6. data/data/mod_spox/extras/AutoKick.rb +10 -23
  7. data/data/mod_spox/extras/AutoMode.rb +12 -23
  8. data/data/mod_spox/extras/Bash.rb +55 -0
  9. data/data/mod_spox/extras/Bouncer.rb +85 -57
  10. data/data/mod_spox/extras/Bullshit.rb +1 -1
  11. data/data/mod_spox/extras/Bytes.rb +1 -2
  12. data/data/mod_spox/extras/Confess.rb +27 -29
  13. data/data/mod_spox/extras/DCC.rb +11 -20
  14. data/data/mod_spox/extras/DevWatch.rb +21 -23
  15. data/data/mod_spox/extras/DownForEveryoneOrJustMe.rb +47 -0
  16. data/data/mod_spox/extras/EightBall.rb +1 -1
  17. data/data/mod_spox/extras/FML.rb +35 -0
  18. data/data/mod_spox/extras/Headers.rb +31 -50
  19. data/data/mod_spox/extras/Karma.rb +81 -29
  20. data/data/mod_spox/extras/Logger.rb +2 -2
  21. data/data/mod_spox/extras/LolSpeak.rb +1 -2
  22. data/data/mod_spox/extras/PhpCli.rb +138 -8
  23. data/data/mod_spox/extras/PhpFuncLookup.rb +20 -23
  24. data/data/mod_spox/extras/Pinger.rb +1 -1
  25. data/data/mod_spox/extras/Quotes.rb +8 -10
  26. data/data/mod_spox/extras/RegexTracker.rb +2 -4
  27. data/data/mod_spox/extras/Roulette.rb +20 -27
  28. data/data/mod_spox/extras/RubyCli.rb +93 -0
  29. data/data/mod_spox/extras/Search.rb +17 -3
  30. data/data/mod_spox/extras/Seen.rb +150 -0
  31. data/data/mod_spox/extras/SlashdotHeadlineGenerator.rb +500 -0
  32. data/data/mod_spox/extras/Talk.rb +2 -4
  33. data/data/mod_spox/extras/Topten.rb +10 -12
  34. data/data/mod_spox/extras/TracTicket.rb +3 -5
  35. data/data/mod_spox/extras/Translate.rb +20 -22
  36. data/data/mod_spox/extras/Twitter.rb +118 -33
  37. data/data/mod_spox/extras/UrbanDictionary.rb +8 -17
  38. data/data/mod_spox/extras/Weather.rb +1 -2
  39. data/data/mod_spox/plugins/Authenticator.rb +93 -98
  40. data/data/mod_spox/plugins/Banner.rb +26 -56
  41. data/data/mod_spox/plugins/Helper.rb +5 -6
  42. data/data/mod_spox/plugins/Initializer.rb +4 -14
  43. data/data/mod_spox/plugins/Joiner.rb +1 -1
  44. data/data/mod_spox/plugins/Nicker.rb +13 -0
  45. data/data/mod_spox/plugins/Parter.rb +2 -2
  46. data/data/mod_spox/plugins/Permissions.rb +60 -0
  47. data/data/mod_spox/plugins/PluginLoader.rb +7 -12
  48. data/data/mod_spox/plugins/Ponger.rb +51 -0
  49. data/data/mod_spox/plugins/Quitter.rb +1 -2
  50. data/data/mod_spox/plugins/Servers.rb +57 -0
  51. data/data/mod_spox/plugins/Status.rb +3 -2
  52. data/data/mod_spox/plugins/Triggers.rb +9 -9
  53. data/lib/mod_spox/Bot.rb +109 -33
  54. data/lib/mod_spox/BotConfig.rb +2 -2
  55. data/lib/mod_spox/ConfigurationWizard.rb +12 -12
  56. data/lib/mod_spox/Database.rb +1 -4
  57. data/lib/mod_spox/Exceptions.rb +26 -0
  58. data/lib/mod_spox/Helpers.rb +29 -68
  59. data/lib/mod_spox/Loader.rb +23 -24
  60. data/lib/mod_spox/Logger.rb +19 -17
  61. data/lib/mod_spox/MessageFactory.rb +50 -24
  62. data/lib/mod_spox/Pipeline.rb +21 -7
  63. data/lib/mod_spox/Plugin.rb +27 -3
  64. data/lib/mod_spox/PluginManager.rb +28 -15
  65. data/lib/mod_spox/PriorityQueue.rb +69 -0
  66. data/lib/mod_spox/Socket.rb +93 -51
  67. data/lib/mod_spox/Sockets.rb +76 -63
  68. data/lib/mod_spox/Timer.rb +21 -141
  69. data/lib/mod_spox/Version.rb +14 -0
  70. data/lib/mod_spox/handlers/BadNick.rb +1 -1
  71. data/lib/mod_spox/handlers/Bounce.rb +5 -5
  72. data/lib/mod_spox/handlers/Created.rb +13 -5
  73. data/lib/mod_spox/handlers/Handler.rb +12 -3
  74. data/lib/mod_spox/handlers/Invite.rb +14 -8
  75. data/lib/mod_spox/handlers/Join.rb +24 -20
  76. data/lib/mod_spox/handlers/Kick.rb +22 -13
  77. data/lib/mod_spox/handlers/Mode.rb +42 -36
  78. data/lib/mod_spox/handlers/Motd.rb +4 -0
  79. data/lib/mod_spox/handlers/Names.rb +66 -39
  80. data/lib/mod_spox/handlers/Nick.rb +20 -14
  81. data/lib/mod_spox/handlers/Part.rb +25 -8
  82. data/lib/mod_spox/handlers/Ping.rb +11 -5
  83. data/lib/mod_spox/handlers/Pong.rb +9 -5
  84. data/lib/mod_spox/handlers/Privmsg.rb +25 -17
  85. data/lib/mod_spox/handlers/Quit.rb +13 -8
  86. data/lib/mod_spox/handlers/Topic.rb +4 -0
  87. data/lib/mod_spox/handlers/Welcome.rb +16 -24
  88. data/lib/mod_spox/handlers/Who.rb +64 -48
  89. data/lib/mod_spox/handlers/Whois.rb +92 -60
  90. data/lib/mod_spox/messages/incoming/Nick.rb +2 -2
  91. data/lib/mod_spox/messages/incoming/Privmsg.rb +1 -1
  92. data/lib/mod_spox/messages/incoming/Whois.rb +1 -0
  93. data/lib/mod_spox/messages/internal/EstablishConnection.rb +1 -1
  94. data/lib/mod_spox/messages/internal/PluginsReady.rb +10 -0
  95. data/lib/mod_spox/messages/internal/QueueSocket.rb +8 -0
  96. data/lib/mod_spox/messages/internal/Reconnect.rb +8 -0
  97. data/lib/mod_spox/messages/internal/UnqueueSocket.rb +8 -0
  98. data/lib/mod_spox/migrations/002_persistent_sigs.rb +14 -0
  99. data/lib/mod_spox/migrations/003_auth_restructure.rb +31 -0
  100. data/lib/mod_spox/migrations/004_mode_index_fix.rb +18 -0
  101. data/lib/mod_spox/migrations/005_nick_mode_nopark.rb +18 -0
  102. data/lib/mod_spox/models/Auth.rb +16 -46
  103. data/lib/mod_spox/models/AuthMask.rb +13 -0
  104. data/lib/mod_spox/models/Channel.rb +46 -27
  105. data/lib/mod_spox/models/Config.rb +10 -19
  106. data/lib/mod_spox/models/Group.rb +20 -8
  107. data/lib/mod_spox/models/Models.rb +1 -1
  108. data/lib/mod_spox/models/Nick.rb +105 -113
  109. data/lib/mod_spox/models/NickMode.rb +23 -9
  110. data/lib/mod_spox/models/Server.rb +12 -1
  111. data/lib/mod_spox/models/Setting.rb +12 -16
  112. data/lib/mod_spox/models/Signature.rb +28 -8
  113. data/tests/BotHolder.rb +24 -0
  114. data/tests/handlers/tc_BadNick.rb +21 -0
  115. data/tests/handlers/tc_Created.rb +24 -0
  116. data/tests/handlers/tc_Invite.rb +50 -0
  117. data/tests/handlers/tc_Join.rb +33 -0
  118. data/tests/handlers/tc_Kick.rb +32 -0
  119. data/tests/handlers/tc_Mode.rb +85 -0
  120. data/tests/handlers/tc_Names.rb +35 -0
  121. data/tests/handlers/tc_Nick.rb +55 -0
  122. data/tests/handlers/tc_Part.rb +44 -0
  123. data/tests/handlers/tc_Ping.rb +40 -0
  124. data/tests/handlers/tc_Pong.rb +28 -0
  125. data/tests/handlers/tc_Privmsg.rb +85 -0
  126. data/tests/handlers/tc_Quit.rb +40 -0
  127. data/tests/handlers/tc_Who.rb +50 -0
  128. data/tests/handlers/tc_Whois.rb +61 -0
  129. data/tests/models/tc_Auth.rb +34 -0
  130. data/tests/models/tc_Channel.rb +52 -0
  131. data/tests/models/tc_Config.rb +19 -0
  132. data/tests/models/tc_Nick.rb +142 -0
  133. data/tests/models/tc_NickMode.rb +40 -0
  134. data/tests/models/tc_Setting.rb +21 -0
  135. data/tests/models/tc_Signature.rb +14 -0
  136. data/tests/run_tests.rb +4 -0
  137. metadata +284 -212
  138. data/README +0 -36
  139. data/lib/mod_spox/Cache.rb +0 -57
  140. data/lib/mod_spox/Monitors.rb +0 -84
  141. data/lib/mod_spox/Pool.rb +0 -164
  142. data/lib/mod_spox/models/AuthGroup.rb +0 -16
  143. data/lib/mod_spox/models/ChannelMode.rb +0 -14
  144. data/lib/mod_spox/models/NickChannel.rb +0 -45
  145. data/lib/mod_spox/models/NickGroup.rb +0 -16
@@ -0,0 +1,73 @@
1
+ == mod_spox IRC bot
2
+
3
+ mod_spox is an IRC robot, written in Ruby, and will completely change your prospective on life. mod_spox is proof that doing nothing is complex, and that doing nothing can, in fact, be doing something.
4
+
5
+ The core of mod_spox is basically a framework for interacting with IRC. By itself, the bot does nothing of value, aside from sucking up bandwidth and resources from the server it is connected to. The core bot can connect to a server, format information from the server, and send information back to the server properly. That's pretty much it.
6
+
7
+ The framework provided by mod_spox allows it to quickly transform from a useless bag of bytes to something entertaining, annoying, helpful, and aggravating, occasionally all at the same time. This transformation is accomplished through the use of plugins which use the framework to accomplish feats of greatness.
8
+
9
+ == Critical informations
10
+
11
+ * Author: spox <spox@rubyforge.org>
12
+ * {Dev Site}[http://dev.modspox.com]
13
+ * {Rubyforge}[http://rubyforge.org/projects/modspox]
14
+ * {GitHub}[http://github.com/spox/mod_spox/tree/master]
15
+
16
+ == Aquiring
17
+
18
+ * Gem: gem install mod_spox
19
+
20
+ == Aquiring current unstable
21
+
22
+ Gem:
23
+ gem sources -a http://gems.github.com
24
+ gem install spox-mod_spox
25
+
26
+ Source:
27
+ git clone git://github.com/spox/mod_spox.git
28
+ cd mod_spox/
29
+ gem build *.gemspec
30
+ gem install ./
31
+
32
+ == Requirements
33
+
34
+ * {Sequel}[http://sequel.rubyforge.org]
35
+ * {ActionTimer}[http://dev.modspox.com/~sine/ActionTimer]
36
+ * {ActionPool}[http://dev.modspox.com/~sine/ActionPool]
37
+ * {spockets}[http://dev.modspox.com/~sine/spockets]
38
+ * Database adapter of choice compatible with sequel
39
+
40
+ == Configuration
41
+
42
+ mod_spox --config
43
+
44
+ == Running
45
+
46
+ === Plain
47
+
48
+ mod_spox
49
+
50
+ === Debug to STDOUT
51
+
52
+ mod_spox -V info -d
53
+
54
+ === Daemonize with debug to file
55
+
56
+ mod_spox -V info -d /home/user/logfiles/mod_spox.log -D
57
+
58
+ == Extending
59
+
60
+ {Plugins HOWTO}[http://dev.modspox.com/trac/mod_spox/wiki/PluginHowto]
61
+
62
+ == Helping
63
+
64
+ Helpful things if you are feeling helpful:
65
+
66
+ * Report bugs
67
+ * Write unit tests
68
+ * New and/or useful plugins
69
+
70
+ == License
71
+
72
+ mod_spox is licensed under the GPLv3
73
+ Copyright (c) 2009 spox <spox@modspox.com>
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
-
2
+ # encoding: utf-8
3
3
  ## include our needed libraries ##
4
4
 
5
5
  ['rubygems', 'sequel', 'thread', 'etc', 'getoptlong', 'logger'].each do |file|
@@ -18,16 +18,14 @@ rescue Object => boom
18
18
  # ignore if not found #
19
19
  end
20
20
 
21
- $BOTVERSION='0.2.0'
22
- $BOTCODENAME='avocado'
23
- $VERBOSITY = 0
24
- $MOD_SPOX_PATH = nil
25
- $DAEMON_BOT = false
26
- $LOGTO = $stdout
27
- $LOGLEVEL = :fatal
28
- $JDBC = false
21
+ require 'mod_spox/Version'
29
22
 
23
+ # lets get sequel setup like we want it #
24
+ require 'sequel/extensions/migration'
25
+ Sequel::Model.plugin :validation_helpers
26
+ Sequel::Model.plugin :schema
30
27
  Sequel::Model.unrestrict_primary_key
28
+ # okay, lets go #
31
29
 
32
30
  begin
33
31
  require 'mod_spox/Loader'
@@ -66,7 +64,7 @@ opts.each do |opt, arg|
66
64
  puts 'http://rubyforge.org/projects/modspox'
67
65
  exit
68
66
  when '--jdbc'
69
- $JDBC = true
67
+ ModSpox.jdbc = true
70
68
  begin
71
69
  require 'jdbc/postgres'
72
70
  rescue Object => boom
@@ -74,10 +72,10 @@ opts.each do |opt, arg|
74
72
  exit 1
75
73
  end
76
74
  when '--debug'
77
- if(arg && File.writable?(arg))
78
- $LOGTO = arg
75
+ if(arg && arg.gsub(' ', '').size > 0)
76
+ ModSpox.logto = arg
79
77
  else
80
- $LOGTO = $stdout
78
+ ModSpox.logto = $stdout
81
79
  end
82
80
  when '--config'
83
81
  require 'mod_spox/ConfigurationWizard'
@@ -85,28 +83,30 @@ opts.each do |opt, arg|
85
83
  BotConfig.configured? ? wizard.update : wizard.run
86
84
  exit
87
85
  when '--path'
88
- $MOD_SPOX_PATH = arg
86
+ ModSpox.mod_spox_path = arg
89
87
  when '--daemon'
90
- begin
91
- $DAEMON_BOT = true
92
- require 'daemons'
93
- rescue Object => boom
94
- puts 'Error: You must install the Daemons gem: (http://daemons.rubyforge.org)'
95
- exit 1
96
- end
88
+ ModSpox.daemon_bot = true
97
89
  when '--verbosity'
98
- if(arg && arg =~ /^(info|warn|fatal)$/)
99
- $LOGLEVEL = arg.to_sym
90
+ if(arg && arg =~ /^(info|warn|error|fatal)$/)
91
+ ModSpox.loglevel = arg.to_sym
100
92
  end
101
93
  end
102
94
  end
103
95
 
104
- initialize_bot
96
+ ModSpox.initialize_bot
105
97
  require 'mod_spox/Bot'
106
-
107
- if($DAEMON_BOT)
108
- Daemonize.daemonize(nil, 'mod_spox')
98
+ if(ModSpox.daemon_bot)
99
+ if(RUBY_VERSION > '1.9.0')
100
+ Process.daemon if ModSpox.daemon_bot
101
+ else
102
+ begin
103
+ require 'daemons'
104
+ Daemons.daemonize
105
+ rescue Object
106
+ puts "ERROR: Failed to load daemons gem"
107
+ exit 1
108
+ end
109
+ end
109
110
  end
110
-
111
111
  bot = Bot.new
112
112
  bot.run
@@ -5,9 +5,8 @@ class AOLSpeak < ModSpox::Plugin
5
5
  def initialize(pipeline)
6
6
  super
7
7
  group = Group.find_or_create(:name => 'banner')
8
- Signature.find_or_create(:signature => 'aolspeak', :plugin => name, :method => 'aolspeak', :description => 'AOL speak')
9
- Signature.find_or_create(:signature => 'aolkick (\S+) ?(\S+)?', :plugin => name, :method => 'aolkick', :description => 'AOL speak kick',
10
- :group_id => group.pk).params = [:nick, :channel]
8
+ add_sig(:sig => 'aolspeak', :method => :aolspeak, :desc => 'AOL speak')
9
+ add_sig(:sig => 'aolkick (\S+) ?(\S+)?', :method => :aolkick, :desc => 'AOL speak kick', :group => group, :params => [:nick, :channel])
11
10
  build_aolspeak
12
11
  end
13
12
 
@@ -5,19 +5,13 @@ class AutoKick < ModSpox::Plugin
5
5
  def initialize(pipeline)
6
6
  super
7
7
  group = Group.find_or_create(:name => 'autokick')
8
- Signature.find_or_create(:signature => 'autokick list', :plugin => name, :method => 'list', :group_id => group.pk,
9
- :description => 'List active autokick rules')
10
- Signature.find_or_create(:signature => 'autokick add (#\S+) (\d+) (\S+) (.+)', :plugin => name, :method => 'add',
11
- :group_id => group.pk, :description => 'Add new autokick rule for current channel',
12
- :requirement => 'public').params = [:channel, :time, :regex, :message]
13
- Signature.find_or_create(:signature => 'autokick add (\d+) (\S+) (.+)', :plugin => name, :method => 'add',
14
- :group_id => group.pk, :description => 'Add a new autokick rule').params = [:time, :regex, :message]
15
- Signature.find_or_create(:signature => 'autokick remove (\d+)', :plugin => name, :method => 'remove',
16
- :group_id => group.pk, :description => 'Remove an autokick rule').params = [:id]
17
- Signature.find_or_create(:signature => 'autokick colors ?(on|off)?', :plugin => name, :method => 'colors',
18
- :group_id => group.pk, :description => 'Kick user for using colors', :requirement => 'public').params = [:action]
8
+ add_sig(:sig => 'autokick list', :method => :list, :group => group, :desc => 'List active autokick rules')
9
+ add_sig(:sig => 'autokick add (#\S+) (\d+) (\S+) (.+)', :method => :add, :group => group, :desc => 'Add new autokick rule for current channel', :req => 'public', :params => [:channel, :time, :regex, :message])
10
+ add_sig(:sig => 'autokick add (\d+) (\S+) (.+)', :method => :add, :group => group, :desc => 'Add a new autokick rule', :params => [:time, :regex, :message])
11
+ add_sig(:sig => 'autokick remove (\d+)', :method => :remove, :group => group, :desc => 'Remove an autokick rule', :params => [:id])
12
+ add_sig(:sig => 'autokick colors ?(on|off)?', :method => :colors, :group => group, :desc => 'Kick user for using colors', :req => 'public', :params => [:action])
19
13
  @map = nil
20
- @colors = Setting[:colorkick]
14
+ @colors = Setting.val(:colorkick)
21
15
  @colors = Array.new unless @colors.is_a?(Array)
22
16
  AutoKickRecord.create_table unless AutoKickRecord.table_exists?
23
17
  do_listen
@@ -138,9 +132,7 @@ class AutoKick < ModSpox::Plugin
138
132
  foreign_key :channel_id, :table => :channels
139
133
  end
140
134
 
141
- def channel
142
- ModSpox::Models::Channel[channel_id]
143
- end
135
+ many_to_one :channel, :class => ModSpox::Models::Channel
144
136
  end
145
137
 
146
138
  class AutoKickPersonal < Sequel::Model
@@ -152,14 +144,9 @@ class AutoKick < ModSpox::Plugin
152
144
  foreign_key :nick_id, :table => :nicks
153
145
  foreign_key :channel_id, :table => :channels
154
146
  end
155
-
156
- def nick
157
- ModSpox::Models::Nick[nick_id]
158
- end
159
-
160
- def channel
161
- ModSpox::Models::Channel[channel_id]
162
- end
147
+
148
+ many_to_one :nick, :class => ModSpox::Models::Nick
149
+ many_to_one :channel, :class => ModSpox::Models::Channel
163
150
  end
164
151
 
165
152
  end
@@ -6,18 +6,12 @@ class AutoMode < ModSpox::Plugin
6
6
  super
7
7
  @admin = Group.find_or_create(:name => 'moder')
8
8
  @user = Group.find_or_create(:name => 'modee')
9
- Signature.find_or_create(:signature => 'addop (\S+)', :plugin => name, :method => 'addop', :group_id => @admin.pk,
10
- :description => 'Add a nick to the auto op list', :requirement => 'public').params = [:nick]
11
- Signature.find_or_create(:signature => 'addvoice (\S+)', :plugin => name, :method => 'addvoice', :group_id => @admin.pk,
12
- :description => 'Add a nick to the auto voice list', :requirement => 'public').params = [:nick]
13
- Signature.find_or_create(:signature => 'op', :plugin => name, :method => 'op', :group_id => @user.pk,
14
- :description => 'Instruct bot to give you operator status', :requirement => 'public')
15
- Signature.find_or_create(:signature => 'voice', :plugin => name, :method => 'voice', :group_id => @user.pk,
16
- :description => 'Instruct bot to give you voice status', :requirement => 'public')
17
- Signature.find_or_create(:signature => 'automode list (\S+)', :plugin => name, :method => 'list', :group_id => @admin.pk,
18
- :description => 'Show list of current auto-modes for channel').params = [:channel]
19
- Signature.find_or_create(:signature => 'delmode (\S+)', :plugin => name, :method => 'remove', :group_id => @admin.pk,
20
- :description => 'Remove nick from any auto-modes in channel', :requirement => 'public').params = [:nick]
9
+ add_sig(:sig => 'addop (\S+)', :method => :addop, :group => @admin, :desc => 'Add a nick to the auto op list', :req => 'public', :params => [:nick])
10
+ add_sig(:sig => 'addvoice (\S+)', :method => :addvoice, :group => @admin, :desc => 'Add a nick to the auto voice list', :req => 'public', :params => [:nick])
11
+ add_sig(:sig => 'op', :method => :op, :group => @user, :desc => 'Instruct bot to give you operator status', :req => 'public')
12
+ add_sig(:sig => 'voice', :method => :voice, :group => @user, :desc => 'Instruct bot to give you voice status', :req => 'public')
13
+ add_sig(:sig => 'automode list (\S+)', :method => :list, :group => @admin, :desc => 'Show list of current auto-modes for channel', :params => [:channel])
14
+ add_sig(:sig => 'delmode (\S+)', :method => :remove, :group => @admin, :desc => 'Remove nick from any auto-modes in channel', :req => 'public', :params => [:nick])
21
15
  ModeRecord.create_table unless ModeRecord.table_exists?
22
16
  @pipeline.hook(self, :check_join, :Incoming_Join)
23
17
  end
@@ -63,7 +57,7 @@ class AutoMode < ModSpox::Plugin
63
57
  channel = Helpers.find_model(p[:channel], false)
64
58
  if(channel.is_a?(Channel))
65
59
  records = ModeRecord.filter(:channel_id => channel.pk)
66
- if(records.size > 0)
60
+ if(records.count > 0)
67
61
  reply m.replyto, "\2Auto-Mode Listing:\2"
68
62
  sleep(0.01)
69
63
  records.each do |record|
@@ -91,7 +85,7 @@ class AutoMode < ModSpox::Plugin
91
85
  def check_join(m)
92
86
  return unless me.is_op?(m.channel)
93
87
  matches = ModeRecord.filter(:nick_id => m.nick.pk, :channel_id => m.channel.pk)
94
- if(matches.size > 0)
88
+ if(matches.count > 0)
95
89
  matches.each do |record|
96
90
  mode = record.voice ? '+v' : '+o'
97
91
  @pipeline << Messages::Outgoing::ChannelMode.new(m.channel, mode, m.nick.nick)
@@ -106,7 +100,7 @@ class AutoMode < ModSpox::Plugin
106
100
 
107
101
  def remove_modee(nick)
108
102
  modee = Group.find_or_create(:name => 'modee')
109
- if(ModeRecord.filter(:nick_id => nick.pk).size < 1)
103
+ if(ModeRecord.filter(:nick_id => nick.pk).count < 1)
110
104
  nick.remove_group(modee)
111
105
  end
112
106
  end
@@ -119,14 +113,9 @@ class AutoMode < ModSpox::Plugin
119
113
  foreign_key :channel_id, :table => :channels, :null => false
120
114
  index [:nick_id, :channel_id, :voice], :unique => true
121
115
  end
122
-
123
- def channel
124
- ModSpox::Models::Channel[channel_id]
125
- end
126
-
127
- def nick
128
- ModSpox::Models::Nick[nick_id]
129
- end
116
+
117
+ many_to_one :channel, :class => ModSpox::Models::Channel
118
+ many_to_one :nick, :class => ModSpox::Models::Nick
130
119
  end
131
120
 
132
121
  end
@@ -0,0 +1,55 @@
1
+ # ex: set ts=4 et:
2
+ require "net/http"
3
+ require "cgi"
4
+
5
+ # bash.org quote plugin
6
+ # by pizza
7
+
8
+ class Bash < ModSpox::Plugin
9
+
10
+ def initialize(pipeline)
11
+ super
12
+ add_sig(:sig => 'bash( (top|latest|#\d+))?', :method => :random, :desc => 'Bash quote fetcher', :params => [:wspace, :cmd])
13
+ @site = 'http://bash.org/'
14
+ end
15
+
16
+ def random(m, params)
17
+ begin
18
+ u = @site + '?top'
19
+ if 'latest' == params[:cmd]
20
+ u = @site + '?latest'
21
+ elsif /^#(\d+)$/.match(params[:cmd])
22
+ u = @site + '?' + $1
23
+ end
24
+ reply m.replyto, get_text(u)
25
+ rescue Object => boom
26
+ error m.replyto, "Failed to fetch. #{boom}"
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def get_text(url)
33
+ begin
34
+ data = Net::HTTP.get_response(URI.parse(url)).body
35
+ # parse individual entries, they have a "qt" section within "quote"
36
+ m = data.scan(/<p class="qt">(.*?)<\/p>/m)
37
+ raise 'No quotes found' unless m.length > 0
38
+ if m.length > 1
39
+ m = m.delete_if{|x| x[0].length > 200 }
40
+ raise 'Only overly long quotes found' unless m.length > 0
41
+ end
42
+ i = rand(m.length) # NOTE: this works fine for individuals, since rand(1) is always 0
43
+ n = m[i][0].gsub(/<[^<]+>/, '') # select a random quote
44
+ o = Helpers.convert_entities(n) # unescape html entities
45
+ p = o.gsub("\r\n", " ").strip # replace newlines with spaces and trim
46
+ q = p.gsub(/(<([^>]+)>(?:[^<]+))<\2>/){ $1 } # replace duplicated name tags; condense lines
47
+ r = q.gsub(/\s{2,}/, ' ') # condense spaces
48
+ return r
49
+ rescue Object => boom
50
+ Logger.error(boom)
51
+ raise boom
52
+ end
53
+ end
54
+ end
55
+
@@ -1,44 +1,34 @@
1
+ require 'openssl'
2
+
1
3
  class Bouncer < ModSpox::Plugin
2
-
3
- include Models
4
-
4
+
5
5
  def initialize(pipeline)
6
6
  super
7
- admin = Group.find_or_create(:name => 'bouncer')
8
- Signature.find_or_create(:signature => 'bouncer port ?(\d+)?', :plugin => name, :method => 'port',
9
- :group_id => admin.pk, :description => 'Show or set bouncer port').params = [:port]
10
- Signature.find_or_create(:signature => 'bouncer (start|stop|restart)', :plugin => name, :method => 'do_service',
11
- :group_id => admin.pk, :description => 'Start or stop the bouncer').params = [:action]
12
- Signature.find_or_create(:signature => 'bouncer status', :plugin => name, :method => 'status',
13
- :group_id => admin.pk, :description => 'Show current bouncer status')
14
- Signature.find_or_create(:signature => 'bouncer disconnect', :plugin => name, :method => 'disconnect',
15
- :group_id => admin.pk, :description => 'Disconnect all users connected to bouncer')
16
- Signature.find_or_create(:signature => 'bouncer clients', :plugin => name, :method => 'clients',
17
- :group_id => admin.pk, :description => 'List clients connected to bouncer')
7
+ bounce = Group.find_or_create(:name => 'bouncer')
8
+ add_sig(:sig => 'bouncer port( (\d+))?', :method => :port, :group => bounce, :desc => 'Show or set bouncer port',
9
+ :params => [:port])
10
+ add_sig(:sig => 'bouncer (start|stop|restart)', :method => :do_service, :group => bounce, :desc => 'Start, stop, or restart bouncer')
11
+ add_sig(:sig => 'bouncer status', :method => :status, :group => bounce, :desc => 'Show current bouncer status')
12
+ add_sig(:sig => 'bouncer disconnect', :method => :disconnect, :group => bounce, :desc => 'Disconnect all connected clients')
13
+ add_sig(:sig => 'bouncer clients'< :method => :clients, :group => bounce, :desc => 'List clients connected to bouncer')
18
14
  @pipeline.hook(self, :get_msgs, :Incoming)
19
15
  @listener = nil
20
16
  @clients = []
21
17
  @socket = nil
22
18
  @processor = nil
23
19
  @to_server = Queue.new
24
- if(Config[:bouncer_port])
25
- start_listener
26
- end
20
+ start_listener if Models::Config.filter(:name => 'bouncer_port').count > 0
27
21
  end
28
22
 
29
23
  def get_msgs(message)
30
24
  unless(@clients.empty?)
31
- Logger.info("BOUNCER: Sending to #{@clients.size} clients")
25
+ Logger.info("Bouncer has #{@clients.size} clients to send a message to")
32
26
  @clients.each do |client|
33
27
  begin
34
- if(message.raw_content.is_a?(Array))
35
- message.raw_content.each do |m|
36
- client[:connection].puts(m + "\n")
37
- end
38
- else
39
- client[:connection].puts(message.raw_content + "\n")
40
- end
28
+ output = message.raw_content.is_a?(Array) ? message.raw_content.join("\n") : message.raw_content + "\n"
29
+ client[:connection].puts(output)
41
30
  rescue Object => boom
31
+ Logger.warn("Bouncer encountered unexpected error. Disconnecting client. #{boom}")
42
32
  client[:thread].kill if client[:thread].alive?
43
33
  @clients.delete(client)
44
34
  end
@@ -46,54 +36,92 @@ class Bouncer < ModSpox::Plugin
46
36
  end
47
37
  end
48
38
 
49
- def port(message, params)
50
- unless(params[:port])
51
- if(Config[:bouncer_port])
52
- reply message.replyto, "Bouncer is currently listening on port: #{Config[:bouncer_port]}"
39
+ def port(m, params)
40
+ if(params[:port])
41
+ if(Models::Config.filter(:name => 'bouncer_port').count > 0)
42
+ reply m.replyto, "Bouncer port is set to: #{Models::Config.filter(:name => 'bouncer_port').first.value
53
43
  else
54
- reply message.replyto, "\2Warning:\2 Listening port is not currently set for bouncer"
44
+ error m.replyo, 'No port has been set for bouncer'
55
45
  end
56
46
  else
57
- Config[:bouncer_port] = params[:port].to_i
58
- reply message.replyto, "Bouncer will now listen on port: #{params[:port].to_i}"
59
- restart_listener
47
+ parmas[:port].strip!
48
+ c = Models::Config.find_or_create(:name => 'bouncer_port')
49
+ c.value = params[:port]
50
+ c.save
51
+ information m.replyto, "Bouncer port is not set to: #{params[:port]}"
60
52
  end
61
53
  end
62
54
 
63
- def do_service(message, params)
64
- if(params[:action] == 'start')
65
- if(listening?)
66
- reply message.replyto, "\2Error:\2 Bouncer is already running"
67
- else
68
- start_listener
69
- reply message.replyto, "Bouncer has been started"
70
- end
71
- elsif(params[:action] == 'stop')
72
- if(listening?)
55
+ def do_service(m, params)
56
+ begin
57
+ case params[:action]
58
+ when 'start'
59
+ if(listening?)
60
+ error m.replyto, 'Bouncer is already running'
61
+ else
62
+ start_listener
63
+ information m.replyto, 'Bouncer has been started'
64
+ end
65
+ when 'stop'
66
+ if(listening?)
67
+ stop_listener
68
+ information m.replyto, 'Bouncer has been stopped'
69
+ else
70
+ error m.replyto, 'Bouncer is not currently running'
71
+ end
72
+ when 'restart'
73
73
  stop_listener
74
- reply message.replyto, "Bouncer has been stopped"
75
- else
76
- reply message.replyto, "\2Error:\2 Bouncer is not currently running"
74
+ start_listener
75
+ information m.replyto, 'Bouncer has been restarted'
77
76
  end
78
- elsif(params[:action] == 'restart')
79
- stop_listener
80
- start_listener
81
- reply message.replyto, "Bouncer has been restarted"
77
+ rescue Object => boom
78
+ error m.replyto, "Error was encountered during #{params[:action]} process. (#{boom})"
82
79
  end
83
80
  end
84
-
85
- def disconnect(message, params)
81
+
82
+ def disconnect(m, params)
86
83
  unless(@clients.empty?)
87
- @clients.each do |socket|
88
- socket[:connection].close
89
- @clients.delete(socket)
84
+ @clients.each do |client|
85
+ client[:connection].close unless client[:connection].closed?
86
+ @clients.delete(client)
90
87
  end
91
- reply message.replyto, "Bouncer has disconnected all clients"
88
+ information m.replyto, 'All clients have been disconnected'
92
89
  else
93
- reply message.replyto, "\2Error:\2 No clients connected to bouncer"
90
+ warning m.replyto, 'No clients are connected to bouncer'
94
91
  end
95
92
  end
96
93
 
94
+ def status(m, params)
95
+ warning m.replyto, 'not implemented'
96
+ end
97
+
98
+ private
99
+
100
+ def start_listener
101
+ port = Models::Config.filter(:name => 'bouncer_port').first
102
+ raise 'Port has not been set' unless port
103
+ port = port.value.to_i
104
+ @socket = OpenSSL::SSL::SSLServer.new(port)
105
+ @listener = Thread.new do
106
+ until(@socket.closed?)
107
+ begin
108
+ new_con = @socket.accept_nonblock
109
+ add_client(new_con)
110
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR
111
+ IO.select([@socket])
112
+ retry
113
+ rescue Object => boom
114
+ Logger.warn "Bouncer listener encountered an error: #{boom}"
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ def add_client
121
+ end
122
+
123
+ class Bouncer < ModSpox::Plugin
124
+
97
125
  def status(message, params)
98
126
  end
99
127