kanamei-kanamei-keystone 0.0.7 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'keystone'
3
+ require 'keystone/batch_base'
4
+ require 'keystone/mail'
5
+
6
+ include Keystone::BatchBase
7
+
8
+ if ARGV[0] == nil
9
+ puts "set mail addr"
10
+ exit
11
+ end
12
+
13
+ MAIL_FROM = ARGV[0]
14
+ MAIL_TO = [ARGV[0]]
15
+ MAIL_SUBJECT = 'テストメール~~'
16
+ MAIL_BODY = <<BODY
17
+ こんにちは
18
+ どないでしょう??
19
+ 〜〜〜
20
+ #{Keystone::Environment.dump}
21
+ BODY
22
+
23
+ execute do
24
+ info "batch process01"
25
+ sleep 1.2
26
+
27
+ begin
28
+ raise 'error occur'
29
+ rescue => e
30
+ error e
31
+ Keystone::Mail::Send.new().send(MAIL_FROM,MAIL_TO,MAIL_SUBJECT,MAIL_BODY)
32
+ Keystone::Mail::Send.send(MAIL_FROM,MAIL_TO,MAIL_SUBJECT,MAIL_BODY)
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'keystone'
3
+
4
+ st = %|test "test 02" 日本語 ニホンゴハンカク "にほ んご ですが なにか"|
5
+ st2 = Keystone::StringUtil.to_searchtext(st)
6
+
7
+ p Keystone::StringUtil.serach_string_to_array(st)
8
+ p Keystone::StringUtil.serach_string_to_array(st2)
@@ -1,7 +1,25 @@
1
+
2
+ $KCODE = 'u'
3
+
4
+ require 'keystone/core_ext'
5
+ require 'keystone/base'
6
+
7
+ include Keystone::Base
8
+
9
+ autoload :FlagSetMaker , 'flag_set_maker'
10
+ autoload :Moji , 'moji'
11
+
1
12
  module Keystone
2
- autoload :StringUtil , 'keystone/string_util'
13
+
14
+ VERSION = '0.0.10'
15
+
16
+ autoload :StringUtil , 'keystone/string_util'
17
+ autoload :BatchUtil , 'keystone/batch_util'
18
+ autoload :Environment , 'keystone/environment'
19
+ autoload :Mail , 'keystone/mail'
3
20
 
4
21
  module Rails
5
22
  #autoload :ActiveSupportExt, 'keystone/rails/active_support_ext'
6
23
  end
7
- end
24
+ end
25
+
@@ -0,0 +1,36 @@
1
+ module Keystone
2
+ module Base
3
+ def log(log_type,message, is_base_info = true)
4
+ if is_base_info
5
+ puts "[#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}][#{$$}][#{log_type.to_s}] #{message}"
6
+ else
7
+ puts "[#{log_type.to_s}] #{message}"
8
+ end
9
+ end
10
+
11
+ def info(message)
12
+ log(:INFO,message)
13
+ end
14
+
15
+ def error(message)
16
+ if message.is_a? Exception
17
+ log(:ERROR," #{message.message}")
18
+ message.backtrace.each_with_index {|line, i|
19
+ log(:ERROR," #{line})",false)
20
+ }
21
+ else
22
+ log(:ERROR,message.to_s)
23
+ end
24
+ end
25
+
26
+ def warn(message)
27
+ log(:WARN,message)
28
+ end
29
+
30
+ def debug(message)
31
+ if $DEBUG
32
+ log(:DEBUG,message)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module Keystone
2
+ module BatchBase
3
+ def execute(&process)
4
+ info "start script"
5
+ script_started_at = Time.now
6
+ begin
7
+ return (yield process)
8
+ rescue => e
9
+ error e
10
+ Skutil::Mail.send_error(ERROR_MAIL_FROM,ERROR_MAIL_TO,ERROR_MAIL_SUBJECT,e)
11
+ return e
12
+ ensure
13
+ info "finish script (%1.3fsec)" % (Time.now - script_started_at)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,76 @@
1
+
2
+ require 'tempfile'
3
+
4
+ class Uri
5
+ #
6
+ def self.escape_raw(st)
7
+ st.gsub(/([^a-zA-Z0-9_\-\.~])/) { "%#{$1.unpack('H*')[0].scan(/../).join('%').upcase }" }
8
+ end
9
+
10
+ #
11
+ # usage
12
+ # @search_tag = Uri.unescape_raw(params[:tag]).toutf8
13
+ #
14
+ #
15
+ def self.unescape_raw(st)
16
+ st.tr('+',' ').gsub(/%([A-Fa-f0-9][A-Fa-f0-9])/) { [$1.hex].pack('C') }
17
+ end
18
+ end
19
+
20
+ class Tempfile
21
+ def self.open_with_block(name = nil, dir = nil)
22
+ name ||= (0..8).map{rand(36).to_s(36)}.join
23
+ args = dir ? [name, dir] : [name]
24
+ tmp = Tempfile.open *args
25
+ begin
26
+ yield tmp
27
+ ensure
28
+ tmp.close true
29
+ end
30
+ end
31
+ end
32
+
33
+ class Dir
34
+ def self.mkdir_r(dirPath)
35
+ folders = dirPath.split('/')
36
+ folderToCreate = ''
37
+ folders.each do |folder|
38
+ folderToCreate += folder + '/'
39
+ if !File.directory?(folderToCreate)
40
+ Dir.mkdir(folderToCreate)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ class Object
47
+ # http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
48
+ def metaclass
49
+ class << self
50
+ self
51
+ end
52
+ end
53
+
54
+ # http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
55
+ def meta_eval(&blk)
56
+ metaclass.instance_eval(&blk)
57
+ end
58
+
59
+ # http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
60
+ def meta_def(name, &blk)
61
+ meta_eval { define_method name, &blk }
62
+ end
63
+
64
+ # http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
65
+ def class_def(name, &blk)
66
+ class_eval { define_method name, &blk }
67
+ end
68
+
69
+ # 1.8.7 エミュレート
70
+ def tap
71
+ yield(self)
72
+ self
73
+ end
74
+ end
75
+
76
+
@@ -0,0 +1,47 @@
1
+ module Keystone
2
+ class Environment
3
+ def self.ip_address
4
+ ifconfig = `/sbin/ifconfig`
5
+ ips = []
6
+
7
+ # TODO mac
8
+ ifconfig.gsub(/inet addr:(\d+\.\d+\.\d+\.\d+)/){|ip|
9
+ if $1 != '127.0.0.1'
10
+ ips << $1
11
+ end
12
+ }
13
+ return ips
14
+ end
15
+
16
+ def self.hostname
17
+ `/bin/hostname`.chomp
18
+ end
19
+
20
+ def self.df
21
+ `/bin/df -h`.chomp
22
+ end
23
+
24
+ def self.ps
25
+ `/bin/ps -ef`.chomp
26
+ end
27
+
28
+ def self.netstat
29
+ `/usr/sbin/netstat -an`.chomp
30
+ end
31
+
32
+ def self.execute(command)
33
+ `#{command}`.chomp
34
+ end
35
+
36
+ def self.dump
37
+ self_methods = self.methods - Class.methods
38
+ self_methods.delete("dump")
39
+ self_methods.delete("execute")
40
+ st = ""
41
+ self_methods.each do |method|
42
+ st << "#{method}:\n #{self.__send__(method).to_s.split("\n").join("\n ")}\n"
43
+ end
44
+ return st
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,6 @@
1
+ module Keystone
2
+ module Mail
3
+ autoload :Send , 'keystone/mail/send'
4
+ autoload :Receive , 'keystone/mail/receive'
5
+ end
6
+ end
@@ -0,0 +1,68 @@
1
+ #
2
+ # 普通なことをしたいならTMailを使いましょう
3
+ #
4
+
5
+ require 'net/smtp'
6
+ require 'kconv'
7
+
8
+ module Keystone
9
+ module Mail
10
+ class Send
11
+ def initialize(smtp_addr="127.0.0.1",smtp_port=25)
12
+ @smtp_addr,@smtp_port=smtp_addr,smtp_port
13
+ end
14
+
15
+ def self.send(from,to,title,body,smtp_addr="127.0.0.1",smtp_port=25)
16
+ from_addr,from_addr_4_header = create_addr_and_header(from)
17
+ title = Kconv.tojis(title)
18
+ title = title.split(//,1).pack('m'); title = title.chomp
19
+ if to.class.to_s == 'Array'
20
+ tomany = to.join(',')
21
+ else
22
+ tomany = to.to_s;
23
+ end
24
+
25
+ head = <<HEAD
26
+ Subject: =?ISO-2022-JP?B?#{title}?=
27
+ To: #{tomany}
28
+ From: #{from_addr_4_header}
29
+ Mime-Version: 1.0
30
+ Content-Transfer-Encoding: 7bit
31
+ Content-Type: Text/Plain; charset=iso-2022-jp
32
+ HEAD
33
+ src = head + "\n" + Kconv.tojis(body)
34
+ # puts src
35
+ m = Net::SMTPSession.new(smtp_addr, smtp_port)
36
+ m.start()
37
+ m.sendmail(src, from_addr, to)
38
+ m.finish
39
+ end
40
+
41
+ def send(from,to,title,body)
42
+ self.class.send(from,to,title,body,@smtp_addr,@smtp_port)
43
+ end
44
+
45
+ private
46
+
47
+ def self.create_addr_and_header(addr_data)
48
+ addr = ''
49
+ addr_4_header = ''
50
+ case addr_data.class.to_s
51
+ when 'String'
52
+ addr = addr_data.dup
53
+ addr_4_header = addr.dup
54
+ when 'Array'
55
+ addr = addr_data[1].dup
56
+ addr_4_header = addr_data[0].dup
57
+ addr_4_header = Kconv.tojis(addr_4_header)
58
+ addr_4_header = addr_4_header.split(//,1).pack('m'); addr_4_header = addr_4_header.chomp
59
+ addr_4_header = "=?ISO-2022-JP?B?#{addr_4_header}?=<#{addr}>"
60
+ else
61
+ # TODO exception
62
+ raise 'addr_data must be String or Array'
63
+ end
64
+ return addr,addr_4_header
65
+ end
66
+ end
67
+ end
68
+ end
@@ -2,8 +2,8 @@ module Keystone
2
2
  class StringUtil
3
3
  def self.int_to_splitted_path(i_value,value_length,base_folder,suffix="")
4
4
  file_name = Integer(i_value).to_s
5
- raise "value_length must bigger than 0" if value_length < 1
6
- raise 'i_value length is bigger than value_length' if file_name.size > value_length
5
+ raise RangeError,"value_length must bigger than 0" if value_length < 1
6
+ raise RangeError, 'i_value length is bigger than value_length' if file_name.size > value_length
7
7
  file_name = file_name.rjust(value_length, '0')
8
8
  new_path = base_folder.dup
9
9
  group_regex = ""
@@ -28,5 +28,47 @@ module Keystone
28
28
  new_path << suffix if suffix != ""
29
29
  return new_path
30
30
  end
31
+
32
+ def self.reverse_mail(mail)
33
+ if mail.index('@') == nil
34
+ return mail
35
+ end
36
+ user,dom = mail.split('@')
37
+ if dom == nil
38
+ return "@#{user}"
39
+ end
40
+ return dom.split('.').reverse.join(".") + "@" + user
41
+ end
42
+
43
+ MULTIBYTE_SPACE = [0x3000].pack("U")
44
+ PRESERVED_QUERY_WORDS_RE = /(AND|OR|ANDNOT)/
45
+ #
46
+ # adviced by Mr.morohashi
47
+ #
48
+ def self.serach_string_to_array(query)
49
+ tokens = query.scan(/'([^']*)'|"([^"]*)"|([^\s#{MULTIBYTE_SPACE}]*)/).flatten.reject{|i| i == nil || i == "" }
50
+ tokens.map do |token|
51
+ next unless token
52
+ #token.gsub!(PRESERVED_QUERY_WORDS_RE, $1.downcase) if token =~ PRESERVED_QUERY_WORDS_RE
53
+ token.gsub!(/\A['"]|['"]\z/, '') # strip quatos
54
+ token
55
+ end
56
+ end
57
+
58
+ #
59
+ #
60
+ # TODO
61
+ def self.downcase_roma_number(st)
62
+ st.tr("ⅠⅡⅢⅣ", "ⅰⅱⅲⅳ")
63
+ end
64
+
65
+ #
66
+ # making search text for indexing
67
+ #
68
+ def self.to_searchtext(str)
69
+ self.downcase_roma_number(Moji.han_to_zen(
70
+ Moji.zen_to_han(str,Moji::ZEN_ALNUM | Moji::ZEN_SYMBOL).downcase,Moji::HAN_KATA | Moji::HAN_JSYMBOL).tr("ー~/","ー~/")
71
+ )
72
+ end
31
73
  end
32
- end
74
+ end
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'redgreen'
3
+ require 'lib/keystone'
4
+ require 'lib/keystone/string_util'
5
+
6
+ $KCODE='u'
7
+
8
+ class TestStringUtilBase < Test::Unit::TestCase
9
+ def setup
10
+ end
11
+
12
+ def test_reverse_mail
13
+ assert_equal(Keystone::StringUtil::reverse_mail("testuser@softbank.ne.jp"),"jp.ne.softbank@testuser")
14
+ assert_equal(Keystone::StringUtil::reverse_mail("test.user@somedomain.com"),"com.somedomain@test.user")
15
+ assert_equal(Keystone::StringUtil::reverse_mail("a.b@c.d"),"d.c@a.b")
16
+ assert_equal(Keystone::StringUtil::reverse_mail("a.b@"),"@a.b")
17
+ assert_equal(Keystone::StringUtil::reverse_mail("@c.d"),"d.c@")
18
+ assert_equal(Keystone::StringUtil::reverse_mail("a.b"),"a.b")
19
+ end
20
+
21
+ def test_int_to_splitted_path
22
+ assert_equal(Keystone::StringUtil.int_to_splitted_path(113355,12,"/tmp",".jpg"),"/tmp/000/000/113/355.jpg")
23
+ assert_equal(Keystone::StringUtil.int_to_splitted_path(1234567890,10,"/temp",".png"),"/temp/1/234/567/890.png")
24
+ assert_equal(Keystone::StringUtil.int_to_splitted_path(1234567890,11,"/temp",".png"),"/temp/01/234/567/890.png")
25
+ assert_raise(RangeError){Keystone::StringUtil.int_to_splitted_path(12345678901,10,"/tmp")}
26
+ assert_equal(Keystone::StringUtil.int_to_splitted_path(00000000000000001,11,"/tmp",".gif"),"/tmp/00/000/000/001.gif")
27
+ end
28
+
29
+ def test_serach_string_to_array
30
+ assert_equal(Keystone::StringUtil.serach_string_to_array(%|test test2 test3|),%w|test test2 test3|)
31
+ assert_equal(Keystone::StringUtil.serach_string_to_array(%|test "test2" test3|),%w|test test2 test3|)
32
+ assert_equal(Keystone::StringUtil.serach_string_to_array(%|test "test 2" test3|),["test","test 2","test3"])
33
+ assert_equal(Keystone::StringUtil.serach_string_to_array(%|"test 1" "test 2" test3|),["test 1","test 2","test3"])
34
+ assert_equal(Keystone::StringUtil.serach_string_to_array(%|"日本語 1" "test 2" test3|),["日本語 1","test 2","test3"])
35
+ assert_equal(Keystone::StringUtil.serach_string_to_array(%|"日本語 1" "test 2" ハンカク|),["日本語 1","test 2","ハンカク"])
36
+ # TODO
37
+ # assert_equal(Keystone::StringUtil.serach_string_to_array(%|"日本語 1" "tes\"t 2" ハンカク|),["日本語 1","test 2","ハンカク"])
38
+ end
39
+
40
+ def test_to_searchtext
41
+ assert_equal(Keystone::StringUtil.to_searchtext("日本語"),"日本語")
42
+ assert_equal(Keystone::StringUtil.to_searchtext("カタカナ"),"カタカナ")
43
+ assert_equal(Keystone::StringUtil.to_searchtext("ハンカク"),"ハンカク")
44
+ assert_equal(Keystone::StringUtil.to_searchtext("A"),"a")
45
+ assert_equal(Keystone::StringUtil.to_searchtext("1"),"1")
46
+ assert_equal(Keystone::StringUtil.to_searchtext("abCD1234"),"abcd1234")
47
+ assert_equal(Keystone::StringUtil.to_searchtext("スープ"),"スープ")
48
+ assert_equal(Keystone::StringUtil.to_searchtext("スープ"),"スープ") # ハンカク半濁点
49
+ assert_equal(Keystone::StringUtil.to_searchtext("コズミックラナウェイ"),"コズミックラナウェイ") # ハンカク濁点
50
+ assert_equal(Keystone::StringUtil.to_searchtext("句読点。、・/"),"句読点。、・/") # ??? ここおかしくない??
51
+ # TODO
52
+ assert_equal(Keystone::StringUtil.to_searchtext("!”$%&¥’()*+,-./:;<=>?@[¥]^_‘{|}~#"),"!\"$%&\\'()*+,-./:;<=>?@[\\]^_`{|}~#") # 半角全角変換可能記号
53
+ assert_equal(Keystone::StringUtil.to_searchtext("。「」、ー゙゚・"),"。「」、ー゛゜・")
54
+ assert_equal(Keystone::StringUtil.to_searchtext("ⅠⅡⅢⅣ"),"ⅰⅱⅲⅳ")
55
+ end
56
+ end
@@ -0,0 +1,121 @@
1
+ require "forwardable"
2
+
3
+
4
+ module FlagSetMaker
5
+
6
+
7
+ class FlagSet
8
+
9
+ def initialize(mod, names, zero= nil)
10
+ @module= mod
11
+ @flag_names= names.to_a()
12
+ @zero_name= zero
13
+ for i in 0...@flag_names.size
14
+ mod.const_set(@flag_names[i], Flags.new(1 << i, self))
15
+ end
16
+ mod.const_set(@zero_name, Flags.new(0, self)) if @zero_name
17
+ end
18
+
19
+ def to_s(v)
20
+ names= []
21
+ @flag_names.each_with_index(){ |name, i| names.push(name) if v[i]==1 }
22
+ if names.empty?()
23
+ return (@zero_name.to_s() || "0")
24
+ elsif names.size==1
25
+ return names[0].to_s()
26
+ else
27
+ return "("+names.join("|")+")"
28
+ end
29
+ end
30
+
31
+ def inspect(v= nil)
32
+ return v ? format("%p::%s", @module, to_s(v)) : super()
33
+ end
34
+
35
+ def validate(v)
36
+ return v&((1 << @flag_names.size)-1)
37
+ end
38
+
39
+ end
40
+
41
+
42
+ class Flags
43
+
44
+ extend(Forwardable)
45
+
46
+ def initialize(v, fs)
47
+ @value= fs.validate(v)
48
+ @flag_set= fs
49
+ end
50
+
51
+ def to_i()
52
+ return @value
53
+ end
54
+
55
+ def to_s()
56
+ return @flag_set.to_s(@value)
57
+ end
58
+
59
+ def inspect()
60
+ return @flag_set.inspect(@value)
61
+ end
62
+
63
+ def ==(rhs)
64
+ return rhs.is_a?(Flags) && @flag_set==rhs.flag_set && @value==rhs.to_i()
65
+ end
66
+
67
+ alias :eql? :==
68
+
69
+ def_delegators(:to_i, :hash)
70
+
71
+ def &(rhs)
72
+ return new_flag(@value&rhs.to_i())
73
+ end
74
+
75
+ def |(rhs)
76
+ return new_flag(@value|rhs.to_i())
77
+ end
78
+
79
+ def ~()
80
+ return new_flag(~@value)
81
+ end
82
+
83
+ def include?(flags)
84
+ return (@value&flags.to_i())==flags.to_i()
85
+ end
86
+
87
+ def empty?()
88
+ return @value!=0
89
+ end
90
+
91
+ protected
92
+
93
+ attr_reader(:flag_set)
94
+
95
+ private
96
+
97
+ def new_flag(v)
98
+ return Flags.new(v, @flag_set)
99
+ end
100
+
101
+ end
102
+
103
+
104
+ def make_flag_set(*args)
105
+ FlagSet.new(self, *args)
106
+ end
107
+
108
+ end
109
+
110
+
111
+ if __FILE__==$0
112
+
113
+ class Hoge
114
+
115
+ extend(FlagSetMaker)
116
+
117
+ make_flag_set([:FOO, :BAR, :HOGE], :NONE)
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,501 @@
1
+ #このファイルの文字コードはUTF-8です。
2
+ #このファイルをUnicode非対応のエディタで編集してはいけません(〜が文字化ける)。
3
+
4
+ =begin
5
+
6
+ =Moji モジュール
7
+
8
+ 日本語の文字種判定、文字種変換(半角→全角、ひらがな→カタカナなど)を行います。
9
+
10
+ ==インストール:
11
+
12
+ 解凍してできた moji ディレクトリの中で以下のコマンドを実行してください。
13
+
14
+ # ruby setup.rb
15
+
16
+ または、 moji/lib の中の moji.rb と flag_set_maker.rb を lib/ruby/site_ruby/1.8 にコピーしてください。
17
+
18
+ ==使い方:
19
+
20
+ (({$KCODE})) を指定してから (({require "moji"})) してください。
21
+ Moji モジュールの関数に渡す文字列の文字コードは (({$KCODE})) と一致させてください。
22
+
23
+ $KCODE= "UTF8"
24
+ require "moji"
25
+
26
+ #文字種判定。
27
+ p Moji.type("漢") # => Moji::ZEN_KANJI
28
+ p Moji.type?("A", Moji::ZEN) # => true
29
+
30
+ #文字種変換。
31
+ p Moji.zen_to_han("Ruby") # => "Ruby"
32
+ p Moji.upcase("Ruby") # => "RUBY"
33
+ p Moji.kata_to_hira("ルビー") # => "るびー"
34
+
35
+ #文字種による正規表現。
36
+ p /#{Moji.kata}+#{Moji.hira}+/ =~ "ぼくドラえもん" # => 6
37
+ p Regexp.last_match.to_s # => "ドラえもん"
38
+
39
+ ==定数:
40
+
41
+ 以下の定数は、文字種の一番細かい分類です。
42
+ (({Moji.type})) が返すのは、以下の定数のうちの1つです。
43
+
44
+ --- HAN_CONTROL
45
+ 制御文字。
46
+ --- HAN_ASYMBOL
47
+ ASCIIに含まれる半角記号。
48
+ --- HAN_JSYMBOL
49
+ JISに含まれるがASCIIには含まれない半角記号。
50
+ --- HAN_NUMBER
51
+ 半角数字。
52
+ --- HAN_UPPER
53
+ 半角アルファベット大文字。
54
+ --- HAN_LOWER
55
+ 半角アルファベット小文字。
56
+ --- HAN_KATA
57
+ 半角カタカナ。
58
+ --- ZEN_ASYMBOL
59
+ JISの全角記号のうち、ASCIIに対応する半角記号があるもの。
60
+ --- ZEN_JSYMBOL
61
+ JISの全角記号のうち、ASCIIに対応する半角記号がないもの。
62
+ --- ZEN_NUMBER
63
+ 全角数字。
64
+ --- ZEN_UPPER
65
+ 全角アルファベット大文字。
66
+ --- ZEN_LOWER
67
+ 全角アルファベット小文字。
68
+ --- ZEN_HIRA
69
+ ひらがな。
70
+ --- ZEN_KATA
71
+ 全角カタカナ。
72
+ --- ZEN_GREEK
73
+ ギリシャ文字。
74
+ --- ZEN_CYRILLIC
75
+ キリル文字。
76
+ --- ZEN_LINE
77
+ 罫線のかけら。
78
+ --- ZEN_KANJI
79
+ 漢字。
80
+
81
+ 以下の定数は、上の文字種の組み合わせと別名です。
82
+
83
+ --- HAN_SYMBOL
84
+ JISに含まれる半角記号。(({HAN_ASYMBOL | HAN_JSYMBOL}))
85
+ --- HAN_ALPHA
86
+ 半角アルファベット。(({HAN_UPPER | HAN_LOWER}))
87
+ --- HAN_ALNUM
88
+ 半角英数字。(({HAN_ALPHA | HAN_NUMBER}))
89
+ --- HAN
90
+ 全ての半角文字。(({HAN_CONTROL | HAN_SYMBOL | HAN_ALNUM | HAN_KATA}))
91
+ --- ZEN_SYMBOL
92
+ JISに含まれる全角記号。(({ZEN_ASYMBOL | ZEN_JSYMBOL}))
93
+ --- ZEN_ALPHA
94
+ 全角アルファベット。(({ZEN_UPPER | ZEN_LOWER}))
95
+ --- ZEN_ALNUM
96
+ 全角英数字。(({ZEN_ALPHA | ZEN_NUMBER}))
97
+ --- ZEN_KANA
98
+ 全角かな/カナ。(({ZEN_KATA | ZEN_HIRA}))
99
+ --- ZEN
100
+ JISに含まれる全ての全角文字。(({ZEN_SYMBOL | ZEN_ALNUM | ZEN_KANA | ZEN_GREEK | ZEN_CYRILLIC | ZEN_LINE | ZEN_KANJI}))
101
+ --- ASYMBOL
102
+ ASCIIに含まれる半角記号とその全角版。(({HAN_ASYMBOL | ZEN_ASYMBOL}))
103
+ --- JSYMBOL
104
+ JISに含まれるが (({ASYMBOL})) には含まれない全角/半角記号。(({HAN_JSYMBOL | ZEN_JSYMBOL}))
105
+ --- SYMBOL
106
+ JISに含まれる全ての全角/半角記号。(({HAN_SYMBOL | ZEN_SYMBOL}))
107
+ --- NUMBER
108
+ 全角/半角数字。(({HAN_NUMBER | ZEN_NUMBER}))
109
+ --- UPPER
110
+ 全角/半角アルファベット大文字。(({HAN_UPPER | ZEN_UPPER}))
111
+ --- LOWER
112
+ 全角/半角アルファベット小文字。(({HAN_LOWER | ZEN_LOWER}))
113
+ --- ALPHA
114
+ 全角/半角アルファベット。(({HAN_ALPHA | ZEN_ALPHA}))
115
+ --- ALNUM
116
+ 全角/半角英数字。(({HAN_ALNUM | ZEN_ALNUM}))
117
+ --- HIRA
118
+ (({ZEN_HIRA})) の別名。
119
+ --- KATA
120
+ 全角/半角カタカナ。(({HAN_KATA | ZEN_KATA}))
121
+ --- KANA
122
+ 全角/半角 かな/カナ。(({KATA | ZEN_HIRA}))
123
+ --- GREEK
124
+ (({ZEN_GREEK})) の別名。
125
+ --- CYRILLIC
126
+ (({ZEN_CYRILLIC})) の別名。
127
+ --- LINE
128
+ (({ZEN_LINE})) の別名。
129
+ --- KANJI
130
+ (({ZEN_KANJI})) の別名。
131
+ --- ALL
132
+ 上記全ての文字。
133
+
134
+ ==モジュール関数:
135
+
136
+ --- Moji.type(ch)
137
+
138
+ 文字 ((|ch|)) の文字種を返します。
139
+
140
+ 「一番細かい分類」の((<定数|定数:>))のうち1つを返します。
141
+
142
+ 上の分類に当てはまらない文字(Unicodeのハングルなど)に対しては (({nil})) を返します。
143
+ また、UnicodeのB面以降の文字に対しても (({nil})) を返します。
144
+
145
+ 文字が割り当てられていない文字コードに対する結果は不定です( (({nil})) を返す事もあります)。
146
+
147
+ p Moji.type("漢") # => Moji::ZEN_KANJI
148
+
149
+ --- Moji.type?(ch, type)
150
+
151
+ 文字 ((|ch|)) が文字種 ((|type|)) に含まれれば、 (({true})) を返します。
152
+
153
+ ((|type|)) には全ての((<定数|定数:>))と、それらを (({|}))
154
+ で結んだものを使えます。
155
+
156
+ p Moji.type?("A", Moji::ZEN) # => true
157
+
158
+ --- Moji.regexp(type)
159
+
160
+ 文字種 ((|type|)) の1文字を表す正規表現を返します。
161
+
162
+ ((|type|)) には全ての((<定数|定数:>))と、それらを (({|}))
163
+ で結んだものを使えます。
164
+
165
+ p Moji.regexp(Moji::HIRA) # => /[ぁ-ん]/
166
+
167
+ --- Moji.zen_to_han(str[, type])
168
+
169
+ 文字列 ((|str|)) の全角を半角に変換して返します。
170
+
171
+ ((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
172
+ デフォルトは (({ALL})) (全て)です。
173
+
174
+ p Moji.zen_to_han("Ruby!?") # => "Ruby!?"
175
+ p Moji.zen_to_han("Ruby!?", Moji::ALPHA) # => "Ruby!?"
176
+
177
+ --- Moji.han_to_zen(str[, type])
178
+
179
+ 文字列 ((|str|)) の半角を全角に変換して返します。
180
+
181
+ ((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
182
+ デフォルトは (({ALL})) (全て)です。
183
+
184
+ p Moji.han_to_zen("Ruby!?") # => "Ruby!?"
185
+ p Moji.han_to_zen("Ruby!?", Moji::SYMBOL) # => "Ruby!?"
186
+
187
+ --- Moji.normalize_zen_han(str)
188
+
189
+ 文字列 ((|str|)) の大文字、小文字を一般的なものに統一します。
190
+
191
+ 具体的には、ASCIIに含まれる記号と英数字( (({ALNUM|ASYMBOL}))
192
+ )を半角に、それ以外の記号とカタカナ( (({JSYMBOL|HAN_KATA})) )を全角に変換します。
193
+
194
+ --- Moji.upcase(str[, type])
195
+
196
+ 文字列 ((|str|)) の小文字を大文字に変換して返します。
197
+
198
+ ((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
199
+ デフォルトは (({LOWER})) (全角/半角のアルファベット)です。
200
+ ギリシャ文字、キリル文字には対応していません。
201
+
202
+ p Moji.upcase("Ruby") # => "RUBY"
203
+
204
+ --- Moji.downcase(str[, type])
205
+
206
+ 文字列 ((|str|)) の小文字を大文字に変換して返します。
207
+
208
+ ((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
209
+ デフォルトは (({UPPER})) (全角/半角のアルファベット)です。
210
+ ギリシャ文字、キリル文字には対応していません。
211
+
212
+ p Moji.downcase("Ruby") # => "ruby"
213
+
214
+ --- Moji.kata_to_hira(str)
215
+
216
+ 文字列 ((|str|)) の全角カタカナをひらがなに変換して返します。
217
+
218
+ 半角カタカナは直接変換できません。 (({han_to_zen})) で全角にしてから変換してください。
219
+
220
+ p Moji.kata_to_hira("ルビー") # => "るびー"
221
+
222
+ --- Moji.hira_to_kata(str)
223
+
224
+ 文字列 ((|str|)) のひらがなを全角カタカナに変換して返します。
225
+
226
+ p Moji.hira_to_kata("るびー") # => "ルビー"
227
+
228
+ --- Moji.han_control
229
+ --- Moji.han_asymbol
230
+ --- ...
231
+ --- Moji.kana
232
+ --- ...
233
+
234
+ ((<定数|定数:>))それぞれに対応するメソッドが有り、
235
+ それぞれの文字種の1文字を表す正規表現を返します。
236
+
237
+ 例えば、 (({Moji.kana})) は (({Moji.regexp(Moji::KANA)})) と同じです。
238
+
239
+ 以下の例のように、文字クラスっぽく使えます。
240
+ p /#{Moji.kata}+#{Moji.hira}+/ =~ "ぼくドラえもん" # => 6
241
+ p Regexp.last_match.to_s # => "ドラえもん"
242
+
243
+ ==動作環境:
244
+
245
+ たぶんRuby 1.8以降。
246
+
247
+ FreeBSD Ruby 1.8.5にて動作確認しました。
248
+
249
+ ==置き場所/連絡先:
250
+
251
+ 置き場所: ((<URL:http://gimite.ddo.jp/pukiwiki/index.php?Ruby%BE%AE%CA%AA%BD%B8>))
252
+
253
+ 作者: Gimite 市川 (連絡先: ((<URL:http://gimite.ddo.jp/bbs/tnote.cgi>)) )
254
+
255
+ ==ライセンス:
256
+
257
+ Public Domainです。煮るなり焼くなりご自由に。
258
+
259
+ ==更新履歴:
260
+
261
+ 2006/7/23 Ver.1.3
262
+ *半角中黒(・)の字種判別、全角中黒との相互変換ができていなかったのを修正。(thanks to xyzzyさん)
263
+
264
+ 2006/10/5 Ver.1.2
265
+ *EUC 以外の文字コードにも対応し、ライブラリ名を Moji に変更。
266
+ *han_to_zen, zen_to_han の対象文字種のデフォルトを全て( (({ALL})) )に。
267
+ *normalize_zen_han 追加。
268
+
269
+ 2005/1/3 Ver.1.1
270
+ *(({$KCODE})) が指定されていないとEUCUtil.typeが正常動作しない問題を修正。
271
+ *定数に (({ASYMBOL})) と (({JSYMBOL})) を追加。
272
+
273
+ 2004/11/16 Ver.1.0
274
+ *EUCUtil 公開。
275
+
276
+ =end
277
+
278
+
279
+ if $KCODE=="NONE"
280
+ warn("Warning: Set $KCODE before requiring 'moji' (UTF8 assumed)")
281
+ $KCODE= "u"
282
+ end
283
+
284
+ require "nkf"
285
+ require "jcode"
286
+ require "enumerator"
287
+ require "flag_set_maker"
288
+
289
+ nkf_kcode= {"SJIS" => "s", "EUC" => "e"}[$KCODE]
290
+
291
+ script= <<'EOS'
292
+
293
+
294
+ module Moji
295
+
296
+ extend(FlagSetMaker)
297
+
298
+ module Detail
299
+
300
+ HAN_ASYMBOL_LIST= ' !"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'
301
+ ZEN_ASYMBOL_LIST= ' !”#$%&’()*+,-./:;<=>?@[¥]^_‘{|} ̄'
302
+ HAN_JSYMBOL1_LIST= '。「」、ー゙゚・'
303
+ ZEN_JSYMBOL1_LIST= '。「」、ー゛゜・'
304
+ ZEN_JSYMBOL_LIST= '、。・゛゜´`¨ヽヾゝゞ〃仝々〆〇ー―‐\~〜∥…‥“〔〕〈〉《》「」『』【】'+
305
+ '±×÷≠≦≧∞∴♂♀°′″℃¢£§☆★○●◎◇◇◆□■△▲▽▼※〒→←↑↓〓'
306
+ HAN_KATA_LIST= 'ハヒフヘホウカキクケコサシスセソタチツテトアイエオナニヌネノマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ'.split(//)
307
+ HAN_VSYMBOLS= ['', '゙', '゚']
308
+ ZEN_KATA_LISTS= [
309
+ 'ハヒフヘホウカキクケコサシスセソタチツテトアイエオ'+
310
+ 'ナニヌネノマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ',
311
+ 'バビブベボヴガギグゲゴザジズゼゾダヂヅデド',
312
+ 'パピプペポ',
313
+ ].map(){ |s| s.split(//) }
314
+
315
+ end
316
+
317
+ def self.uni_range(*args)
318
+ if $KCODE=="UTF8"
319
+ str= args.map(){ |n| NKF.nkf("-wW160x", [n].pack("n")) }.
320
+ enum_slice(2).map(){ |f, e| "#{f}-#{e}" }.to_s()
321
+ return /[#{str}]/u
322
+ else
323
+ return nil
324
+ end
325
+ end
326
+
327
+ make_flag_set([
328
+ :HAN_CONTROL, :HAN_ASYMBOL, :HAN_JSYMBOL, :HAN_NUMBER, :HAN_UPPER, :HAN_LOWER, :HAN_KATA,
329
+ :ZEN_ASYMBOL, :ZEN_JSYMBOL, :ZEN_NUMBER, :ZEN_UPPER, :ZEN_LOWER, :ZEN_HIRA, :ZEN_KATA,
330
+ :ZEN_GREEK, :ZEN_CYRILLIC, :ZEN_LINE, :ZEN_KANJI,
331
+ ])
332
+
333
+ HAN_SYMBOL= HAN_ASYMBOL | HAN_JSYMBOL
334
+ HAN_ALPHA= HAN_UPPER | HAN_LOWER
335
+ HAN_ALNUM= HAN_ALPHA | HAN_NUMBER
336
+ HAN= HAN_CONTROL | HAN_SYMBOL | HAN_ALNUM | HAN_KATA
337
+ ZEN_SYMBOL= ZEN_ASYMBOL | ZEN_JSYMBOL
338
+ ZEN_ALPHA= ZEN_UPPER | ZEN_LOWER
339
+ ZEN_ALNUM= ZEN_ALPHA | ZEN_NUMBER
340
+ ZEN_KANA= ZEN_KATA | ZEN_HIRA
341
+ ZEN= ZEN_SYMBOL | ZEN_ALNUM | ZEN_KANA | ZEN_GREEK | ZEN_CYRILLIC | ZEN_LINE | ZEN_KANJI
342
+ ASYMBOL= HAN_ASYMBOL | ZEN_ASYMBOL
343
+ JSYMBOL= HAN_JSYMBOL | ZEN_JSYMBOL
344
+ SYMBOL= HAN_SYMBOL | ZEN_SYMBOL
345
+ NUMBER= HAN_NUMBER | ZEN_NUMBER
346
+ UPPER= HAN_UPPER | ZEN_UPPER
347
+ LOWER= HAN_LOWER | ZEN_LOWER
348
+ ALPHA= HAN_ALPHA | ZEN_ALPHA
349
+ ALNUM= HAN_ALNUM | ZEN_ALNUM
350
+ HIRA= ZEN_HIRA
351
+ KATA= HAN_KATA | ZEN_KATA
352
+ KANA= KATA | ZEN_HIRA
353
+ GREEK= ZEN_GREEK
354
+ CYRILLIC= ZEN_CYRILLIC
355
+ LINE= ZEN_LINE
356
+ KANJI= ZEN_KANJI
357
+ ALL= HAN | ZEN
358
+
359
+ CHAR_REGEXPS= {
360
+ HAN_CONTROL => /[\x00-\x1f\x7f]/,
361
+ HAN_ASYMBOL =>
362
+ Regexp.new("["+Detail::HAN_ASYMBOL_LIST.gsub(/[\[\]\-\^\\]/){ "\\"+$& }+"]"),
363
+ HAN_JSYMBOL => Regexp.new("["+Detail::HAN_JSYMBOL1_LIST+"]"),
364
+ HAN_NUMBER => /[0-9]/,
365
+ HAN_UPPER => /[A-Z]/,
366
+ HAN_LOWER => /[a-z]/,
367
+ HAN_KATA => /[ヲ-ッア-ン]/,
368
+ ZEN_ASYMBOL => Regexp.new("["+Detail::ZEN_ASYMBOL_LIST+"]"),
369
+ ZEN_JSYMBOL => Regexp.new("["+Detail::ZEN_JSYMBOL_LIST+"]"),
370
+ ZEN_NUMBER => /[0-9]/,
371
+ ZEN_UPPER => /[A-Z]/,
372
+ ZEN_LOWER => /[a-z]/,
373
+ ZEN_HIRA => /[ぁ-ん]/,
374
+ ZEN_KATA => /[ァ-ヶ]/,
375
+ ZEN_GREEK => /[Α-Ωα-ω]/,
376
+ ZEN_CYRILLIC => /[А-Яа-я]/,
377
+ ZEN_LINE => uni_range(0x2570, 0x25ff) || /[─-╂]/,
378
+ ZEN_KANJI => uni_range(0x3400, 0x9fff, 0xf900, 0xfaff) || /[亜-瑤]/,
379
+ }
380
+
381
+ def type(ch)
382
+ ch=~/^./
383
+ ch= $&
384
+ for tp, reg in CHAR_REGEXPS
385
+ return tp if ch=~reg
386
+ end
387
+ return nil
388
+ end
389
+
390
+ def type?(ch, tp)
391
+ return tp.include?(type(ch))
392
+ end
393
+
394
+ def regexp(tp)
395
+ regs= []
396
+ for tp2, reg in CHAR_REGEXPS
397
+ regs.push(reg) if tp.include?(tp2)
398
+ end
399
+ return regs.size==1 ? regs[0] : Regexp.new(regs.join("|"))
400
+ end
401
+
402
+ def zen_to_han(str, tp= ALL)
403
+ if tp.include?(ZEN_KATA)
404
+ reg= Regexp.new("["+Detail::ZEN_KATA_LISTS.to_s()+"]")
405
+ str= str.gsub(reg) do
406
+ for i in 0...3
407
+ pos= Detail::ZEN_KATA_LISTS[i].index($&)
408
+ break Detail::HAN_KATA_LIST[pos]+Detail::HAN_VSYMBOLS[i] if pos
409
+ end
410
+ end
411
+ end
412
+ str= str.tr("a-z", "a-z") if tp.include?(ZEN_LOWER)
413
+ str= str.tr("A-Z", "A-Z") if tp.include?(ZEN_UPPER)
414
+ str= str.tr("0-9", "0-9") if tp.include?(ZEN_NUMBER)
415
+ str= str.tr(Detail::ZEN_ASYMBOL_LIST,
416
+ Detail::HAN_ASYMBOL_LIST.gsub(/[\-\^\\]/){ "\\"+$& }) if tp.include?(ZEN_ASYMBOL)
417
+ str= str.tr(Detail::ZEN_JSYMBOL1_LIST,
418
+ Detail::HAN_JSYMBOL1_LIST) if tp.include?(ZEN_JSYMBOL)
419
+ return str
420
+ end
421
+
422
+ def han_to_zen(str, tp= ALL)
423
+ #[半]濁音記号がJSYMBOLに含まれるので、KATAの変換をJSYMBOLより前にやる必要あり。
424
+ if tp.include?(HAN_KATA)
425
+ str= str.gsub(/(#{han_kata})([゙゚]?)/) do
426
+ i= {""=>0, "゙"=>1, "゚"=>2}[$2]
427
+ pos= Detail::HAN_KATA_LIST.index($1)
428
+ s= Detail::ZEN_KATA_LISTS[i][pos]
429
+ (!s || s=="") ? Detail::ZEN_KATA_LISTS[0][pos]+$2 : s
430
+ end
431
+ end
432
+ str= str.tr("a-z", "a-z") if tp.include?(HAN_LOWER)
433
+ str= str.tr("A-Z", "A-Z") if tp.include?(HAN_UPPER)
434
+ str= str.tr("0-9", "0-9") if tp.include?(HAN_NUMBER)
435
+ str= str.tr(Detail::HAN_ASYMBOL_LIST.gsub(/[\-\^\\]/){ "\\"+$& },
436
+ Detail::ZEN_ASYMBOL_LIST) if tp.include?(HAN_ASYMBOL)
437
+ str= str.tr(Detail::HAN_JSYMBOL1_LIST,
438
+ Detail::ZEN_JSYMBOL1_LIST) if tp.include?(HAN_JSYMBOL)
439
+ return str
440
+ end
441
+
442
+ def normalize_zen_han(str)
443
+ return zen_to_han(han_to_zen(str, HAN_JSYMBOL|HAN_KATA), ZEN_ALNUM|ZEN_ASYMBOL)
444
+ end
445
+
446
+ def upcase(str, tp= LOWER)
447
+ str= str.tr("a-z", "A-Z") if tp.include?(HAN_LOWER)
448
+ str= str.tr("a-z", "A-Z") if tp.include?(ZEN_LOWER)
449
+ end
450
+
451
+ def downcase(str, tp= UPPER)
452
+ str= str.tr("A-Z", "a-z") if tp.include?(HAN_UPPER)
453
+ str= str.tr("A-Z", "a-z") if tp.include?(ZEN_UPPER)
454
+ end
455
+
456
+ def kata_to_hira(str)
457
+ return str.tr("ァ-ン", "ぁ-ん")
458
+ end
459
+
460
+ def hira_to_kata(str)
461
+ return str.tr("ぁ-ん", "ァ-ン")
462
+ end
463
+
464
+ module_function(
465
+ :type, :type?, :regexp, :zen_to_han, :han_to_zen, :normalize_zen_han, :upcase, :downcase,
466
+ :kata_to_hira, :hira_to_kata
467
+ )
468
+
469
+ def self.define_regexp_method(name, tp)
470
+ define_method(name){ regexp(tp) }
471
+ module_function(name)
472
+ end
473
+
474
+ #han_control, han_asymbol, …などのモジュール関数を定義。
475
+ for cons in constants
476
+ val= const_get(cons)
477
+ define_regexp_method(cons.downcase(), val) if val.is_a?(FlagSetMaker::Flags)
478
+ end
479
+
480
+ def self.test()
481
+ str= "ドラえもん(Doraemon)は、日本で1番有名な漫画だ。"
482
+ str.each_char() do |ch|
483
+ printf("%2s %s\n", ch, Moji.type(ch))
484
+ end
485
+ str= Moji.zen_to_han(str, Moji::ALL)
486
+ puts(str)
487
+ str= Moji.han_to_zen(str, Moji::ALL)
488
+ puts(str)
489
+ end
490
+
491
+ end
492
+
493
+ EOS
494
+
495
+ script= NKF.nkf("-#{nkf_kcode}Wx", script) if nkf_kcode
496
+ #UTF-8の場合、nkfしてはいけない(~が〜になるので)。
497
+ eval(script, TOPLEVEL_BINDING)
498
+
499
+ if __FILE__==$0
500
+ Moji.test()
501
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kanamei-kanamei-keystone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - kanamei
@@ -22,9 +22,21 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
+ - example/batch_sample.rb
26
+ - example/string_util.rb
27
+ - test/test_string_util.rb
25
28
  - lib/keystone
29
+ - lib/keystone/base.rb
30
+ - lib/keystone/batch_base.rb
31
+ - lib/keystone/core_ext.rb
32
+ - lib/keystone/environment.rb
33
+ - lib/keystone/mail
34
+ - lib/keystone/mail/send.rb
35
+ - lib/keystone/mail.rb
26
36
  - lib/keystone/string_util.rb
27
37
  - lib/keystone.rb
38
+ - vendor/flag_set_maker.rb
39
+ - vendor/moji.rb
28
40
  has_rdoc: false
29
41
  homepage: http://github.com/kanamei/keystone/tree/master
30
42
  post_install_message:
@@ -32,6 +44,9 @@ rdoc_options: []
32
44
 
33
45
  require_paths:
34
46
  - lib
47
+ - vendor
48
+ - example
49
+ - test
35
50
  required_ruby_version: !ruby/object:Gem::Requirement
36
51
  requirements:
37
52
  - - ">="