[damned-lies: 18/18] merge: from 'develop'
- From: Guillaume Bernard <gbernard src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [damned-lies: 18/18] merge: from 'develop'
- Date: Wed, 5 Oct 2022 15:02:42 +0000 (UTC)
commit 35770e0c3ddd8e0d1ba04a7586cbf99c98eb2216
Merge: deeb1429 99fcc47f
Author: Guillaume Bernard <associations guillaume-bernard fr>
Date: Wed Oct 5 17:00:28 2022 +0200
merge: from 'develop'
.gitlab-ci.yml | 4 +-
.pre-commit-config.yaml | 16 +
CONTRIBUTING.md | 13 +-
README.md | 55 +-
api/tests.py | 225 ++--
api/urls.py | 42 +-
api/views.py | 228 ++--
common/backends.py | 4 +-
common/context_processors.py | 2 +-
common/fields.py | 5 +-
common/middleware.py | 4 +-
common/templatetags/list_to_columns.py | 4 +-
common/tests.py | 107 +-
common/utils.py | 61 +-
common/views.py | 95 +-
containers/build_buildah_runtime.sh | 1 -
.../configuration/local_settings.py.jinja2 | 6 +
.../production/render_configuration_templates.sh | 5 +
damnedlies/context_processors.py | 12 +
damnedlies/settings.py | 214 +--
damnedlies/settings_tests.py | 8 +-
damnedlies/urls.py | 156 +--
docs/source/conf.py | 46 +-
feeds/urls.py | 6 +-
languages/admin.py | 3 +-
languages/management/commands/load-plurals.py | 218 ++--
languages/migrations/0001_initial.py | 23 +-
languages/models.py | 35 +-
languages/tests.py | 24 +-
languages/urls.py | 32 +-
languages/views.py | 139 +-
people/admin.py | 7 +-
people/forms.py | 107 +-
people/migrations/0001_initial.py | 62 +-
.../0002_set_use_gravatar_verbose_name.py | 10 +-
people/migrations/0003_person_avatar_service.py | 13 +-
people/migrations/0004_migrate_use_gravatar.py | 5 +-
.../migrations/0005_remove_person_use_gravatar.py | 6 +-
.../0006_remove_person_bugzilla_account.py | 6 +-
people/migrations/0007_person_auth_token.py | 8 +-
people/models.py | 83 +-
people/templatetags/people.py | 15 +-
people/tests.py | 227 ++--
people/urls.py | 36 +-
people/views.py | 84 +-
pyproject.toml | 8 +-
requirements-dev.txt | 4 +
requirements.txt | 3 +-
setup.py | 5 +-
stats/admin.py | 151 ++-
stats/doap.py | 40 +-
stats/forms.py | 55 +-
stats/management/commands/archive-release.py | 28 +-
stats/management/commands/compile-trans.py | 25 +-
stats/management/commands/run-maintenance.py | 2 +-
stats/management/commands/update-from-doap.py | 7 +-
stats/management/commands/update-stats.py | 68 +-
stats/management/commands/update-trans.py | 7 +-
stats/migrations/0001_initial.py | 368 ++++--
stats/migrations/0002_add_category_name.py | 20 +-
stats/migrations/0003_migrate_category_names.py | 40 +-
stats/migrations/0004_remove_old_cat_name.py | 20 +-
stats/migrations/0005_update_module_name_field.py | 21 +-
stats/migrations/0006_add_domain_branch_from_to.py | 31 +-
stats/migrations/0007_extend_bugs_base.py | 6 +-
stats/migrations/0008_domain_extra_its_dirs.py | 10 +-
.../migrations/0009_remove_null_on_text_fields.py | 96 +-
stats/migrations/0010_pot_method.py | 36 +-
stats/migrations/0011_migrate_pot_method.py | 22 +-
.../0012_remove_domain_pot_method_old.py | 6 +-
stats/migrations/0013_domain_layout.py | 12 +-
stats/migrations/0014_migrate_dir_to_layout.py | 10 +-
stats/migrations/0015_remove_domain_directory.py | 6 +-
stats/migrations/0016_removed_bugs_fields.py | 10 +-
stats/migrations/0017_pofile_path_relative.py | 14 +-
stats/migrations/0018_new_jsonfields.py | 22 +-
stats/migrations/0019_migrate_old_custom_files.py | 4 +-
stats/migrations/0020_remove_pofile_figures_old.py | 10 +-
stats/migrations/0021_release_name_unique.py | 6 +-
stats/models.py | 1375 ++++++++++----------
stats/potdiff.py | 9 +-
stats/repos.py | 78 +-
stats/templatetags/stats_extras.py | 152 ++-
stats/tests/fixture_factory.py | 143 +-
stats/tests/tests.py | 845 ++++++------
stats/tests/utils.py | 20 +-
stats/utils.py | 345 +++--
stats/views.py | 225 ++--
teams/admin.py | 18 +-
teams/forms.py | 64 +-
teams/migrations/0001_initial.py | 73 +-
teams/models.py | 93 +-
teams/tests.py | 175 ++-
teams/urls.py | 13 +-
teams/views.py | 108 +-
templates/about.html | 10 +-
templates/base.html | 4 +
vertimus/admin.py | 18 +-
vertimus/feeds.py | 71 +-
vertimus/forms.py | 83 +-
vertimus/migrations/0001_initial.py | 278 ++--
vertimus/migrations/0002_state_person_blank.py | 8 +-
vertimus/migrations/0003_add_action_sent_to_ml.py | 10 +-
vertimus/migrations/0004_tables_to_utf8mb4.py | 7 +-
vertimus/migrations/0005_action_proxy_pofile.py | 31 +-
vertimus/migrations/0006_pofile_path_relative.py | 5 +-
.../migrations/0008_actions_on_delete_setnull.py | 16 +-
vertimus/models.py | 362 +++---
vertimus/templatetags/vertimus.py | 32 +-
vertimus/tests/tests.py | 627 ++++-----
vertimus/urls.py | 53 +-
vertimus/views.py | 324 ++---
112 files changed, 4768 insertions(+), 4542 deletions(-)
---
diff --cc CONTRIBUTING.md
index 48fa6b70,33c77dd5..2afe3533
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@@ -93,11 -93,11 +93,11 @@@ You can install them on your operating
* On **Debian** based systems:
```bash
- apt install gettext intltool itstool libmariadbclient-dev libicu-dev libxml2-dev python3-dev yelp-tools
build-essential translate-toolkit
- apt install gettext intltool itstool libmariadbclient-dev libicu-dev libxml2-dev python3-dev yelp-tools
build-essential python3-pillow pyicu
++ apt install gettext intltool itstool libmariadbclient-dev libicu-dev libxml2-dev python3-dev yelp-tools
build-essential python3-pillow pyicu translate-toolkit
```
* On **Fedora** based systems:
```
- dnf install gettext intltool itstool mariadb-devel libicu-devel libxml2-devel python-devel yelp-tools
@development-tools translate-toolkit
- dnf install gettext intltool itstool mariadb-devel libicu-devel libxml2-devel python-devel yelp-tools
@development-tools python3-pillow python3-pyicu
++ dnf install gettext intltool itstool mariadb-devel libicu-devel libxml2-devel python-devel yelp-tools
@development-tools python3-pillow python3-pyicu translate-toolkit
```
## Python environment
diff --cc api/tests.py
index e9cc976b,0ef7abf8..ee71b61f
--- a/api/tests.py
+++ b/api/tests.py
@@@ -151,90 -158,50 +159,81 @@@ class APITests(TestCase)
response = self.client.post(url, data={})
self.assertEqual(response.status_code, 403)
- def test_upload_translation(self):
- translator = Person.objects.create(
++
+class APIUploadTests(TestCase):
- fixtures = ['sample_data.json']
++ fixtures = ["sample_data.json"]
+
+ @classmethod
+ def setUpTestData(cls):
+ super().setUpTestData()
+ cls.translator = Person.objects.create(
- first_name='John', last_name='Translator',
- email='jt devnull com', username='translator'
+ first_name="John", last_name="Translator", email="jt devnull com", username="translator"
)
- cls.team = Team.objects.get(name='fr')
- somebody = Person.objects.create(email="some devnull com", username="somebody")
- team = Team.objects.get(name="fr")
- Role.objects.create(team=team, person=translator)
- Role.objects.create(team=team, person=somebody)
++ cls.team = Team.objects.get(name="fr")
+ Role.objects.create(team=cls.team, person=cls.translator)
- cls.url = reverse('api-upload', args=['gnome-hello', 'master', 'po', 'fr'])
++ cls.url = reverse("api-upload", args=["gnome-hello", "master", "po", "fr"])
+ cls.test_po = Path(__file__).parent.parent / "stats" / "tests" / "test.po"
+ def _get_module_state(self):
+ """Create basic data ready for testing file upload."""
_, _, state = get_vertimus_state(
- Branch.objects.get(module__name='gnome-hello'),
- Domain.objects.get(module__name='gnome-hello', name='po'),
- Language.objects.get(locale='fr')
+ Branch.objects.get(module__name="gnome-hello"),
+ Domain.objects.get(module__name="gnome-hello", name="po"),
+ Language.objects.get(locale="fr"),
)
- url = reverse("api-upload", args=["gnome-hello", "master", "po", "fr"])
- test_po = Path(__file__).parent.parent / "stats" / "tests" / "test.po"
- # Test anonymous cannot post
- with test_po.open("rb") as fh:
- response = self.client.post(url, data={"file": File(fh)})
- self.assertRedirects(response, reverse("login") + f"?next={url}")
+ return state
- state.change_state(StateTranslating, person=translator)
+ def test_upload_translation_anonymously(self):
+ """Non-logged in user cannot submit file."""
- somebody = Person.objects.create(
- email='some devnull com', username='somebody'
- )
++ somebody = Person.objects.create(email="some devnull com", username="somebody")
+ Role.objects.create(team=self.team, person=somebody)
- # somebody cannot post translation if reserved by translator.
+ # Anonymous cannot post
- with self.test_po.open('rb') as fh:
- response = self.client.post(self.url, data={'file': File(fh)})
- self.assertRedirects(response, reverse('login') + f'?next={self.url}')
++ with self.test_po.open("rb") as fh:
++ response = self.client.post(self.url, data={"file": File(fh)})
++ self.assertRedirects(response, reverse("login") + f"?next={self.url}")
+
+ def test_upload_translation_translating(self):
+ """If module is already reserved by another translator, uploading will be refused."""
+ state = self._get_module_state()
+ state.change_state(StateTranslating, person=self.translator)
+
- somebody = Person.objects.create(
- email='some devnull com', username='somebody'
- )
++ somebody = Person.objects.create(email="some devnull com", username="somebody")
+ Role.objects.create(team=self.team, person=somebody)
self.client.force_login(somebody)
- with self.test_po.open('rb') as fh:
- response = self.client.post(self.url, data={'file': File(fh)})
- with test_po.open("rb") as fh:
- response = self.client.post(url, data={"file": File(fh)})
++
++ with self.test_po.open("rb") as fh:
++ response = self.client.post(self.url, data={"file": File(fh)})
self.assertEqual(response.status_code, 403)
- self.client.force_login(translator)
- with test_po.open("rb") as fh:
- response = self.client.post(url, data={"file": File(fh)})
+ def test_upload_invalid_file(self):
+ state = self._get_module_state()
+ state.change_state(StateTranslating, person=self.translator)
+ self.client.force_login(self.translator)
- response = self.client.post(self.url, data={
- 'file': SimpleUploadedFile('filename.po', b'No valid po file content')
- })
- err = '.po file does not pass “msgfmt -vc”. Please correct the file and try again.'
- self.assertEqual(
- response.json(),
- {
- 'result': 'Error',
- 'error': {'file': [err]}
- }
++ response = self.client.post(
++ self.url, data={"file": SimpleUploadedFile("filename.po", b"No valid po file content")}
+ )
++ err = ".po file does not pass “msgfmt -vc”. Please correct the file and try again."
++ self.assertEqual(response.json(), {"result": "Error", "error": {"file": [err]}})
+
+ def test_upload_translation(self):
+ state = self._get_module_state()
+ state.change_state(StateTranslating, person=self.translator)
+ self.client.force_login(self.translator)
- with self.test_po.open('rb') as fh:
- response = self.client.post(self.url, data={'file': File(fh)})
- self.assertEqual(response.json(), {'result': 'OK'})
++ with self.test_po.open("rb") as fh:
++ response = self.client.post(self.url, data={"file": File(fh)})
+ self.assertEqual(response.json(), {"result": "OK"})
self.assertEqual(len(mail.outbox), 1)
- self.assertEqual(mail.outbox[0].recipients(), [team.mailing_list])
+ self.assertEqual(mail.outbox[0].recipients(), [self.team.mailing_list])
# Test upload with comment
- state.change_state(StateTranslating, person=translator)
- with test_po.open("rb") as fh:
+ state.change_state(StateTranslating, person=self.translator)
- with self.test_po.open('rb') as fh:
++ with self.test_po.open("rb") as fh:
data = {
- 'file': File(fh),
- 'comment': 'The comment',
+ "file": File(fh),
+ "comment": "The comment",
}
- response = self.client.post(url, data=data)
+ response = self.client.post(self.url, data=data)
- self.assertEqual(response.json(), {'result': 'OK'})
+ self.assertEqual(response.json(), {"result": "OK"})
action = Action.objects.last()
self.assertEqual(action.comment, "The comment")
diff --cc api/views.py
index c2d07f1f,9988ac09..34aaa322
--- a/api/views.py
+++ b/api/views.py
@@@ -256,24 -253,14 +254,26 @@@ class ReserveTranslationView(LoginRequi
class UploadTranslationView(LoginRequiredMixin, VertimusPageMixin, View):
def post(self, request, *args, **kwargs):
stats, state = self.get_state_from_kwargs()
- actions = [x.name for x in state.get_available_actions(request.user.person)]
- if "UT" not in actions:
+ actions = state.get_available_actions(request.user.person)
- if 'UT' not in [x.name for x in actions]:
- return HttpResponseForbidden('You cannot upload a translation to this module')
++ if "UT" not in [x.name for x in actions]:
+ return HttpResponseForbidden("You cannot upload a translation to this module")
- action = ActionUT(person=request.user.person, file=request.FILES.get("file"))
- comment = request.POST.get("comment", "")
- action.apply_on(state, {"comment": comment, "send_to_ml": True})
- return JsonResponse({"result": "OK"})
+ action_form = ActionForm(
- request.user, state, actions,
++ request.user,
++ state,
++ actions,
+ data={
- 'action': 'UT',
- 'comment': request.POST.get('comment', ''),
++ "action": "UT",
++ "comment": request.POST.get("comment", ""),
+ },
+ files=request.FILES,
+ )
+ if action_form.is_valid():
- action = ActionUT(person=request.user.person, file=action_form.cleaned_data['file'])
- action.apply_on(state, {'comment': action_form.cleaned_data['comment'], 'send_to_ml': True})
- return JsonResponse({'result': 'OK'})
++ action = ActionUT(person=request.user.person, file=action_form.cleaned_data["file"])
++ action.apply_on(state, {"comment": action_form.cleaned_data["comment"], "send_to_ml": True})
++ return JsonResponse({"result": "OK"})
+ else:
- return JsonResponse({'result': 'Error', 'error': action_form.errors})
++ return JsonResponse({"result": "Error", "error": action_form.errors})
# CSRF skipped, verification using a secret token.
diff --cc vertimus/forms.py
index aec1b9ab,278df385..f3e20ae5
--- a/vertimus/forms.py
+++ b/vertimus/forms.py
@@@ -51,46 -49,42 +49,43 @@@ class ActionForm(forms.Form)
)
author = AuthorChoiceField(label=_("Commit author"), queryset=Person.objects.none(), required=False)
sync_master = forms.BooleanField(required=False)
- file = forms.FileField(label=_("File"), required=False,
- help_text=_("Upload a .po, .gz, .bz2, .xz or .png file"))
+ file = forms.FileField(label=_("File"), required=False, help_text=_("Upload a .po, .gz, .bz2, .xz or
.png file"))
send_to_ml = forms.BooleanField(label=_("Send message to the team mailing list"), required=False)
- def __init__(self, current_user, state, actions, has_mailing_list, *args, **kwargs):
+ def __init__(self, current_user, state, actions, *args, **kwargs):
super().__init__(*args, **kwargs)
self.actions = actions
self.current_user = current_user
- self.fields['action'].choices = [(
- act.name,
- DisabledLabel(act.description) if isinstance(act, ActionSeparator) else act.description
- ) for act in actions]
- self.fields['action'].help_link = reverse('help', args=['vertimus_workflow', 1])
+ self.fields["action"].choices = [
+ (act.name, DisabledLabel(act.description) if isinstance(act, ActionSeparator) else
act.description)
+ for act in actions
+ ]
+ self.fields["action"].help_link = reverse("help", args=["vertimus_workflow", 1])
if state and ActionCI in map(type, self.actions):
- self.fields['author'].queryset = state.involved_persons(
- extra_user=current_user
- ).order_by('last_name', 'username')
- self.fields['author'].initial = state.get_latest_po_file_action().person
- has_mailing_list = (
- state and state.language and state.language.team and bool(state.language.team.mailing_list)
- )
+ self.fields["author"].queryset = state.involved_persons(extra_user=current_user).order_by(
+ "last_name", "username"
+ )
+ self.fields["author"].initial = state.get_latest_po_file_action().person
++ has_mailing_list = state and state.language and state.language.team and
bool(state.language.team.mailing_list)
if not has_mailing_list:
- del self.fields['send_to_ml']
+ del self.fields["send_to_ml"]
if state and state.branch.is_head():
- del self.fields['sync_master']
+ del self.fields["sync_master"]
elif state:
main_branch = state.branch.module.get_head_branch()
- self.fields['sync_master'].label = _("Sync with %(name)s") % {'name': main_branch.name}
- self.fields['sync_master'].help_text = (
- _("Try to cherry-pick the commit to the %(name)s branch") % {'name': main_branch.name}
- )
+ self.fields["sync_master"].label = _("Sync with %(name)s") % {"name": main_branch.name}
+ self.fields["sync_master"].help_text = _("Try to cherry-pick the commit to the %(name)s
branch") % {
+ "name": main_branch.name
+ }
def clean_file(self):
- data = self.cleaned_data['file']
+ data = self.cleaned_data["file"]
if data:
ext = os.path.splitext(data.name)[1]
- if ext not in ('.po', '.gz', '.bz2', '.xz', '.png'):
+ if ext not in (".po", ".gz", ".bz2", ".xz", ".png"):
raise ValidationError(_("Only files with extension .po, .gz, .bz2, .xz or .png are
admitted."))
# If this is a .po file, check validity (msgfmt)
- if ext == '.po':
+ if ext == ".po":
if check_po_conformity(data):
raise ValidationError(
_(".po file does not pass “msgfmt -vc”. Please correct the file and try again.")
diff --cc vertimus/tests/tests.py
index d98e071d,512921bf..2d933c51
--- a/vertimus/tests/tests.py
+++ b/vertimus/tests/tests.py
@@@ -226,18 -243,18 +243,18 @@@ class VertimusTest(TeamsAndRolesMixin,
def test_action_menu(self):
state = StateNone(branch=self.b, domain=self.d, language=self.language)
- form = ActionForm(self.pt, state, state.get_available_actions(self.pt), False)
+ form = ActionForm(self.pt, state, state.get_available_actions(self.pt))
self.assertHTMLEqual(
- str(form['action']),
+ str(form["action"]),
'<select id="id_action" name="action">'
'<option value="RT">Reserve for translation</option>'
'<option value="UT">Upload the new translation</option>'
'<option value="WC">Write a comment</option>'
- '</select>'
+ "</select>",
)
- form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo), False)
+ form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo))
self.assertHTMLEqual(
- str(form['action']),
+ str(form["action"]),
'<select id="id_action" name="action">'
'<option value="RT">Reserve for translation</option>'
'<option value="UT">Upload the new translation</option>'
@@@ -264,7 -281,7 +281,7 @@@
self.assertEqual(len(mail.outbox), 2)
self.assertEqual(mail.outbox[1].recipients(), [self.pt.email])
# Test that submitting a comment without text generates a validation error
- form = ActionForm(self.pt, state, [ActionWC()], data=QueryDict('action=WC&comment='))
- form = ActionForm(self.pt, state, [ActionWC()], True, QueryDict("action=WC&comment="))
++ form = ActionForm(self.pt, state, [ActionWC()], data=QueryDict("action=WC&comment="))
self.assertTrue("A comment is needed" in str(form.errors))
self.assertNotEqual(state.updated, prev_updated)
@@@ -446,13 -464,13 +464,13 @@@
self.assertIn(ActionCI, map(type, state.get_available_actions(self.pcoo)))
- form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo), True)
+ form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo))
- self.assertEqual(len(form.fields['author'].choices), 6)
- self.assertEqual(form.fields['author'].initial, self.pr)
- self.assertIn('sync_master', form.fields)
- self.assertEqual(form.fields['sync_master'].label, "Sync with master")
+ self.assertEqual(len(form.fields["author"].choices), 6)
+ self.assertEqual(form.fields["author"].initial, self.pr)
+ self.assertIn("sync_master", form.fields)
+ self.assertEqual(form.fields["sync_master"].label, "Sync with master")
self.assertHTMLEqual(
- str(form['author']),
+ str(form["author"]),
'<select id="id_author" name="author">'
'<option value="">---------</option>'
'<option disabled value="%d">ûsername (full name missing)</option>'
@@@ -478,34 -501,26 +501,26 @@@
state = StateProofreading(branch=self.b, domain=self.d, language=self.language, person=pers)
state.save()
# Adding two comments from the commit author, as this might trigger a form error
- action = Action.new_by_name('WC', person=self.pcoo)
- action.apply_on(state, {'send_to_ml': False, 'comment': "Looks good"})
- action = Action.new_by_name('WC', person=self.pcoo)
- action.apply_on(state, {'send_to_ml': False, 'comment': "Looks good too"})
-
- self.upload_file(state, 'UP', pers=pers)
- post_data = {
- 'action': 'CI',
- 'author': '',
- 'comment': '',
- 'send_to_ml': True
- }
+ action = Action.new_by_name("WC", person=self.pcoo)
+ action.apply_on(state, {"send_to_ml": False, "comment": "Looks good"})
+ action = Action.new_by_name("WC", person=self.pcoo)
+ action.apply_on(state, {"send_to_ml": False, "comment": "Looks good too"})
+
+ self.upload_file(state, "UP", pers=pers)
+ post_data = {"action": "CI", "author": "", "comment": "", "send_to_ml": True}
- form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo), True, post_data)
+ form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo), data=post_data)
# Missing author
self.assertFalse(form.is_valid())
- post_data['author'] = str(self.pcoo.pk)
+ post_data["author"] = str(self.pcoo.pk)
- form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo), True, post_data)
+ form = ActionForm(self.pcoo, state, state.get_available_actions(self.pcoo), data=post_data)
self.assertTrue(form.is_valid())
# path needed when copying file to commit
- (self.b.co_path / 'po').mkdir(parents=True, exist_ok=True)
- with PatchShellCommand(only=['git ']) as cmds:
- action = Action.new_by_name('CI', person=self.pcoo)
+ (self.b.co_path / "po").mkdir(parents=True, exist_ok=True)
+ with PatchShellCommand(only=["git "]) as cmds:
+ action = Action.new_by_name("CI", person=self.pcoo)
msg = action.apply_on(state, form.cleaned_data)
- self.assertIn(
- 'git commit -m Update French translation --author John Coordinator <jcoo imthebigboss fr>',
- cmds
- )
- self.assertEqual(msg, 'The file has been successfully committed to the repository.')
+ self.assertIn("git commit -m Update French translation --author John Coordinator <jcoo imthebigboss
fr>", cmds)
+ self.assertEqual(msg, "The file has been successfully committed to the repository.")
state.refresh_from_db()
# All actions should have been archived
self.assertEqual(state.action_set.count(), 0)
@@@ -718,18 -740,18 +740,18 @@@
def test_uploaded_file_validation(self):
# Test a non valid po file
- post_content = QueryDict('action=WC&comment=Test1')
- post_file = MultiValueDict({'file': [SimpleUploadedFile('filename.po', b'Not valid po file
content')]})
+ post_content = QueryDict("action=WC&comment=Test1")
+ post_file = MultiValueDict({"file": [SimpleUploadedFile("filename.po", b"Not valid po file
content")]})
- form = ActionForm(self.pt, None, [ActionWC()], True, post_content, post_file)
+ form = ActionForm(self.pt, None, [ActionWC()], data=post_content, files=post_file)
- self.assertTrue('file' in form.errors)
- post_file = MultiValueDict({'file': [SimpleUploadedFile('filename.po', 'Niña'.encode('latin-1'))]})
+ self.assertTrue("file" in form.errors)
+ post_file = MultiValueDict({"file": [SimpleUploadedFile("filename.po", "Niña".encode("latin-1"))]})
- form = ActionForm(self.pt, None, [ActionWC()], True, post_content, post_file)
+ form = ActionForm(self.pt, None, [ActionWC()], data=post_content, files=post_file)
- self.assertTrue('file' in form.errors)
+ self.assertTrue("file" in form.errors)
# Test a valid po file
- with (Path(__file__).parent / "valid_po.po").open('rb') as fh:
- post_file = MultiValueDict({'file': [File(fh)]})
+ with (Path(__file__).parent / "valid_po.po").open("rb") as fh:
+ post_file = MultiValueDict({"file": [File(fh)]})
- form = ActionForm(self.pt, None, [ActionWC()], True, post_content, post_file)
+ form = ActionForm(self.pt, None, [ActionWC()], data=post_content, files=post_file)
self.assertTrue(form.is_valid())
# Test form without file
diff --cc vertimus/views.py
index 79209f04,afceaa3f..44c61998
--- a/vertimus/views.py
+++ b/vertimus/views.py
@@@ -89,10 -102,9 +102,8 @@@ def vertimus(request, branch, domain, l
# Only authenticated user can act on the translation and it's not
# possible to edit an archived workflow
available_actions = state.get_available_actions(person)
- if request.method == 'POST':
- action_form = ActionForm(
- request.user, state, available_actions, request.POST, request.FILES
- )
- has_ml = bool(language.team.mailing_list) if language.team else False
+ if request.method == "POST":
- action_form = ActionForm(request.user, state, available_actions, has_ml, request.POST,
request.FILES)
++ action_form = ActionForm(request.user, state, available_actions, request.POST, request.FILES)
if action_form.is_valid():
# Process the data in form.cleaned_data
@@@ -118,37 -122,34 +121,34 @@@
messages.success(request, msg)
return HttpResponseRedirect(
- reverse(
- 'vertimus_by_names',
- args=(branch.module.name, branch.name, domain.name, language.locale)
- )
+ reverse("vertimus_by_names", args=(branch.module.name, branch.name, domain.name,
language.locale))
)
elif available_actions:
- action_form = ActionForm(request.user, state, available_actions, has_ml)
+ action_form = ActionForm(request.user, state, available_actions)
context = {
- 'pageSection': 'module',
- 'stats': stats,
- 'pot_stats': pot_stats,
- 'po_url': stats.po_url(),
- 'po_url_reduced': stats.has_reducedstat() and stats.po_url(reduced=True) or '',
- 'branch': branch,
- 'other_states': other_branch_states,
- 'domain': domain,
- 'language': language,
- 'module': branch.module,
- 'non_standard_repo_msg': _(settings.VCS_HOME_WARNING),
- 'state': state,
- 'is_team_member': person and language.team and person.is_translator(language.team),
- 'action_history': action_history,
- 'action_form': action_form,
- 'level': level,
- 'grandparent_level': grandparent_level,
+ "pageSection": "module",
+ "stats": stats,
+ "pot_stats": pot_stats,
+ "po_url": stats.po_url(),
+ "po_url_reduced": stats.has_reducedstat() and stats.po_url(reduced=True) or "",
+ "branch": branch,
+ "other_states": other_branch_states,
+ "domain": domain,
+ "language": language,
+ "module": branch.module,
+ "non_standard_repo_msg": _(settings.VCS_HOME_WARNING),
+ "state": state,
+ "is_team_member": person and language.team and person.is_translator(language.team),
+ "action_history": action_history,
+ "action_form": action_form,
+ "level": level,
+ "grandparent_level": grandparent_level,
}
if stats.has_figures():
- context['fig_stats'] = stats.fig_stats()
- del context['fig_stats']['prc']
- return render(request, 'vertimus/vertimus_detail.html', context)
+ context["fig_stats"] = stats.fig_stats()
+ del context["fig_stats"]["prc"]
+ return render(request, "vertimus/vertimus_detail.html", context)
def get_vertimus_state(branch, domain, language, stats=None):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]