Skip to content
This repository has been archived by the owner on Jan 31, 2018. It is now read-only.

Commit

Permalink
[bug 1018727] Backfill translations
Browse files Browse the repository at this point in the history
This adds a "backfill translations" form to the admin allowing us to
backfill missing translations for responses. It's rough, but probably
good enough for now.
  • Loading branch information
willkg committed Jul 14, 2014
1 parent 2d3112a commit 44e702b
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 3 deletions.
3 changes: 3 additions & 0 deletions fjord/feedback/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ def generate_translation_jobs(self, system=None):
Otherwise we generate a list of jobs to be done.
"""
if self.translated_description:
return []

# If the text is coming from an English-speaking locale, we
# assume it's also in English and just copy it over. We do
# this regardless of whether auto-translation is enabled or
Expand Down
1 change: 1 addition & 0 deletions fjord/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@
'fjord.grappellioverride',
'grappelli',
'django.contrib.admin',
'django.contrib.messages',
'django_extensions',
'django_nose',
'djcelery',
Expand Down
57 changes: 56 additions & 1 deletion fjord/translations/admin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from datetime import datetime, timedelta

from django.conf import settings
from django.contrib import admin
from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.utils.module_loading import import_by_path

from .gengo_utils import FjordGengo
from .models import GengoJob, GengoOrder
from .tasks import create_translation_tasks
from .utils import locale_equals_language
from fjord.base.util import smart_date, smart_str
from fjord.feedback.models import Product
from fjord.journal.models import Record

Expand Down Expand Up @@ -143,6 +147,57 @@ def gengo_translator_view(request):
'Translations - Gengo Maintenance')


def translations_management_backfill_view(request):
"""Takes start and end dates and a model and backfills translations"""
date_start = smart_date(request.POST.get('date_start'))
date_end = smart_date(request.POST.get('date_end'))
model = smart_str(request.POST.get('model'))

if request.method == 'POST':
# NB: We just let the errors propagate because this is an
# admin page. That way we get a traceback and all that detail.

model_cls = import_by_path(model)

# FIXME: This assumes the model has a "created" field. If it
# doesn't, then this breaks. When we have another model that we
# want to translate, we can figure out how to generalize this
# then.
objects = model_cls.objects.filter(
created__gte=date_start,
created__lte=date_end
)

total_jobs = 0

for instance in objects:
total_jobs += len(create_translation_tasks(instance))

messages.success(request, '%s jobs added' % total_jobs)
return HttpResponseRedirect(request.path)

from fjord.translations.tasks import REGISTERED_MODELS
model_classes = [
cls.__module__ + '.' + cls.__name__
for cls in REGISTERED_MODELS
]

return render(request, 'admin/translations_backfill.html', {
'title': 'Translations - General Maintenance - Backfill',
'settings': settings,
'model_classes': model_classes,
'date_start': request.POST.get('date_start', ''),
'date_end': request.POST.get('date_end', ''),
'model': request.POST.get('model', '')
})


admin.site.register_view(
'translations-management-backfill-view',
translations_management_backfill_view,
'Translations - General - Backfill')


def translations_management_view(request):
"""Covers general translation system status"""
# We want to order the record objects by whichever column was
Expand Down
11 changes: 9 additions & 2 deletions fjord/translations/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def create_translation_tasks(instance, system=None):
"""Generate translation tasks for a given translateable instance"""
jobs = instance.generate_translation_jobs(system=system)
if not jobs:
return
return []

for key, system, src_lang, src_field, dst_lang, dst_field in jobs:
if not getattr(instance, src_field).strip():
Expand All @@ -49,6 +49,8 @@ def create_translation_tasks(instance, system=None):
translate_task.delay(key, system, src_lang, src_field,
dst_lang, dst_field)

return jobs


def translate_handler(sender, instance=None, created=False, **kwargs):
"""post-save handler that generates translation jobs
Expand All @@ -66,6 +68,10 @@ def translate_handler(sender, instance=None, created=False, **kwargs):
return create_translation_tasks(instance)


# Set of models registered for translation.
REGISTERED_MODELS = set()


def register_auto_translation(model_cls):
"""Decorator that Registers model class for automatic translation
Expand All @@ -81,6 +87,7 @@ def register_auto_translation(model_cls):
that we can save the data back to the instance later.
"""
uid = str(model_cls) + 'translation'
uid = '-'.join([model_cls.__module__, model_cls.__name__, 'translation'])
post_save.connect(translate_handler, model_cls, dispatch_uid=uid)
REGISTERED_MODELS.add(model_cls)
return model_cls
62 changes: 62 additions & 0 deletions fjord/translations/templates/admin/translations_backfill.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{% extends "admin/base_site.html" %}
{% block content_title %}
<h1>Translations - Maintenance - Backfill</h1>
{% endblock %}

{% block extrastyle %}
{{ block.super }}
<style type="text/css">
section {
clear: both;
margin: 1em 0em 1em 0em;
}
div#content div {
margin-bottom: .5em;
}
</style>
{% endblock %}

{% block content %}
<section>
<p class="errornote">
Be very careful how you fill out this form. It can create lots
of translation jobs. If you make a mistake, you might need an
account on the translation system in question and then have to
remove them by hand.
</p>
</section>

<section>
<form action="{{ request.path }}" method=POST>
{% csrf_token %}
<table>
<tr>
<th>Date start (yyyy-mm-dd)</th>
<td>
<input type="text" name="date_start" value="{{ date_start }}">
</td>
</tr>
<tr>
<th>Date end (yyyy-mm-dd)</th>
<td>
<input type="text" name="date_end" value="{{ date_end }}">
</td>
</tr>
<tr>
<th>Model</th>
<td>
<select name="model">
{% for cls in model_classes %}
<option value="{{ cls }}">{{ cls }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="Submit"></td>
</tr>
</table>
</form>
</section>
{% endblock %}

0 comments on commit 44e702b

Please sign in to comment.