sekka 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,73 @@
1
+ :; #-*- mode: nendo; syntax: scheme -*-;;
2
+ ;;;
3
+ ;;; google-imd.nnd - google-imdを使ってひらがなから、漢字変換候補を取得する
4
+ ;;;
5
+ ;;; Copyright (c) 2010 Kiyoka Nishiyama <kiyoka@sumibi.org>
6
+ ;;;
7
+ ;;; Redistribution and use in source and binary forms, with or without
8
+ ;;; modification, are permitted provided that the following conditions
9
+ ;;; are met:
10
+ ;;;
11
+ ;;; 1. Redistributions of source code must retain the above copyright
12
+ ;;; notice, this list of conditions and the following disclaimer.
13
+ ;;;
14
+ ;;; 2. Redistributions in binary form must reproduce the above copyright
15
+ ;;; notice, this list of conditions and the following disclaimer in the
16
+ ;;; documentation and/or other materials provided with the distribution.
17
+ ;;;
18
+ ;;; 3. Neither the name of the authors nor the names of its contributors
19
+ ;;; may be used to endorse or promote products derived from this
20
+ ;;; software without specific prior written permission.
21
+ ;;;
22
+ ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
+ ;;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ ;;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25
+ ;;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26
+ ;;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27
+ ;;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28
+ ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
+ ;;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
+ ;;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
+ ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
+ ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ ;;;
34
+ ;;; $Id:
35
+ ;;;
36
+ (use srfi-1)
37
+ (use rfc.json)
38
+ (require "net/http")
39
+
40
+ (define (json-string->sekka-result-string jsonstr)
41
+ (let* ((obj (parse-json-string jsonstr))
42
+ (kouho-list (filter-map
43
+ (lambda (entry)
44
+ (if (vector? entry)
45
+ (vector->list (vector-ref entry 1))
46
+ false))
47
+ (vector->list obj))))
48
+ (if (null? kouho-list)
49
+ kouho-list
50
+ (map
51
+ (lambda (x)
52
+ (string-join x))
53
+ (apply zip kouho-list)))))
54
+
55
+
56
+ (define (request-google-ime keyword unit-test proxy-host proxy-port)
57
+ (let* ((body "")
58
+ (target "google-ime-api-normalizer.heroku.com")
59
+ (_ (Net::HTTP.version_1_2))
60
+ (http (if proxy-host
61
+ (let1 proxy-class (Net::HTTP.Proxy proxy-host proxy-port)
62
+ (proxy-class.new target))
63
+ (Net::HTTP.new target))))
64
+ (set! http.open_timeout (if unit-test 30 5))
65
+ (set! http.read_timeout (if unit-test 30 5))
66
+ (http.start
67
+ (&block ()
68
+ (let* ((path (sprintf "/transliterate%s?langpair=%s&text=%s"
69
+ (if unit-test "_test" "")
70
+ "ja-Hira|ja" (URI.encode keyword)))
71
+ (response (http.get path)))
72
+ (set! body response.body))))
73
+ (json-string->sekka-result-string body)))
@@ -34,10 +34,12 @@
34
34
  ;;; $Id:
35
35
  ;;;
36
36
  (use srfi-1)
37
+ (use rfc.json)
37
38
  (use sekka.util)
38
39
  (use sekka.convert-jisyo)
39
40
  (use sekka.jisyo-db)
40
41
  (use sekka.alphabet-lib)
42
+ (use sekka.google-ime)
41
43
  (require "sekka/approximatesearch")
42
44
 
43
45
 
@@ -477,3 +479,9 @@
477
479
  ;; Export to Ruby world
478
480
  (export-to-ruby registerUserJisyo)
479
481
 
482
+
483
+ ;; ユーザー定義語彙の登録処理
484
+ (define (googleIme keyword proxy-host proxy-port)
485
+ (request-google-ime keyword #f proxy-host proxy-port))
486
+ ;; Export to Ruby world
487
+ (export-to-ruby googleIme)
@@ -1,6 +1,6 @@
1
1
  class SekkaVersion
2
2
  include Singleton
3
3
  def self.version
4
- "0.8.2"
4
+ "0.8.3"
5
5
  end
6
6
  end
@@ -40,10 +40,12 @@ module SekkaServer
40
40
  class Config
41
41
  include Singleton
42
42
 
43
- def self.setup( dictSource, cacheSource = false, listenPort )
43
+ def self.setup( dictSource, cacheSource = false, listenPort, proxyHost, proxyPort )
44
44
  @@dictSource = dictSource
45
45
  @@cacheSource = cacheSource
46
46
  @@listenPort = listenPort
47
+ @@proxyHost = proxyHost
48
+ @@proxyPort = proxyPort
47
49
  end
48
50
 
49
51
  def self.dictSource
@@ -57,6 +59,14 @@ module SekkaServer
57
59
  def self.listenPort
58
60
  @@listenPort
59
61
  end
62
+
63
+ def self.proxyHost
64
+ @@proxyHost
65
+ end
66
+
67
+ def self.proxyPort
68
+ @@proxyPort
69
+ end
60
70
  end
61
71
  end
62
72
 
@@ -42,6 +42,7 @@ require 'uri'
42
42
  require 'date'
43
43
  require './lib/sekkaconfig'
44
44
  require './lib/sekka/sekkaversion'
45
+ require 'memcache'
45
46
 
46
47
  module SekkaServer
47
48
  class Server
@@ -56,12 +57,15 @@ module SekkaServer
56
57
  (@kvs,@cachesv) = @core.openSekkaJisyo( SekkaServer::Config.dictSource,
57
58
  SekkaServer::Config.cacheSource )
58
59
  @queue = EM::Queue.new
60
+ @mutex = Mutex.new
59
61
 
60
62
  STDERR.puts( "----- Sekka Server Started -----" )
61
- STDERR.printf( " version : %s\n", SekkaVersion.version )
62
- STDERR.printf( " dict-db : %s\n", SekkaServer::Config.dictSource )
63
- STDERR.printf( " memcached: %s\n", SekkaServer::Config.cacheSource )
63
+ STDERR.printf( " version : %s\n", SekkaVersion.version )
64
+ STDERR.printf( " dict-db : %s\n", SekkaServer::Config.dictSource )
65
+ STDERR.printf( " memcached : %s\n", SekkaServer::Config.cacheSource )
64
66
  STDERR.printf( " listenPort: %s\n", SekkaServer::Config.listenPort )
67
+ STDERR.printf( " proxyHost : %s\n", SekkaServer::Config.proxyHost )
68
+ STDERR.printf( " proxyPort : %s\n", SekkaServer::Config.proxyPort )
65
69
  STDERR.puts( "--------------------------------" )
66
70
 
67
71
  begin
@@ -69,28 +73,60 @@ module SekkaServer
69
73
  Thread.pass
70
74
  EventMachine::run {
71
75
  d = DateTime.now
72
- EventMachine::PeriodicTimer.new( 5 ) do
73
- while not @queue.empty?
76
+ EventMachine::PeriodicTimer.new( 1 ) do
77
+ if not @queue.empty?
74
78
  @queue.pop { |word|
75
79
  arr = word.split( /[ ]+/ )
76
- userid = arr[0]
77
- dictline =
78
- if 3 == arr.size
79
- arr[1] + " " + arr[2]
80
- else
81
- ";; comment"
82
- end
83
- registered = @core.registerUserJisyo(userid, @kvs, dictline)
84
- if registered
85
- str = d.strftime( "%D %X" )
86
- puts "Info: [" + str + "]added to dict userid[" + userid + "] dictline[" + dictline + "]"
87
- @core.flushCacheServer( @cachesv )
88
- else
89
- puts "Info: ignored (already added or comment) userid[" + userid + "] dictline[" + dictline + "]"
90
- end
80
+ command = arr[0]
81
+ userid = arr[1]
82
+ @mutex.synchronize {
83
+ case command
84
+ when 'r' # register
85
+ dictline =
86
+ if 4 == arr.size
87
+ arr[2] + " " + arr[3]
88
+ else
89
+ ";; comment"
90
+ end
91
+ STDERR.puts "Info: processing [register(" + dictline + ")] batch command..."
92
+ begin
93
+ registered = @core.registerUserJisyo(userid, @kvs, dictline)
94
+ rescue RuntimeError
95
+ "Info: missing [register(" + dictline + ")] batch command..."
96
+ end
97
+ if registered
98
+ str = d.strftime( "%D %X" )
99
+ STDERR.puts "Info: [" + str + "]added to dict userid[" + userid + "] dictline[" + dictline + "]"
100
+ @core.flushCacheServer( @cachesv )
101
+ else
102
+ STDERR.puts "Info: ignored (already added or comment) userid[" + userid + "] dictline[" + dictline + "]"
103
+ end
104
+ when 'k' # kakutei
105
+ arr = word.split( /[ ]+/ )
106
+ _key = arr[2]
107
+ _tango = arr[3]
108
+ STDERR.puts "Info: processing [kakutei(" + _tango + ")] batch command..."
109
+ begin
110
+ @core.sekkaKakutei( userid, @kvs, @cachesv, _key, _tango )
111
+ rescue RuntimeError
112
+ STDERR.puts "Info: missing [kakutei(" + _tango + ")] batch command..."
113
+ end
114
+
115
+ STDERR.printf( "Info: kakutei [%s:%s] \n", _key, _tango )
116
+ when 'f' # flush
117
+ STDERR.puts "Info: processing [flush] batch command..."
118
+ begin
119
+ n = @core.flushUserJisyo( userid, @kvs )
120
+ rescue RuntimeError
121
+ STDERR.puts "Info: missing [flush] batch command..."
122
+ end
123
+ @core.flushCacheServer( @cachesv )
124
+ STDERR.printf( "info : flush [%s] user's dict %d entries. \n", userid, n )
125
+ end
126
+ }
91
127
  }
92
128
  end
93
- end
129
+ end
94
130
  }
95
131
  end
96
132
  @thread.run
@@ -110,20 +146,42 @@ module SekkaServer
110
146
  _yomi = URI.decode( req.params[ 'yomi'].force_encoding("UTF-8") )
111
147
  _limit = URI.decode( req.params[ 'limit'].force_encoding("UTF-8") )
112
148
  _method = URI.decode( req.params['method'].force_encoding("UTF-8") )
113
- @core.writeToString( @core.sekkaHenkan( userid, @kvs, @cachesv, _yomi, _limit.to_i, _method ))
149
+ @mutex.synchronize {
150
+ begin
151
+ @core.writeToString( @core.sekkaHenkan( userid, @kvs, @cachesv, _yomi, _limit.to_i, _method ))
152
+ rescue MemCache::MemCacheError
153
+ "sekka-server: memcached server is down (or may be offline)"
154
+ end
155
+ }
114
156
  when "/kakutei"
115
157
  _key = URI.decode( req.params[ 'key'].force_encoding("UTF-8") )
116
158
  _tango = URI.decode( req.params[ 'tango'].force_encoding("UTF-8") )
117
- @core.sekkaKakutei( userid, @kvs, @cachesv, _key, _tango )
159
+ @queue.push( 'k ' + userid + " " + _key + " " + _tango )
118
160
  when "/register"
119
161
  dict = URI.decode( req.params['dict'].force_encoding( "UTF-8" ) ).split( "\n" )
120
- dict.each { |x| @queue.push( userid + " " + x ) }
162
+ dict.each { |x|
163
+ @queue.push( 'r ' + userid + " " + x )
164
+ }
121
165
  sprintf( "sekka-server:register request (%s) words added, current-queue-size (%s)", dict.size, @queue.size )
122
166
  when "/flush"
123
- @core.flushCacheServer( @cachesv )
124
- n = @core.flushUserJisyo( userid, @kvs )
125
- printf( "info : flush [%s] user's dict %d entries.", userid, n )
126
- sprintf( "sekka-server:flush request successful. flush (%d) entries.", n )
167
+ @queue.push( 'f ' + userid )
168
+ sprintf( "sekka-server:flush request successful." )
169
+ when "/googleime"
170
+ _yomi = URI.decode( req.params[ 'yomi'].force_encoding("UTF-8") )
171
+ printf( "info : google-ime request [%s]\n", _yomi )
172
+ result = "sekka-server: google-ime error"
173
+ begin
174
+ result = @core.googleIme( _yomi,
175
+ SekkaServer::Config.proxyHost,
176
+ SekkaServer::Config.proxyPort )
177
+ rescue Timeout
178
+ result = "sekka-server: Timeout to request google-ime (may be offline)"
179
+ rescue SocketError
180
+ result = "sekka-server: SocketError to request google-ime (may be offline)"
181
+ rescue Errno::ECONNREFUSED
182
+ result = "sekka-server: http proxy server is down (or may be offline)"
183
+ end
184
+ @core.writeToString( result )
127
185
  else
128
186
  sprintf( "sekka-server:unknown path name. [%s]", req.path )
129
187
  end
@@ -0,0 +1,60 @@
1
+ #!/bin/sh
2
+
3
+ ###
4
+ ### /etc/init.d/sekkaserver file for Debian
5
+ ###
6
+
7
+ ### BEGIN INIT INFO
8
+ # Provides: sekkaserver
9
+ # Required-Start: $network $local_fs $remote_fs
10
+ # Required-Stop: $network $local_fs $remote_fs
11
+ # Default-Start: 2 3 4 5
12
+ # Default-Stop: 0 1 6
13
+ # Short-Description: start sekka-server daemon
14
+ ### END INIT INFO
15
+
16
+
17
+ # Defaults
18
+ RUN_MODE="daemons"
19
+
20
+ PIDFILE=/home/sekka/.sekka-server/pid
21
+ LOGFILE=/home/sekka/.sekka-server/server.log
22
+
23
+ # clear conflicting settings from the environment
24
+ unset TMPDIR
25
+
26
+ . /lib/lsb/init-functions
27
+
28
+ case "$1" in
29
+ start)
30
+ log_daemon_msg "Starting sekka-server daemon"
31
+ su - sekka -c "nohup sekka-server > ${LOGFILE} &"
32
+ log_end_msg 0
33
+ ;;
34
+ stop)
35
+ log_daemon_msg "Stopping sekka-server daemon"
36
+ kill -KILL `cat ${PIDFILE}`
37
+ log_end_msg 0
38
+ ;;
39
+ status)
40
+ log_daemon_msg "sekka-server status"
41
+ ps -p `cat ${PIDFILE}` | grep sekka-server
42
+ if [ "$?" = "0" ] ; then
43
+ echo " sekka-server is running"
44
+ else
45
+ echo " sekka-server is not running"
46
+ fi
47
+ log_end_msg 0
48
+ ;;
49
+ restart)
50
+ $0 stop
51
+ sleep 1
52
+ $0 start
53
+ ;;
54
+ *)
55
+ echo "Usage: /etc/init.d/sekkaserver {status|start|stop|restart}"
56
+ exit 1
57
+ ;;
58
+ esac
59
+
60
+ exit 0
@@ -0,0 +1,87 @@
1
+ ;;-*- mode: nendo; syntax: scheme -*-
2
+ ;;;
3
+ ;;; google-ime.nnd - google-ime部のテスト
4
+ ;;;
5
+ ;;; Copyright (c) 2010 Kiyoka Nishiyama <kiyoka@sumibi.org>
6
+ ;;;
7
+ ;;; Redistribution and use in source and binary forms, with or without
8
+ ;;; modification, are permitted provided that the following conditions
9
+ ;;; are met:
10
+ ;;;
11
+ ;;; 1. Redistributions of source code must retain the above copyright
12
+ ;;; notice, this list of conditions and the following disclaimer.
13
+ ;;;
14
+ ;;; 2. Redistributions in binary form must reproduce the above copyright
15
+ ;;; notice, this list of conditions and the following disclaimer in the
16
+ ;;; documentation and/or other materials provided with the distribution.
17
+ ;;;
18
+ ;;; 3. Neither the name of the authors nor the names of its contributors
19
+ ;;; may be used to endorse or promote products derived from this
20
+ ;;; software without specific prior written permission.
21
+ ;;;
22
+ ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
+ ;;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ ;;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25
+ ;;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26
+ ;;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27
+ ;;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28
+ ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
+ ;;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
+ ;;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
+ ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
+ ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ ;;;
34
+ ;;; $Id:
35
+ ;;;
36
+ (use nendo.test)
37
+ (use sekka.google-ime)
38
+
39
+ (test-start "google-ime")
40
+
41
+ ;;===================================================================
42
+
43
+ ;;-------------------------------------------------------------------
44
+ (test-section "conversion json => sekka result")
45
+
46
+ (test* "no split (1)"
47
+ '("四文字熟語" "4文字熟語" "4文字熟語" "よんもじじゅくご" "ヨンモジジュクゴ")
48
+ (json-string->sekka-result-string
49
+ "[[\"よんもじじゅくご\", [\"四文字熟語\", \"4文字熟語\", \"4文字熟語\", \"よんもじじゅくご\", \"ヨンモジジュクゴ\"]]]"))
50
+
51
+ (test* "no split (2)"
52
+ '()
53
+ (json-string->sekka-result-string
54
+ "[]"))
55
+
56
+ (test* "split (1)"
57
+ '("曖昧文字列" "あいまいもじれつ" "アイマイモジレツ")
58
+ (json-string->sekka-result-string
59
+ "[[\"あいまい\", [\"曖昧\", \"あいまい\", \"アイマイ\", \"愛舞\", \"愛麻衣\"]], [\"もじれつ\", [\"文字列\", \"もじれつ\", \"モジレツ\"]]]"))
60
+
61
+ (test* "split (2)"
62
+ '("竹内関数" "竹内関数" "竹内巻数" "武内函数" "タケウチ韓嵩")
63
+ (json-string->sekka-result-string
64
+ "[[\"たけうち\", [\"竹内\", \"竹内\", \"竹内\", \"武内\", \"タケウチ\"]], [\"かんすう\", [\"関数\", \"関数\", \"巻数\", \"函数\", \"韓嵩\"]]]"))
65
+
66
+ ;;-------------------------------------------------------------------
67
+ (test-section "request to google-ime")
68
+
69
+ (test* "request online (1)"
70
+ '("日本語" "ニホンゴ" "ニホン語" "にほんご" "ニホンゴ")
71
+ (request-google-ime "1" #t nil nil))
72
+
73
+ (test* "request online (2)"
74
+ '("変換" "返還" "へんかん" "偏官" "変漢")
75
+ (request-google-ime "2" #t nil nil))
76
+
77
+ (test* "request online (3)"
78
+ '()
79
+ (request-google-ime "3" #t nil nil))
80
+
81
+ (test* "request online (4)"
82
+ '()
83
+ (request-google-ime "4" #t nil nil))
84
+
85
+
86
+ ;;===================================================================
87
+ (test-end)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 8
8
- - 2
9
- version: 0.8.2
8
+ - 3
9
+ version: 0.8.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Kiyoka Nishiyama
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-06 00:00:00 +09:00
17
+ date: 2011-02-12 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -106,8 +106,8 @@ dependencies:
106
106
  segments:
107
107
  - 0
108
108
  - 4
109
- - 0
110
- version: 0.4.0
109
+ - 1
110
+ version: 0.4.1
111
111
  type: :runtime
112
112
  version_requirements: *id007
113
113
  - !ruby/object:Gem::Dependency
@@ -154,11 +154,13 @@ files:
154
154
  - bin/sekka-server
155
155
  - emacs/http-cookies.el
156
156
  - emacs/http-get.el
157
+ - emacs/popup.el
157
158
  - emacs/sekka.el
158
159
  - lib/sekka.ru
159
160
  - lib/sekka/alphabet-lib.nnd
160
161
  - lib/sekka/approximatesearch.rb
161
162
  - lib/sekka/convert-jisyo.nnd
163
+ - lib/sekka/google-ime.nnd
162
164
  - lib/sekka/henkan.nnd
163
165
  - lib/sekka/jisyo-db.nnd
164
166
  - lib/sekka/kvs.rb
@@ -167,10 +169,12 @@ files:
167
169
  - lib/sekka/util.nnd
168
170
  - lib/sekkaconfig.rb
169
171
  - lib/sekkaserver.rb
172
+ - script/sekkaserver.debian
170
173
  - test/alphabet-lib.nnd
171
174
  - test/approximate-bench.nnd
172
175
  - test/azik-verification.nnd
173
176
  - test/common.nnd
177
+ - test/google-ime.nnd
174
178
  - test/henkan-main.nnd
175
179
  - test/jisyo.nnd
176
180
  - test/roman-lib.nnd