py-phias/aore/search/fiasfactory.py
2016-03-16 22:18:36 +03:00

100 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import logging
import re
import urllib
from uuid import UUID
import psycopg2
import traceback
from bottle import template
from aore.config import DatabaseConfig, BasicConfig
from aore.dbutils.dbimpl import DBImpl
from search import SphinxSearch
class FiasFactory:
def __init__(self):
self.db = DBImpl(psycopg2, DatabaseConfig)
self.searcher = SphinxSearch(self.db)
self.expand_templ = template('aore/templates/postgre/expand_query.sql', aoid="//aoid")
self.normalize_templ = template('aore/templates/postgre/normalize_query.sql', aoid="//aoid")
# Проверка, что строка является действительым UUID v4
@staticmethod
def __check_uuid(guid):
try:
UUID(guid)
except ValueError:
return False
return True
# Проверяет входящий параметр на соотвествие
# param - сам параметр
# rule - "boolean", "uuid", "text"
def __check_param(self, param, rule):
if rule == "boolean":
assert isinstance(param, bool), "Invalid parameter type"
if rule == "uuid":
assert (isinstance(param, str) or isinstance(param, unicode)) and self.__check_uuid(
param), "Invalid parameter value"
if rule == "text":
assert isinstance(param, str) or isinstance(param, unicode), "Invalid parameter type"
assert len(param) > 3, "Text too short"
pattern = re.compile(r"[A-za-zА-Яа-я \-,.#№]+")
assert pattern.match(param), "Invalid parameter value"
# text - строка поиска
# strong - строгий поиск (True) или "мягкий" (False) (с допущением ошибок, опечаток)
# Строгий используется при импорте из внешних систем (автоматически), где ошибка критична
def find(self, text, strong=False):
try:
text = urllib.unquote(text).decode('utf8')
self.__check_param(text, "text")
self.__check_param(strong, "boolean")
results = self.searcher.find(text, strong)
except Exception, err:
if BasicConfig.logging:
logging.error(traceback.format_exc(err))
return dict(error=err.args[0])
return results
# Нормализует подаваемый AOID или AOGUID в актуальный AOID
def normalize(self, aoid_guid):
try:
self.__check_param(aoid_guid, "uuid")
sql_query = self.normalize_templ.replace("//aoid", aoid_guid)
rows = self.db.get_rows(sql_query, True)
except Exception, err:
if BasicConfig.logging:
logging.error(traceback.format_exc(err))
return dict(error=err.args[0])
if len(rows) == 0:
return []
else:
return rows[0]
# Разворачивает AOID в представление (перед этим нормализует)
def expand(self, aoid_guid):
try:
self.__check_param(aoid_guid, "uuid")
normalized_id = self.normalize(aoid_guid)
assert 'aoid' in normalized_id, "AOID or AOGUID not found in DB"
normalized_id = normalized_id['aoid']
sql_query = self.expand_templ.replace("//aoid", normalized_id)
rows = self.db.get_rows(sql_query, True)
except Exception, err:
if BasicConfig.logging:
logging.error(traceback.format_exc(err))
return dict(error=err.args[0])
return rows