00001
00002
00003
00004 from email.parser import Parser
00005 from xml.etree import ElementTree as ET
00006
00007
00008 import requests
00009
00010
00011 from rospeex_core import logging_util
00012 from rospeex_core.sr.base import IState
00013 from rospeex_core.sr.base import PacketType
00014 from rospeex_core.sr.base import SessionState
00015 from rospeex_core.sr.base import IRequest
00016 from mime_message import MIMEMessage
00017
00018
00019
00020 logger = logging_util.get_logger(__name__)
00021
00022
00023 class NICTRequest(IRequest):
00024 """ NICT Request class
00025 """
00026 def __init__(self, url, data=None, cookies=None):
00027 """ init class
00028
00029 @param url:
00030 @param data:
00031 @param cookies:
00032 """
00033 self._url = url
00034 self._cookies = cookies
00035 self._data = data
00036 self._response = None
00037 self._has_err = False
00038 self._stml_text = ''
00039
00040 def _create_request_string(self):
00041 pass
00042
00043 def request(self, *args, **kwargs):
00044 """ request to server
00045
00046 @param args: not used
00047 @param kwargs: not used
00048 """
00049
00050 headers, message = self._create_request_string()
00051 try:
00052 self._response = requests.post(
00053 self._url,
00054 data=message,
00055 headers=headers,
00056 timeout=10.0
00057 )
00058
00059 except requests.exceptions.RequestException as err:
00060 self._has_err = True
00061 msg = str(err)
00062 logger.warn(msg)
00063 return
00064
00065
00066 if self._response.status_code == requests.codes.ok:
00067 try:
00068 self._stml_text = self._parse_mime_text(self._response.content)
00069 self._check_stml_format(self._stml_text)
00070
00071 except Exception as err:
00072 self._has_err = True
00073 msg = 'Invalid MIME format. Err {}'.format(err)
00074 logger.exception(msg)
00075
00076 else:
00077 self._has_err = True
00078 msg = 'server [{}] returns error code [{}]'.format(
00079 self._url,
00080 self._response.status_code
00081 )
00082 logger.warn(msg)
00083
00084 def _parse_mime_text(self, mime_text):
00085 """ parse mime data format
00086
00087 @param mime_text:
00088 @return: stml text
00089 """
00090 parser = Parser()
00091 encoded_text = mime_text.decode('utf-8').encode('utf-8')
00092 message = parser.parsestr(encoded_text)
00093
00094 response_text = None
00095 for part in message.walk():
00096 if part.get_content_type() == 'text/xml':
00097 response_text = part.get_payload().decode('utf-8').encode('utf-8')
00098 break
00099 return response_text
00100
00101 def _check_stml_format(self, stml_text):
00102 root = ET.fromstring(stml_text)
00103 for elem in root.findall('.//Error'):
00104 self._has_err = True
00105 msg = 'stml string has error attr. [{}]'.format(elem.text)
00106 logger.warn(msg)
00107
00108 def has_error(self):
00109 """ execute error check
00110
00111 @reutrn: True for Error occured / False for Succes.
00112 """
00113 return self._has_err
00114
00115 def response(self):
00116 """ get response
00117 @return: response data
00118 """
00119 return self._response
00120
00121 def result(self):
00122 return self._stml_text
00123
00124
00125 class StartRequest(NICTRequest):
00126 """ StartRequest class
00127 """
00128 def __init__(self, url, language, cookies=None):
00129 """ init class
00130
00131 @param url:
00132 @param cookies:
00133 """
00134 super(StartRequest, self).__init__(url, None, cookies)
00135 self._language = language
00136
00137 def _create_request_string(self):
00138 """ create request string
00139 """
00140 headers = MIMEMessage.create_http_header(self._cookies)
00141 message = MIMEMessage.create_header_request(self._language, 1)
00142 return headers, message
00143
00144
00145 class DataRequest(NICTRequest):
00146 def __init__(self, url, data=None, cookies=None):
00147 """ init class
00148
00149 @param url:
00150 @param data:
00151 @param cookies:
00152 """
00153 super(DataRequest, self).__init__(url, data, cookies)
00154
00155 def _create_request_string(self):
00156 """ create request string
00157 """
00158 headers = MIMEMessage.create_http_header(self._cookies)
00159 message = MIMEMessage.create_data_request(self._data)
00160 return headers, message
00161
00162
00163 class EndRequest(NICTRequest):
00164 def __init__(self, url, cookies=None):
00165 """ init class
00166
00167 @param url:
00168 @param cookies:
00169 """
00170 super(EndRequest, self).__init__(url, None, cookies)
00171
00172 def _create_request_string(self):
00173 """ create request string
00174 """
00175 headers = MIMEMessage.create_http_header(self._cookies)
00176 message = MIMEMessage.create_finish_request()
00177 return headers, message
00178
00179
00180 class NICTClientState(IState):
00181 def run(self, packet_data):
00182 pass
00183
00184 def next(self, packet_type):
00185 pass
00186
00187 def result(self):
00188 pass
00189
00190 def state(self):
00191 pass
00192
00193 def _create_url(self, base_url, index, is_last):
00194 if is_last:
00195 url = '{base}/n{index}last'.format(
00196 base=base_url,
00197 index=index
00198 )
00199 else:
00200 url = '{base}/n{index}'.format(
00201 base=base_url,
00202 index=index
00203 )
00204 return url
00205
00206
00207 class InitState(NICTClientState):
00208 def __init__(self, base_url, language, pool):
00209 self._pool = pool
00210 self._language = language
00211 self._base_url = base_url
00212 self._request = None
00213
00214 def run(self, packet_data):
00215 pass
00216
00217 def next(self, packet_type):
00218 if packet_type == PacketType.START:
00219 logger.debug('Change session state INIT -> START')
00220 return StartState(
00221 self._base_url,
00222 1,
00223 self._language,
00224 None,
00225 self._pool
00226 )
00227
00228 else:
00229 logger.debug('Change session state INIT -> ERROR')
00230 return ErrorState(
00231 self._base_url,
00232 0,
00233 self._language,
00234 None,
00235 self._pool
00236 )
00237
00238 def result(self):
00239 return None
00240
00241 def state(self):
00242 return SessionState.INIT
00243
00244
00245 class StartState(NICTClientState):
00246 def __init__(self, base_url, index, language, cookie, pool):
00247 self._pool = pool
00248 self._language = language
00249 self._base_url = base_url
00250 self._index = index
00251 self._request = None
00252 self._cookie = cookie
00253
00254 def run(self, packet_data):
00255 url = self._create_url(self._base_url, self._index, False)
00256 self._request = StartRequest(url, self._language, self._cookie)
00257 self._request.request()
00258 response = self._request.response()
00259 if response:
00260 self._cookie = response.headers['set-cookie']
00261
00262 def next(self, packet_type):
00263 if self._request.has_error():
00264 logger.debug('Change session state START -> ERROR')
00265 return ErrorState(
00266 self._base_url,
00267 0,
00268 self._language,
00269 self._cookie,
00270 self._pool
00271 )
00272
00273 if packet_type == PacketType.DATA:
00274 logger.debug('Change session state START -> DATA')
00275 return DataState(
00276 self._base_url,
00277 self._index+1,
00278 self._language,
00279 self._cookie,
00280 self._pool
00281 )
00282
00283 elif packet_type == PacketType.END:
00284 logger.debug('Change session state START -> END')
00285 return EndState(
00286 self._base_url,
00287 self._index+1,
00288 self._language,
00289 self._cookie,
00290 self._pool
00291 )
00292
00293 else:
00294 logger.debug('Change session state START -> ERROR')
00295 return ErrorState(
00296 self._base_url,
00297 0,
00298 self._language,
00299 self._cookie,
00300 self._pool
00301 )
00302
00303 def result(self):
00304 return None
00305
00306 def state(self):
00307 return SessionState.START
00308
00309
00310 class DataState(NICTClientState):
00311 def __init__(self, base_url, index, language, cookie, pool):
00312 self._pool = pool
00313 self._language = language
00314 self._base_url = base_url
00315 self._index = index
00316 self._request = None
00317 self._cookie = cookie
00318
00319 def run(self, packet_data):
00320 url = self._create_url(self._base_url, self._index, False)
00321 self._request = DataRequest(url, packet_data, self._cookie)
00322 self._pool.add_request(self._request)
00323
00324 def next(self, packet_type):
00325 if packet_type == PacketType.DATA:
00326 logger.debug('Change session state DATA -> DATA')
00327 return DataState(
00328 self._base_url,
00329 self._index+1,
00330 self._language,
00331 self._cookie,
00332 self._pool
00333 )
00334
00335 elif packet_type == PacketType.END:
00336 logger.debug('Change session state DATA -> END')
00337 task_state = self._check_task_state()
00338 if task_state:
00339 return EndState(
00340 self._base_url,
00341 self._index+1,
00342 self._language,
00343 self._cookie,
00344 self._pool
00345 )
00346
00347 else:
00348 logger.debug('Change session state DATA -> ERROR')
00349 return ErrorState(
00350 self._base_url,
00351 0,
00352 self._language,
00353 self._cookie,
00354 self._pool
00355 )
00356
00357 elif packet_type == PacketType.START:
00358 task_state = self._check_task_state()
00359 return StartState(
00360 self._base_url,
00361 1,
00362 self._language,
00363 None,
00364 self._pool
00365 )
00366
00367 else:
00368 logger.debug('Change session state DATA -> ERROR')
00369 return ErrorState(
00370 self._base_url,
00371 0,
00372 self._language,
00373 self._cookie,
00374 self._pool
00375 )
00376
00377 def _check_task_state(self):
00378 self._pool.wait_completion()
00379 success = True
00380 while True:
00381 task = self._pool.get_finish_task(wait=False)
00382 if task:
00383 if task.has_error():
00384 success = False
00385 else:
00386 break
00387 return success
00388
00389 def result(self):
00390 return None
00391
00392 def state(self):
00393 return SessionState.DATA
00394
00395
00396 class EndState(NICTClientState):
00397 def __init__(self, base_url, index, language, cookie, pool):
00398 self._pool = pool
00399 self._language = language
00400 self._base_url = base_url
00401 self._index = index
00402 self._request = None
00403 self._cookie = cookie
00404 self._result_text = ''
00405
00406 def run(self, packet_data):
00407 url = self._create_url(self._base_url, self._index, True)
00408 self._request = EndRequest(url, self._cookie)
00409 self._request.request()
00410
00411 if not self._request.has_error():
00412 stml_text = self._request.result()
00413 root = ET.fromstring(stml_text)
00414 elem = root.find('.//s')
00415 if elem is not None:
00416 self._result_text = elem.text
00417
00418 if self._result_text is None:
00419 self._result_text = ''
00420
00421 def next(self, packet_type):
00422 if self._request.has_error():
00423 logger.debug('Change session state END -> ERROR')
00424 return ErrorState(
00425 self._base_url,
00426 0,
00427 self._language,
00428 self._cookie,
00429 self._pool
00430 )
00431
00432 if packet_type == PacketType.START:
00433 logger.debug('Change session state END -> START')
00434 return StartState(
00435 self._base_url,
00436 1,
00437 self._language,
00438 self._cookie,
00439 self._pool
00440 )
00441
00442 else:
00443 logger.debug('Change session state END -> ERROR')
00444 return ErrorState(
00445 self._base_url,
00446 0,
00447 self._language,
00448 self._cookie,
00449 self._pool
00450 )
00451
00452 def result(self):
00453 return self._result_text
00454
00455 def state(self):
00456 return SessionState.END
00457
00458
00459 class ErrorState(NICTClientState):
00460 def __init__(self, base_url, index, language, cookie, pool):
00461 self._pool = pool
00462 self._language = language
00463 self._base_url = base_url
00464 self._index = index
00465 self._request = None
00466 self._cookie = cookie
00467
00468 def run(self, packet_data):
00469 pass
00470
00471 def next(self, packet_type):
00472 if packet_type == PacketType.START:
00473 logger.debug('Change session state ERROR -> START')
00474 return StartState(
00475 self._base_url,
00476 1,
00477 self._language,
00478 None,
00479 self._pool
00480 )
00481
00482 else:
00483 logger.debug('Change session state ERROR -> ERROR')
00484 return ErrorState(
00485 self._base_url,
00486 0,
00487 self._language,
00488 self._cookie,
00489 self._pool
00490 )
00491
00492 def result(self):
00493 return None
00494
00495 def state(self):
00496 return SessionState.ERROR