sekka 0.8.2 → 0.8.3

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.
@@ -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