VPN Invite app translation

This commit is contained in:
Eduardo Silva
2025-04-16 10:18:23 -03:00
parent 036dcc75da
commit 3cb10b6ec4
7 changed files with 401 additions and 115 deletions

View File

@@ -1,10 +1,10 @@
from django import forms
from django.core.exceptions import ValidationError
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Row, Column, Submit, HTML
from crispy_forms.templatetags.crispy_forms_field import css_class
from .models import InviteSettings
from crispy_forms.layout import Column, HTML, Layout, Row, Submit
from django import forms
from django.utils.translation import gettext_lazy as _
from wireguard_tools.models import EmailSettings
from .models import InviteSettings
class InviteSettingsForm(forms.ModelForm):
@@ -46,7 +46,7 @@ class InviteSettingsForm(forms.ModelForm):
super(InviteSettingsForm, self).__init__(*args, **kwargs)
# Define boolean dropdown choices
bool_choices = [(True, 'Enabled'), (False, 'Disabled')]
bool_choices = [(True, _('Enabled')), (False, _('Disabled'))]
bool_coerce = lambda x: True if x == 'True' else False
for field_name in [
@@ -65,37 +65,42 @@ class InviteSettingsForm(forms.ModelForm):
initial=self.instance.__dict__.get(field_name, True) if self.instance and self.instance.pk else True,
)
self.fields['download_1_url'].label = 'URL'
self.fields['download_2_url'].label = 'URL'
self.fields['download_3_url'].label = 'URL'
self.fields['download_4_url'].label = 'URL'
self.fields['download_5_url'].label = 'URL'
self.fields['download_1_label'].label = 'Text'
self.fields['download_2_label'].label = 'Text'
self.fields['download_3_label'].label = 'Text'
self.fields['download_4_label'].label = 'Text'
self.fields['download_5_label'].label = 'Text'
self.fields['download_1_enabled'].label = 'Status'
self.fields['download_2_enabled'].label = 'Status'
self.fields['download_3_enabled'].label = 'Status'
self.fields['download_4_enabled'].label = 'Status'
self.fields['download_5_enabled'].label = 'Status'
self.fields['download_instructions'].label = 'Web Page Instructions'
self.fields['invite_email_subject'].label = 'Email Subject'
self.fields['invite_email_body'].label = 'Email Message'
self.fields['invite_email_enabled'].label = 'Email Enabled'
self.fields['invite_whatsapp_body'].label = 'WhatsApp Message'
self.fields['invite_whatsapp_enabled'].label = 'WhatsApp Enabled'
self.fields['invite_text_body'].label = 'Text Message'
self.fields['invite_expiration'].label = 'Expiration (minutes)'
self.fields['enforce_random_password'].label = 'Random Password'
self.fields['download_1_url'].label = _('URL')
self.fields['download_2_url'].label = _('URL')
self.fields['download_3_url'].label = _('URL')
self.fields['download_4_url'].label = _('URL')
self.fields['download_5_url'].label = _('URL')
self.fields['download_1_label'].label = _('Text')
self.fields['download_2_label'].label = _('Text')
self.fields['download_3_label'].label = _('Text')
self.fields['download_4_label'].label = _('Text')
self.fields['download_5_label'].label = _('Text')
self.fields['download_1_enabled'].label = _('Status')
self.fields['download_2_enabled'].label = _('Status')
self.fields['download_3_enabled'].label = _('Status')
self.fields['download_4_enabled'].label = _('Status')
self.fields['download_5_enabled'].label = _('Status')
self.fields['download_instructions'].label = _('Web Page Instructions')
self.fields['invite_email_subject'].label = _('Email Subject')
self.fields['invite_email_body'].label = _('Email Message')
self.fields['invite_email_enabled'].label = _('Email Enabled')
self.fields['invite_whatsapp_body'].label = _('WhatsApp Message')
self.fields['invite_whatsapp_enabled'].label = _('WhatsApp Enabled')
self.fields['invite_text_body'].label = _('Text Message')
self.fields['invite_expiration'].label = _('Expiration (minutes)')
self.fields['enforce_random_password'].label = _('Random Password')
self.fields['invite_url'].label = _('Invite URL')
self.fields['required_user_level'].label = _('Required User Level')
self.fields['default_password'].label = _('Default Password')
self.fields['random_password_length'].label = _('Random Password Length')
self.fields['random_password_complexity'].label = _('Random Password Complexity')
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.layout = Layout(
Row(
Column(
HTML("<h3>General Settings</h3>"),
HTML("<h3>" + _("General Settings") + "</h3>"),
Row(
Column('invite_url', css_class='form-group col-md-12 mb-0'),
),
@@ -117,7 +122,7 @@ class InviteSettingsForm(forms.ModelForm):
),
HTML("<hr>"),
Row(
Column(HTML("<h5>Download Buttons</h5>"), css_class='form-group col-md-12 mb-0'),
Column(HTML("<h5>" + _("Download Buttons") + "</h5>"), css_class='form-group col-md-12 mb-0'),
Column('download_1_label', css_class='form-group col-md-3 mb-0'),
Column('download_1_url', css_class='form-group col-md-6 mb-0'),
Column('download_1_enabled', css_class='form-group col-md-3 mb-0'),
@@ -147,24 +152,17 @@ class InviteSettingsForm(forms.ModelForm):
Column('download_5_enabled', css_class='form-group col-md-3 mb-0'),
css_class='form-row'
),
Row(
Column(
Submit('submit', 'Save', css_class='btn btn-success'),
HTML(' <a class="btn btn-secondary" href="/vpn_invite/">Back</a> '),
css_class='col-md-12'
),
css_class='form-row'
),
css_class='col-xl-6'),
css_class='col-xl-12'),
Column(
HTML("<h3>Message templates</h3>"),
HTML("<h3>" + _('Message templates') + "</h3>"),
Row(
Column('download_instructions', css_class='form-group col-md-12 mb-0'),
css_class='form-row'
),
HTML("<hr>"),
Row(
Column(HTML("<h5>Email Message Template</h5>"), css_class='form-group col-md-12 mb-0'),
Column(HTML("<h5>" + _("Email Message Template") + "</h5>"), css_class='form-group col-md-12 mb-0'),
Column('invite_email_subject', css_class='form-group col-md-12 mb-0'),
Column('invite_email_body', css_class='form-group col-md-12 mb-0'),
css_class='form-row'
@@ -175,19 +173,26 @@ class InviteSettingsForm(forms.ModelForm):
),
HTML("<hr>"),
Row(
Column(HTML("<h5>WhatsApp Message Template</h5>"), css_class='form-group col-md-12 mb-0'),
Column(HTML("<h5>" + _("WhatsApp Message Template") + "</h5>"), css_class='form-group col-md-12 mb-0'),
Column('invite_whatsapp_body', css_class='form-group col-md-12 mb-0'),
Column('invite_whatsapp_enabled', css_class='form-group col-md-12 mb-0'),
css_class='form-row'
),
HTML("<hr>"),
Row(
Column(HTML("<h5>Text Message Template</h5>"), css_class='form-group col-md-12 mb-0'),
Column(HTML("<h5>" + _("Text Message Template") + "</h5>"), css_class='form-group col-md-12 mb-0'),
Column('invite_text_body', css_class='form-group col-md-12 mb-0'),
css_class='form-row'
),
css_class='col-xl-6'),
css_class='col-xl-12'),
css_class='row'),
Row(
Column(
Submit('submit', _('Save'), css_class='btn btn-success'),
HTML(' <a class="btn btn-secondary" href="/vpn_invite/">' + _('Back') + '</a> '),
css_class='col-md-12'
),
css_class='form-row'),
)
def clean(self):
@@ -197,15 +202,15 @@ class InviteSettingsForm(forms.ModelForm):
invite_url = cleaned_data.get('invite_url')
if invite_url:
if not invite_url.startswith("https://"):
self.add_error('invite_url', "Invite URL must start with 'https://'.")
self.add_error('invite_url', _("Invite URL must start with 'https://'."))
if not invite_url.endswith("/invite/"):
self.add_error('invite_url', "Invite URL must end with '/invite/'.")
self.add_error('invite_url', _("Invite URL must end with '/invite/'."))
# Validate invite_expiration: must be between 1 and 1440 minutes
invite_expiration = cleaned_data.get('invite_expiration')
if invite_expiration is not None:
if invite_expiration < 1 or invite_expiration > 1440:
self.add_error('invite_expiration', "Expiration (minutes) must be between 1 and 1440.")
self.add_error('invite_expiration', _("Expiration (minutes) must be between 1 and 1440."))
# Validate default_password based on enforce_random_password flag
default_password = cleaned_data.get('default_password', '')
@@ -214,16 +219,16 @@ class InviteSettingsForm(forms.ModelForm):
if enforce_random_password is True:
if default_password:
self.add_error('default_password',
"Default password must not be provided when random password is enabled.")
_("Default password must not be provided when random password is enabled."))
if random_password_length < 6:
self.add_error('random_password_length', "Random password length must be at least 6 characters.")
self.add_error('random_password_length', _("Random password length must be at least 6 characters."))
else:
# When random password is disabled, default password must be provided and have at least 6 characters.
if not default_password:
self.add_error('default_password',
"Default password must be provided when random password is disabled.")
_("Default password must be provided when random password is disabled."))
elif len(default_password) < 6:
self.add_error('default_password', "Default password must be at least 6 characters long.")
self.add_error('default_password', _("Default password must be at least 6 characters long."))
# Validate download buttons: if enabled, the respective text and url fields must not be blank.
for i in range(1, 6):
@@ -233,9 +238,9 @@ class InviteSettingsForm(forms.ModelForm):
if enabled:
if not label:
self.add_error(f'download_{i}_label',
"Text field must not be empty when download button is enabled.")
_("Text field must not be empty when download button is enabled."))
if not url:
self.add_error(f'download_{i}_url', "URL field must not be empty when download button is enabled.")
self.add_error(f'download_{i}_url', _("URL field must not be empty when download button is enabled."))
# Validate that default_password is not contained in any message templates or the subject
message_fields = ['invite_text_body', 'invite_email_subject', 'invite_email_body', 'invite_whatsapp_body']
@@ -244,14 +249,14 @@ class InviteSettingsForm(forms.ModelForm):
content = cleaned_data.get(field, '')
if default_password in content:
self.add_error('default_password',
f"Default password must not be contained in {field.replace('_', ' ')}.")
_("Default password must not be contained in any message template. Found at: ") + f"{field.replace('_', ' ')}.")
# Validate that all message templates include the placeholder '{invite_url}'
for field in message_fields:
if field != 'invite_email_subject':
content = cleaned_data.get(field, '')
if '{invite_url}' not in content:
self.add_error(field, "The template must include the placeholder '{invite_url}'.")
self.add_error(field, _("The template must include the placeholder '{invite_url}'."))
return cleaned_data
@@ -273,12 +278,12 @@ class EmailSettingsForm(forms.ModelForm):
super(EmailSettingsForm, self).__init__(*args, **kwargs)
# Set custom labels for form fields
self.fields['smtp_username'].label = 'Username'
self.fields['smtp_password'].label = 'Password'
self.fields['smtp_host'].label = 'Host'
self.fields['smtp_port'].label = 'Port'
self.fields['smtp_encryption'].label = 'Encryption'
self.fields['smtp_from_address'].label = 'From Address'
self.fields['smtp_username'].label = _('Username')
self.fields['smtp_password'].label = _('Password')
self.fields['smtp_host'].label = _('Host')
self.fields['smtp_port'].label = _('Port')
self.fields['smtp_encryption'].label = _('Encryption')
self.fields['smtp_from_address'].label = _('From Address')
self.fields['smtp_password'].required = True
self.fields['smtp_host'].required = True
@@ -286,6 +291,7 @@ class EmailSettingsForm(forms.ModelForm):
self.fields['smtp_encryption'].required = True
self.fields['smtp_from_address'].required = True
self.fields['smtp_username'].required = True
self.fields['enabled'].label = _('Enabled')
# Use PasswordInput widget to hide the password
self.fields['smtp_password'].widget = forms.PasswordInput(render_value=False)
@@ -316,8 +322,8 @@ class EmailSettingsForm(forms.ModelForm):
),
Row(
Column(
Submit('submit', 'Save', css_class='btn btn-success'),
HTML(' <a class="btn btn-secondary" href="/vpn_invite/">Back</a> '),
Submit('submit', _('Save'), css_class='btn btn-success'),
HTML(' <a class="btn btn-secondary" href="/vpn_invite/">' + _('Back') + '</a> '),
css_class='col-md-12'
),
css_class='form-row'
@@ -328,7 +334,7 @@ class EmailSettingsForm(forms.ModelForm):
cleaned_data = super().clean()
smtp_port = cleaned_data.get('smtp_port')
if smtp_port is not None and smtp_port <= 0:
self.add_error('smtp_port', "SMTP port must be a positive integer.")
self.add_error('smtp_port', _("SMTP port must be between 1 and 65535."))
return cleaned_data