Ejemplo n.º 1
0
def _complete_delete_operation(system_id):
    feed_ids = set()
    with dbconnection.inline_unit_of_work():
        system = systemqueries.get_by_id(system_id)
        for feed in system.feeds:
            feed_ids.add(feed.id)

    for feed_id in feed_ids:
        _delete_feed(system_id, feed_id)

    with dbconnection.inline_unit_of_work():
        systemqueries.delete_by_id(system_id)
Ejemplo n.º 2
0
def _delete_feed(system_id, feed_id):
    logger.info("Deleting feed {}/{}".format(system_id, feed_id))
    updatemanager.execute_feed_update(
        updatemanager.create_feed_flush(system_id, feed_id)
    )
    with dbconnection.inline_unit_of_work():
        feedqueries.delete_in_system_by_id(system_id, feed_id)
Ejemplo n.º 3
0
def _calculate_content_hash(context: _UpdateContext):
    m = hashlib.md5()
    m.update(context.content)
    context.feed_update.content_hash = m.hexdigest()
    with dbconnection.inline_unit_of_work():
        previous_hash = feedqueries.get_last_successful_update_hash(
            context.feed_update.feed.pk)
    if previous_hash is not None and previous_hash == context.feed_update.content_hash:
        context.feed_update.status = models.FeedUpdate.Status.SUCCESS
        context.feed_update.result = models.FeedUpdate.Result.NOT_NEEDED
Ejemplo n.º 4
0
def _initialize_update_context(feed_update_pk, content) -> _UpdateContext:
    with dbconnection.inline_unit_of_work() as session:
        feed_update = feedqueries.get_update_by_pk(feed_update_pk)
        feed = feed_update.feed
        feed_update.status = feed_update.Status.IN_PROGRESS
        # We need to flush the session to persist the status change.
        session.flush()
        session.expunge(feed_update)
        session.expunge(feed)
    return _UpdateContext(feed_update=feed_update, content=content)
Ejemplo n.º 5
0
def _import(context: _UpdateContext):
    feed_update = context.feed_update
    with dbconnection.inline_unit_of_work() as session:
        stats = import_.run_import(feed_update.pk, context.parser)

        feed_update.num_added_entities = stats.num_added()
        feed_update.num_updated_entities = stats.num_updated()
        feed_update.num_deleted_entities = stats.num_deleted()
        feed_update.num_parsed_entities = -1
        feed_update.status = models.FeedUpdate.Status.SUCCESS
        feed_update.result = models.FeedUpdate.Result.UPDATED

        session.merge(feed_update)
        return stats
Ejemplo n.º 6
0
def delete_by_id(system_id, error_if_not_exists=True, sync=True):
    """
    Delete a transit system
    """
    with dbconnection.inline_unit_of_work():
        system = systemqueries.get_by_id(system_id)
        if system is not None:
            system.status = models.System.SystemStatus.DELETING
            if not sync:
                system.id = system.id + "_deleting_" + str(uuid.uuid4())
                system_id = system.id
        elif error_if_not_exists:
            raise exceptions.IdNotFoundError
        else:
            return
    client.refresh_tasks()

    sync_to_function = {
        True: _complete_delete_operation,
        False: _complete_delete_operation_async.delay,
    }
    sync_to_function[sync](system_id)
Ejemplo n.º 7
0
def db_session(test_db):
    with dbconnection.inline_unit_of_work() as session:
        yield session
        session.rollback()
Ejemplo n.º 8
0
def set_auto_update_enabled(system_id, auto_update):
    with dbconnection.inline_unit_of_work():
        response = systemqueries.set_auto_update_enabled(system_id, auto_update)
    client.refresh_tasks()
    return response
Ejemplo n.º 9
0
def execute_feed_update(
    feed_update_pk,
    content=None
) -> typing.Tuple[models.FeedUpdate, typing.Optional[Exception]]:
    """
    Execute a feed update with logging and timing.

    For a description of what feed updates involve consult the module docs.
    """

    context = _initialize_update_context(feed_update_pk, content)

    if context.feed_update.update_type == models.FeedUpdate.Type.FLUSH:
        actions = _FLUSH_UPDATE_ACTIONS
    else:
        actions = _REGULAR_UPDATE_ACTIONS

    stats = None
    exception = None
    for action in actions:
        try:
            stats = action(context)
        except Exception as e:
            logger.exception("Exception encountered during update")
            exception_type_to_outcome = getattr(
                action, "__exception_type_to_outcome__", {})
            for exception_type, (status,
                                 result) in exception_type_to_outcome.items():
                if isinstance(e, exception_type):
                    context.feed_update.status = status
                    context.feed_update.result = result
                    context.feed_update.result_message = str(
                        traceback.format_exc())
                    exception = e
                    break
            if context.feed_update.result_message is None:
                context.feed_update.status = models.FeedUpdate.Status.FAILURE
                context.feed_update.result = models.FeedUpdate.Result.UNEXPECTED_ERROR
                context.feed_update.result_message = str(
                    traceback.format_exc())
                exception = e

        # If the action or one of its error handlers marked a status on the update, we
        # need to finish right now.
        if context.feed_update.status != models.FeedUpdate.Status.IN_PROGRESS:
            break

    context.feed_update.total_duration = time.time() - context.start_time
    context.feed_update.completed_at = datetime.datetime.utcnow()
    with dbconnection.inline_unit_of_work() as session:
        session.merge(context.feed_update)
    logger.info("{:7} / {:13} {:.2f} seconds / feed pk = {}.".format(
        context.feed_update.status.name,
        context.feed_update.result.name,
        context.feed_update.total_duration,
        context.feed_update.feed_pk,
    ))
    client.feed_update_callback(
        context.feed_update.feed_pk,
        context.feed_update.status,
        context.feed_update.result,
        stats.entity_type_to_num_in_db() if stats is not None else {},
    )
    return context.feed_update, exception