rack-ketai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/.gitignore +1 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README.rdoc +122 -0
  4. data/VERSION +1 -0
  5. data/lib/rack/ketai/carrier/abstract.rb +263 -0
  6. data/lib/rack/ketai/carrier/au.rb +153 -0
  7. data/lib/rack/ketai/carrier/cidrs/au.rb +32 -0
  8. data/lib/rack/ketai/carrier/cidrs/docomo.rb +14 -0
  9. data/lib/rack/ketai/carrier/cidrs/softbank.rb +10 -0
  10. data/lib/rack/ketai/carrier/docomo.rb +157 -0
  11. data/lib/rack/ketai/carrier/emoji/ausjisstrtoemojiid.rb +1391 -0
  12. data/lib/rack/ketai/carrier/emoji/docomosjisstrtoemojiid.rb +759 -0
  13. data/lib/rack/ketai/carrier/emoji/emojidata.rb +836 -0
  14. data/lib/rack/ketai/carrier/emoji/emojiidtotypecast.rb +432 -0
  15. data/lib/rack/ketai/carrier/emoji/softbankutf8strtoemojiid.rb +1119 -0
  16. data/lib/rack/ketai/carrier/emoji/softbankwebcodetoutf8str.rb +499 -0
  17. data/lib/rack/ketai/carrier/general.rb +75 -0
  18. data/lib/rack/ketai/carrier/iphone.rb +16 -0
  19. data/lib/rack/ketai/carrier/softbank.rb +144 -0
  20. data/lib/rack/ketai/carrier/specs/au.rb +1 -0
  21. data/lib/rack/ketai/carrier/specs/docomo.rb +1 -0
  22. data/lib/rack/ketai/carrier/specs/softbank.rb +1 -0
  23. data/lib/rack/ketai/carrier.rb +18 -0
  24. data/lib/rack/ketai/display.rb +16 -0
  25. data/lib/rack/ketai/middleware.rb +36 -0
  26. data/lib/rack/ketai.rb +12 -0
  27. data/spec/spec_helper.rb +11 -0
  28. data/spec/unit/au_filter_spec.rb +96 -0
  29. data/spec/unit/au_spec.rb +240 -0
  30. data/spec/unit/carrier_spec.rb +30 -0
  31. data/spec/unit/display_spec.rb +25 -0
  32. data/spec/unit/docomo_filter_spec.rb +106 -0
  33. data/spec/unit/docomo_spec.rb +344 -0
  34. data/spec/unit/emoticon_filter_spec.rb +91 -0
  35. data/spec/unit/filter_spec.rb +38 -0
  36. data/spec/unit/iphone_spec.rb +16 -0
  37. data/spec/unit/middleware_spec.rb +38 -0
  38. data/spec/unit/softbank_filter_spec.rb +133 -0
  39. data/spec/unit/softbank_spec.rb +200 -0
  40. data/spec/unit/valid_addr_spec.rb +86 -0
  41. data/test/spec_runner.rb +29 -0
  42. data/tools/generate_emoji_dic.rb +434 -0
  43. data/tools/update_speclist.rb +87 -0
  44. metadata +138 -0
@@ -0,0 +1,157 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'scanf'
4
+
5
+ module Rack::Ketai::Carrier
6
+ class Docomo < Abstract
7
+ autoload :CIDRS, 'rack/ketai/carrier/cidrs/docomo'
8
+ autoload :SPECS, 'rack/ketai/carrier/specs/docomo'
9
+
10
+ USER_AGENT_REGEXP = /^DoCoMo/
11
+
12
+ class Filter < ::Rack::Ketai::Carrier::Abstract::SjisFilter
13
+
14
+ # 絵文字コード -> 絵文字ID 対応表から、絵文字コード検出用の正規表現をつくる
15
+ # 複数の絵文字の組み合わせのものを前におくことで
16
+ # そっちを優先的にマッチさせる
17
+ def Filter.sjis_regexp
18
+ @sjis_regexp ||=
19
+ if RUBY_VERSION >= '1.9.1'
20
+ codes = EMOJI_TO_EMOJIID.keys.sort_by{ |codes| - codes.size }.collect{ |sjis| Regexp.escape(sjis)}
21
+ Regexp.new(codes.join('|'), nil)
22
+ else
23
+ codes = EMOJI_TO_EMOJIID.keys.sort_by{ |codes| - codes.size }.collect{ |sjis| Regexp.escape(sjis, 's') }
24
+ Regexp.new(codes.join('|'), nil, 's')
25
+ end
26
+ end
27
+
28
+ private
29
+ def to_internal(env)
30
+ # ドコモSJISバイナリ -> 絵文字ID表記
31
+ request = Rack::Request.new(env)
32
+
33
+ request.params # 最低でも1回呼んでないと query_stringが未設定
34
+
35
+ converter = lambda do |value|
36
+ value.force_encoding('Shift_JIS') if value.respond_to?(:force_encoding)
37
+ value.gsub(Filter.sjis_regexp) do |match|
38
+ format("[e:%03X]", EMOJI_TO_EMOJIID[match])
39
+ end
40
+ end
41
+ deep_apply(request.env["rack.request.query_hash"], &converter)
42
+ deep_apply(request.env["rack.request.form_hash"], &converter)
43
+
44
+ # 文字コード変換
45
+ super(request.env)
46
+ end
47
+
48
+ def to_external(status, headers, body)
49
+ status, headers, body = super
50
+
51
+ return [status, headers, body] unless body[0]
52
+
53
+ body = body.collect do |str|
54
+ str.gsub(/\[e:([0-9A-F]{3})\]/) do |match|
55
+ emojiid = $1.scanf('%X').first
56
+ sjis = EMOJIID_TO_EMOJI[emojiid]
57
+ if sjis
58
+ # 絵文字があるので差替え
59
+ sjis
60
+ else
61
+ # 絵文字がないので代替文字列
62
+ emoji_data = EMOJI_DATA[emojiid]
63
+ NKF.nkf('-Ws', (emoji_data[:fallback] || emoji_data[:name] || '〓'))
64
+ end
65
+ end
66
+ end
67
+
68
+ content = (body.is_a?(Array) ? body[0] : body).to_s
69
+ headers['Content-Length'] = (content.respond_to?(:bytesize) ? content.bytesize : content.size).to_s if headers.member?('Content-Length')
70
+
71
+ headers['Content-Type'].sub! Regexp.new(Regexp.quote('text/html')), 'application/xhtml+xml' if headers['Content-Type']
72
+
73
+ [status, headers, body]
74
+ end
75
+ end
76
+
77
+ class << self
78
+ def filters
79
+ super | [Rack::Ketai::Carrier::Docomo::Filter]
80
+ end
81
+ end
82
+
83
+ def mobile?
84
+ true
85
+ end
86
+
87
+ # 端末個体識別子があれば返す。
88
+ def deviceid
89
+ case @env['HTTP_USER_AGENT']
90
+ when /ser([0-9a-zA-Z]{11})$/ # mova
91
+ return $1
92
+ when /ser([0-9a-zA-Z]{15});/ # FOMA
93
+ return $1
94
+ else
95
+ return nil
96
+ end
97
+ end
98
+
99
+ # iモードIDかFOMAカード個体識別子を返す
100
+ # iモードIDの方が優先度が高い
101
+ def subscriberid
102
+ guid || icc
103
+ end
104
+
105
+ # FOMAカード個体識別子
106
+ def icc
107
+ @icc ||= @env['HTTP_USER_AGENT'] =~ /icc([0-9a-zA-Z]{20})\)/ && $1
108
+ end
109
+
110
+ # iモードID
111
+ def guid
112
+ @guid ||= @env['HTTP_X_DCMGUID'] =~ /([0-9A-Za-z]{7})/ && $1
113
+ end
114
+
115
+ # 機種名
116
+ def name
117
+ @name ||= @env['HTTP_USER_AGENT'].split(/[\/\s\(\)]+/)[2]
118
+ end
119
+
120
+ # ディスプレイ情報
121
+ def display
122
+ @display ||= Rack::Ketai::Display.new(:colors => spec[7],
123
+ :width => spec[5],
124
+ :height => spec[6])
125
+ end
126
+
127
+ # キャッシュサイズ(Byte)
128
+ # 不明なら最低の5KBを返す
129
+ def cache_size
130
+ return @cache_size if @cache_size
131
+ @cache_size ||= if @env['HTTP_USER_AGENT'] =~ /DoCoMo\/\d\.\d\/[^\/]+\/c(\d+)/ ||
132
+ @env['HTTP_USER_AGENT'] =~ /DoCoMo\/\d\.\d[^\(]+\(c(\d+)/
133
+ $1.to_i * 1000
134
+ else
135
+ 5000
136
+ end
137
+ end
138
+
139
+ # Cookie対応
140
+ # iモードブラウザ2.0 なら Cookie対応
141
+ # ただしiモードブラウザ2.0かどうかはキャッシュサイズ(500K)から判断するしかない
142
+ # キャッシュサイズが取得できなかったらやむを得ずデータ参照(信頼性低い)
143
+ def supports_cookie?
144
+ cache_size >= 500000 || (spec[8].to_i >= 500 || spec[20].to_i > 0)
145
+ end
146
+
147
+ private
148
+ def spec
149
+ @spec = SPECS[name] || []
150
+ end
151
+
152
+ end
153
+ end
154
+
155
+ # 変換テーブル読み込み
156
+ require 'rack/ketai/carrier/emoji/docomosjisstrtoemojiid'
157
+