Beispiel #1
0
 def app_after_request(response):
     """
     После каждого запроса надо инвалидировать реестр справочников, ибо неизвестно, что произошло с ними в
     других процессах
     """
     from nvesta.library.rb.registry import RefBookRegistry
     RefBookRegistry.invalidate()
     return response
Beispiel #2
0
def update_nsi_dicts():
    parser = argparse.ArgumentParser()
    parser.add_argument('--all',
                        action='store_const',
                        const=True,
                        default=False)
    parser.add_argument('--list',
                        action='store_const',
                        const=True,
                        default=False)
    parser.add_argument('--host', default=None)
    parser.add_argument('--port', default=None)
    parser.add_argument('--url', default=url)
    parser.add_argument('--key', default=key)
    parser.add_argument('--db', default=nvesta_db)

    args = parser.parse_args(sys.argv[1:])

    mongo = pymongo.MongoClient(
        host=args.host,
        port=args.port,
    )

    RefBookRegistry.bootstrap(mongo[args.db])
    client = NsiClient(url=args.url, user_key=args.key)

    print('Retrieving data from NSI')
    listed = list_nsi_dictionaries(client)

    cooked = [(their['code'], their['name'],
               safe_traverse(our, 'version',
                             default='?'), their.get('version', 0), their)
              for our, their in ((safe_dict(desc['our']),
                                  safe_dict(desc['their']))
                                 for desc in listed)]

    if args.list:
        for code, name, our, their, nsi_dict in cooked:
            print('%s %s %s->%s' % (code, name, our, their))
    elif args.all:
        to_update = [(code, name, our, their, nsi_dict)
                     for code, name, our, their, nsi_dict in cooked
                     if their != our]
        for code, name, our, their, nsi_dict in to_update:
            print('%s %s %s->%s' % (code, name, our, their))
            print 'Updating (%s) %s...' % (code, name)
            nsi_dict['version'] = their
            import_nsi_dict(nsi_dict, client)
        if not to_update:
            print('Nothing to update')
Beispiel #3
0
def list_nsi_dictionaries(nsi_client):
    result = nsi_client.getRefbookList() or []
    final = []
    for nsi_dict_raw in result:
        if nsi_dict_raw.key == 'errors':
            raise ApiException(
                500, u'Ошибка доступа к НСИ:\n%s' %
                (u'\n'.join(u'%s: %s' % (item.key, item.value)
                            for item in nsi_dict_raw.children.item)))
        nsi_dict = prepare_dictionary(nsi_dict_raw)
        code = nsi_dict['code']
        try:
            # Пытаемся понять, какая версия справочника нынче актуальна
            nsi_dict['version'] = prepare_dictionary(
                nsi_client.getVersionList(code)[-1])['version']
        except (IndexError, ValueError):
            continue
        meta = None
        try:
            rb = RefBookRegistry.get(code)
            meta = rb.meta
        except KeyError:
            pass
        final.append({
            'their': nsi_dict,
            'our': meta,
        })
    return final
Beispiel #4
0
def get_data_hs(code, field, field_value):
    rb = RefBookRegistry.get(code)
    find = {field: field_value}
    doc = rb.find_one(find)
    if rb.meta.oid:
        # Работаем с НСИ справочником
        data = doc
        oid = rb.meta.oid
    else:
        # Переключаемся на НСИ справочник
        link_meta = rb.meta.primary_link
        linked_rb = rb.get_primary_linked_rb()
        if not linked_rb or not linked_rb.meta.oid:
            raise ApiException(404, u'Нет связанного справочника НСИ')
        data = linked_rb.find_one(
            {link_meta.right_field: doc[link_meta.left_field]})
        oid = linked_rb.meta.oid
    if data:
        data = _prepare_hs_response(data, code)
    else:
        data = {}
    return {
        'oid': oid,
        'data': data,
    }
Beispiel #5
0
    def as_json(self, edge=True, with_meta=False):
        from nvesta.library.rb.registry import RefBookRegistry

        if edge:
            data = self.meta.edit or self.data
        else:
            data = self.data

        result = {}
        for description in self.rb.meta.fields:
            key = description.key
            value = data.get(key)
            result[key] = value
            if description.link:
                add_key = description.link['key']
                rb_code = description.link['code']
                rb_field = description.link['linked_field']
                as_list = description.link.get('list')
                ref_book = RefBookRegistry.get(rb_code)
                if as_list:
                    result[add_key] = ref_book.find({rb_field: value})
                else:
                    result[add_key] = ref_book.find_one({rb_field: value})

        if self._id:
            result['_id'] = str(self._id)

        if with_meta:
            _meta = self.meta.__json__()
            dirty = bool(_meta.pop('edit', False))
            result['_meta'] = dict(_meta, dirty=dirty)
        return result
Beispiel #6
0
def dictionary_put(rb_code, document_id):
    data = force_json(request)
    rb = RefBookRegistry.get(rb_code)
    data['_id'] = bson.ObjectId(document_id)
    record = rb.record_factory(data)
    rb.save(record)
    return document_id
Beispiel #7
0
def v1_get_document_by_field(rb_code, field, value):
    if field == 'id':
        value = int(value)
    elif field == '_id':
        value = bson.ObjectId(value)
    rb = RefBookRegistry.get(rb_code)
    return rb.find_one(field, value)
Beispiel #8
0
def find_data_hs(code):
    data = force_json(request)

    rb = RefBookRegistry.get(code)

    ret_data = rb.meta.__json__()
    ret_data['data'] = rb.find_one(prepare_find_params(data))
    return ret_data
Beispiel #9
0
def rb_post():
    """
    Создание нового справочника
    :return:
    """
    j = flask.request.get_json()
    rb = RefBookRegistry.create(j)
    return rb.meta
Beispiel #10
0
def kladr_maintenance():
    with log_context(['kladr', 'maintenance']) as log:
        log.log(u'Проверяем индексы на справочнике STR172 (улицы)')
        rb = RefBookRegistry.get('STR172')
        log.log(u'   name')
        rb.collection.create_index([('name', ASCENDING)])
        log.log(u'   identcode')
        rb.collection.create_index([('identcode', ASCENDING)])
        log.log(u'   identparent')
        rb.collection.create_index([('identparent', ASCENDING)])

        log.log(u'Проверяем индексы на справочнике KLD172 (регионы)')
        rb = RefBookRegistry.get('KLD172')
        log.log(u'   name + level')
        rb.collection.create_index([('name', ASCENDING), ('level', ASCENDING)])
        log.log(u'   identparent')
        rb.collection.create_index([('identcode', ASCENDING)])
Beispiel #11
0
def kladr_maintenance():
    parser = argparse.ArgumentParser()
    parser.add_argument('--host', default=None)
    parser.add_argument('--port', default=None)
    parser.add_argument('--db', default=nvesta_db)

    args = parser.parse_args(sys.argv[1:])

    mongo = pymongo.MongoClient(
        host=args.host,
        port=args.port,
    )

    RefBookRegistry.bootstrap(mongo[args.db])

    from nvesta.library.nsi.data import kladr_maintenance
    kladr_maintenance()
Beispiel #12
0
    def get_primary_linked_rb(self):
        """
        Получение справочника по первичной связке
        @return: Справочник
        @rtype: RefBook | NoneType
        """
        if self.meta.primary_link.right_rb_code:
            from nvesta.library.rb.registry import RefBookRegistry

            return RefBookRegistry.get(self.meta.primary_link.right_rb_code)
Beispiel #13
0
def rb_get(rb_code):
    """
    Получение метаданных справочника
    :param rb_code:
    :return:
    """
    rb = RefBookRegistry.get(rb_code)
    if rb_code:
        return rb.meta
    raise ApiException(404, 'Reference Book not found')
Beispiel #14
0
def rb_put(rb_code):
    """
    Изменение метаданных справочника
    :param rb_code:
    :return:
    """
    j = flask.request.get_json()
    rb = RefBookRegistry.get(rb_code)
    rb.meta.update(j)
    rb.meta.reshape()
    return rb.meta
Beispiel #15
0
def _get_parents(city):
    rb = RefBookRegistry.get(CITY_CODE)
    result = []

    def _get_parent(c, f=False):
        if c['identparent']:
            _get_parent(rb.find_one({'identcode': c['identparent']}))
        if not f:
            result.append(_safe_city(c))

    _get_parent(city, True)
    return result
Beispiel #16
0
def rb_list_get():
    """
    Список всех имеющихся справочников
    :return:
    """
    rb_list = RefBookRegistry.list()
    result = [
        d.meta
        for d in rb_list
    ]
    result.sort(key=lambda meta: meta.code)
    return result
Beispiel #17
0
def v1_dictionary_post(rb_code):
    data = force_json(request)
    rb = RefBookRegistry.get(rb_code)
    if isinstance(data, list):
        id_list = []
        for doc in data:
            record = rb.record_factory(doc)
            rb.save(record)
            id_list.append(record.data.get('_id'))
        return {'_id': id_list}
    record = rb.record_factory(data)
    rb.save(record)
    return {'_id': record.data.get('_id')}
Beispiel #18
0
def search_city_country(value, limit=None):
    rb = RefBookRegistry.get(CITY_CODE)
    find = {
        'is_actual': '1',
        '$or': [{
            'name': prepare_find_params(value)
        }, {
            'identcode': value
        }]
    }
    cities = rb.find(find, 'level', limit)
    result = _set_cities_parents(cities)
    return result
Beispiel #19
0
def rb_record_get_id(rb_code, field, rec_id):
    """
    Получение записи из справочника
    :param rb_code:
    :param rec_id:
    :return:
    """
    rb = RefBookRegistry.get(rb_code)
    edge = bool(flask.request.args.get('edge', False))
    with_meta = bool(flask.request.args.get('with-meta', False))
    version = edge and EdgeVersion or flask.request.args.get('version') or None
    record = rb.find_one(field, rec_id, version=version)
    return record.as_json(edge, with_meta)
Beispiel #20
0
def autofix():
    parser = argparse.ArgumentParser()
    parser.add_argument('--all',
                        action='store_const',
                        const=True,
                        default=False)
    parser.add_argument('--host', default=None)
    parser.add_argument('--port', default=None)
    parser.add_argument('--db', default=nvesta_db)
    parser.add_argument('--list',
                        action='store_const',
                        const=True,
                        default=False)
    parser.add_argument('version')

    args = parser.parse_args(sys.argv[1:])

    mongo = pymongo.MongoClient(
        host=args.host,
        port=args.port,
    )

    RefBookRegistry.bootstrap(mongo[args.db])

    refbooks = RefBookRegistry.list()
    to_fix = set(rb for rb in refbooks if not rb.meta.version)
    if args.list:
        for rb in to_fix:
            print(u"%s -- %s" % (rb.code, rb.name))
    elif args.all:
        for rb in refbooks:
            if rb in to_fix:
                rb.fixate(args.version)
            else:
                rb._fix_meta(args.version)
    else:
        parser.print_help()
Beispiel #21
0
def rb_records_get(rb_code):
    """
    Получение всех данных из справочника
    :param rb_code:
    :return:
    """
    skip = flask.request.args.get('skip') or None
    limit = flask.request.args.get('limit') or 100
    edge = bool(flask.request.args.get('edge', False))
    with_meta = bool(flask.request.args.get('with-meta', False))
    version = edge and EdgeVersion or flask.request.args.get('version') or None
    rb = RefBookRegistry.get(rb_code)
    return [
        record.as_json(edge, with_meta)
        for record in rb.find({}, 'code', limit=limit, skip=skip, version=version)
    ]
Beispiel #22
0
def search_street(city_code, value=None, limit=None):
    rb = RefBookRegistry.get(STREET_CODE)
    find = {'identparent': city_code, 'is_actual': '1'}
    if value:
        prepared = prepare_find_params(value)
        find.update({
            '$or': [{
                'name': prepared
            }, {
                'fulltype': prepared
            }, {
                'shorttype': prepared
            }, {
                'identcode': value
            }]
        })
    result = rb.find(find, 'name', limit)
    return list(result)
Beispiel #23
0
 def refbooks_dict(self):
     from nvesta.library.rb.registry import RefBookRegistry
     return {
         code: RefBookRegistry.get(code)
         for code in self.codes if RefBookRegistry.get(code)
     }
Beispiel #24
0
def migrate_from_v1():
    def blocks(iterable, max_size=2000):
        result = []
        i = 0
        for item in iterable:
            result.append(item)
            i += 1
            if i >= max_size:
                yield result
                result = []
                i = 0
        if result:
            yield result

    def get_field_codes(collection):
        codes = set()
        for row in collection.find():
            codes |= set(row.keys())
        codes.discard('_id')
        return codes

    parser = argparse.ArgumentParser()
    parser.add_argument('--all',
                        action='store_const',
                        const=True,
                        default=False)
    parser.add_argument('--host', default=None)
    parser.add_argument('--port', default=None)
    parser.add_argument('--from-db', default='vesta')
    parser.add_argument('--db', default=nvesta_db)

    args = parser.parse_args(sys.argv[1:])

    mongo = pymongo.MongoClient(
        host=args.host,
        port=args.port,
    )

    RefBookRegistry.bootstrap(mongo[args.db])

    db_vesta = mongo[args.from_db]
    RefBookRegistry.bootstrap(mongo[args.db])

    processed_dicts = {'dict_names'}
    processed_dicts.update(set(RefBookRegistry.names()))

    for v_description in db_vesta['dict_names'].find():
        code = v_description.get('code')
        if code in processed_dicts:
            continue
        v_collection = db_vesta[code]
        count = v_collection.count()

        print 'Transferring', str(count).rjust(6), code

        primary_link = None
        linked = v_description.get('linked')
        if linked:
            primary_link = {
                'left_field': linked['origin_field'],
                'right_field': linked['linked_field'],
                'right_rb': linked['collection']['code'],
            }

        rb = RefBookRegistry.create({
            'code':
            code,
            'name':
            v_description.get('name') or code,
            'description':
            v_description.get('description'),
            'oid':
            v_description.get('oid'),
            'fields': [{
                'key': fc,
                'mandatory': fc == 'code',
            } for fc in sorted(get_field_codes(v_collection))],
            'primary_link':
            primary_link,
            'version':
            safe_traverse(v_description, 'version', 'version', default=None)
        })

        for block in blocks(v_collection.find()):
            rb.save_bulk(rb.record_factory(raw) for raw in block)

        processed_dicts.add(code)

    for code in db_vesta.collection_names(False):
        if code in processed_dicts:
            continue

        v_collection = db_vesta[code]
        count = v_collection.count()

        print 'Transferring', str(count).rjust(6), code

        rb = RefBookRegistry.create({
            'code':
            code,
            'name':
            code,
            'description':
            '',
            'oid':
            '',
            'fields': [{
                'key': fc,
                'mandatory': fc == 'code',
            } for fc in sorted(get_field_codes(v_collection))],
            'primary_link':
            None,
        })

        for block in blocks(v_collection.find()):
            rb.save_bulk(rb.record_factory(raw) for raw in block)

    RefBookRegistry.bootstrap(mongo[args.db])
Beispiel #25
0
def rb_version_fix(rb_code):
    version = flask.request.args.get('version') or bail_out(ApiException(400, 'Need "version" argument'))
    rb = RefBookRegistry.get(rb_code)
    rb.fixate(version)
    return rb.meta
Beispiel #26
0
def rb_diff(rb_code):
    rb = RefBookRegistry.get(rb_code)
    return [
        record.as_json(True, True)
        for record in rb.find({}, version=DiffVersion)
    ]
Beispiel #27
0
def rb_record_post(rb_code):
    rb = RefBookRegistry.get(rb_code)
    record = rb.record_factory()
    record.update(flask.request.get_json())
    record.save()
    return record.as_json(True, True)
Beispiel #28
0
def rb_record_delete(rb_code, field, rec_id):
    rb = RefBookRegistry.get(rb_code)
    record = rb.find_one(field, rec_id, version=EdgeVersion)
    record.delete()
    record.save()
    return record.as_json(True, True)
Beispiel #29
0
def rb_record_put_id(rb_code, field, rec_id):
    rb = RefBookRegistry.get(rb_code)
    record = rb.find_one(field, rec_id, version=EdgeVersion)
    record.update(flask.request.get_json())
    record.save()
    return record.as_json(True, True)
Beispiel #30
0
 def refbooks_metas(self):
     from nvesta.library.rb.registry import RefBookRegistry
     return [
         RefBookRegistry.get(code).meta for code in self.codes
         if RefBookRegistry.get(code)
     ]