Example #1
0
def index():
    """Application main route.

    Responding to a GET request, it renders a single-page application
    with a form to input an English text to be translated and a table
    containing a list of previous translations ordered by the length
    or the translated text.

    Responding to a POST request it validates if the form (avoiding a
    blank input), creates a new Translation aggregate with the given
    input and then saves it to the repository to be processesd in the
    background (and re-processed if the application breaks for some
    reason before enqueuing the task).

    Args:
        page (int): There is a limit of translations displayed per page,
            and a page can be selected passing this URL argument.

    """
    form = TranslationForm()

    if form.validate_on_submit():
        # POST handling
        logger.debug(f'processing POST "/"')

        text = form.text.data
        text = text.replace("'", "\\'")
        text = text.replace('\r', '')
        text = text.replace('\n', '')
        translation = Translation.create(text)

        repository.save(translation)

        method = form.method.data
        if method == 'mt':
            tasks.nmt_task.send(translation.id)
        else:
            tasks.translation_task.send(translation.id)
        tasks.projections_task.send(translation.id)

        return redirect(url_for('index'))

    # GET handling
    page = request.args.get('page', 1, type=int)
    translations = projections.get(page)
    logger.debug(
        f'processing GET "/json", page:{page}/{translations.last_page}')

    next_url = url_for('index', page=translations.next_page) \
        if translations.has_next else None
    prev_url = url_for('index', page=translations.prev_page) \
        if translations.has_prev else None

    return render_template('index.html',
                           form=form,
                           translations=translations.items,
                           next_url=next_url,
                           prev_url=prev_url)
Example #2
0
def nmt_task(id):
    """ Task for automatically processing a translation.

    This task is responsible for requesting the Marian-NMT server to
    translate a given text from English to Spanish.

    The Translation aggregate is already created and persisted, so this
    task must fetch its data. If for some reason the application goes
    down, it's possible to reprocess "requested" translations adding
    their IDs to the workers queue.

    Args:
        id (string): The translation aggregate UUID4 string.
    """
    translation = repository.get(id)
    translation = translator.nmt_process(translation)
    repository.save(translation)
    projections_task.send(id)
Example #3
0
def callback(id=None):
    """Callback route to update a Translation resource.

    This route is used by an external translation service to notify it
    finished processing a text.

    Args:
        id (str): The Translation aggregate ID to update it.

    """
    if id:
        logger.debug(f'processing POST "/callback/{id}"')
        translation = repository.get(id)
        translation = translator.get(translation)
        repository.save(translation)
        tasks.projections_task.send(id)
        return jsonify(success=True)

    return jsonify(error=404, text="Resource not found.")
Example #4
0
def translation_task(id):
    """ Task for processing a translation.

    This task is responsible for requesting the translation service to
    translated a given text from English to Spanish.

    The Translation aggregate is already created and persisted, so this
    task must fetch its data. If for some reason the application goes
    down, it's possible to reprocess "requested" translations adding
    their IDs to the workers queue.

    After sending a request to the translation service, this worker will
    persist a tracking identifier and poll this translation until it's
    finished.

    Args:
        id (string): The translation aggregate UUID4 string.
    """
    translation = repository.get(id)
    translation = translator.process(translation)
    repository.save(translation)
    projections_task.send(id)