jpmobile 0.1.6 → 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/README +0 -0
  2. data/README.rdoc +58 -29
  3. data/Rakefile +1 -1
  4. data/VERSION.yml +4 -4
  5. data/lib/jpmobile.rb +3 -0
  6. data/lib/jpmobile/email.rb +17 -2
  7. data/lib/jpmobile/emoticon.rb +87 -23
  8. data/lib/jpmobile/emoticon/au.rb +644 -0
  9. data/lib/jpmobile/emoticon/softbank.rb +488 -0
  10. data/lib/jpmobile/emoticon/z_combine.rb +16 -13
  11. data/lib/jpmobile/hook_action_controller.rb +1 -13
  12. data/lib/jpmobile/hook_action_view.rb +3 -62
  13. data/lib/jpmobile/mail.rb +316 -0
  14. data/lib/jpmobile/mailer.rb +31 -0
  15. data/lib/jpmobile/mobile/abstract_mobile.rb +66 -0
  16. data/lib/jpmobile/mobile/au.rb +25 -2
  17. data/lib/jpmobile/mobile/docomo.rb +23 -1
  18. data/lib/jpmobile/mobile/emobile.rb +1 -1
  19. data/lib/jpmobile/mobile/softbank.rb +33 -1
  20. data/lib/jpmobile/mobile/vodafone.rb +1 -1
  21. data/lib/jpmobile/mobile/willcom.rb +1 -1
  22. data/lib/jpmobile/path_set.rb +40 -0
  23. data/lib/jpmobile/rails.rb +24 -0
  24. data/lib/jpmobile/resolver.rb +38 -0
  25. data/lib/jpmobile/util.rb +223 -14
  26. data/lib/tasks/jpmobile_tasks.rake +41 -48
  27. data/spec/rack/jpmobile/emoticon_spec.rb +3 -8
  28. data/spec/rack/jpmobile/filter_spec.rb +1 -1
  29. data/spec/rack/jpmobile/params_filter_spec.rb +4 -4
  30. data/spec/rack_helper.rb +5 -9
  31. data/spec/unit/detect_by_email_spec.rb +29 -0
  32. data/spec/unit/emoticon_spec.rb +90 -0
  33. data/spec/unit/encoding_spec.rb +102 -0
  34. data/spec/unit/mail_spec.rb +117 -0
  35. data/spec/unit/receive_mail_spec.rb +289 -0
  36. data/spec/unit/spec_helper.rb +8 -0
  37. data/spec/unit/util_spec.rb +5 -0
  38. data/test/rails/overrides/app/controllers/application_controller.rb +3 -2
  39. data/test/rails/overrides/app/controllers/template_path_controller.rb +8 -0
  40. data/test/rails/overrides/app/models/mobile_mailer.rb +19 -0
  41. data/test/rails/overrides/app/models/normal_mailer.rb +9 -0
  42. data/test/rails/overrides/spec/models/mobile_mailer_spec.rb +737 -0
  43. data/test/rails/overrides/spec/models/normal_mailer_spec.rb +34 -0
  44. data/test/rails/overrides/spec/requests/template_path_spec.rb +13 -7
  45. data/test/rails/overrides/spec/spec_helper.rb +6 -0
  46. data/test/rails/rails_root/app/controllers/application_controller.rb +3 -2
  47. data/test/rails/rails_root/app/controllers/template_path_controller.rb +8 -0
  48. data/test/rails/rails_root/app/models/mobile_mailer.rb +2 -1
  49. data/test/rails/rails_root/app/models/normal_mailer.rb +9 -0
  50. data/test/rails/rails_root/config/initializers/secret_token.rb +1 -1
  51. data/test/rails/rails_root/spec/models/mobile_mailer_spec.rb +73 -80
  52. data/test/rails/rails_root/spec/models/normal_mailer_spec.rb +34 -0
  53. data/test/rails/rails_root/spec/requests/template_path_spec.rb +13 -7
  54. data/test/rails/rails_root/spec/spec_helper.rb +1 -1
  55. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile.rb +2 -1
  56. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/emoticon.rb +7 -5
  57. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/hook_action_controller.rb +1 -13
  58. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/hook_action_view.rb +3 -62
  59. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/mail.rb +162 -111
  60. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/mailer.rb +31 -0
  61. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/mobile/abstract_mobile.rb +34 -3
  62. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/mobile/au.rb +2 -5
  63. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/mobile/docomo.rb +4 -5
  64. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/mobile/softbank.rb +7 -8
  65. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/path_set.rb +40 -0
  66. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/rack/params_filter.rb +1 -1
  67. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/rails.rb +24 -0
  68. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/resolver.rb +38 -0
  69. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/util.rb +33 -23
  70. metadata +43 -14
  71. data/test/legacy/emoticon_test.rb +0 -63
  72. data/test/legacy/helper.rb +0 -8
  73. data/test/rails/rails_root/vendor/plugins/jpmobile/lib/jpmobile/hook_action_mailer.rb +0 -22
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'jpmobile/mail'
3
+
4
+ module Jpmobile
5
+ module Mailer
6
+ class Base < ActionMailer::Base
7
+ self._view_paths = self._view_paths.dup
8
+ self.view_paths.unshift(Jpmobile::Resolver.new(File.join(::Rails.root, "app/views")))
9
+
10
+ def mail(headers={}, &block)
11
+ tos = headers[:to].split(/,/)
12
+
13
+ @mobile = if tos.size == 1
14
+ # for mobile
15
+ (Jpmobile::Email.detect(tos.first) || Jpmobile::Mobile::AbstractMobile).new(nil, nil)
16
+ else
17
+ # for multi to addresses
18
+ Jpmobile::Mobile::AbstractMobile.new(nil, nil)
19
+ end
20
+ self.lookup_context.mobile = @mobile.variants
21
+
22
+ m = super(headers, &block)
23
+
24
+ m.mobile = @mobile
25
+ m.charset = @mobile.mail_charset
26
+
27
+ m
28
+ end
29
+ end
30
+ end
31
+ end
@@ -4,6 +4,9 @@ require 'ipaddr'
4
4
  module Jpmobile::Mobile
5
5
  # 携帯電話の抽象クラス。
6
6
  class AbstractMobile
7
+ # メールのデフォルトのcharset
8
+ MAIL_CHARSET = "ISO-2022-JP"
9
+
7
10
  def initialize(env, request)
8
11
  @env = env
9
12
  @request = request
@@ -65,6 +68,69 @@ module Jpmobile::Mobile
65
68
  def default_charset
66
69
  "UTF-8"
67
70
  end
71
+
72
+ # for view selector
73
+ def variants
74
+ return @_variants if @_variants
75
+
76
+ @_variants = self.class.ancestors.select {|c| c.to_s =~ /^Jpmobile/}.map do |klass|
77
+ klass = klass.to_s.
78
+ gsub(/Jpmobile::/, '').
79
+ gsub(/AbstractMobile::/, '').
80
+ gsub(/Mobile::SmartPhone/, 'smart_phone').
81
+ gsub(/::/, '_').
82
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
83
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
84
+ downcase
85
+ klass =~ /abstract/ ? "mobile" : klass
86
+ end
87
+
88
+ if @_variants.include?("smart_phone")
89
+ @_variants = @_variants.reject{|v| v == "mobile"}.map{|v| v.gsub(/mobile/, "smart_phone")}
90
+ end
91
+
92
+ @_variants
93
+ end
94
+
95
+ # メール送信用
96
+ def to_mail_subject(str)
97
+ "=?#{mail_charset}?B?" + [to_mail_encoding(str)].pack('m').strip + "?="
98
+ end
99
+ def to_mail_body(str)
100
+ to_mail_encoding(str)
101
+ end
102
+ def mail_charset(charset = nil)
103
+ (charset.nil? or charset == "") ? self.class::MAIL_CHARSET : charset
104
+ end
105
+ def to_mail_encoding(str)
106
+ str = Jpmobile::Emoticon.unicodecr_to_external(str, Jpmobile::Emoticon::CONVERSION_TABLE_TO_PC_EMAIL, false)
107
+ Jpmobile::Util.encode(str, mail_charset)
108
+ end
109
+ def utf8_to_mail_encode(str)
110
+ case mail_charset
111
+ when /ISO-2022-JP/i
112
+ Jpmobile::Util.utf8_to_jis(str)
113
+ when /Shift_JIS/i
114
+ Jpmobile::Util.utf8_to_sjis(str)
115
+ else
116
+ str
117
+ end
118
+ end
119
+ def to_mail_internal(str, charset)
120
+ str
121
+ end
122
+ def to_mail_subject_encoded?(str)
123
+ str.match(/\=\?#{mail_charset}\?B.+\?\=/i)
124
+ end
125
+ def to_mail_body_encoded?(str)
126
+ Jpmobile::Util.jis?(str)
127
+ end
128
+ def decode_transfer_encoding(body, charset)
129
+ body = Jpmobile::Util.set_encoding(body, charset)
130
+ body = to_mail_internal(body, nil)
131
+ Jpmobile::Util.force_encode(body, charset, Jpmobile::Util::UTF8)
132
+ end
133
+
68
134
  # リクエストがこのクラスに属するか調べる
69
135
  # メソッド名に関して非常に不安
70
136
  def self.check_carrier(env)
@@ -9,7 +9,7 @@ module Jpmobile::Mobile
9
9
  # User-Agent文字列中に "UP.Browser" を含むVodafoneの端末があるので注意が必要
10
10
  USER_AGENT_REGEXP = /^(?:KDDI|UP.Browser\/.+?)-(.+?) /
11
11
  # 対応するメールアドレスの正規表現
12
- MAIL_ADDRESS_REGEXP = /^.+@ezweb\.ne\.jp$/
12
+ MAIL_ADDRESS_REGEXP = /.+@ezweb\.ne\.jp/
13
13
  # 簡易位置情報取得に対応していないデバイスID
14
14
  # http://www.au.kddi.com/ezfactory/tec/spec/eznavi.html
15
15
  LOCATION_UNSUPPORTED_DEVICE_ID = ["PT21", "TS25", "KCTE", "TST9", "KCU1", "SYT5", "KCTD", "TST8", "TST7", "KCTC", "SYT4", "KCTB", "KCTA", "TST6", "KCT9", "TST5", "TST4", "KCT8", "SYT3", "KCT7", "MIT1", "MAT3", "KCT6", "TST3", "KCT5", "KCT4", "SYT2", "MAT1", "MAT2", "TST2", "KCT3", "KCT2", "KCT1", "TST1", "SYT1"]
@@ -86,7 +86,6 @@ module Jpmobile::Mobile
86
86
  str = Jpmobile::Util.sjis_to_utf8(str)
87
87
  # 数値参照を UTF-8 に変換
88
88
  Jpmobile::Emoticon::unicodecr_to_utf8(str)
89
- # 半角->全角変換
90
89
  end
91
90
  def to_external(str, content_type, charset)
92
91
  # UTF-8を数値参照に
@@ -104,5 +103,29 @@ module Jpmobile::Mobile
104
103
  def default_charset
105
104
  "Shift_JIS"
106
105
  end
106
+
107
+ # メール送信用
108
+ def to_mail_subject(str)
109
+ "=?#{mail_charset}?B?" + [to_mail_encoding(str)].pack('m').strip + "?="
110
+ end
111
+ def to_mail_body(str)
112
+ to_mail_encoding(str)
113
+ end
114
+
115
+ def to_mail_internal(str, charset)
116
+ if Jpmobile::Util.jis?(str) or Jpmobile::Util.ascii_8bit?(str) or charset == mail_charset
117
+ # 絵文字を数値参照に変換
118
+ str = Jpmobile::Emoticon.external_to_unicodecr_au_mail(Jpmobile::Util.jis(str))
119
+ str = Jpmobile::Util.jis_to_utf8(Jpmobile::Util.jis(str))
120
+ end
121
+ str
122
+ end
123
+
124
+ private
125
+ def to_mail_encoding(str)
126
+ str = Jpmobile::Emoticon.utf8_to_unicodecr(str)
127
+ str = Jpmobile::Util.utf8_to_jis(str)
128
+ Jpmobile::Util.jis(Jpmobile::Emoticon.unicodecr_to_au_email(str))
129
+ end
107
130
  end
108
131
  end
@@ -7,7 +7,9 @@ module Jpmobile::Mobile
7
7
  # 対応するUser-Agentの正規表現
8
8
  USER_AGENT_REGEXP = /^DoCoMo/
9
9
  # 対応するメールアドレスの正規表現
10
- MAIL_ADDRESS_REGEXP = /^.+@docomo\.ne\.jp$/
10
+ MAIL_ADDRESS_REGEXP = /.+@docomo\.ne\.jp/
11
+ # メールのデフォルトのcharset
12
+ MAIL_CHARSET = "Shift_JIS"
11
13
 
12
14
  # オープンiエリアがあればエリアコードを +String+ で返す。無ければ +nil+ を返す。
13
15
  def areacode
@@ -94,6 +96,26 @@ module Jpmobile::Mobile
94
96
  "Shift_JIS"
95
97
  end
96
98
 
99
+ # メール送信用
100
+ def to_mail_subject(str)
101
+ str = to_external(str, nil, nil).first
102
+ "=?#{mail_charset}?B?" + [str].pack('m').strip + "?="
103
+ end
104
+ def to_mail_body(str)
105
+ to_external(str, nil, nil).first
106
+ end
107
+ def to_mail_internal(str, charset)
108
+ if Jpmobile::Util.shift_jis?(str) or Jpmobile::Util.ascii_8bit?(str) or charset == mail_charset
109
+ # 絵文字を数値参照に変換
110
+ str = Jpmobile::Emoticon.external_to_unicodecr_docomo(Jpmobile::Util.sjis(str))
111
+ end
112
+
113
+ str
114
+ end
115
+ def to_mail_body_encoded?(str)
116
+ Jpmobile::Util.shift_jis?(str)
117
+ end
118
+
97
119
  # i-mode ブラウザのバージョンを返す。
98
120
  # http://labs.unoh.net/2009/07/i_20.html
99
121
  def imode_browser_version
@@ -6,7 +6,7 @@ module Jpmobile::Mobile
6
6
  class Emobile < AbstractMobile
7
7
  USER_AGENT_REGEXP = %r{^emobile/|^Mozilla/5.0 \(H11T; like Gecko; OpenBrowser\) NetFront/3.4$|^Mozilla/4.0 \(compatible; MSIE 6.0; Windows CE; IEMobile 7.7\) S11HT$}
8
8
  # 対応するメールアドレスの正規表現
9
- MAIL_ADDRESS_REGEXP = /^.+@emnet\.ne\.jp$/
9
+ MAIL_ADDRESS_REGEXP = /.+@emnet\.ne\.jp/
10
10
  # EMnet対応端末から通知されるユニークなユーザIDを取得する。
11
11
  def em_uid
12
12
  @request.env['HTTP_X_EM_UID']
@@ -8,7 +8,9 @@ module Jpmobile::Mobile
8
8
  # 対応するuser-agentの正規表現
9
9
  USER_AGENT_REGEXP = /^(?:SoftBank|Semulator)/
10
10
  # 対応するメールアドレスの正規表現 ディズニーモバイル対応
11
- MAIL_ADDRESS_REGEXP = /^.+@(?:softbank\.ne\.jp|disney\.ne\.jp)$/
11
+ MAIL_ADDRESS_REGEXP = /.+@(?:softbank\.ne\.jp|disney\.ne\.jp)/
12
+ # メールのデフォルトのcharset
13
+ MAIL_CHARSET = "Shift_JIS"
12
14
 
13
15
  # 製造番号を返す。無ければ +nil+ を返す。
14
16
  def serial_number
@@ -58,5 +60,35 @@ module Jpmobile::Mobile
58
60
 
59
61
  [str, charset]
60
62
  end
63
+
64
+ # メール送信用
65
+ def to_mail_subject(str)
66
+ "=?#{mail_charset}?B?" + [to_mail_encoding(str)].pack('m').strip + "?="
67
+ end
68
+ def to_mail_body(str)
69
+ to_mail_encoding(str)
70
+ end
71
+ def to_mail_internal(str, charset)
72
+ # 絵文字を数値参照に変換
73
+ if Jpmobile::Util.utf8?(str) or charset == "UTF-8"
74
+ # UTF-8
75
+ str = Jpmobile::Emoticon.external_to_unicodecr_softbank(Jpmobile::Util.utf8(str))
76
+ elsif Jpmobile::Util.shift_jis?(str) or Jpmobile::Util.ascii_8bit?(str) or charset == mail_charset
77
+ # Shift_JIS
78
+ str = Jpmobile::Emoticon.external_to_unicodecr_softbank_sjis(Jpmobile::Util.sjis(str))
79
+ end
80
+
81
+ str
82
+ end
83
+ def to_mail_body_encoded?(str)
84
+ Jpmobile::Util.shift_jis?(str)
85
+ end
86
+
87
+ private
88
+ def to_mail_encoding(str)
89
+ str = Jpmobile::Emoticon.utf8_to_unicodecr(str)
90
+ str = Jpmobile::Util.utf8_to_sjis(str)
91
+ Jpmobile::Emoticon.unicodecr_to_softbank_email(str)
92
+ end
61
93
  end
62
94
  end
@@ -7,7 +7,7 @@ module Jpmobile::Mobile
7
7
  # 対応するUser-Agentの正規表現
8
8
  USER_AGENT_REGEXP = /^(Vodafone|Vemulator)/
9
9
  # 対応するメールアドレスの正規表現
10
- MAIL_ADDRESS_REGEXP = /^.+@[dhtcrknsq]\.vodafone\.ne\.jp$/
10
+ MAIL_ADDRESS_REGEXP = /.+@[dhtcrknsq]\.vodafone\.ne\.jp/
11
11
 
12
12
  # cookieに対応しているか?
13
13
  def supports_cookie?
@@ -7,7 +7,7 @@ module Jpmobile::Mobile
7
7
  # 対応するUser-Agentの正規表現
8
8
  USER_AGENT_REGEXP = /^Mozilla\/3.0\(WILLCOM/
9
9
  # 対応するメールアドレスの正規表現
10
- MAIL_ADDRESS_REGEXP = /^.+@(.+\.)?pdx\.ne\.jp$/
10
+ MAIL_ADDRESS_REGEXP = /.+@((.+\.)?pdx\.ne\.jp|willcom\.com)/
11
11
 
12
12
  # 位置情報があれば Position のインスタンスを返す。無ければ +nil+ を返す。
13
13
  def position
@@ -0,0 +1,40 @@
1
+ module Jpmobile
2
+ class PathSet < Array
3
+ %w(initialize << concat insert push unshift).each do |method|
4
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
5
+ def #{method}(*args)
6
+ super
7
+ typecast!
8
+ end
9
+ METHOD
10
+ end
11
+
12
+ def find(path, prefix = nil, partial = false, details = {}, key = nil)
13
+ template = find_all(path, prefix, partial, details, key).first
14
+ raise MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) unless template
15
+ template
16
+ end
17
+
18
+ def find_all(*args)
19
+ each do |resolver|
20
+ templates = resolver.find_all(*args)
21
+ return templates unless templates.empty?
22
+ end
23
+ []
24
+ end
25
+
26
+ def exists?(*args)
27
+ find_all(*args).any?
28
+ end
29
+
30
+ protected
31
+
32
+ def typecast!
33
+ each_with_index do |path, i|
34
+ path = path.to_s if path.is_a?(Pathname)
35
+ next unless path.is_a?(String)
36
+ self[i] = Jpmobile::Resolver.new(path)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -21,3 +21,27 @@ ActiveSupport.on_load(:before_configuration) do
21
21
  end
22
22
  end
23
23
  end
24
+
25
+ module Jpmobile
26
+ module ViewSelector
27
+ def self.included(base)
28
+ base.class_eval do
29
+ before_filter :register_mobile
30
+
31
+ self._view_paths = self._view_paths.dup
32
+ self.view_paths.unshift(Jpmobile::Resolver.new(File.join(Rails.root, "app/views")))
33
+ end
34
+ end
35
+
36
+ def register_mobile
37
+ if request.mobile
38
+ # register mobile
39
+ self.lookup_context.mobile = request.mobile.variants
40
+ end
41
+ end
42
+
43
+ def disable_mobile_view!
44
+ self.lookup_context.mobile = nil
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ module Jpmobile
2
+ class Resolver < ActionView::FileSystemResolver
3
+ # EXTENSION_ORDER = [:variants, :locale, :formats, :handlers]
4
+
5
+ def find_templates(name, prefix, partial, details)
6
+ path = build_path(name, prefix, partial, details)
7
+ query(path, EXTENSION_ORDER.map { |ext| details[ext] }, details[:formats], details[:mobile])
8
+ end
9
+
10
+ def build_path(name, prefix, partial, details)
11
+ path = ""
12
+ path << "#{prefix}/" unless prefix.empty?
13
+ path << (partial ? "_#{name}" : name)
14
+ path
15
+ end
16
+
17
+ def query(path, exts, formats, mobile)
18
+ query = File.join(@path, path)
19
+ query << '{' << mobile.map {|v| "_#{v}"}.join(',') << ',}' if mobile and mobile.respond_to?(:map)
20
+
21
+ exts.each do |ext|
22
+ query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << ',}'
23
+ end
24
+
25
+ query.gsub!(/\{\.html,/, "{.html,.text.html,")
26
+ query.gsub!(/\{\.text,/, "{.text,.text.plain,")
27
+
28
+ Dir[query].reject { |p| File.directory?(p) }.map do |p|
29
+ handler, format = extract_handler_and_format(p, formats)
30
+
31
+ contents = File.open(p, "rb") {|io| io.read }
32
+
33
+ ActionView::Template.new(contents, File.expand_path(p), handler,
34
+ :virtual_path => path, :format => format)
35
+ end
36
+ end
37
+ end
38
+ end
data/lib/jpmobile/util.rb CHANGED
@@ -1,6 +1,16 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'tempfile'
2
3
  module Jpmobile
3
4
  module Util
5
+ # SJIS = "Shift_JIS"
6
+ SJIS = "Windows-31J"
7
+ UTF8 = "UTF-8"
8
+ JIS = "ISO-2022-JP"
9
+ BINARY = "ASCII-8BIT"
10
+
11
+ WAVE_DASH = [0x301c].pack("U")
12
+ FULLWIDTH_TILDE = [0xff5e].pack("U")
13
+
4
14
  module_function
5
15
  def deep_apply(obj, &proc)
6
16
  case obj
@@ -44,40 +54,69 @@ module Jpmobile
44
54
  new_obj
45
55
  end
46
56
 
47
- def sjis(ascii_8bit)
48
- if ascii_8bit.respond_to?(:force_encoding)
49
- ascii_8bit.force_encoding("Shift_JIS")
57
+ def sjis(str)
58
+ if str.respond_to?(:force_encoding) and !shift_jis?(str)
59
+ str.force_encoding(SJIS)
60
+ end
61
+ str
62
+ end
63
+
64
+ def utf8(str)
65
+ if str.respond_to?(:force_encoding) and !utf8?(str)
66
+ str.force_encoding(UTF8)
50
67
  end
51
- ascii_8bit
68
+ str
52
69
  end
53
70
 
54
- def utf8(ascii_8bit)
55
- if ascii_8bit.respond_to?(:force_encoding)
56
- ascii_8bit.force_encoding("utf-8")
71
+ def jis(str)
72
+ if str.respond_to?(:force_encoding) and !jis?(str)
73
+ str.force_encoding(JIS)
57
74
  end
58
- ascii_8bit
75
+ str
59
76
  end
60
77
 
61
78
  def ascii_8bit(str)
62
- if str.respond_to?(:force_encoding)
63
- str.force_encoding("ASCII-8BIT")
79
+ if str.respond_to?(:force_encoding) and !ascii_8bit?(str)
80
+ str.force_encoding(BINARY)
64
81
  end
65
82
  str
66
83
  end
67
84
 
68
85
  def utf8_to_sjis(utf8_str)
86
+ # 波ダッシュ対策
87
+ utf8_str = wavedash_to_fullwidth_tilde(utf8_str)
88
+
69
89
  if utf8_str.respond_to?(:encode)
70
- utf8_str.encode("Shift_JIS", :crlf_newline => true)
90
+ utf8_str.encode(SJIS, :crlf_newline => true)
71
91
  else
72
92
  NKF.nkf("-m0 -x -W --oc=cp932", utf8_str).gsub(/\n/, "\r\n")
73
93
  end
74
94
  end
75
95
 
76
96
  def sjis_to_utf8(sjis_str)
77
- if sjis_str.respond_to?(:encode)
78
- sjis_str.encode("UTF-8", :universal_newline => true)
97
+ utf8_str = if sjis_str.respond_to?(:encode)
98
+ sjis_str.encode("UTF-8", :universal_newline => true)
99
+ else
100
+ NKF.nkf("-m0 -x -w --ic=cp932", sjis_str).gsub(/\r\n/, "\n")
101
+ end
102
+
103
+ # 波ダッシュ対策
104
+ fullwidth_tilde_to_wavedash(utf8_str)
105
+ end
106
+
107
+ def utf8_to_jis(utf8_str)
108
+ if utf8_str.respond_to?(:encode)
109
+ utf8_str.encode(JIS, :crlf_newline => true)
110
+ else
111
+ NKF.nkf("-m0 -x -Wj", utf8_str).gsub(/\n/, "\r\n")
112
+ end
113
+ end
114
+
115
+ def jis_to_utf8(jis_str)
116
+ if jis_str.respond_to?(:encode)
117
+ jis_str.encode(UTF8, :universal_newline => true)
79
118
  else
80
- NKF.nkf("-m0 -x -w --ic=cp932", sjis_str).gsub(/\r\n/, "\n")
119
+ NKF.nkf("-m0 -x -Jw", jis_str).gsub(/\r\n/, "\n")
81
120
  end
82
121
  end
83
122
 
@@ -89,11 +128,181 @@ module Jpmobile
89
128
  end
90
129
  end
91
130
 
131
+ def regexp_to_sjis(sjis_str)
132
+ if Object.const_defined?(:Encoding)
133
+ Regexp.compile(Regexp.escape(sjis(sjis_str)))
134
+ else
135
+ Regexp.compile(Regexp.escape(sjis_str,"s"),nil,'s')
136
+ end
137
+ end
138
+
92
139
  def hash_to_utf8(hash)
93
140
  new_hash = {}
94
141
  hash.each do |keu, value|
95
142
  new_hash[utf8(key)] = utf8(value)
96
143
  end
97
144
  end
145
+
146
+ def sjis_regexp(sjis)
147
+ sjis_str = sjis.kind_of?(Numeric) ? [sjis].pack('n') : sjis
148
+
149
+ if Object.const_defined?(:Encoding)
150
+ Regexp.compile(Regexp.escape(sjis_str.force_encoding(SJIS)))
151
+ else
152
+ Regexp.compile(Regexp.escape(sjis_str,"s"),nil,'s')
153
+ end
154
+ end
155
+
156
+ def jis_regexp(jis)
157
+ jis_str = jis.kind_of?(Numeric) ? [jis].pack('n') : jis
158
+
159
+ if Object.const_defined?(:Encoding)
160
+ # Regexp.compile(Regexp.escape(jis_str.force_encoding("stateless-ISO-2022-JP-KDDI"))) # for au only
161
+ Regexp.compile(Regexp.escape(jis_str.force_encoding(BINARY))) # for au only
162
+ else
163
+ Regexp.compile(Regexp.escape(jis_str,"j"),nil,'j')
164
+ end
165
+ end
166
+
167
+ def jis_string_regexp
168
+ Regexp.compile(Regexp.escape(ascii_8bit("\x1b\x24\x42")) + "(.+)" + Regexp.escape(ascii_8bit("\x1b\x28\x42")))
169
+ end
170
+
171
+ def encode(str, charset)
172
+ if Object.const_defined?(:Encoding)
173
+ (charset.nil? or charset == "" or str.nil? or str == "") ? str : str.encode(charset)
174
+ else
175
+ if str.nil?
176
+ str
177
+ else
178
+ case charset
179
+ when /iso-2022-jp/i
180
+ NKF.nkf("-j", str)
181
+ when /shift_jis/i
182
+ NKF.nkf("-s", str)
183
+ when /utf-8/i
184
+ NKF.nkf("-w", str)
185
+ else
186
+ str
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ def wavedash_to_fullwidth_tilde(utf8_str)
193
+ utf8_str.gsub(WAVE_DASH, FULLWIDTH_TILDE)
194
+ end
195
+
196
+ def fullwidth_tilde_to_wavedash(utf8_str)
197
+ utf8_str.gsub(FULLWIDTH_TILDE, WAVE_DASH)
198
+ end
199
+
200
+ def force_encode(str, from, to)
201
+ s = str.dup
202
+ return str if detect_encoding(str) == to
203
+
204
+ if Object.const_defined?(:Encoding)
205
+ to = SJIS if to =~ /shift_jis/i
206
+
207
+ to_enc = ::Encoding.find(to)
208
+ return str if s.encoding == to_enc
209
+
210
+ if from
211
+ from_enc = ::Encoding.find(from)
212
+ s.force_encoding(from) unless s.encoding == from_enc
213
+ end
214
+
215
+ s.encode(to)
216
+ else
217
+ opt = []
218
+ opt << case from
219
+ when /iso-2022-jp/i
220
+ "-Jx"
221
+ when /shift_jis/i
222
+ "-Sx"
223
+ when /utf-8/i
224
+ "-Wx"
225
+ else
226
+ ""
227
+ end
228
+ opt << case to
229
+ when /iso-2022-jp/i
230
+ "-j"
231
+ when /shift_jis/i, /windows_31j/i
232
+ "-s"
233
+ when /utf-8/i
234
+ "-w"
235
+ else
236
+ ""
237
+ end
238
+ NKF.nkf(opt.join(" "), str)
239
+ end
240
+ end
241
+
242
+ def set_encoding(str, encoding)
243
+ if encoding and Object.const_defined?(:Encoding)
244
+ encoding = SJIS if encoding =~ /shift_jis/i
245
+
246
+ str.force_encoding(encoding)
247
+ end
248
+
249
+ str
250
+ end
251
+
252
+ def extract_charset(str)
253
+ case str
254
+ when /iso-2022-jp/i
255
+ "ISO-2022-JP"
256
+ when /shift_jis/i
257
+ "Shift_JIS"
258
+ when /utf-8/i
259
+ "UTF-8"
260
+ else
261
+ ""
262
+ end
263
+ end
264
+
265
+ def detect_encoding(str)
266
+ if Object.const_defined?(:Encoding)
267
+ case str.encoding
268
+ when ::Encoding::ISO2022_JP
269
+ JIS
270
+ when ::Encoding::Shift_JIS, ::Encoding::Windows_31J, ::Encoding::CP932
271
+ SJIS
272
+ when ::Encoding::UTF_8
273
+ UTF8
274
+ when ::Encoding::ASCII_8BIT
275
+ BINARY
276
+ else
277
+ BINARY
278
+ end
279
+ else
280
+ case NKF.guess(str)
281
+ when NKF::SJIS
282
+ SJIS
283
+ when NKF::JIS
284
+ JIS
285
+ when NKF::UTF8
286
+ UTF8
287
+ when NKF::BINARY
288
+ BINARY
289
+ else
290
+ BINARY
291
+ end
292
+ end
293
+ end
294
+
295
+ def ascii_8bit?(str)
296
+ detect_encoding(str) == BINARY
297
+ end
298
+ def utf8?(str)
299
+ detect_encoding(str) == UTF8
300
+ end
301
+ def shift_jis?(str)
302
+ detect_encoding(str) == SJIS
303
+ end
304
+ def jis?(str)
305
+ detect_encoding(str) == JIS
306
+ end
98
307
  end
99
308
  end