diff --git a/aore/fias/fiasfactory.py b/aore/fias/fiasfactory.py index edb9e2b..23e2656 100644 --- a/aore/fias/fiasfactory.py +++ b/aore/fias/fiasfactory.py @@ -5,6 +5,8 @@ from bottle import template from aore.dbutils.dbimpl import DBImpl from aore.fias.search import SphinxSearch from aore.config import db_conf +from uuid import UUID +import re class FiasFactory: @@ -14,24 +16,52 @@ class FiasFactory: 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 + def __check_uuid(self, 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 type(param) is bool, "Invalid parameter type" + if rule == "uuid": + assert (type(param) is str or type(param) is unicode) and self.__check_uuid(param), "Invalid parameter value" + if rule == "text": + assert type(param) is str or type(param) is unicode, "Invalid parameter type" + assert len(param) > 3, "Text too short" + pattern = re.compile("[A-za-zА-Яа-я \-,.#№]+") + assert pattern.match(param), "Invalid parameter value" + # text - строка поиска # strong - строгий поиск (True) или "мягкий" (False) (с допущением ошибок, опечаток) # Строгий используется при импорте из внешних систем (автоматически), где ошибка критична def find(self, text, strong=False): try: + self.__check_param(text, "text") + self.__check_param(strong, "boolean") + results = self.searcher.find(text, strong) except Exception, err: - return dict(error=err.args[0]) + return dict(error=err.message) 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: - return dict(error=err.args[0]) + return dict(error=err.message) if len(rows) == 0: return [] @@ -41,14 +71,15 @@ class FiasFactory: # Разворачивает AOID в представление (перед этим нормализует) def expand(self, aoid_guid): try: + self.__check_param(aoid_guid, "uuid") + normalized_id = self.normalize(aoid_guid) - if 'aoid' not in normalized_id: - raise BaseException("Invalid AOID or AOGUID") - else: - normalized_id = normalized_id['aoid'] + 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: - return dict(error=err.args[0]) + return dict(error=err.message) return rows diff --git a/manage.py b/manage.py index 0d61134..5ca6e56 100644 --- a/manage.py +++ b/manage.py @@ -65,23 +65,24 @@ def main(): # Parse options p = optparse.OptionParser() p.add_option('--database', '-b', action="store", type="string", - help="Manage database. Values: " + help="Database management. Values: " "create - create new DB, " - "update - update existing DB without loose the data") + "update - update existing DB without losing the data") p.add_option('--update-version', '-u', default="all", type="string", - help="Valid for updating via HTTP. " - "Versions of updates to process. Can be 111 or 111-222 or 111,222,333." - "For '--database-create' only one value is necessary. If not specified, " + help="Valid only for updating via HTTP. " + "Version update numbers for processing. Can be 111 or 111-222 or 111,222,333." + "For '--database-create' only one value (like 111) may be specified. If not specified, " "all updates will be processed (for '--database update') or last DB snapshot " "(for '--database create')") p.add_option('--show-versions', '-v', action="store_true", dest="show_versions", default=False, - help="Show allowed fias versions") + help="Show available fias versions. " + "These version numbers are required for the '--update-version' option") p.add_option('--source', '-s', default="http", help="Create/update DB from source. Value: 'http' or absolute path to folder containing XMLs") p.add_option('--sphinx-configure', '-c', action="store_true", dest="sphinx", default="False", - help="Configure sphinx. Creates sphinx.conf specified in '--output-conf'") + help="Configure Sphinx. Creates a sphinx.conf file specified in '--output-conf'") p.add_option('--indexer-path', '-i', - help="Path to sphinx indexer binary. Required for '--sphinx-configure'") + help="Path to Sphinx indexer binary. Required for '--sphinx-configure'") p.add_option('--output-conf', '-o', help="Output config filename. Required for '--sphinx-configure'") p.add_option('--test', '-t', action="store_true", dest="test", @@ -118,7 +119,7 @@ def main(): if options.test: sph = FiasFactory() print json.dumps(sph.normalize("463ce8e4-928b-45cc-be76-46c2494632b6")) - print json.dumps(sph.expand("453091f5-2336-4aea-9b90-c4060dca0b33")) + print json.dumps(sph.expand("463ce8e4-928b-45cc-be76-46c2494632b6")) print json.dumps(sph.find('ул кемровая пасраул алтай майминский р-н')) diff --git a/setup.py b/setup.py index 5e2f55a..b7d1587 100644 --- a/setup.py +++ b/setup.py @@ -8,11 +8,12 @@ setup( license='', author='hellotan', author_email='hellotan@live.ru', - description='Python application that can operate with FIAS (Russian Address Object DB)', requires=['lxml', - 'bottle', - 'pysimplesoap', - 'python-Levenshtein', - 'enum34', - 'rarfile', - 'requests'] + description='Python application that can operate with FIAS (Russian Address Object DB)', + requires=['lxml', + 'bottle', + 'pysimplesoap', + 'python-Levenshtein', + 'enum34', + 'rarfile', + 'requests'] )