opener-chained-daemon 2.2.2 → 3.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb437fa8aeeb2133629c9545254252aa07145cbe9c81a9804703b168cc32c098
4
- data.tar.gz: 47c6e1b0462a52710100b201c41b7a3feddaa89d9e80649efc323eaa4546db5e
3
+ metadata.gz: 1f37e21fff5f35b6736a17e4d4efcad5d496c1c2ec63e74c7b8907db45210770
4
+ data.tar.gz: 6e3b80ba665a950407b1c4bcba9e0f6074db41db86b2da233b21c1db638c792f
5
5
  SHA512:
6
- metadata.gz: ff6d5446a98856a6d3981f1610a776374a50b5ae0f78bd3a9040e8f58fc704ce6a2f453475c88ecadc13cd4c0adb872403d60e827c4b2a95fd2ff11391fecb37
7
- data.tar.gz: 25e202e8df0be31a8c03a6588b68f30d7a82faec24e1c461302ca8d7369de81a1ee87468df9a7b28cb472cb0aa5c476adbc4b004c525230fbff3aa56b7b841cb
6
+ metadata.gz: 5738bfe0a4dbf5ff66010a9aa54ef7de4e951e7728d753000b99effbb0f4c17884791a8eb6c58fcfcafd51f0ba94520148f6d3699dd592c74145766e2c06917f
7
+ data.tar.gz: 7100f63ac6fd859b98f28eac22dd73e60419f21fc40e3b59c34c6550915182ca0598eb74f2ec9eddaa870fd4b91f94b31a694f70fc62ed20307b1415c0e82804
@@ -0,0 +1,11 @@
1
+ APP_NAME = 'opener'
2
+ deploy_to = "/var/www/#{APP_NAME}"
3
+ run_path = "/var/run/#{APP_NAME}"
4
+ log_path = "/var/log/#{APP_NAME}"
5
+
6
+ workers ENV['WORKERS']&.to_i || 1 unless RUBY_ENGINE == 'jruby'
7
+ threads 0, ENV['THREADS']&.to_i || 16
8
+
9
+ bind 'tcp://0.0.0.0:9292'
10
+ #bind "unix://#{run_path}/chained-daemon-server.sock"
11
+
@@ -4,5 +4,8 @@ require 'opener/daemons'
4
4
 
5
5
  require_relative '../lib/opener/chained_daemon'
6
6
 
7
+ webservice = Rack::Server.new app: Opener::ChainedDaemon::Webservice.freeze.app
8
+ Thread.new{ webservice.start }
9
+
7
10
  daemon = Opener::Daemons::Daemon.new Opener::ChainedDaemon
8
11
  daemon.start
@@ -5,15 +5,20 @@ require 'google/cloud/translate'
5
5
 
6
6
  require 'opener/daemons'
7
7
 
8
+ require_relative 'chained_daemon/languages_cache'
8
9
  require 'opener/language_identifier'
9
10
  require 'opener/tokenizer'
10
- # require ner before pos_tagger for compatible opennlp
11
- require 'opener/pos_tagger'
11
+ require 'opener/pos_tagger' if RUBY_ENGINE == 'jruby'
12
12
  require 'opener/polarity_tagger'
13
13
  require 'opener/property_tagger'
14
14
  require 'opener/opinion_detector_basic'
15
+ require 'opener/stanza/tokenizer_pos'
15
16
 
16
17
  require_relative 'chained_daemon/chained_daemon'
17
18
  require_relative 'chained_daemon/cli'
18
19
  require_relative 'chained_daemon/microsoft_translator'
20
+ require_relative 'chained_daemon/webservice'
21
+
22
+ require_relative 'kaf/document'
23
+ require_relative 'kaf/term'
19
24
 
@@ -8,8 +8,9 @@ module Opener
8
8
  @options = DEFAULT_OPTIONS.merge options
9
9
  @queue_map = {
10
10
  'opener-language-identifier': Opener::LanguageIdentifier.new,
11
- 'opener-tokenizer': Opener::Tokenizer.new,
12
- 'opener-pos-tagger': Opener::POSTagger.new,
11
+ 'stanza-tokenizer-pos': Stanza::TokenizerPos.new, # replace this tokenizer-pos with both below with you dont have a stanza server
12
+ #'opener-tokenizer': Opener::Tokenizer.new,
13
+ #'opener-pos-tagger': Opener::POSTagger.new,
13
14
  'opener-polarity-tagger': Opener::PolarityTagger.new,
14
15
  'opener-property-tagger': Opener::PropertyTagger.new,
15
16
  'opener-opinion-detector-basic': Opener::OpinionDetectorBasic.new,
@@ -18,15 +19,16 @@ module Opener
18
19
 
19
20
  def run input, params = {}
20
21
  params ||= {}
21
- params.symbolize_keys!
22
+ params.deep_symbolize_keys!
22
23
  params[:translate_languages] ||= []
24
+ params[:cache_keys] = params[:cache_keys]&.sort&.to_h || {}
23
25
 
24
26
  lang = nil
25
27
  output = nil
26
28
  @queue_map.each do |queue, component|
27
29
  debug_print queue, input if ENV['DEBUG']
28
30
 
29
- output = component.run input
31
+ output = component.run input, params
30
32
  input = output
31
33
 
32
34
  rescue Core::UnsupportedLanguageError
@@ -0,0 +1,45 @@
1
+ module Opener
2
+ class ChainedDaemon
3
+ class LanguagesCache
4
+
5
+ include MonitorMixin
6
+
7
+ UPDATE_INTERVAL = (ENV['CACHE_EXPIRE_MINS']&.to_i || 5).minutes
8
+
9
+ def initialize
10
+ super #MonitorMixin
11
+
12
+ @url = ENV['SUPPORTED_LANGUAGES_URL']
13
+ @cache = []
14
+ @last_updated = nil
15
+ end
16
+
17
+ def get
18
+ synchronize do
19
+ break @cache if @last_updated and @last_updated > UPDATE_INTERVAL.ago
20
+ cache_update
21
+ end
22
+ @cache
23
+ end
24
+
25
+ def cache_update
26
+ puts "loading supported languages from url #{@url}" if ENV['DEBUG']
27
+
28
+ languages = JSON.parse http.get(@url).body
29
+ @cache = languages['data'].map { |l| l['code'] }
30
+ @last_updated = Time.now
31
+ end
32
+
33
+ def http
34
+ return @http if @http
35
+
36
+ @http = HTTPClient.new
37
+ @http.send_timeout = 120
38
+ @http.receive_timeout = 120
39
+ @http.connect_timeout = 120
40
+ @http
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -1,7 +1,7 @@
1
1
  module Opener
2
2
  class ChainedDaemon
3
3
 
4
- VERSION = '2.2.2'
4
+ VERSION = '3.0.7'
5
5
 
6
6
  end
7
7
  end
@@ -0,0 +1,29 @@
1
+ require 'roda'
2
+
3
+ module Opener
4
+ class ChainedDaemon
5
+ class Webservice < Roda
6
+
7
+ TOKEN = ENV['PRIVATE_TOKEN']
8
+
9
+ class_attribute :processor
10
+ self.processor = ChainedDaemon.new
11
+
12
+ route do |r|
13
+ response.status = 403 and r.halt if r.params['auth_token'] != TOKEN
14
+
15
+ sentiment = -> do
16
+ r.params.deep_symbolize_keys!
17
+ kaf = processor.run r.params[:input], **r.params.except(:input)
18
+
19
+ response['Content-Type'] = 'text/xml'
20
+ kaf
21
+ end
22
+
23
+ r.get 'sentiment.kaf', &sentiment
24
+ r.post 'sentiment.kaf', &sentiment
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,89 @@
1
+ require_relative 'term'
2
+
3
+ module Opener
4
+ module KAF
5
+ class Document
6
+
7
+ attr_reader :document
8
+ attr_reader :lexicons
9
+
10
+ attr_accessor :map
11
+
12
+ def initialize xml
13
+ @document = xml
14
+ end
15
+
16
+ def self.from_xml xml
17
+ new Nokogiri::XML xml
18
+ end
19
+
20
+ def language
21
+ @language ||= @document.at_xpath('KAF').attr 'xml:lang'
22
+ end
23
+
24
+ def terms
25
+ @terms ||= collection 'KAF/terms/term', Term
26
+ end
27
+
28
+ def texts
29
+ @texts ||= collection 'KAF/texts/wf', Text
30
+ end
31
+
32
+ def raw
33
+ @document.at('raw').text
34
+ end
35
+
36
+ def add_linguistic_processor name, version, layer, timestamp: false
37
+ header = @document.at('kafHeader') || @document.root.add_child('<kafHeader/>').first
38
+ procs = header.css('linguisticProcessors').find{ |l| l.attr(:layer) == layer }
39
+ procs ||= header.add_child("<linguisticProcessors layer='#{layer}'/>").first
40
+ lp = procs.add_child('<lp/>')
41
+ lp.attr(
42
+ timestamp: if timestamp then Time.now.iso8601 else '*' end,
43
+ version: version,
44
+ name: name,
45
+ )
46
+ lp
47
+ end
48
+
49
+ def add_word_form params
50
+ text = @document.at('text') || @document.root.add_child('<text/>').first
51
+ wf = text.add_child("<wf>#{params[:text]}</wf>")
52
+ attrs = {
53
+ wid: "w#{params[:wid]}",
54
+ sent: params[:sid],
55
+ para: params[:para],
56
+ offset: params[:offset],
57
+ length: params[:length],
58
+ }
59
+ wf.attr attrs
60
+ end
61
+
62
+ def add_term params
63
+ text = @document.at('terms') || @document.root.add_child('<terms/>').first
64
+ term = text.add_child("<term/>")
65
+ attrs = {
66
+ tid: "t#{params[:tid]}",
67
+ type: params[:type],
68
+ lemma: params[:lemma],
69
+ text: params[:text],
70
+ pos: params[:pos],
71
+ morphofeat: params[:morphofeat],
72
+ }
73
+ term.attr attrs
74
+ term.first.add_child("<span><target id='w#{params[:wid]}' /></span>")
75
+ end
76
+
77
+ def to_xml
78
+ @document.to_xml indent: 2
79
+ end
80
+
81
+ protected
82
+
83
+ def collection query, wrapper
84
+ @document.xpath(query).map{ |node| wrapper.new self, node }
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,35 @@
1
+ module Opener
2
+ module KAF
3
+ class Term
4
+
5
+ attr_reader :document
6
+ attr_reader :node
7
+
8
+ def initialize document, node
9
+ @document = document
10
+ @node = node
11
+ end
12
+
13
+ def id
14
+ @id ||= @node.attr :tid
15
+ end
16
+
17
+ def lemma
18
+ @node.attr :lemma
19
+ end
20
+
21
+ def pos
22
+ @node.attr :pos
23
+ end
24
+
25
+ def setPolarity attrs, polarity_pos
26
+ #In case there is no pos info, we use the polarityPos
27
+ @node[:pos] = polarity_pos if !pos and polarity_pos
28
+
29
+ sentiment = @node.add_child('<sentiment/>')
30
+ sentiment.attr attrs
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ module Opener
2
+ module KAF
3
+ class WordForm
4
+ def initialize(document, xml_node)
5
+ @document = document
6
+ @xml_node = xml_node
7
+ end
8
+
9
+ def id
10
+ return @id ||= @xml_node.attr('wid')
11
+ end
12
+
13
+ def text
14
+ return @text ||= @xml_node.text
15
+ end
16
+
17
+ def length
18
+ return @length ||= @xml_node.attr('length').to_i
19
+ end
20
+
21
+ def offset
22
+ return @offset ||= @xml_node.attr('offset').to_i
23
+ end
24
+
25
+ def paragraph
26
+ return @paragraph ||= @xml_node.attr('para').to_i
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,87 @@
1
+ module Opener
2
+ module Stanza
3
+ class TokenizerPos
4
+
5
+ DESC = 'Tokenizer / POS by Stanza'
6
+ VERSION = '1.0'
7
+
8
+ BASE_URL = ENV['STANZA_SERVER']
9
+ LANGUAGES_CACHE = Opener::ChainedDaemon::LanguagesCache.new
10
+
11
+ POS = {
12
+ 'DET' => 'D',
13
+ 'ADJ' => 'G',
14
+ 'NOUN' => 'N',
15
+ 'VERB' => 'V',
16
+ 'AUX' => 'V',
17
+ 'ADV' => 'A',
18
+ 'CCONJ' => 'J',
19
+ 'PUNCT' => '.',
20
+ 'ADP' => 'P',
21
+ 'PRON' => 'Q',
22
+ 'PROPN' => 'R',
23
+ 'PART' => 'P',
24
+ 'NUM' => 'O',
25
+ 'X' => 'O',
26
+ 'SYM' => 'O',
27
+ 'SCONJ' => 'P',
28
+ 'INTJ' => 'O',
29
+ }
30
+
31
+ POS_OPEN = %w[N R G V A O]
32
+
33
+ def run input, params
34
+ raise 'missing Stanza server' if ENV['STANZA_SERVER'].blank?
35
+
36
+ kaf = KAF::Document.from_xml input
37
+
38
+ prod = params[:cache_keys][:environment] != 'staging'
39
+ if prod and !LANGUAGES_CACHE.get.include?(kaf.language)
40
+ raise Core::UnsupportedLanguageError.new kaf.language
41
+ end
42
+
43
+ response = Faraday.post BASE_URL, {lang: kaf.language, input: kaf.raw}.to_query
44
+ raise Core::UnsupportedLanguageError, kaf.language if response.status == 406
45
+ raise response.body if response.status >= 400
46
+ tokens = JSON.parse response.body
47
+
48
+ w_index = 0
49
+ tokens.each_with_index do |sentence, s_index|
50
+ sentence.each_with_index do |word|
51
+ w_index += 1
52
+ misc = word['misc']
53
+ offset = misc.match(/start_char=(\d+)|/)[1].to_i
54
+ length = misc.match(/end_char=(\d+)/)[1].to_i - offset
55
+
56
+ u_pos = word['upos']
57
+ pos = POS[u_pos]
58
+ raise "Didn't find a map for #{u_pos}" if pos.nil?
59
+ type = if POS_OPEN.include? pos then 'open' else 'close' end
60
+
61
+ params = {
62
+ wid: w_index,
63
+ sid: s_index + 1,
64
+ tid: w_index,
65
+ para: 1,
66
+ offset: offset,
67
+ length: length,
68
+ text: word['text'],
69
+ lemma: word['lemma'],
70
+ morphofeat: u_pos,
71
+ pos: pos,
72
+ type: type,
73
+ }
74
+
75
+ kaf.add_word_form params
76
+ kaf.add_term params
77
+ end
78
+ end
79
+
80
+ kaf.add_linguistic_processor DESC, "#{VERSION}", 'text', timestamp: true
81
+
82
+ kaf.to_xml
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -10,6 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.license = 'Apache 2.0'
11
11
 
12
12
  spec.files = Dir.glob([
13
+ 'config/**/*',
13
14
  'exec/**/*',
14
15
  'lib/**/*',
15
16
  '*.gemspec',
@@ -18,22 +19,25 @@ Gem::Specification.new do |spec|
18
19
  ]).select{ |file| File.file? file }
19
20
 
20
21
  spec.bindir = 'bin'
21
- spec.executables = Dir.glob('bin/*').map { |file| File.basename(file) }
22
+ spec.executables = Dir.glob('bin/*').map{ |file| File.basename(file) }
22
23
 
23
24
  spec.add_dependency 'activesupport'
24
25
  spec.add_dependency 'google-cloud-translate', '~> 1.0'
25
26
  spec.add_dependency 'httpclient'
26
27
  spec.add_dependency 'hashie'
27
28
 
28
- spec.add_dependency 'opener-daemons', '~> 2.7.1'
29
+ spec.add_dependency 'roda'
30
+ spec.add_dependency 'rack-timeout'
31
+ spec.add_dependency 'faraday'
32
+ spec.add_dependency 'opener-daemons', '~> 2.7.2'
29
33
  spec.add_dependency 'opener-callback-handler', '~> 1.0'
30
34
 
31
- spec.add_dependency 'opener-language-identifier'
32
- spec.add_dependency 'opener-tokenizer'
33
- spec.add_dependency 'opener-pos-tagger'
34
- spec.add_dependency 'opener-polarity-tagger', '>= 3.1.3'
35
- spec.add_dependency 'opener-property-tagger', '>= 3.2.1'
36
- spec.add_dependency 'opener-opinion-detector-basic'
35
+ spec.add_dependency 'opener-language-identifier', '>= 4.4.0'
36
+ spec.add_dependency 'opener-tokenizer', '>= 2.2.0'
37
+ spec.add_dependency 'opener-pos-tagger', '>= 3.2.0'
38
+ spec.add_dependency 'opener-polarity-tagger', '>= 3.2.7'
39
+ spec.add_dependency 'opener-property-tagger', '>= 3.3.5'
40
+ spec.add_dependency 'opener-opinion-detector-basic', '>= 3.2.3'
37
41
 
38
42
  spec.add_development_dependency 'bundler', '~> 1.3'
39
43
  spec.add_development_dependency 'rake'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opener-chained-daemon
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 3.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - development@olery.com
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-23 00:00:00.000000000 Z
11
+ date: 2020-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,20 +66,62 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: roda
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-timeout
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: faraday
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
69
111
  - !ruby/object:Gem::Dependency
70
112
  name: opener-daemons
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
115
  - - "~>"
74
116
  - !ruby/object:Gem::Version
75
- version: 2.7.1
117
+ version: 2.7.2
76
118
  type: :runtime
77
119
  prerelease: false
78
120
  version_requirements: !ruby/object:Gem::Requirement
79
121
  requirements:
80
122
  - - "~>"
81
123
  - !ruby/object:Gem::Version
82
- version: 2.7.1
124
+ version: 2.7.2
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: opener-callback-handler
85
127
  requirement: !ruby/object:Gem::Requirement
@@ -100,84 +142,84 @@ dependencies:
100
142
  requirements:
101
143
  - - ">="
102
144
  - !ruby/object:Gem::Version
103
- version: '0'
145
+ version: 4.4.0
104
146
  type: :runtime
105
147
  prerelease: false
106
148
  version_requirements: !ruby/object:Gem::Requirement
107
149
  requirements:
108
150
  - - ">="
109
151
  - !ruby/object:Gem::Version
110
- version: '0'
152
+ version: 4.4.0
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: opener-tokenizer
113
155
  requirement: !ruby/object:Gem::Requirement
114
156
  requirements:
115
157
  - - ">="
116
158
  - !ruby/object:Gem::Version
117
- version: '0'
159
+ version: 2.2.0
118
160
  type: :runtime
119
161
  prerelease: false
120
162
  version_requirements: !ruby/object:Gem::Requirement
121
163
  requirements:
122
164
  - - ">="
123
165
  - !ruby/object:Gem::Version
124
- version: '0'
166
+ version: 2.2.0
125
167
  - !ruby/object:Gem::Dependency
126
168
  name: opener-pos-tagger
127
169
  requirement: !ruby/object:Gem::Requirement
128
170
  requirements:
129
171
  - - ">="
130
172
  - !ruby/object:Gem::Version
131
- version: '0'
173
+ version: 3.2.0
132
174
  type: :runtime
133
175
  prerelease: false
134
176
  version_requirements: !ruby/object:Gem::Requirement
135
177
  requirements:
136
178
  - - ">="
137
179
  - !ruby/object:Gem::Version
138
- version: '0'
180
+ version: 3.2.0
139
181
  - !ruby/object:Gem::Dependency
140
182
  name: opener-polarity-tagger
141
183
  requirement: !ruby/object:Gem::Requirement
142
184
  requirements:
143
185
  - - ">="
144
186
  - !ruby/object:Gem::Version
145
- version: 3.1.3
187
+ version: 3.2.7
146
188
  type: :runtime
147
189
  prerelease: false
148
190
  version_requirements: !ruby/object:Gem::Requirement
149
191
  requirements:
150
192
  - - ">="
151
193
  - !ruby/object:Gem::Version
152
- version: 3.1.3
194
+ version: 3.2.7
153
195
  - !ruby/object:Gem::Dependency
154
196
  name: opener-property-tagger
155
197
  requirement: !ruby/object:Gem::Requirement
156
198
  requirements:
157
199
  - - ">="
158
200
  - !ruby/object:Gem::Version
159
- version: 3.2.1
201
+ version: 3.3.5
160
202
  type: :runtime
161
203
  prerelease: false
162
204
  version_requirements: !ruby/object:Gem::Requirement
163
205
  requirements:
164
206
  - - ">="
165
207
  - !ruby/object:Gem::Version
166
- version: 3.2.1
208
+ version: 3.3.5
167
209
  - !ruby/object:Gem::Dependency
168
210
  name: opener-opinion-detector-basic
169
211
  requirement: !ruby/object:Gem::Requirement
170
212
  requirements:
171
213
  - - ">="
172
214
  - !ruby/object:Gem::Version
173
- version: '0'
215
+ version: 3.2.3
174
216
  type: :runtime
175
217
  prerelease: false
176
218
  version_requirements: !ruby/object:Gem::Requirement
177
219
  requirements:
178
220
  - - ">="
179
221
  - !ruby/object:Gem::Version
180
- version: '0'
222
+ version: 3.2.3
181
223
  - !ruby/object:Gem::Dependency
182
224
  name: bundler
183
225
  requirement: !ruby/object:Gem::Requirement
@@ -276,12 +318,19 @@ files:
276
318
  - bin/chained-daemon-csv
277
319
  - bin/chained-daemon-daemon
278
320
  - bin/console
321
+ - config/puma.rb
279
322
  - exec/chained-daemon.rb
280
323
  - lib/opener/chained_daemon.rb
281
324
  - lib/opener/chained_daemon/chained_daemon.rb
282
325
  - lib/opener/chained_daemon/cli.rb
326
+ - lib/opener/chained_daemon/languages_cache.rb
283
327
  - lib/opener/chained_daemon/microsoft_translator.rb
284
328
  - lib/opener/chained_daemon/version.rb
329
+ - lib/opener/chained_daemon/webservice.rb
330
+ - lib/opener/kaf/document.rb
331
+ - lib/opener/kaf/term.rb
332
+ - lib/opener/kaf/text.rb
333
+ - lib/opener/stanza/tokenizer_pos.rb
285
334
  - opener-chained-daemon.gemspec
286
335
  homepage:
287
336
  licenses:
@@ -303,7 +352,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
303
352
  version: '0'
304
353
  requirements: []
305
354
  rubyforge_project:
306
- rubygems_version: 2.7.8
355
+ rubygems_version: 2.7.6.2
307
356
  signing_key:
308
357
  specification_version: 4
309
358
  summary: OpeNER daemon for processing multiple queues at once