nadoka 0.8.5 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a0027c38e7562857343bf5e48f87e1916ec53cde
4
- data.tar.gz: 86d15edf115119b3f5bcd9f54804195684c3bfa9
2
+ SHA256:
3
+ metadata.gz: 8794eb0d0b61ad6529c1f96b4b55fadd8eec443f0a36e8b284e6eaf21b9ad3c8
4
+ data.tar.gz: 43242ba299e9acc927cdce8a1049d8ca5160cb1b8ff4d7ddc478e8cdc0c3152a
5
5
  SHA512:
6
- metadata.gz: 9a5a016d5cf5855d582ff360ab65022d4c53e2edab751d8349154b379dd1913091b6522b4b5ae56567433723d3801e9d3836edc3fd9df5f2918c15511004d5ea
7
- data.tar.gz: 1548049a15809f1f5a54bf9521d14d426bd0ad0bb0182114b7ea79c7aa36f94ef117ff26fc83073c70e8981a221f715d0d1e0fc81edef91b729a679aa1450698
6
+ metadata.gz: 643b75b33ebb71275c0c1c71a437c3dee2f2b1a313bdc0c7164f6db66371197206cb3f12cef9a2d034fa0a86d7c48158ee53e7c268994bbb3aa2b29d3bd010c8
7
+ data.tar.gz: 9ea081ef58fdfdc708d0cf92d37db5fc725a0d95028fa391339dc9408648489b8dbcbd2a693c6acc06b09d39978d55428e479805f4122353c56aa4492a8f5cd9
@@ -1,24 +1,20 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
4
- - 1.9.3
5
- - jruby-18mode # JRuby in 1.8 mode
6
- - jruby-19mode # JRuby in 1.9 mode
7
- - rbx-18mode
8
- - rbx-19mode
3
+ - 2.7
4
+ - 2.6
5
+ - 2.5
6
+ - 2.4
7
+ - 2.3
9
8
  - ruby-head
10
9
  - jruby-head
11
- - 1.8.7
12
- - ree
13
10
  matrix:
14
11
  allow_failures:
15
12
  - rvm: jruby-18mode
16
13
  - rvm: jruby-19mode
17
- - rvm: rbx-18mode
18
- - rvm: rbx-19mode
19
14
  - rvm: ruby-head
20
15
  - rvm: jruby-head
21
- - rvm: ree
16
+ before_install:
17
+ - gem update bundler
22
18
  script: ruby check-syntax.rb
23
19
  notifications:
24
20
  irc: "irc.freenode.org#nadoka_jp"
data/README.md CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  Written by SASADA Koichi <ko1 at atdot.net>
4
4
 
5
- [![Build Status](https://travis-ci.org/nadoka/nadoka.png?branch=master)](https://travis-ci.org/nadoka/nadoka)
6
- [![Code Climate](https://codeclimate.com/github/nadoka/nadoka.png)](https://codeclimate.com/github/nadoka/nadoka)
5
+ [![Gem Version](https://badge.fury.io/rb/nadoka.svg)](http://badge.fury.io/rb/nadoka)
6
+ [![Build Status](https://img.shields.io/travis/nadoka/nadoka.svg)](https://travis-ci.org/nadoka/nadoka)
7
+ [![Code Climate](https://img.shields.io/codeclimate/github/nadoka/nadoka.svg)](https://codeclimate.com/github/nadoka/nadoka)
7
8
 
8
9
  ## What's this?
9
10
 
@@ -21,5 +22,4 @@ You can do with this software:
21
22
  See Web pages:
22
23
 
23
24
  - https://github.com/nadoka/nadoka
24
- - http://rubyforge.org/projects/nadoka/
25
25
  - http://www.atdot.net/nadoka/
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2019 Kazuhiro NISHIYAMA
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ # see https://www.freedesktop.org/software/systemd/man/sd_notify.html
26
+ class NotifySocket
27
+ def initialize(path=ENV['NOTIFY_SOCKET'])
28
+ @notify_socket = nil
29
+ return unless path
30
+ @notify_socket = Addrinfo.unix(path, :DGRAM).connect
31
+ end
32
+
33
+ def []=(key, value)
34
+ return unless @notify_socket
35
+ @notify_socket.puts "#{key}=#{value}"
36
+ end
37
+
38
+ def ready!
39
+ self['READY'] = 1
40
+ end
41
+
42
+ def reloading!
43
+ self['RELOADING'] = 1
44
+ end
45
+
46
+ def stopping!
47
+ self['STOPPING'] = 1
48
+ end
49
+
50
+ # notify_socket.status = 'Completed 66% of file system check…'
51
+ def status=(state)
52
+ self['STATUS'] = state
53
+ end
54
+
55
+ # notify_socket.errno = 2
56
+ def errno=(error_code)
57
+ self['ERRNO'] = error_code
58
+ end
59
+
60
+ # notify_socket.buserror = 'org.freedesktop.DBus.Error.TimedOut'
61
+ def buserror=(error_code)
62
+ self['BUSERROR'] = error_code
63
+ end
64
+
65
+ # notify_socket.mainpid = 4711
66
+ def mainpid=(pid)
67
+ self['MAINPID'] = pid
68
+ end
69
+
70
+ def watchdog!
71
+ self['WATCHDOG'] = 1
72
+ end
73
+
74
+ # notify_socket.watchdog_usec = 20_000_000
75
+ def watchdog_usec=(usec)
76
+ self['WATCHDOG_USEC'] = usec
77
+ end
78
+
79
+ def extend_timeout_usec=(usec)
80
+ self['EXTEND_TIMEOUT_USEC'] = usec
81
+ end
82
+ end
@@ -79,7 +79,7 @@ class RSS_Check
79
79
 
80
80
  def read_content
81
81
  case @uri.scheme
82
- when 'http'
82
+ when 'http', 'https'
83
83
  open(@uri){|f|
84
84
  if f.content_encoding.any?{|e| /gzip/ =~ e}
85
85
  Zlib::GzipReader.new(StringIO.new(f.read)).read || ''
@@ -96,7 +96,7 @@ class RSS_Check
96
96
 
97
97
  def mtime
98
98
  case @uri.scheme
99
- when 'http'
99
+ when 'http', 'https'
100
100
  open(@uri){|f|
101
101
  f.last_modified || Time.now
102
102
  }
@@ -204,13 +204,11 @@ if $0 == __FILE__
204
204
  ARGV.shift || './rss_cache',
205
205
  false # false
206
206
  )
207
- require 'iconv'
208
207
  require 'kconv'
209
- ic = Iconv.open("EUC-JP", "UTF-8")
210
208
 
211
209
  rssc.check.each{|e|
212
210
  puts e[:about]
213
- title = (e[:ccode] == 'UTF-8') ? ic.iconv(e[:title]) : e[:title]
211
+ title = (e[:ccode] == 'UTF-8') ? e[:title].toeuc : e[:title]
214
212
  puts title
215
213
  }
216
214
  rssc.dump
@@ -16,8 +16,6 @@ Gem::Specification.new do |s|
16
16
  older proxy written in Perl.
17
17
  }.tr_s(" \n", " ").strip
18
18
 
19
- s.rubyforge_project = "nadoka"
20
-
21
19
  s.files = `git ls-files`.split("\n")
22
20
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
data/nadoka.rb CHANGED
@@ -29,6 +29,16 @@ require 'ndk/bot'
29
29
  $stdout.sync=true
30
30
  $NDK_Debug = false
31
31
 
32
+ if ENV.key?('NOTIFY_SOCKET')
33
+ require 'lib/notify_socket'
34
+ $NDK_NOTIFY_SOCKET = NotifySocket.new
35
+ else
36
+ $NDK_NOTIFY_SOCKET = Object.new
37
+ def $NDK_NOTIFY_SOCKET.method_missing(*)
38
+ # ignore
39
+ end
40
+ end
41
+
32
42
  unless defined? Process.daemon
33
43
  def Process.daemon(nochdir = nil, noclose = nil)
34
44
  exit!(0) if fork
@@ -45,6 +55,7 @@ unless defined? Process.daemon
45
55
  end
46
56
 
47
57
  rcfile = nil
58
+ pidfile = nil
48
59
  daemon = false
49
60
  optparse = OptionParser.new{|opts|
50
61
  opts.banner = "Usage: ruby #{$0} [options]"
@@ -70,6 +81,9 @@ optparse = OptionParser.new{|opts|
70
81
  opts.on("--daemon", "run as daemon"){
71
82
  daemon = true
72
83
  }
84
+ opts.on("--pid [PIDFILE]", "Put process pid into PIDFILE"){|f|
85
+ pidfile = f
86
+ }
73
87
 
74
88
  opts.separator ""
75
89
  opts.separator "Common options:"
@@ -95,21 +109,31 @@ if daemon
95
109
  Process.daemon
96
110
  end
97
111
 
112
+ if pidfile
113
+ open(pidfile, "w") {|f| f.puts Process.pid }
114
+ end
115
+
98
116
  begin
99
117
  GC.start
100
118
  Nadoka::NDK_Server.new(rcfile).start
101
119
  rescue Nadoka::NDK_QuitProgram
102
- #
120
+ $NDK_NOTIFY_SOCKET.stopping!
103
121
  rescue Nadoka::NDK_RestartProgram
122
+ $NDK_NOTIFY_SOCKET.reloading!
104
123
  GC.start
105
124
  ObjectSpace.each_object(Socket) {|sock| sock.close}
106
125
  retry
107
126
  rescue Exception => e
127
+ $NDK_NOTIFY_SOCKET.stopping!
108
128
  open('nadoka_fatal_error', 'w'){|f|
109
129
  f.puts e
110
130
  f.puts e.backtrace.join("\n")
111
131
  }
112
132
  end
113
133
 
134
+ if pidfile
135
+ File.unlink(pidfile)
136
+ end
137
+
114
138
  end
115
139
 
data/nadokarc CHANGED
@@ -7,7 +7,7 @@
7
7
  #
8
8
  # This program is free software with ABSOLUTELY NO WARRANTY.
9
9
  # You can re-distribute and/or modify this program under
10
- # the same terms of the Ruby's lisence.
10
+ # the same terms of the Ruby's license.
11
11
  #
12
12
  #
13
13
 
@@ -68,19 +68,19 @@ class NADOKA_Config < Nadoka::NDK_ConfigBase
68
68
  :port => 6667, # default: 6667
69
69
  :pass => nil, # default: nil
70
70
  },
71
- { :host => 'irc.media.kyoto-u.ac.jp',
72
- :port => (6660 .. 6669),
73
- },
74
- { :host => 'irc.huie.hokudai.ac.jp',
71
+ # { :host => 'irc.media.kyoto-u.ac.jp',
72
+ # :port => (6660 .. 6669),
73
+ # },
74
+ # { :host => 'irc.huie.hokudai.ac.jp',
75
75
  # without :port, use 6667 as default port
76
- },
76
+ # },
77
77
  # IPv6 Sample
78
78
  # {
79
79
  # :host => 'irc6.ircnet.ne.jp',
80
80
  # :port => 6667,
81
81
  # },
82
82
  # {
83
- # :host => 'irc6.livedoor.ne.jp',
83
+ # :host => 'dh6.ircnet.ne.jp',
84
84
  # :port => (6660 .. 6669),
85
85
  # },
86
86
  ]
@@ -387,7 +387,7 @@ module Nadoka
387
387
  @config = {}
388
388
  klass = ConfigClass.last
389
389
 
390
- klass.ancestors[0..-3].reverse_each{|kl|
390
+ klass.ancestors[0..klass.ancestors.index(NDK_ConfigBase)].reverse_each{|kl|
391
391
  kl.constants.each{|e|
392
392
  @config[e.downcase.intern] = klass.const_get(e)
393
393
  }
@@ -506,9 +506,10 @@ module Nadoka
506
506
  else
507
507
  if m = msgobj[$1.intern]
508
508
  if m.respond_to?(:force_encoding)
509
- m.force_encoding(Encoding::ASCII_8BIT)
509
+ m.dup.force_encoding(Encoding::ASCII_8BIT)
510
+ else
511
+ m
510
512
  end
511
- m
512
513
  else
513
514
  "!!unknown attribute: #{$1}!!"
514
515
  end
@@ -214,7 +214,7 @@ module Nadoka
214
214
  :nostamp => nostamp,
215
215
  :ch => ch,
216
216
  }
217
-
217
+ $NDK_NOTIFY_SOCKET.status = msgobj.inspect.tr("\n", ' ')
218
218
  msgobj
219
219
  end
220
220
 
@@ -180,6 +180,10 @@ module Nadoka
180
180
  @server_thread.raise NDK_ReconnectToServer
181
181
  when '020'
182
182
  # ignore
183
+ when 'PRIVMSG'
184
+ # ignore
185
+ when '004'
186
+ # ignore
183
187
  else
184
188
  msg = "Server login fail!(#{q})"
185
189
  @logger.slog msg
@@ -215,6 +219,7 @@ module Nadoka
215
219
  end
216
220
 
217
221
  invoke_event :invoke_bot, :server_connected
222
+ $NDK_NOTIFY_SOCKET.ready!
218
223
 
219
224
  # loop
220
225
  while q = recv_from_server
@@ -409,6 +414,7 @@ module Nadoka
409
414
  if @connected
410
415
  if @pong_recieved
411
416
  @pong_fail_count = 0
417
+ $NDK_NOTIFY_SOCKET.watchdog!
412
418
  else
413
419
  # fail
414
420
  @pong_fail_count += 1
@@ -11,7 +11,7 @@
11
11
  #
12
12
 
13
13
  module Nadoka
14
- VERSION = '0.8.5'
14
+ VERSION = '0.10.0'
15
15
  NDK_Version = VERSION.dup
16
16
  NDK_Created = Time.now
17
17
 
@@ -29,7 +29,7 @@ BotConfig = [
29
29
 
30
30
  This program is free software with ABSOLUTELY NO WARRANTY.
31
31
  You can re-distribute and/or modify this program under
32
- the same terms of the Ruby's lisence.
32
+ the same terms of the Ruby's license.
33
33
 
34
34
  == Author
35
35
 
@@ -0,0 +1,93 @@
1
+ # -*-ruby-*-
2
+ require 'ffi/clang'
3
+ require 'tempfile'
4
+
5
+ # dependency:
6
+ # * ffi-clang.gem
7
+ # * libclang
8
+ # * lang/clang34 in FreeBSD ports
9
+ # * llvm of homebrew
10
+ #
11
+ # example setting:
12
+ # {
13
+ # :name => :CRubyBot,
14
+ # :channels => [ "#ruby-ja" ],
15
+ # :ruby_srcdir => '/path/of/ruby/src',
16
+ # }
17
+ #
18
+ class CRubyBot < Nadoka::NDK_Bot
19
+ def bot_initialize
20
+ if @bot_config.key?(:channels)
21
+ channels = '\A(?:' + @bot_config[:channels].collect{|ch|
22
+ Regexp.quote(ch)
23
+ }.join('|') + ')\z'
24
+ @available_channel = Regexp.compile(channels)
25
+ else
26
+ @available_channel = @bot_config.fetch(:ch, //)
27
+ end
28
+ unless @ruby_srcdir = @bot_config[:ruby_srcdir]
29
+ raise "ruby_srcdir is not specified"
30
+ end
31
+ unless Dir.exist?(@ruby_srcdir)
32
+ raise "ruby_srcdir(#{@ruby_srcdir}) does not exist"
33
+ end
34
+ @ruby_srcdir << '/' if @ruby_srcdir[-1] != '/'
35
+ @translation_unit = nil
36
+ @translation_unit_rev = nil
37
+ end
38
+
39
+ def bot_state
40
+ "<#{self.class.to_s}>"
41
+ end
42
+
43
+ def translation_unit
44
+ rev = IO.read("#@ruby_srcdir/revision.h").to_s[/\d+/].to_i
45
+ return @translation_unit if @translation_unit_rev == rev
46
+ ary = Dir[File.join @ruby_srcdir, "*.c"]
47
+ f = Tempfile.open(["crubybot-ruby", ".c"])
48
+ ary = Dir[File.join @ruby_srcdir, "*.c"]
49
+ ary << File.join(@ruby_srcdir, "win32/win32.c")
50
+ ary.each do |fn|
51
+ f.puts %[#include "#{fn}"]
52
+ end
53
+ f.flush
54
+ index = FFI::Clang::Index.new
55
+ @translation_unit = index.parse_translation_unit(f.path, "-I#{@ruby_srcdir}/include")
56
+ @translation_unit_rev = rev
57
+ f.close(true)
58
+ @translation_unit
59
+ end
60
+
61
+ def find_def(name, kind)
62
+ translation_unit.cursor.visit_children do |cursor, parent|
63
+ if cursor.kind == kind && cursor.definition? && cursor.spelling == name
64
+ loc = cursor.location
65
+ path = loc.file
66
+ if path.start_with?(@ruby_srcdir)
67
+ return [path[@ruby_srcdir.size..-1], loc.line]
68
+ end
69
+ end
70
+ next :recurse
71
+ end
72
+ return nil
73
+ end
74
+
75
+ def on_privmsg(client, ch, message)
76
+ return unless @available_channel === ch
77
+ case message
78
+ when /\A\S*(struct|fun\w*)\s+(\w+)/
79
+ kind1 = $1
80
+ name = $2
81
+ kind = case kind1
82
+ when "struct"
83
+ :cursor_struct
84
+ when /\Afun/
85
+ :cursor_function
86
+ end
87
+ path, line = find_def(name, kind)
88
+ return unless path
89
+ send_notice(ch, "crubybot: #{kind1} #{name} at " \
90
+ "https://github.com/ruby/ruby/blob/trunk/#{path}#L#{line}")
91
+ end
92
+ end
93
+ end